Date:2010-08-01 14:39:19 (4 years 4 months ago)
Author:florian
Commit:565343952de0f30743e7d0c2e01ad562a79b471b
Message:[toolchain] add support for gcc-4.5.1

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22450 3c298f89-4303-0410-b956-a3cf2f4a3e73
Files: toolchain/gcc/Config.in (1 diff)
toolchain/gcc/Config.version (2 diffs)
toolchain/gcc/common.mk (1 diff)
toolchain/gcc/patches/4.5.1/100-uclibc-conf.patch (1 diff)
toolchain/gcc/patches/4.5.1/301-missing-execinfo_h.patch (1 diff)
toolchain/gcc/patches/4.5.1/302-c99-snprintf.patch (1 diff)
toolchain/gcc/patches/4.5.1/305-libmudflap-susv3-legacy.patch (1 diff)
toolchain/gcc/patches/4.5.1/600-ubicom_support.patch (1 diff)
toolchain/gcc/patches/4.5.1/810-arm-softfloat-libgcc.patch (1 diff)
toolchain/gcc/patches/4.5.1/820-libgcc_pic.patch (1 diff)
toolchain/gcc/patches/4.5.1/910-mbsd_multi.patch (1 diff)
toolchain/gcc/patches/4.5.1/993-arm_insn-opinit-RTX_CODE-fixup.patch (1 diff)
toolchain/gcc/patches/4.5.1/999-coldfire.patch (1 diff)

Change Details

toolchain/gcc/Config.in
4646    config GCC_VERSION_4_5_0
4747        bool "gcc 4.5.0"
4848
49    config GCC_VERSION_4_5_1
50        bool "gcc 4.5.1"
51
4952    config GCC_VERSION_LLVM
5053        bool "llvm-gcc 4.2"
5154        depends BROKEN
toolchain/gcc/Config.version
1313    default "4.4.3" if GCC_VERSION_4_4_3
1414    default "4.4.4" if GCC_VERSION_4_4_4
1515    default "4.5.0" if GCC_VERSION_4_5_0
16    default "4.5.1" if GCC_VERSION_4_5_1
1617    default "4.4.3+cs" if GCC_VERSION_4_4_3_CS
1718    default "llvm" if GCC_VERSION_LLVM
1819    default "4.1.2"
...... 
6162config GCC_VERSION_4_5
6263    bool
6364    default y if GCC_VERSION_4_5_0
65    default y if GCC_VERSION_4_5_1
6466
6567if !TOOLCHAINOPTS
6668    config GCC_VERSION_4_2_4
toolchain/gcc/common.mk
7272  ifeq ($(PKG_VERSION),4.5.0)
7373  PKG_MD5SUM:=ff27b7c4a5d5060c8a8543a44abca31f
7474  endif
75  ifeq ($(PKG_VERSION),4.5.1)
76  PKG_MD5SUM:=48231a8e33ed6e058a341c53b819de1a
77  endif
7578endif
7679
7780PATCH_DIR=../patches/$(GCC_VERSION)
toolchain/gcc/patches/4.5.1/100-uclibc-conf.patch
1--- a/contrib/regression/objs-gcc.sh
2@@ -106,6 +106,10 @@
3  then
4   make all-gdb all-dejagnu all-ld || exit 1
5   make install-gdb install-dejagnu install-ld || exit 1
6+elif [ $H_REAL_TARGET = $H_REAL_HOST -a $H_REAL_TARGET = i686-pc-linux-uclibc ]
7+ then
8+ make all-gdb all-dejagnu all-ld || exit 1
9+ make install-gdb install-dejagnu install-ld || exit 1
10 elif [ $H_REAL_TARGET = $H_REAL_HOST ] ; then
11   make bootstrap || exit 1
12   make install || exit 1
13--- a/libjava/classpath/ltconfig
14@@ -603,7 +603,7 @@
15
16 # Transform linux* to *-*-linux-gnu*, to support old configure scripts.
17 case $host_os in
18-linux-gnu*) ;;
19+linux-gnu*|linux-uclibc*) ;;
20 linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'`
21 esac
22
23@@ -1251,7 +1251,7 @@
24   ;;
25
26 # This must be Linux ELF.
27-linux-gnu*)
28+linux*)
29   version_type=linux
30   need_lib_prefix=no
31   need_version=no
toolchain/gcc/patches/4.5.1/301-missing-execinfo_h.patch
1--- a/boehm-gc/include/gc.h
2@@ -503,7 +503,7 @@
3 #if defined(__linux__) || defined(__GLIBC__)
4 # include <features.h>
5 # if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
6- && !defined(__ia64__)
7+ && !defined(__ia64__) && !defined(__UCLIBC__)
8 # ifndef GC_HAVE_BUILTIN_BACKTRACE
9 # define GC_HAVE_BUILTIN_BACKTRACE
10 # endif
toolchain/gcc/patches/4.5.1/302-c99-snprintf.patch
1--- a/libstdc++-v3/include/c_global/cstdio
2@@ -139,7 +139,7 @@
3
4 _GLIBCXX_END_NAMESPACE
5
6-#if _GLIBCXX_USE_C99
7+#if _GLIBCXX_USE_C99 || defined __UCLIBC__
8
9 #undef snprintf
10 #undef vfscanf
toolchain/gcc/patches/4.5.1/305-libmudflap-susv3-legacy.patch
1--- a/libmudflap/mf-hooks2.c
2@@ -421,7 +421,7 @@
3 {
4   TRACE ("%s\n", __PRETTY_FUNCTION__);
5   MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
6- bzero (s, n);
7+ memset (s, 0, n);
8 }
9
10
11@@ -431,7 +431,7 @@
12   TRACE ("%s\n", __PRETTY_FUNCTION__);
13   MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
14   MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
15- bcopy (src, dest, n);
16+ memmove (dest, src, n);
17 }
18
19
20@@ -441,7 +441,7 @@
21   TRACE ("%s\n", __PRETTY_FUNCTION__);
22   MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
23   MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
24- return bcmp (s1, s2, n);
25+ return n == 0 ? 0 : memcmp (s1, s2, n);
26 }
27
28
29@@ -450,7 +450,7 @@
30   size_t n = strlen (s);
31   TRACE ("%s\n", __PRETTY_FUNCTION__);
32   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
33- return index (s, c);
34+ return strchr (s, c);
35 }
36
37
38@@ -459,7 +459,7 @@
39   size_t n = strlen (s);
40   TRACE ("%s\n", __PRETTY_FUNCTION__);
41   MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
42- return rindex (s, c);
43+ return strrchr (s, c);
44 }
45
46 /* XXX: stpcpy, memccpy */
toolchain/gcc/patches/4.5.1/600-ubicom_support.patch
1--- a/configure
2@@ -2688,6 +2688,9 @@ case "${target}" in
3   ip2k-*-*)
4     noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
5     ;;
6+ ubicom32-*-*)
7+ noconfigdirs="$noconfigdirs target-libffi"
8+ ;;
9   *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
10     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
11     ;;
12--- /dev/null
13@@ -0,0 +1,149 @@
14+; Constraint definitions for Ubicom32
15+
16+; Copyright (C) 2009 Free Software Foundation, Inc.
17+; Contributed by Ubicom, Inc.
18+
19+; This file is part of GCC.
20+
21+; GCC is free software; you can redistribute it and/or modify it
22+; under the terms of the GNU General Public License as published
23+; by the Free Software Foundation; either version 3, or (at your
24+; option) any later version.
25+
26+; GCC is distributed in the hope that it will be useful, but WITHOUT
27+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
28+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
29+; License for more details.
30+
31+; You should have received a copy of the GNU General Public License
32+; along with GCC; see the file COPYING3. If not see
33+; <http://www.gnu.org/licenses/>.
34+
35+(define_register_constraint "a" "ALL_ADDRESS_REGS"
36+ "An An register.")
37+
38+(define_register_constraint "d" "DATA_REGS"
39+ "A Dn register.")
40+
41+(define_register_constraint "h" "ACC_REGS"
42+ "An accumulator register.")
43+
44+(define_register_constraint "l" "ACC_LO_REGS"
45+ "An accn_lo register.")
46+
47+(define_register_constraint "Z" "FDPIC_REG"
48+ "The FD-PIC GOT pointer: A0.")
49+
50+(define_constraint "I"
51+ "An 8-bit signed constant value."
52+ (and (match_code "const_int")
53+ (match_test "(ival >= -128) && (ival <= 127)")))
54+
55+(define_constraint "Q"
56+ "An 8-bit signed constant value represented as unsigned."
57+ (and (match_code "const_int")
58+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
59+
60+(define_constraint "R"
61+ "An 8-bit signed constant value represented as unsigned."
62+ (and (match_code "const_int")
63+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
64+
65+(define_constraint "J"
66+ "A 7-bit unsigned constant value."
67+ (and (match_code "const_int")
68+ (match_test "(ival >= 0) && (ival <= 127)")))
69+
70+(define_constraint "K"
71+ "A 7-bit unsigned constant value shifted << 1."
72+ (and (match_code "const_int")
73+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
74+
75+(define_constraint "L"
76+ "A 7-bit unsigned constant value shifted << 2."
77+ (and (match_code "const_int")
78+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
79+
80+(define_constraint "M"
81+ "A 5-bit unsigned constant value."
82+ (and (match_code "const_int")
83+ (match_test "(ival >= 0) && (ival <= 31)")))
84+
85+(define_constraint "N"
86+ "A signed 16 bit constant value."
87+ (and (match_code "const_int")
88+ (match_test "(ival >= -32768) && (ival <= 32767)")))
89+
90+(define_constraint "O"
91+ "An exact bitmask of contiguous 1 bits starting at bit 0."
92+ (and (match_code "const_int")
93+ (match_test "exact_log2 (ival + 1) != -1")))
94+
95+(define_constraint "P"
96+ "A 7-bit negative constant value shifted << 2."
97+ (and (match_code "const_int")
98+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
99+
100+(define_constraint "S"
101+ "A symbolic reference."
102+ (match_code "symbol_ref"))
103+
104+(define_constraint "Y"
105+ "An FD-PIC symbolic reference."
106+ (and (match_test "TARGET_FDPIC")
107+ (match_test "GET_CODE (op) == UNSPEC")
108+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
109+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
110+
111+(define_memory_constraint "T1"
112+ "A memory operand that can be used for .1 instruction."
113+ (and (match_test "memory_operand (op, GET_MODE(op))")
114+ (match_test "GET_MODE (op) == QImode")))
115+
116+(define_memory_constraint "T2"
117+ "A memory operand that can be used for .2 instruction."
118+ (and (match_test "memory_operand (op, GET_MODE(op))")
119+ (match_test "GET_MODE (op) == HImode")))
120+
121+(define_memory_constraint "T4"
122+ "A memory operand that can be used for .4 instruction."
123+ (and (match_test "memory_operand (op, GET_MODE(op))")
124+ (ior (match_test "GET_MODE (op) == SImode")
125+ (match_test "GET_MODE (op) == DImode")
126+ (match_test "GET_MODE (op) == SFmode"))))
127+
128+(define_memory_constraint "U1"
129+ "An offsettable memory operand that can be used for .1 instruction."
130+ (and (match_test "memory_operand (op, GET_MODE(op))")
131+ (match_test "GET_MODE (op) == QImode")
132+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
133+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
134+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
135+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
136+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
137+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
138+
139+(define_memory_constraint "U2"
140+ "An offsettable memory operand that can be used for .2 instruction."
141+ (and (match_test "memory_operand (op, GET_MODE(op))")
142+ (match_test "GET_MODE (op) == HImode")
143+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
144+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
145+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
146+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
147+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
148+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
149+
150+(define_memory_constraint "U4"
151+ "An offsettable memory operand that can be used for .4 instruction."
152+ (and (match_test "memory_operand (op, GET_MODE(op))")
153+ (ior (match_test "GET_MODE (op) == SImode")
154+ (match_test "GET_MODE (op) == DImode")
155+ (match_test "GET_MODE (op) == SFmode"))
156+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
157+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
158+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
159+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
160+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
161+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
162+
163--- /dev/null
164@@ -0,0 +1,54 @@
165+/* Specialized code needed to support construction and destruction of
166+ file-scope objects in C++ and Java code, and to support exception handling.
167+ Copyright (C) 1999 Free Software Foundation, Inc.
168+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
169+
170+This file is part of GCC.
171+
172+GCC is free software; you can redistribute it and/or modify
173+it under the terms of the GNU General Public License as published by
174+the Free Software Foundation; either version 2, or (at your option)
175+any later version.
176+
177+GCC is distributed in the hope that it will be useful,
178+but WITHOUT ANY WARRANTY; without even the implied warranty of
179+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
180+GNU General Public License for more details.
181+
182+You should have received a copy of the GNU General Public License
183+along with GCC; see the file COPYING. If not, write to
184+the Free Software Foundation, 59 Temple Place - Suite 330,
185+Boston, MA 02111-1307, USA. */
186+
187+/* As a special exception, if you link this library with files
188+ compiled with GCC to produce an executable, this does not cause
189+ the resulting executable to be covered by the GNU General Public License.
190+ This exception does not however invalidate any other reasons why
191+ the executable file might be covered by the GNU General Public License. */
192+
193+/*
194+ * This file just supplies function prologues for the .init and .fini
195+ * sections. It is linked in before crtbegin.o.
196+ */
197+ .file "crti.o"
198+ .ident "GNU C crti.o"
199+
200+ .section .init
201+ .align 2
202+ .globl _init
203+ .type _init, @function
204+_init:
205+ move.4 -4(sp)++, a5
206+#ifdef __UBICOM32_FDPIC__
207+ move.4 -4(sp)++, a0
208+#endif
209+
210+ .section .fini
211+ .align 2
212+ .globl _fini
213+ .type _fini, @function
214+_fini:
215+ move.4 -4(sp)++, a5
216+#ifdef __UBICOM32_FDPIC__
217+ move.4 -4(sp)++, a0
218+#endif
219--- /dev/null
220@@ -0,0 +1,47 @@
221+/* Specialized code needed to support construction and destruction of
222+ file-scope objects in C++ and Java code, and to support exception handling.
223+ Copyright (C) 1999 Free Software Foundation, Inc.
224+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
225+
226+This file is part of GCC.
227+
228+GCC is free software; you can redistribute it and/or modify
229+it under the terms of the GNU General Public License as published by
230+the Free Software Foundation; either version 2, or (at your option)
231+any later version.
232+
233+GCC is distributed in the hope that it will be useful,
234+but WITHOUT ANY WARRANTY; without even the implied warranty of
235+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
236+GNU General Public License for more details.
237+
238+You should have received a copy of the GNU General Public License
239+along with GCC; see the file COPYING. If not, write to
240+the Free Software Foundation, 59 Temple Place - Suite 330,
241+Boston, MA 02111-1307, USA. */
242+
243+/* As a special exception, if you link this library with files
244+ compiled with GCC to produce an executable, this does not cause
245+ the resulting executable to be covered by the GNU General Public License.
246+ This exception does not however invalidate any other reasons why
247+ the executable file might be covered by the GNU General Public License. */
248+
249+/*
250+ * This file supplies function epilogues for the .init and .fini sections.
251+ * It is linked in after all other files.
252+ */
253+
254+ .file "crtn.o"
255+ .ident "GNU C crtn.o"
256+
257+ .section .init
258+#ifdef __UBICOM32_FDPIC__
259+ move.4 a0, (sp)4++
260+#endif
261+ ret (sp)4++
262+
263+ .section .fini
264+#ifdef __UBICOM32_FDPIC__
265+ move.4 a0, (sp)4++
266+#endif
267+ ret (sp)4++
268--- /dev/null
269@@ -0,0 +1,29 @@
270+#undef STARTFILE_SPEC
271+#define STARTFILE_SPEC "\
272+%{msim:%{!shared:crt0%O%s}} \
273+crti%O%s crtbegin%O%s"
274+
275+#undef ENDFILE_SPEC
276+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
277+
278+#ifdef __UBICOM32_FDPIC__
279+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
280+ asm (SECTION_OP); \
281+ asm ("move.4 a0, 0(sp);\n\t" \
282+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
283+ asm (TEXT_SECTION_ASM_OP);
284+#endif
285+
286+#undef SUBTARGET_DRIVER_SELF_SPECS
287+#define SUBTARGET_DRIVER_SELF_SPECS \
288+ "%{mfdpic:-msim} "
289+
290+#define NO_IMPLICIT_EXTERN_C
291+
292+/*
293+ * We need this to compile crtbegin/crtend. This should really be picked
294+ * up from elfos.h but at the moment including elfos.h causes other more
295+ * serous linker issues.
296+ */
297+#define INIT_SECTION_ASM_OP "\t.section\t.init"
298+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
299--- /dev/null
300@@ -0,0 +1,80 @@
301+/* Definitions of target machine for Ubicom32-uclinux
302+
303+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
304+ 2009 Free Software Foundation, Inc.
305+ Contributed by Ubicom, Inc.
306+
307+ This file is part of GCC.
308+
309+ GCC is free software; you can redistribute it and/or modify it
310+ under the terms of the GNU General Public License as published
311+ by the Free Software Foundation; either version 3, or (at your
312+ option) any later version.
313+
314+ GCC is distributed in the hope that it will be useful, but WITHOUT
315+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
316+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
317+ License for more details.
318+
319+ You should have received a copy of the GNU General Public License
320+ along with GCC; see the file COPYING3. If not see
321+ <http://www.gnu.org/licenses/>. */
322+
323+/* Don't assume anything about the header files. */
324+#define NO_IMPLICIT_EXTERN_C
325+
326+#undef LIB_SPEC
327+#define LIB_SPEC \
328+ "%{pthread:-lpthread} " \
329+ "-lc"
330+
331+#undef LINK_GCC_C_SEQUENCE_SPEC
332+#define LINK_GCC_C_SEQUENCE_SPEC \
333+ "%{static:--start-group} %G %L %{static:--end-group} " \
334+ "%{!static: %G}"
335+
336+#undef STARTFILE_SPEC
337+#define STARTFILE_SPEC \
338+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
339+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
340+
341+#undef ENDFILE_SPEC
342+#define ENDFILE_SPEC \
343+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
344+
345+/* taken from linux.h */
346+/* The GNU C++ standard library requires that these macros be defined. */
347+#undef CPLUSPLUS_CPP_SPEC
348+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
349+
350+#define TARGET_OS_CPP_BUILTINS() \
351+ do { \
352+ builtin_define_std ("__UBICOM32__"); \
353+ builtin_define_std ("__ubicom32__"); \
354+ builtin_define ("__gnu_linux__"); \
355+ builtin_define_std ("linux"); \
356+ builtin_define_std ("unix"); \
357+ builtin_assert ("system=linux"); \
358+ builtin_assert ("system=unix"); \
359+ builtin_assert ("system=posix"); \
360+ } while (0)
361+
362+#define OBJECT_FORMAT_ELF
363+
364+
365+#undef DRIVER_SELF_SPECS
366+#define DRIVER_SELF_SPECS \
367+ "%{!mno-fdpic:-mfdpic}"
368+
369+#undef LINK_SPEC
370+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
371+ %{static:-dn -Bstatic} \
372+ %{shared:-G -Bdynamic} \
373+ %{!shared: %{!static: \
374+ %{rdynamic:-export-dynamic} \
375+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
376+ %{static}} "
377+
378+/*
379+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
380+*/
381--- /dev/null
382@@ -0,0 +1,327 @@
383+; Predicate definitions for Ubicom32.
384+
385+; Copyright (C) 2009 Free Software Foundation, Inc.
386+; Contributed by Ubicom, Inc.
387+
388+; This file is part of GCC.
389+
390+; GCC is free software; you can redistribute it and/or modify it
391+; under the terms of the GNU General Public License as published
392+; by the Free Software Foundation; either version 3, or (at your
393+; option) any later version.
394+
395+; GCC is distributed in the hope that it will be useful, but WITHOUT
396+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
397+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
398+; License for more details.
399+
400+; You should have received a copy of the GNU General Public License
401+; along with GCC; see the file COPYING3. If not see
402+; <http://www.gnu.org/licenses/>.
403+
404+(define_predicate "ubicom32_move_operand"
405+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
406+{
407+ if (CONST_INT_P (op))
408+ return true;
409+
410+ if (GET_CODE (op) == CONST_DOUBLE)
411+ return true;
412+
413+ if (GET_CODE (op) == CONST)
414+ return memory_address_p (mode, op);
415+
416+ if (GET_MODE (op) != mode)
417+ return false;
418+
419+ if (MEM_P (op))
420+ return memory_address_p (mode, XEXP (op, 0));
421+
422+ if (GET_CODE (op) == SUBREG) {
423+ op = SUBREG_REG (op);
424+
425+ if (REG_P (op))
426+ return true;
427+
428+ if (! MEM_P (op))
429+ return false;
430+
431+ /* Paradoxical SUBREG. */
432+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
433+ return false;
434+
435+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
436+ }
437+
438+ return register_operand (op, mode);
439+})
440+
441+;; Returns true if OP is either a symbol reference or a sum of a
442+;; symbol reference and a constant.
443+
444+(define_predicate "ubicom32_symbolic_address_operand"
445+ (match_code "symbol_ref, label_ref, const")
446+{
447+ switch (GET_CODE (op))
448+ {
449+ case SYMBOL_REF:
450+ case LABEL_REF:
451+ return true;
452+
453+ case CONST:
454+ op = XEXP (op, 0);
455+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
456+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
457+ && CONST_INT_P (XEXP (op, 1)));
458+
459+ default:
460+ return false;
461+ }
462+})
463+
464+;; Return true if operand is the uClinux FD-PIC register.
465+
466+(define_predicate "ubicom32_fdpic_operand"
467+ (match_code "reg")
468+{
469+ if (! TARGET_FDPIC)
470+ return false;
471+
472+ if (!REG_P (op))
473+ return false;
474+
475+ if (GET_MODE (op) != mode && mode != VOIDmode)
476+ return false;
477+
478+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
479+ return false;
480+
481+ return true;
482+})
483+
484+(define_predicate "ubicom32_fdpic_got_offset_operand"
485+ (match_code "unspec")
486+{
487+ if (! TARGET_FDPIC)
488+ return false;
489+
490+ if (GET_CODE (op) != UNSPEC)
491+ return false;
492+
493+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
494+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
495+ return false;
496+
497+ return true;
498+})
499+
500+(define_predicate "ubicom32_arith_operand"
501+ (match_code "subreg, reg, const_int, lo_sum, mem")
502+{
503+ return (ubicom32_move_operand (op, mode)
504+ && ! ubicom32_symbolic_address_operand (op, mode)
505+ && (! CONST_INT_P (op)
506+ || satisfies_constraint_I (op)));
507+})
508+
509+(define_predicate "ubicom32_arith_operand_dot1"
510+ (match_code "subreg, reg, const_int, lo_sum, mem")
511+{
512+ return (ubicom32_move_operand (op, mode)
513+ && ! ubicom32_symbolic_address_operand (op, mode)
514+ && (! CONST_INT_P (op)
515+ || satisfies_constraint_Q (op)));
516+})
517+
518+(define_predicate "ubicom32_arith_operand_dot2"
519+ (match_code "subreg, reg, const_int, lo_sum, mem")
520+{
521+ return (ubicom32_move_operand (op, mode)
522+ && ! ubicom32_symbolic_address_operand (op, mode)
523+ && (! CONST_INT_P (op)
524+ || satisfies_constraint_R (op)));
525+})
526+
527+(define_predicate "ubicom32_compare_operand"
528+ (match_code "subreg, reg, const_int, lo_sum, mem")
529+{
530+ return (ubicom32_move_operand (op, mode)
531+ && ! ubicom32_symbolic_address_operand (op, mode)
532+ && (! CONST_INT_P (op)
533+ || satisfies_constraint_N (op)));
534+})
535+
536+(define_predicate "ubicom32_compare_operator"
537+ (match_code "compare"))
538+
539+(define_predicate "ubicom32_and_or_si3_operand"
540+ (match_code "subreg, reg, const_int, lo_sum, mem")
541+{
542+ return (ubicom32_arith_operand (op, mode)
543+ || (CONST_INT_P (op)
544+ && ((exact_log2 (INTVAL (op) + 1) != -1
545+ && exact_log2 (INTVAL (op) + 1) <= 31)
546+ || (exact_log2 (INTVAL (op)) != -1
547+ && exact_log2 (INTVAL (op)) <= 31)
548+ || (exact_log2 (~INTVAL (op)) != -1
549+ && exact_log2 (~INTVAL (op)) <= 31))));
550+})
551+
552+(define_predicate "ubicom32_and_or_hi3_operand"
553+ (match_code "subreg, reg, const_int, lo_sum, mem")
554+{
555+ return (ubicom32_arith_operand (op, mode)
556+ || (CONST_INT_P (op)
557+ && exact_log2 (INTVAL (op) + 1) != -1
558+ && exact_log2 (INTVAL (op) + 1) <= 15));
559+})
560+
561+(define_predicate "ubicom32_mem_or_address_register_operand"
562+ (match_code "subreg, reg, mem")
563+{
564+ unsigned int regno;
565+
566+ if (MEM_P (op)
567+ && memory_operand (op, mode))
568+ return true;
569+
570+ if (REG_P (op))
571+ regno = REGNO (op);
572+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
573+ {
574+ int offset;
575+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
576+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
577+ else
578+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
579+ GET_MODE (SUBREG_REG (op)),
580+ SUBREG_BYTE (op),
581+ GET_MODE (op));
582+ regno = REGNO (SUBREG_REG (op)) + offset;
583+ }
584+ else
585+ return false;
586+
587+ return (regno >= FIRST_PSEUDO_REGISTER
588+ || REGNO_REG_CLASS (regno) == FDPIC_REG
589+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
590+})
591+
592+(define_predicate "ubicom32_data_register_operand"
593+ (match_code "subreg, reg")
594+{
595+ unsigned int regno;
596+
597+ if (REG_P (op))
598+ regno = REGNO (op);
599+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
600+ {
601+ int offset;
602+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
603+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
604+ else
605+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
606+ GET_MODE (SUBREG_REG (op)),
607+ SUBREG_BYTE (op),
608+ GET_MODE (op));
609+ regno = REGNO (SUBREG_REG (op)) + offset;
610+ }
611+ else
612+ return false;
613+
614+ return ((regno >= FIRST_PSEUDO_REGISTER
615+ && regno != REGNO (virtual_stack_vars_rtx))
616+ || REGNO_REG_CLASS (regno) == DATA_REGS);
617+})
618+
619+(define_predicate "ubicom32_address_register_operand"
620+ (match_code "subreg, reg")
621+{
622+ unsigned int regno;
623+
624+ if (REG_P (op))
625+ regno = REGNO (op);
626+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
627+ {
628+ int offset;
629+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
630+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
631+ else
632+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
633+ GET_MODE (SUBREG_REG (op)),
634+ SUBREG_BYTE (op),
635+ GET_MODE (op));
636+ regno = REGNO (SUBREG_REG (op)) + offset;
637+ }
638+ else
639+ return false;
640+
641+ return (regno >= FIRST_PSEUDO_REGISTER
642+ || REGNO_REG_CLASS (regno) == FDPIC_REG
643+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
644+})
645+
646+(define_predicate "ubicom32_acc_lo_register_operand"
647+ (match_code "subreg, reg")
648+{
649+ unsigned int regno;
650+
651+ if (REG_P (op))
652+ regno = REGNO (op);
653+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
654+ {
655+ int offset;
656+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
657+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
658+ else
659+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
660+ GET_MODE (SUBREG_REG (op)),
661+ SUBREG_BYTE (op),
662+ GET_MODE (op));
663+ regno = REGNO (SUBREG_REG (op)) + offset;
664+ }
665+ else
666+ return false;
667+
668+ return ((regno >= FIRST_PSEUDO_REGISTER
669+ && regno != REGNO (virtual_stack_vars_rtx))
670+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
671+})
672+
673+(define_predicate "ubicom32_acc_hi_register_operand"
674+ (match_code "subreg, reg")
675+{
676+ unsigned int regno;
677+
678+ if (REG_P (op))
679+ regno = REGNO (op);
680+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
681+ {
682+ int offset;
683+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
684+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
685+ else
686+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
687+ GET_MODE (SUBREG_REG (op)),
688+ SUBREG_BYTE (op),
689+ GET_MODE (op));
690+ regno = REGNO (SUBREG_REG (op)) + offset;
691+ }
692+ else
693+ return false;
694+
695+ return ((regno >= FIRST_PSEUDO_REGISTER
696+ && regno != REGNO (virtual_stack_vars_rtx))
697+ || REGNO_REG_CLASS (regno) == ACC_REGS);
698+})
699+
700+(define_predicate "ubicom32_call_address_operand"
701+ (match_code "symbol_ref, subreg, reg")
702+{
703+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
704+})
705+
706+(define_special_predicate "ubicom32_cc_register_operand"
707+ (and (match_code "reg")
708+ (match_test "REGNO (op) == CC_REGNUM")))
709+
710--- /dev/null
711@@ -0,0 +1,52 @@
712+# Name of assembly file containing libgcc1 functions.
713+# This entry must be present, but it can be empty if the target does
714+# not need any assembler functions to support its code generation.
715+CROSS_LIBGCC1 =
716+
717+# Alternatively if assembler functions *are* needed then define the
718+# entries below:
719+# CROSS_LIBGCC1 = libgcc1-asm.a
720+
721+LIB2FUNCS_EXTRA = \
722+ $(srcdir)/config/udivmodsi4.c \
723+ $(srcdir)/config/divmod.c \
724+ $(srcdir)/config/udivmod.c
725+
726+# If any special flags are necessary when building libgcc2 put them here.
727+#
728+# TARGET_LIBGCC2_CFLAGS =
729+
730+# We want fine grained libraries, so use the new code to build the
731+# floating point emulation libraries.
732+FPBIT = fp-bit.c
733+DPBIT = dp-bit.c
734+
735+fp-bit.c: $(srcdir)/config/fp-bit.c
736+ echo '#define FLOAT' > fp-bit.c
737+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
738+
739+dp-bit.c: $(srcdir)/config/fp-bit.c
740+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
741+
742+# Commented out to speed up compiler development!
743+#
744+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
745+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
746+
747+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
748+MULTILIB_OPTIONS += mfdpic
749+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
750+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
751+
752+# Assemble startup files.
753+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
754+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
755+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
756+
757+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
758+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
759+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
760+
761+# these parts are required because uClibc ldso needs them to link.
762+# they are not in the specfile so they will not be included automatically.
763+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
764--- /dev/null
765@@ -0,0 +1,35 @@
766+# Name of assembly file containing libgcc1 functions.
767+# This entry must be present, but it can be empty if the target does
768+# not need any assembler functions to support its code generation.
769+CROSS_LIBGCC1 =
770+
771+# Alternatively if assembler functions *are* needed then define the
772+# entries below:
773+# CROSS_LIBGCC1 = libgcc1-asm.a
774+
775+LIB2FUNCS_EXTRA = \
776+ $(srcdir)/config/udivmodsi4.c \
777+ $(srcdir)/config/divmod.c \
778+ $(srcdir)/config/udivmod.c
779+
780+# If any special flags are necessary when building libgcc2 put them here.
781+#
782+# TARGET_LIBGCC2_CFLAGS =
783+
784+# We want fine grained libraries, so use the new code to build the
785+# floating point emulation libraries.
786+FPBIT = fp-bit.c
787+DPBIT = dp-bit.c
788+
789+fp-bit.c: $(srcdir)/config/fp-bit.c
790+ echo '#define FLOAT' > fp-bit.c
791+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
792+
793+dp-bit.c: $(srcdir)/config/fp-bit.c
794+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
795+
796+# We only support v3 and v4 ISAs for uClinux.
797+
798+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
799+
800+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
801--- /dev/null
802@@ -0,0 +1,35 @@
803+# Name of assembly file containing libgcc1 functions.
804+# This entry must be present, but it can be empty if the target does
805+# not need any assembler functions to support its code generation.
806+CROSS_LIBGCC1 =
807+
808+# Alternatively if assembler functions *are* needed then define the
809+# entries below:
810+# CROSS_LIBGCC1 = libgcc1-asm.a
811+
812+LIB2FUNCS_EXTRA = \
813+ $(srcdir)/config/udivmodsi4.c \
814+ $(srcdir)/config/divmod.c \
815+ $(srcdir)/config/udivmod.c
816+
817+# If any special flags are necessary when building libgcc2 put them here.
818+#
819+# TARGET_LIBGCC2_CFLAGS =
820+
821+# We want fine grained libraries, so use the new code to build the
822+# floating point emulation libraries.
823+FPBIT = fp-bit.c
824+DPBIT = dp-bit.c
825+
826+fp-bit.c: $(srcdir)/config/fp-bit.c
827+ echo '#define FLOAT' > fp-bit.c
828+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
829+
830+dp-bit.c: $(srcdir)/config/fp-bit.c
831+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
832+
833+# We only support v3 and v4 ISAs for uClinux.
834+
835+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
836+
837+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
838--- /dev/null
839@@ -0,0 +1,30 @@
840+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
841+ Copyright (C) 2009 Free Software Foundation, Inc.
842+ Contributed by Ubicom, Inc.
843+
844+ This file is part of GCC.
845+
846+ GCC is free software; you can redistribute it and/or modify it
847+ under the terms of the GNU General Public License as published
848+ by the Free Software Foundation; either version 3, or (at your
849+ option) any later version.
850+
851+ GCC is distributed in the hope that it will be useful, but WITHOUT
852+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
853+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
854+ License for more details.
855+
856+ You should have received a copy of the GNU General Public License
857+ along with GCC; see the file COPYING3. If not see
858+ <http://www.gnu.org/licenses/>. */
859+
860+/* Some insns set all condition code flags, some only set the Z and N flags, and
861+ some only set the Z flag. */
862+
863+CC_MODE (CCW);
864+CC_MODE (CCWZN);
865+CC_MODE (CCWZ);
866+CC_MODE (CCS);
867+CC_MODE (CCSZN);
868+CC_MODE (CCSZ);
869+
870--- /dev/null
871@@ -0,0 +1,84 @@
872+/* Function prototypes for Ubicom IP3000.
873+
874+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
875+ 2009 Free Software Foundation, Inc.
876+ Contributed by Ubicom, Inc.
877+
878+ This file is part of GNU CC.
879+
880+ GNU CC is free software; you can redistribute it and/or modify it under
881+ the terms of the GNU General Public License as published by the Free
882+ Software Foundation; either version 2, or (at your option) any later
883+ version.
884+
885+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
886+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
887+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
888+ for more details.
889+
890+ You should have received a copy of the GNU General Public License along
891+ with GNU CC; see the file COPYING. If not, write to the Free Software
892+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
893+
894+#ifdef RTX_CODE
895+
896+#ifdef TREE_CODE
897+extern void ubicom32_va_start (tree, rtx);
898+#endif /* TREE_CODE */
899+
900+extern void ubicom32_print_operand (FILE *, rtx, int);
901+extern void ubicom32_print_operand_address (FILE *, rtx);
902+
903+extern void ubicom32_conditional_register_usage (void);
904+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
905+extern int ubicom32_regno_ok_for_index_p (int, int);
906+extern void ubicom32_expand_movsi (rtx *);
907+extern void ubicom32_expand_addsi3 (rtx *);
908+extern int ubicom32_emit_mult_sequence (rtx *);
909+extern void ubicom32_emit_move_const_int (rtx, rtx);
910+extern bool ubicom32_legitimate_constant_p (rtx);
911+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
912+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
913+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
914+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
915+extern int ubicom32_mode_dependent_address_p (rtx);
916+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
917+extern void ubicom32_expand_eh_return (rtx *);
918+extern void ubicom32_expand_call_fdpic (rtx *);
919+extern void ubicom32_expand_call_value_fdpic (rtx *);
920+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
921+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
922+extern int ubicom32_shiftable_const_int (int);
923+#endif /* RTX_CODE */
924+
925+#ifdef TREE_CODE
926+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
927+ tree fntype,
928+ struct rtx_def *libname,
929+ int indirect);
930+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
931+ enum machine_mode, tree, int);
932+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
933+ enum machine_mode,
934+ tree, int);
935+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
936+ enum machine_mode, tree, int);
937+extern struct rtx_def *ubicom32_va_arg (tree, tree);
938+extern int ubicom32_reg_parm_stack_space (tree);
939+#endif /* TREE_CODE */
940+
941+extern struct rtx_def * ubicom32_builtin_saveregs (void);
942+extern void asm_file_start (FILE *);
943+extern void ubicom32_expand_prologue (void);
944+extern void ubicom32_expand_epilogue (void);
945+extern int ubicom32_initial_elimination_offset (int, int);
946+extern int ubicom32_regno_ok_for_base_p (int, int);
947+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
948+extern int ubicom32_can_use_return_insn_p (void);
949+extern rtx ubicom32_return_addr_rtx (int, rtx);
950+extern void ubicom32_optimization_options (int, int);
951+extern void ubicom32_override_options (void);
952+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
953+
954+extern int ubicom32_reorg_completed;
955+
956--- /dev/null
957@@ -0,0 +1,2881 @@
958+/* Subroutines for insn-output.c for Ubicom32
959+
960+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
961+ 2009 Free Software Foundation, Inc.
962+ Contributed by Ubicom, Inc.
963+
964+ This file is part of GCC.
965+
966+ GCC is free software; you can redistribute it and/or modify it
967+ under the terms of the GNU General Public License as published
968+ by the Free Software Foundation; either version 3, or (at your
969+ option) any later version.
970+
971+ GCC is distributed in the hope that it will be useful, but WITHOUT
972+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
973+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
974+ License for more details.
975+
976+ You should have received a copy of the GNU General Public License
977+ along with GCC; see the file COPYING3. If not see
978+ <http://www.gnu.org/licenses/>. */
979+
980+#include "config.h"
981+#include "system.h"
982+#include "coretypes.h"
983+#include "tm.h"
984+#include "rtl.h"
985+#include "tree.h"
986+#include "regs.h"
987+#include "hard-reg-set.h"
988+#include "real.h"
989+#include "insn-config.h"
990+#include "conditions.h"
991+#include "insn-flags.h"
992+#include "output.h"
993+#include "insn-attr.h"
994+#include "insn-codes.h"
995+#include "flags.h"
996+#include "recog.h"
997+#include "expr.h"
998+#include "function.h"
999+#include "obstack.h"
1000+#include "toplev.h"
1001+#include "tm_p.h"
1002+#include "tm-constrs.h"
1003+#include "basic-block.h"
1004+#include "integrate.h"
1005+#include "target.h"
1006+#include "target-def.h"
1007+#include "reload.h"
1008+#include "df.h"
1009+#include "langhooks.h"
1010+#include "optabs.h"
1011+
1012+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
1013+static void ubicom32_layout_frame (void);
1014+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
1015+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
1016+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
1017+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
1018+ unsigned int *);
1019+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
1020+ enum machine_mode);
1021+static int ubicom32_naked_function_p (void);
1022+static void ubicom32_machine_dependent_reorg (void);
1023+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
1024+static void ubicom32_asm_init_sections (void);
1025+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
1026+ bool);
1027+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1028+ enum machine_mode mode, const_tree type,
1029+ bool named ATTRIBUTE_UNUSED);
1030+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1031+ enum machine_mode mode, const_tree type,
1032+ bool named ATTRIBUTE_UNUSED);
1033+
1034+static bool ubicom32_return_in_memory (const_tree type,
1035+ const_tree fntype ATTRIBUTE_UNUSED);
1036+static bool ubicom32_is_base_reg (rtx, int);
1037+static void ubicom32_init_builtins (void);
1038+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1039+static tree ubicom32_fold_builtin (tree, tree, bool);
1040+static int ubicom32_get_valid_offset_mask (enum machine_mode);
1041+static bool ubicom32_cannot_force_const_mem (rtx);
1042+
1043+/* Case values threshold */
1044+int ubicom32_case_values_threshold = 6;
1045+
1046+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
1047+int ubicom32_v3 = 1;
1048+
1049+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
1050+int ubicom32_v4 = 1;
1051+
1052+/* Valid attributes:
1053+ naked - don't generate function prologue/epilogue and `ret' command. */
1054+const struct attribute_spec ubicom32_attribute_table[] =
1055+{
1056+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1057+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
1058+ { NULL, 0, 0, false, false, false, NULL }
1059+};
1060+
1061+#undef TARGET_ASM_FUNCTION_PROLOGUE
1062+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
1063+
1064+#undef TARGET_ASM_FUNCTION_EPILOGUE
1065+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
1066+
1067+#undef TARGET_ATTRIBUTE_TABLE
1068+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
1069+
1070+/* All addresses cost the same amount. */
1071+#undef TARGET_ADDRESS_COST
1072+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1073+
1074+#undef TARGET_RTX_COSTS
1075+#define TARGET_RTX_COSTS ubicom32_rtx_costs
1076+
1077+#undef TARGET_FIXED_CONDITION_CODE_REGS
1078+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
1079+
1080+#undef TARGET_CC_MODES_COMPATIBLE
1081+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
1082+
1083+#undef TARGET_MACHINE_DEPENDENT_REORG
1084+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
1085+
1086+#undef TARGET_ASM_INTEGER
1087+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
1088+
1089+#undef TARGET_ASM_INIT_SECTIONS
1090+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
1091+
1092+#undef TARGET_ARG_PARTIAL_BYTES
1093+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
1094+
1095+#undef TARGET_PASS_BY_REFERENCE
1096+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
1097+
1098+#undef TARGET_CALLEE_COPIES
1099+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
1100+
1101+#undef TARGET_RETURN_IN_MEMORY
1102+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
1103+
1104+#undef TARGET_INIT_BUILTINS
1105+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
1106+
1107+#undef TARGET_EXPAND_BUILTIN
1108+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
1109+
1110+#undef TARGET_FOLD_BUILTIN
1111+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
1112+
1113+#undef TARGET_CANNOT_FORCE_CONST_MEM
1114+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
1115+
1116+struct gcc_target targetm = TARGET_INITIALIZER;
1117+
1118+static char save_regs[FIRST_PSEUDO_REGISTER];
1119+static int nregs;
1120+static int frame_size;
1121+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
1122+int ubicom32_can_use_calli_to_ret;
1123+
1124+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
1125+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
1126+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
1127+
1128+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
1129+ must report the mode of the memory reference from PRINT_OPERAND to
1130+ PRINT_OPERAND_ADDRESS. */
1131+enum machine_mode output_memory_reference_mode;
1132+
1133+/* Flag for some split insns from the ubicom32.md. */
1134+int ubicom32_reorg_completed;
1135+
1136+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
1137+{
1138+ DATA_REGS,
1139+ DATA_REGS,
1140+ DATA_REGS,
1141+ DATA_REGS,
1142+ DATA_REGS,
1143+ DATA_REGS,
1144+ DATA_REGS,
1145+ DATA_REGS,
1146+ DATA_REGS,
1147+ DATA_REGS,
1148+ DATA_REGS,
1149+ DATA_REGS,
1150+ DATA_REGS,
1151+ DATA_REGS,
1152+ DATA_REGS,
1153+ DATA_REGS,
1154+ FDPIC_REG,
1155+ ADDRESS_REGS,
1156+ ADDRESS_REGS,
1157+ ADDRESS_REGS,
1158+ ADDRESS_REGS,
1159+ ADDRESS_REGS,
1160+ ADDRESS_REGS,
1161+ ADDRESS_REGS,
1162+ ACC_REGS,
1163+ ACC_LO_REGS,
1164+ ACC_REGS,
1165+ ACC_LO_REGS,
1166+ SOURCE3_REG,
1167+ ADDRESS_REGS,
1168+ NO_REGS, /* CC_REG must be NO_REGS */
1169+ SPECIAL_REGS,
1170+ SPECIAL_REGS,
1171+ SPECIAL_REGS,
1172+ SPECIAL_REGS,
1173+ SPECIAL_REGS,
1174+ SPECIAL_REGS,
1175+ SPECIAL_REGS,
1176+ SPECIAL_REGS
1177+};
1178+
1179+rtx ubicom32_compare_op0;
1180+rtx ubicom32_compare_op1;
1181+
1182+/* Handle command line option overrides. */
1183+
1184+void
1185+ubicom32_override_options (void)
1186+{
1187+ flag_pic = 0;
1188+
1189+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
1190+ /* If we have a version 1 architecture then we want to avoid using jump
1191+ tables. */
1192+ ubicom32_case_values_threshold = 30000;
1193+ ubicom32_v3 = 0;
1194+ ubicom32_v4 = 0;
1195+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
1196+ ubicom32_v3 = 0;
1197+ ubicom32_v4 = 0;
1198+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
1199+ ubicom32_v3 = 1;
1200+ ubicom32_v4 = 0;
1201+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
1202+ ubicom32_v3 = 1;
1203+ ubicom32_v4 = 1;
1204+ }
1205+
1206+ /* There is no single unaligned SI op for PIC code. Sometimes we
1207+ need to use ".4byte" and sometimes we need to use ".picptr".
1208+ See ubicom32_assemble_integer for details. */
1209+ if (TARGET_FDPIC)
1210+ targetm.asm_out.unaligned_op.si = 0;
1211+}
1212+
1213+void
1214+ubicom32_conditional_register_usage (void)
1215+{
1216+ /* If we're using the old ipOS ABI we need to make D10 through D13
1217+ caller-clobbered. */
1218+ if (TARGET_IPOS_ABI)
1219+ {
1220+ call_used_regs[D10_REGNUM] = 1;
1221+ call_used_regs[D11_REGNUM] = 1;
1222+ call_used_regs[D12_REGNUM] = 1;
1223+ call_used_regs[D13_REGNUM] = 1;
1224+ }
1225+}
1226+
1227+/* We have some number of optimizations that don't really work for the Ubicom32
1228+ architecture so we deal with them here. */
1229+
1230+void
1231+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
1232+ int size ATTRIBUTE_UNUSED)
1233+{
1234+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
1235+ architecture - it tends to turn things that would happily use pre/post
1236+ increment/decrement into operations involving unecessary loop
1237+ indicies. */
1238+ flag_ivopts = 0;
1239+
1240+ /* We have problems where DSE at the RTL level misses partial stores
1241+ to the stack. For now we disable it to avoid this. */
1242+ flag_dse = 0;
1243+}
1244+
1245+/* Print operand X using operand code CODE to assembly language output file
1246+ FILE. */
1247+
1248+void
1249+ubicom32_print_operand (FILE *file, rtx x, int code)
1250+{
1251+ switch (code)
1252+ {
1253+ case 'A':
1254+ /* Identify the correct accumulator to use. */
1255+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
1256+ fprintf (file, "acc0");
1257+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
1258+ fprintf (file, "acc1");
1259+ else
1260+ abort ();
1261+ break;
1262+
1263+ case 'b':
1264+ case 'B':
1265+ {
1266+ enum machine_mode mode;
1267+
1268+ mode = GET_MODE (XEXP (x, 0));
1269+
1270+ /* These are normal and reversed branches. */
1271+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
1272+ {
1273+ case NE:
1274+ fprintf (file, "ne");
1275+ break;
1276+
1277+ case EQ:
1278+ fprintf (file, "eq");
1279+ break;
1280+
1281+ case GE:
1282+ if (mode == CCSZNmode || mode == CCWZNmode)
1283+ fprintf (file, "pl");
1284+ else
1285+ fprintf (file, "ge");
1286+ break;
1287+
1288+ case GT:
1289+ fprintf (file, "gt");
1290+ break;
1291+
1292+ case LE:
1293+ fprintf (file, "le");
1294+ break;
1295+
1296+ case LT:
1297+ if (mode == CCSZNmode || mode == CCWZNmode)
1298+ fprintf (file, "mi");
1299+ else
1300+ fprintf (file, "lt");
1301+ break;
1302+
1303+ case GEU:
1304+ fprintf (file, "cs");
1305+ break;
1306+
1307+ case GTU:
1308+ fprintf (file, "hi");
1309+ break;
1310+
1311+ case LEU:
1312+ fprintf (file, "ls");
1313+ break;
1314+
1315+ case LTU:
1316+ fprintf (file, "cc");
1317+ break;
1318+
1319+ default:
1320+ abort ();
1321+ }
1322+ }
1323+ break;
1324+
1325+ case 'C':
1326+ /* This is used for the operand to a call instruction;
1327+ if it's a REG, enclose it in parens, else output
1328+ the operand normally. */
1329+ if (REG_P (x))
1330+ {
1331+ fputc ('(', file);
1332+ ubicom32_print_operand (file, x, 0);
1333+ fputc (')', file);
1334+ }
1335+ else
1336+ ubicom32_print_operand (file, x, 0);
1337+ break;
1338+
1339+ case 'd':
1340+ /* Bit operations we need bit numbers. */
1341+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
1342+ break;
1343+
1344+ case 'D':
1345+ /* Bit operations we need bit numbers. */
1346+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
1347+ break;
1348+
1349+ case 'E':
1350+ /* For lea, which we use to add address registers.
1351+ We don't want the '#' on a constant. */
1352+ if (CONST_INT_P (x))
1353+ {
1354+ fprintf (file, "%ld", INTVAL (x));
1355+ break;
1356+ }
1357+ /* FALL THROUGH */
1358+
1359+ default:
1360+ switch (GET_CODE (x))
1361+ {
1362+ case MEM:
1363+ output_memory_reference_mode = GET_MODE (x);
1364+ output_address (XEXP (x, 0));
1365+ break;
1366+
1367+ case PLUS:
1368+ output_address (x);
1369+ break;
1370+
1371+ case REG:
1372+ fprintf (file, "%s", reg_names[REGNO (x)]);
1373+ break;
1374+
1375+ case SUBREG:
1376+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
1377+ break;
1378+
1379+ /* This will only be single precision.... */
1380+ case CONST_DOUBLE:
1381+ {
1382+ unsigned long val;
1383+ REAL_VALUE_TYPE rv;
1384+
1385+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1386+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1387+ fprintf (file, "0x%lx", val);
1388+ break;
1389+ }
1390+
1391+ case CONST_INT:
1392+ case SYMBOL_REF:
1393+ case CONST:
1394+ case LABEL_REF:
1395+ case CODE_LABEL:
1396+ case LO_SUM:
1397+ ubicom32_print_operand_address (file, x);
1398+ break;
1399+
1400+ case HIGH:
1401+ fprintf (file, "#%%hi(");
1402+ ubicom32_print_operand_address (file, XEXP (x, 0));
1403+ fprintf (file, ")");
1404+ break;
1405+
1406+ case UNSPEC:
1407+ switch (XINT (x, 1))
1408+ {
1409+ case UNSPEC_FDPIC_GOT:
1410+ fprintf (file, "#%%got_lo(");
1411+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1412+ fprintf (file, ")");
1413+ break;
1414+
1415+ case UNSPEC_FDPIC_GOT_FUNCDESC:
1416+ fprintf (file, "#%%got_funcdesc_lo(");
1417+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1418+ fprintf (file, ")");
1419+ break;
1420+
1421+ default:
1422+ abort ();
1423+ }
1424+ break;
1425+
1426+ default:
1427+ abort ();
1428+ }
1429+ break;
1430+ }
1431+}
1432+
1433+/* Output assembly language output for the address ADDR to FILE. */
1434+
1435+void
1436+ubicom32_print_operand_address (FILE *file, rtx addr)
1437+{
1438+ switch (GET_CODE (addr))
1439+ {
1440+ case POST_INC:
1441+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1442+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
1443+ break;
1444+
1445+ case PRE_INC:
1446+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
1447+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1448+ fprintf (file, "++");
1449+ break;
1450+
1451+ case POST_DEC:
1452+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1453+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
1454+ break;
1455+
1456+ case PRE_DEC:
1457+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
1458+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1459+ fprintf (file, "++");
1460+ break;
1461+
1462+ case POST_MODIFY:
1463+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1464+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
1465+ break;
1466+
1467+ case PRE_MODIFY:
1468+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
1469+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1470+ fprintf (file, "++");
1471+ break;
1472+
1473+ case REG:
1474+ fputc ('(', file);
1475+ fprintf (file, "%s", reg_names[REGNO (addr)]);
1476+ fputc (')', file);
1477+ break;
1478+
1479+ case PLUS:
1480+ {
1481+ rtx base = XEXP (addr, 0);
1482+ rtx index = XEXP (addr, 1);
1483+
1484+ /* Switch around addresses of the form index * scaling + base. */
1485+ if (! ubicom32_is_base_reg (base, 1))
1486+ {
1487+ rtx tmp = base;
1488+ base = index;
1489+ index = tmp;
1490+ }
1491+
1492+ if (CONST_INT_P (index))
1493+ {
1494+ fprintf (file, "%ld", INTVAL (index));
1495+ fputc ('(', file);
1496+ fputs (reg_names[REGNO (base)], file);
1497+ }
1498+ else if (GET_CODE (index) == MULT
1499+ || REG_P (index))
1500+ {
1501+ if (GET_CODE (index) == MULT)
1502+ index = XEXP (index, 0);
1503+ fputc ('(', file);
1504+ fputs (reg_names[REGNO (base)], file);
1505+ fputc (',', file);
1506+ fputs (reg_names[REGNO (index)], file);
1507+ }
1508+ else
1509+ abort ();
1510+
1511+ fputc (')', file);
1512+ break;
1513+ }
1514+
1515+ case LO_SUM:
1516+ fprintf (file, "%%lo(");
1517+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
1518+ fprintf (file, ")(");
1519+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
1520+ fprintf (file, ")");
1521+ break;
1522+
1523+ case CONST_INT:
1524+ fputc ('#', file);
1525+ output_addr_const (file, addr);
1526+ break;
1527+
1528+ default:
1529+ output_addr_const (file, addr);
1530+ break;
1531+ }
1532+}
1533+
1534+/* X and Y are two things to compare using CODE. Emit the compare insn and
1535+ return the rtx for the cc reg in the proper mode. */
1536+
1537+rtx
1538+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
1539+{
1540+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
1541+ rtx cc_reg;
1542+
1543+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
1544+
1545+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
1546+ gen_rtx_COMPARE (mode, x, y)));
1547+
1548+ return cc_reg;
1549+}
1550+
1551+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1552+ return the mode to be used for the comparison. */
1553+
1554+enum machine_mode
1555+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1556+{
1557+ /* Is this a short compare? */
1558+ if (GET_MODE (x) == QImode
1559+ || GET_MODE (x) == HImode
1560+ || GET_MODE (y) == QImode
1561+ || GET_MODE (y) == HImode)
1562+ {
1563+ switch (op)
1564+ {
1565+ case EQ :
1566+ case NE :
1567+ return CCSZmode;
1568+
1569+ case GE:
1570+ case LT:
1571+ if (y == const0_rtx)
1572+ return CCSZNmode;
1573+
1574+ default :
1575+ return CCSmode;
1576+ }
1577+ }
1578+
1579+ /* We have a word compare. */
1580+ switch (op)
1581+ {
1582+ case EQ :
1583+ case NE :
1584+ return CCWZmode;
1585+
1586+ case GE :
1587+ case LT :
1588+ if (y == const0_rtx)
1589+ return CCWZNmode;
1590+
1591+ default :
1592+ return CCWmode;
1593+ }
1594+}
1595+
1596+/* Return TRUE or FALSE depending on whether the first SET in INSN
1597+ has source and destination with matching CC modes, and that the
1598+ CC mode is at least as constrained as REQ_MODE. */
1599+bool
1600+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
1601+{
1602+ rtx set;
1603+ enum machine_mode set_mode;
1604+
1605+ set = PATTERN (insn);
1606+ if (GET_CODE (set) == PARALLEL)
1607+ set = XVECEXP (set, 0, 0);
1608+ gcc_assert (GET_CODE (set) == SET);
1609+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
1610+
1611+ /* SET_MODE is the mode we have in the instruction. This must either
1612+ be the same or less restrictive that the required mode REQ_MODE. */
1613+ set_mode = GET_MODE (SET_DEST (set));
1614+
1615+ switch (req_mode)
1616+ {
1617+ case CCSZmode:
1618+ if (set_mode != CCSZmode)
1619+ return 0;
1620+ break;
1621+
1622+ case CCSZNmode:
1623+ if (set_mode != CCSZmode
1624+ && set_mode != CCSZNmode)
1625+ return 0;
1626+ break;
1627+
1628+ case CCSmode:
1629+ if (set_mode != CCSmode
1630+ && set_mode != CCSZmode
1631+ && set_mode != CCSZNmode)
1632+ return 0;
1633+ break;
1634+
1635+ case CCWZmode:
1636+ if (set_mode != CCWZmode)
1637+ return 0;
1638+ break;
1639+
1640+ case CCWZNmode:
1641+ if (set_mode != CCWZmode
1642+ && set_mode != CCWZNmode)
1643+ return 0;
1644+ break;
1645+
1646+ case CCWmode:
1647+ if (set_mode != CCWmode
1648+ && set_mode != CCWZmode
1649+ && set_mode != CCWZNmode)
1650+ return 0;
1651+ break;
1652+
1653+ default:
1654+ gcc_unreachable ();
1655+ }
1656+
1657+ return (GET_MODE (SET_SRC (set)) == set_mode);
1658+}
1659+
1660+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1661+ that we can implement more efficiently. */
1662+
1663+void
1664+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
1665+{
1666+ /* If we have a REG and a MEM then compare the MEM with the REG and not
1667+ the other way round. */
1668+ if (REG_P (*op0) && MEM_P (*op1))
1669+ {
1670+ rtx tem = *op0;
1671+ *op0 = *op1;
1672+ *op1 = tem;
1673+ *code = swap_condition (*code);
1674+ return;
1675+ }
1676+
1677+ /* If we have a REG and a CONST_INT then we may want to reverse things
1678+ if the constant can be represented as an "I" constraint. */
1679+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
1680+ {
1681+ rtx tem = *op0;
1682+ *op0 = *op1;
1683+ *op1 = tem;
1684+ *code = swap_condition (*code);
1685+ return;
1686+ }
1687+}
1688+
1689+/* Return the fixed registers used for condition codes. */
1690+
1691+static bool
1692+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
1693+{
1694+ *p1 = CC_REGNUM;
1695+ *p2 = INVALID_REGNUM;
1696+
1697+ return true;
1698+}
1699+
1700+/* If two condition code modes are compatible, return a condition code
1701+ mode which is compatible with both. Otherwise, return
1702+ VOIDmode. */
1703+
1704+static enum machine_mode
1705+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
1706+{
1707+ if (m1 == m2)
1708+ return m1;
1709+
1710+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
1711+ return VOIDmode;
1712+
1713+ switch (m1)
1714+ {
1715+ case CCWmode:
1716+ if (m2 == CCWZNmode || m2 == CCWZmode)
1717+ return m1;
1718+
1719+ return VOIDmode;
1720+
1721+ case CCWZNmode:
1722+ if (m2 == CCWmode)
1723+ return m2;
1724+
1725+ if (m2 == CCWZmode)
1726+ return m1;
1727+
1728+ return VOIDmode;
1729+
1730+ case CCWZmode:
1731+ if (m2 == CCWmode || m2 == CCWZNmode)
1732+ return m2;
1733+
1734+ return VOIDmode;
1735+
1736+ case CCSmode:
1737+ if (m2 == CCSZNmode || m2 == CCSZmode)
1738+ return m1;
1739+
1740+ return VOIDmode;
1741+
1742+ case CCSZNmode:
1743+ if (m2 == CCSmode)
1744+ return m2;
1745+
1746+ if (m2 == CCSZmode)
1747+ return m1;
1748+
1749+ return VOIDmode;
1750+
1751+ case CCSZmode:
1752+ if (m2 == CCSmode || m2 == CCSZNmode)
1753+ return m2;
1754+
1755+ return VOIDmode;
1756+
1757+ default:
1758+ gcc_unreachable ();
1759+ }
1760+}
1761+
1762+static rtx
1763+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
1764+{
1765+ int unspec;
1766+ rtx got_offs;
1767+ rtx got_offs_scaled;
1768+ rtx plus_scaled;
1769+ rtx tmp;
1770+ rtx new_rtx;
1771+
1772+ gcc_assert (reg != 0);
1773+
1774+ if (GET_CODE (orig) == SYMBOL_REF
1775+ && SYMBOL_REF_FUNCTION_P (orig))
1776+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
1777+ else
1778+ unspec = UNSPEC_FDPIC_GOT;
1779+
1780+ got_offs = gen_reg_rtx (SImode);
1781+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
1782+ emit_move_insn (got_offs, tmp);
1783+
1784+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
1785+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
1786+ new_rtx = gen_const_mem (Pmode, plus_scaled);
1787+ emit_move_insn (reg, new_rtx);
1788+
1789+ return reg;
1790+}
1791+
1792+static rtx
1793+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
1794+{
1795+ rtx addr = orig;
1796+ rtx new_rtx = orig;
1797+
1798+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1799+ {
1800+ rtx base;
1801+
1802+ if (GET_CODE (addr) == CONST)
1803+ {
1804+ addr = XEXP (addr, 0);
1805+ gcc_assert (GET_CODE (addr) == PLUS);
1806+ }
1807+
1808+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
1809+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
1810+ }
1811+
1812+ return new_rtx;
1813+}
1814+
1815+/* Code generation. */
1816+
1817+void
1818+ubicom32_expand_movsi (rtx *operands)
1819+{
1820+ if (GET_CODE (operands[1]) == SYMBOL_REF
1821+ || (GET_CODE (operands[1]) == CONST
1822+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
1823+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
1824+ || CONSTANT_ADDRESS_P (operands[1]))
1825+ {
1826+ if (TARGET_FDPIC)
1827+ {
1828+ rtx tmp;
1829+ rtx fdpic_reg;
1830+
1831+ gcc_assert (can_create_pseudo_p ());
1832+ tmp = gen_reg_rtx (Pmode);
1833+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
1834+ if (GET_CODE (operands[1]) == SYMBOL_REF
1835+ || GET_CODE (operands[1]) == LABEL_REF)
1836+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
1837+ else
1838+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
1839+ }
1840+ else
1841+ {
1842+ rtx tmp;
1843+ enum machine_mode mode;
1844+
1845+ /* We want to avoid reusing operand 0 if we can because it limits
1846+ our ability to optimize later. */
1847+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
1848+
1849+ mode = GET_MODE (operands[0]);
1850+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
1851+ gen_rtx_HIGH (mode, operands[1])));
1852+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
1853+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
1854+ {
1855+ tmp = gen_reg_rtx (mode);
1856+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
1857+ operands[1] = tmp;
1858+ }
1859+ }
1860+ }
1861+}
1862+
1863+/* Emit code for addsi3. */
1864+
1865+void
1866+ubicom32_expand_addsi3 (rtx *operands)
1867+{
1868+ rtx op, clob;
1869+
1870+ if (can_create_pseudo_p ())
1871+ {
1872+ /* If we have a non-data reg for operand 1 then prefer that over
1873+ a CONST_INT in operand 2. */
1874+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
1875+ && CONST_INT_P (operands[2]))
1876+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
1877+
1878+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
1879+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
1880+ }
1881+
1882+ /* Emit the instruction. */
1883+
1884+ op = gen_rtx_SET (VOIDmode, operands[0],
1885+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
1886+
1887+ if (! can_create_pseudo_p ())
1888+ {
1889+ /* Reload doesn't know about the flags register, and doesn't know that
1890+ it doesn't want to clobber it. We can only do this with PLUS. */
1891+ emit_insn (op);
1892+ }
1893+ else
1894+ {
1895+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1896+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1897+ }
1898+}
1899+
1900+/* Emit code for mulsi3. Return 1 if we have generated all the code
1901+ necessary to do the multiplication. */
1902+
1903+int
1904+ubicom32_emit_mult_sequence (rtx *operands)
1905+{
1906+ if (! ubicom32_v4)
1907+ {
1908+ rtx a1, a1_1, a2;
1909+ rtx b1, b1_1, b2;
1910+ rtx mac_lo_rtx;
1911+ rtx t1, t2, t3;
1912+
1913+ /* Give up if we cannot create new pseudos. */
1914+ if (!can_create_pseudo_p())
1915+ return 0;
1916+
1917+ /* Synthesize 32-bit multiplication using 16-bit operations:
1918+
1919+ a1 = highpart (a)
1920+ a2 = lowpart (a)
1921+
1922+ b1 = highpart (b)
1923+ b2 = lowpart (b)
1924+
1925+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1926+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1927+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
1928+ Signed Signed Unsigned */
1929+
1930+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
1931+ {
1932+ rtx op1;
1933+
1934+ op1 = gen_reg_rtx (SImode);
1935+ emit_move_insn (op1, operands[1]);
1936+ operands[1] = op1;
1937+ }
1938+
1939+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
1940+ {
1941+ rtx op2;
1942+
1943+ op2 = gen_reg_rtx (SImode);
1944+ emit_move_insn (op2, operands[2]);
1945+ operands[2] = op2;
1946+ }
1947+
1948+ /* a1 = highpart (a) */
1949+ a1 = gen_reg_rtx (HImode);
1950+ a1_1 = gen_reg_rtx (SImode);
1951+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
1952+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
1953+
1954+ /* a2 = lowpart (a) */
1955+ a2 = gen_reg_rtx (HImode);
1956+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
1957+
1958+ /* b1 = highpart (b) */
1959+ b1 = gen_reg_rtx (HImode);
1960+ b1_1 = gen_reg_rtx (SImode);
1961+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
1962+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
1963+
1964+ /* b2 = lowpart (b) */
1965+ b2 = gen_reg_rtx (HImode);
1966+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
1967+
1968+ /* t1 = (a1 * b2) << 16 */
1969+ t1 = gen_reg_rtx (SImode);
1970+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
1971+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
1972+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
1973+
1974+ /* t2 = (a2 * b1) << 16 */
1975+ t2 = gen_reg_rtx (SImode);
1976+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
1977+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
1978+
1979+ /* mac_lo = a2 * b2 */
1980+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
1981+
1982+ /* t3 = t1 + t2 */
1983+ t3 = gen_reg_rtx (SImode);
1984+ emit_insn (gen_addsi3 (t3, t1, t2));
1985+
1986+ /* c = t3 + mac_lo_rtx */
1987+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
1988+
1989+ return 1;
1990+ }
1991+ else
1992+ {
1993+ rtx acc_rtx;
1994+
1995+ /* Give up if we cannot create new pseudos. */
1996+ if (!can_create_pseudo_p())
1997+ return 0;
1998+
1999+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
2000+ {
2001+ rtx op1;
2002+
2003+ op1 = gen_reg_rtx (SImode);
2004+ emit_move_insn (op1, operands[1]);
2005+ operands[1] = op1;
2006+ }
2007+
2008+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
2009+ {
2010+ rtx op2;
2011+
2012+ op2 = gen_reg_rtx (SImode);
2013+ emit_move_insn (op2, operands[2]);
2014+ operands[2] = op2;
2015+ }
2016+
2017+ acc_rtx = gen_reg_rtx (DImode);
2018+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
2019+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
2020+
2021+ return 1;
2022+ }
2023+}
2024+
2025+/* Move the integer value VAL into OPERANDS[0]. */
2026+
2027+void
2028+ubicom32_emit_move_const_int (rtx dest, rtx imm)
2029+{
2030+ rtx xoperands[2];
2031+
2032+ xoperands[0] = dest;
2033+ xoperands[1] = imm;
2034+
2035+ /* Treat mem destinations separately. Values must be explicitly sign
2036+ extended. */
2037+ if (MEM_P (dest))
2038+ {
2039+ rtx low_hword_mem;
2040+ rtx low_hword_addr;
2041+
2042+ /* Emit shorter sequence for signed 7-bit quantities. */
2043+ if (satisfies_constraint_I (imm))
2044+ {
2045+ output_asm_insn ("move.4\t%0, %1", xoperands);
2046+ return;
2047+ }
2048+
2049+ /* Special case for pushing constants. */
2050+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
2051+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
2052+ {
2053+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2054+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2055+ return;
2056+ }
2057+
2058+ /* See if we can add 2 to the original address. This is only
2059+ possible if the original address is of the form REG or
2060+ REG+const. */
2061+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
2062+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
2063+ {
2064+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
2065+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
2066+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
2067+ xoperands[0] = low_hword_mem;
2068+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2069+ return;
2070+ }
2071+
2072+ /* The original address is too complex. We need to use a
2073+ scratch memory by (sp) and move that to the original
2074+ destination. */
2075+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
2076+ {
2077+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2078+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2079+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2080+ return;
2081+ }
2082+
2083+ /* Our address mentions the stack pointer so we need to
2084+ use our scratch data register here as well as scratch
2085+ memory. */
2086+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2087+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2088+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
2089+ output_asm_insn ("move.4\t%0, d15", xoperands);
2090+ return;
2091+ }
2092+
2093+ /* Move into registers are zero extended by default. */
2094+ if (! REG_P (dest))
2095+ abort ();
2096+
2097+ if (satisfies_constraint_N (imm))
2098+ {
2099+ output_asm_insn ("movei\t%0, %1", xoperands);
2100+ return;
2101+ }
2102+
2103+ if (INTVAL (xoperands[1]) >= 0xff80
2104+ && INTVAL (xoperands[1]) < 0x10000)
2105+ {
2106+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
2107+ output_asm_insn ("move.2\t%0, %1", xoperands);
2108+ return;
2109+ }
2110+
2111+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
2112+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
2113+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
2114+ {
2115+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
2116+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
2117+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
2118+ return;
2119+ }
2120+
2121+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
2122+ {
2123+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2124+ output_asm_insn ("move.2\t%0, %0", xoperands);
2125+ return;
2126+ }
2127+
2128+ /* This is very expensive. The constant is so large that we
2129+ need to use the stack to do the load. */
2130+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2131+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2132+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2133+}
2134+
2135+/* Stack layout. Prologue/Epilogue. */
2136+
2137+static int save_regs_size;
2138+
2139+static void
2140+ubicom32_layout_frame (void)
2141+{
2142+ int regno;
2143+
2144+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
2145+ nregs = 0;
2146+ frame_size = get_frame_size ();
2147+
2148+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
2149+ {
2150+ save_regs[FRAME_POINTER_REGNUM] = 1;
2151+ ++nregs;
2152+ }
2153+
2154+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
2155+ ubicom32_can_use_calli_to_ret = 1;
2156+ else
2157+ {
2158+ ubicom32_can_use_calli_to_ret = 0;
2159+ save_regs[LINK_REGNO] = 1;
2160+ ++nregs;
2161+ }
2162+
2163+ /* Figure out which register(s) needs to be saved. */
2164+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
2165+ if (df_regs_ever_live_p(regno)
2166+ && ! call_used_regs[regno]
2167+ && ! fixed_regs[regno]
2168+ && ! save_regs[regno])
2169+ {
2170+ save_regs[regno] = 1;
2171+ ++nregs;
2172+ }
2173+
2174+ save_regs_size = 4 * nregs;
2175+}
2176+
2177+static void
2178+ubicom32_emit_add_movsi (int regno, int adj)
2179+{
2180+ rtx x;
2181+ rtx reg = gen_rtx_REG (SImode, regno);
2182+
2183+ adj += 4;
2184+ if (adj > 8 * 4)
2185+ {
2186+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2187+ GEN_INT (-adj)));
2188+ RTX_FRAME_RELATED_P (x) = 1;
2189+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
2190+ }
2191+ else
2192+ {
2193+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
2194+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2195+ GEN_INT (-adj)));
2196+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
2197+ }
2198+ RTX_FRAME_RELATED_P (x) = 1;
2199+}
2200+
2201+void
2202+ubicom32_expand_prologue (void)
2203+{
2204+ rtx x;
2205+ int regno;
2206+ int outgoing_args_size = crtl->outgoing_args_size;
2207+ int adj;
2208+
2209+ if (ubicom32_naked_function_p ())
2210+ return;
2211+
2212+ ubicom32_builtin_saveregs ();
2213+
2214+ ubicom32_layout_frame ();
2215+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
2216+ + crtl->args.pretend_args_size);
2217+
2218+ if (!adj)
2219+ ;
2220+ else if (outgoing_args_size + save_regs_size < 508
2221+ && get_frame_size () + save_regs_size > 508)
2222+ {
2223+ int i = 0;
2224+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2225+ GEN_INT (-adj));
2226+ x = emit_insn (x);
2227+ RTX_FRAME_RELATED_P (x) = 1;
2228+
2229+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2230+ if (save_regs[regno] && regno != LINK_REGNO)
2231+ {
2232+ x = gen_rtx_MEM (SImode,
2233+ gen_rtx_PLUS (Pmode,
2234+ stack_pointer_rtx,
2235+ GEN_INT (i * 4 + outgoing_args_size)));
2236+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
2237+ RTX_FRAME_RELATED_P (x) = 1;
2238+ ++i;
2239+ }
2240+ if (save_regs[LINK_REGNO])
2241+ {
2242+ x = gen_rtx_MEM (SImode,
2243+ gen_rtx_PLUS (Pmode,
2244+ stack_pointer_rtx,
2245+ GEN_INT (i * 4 + outgoing_args_size)));
2246+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
2247+ RTX_FRAME_RELATED_P (x) = 1;
2248+ }
2249+ }
2250+ else
2251+ {
2252+ int regno;
2253+ int adj = get_frame_size () + crtl->args.pretend_args_size;
2254+ int i = 0;
2255+
2256+ if (save_regs[LINK_REGNO])
2257+ {
2258+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
2259+ ++i;
2260+ }
2261+
2262+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
2263+ if (save_regs[regno] && regno != LINK_REGNO)
2264+ {
2265+ if (i)
2266+ {
2267+ rtx mem = gen_rtx_MEM (SImode,
2268+ gen_rtx_PRE_DEC (Pmode,
2269+ stack_pointer_rtx));
2270+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
2271+ RTX_FRAME_RELATED_P (x) = 1;
2272+ }
2273+ else
2274+ ubicom32_emit_add_movsi (regno, adj);
2275+ ++i;
2276+ }
2277+
2278+ if (outgoing_args_size || (!i && adj))
2279+ {
2280+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2281+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
2282+ x = emit_insn (x);
2283+ RTX_FRAME_RELATED_P (x) = 1;
2284+ }
2285+ }
2286+
2287+ if (frame_pointer_needed)
2288+ {
2289+ int fp_adj = save_regs_size + outgoing_args_size;
2290+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
2291+ GEN_INT (fp_adj));
2292+ x = emit_insn (x);
2293+ RTX_FRAME_RELATED_P (x) = 1;
2294+ }
2295+}
2296+
2297+void
2298+ubicom32_expand_epilogue (void)
2299+{
2300+ rtx x;
2301+ int regno;
2302+ int outgoing_args_size = crtl->outgoing_args_size;
2303+ int adj;
2304+ int i;
2305+
2306+ if (ubicom32_naked_function_p ())
2307+ {
2308+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
2309+ LINK_REGNO)));
2310+ return;
2311+ }
2312+
2313+ if (cfun->calls_alloca)
2314+ {
2315+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
2316+ GEN_INT (-save_regs_size));
2317+ emit_insn (x);
2318+ outgoing_args_size = 0;
2319+ }
2320+
2321+ if (outgoing_args_size)
2322+ {
2323+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2324+ GEN_INT (outgoing_args_size));
2325+ emit_insn (x);
2326+ }
2327+
2328+ i = 0;
2329+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2330+ if (save_regs[regno] && regno != LINK_REGNO)
2331+ {
2332+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2333+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
2334+ ++i;
2335+ }
2336+
2337+ /* Do we have to adjust the stack after we've finished restoring regs? */
2338+ adj = get_frame_size() + crtl->args.pretend_args_size;
2339+ if (cfun->stdarg)
2340+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2341+
2342+#if 0
2343+ if (crtl->calls_eh_return && 0)
2344+ {
2345+ if (save_regs[LINK_REGNO])
2346+ {
2347+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2348+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2349+ }
2350+
2351+ if (adj)
2352+ {
2353+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2354+ GEN_INT (adj));
2355+ x = emit_insn (x);
2356+ }
2357+
2358+ /* Perform the additional bump for __throw. */
2359+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2360+ EH_RETURN_STACKADJ_RTX));
2361+ emit_jump_insn (gen_eh_return_internal ());
2362+ return;
2363+ }
2364+#endif
2365+
2366+ if (save_regs[LINK_REGNO])
2367+ {
2368+ if (adj >= 4 && adj <= (6 * 4))
2369+ {
2370+ x = GEN_INT (adj + 4);
2371+ emit_jump_insn (gen_return_from_post_modify_sp (x));
2372+ return;
2373+ }
2374+
2375+ if (adj == 0)
2376+ {
2377+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2378+ emit_jump_insn (gen_return_internal (x));
2379+ return;
2380+ }
2381+
2382+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2383+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2384+ }
2385+
2386+ if (adj)
2387+ {
2388+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2389+ GEN_INT (adj));
2390+ x = emit_insn (x);
2391+ adj = 0;
2392+ }
2393+
2394+ /* Given that we've just done all the hard work here we may as well use
2395+ a calli to return. */
2396+ ubicom32_can_use_calli_to_ret = 1;
2397+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
2398+}
2399+
2400+void
2401+ubicom32_expand_call_fdpic (rtx *operands)
2402+{
2403+ rtx c;
2404+ rtx addr;
2405+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2406+
2407+ addr = XEXP (operands[0], 0);
2408+
2409+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
2410+ emit_call_insn (c);
2411+}
2412+
2413+void
2414+ubicom32_expand_call_value_fdpic (rtx *operands)
2415+{
2416+ rtx c;
2417+ rtx addr;
2418+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2419+
2420+ addr = XEXP (operands[1], 0);
2421+
2422+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
2423+ emit_call_insn (c);
2424+}
2425+
2426+void
2427+ubicom32_expand_eh_return (rtx *operands)
2428+{
2429+ if (REG_P (operands[0])
2430+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
2431+ {
2432+ rtx sp = EH_RETURN_STACKADJ_RTX;
2433+ emit_move_insn (sp, operands[0]);
2434+ operands[0] = sp;
2435+ }
2436+
2437+ if (REG_P (operands[1])
2438+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
2439+ {
2440+ rtx ra = EH_RETURN_HANDLER_RTX;
2441+ emit_move_insn (ra, operands[1]);
2442+ operands[1] = ra;
2443+ }
2444+}
2445+
2446+/* Compute the offsets between eliminable registers. */
2447+
2448+int
2449+ubicom32_initial_elimination_offset (int from, int to)
2450+{
2451+ ubicom32_layout_frame ();
2452+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2453+ return save_regs_size + crtl->outgoing_args_size;
2454+
2455+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
2456+ return get_frame_size ()/* + save_regs_size */;
2457+
2458+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2459+ return get_frame_size ()
2460+ + crtl->outgoing_args_size
2461+ + save_regs_size;
2462+
2463+ return 0;
2464+}
2465+
2466+/* Return 1 if it is appropriate to emit `ret' instructions in the
2467+ body of a function. Do this only if the epilogue is simple, needing a
2468+ couple of insns. Prior to reloading, we can't tell how many registers
2469+ must be saved, so return 0 then. Return 0 if there is no frame
2470+ marker to de-allocate.
2471+
2472+ If NON_SAVING_SETJMP is defined and true, then it is not possible
2473+ for the epilogue to be simple, so return 0. This is a special case
2474+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
2475+ until final, but jump_optimize may need to know sooner if a
2476+ `return' is OK. */
2477+
2478+int
2479+ubicom32_can_use_return_insn_p (void)
2480+{
2481+ if (! reload_completed || frame_pointer_needed)
2482+ return 0;
2483+
2484+ return 1;
2485+}
2486+
2487+/* Attributes and CC handling. */
2488+
2489+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2490+ struct attribute_spec.handler. */
2491+static tree
2492+ubicom32_handle_fndecl_attribute (tree *node, tree name,
2493+ tree args ATTRIBUTE_UNUSED,
2494+ int flags ATTRIBUTE_UNUSED,
2495+ bool *no_add_attrs)
2496+{
2497+ if (TREE_CODE (*node) != FUNCTION_DECL)
2498+ {
2499+ warning ("'%s' attribute only applies to functions",
2500+ IDENTIFIER_POINTER (name));
2501+ *no_add_attrs = true;
2502+ }
2503+
2504+ return NULL_TREE;
2505+}
2506+
2507+/* A C expression that places additional restrictions on the register class to
2508+ use when it is necessary to copy value X into a register in class CLASS.
2509+ The value is a register class; perhaps CLASS, or perhaps another, smaller
2510+ class. On many machines, the following definition is safe:
2511+
2512+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
2513+
2514+ Sometimes returning a more restrictive class makes better code. For
2515+ example, on the 68000, when X is an integer constant that is in range for a
2516+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
2517+ as CLASS includes the data registers. Requiring a data register guarantees
2518+ that a `moveq' will be used.
2519+
2520+ If X is a `const_double', by returning `NO_REGS' you can force X into a
2521+ memory constant. This is useful on certain machines where immediate
2522+ floating values cannot be loaded into certain kinds of registers. */
2523+
2524+enum reg_class
2525+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
2526+{
2527+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
2528+ it is most likely being used as an address, so
2529+ prefer ADDRESS_REGS. If 'class' is not a superset
2530+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
2531+ if (GET_CODE (x) == PLUS
2532+ || GET_CODE (x) == HIGH
2533+ || GET_CODE (x) == LABEL_REF
2534+ || GET_CODE (x) == SYMBOL_REF
2535+ || GET_CODE (x) == CONST)
2536+ {
2537+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
2538+ return ALL_ADDRESS_REGS;
2539+
2540+ return NO_REGS;
2541+ }
2542+
2543+ return class;
2544+}
2545+
2546+/* Function arguments and varargs. */
2547+
2548+int
2549+ubicom32_reg_parm_stack_space (tree fndecl)
2550+{
2551+ return 0;
2552+
2553+ if (fndecl
2554+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
2555+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
2556+ != void_type_node))
2557+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2558+
2559+ return 0;
2560+}
2561+
2562+/* Flush the argument registers to the stack for a stdarg function;
2563+ return the new argument pointer. */
2564+
2565+rtx
2566+ubicom32_builtin_saveregs (void)
2567+{
2568+ int regno;
2569+
2570+ if (! cfun->stdarg)
2571+ return 0;
2572+
2573+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
2574+ emit_move_insn (gen_rtx_MEM (SImode,
2575+ gen_rtx_PRE_DEC (SImode,
2576+ stack_pointer_rtx)),
2577+ gen_rtx_REG (SImode, regno));
2578+
2579+ return stack_pointer_rtx;
2580+}
2581+
2582+void
2583+ubicom32_va_start (tree valist, rtx nextarg)
2584+{
2585+ std_expand_builtin_va_start (valist, nextarg);
2586+}
2587+
2588+rtx
2589+ubicom32_va_arg (tree valist, tree type)
2590+{
2591+ HOST_WIDE_INT size, rsize;
2592+ tree addr, incr, tmp;
2593+ rtx addr_rtx;
2594+ int indirect = 0;
2595+
2596+ /* Round up sizeof(type) to a word. */
2597+ size = int_size_in_bytes (type);
2598+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
2599+
2600+ /* Large types are passed by reference. */
2601+ if (size > 8)
2602+ {
2603+ indirect = 1;
2604+ size = rsize = UNITS_PER_WORD;
2605+ }
2606+
2607+ incr = valist;
2608+ addr = incr = save_expr (incr);
2609+
2610+ /* FIXME Nat's version - is it correct? */
2611+ tmp = fold_convert (ptr_type_node, size_int (rsize));
2612+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
2613+ incr = fold (tmp);
2614+
2615+ /* FIXME Nat's version - is it correct? */
2616+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
2617+
2618+ TREE_SIDE_EFFECTS (incr) = 1;
2619+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
2620+
2621+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
2622+
2623+ if (size < UNITS_PER_WORD)
2624+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
2625+ GEN_INT (UNITS_PER_WORD - size)));
2626+
2627+ if (indirect)
2628+ {
2629+ addr_rtx = force_reg (Pmode, addr_rtx);
2630+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
2631+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
2632+ }
2633+
2634+ return addr_rtx;
2635+}
2636+
2637+void
2638+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2639+ int indirect ATTRIBUTE_UNUSED)
2640+{
2641+ cum->nbytes = 0;
2642+
2643+ if (!libname)
2644+ {
2645+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
2646+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2647+ != void_type_node));
2648+ }
2649+}
2650+
2651+/* Return an RTX to represent where a value in mode MODE will be passed
2652+ to a function. If the result is 0, the argument will be pushed. */
2653+
2654+rtx
2655+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2656+ int named ATTRIBUTE_UNUSED)
2657+{
2658+ rtx result = 0;
2659+ int size, align;
2660+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
2661+
2662+ /* Figure out the size of the object to be passed. */
2663+ if (mode == BLKmode)
2664+ size = int_size_in_bytes (type);
2665+ else
2666+ size = GET_MODE_SIZE (mode);
2667+
2668+ /* Figure out the alignment of the object to be passed. */
2669+ align = size;
2670+
2671+ cum->nbytes = (cum->nbytes + 3) & ~3;
2672+
2673+ /* Don't pass this arg via a register if all the argument registers
2674+ are used up. */
2675+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
2676+ return 0;
2677+
2678+ /* Don't pass this arg via a register if it would be split between
2679+ registers and memory. */
2680+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
2681+
2682+ return result;
2683+}
2684+
2685+rtx
2686+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2687+ int named ATTRIBUTE_UNUSED)
2688+{
2689+ if (cfun->stdarg)
2690+ return 0;
2691+
2692+ return function_arg (cum, mode, type, named);
2693+}
2694+
2695+
2696+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
2697+
2698+ Returns the number of bytes at the beginning of an argument that
2699+ must be put in registers. The value must be zero for arguments
2700+ that are passed entirely in registers or that are entirely pushed
2701+ on the stack. */
2702+static int
2703+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2704+ tree type, bool named ATTRIBUTE_UNUSED)
2705+{
2706+ int size, diff;
2707+
2708+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
2709+
2710+ /* round up to full word */
2711+ cum->nbytes = (cum->nbytes + 3) & ~3;
2712+
2713+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
2714+ return 0;
2715+
2716+ /* number of bytes left in registers */
2717+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
2718+
2719+ /* regs all used up */
2720+ if (diff <= 0)
2721+ return 0;
2722+
2723+ /* Figure out the size of the object to be passed. */
2724+ if (mode == BLKmode)
2725+ size = int_size_in_bytes (type);
2726+ else
2727+ size = GET_MODE_SIZE (mode);
2728+
2729+ /* enough space left in regs for size */
2730+ if (size <= diff)
2731+ return 0;
2732+
2733+ /* put diff bytes in regs and rest on stack */
2734+ return diff;
2735+
2736+}
2737+
2738+static bool
2739+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2740+ enum machine_mode mode, const_tree type,
2741+ bool named ATTRIBUTE_UNUSED)
2742+{
2743+ int size;
2744+
2745+ if (type)
2746+ size = int_size_in_bytes (type);
2747+ else
2748+ size = GET_MODE_SIZE (mode);
2749+
2750+ return size <= 0 || size > 8;
2751+}
2752+
2753+static bool
2754+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2755+ enum machine_mode mode, const_tree type,
2756+ bool named ATTRIBUTE_UNUSED)
2757+{
2758+ int size;
2759+
2760+ if (type)
2761+ size = int_size_in_bytes (type);
2762+ else
2763+ size = GET_MODE_SIZE (mode);
2764+
2765+ return size <= 0 || size > 8;
2766+}
2767+
2768+static bool
2769+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2770+{
2771+ int size, mode;
2772+
2773+ if (!type)
2774+ return true;
2775+
2776+ size = int_size_in_bytes(type);
2777+ if (size > 8)
2778+ return true;
2779+
2780+ mode = TYPE_MODE(type);
2781+ if (mode == BLKmode)
2782+ return true;
2783+
2784+ return false;
2785+}
2786+
2787+/* Return true if a given register number REGNO is acceptable for machine
2788+ mode MODE. */
2789+bool
2790+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
2791+{
2792+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
2793+ if (! ubicom32_v3)
2794+ {
2795+ if (regno == ACC0_HI_REGNUM)
2796+ return (mode == QImode || mode == HImode);
2797+ }
2798+
2799+ /* Only the flags reg can hold CCmode. */
2800+ if (GET_MODE_CLASS (mode) == MODE_CC)
2801+ return regno == CC_REGNUM;
2802+
2803+ /* We restrict the choice of DImode registers to only being address,
2804+ data or accumulator regs. We also restrict them to only start on
2805+ even register numbers so we never have to worry about partial
2806+ overlaps between operands in instructions. */
2807+ if (GET_MODE_SIZE (mode) > 4)
2808+ {
2809+ switch (REGNO_REG_CLASS (regno))
2810+ {
2811+ case ADDRESS_REGS:
2812+ case DATA_REGS:
2813+ case ACC_REGS:
2814+ return (regno & 1) == 0;
2815+
2816+ default:
2817+ return false;
2818+ }
2819+ }
2820+
2821+ return true;
2822+}
2823+
2824+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
2825+ and check its validity for a certain class.
2826+ We have two alternate definitions for each of them.
2827+ The usual definition accepts all pseudo regs; the other rejects
2828+ them unless they have been allocated suitable hard regs.
2829+ The symbol REG_OK_STRICT causes the latter definition to be used.
2830+
2831+ Most source files want to accept pseudo regs in the hope that
2832+ they will get allocated to the class that the insn wants them to be in.
2833+ Source files for reload pass need to be strict.
2834+ After reload, it makes no difference, since pseudo regs have
2835+ been eliminated by then.
2836+
2837+ These assume that REGNO is a hard or pseudo reg number.
2838+ They give nonzero only if REGNO is a hard reg of the suitable class
2839+ or a pseudo reg currently allocated to a suitable hard reg.
2840+ Since they use reg_renumber, they are safe only once reg_renumber
2841+ has been allocated, which happens in local-alloc.c. */
2842+
2843+int
2844+ubicom32_regno_ok_for_base_p (int regno, int strict)
2845+{
2846+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
2847+ || (!strict
2848+ && (regno >= FIRST_PSEUDO_REGISTER
2849+ || regno == ARG_POINTER_REGNUM))
2850+ || (strict && (reg_renumber
2851+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
2852+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
2853+ return 1;
2854+
2855+ return 0;
2856+}
2857+
2858+int
2859+ubicom32_regno_ok_for_index_p (int regno, int strict)
2860+{
2861+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
2862+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
2863+ || (strict && (reg_renumber
2864+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
2865+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
2866+ return 1;
2867+
2868+ return 0;
2869+}
2870+
2871+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
2872+ registers should be accepted. Accept either REG or SUBREG where a
2873+ register is valid. */
2874+
2875+static bool
2876+ubicom32_is_index_reg (rtx x, int strict)
2877+{
2878+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
2879+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
2880+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
2881+ return true;
2882+
2883+ return false;
2884+}
2885+
2886+/* Return 1 if X is a valid index for a memory address. */
2887+
2888+static bool
2889+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
2890+{
2891+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
2892+ or 4 depending on mode. */
2893+ if (CONST_INT_P (x))
2894+ {
2895+ switch (mode)
2896+ {
2897+ case QImode:
2898+ return satisfies_constraint_J (x);
2899+
2900+ case HImode:
2901+ return satisfies_constraint_K (x);
2902+
2903+ case SImode:
2904+ case SFmode:
2905+ return satisfies_constraint_L (x);
2906+
2907+ case DImode:
2908+ return satisfies_constraint_L (x)
2909+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
2910+
2911+ default:
2912+ return false;
2913+ }
2914+ }
2915+
2916+ if (mode != SImode && mode != HImode && mode != QImode)
2917+ return false;
2918+
2919+ /* Register index scaled by mode of operand: REG + REG * modesize.
2920+ Valid scaled index registers are:
2921+
2922+ SImode (mult (dreg) 4))
2923+ HImode (mult (dreg) 2))
2924+ QImode (mult (dreg) 1)) */
2925+ if (GET_CODE (x) == MULT
2926+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
2927+ && CONST_INT_P (XEXP (x, 1))
2928+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
2929+ return true;
2930+
2931+ /* REG + REG addressing is allowed for QImode. */
2932+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
2933+ return true;
2934+
2935+ return false;
2936+}
2937+
2938+static bool
2939+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
2940+{
2941+ if (offs < 0)
2942+ return false;
2943+
2944+ switch (mode)
2945+ {
2946+ case QImode:
2947+ return offs <= 127;
2948+
2949+ case HImode:
2950+ return offs <= 254;
2951+
2952+ case SImode:
2953+ case SFmode:
2954+ return offs <= 508;
2955+
2956+ case DImode:
2957+ return offs <= 504;
2958+
2959+ default:
2960+ return false;
2961+ }
2962+}
2963+
2964+static int
2965+ubicom32_get_valid_offset_mask (enum machine_mode mode)
2966+{
2967+ switch (mode)
2968+ {
2969+ case QImode:
2970+ return 127;
2971+
2972+ case HImode:
2973+ return 255;
2974+
2975+ case SImode:
2976+ case SFmode:
2977+ return 511;
2978+
2979+ case DImode:
2980+ return 255;
2981+
2982+ default:
2983+ return 0;
2984+ }
2985+}
2986+
2987+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
2988+ registers should be accepted. Accept either REG or SUBREG where a
2989+ register is valid. */
2990+
2991+static bool
2992+ubicom32_is_base_reg (rtx x, int strict)
2993+{
2994+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
2995+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
2996+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
2997+ return true;
2998+
2999+ return false;
3000+}
3001+
3002+static bool
3003+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
3004+{
3005+ return TARGET_FDPIC;
3006+}
3007+
3008+/* Determine if X is a legitimate constant. */
3009+
3010+bool
3011+ubicom32_legitimate_constant_p (rtx x)
3012+{
3013+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
3014+ a constant can be entered into reg_equiv_constant[]. If we return true,
3015+ reload can create new instances of the constant whenever it likes.
3016+
3017+ The idea is therefore to accept as many constants as possible (to give
3018+ reload more freedom) while rejecting constants that can only be created
3019+ at certain times. In particular, anything with a symbolic component will
3020+ require use of the pseudo FDPIC register, which is only available before
3021+ reload. */
3022+ if (TARGET_FDPIC)
3023+ {
3024+ if (GET_CODE (x) == SYMBOL_REF
3025+ || (GET_CODE (x) == CONST
3026+ && GET_CODE (XEXP (x, 0)) == PLUS
3027+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
3028+ || CONSTANT_ADDRESS_P (x))
3029+ return false;
3030+
3031+ return true;
3032+ }
3033+
3034+ /* For non-PIC code anything goes! */
3035+ return true;
3036+}
3037+
3038+/* Address validation. */
3039+
3040+bool
3041+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
3042+{
3043+ if (TARGET_DEBUG_ADDRESS)
3044+ {
3045+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
3046+ (strict) ? " (STRICT)" : "");
3047+ debug_rtx (x);
3048+ }
3049+
3050+ if (CONSTANT_ADDRESS_P (x))
3051+ return false;
3052+
3053+ if (ubicom32_is_base_reg (x, strict))
3054+ return true;
3055+
3056+ if ((GET_CODE (x) == POST_INC
3057+ || GET_CODE (x) == PRE_INC
3058+ || GET_CODE (x) == POST_DEC
3059+ || GET_CODE (x) == PRE_DEC)
3060+ && REG_P (XEXP (x, 0))
3061+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3062+ && mode != DImode)
3063+ return true;
3064+
3065+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
3066+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3067+ && GET_CODE (XEXP (x, 1)) == PLUS
3068+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
3069+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3070+ && mode != DImode)
3071+ {
3072+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
3073+ switch (mode)
3074+ {
3075+ case QImode:
3076+ return disp >= -8 && disp <= 7;
3077+
3078+ case HImode:
3079+ return disp >= -16 && disp <= 14 && ! (disp & 1);
3080+
3081+ case SImode:
3082+ return disp >= -32 && disp <= 28 && ! (disp & 3);
3083+
3084+ default:
3085+ return false;
3086+ }
3087+ }
3088+
3089+ /* Accept base + index * scale. */
3090+ if (GET_CODE (x) == PLUS
3091+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3092+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
3093+ return true;
3094+
3095+ /* Accept index * scale + base. */
3096+ if (GET_CODE (x) == PLUS
3097+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
3098+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
3099+ return true;
3100+
3101+ if (! TARGET_FDPIC)
3102+ {
3103+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
3104+ displacement operand:
3105+
3106+ moveai a1, #%hi(SYM)
3107+ move.4 d3, %lo(SYM)(a1) */
3108+ if (GET_CODE (x) == LO_SUM
3109+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3110+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
3111+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
3112+ && mode != DImode)
3113+ return true;
3114+ }
3115+
3116+ if (TARGET_DEBUG_ADDRESS)
3117+ fprintf (stderr, "\nNot a legitimate address.\n");
3118+
3119+ return false;
3120+}
3121+
3122+rtx
3123+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3124+ enum machine_mode mode)
3125+{
3126+ if (mode == BLKmode)
3127+ return NULL_RTX;
3128+
3129+ if (GET_CODE (x) == PLUS
3130+ && REG_P (XEXP (x, 0))
3131+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
3132+ && CONST_INT_P (XEXP (x, 1))
3133+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
3134+ {
3135+ rtx base;
3136+ rtx plus;
3137+ rtx new_rtx;
3138+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3139+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3140+ HOST_WIDE_INT high = val ^ low;
3141+
3142+ if (val < 0)
3143+ return NULL_RTX;
3144+
3145+ if (! low)
3146+ return NULL_RTX;
3147+
3148+ /* Reload the high part into a base reg; leave the low part
3149+ in the mem directly. */
3150+ base = XEXP (x, 0);
3151+ if (! ubicom32_is_base_reg (base, 0))
3152+ base = copy_to_mode_reg (Pmode, base);
3153+
3154+ plus = expand_simple_binop (Pmode, PLUS,
3155+ gen_int_mode (high, Pmode),
3156+ base, NULL, 0, OPTAB_WIDEN);
3157+ new_rtx = plus_constant (plus, low);
3158+
3159+ return new_rtx;
3160+ }
3161+
3162+ return NULL_RTX;
3163+}
3164+
3165+/* Try a machine-dependent way of reloading an illegitimate address AD
3166+ operand. If we find one, push the reload and and return the new address.
3167+
3168+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
3169+ and TYPE is the reload type of the current reload. */
3170+
3171+rtx
3172+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
3173+ int opnum, int type)
3174+{
3175+ /* Is this an address that we've already fixed up? If it is then
3176+ recognize it and move on. */
3177+ if (GET_CODE (ad) == PLUS
3178+ && GET_CODE (XEXP (ad, 0)) == PLUS
3179+ && REG_P (XEXP (XEXP (ad, 0), 0))
3180+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
3181+ && CONST_INT_P (XEXP (ad, 1)))
3182+ {
3183+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
3184+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3185+ opnum, (enum reload_type) type);
3186+ return ad;
3187+ }
3188+
3189+ /* Have we got an address where the offset is simply out of range? If
3190+ yes then reload the range as a high part and smaller offset. */
3191+ if (GET_CODE (ad) == PLUS
3192+ && REG_P (XEXP (ad, 0))
3193+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3194+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
3195+ && CONST_INT_P (XEXP (ad, 1))
3196+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
3197+ {
3198+ rtx temp;
3199+ rtx new_rtx;
3200+
3201+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
3202+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3203+ HOST_WIDE_INT high = val ^ low;
3204+
3205+ /* Reload the high part into a base reg; leave the low part
3206+ in the mem directly. */
3207+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
3208+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
3209+
3210+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
3211+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3212+ opnum, (enum reload_type) type);
3213+ return new_rtx;
3214+ }
3215+
3216+ /* If we're presented with an pre/post inc/dec then we must force this
3217+ to be done in an address register. The register allocator should
3218+ work this out for itself but at times ends up trying to use the wrong
3219+ class. If we get the wrong class then reload will end up generating
3220+ at least 3 instructions whereas this way we can hopefully keep it to
3221+ just 2. */
3222+ if ((GET_CODE (ad) == POST_INC
3223+ || GET_CODE (ad) == PRE_INC
3224+ || GET_CODE (ad) == POST_DEC
3225+ || GET_CODE (ad) == PRE_DEC)
3226+ && REG_P (XEXP (ad, 0))
3227+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3228+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
3229+ {
3230+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
3231+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
3232+ opnum, RELOAD_OTHER);
3233+ return ad;
3234+ }
3235+
3236+ return NULL_RTX;
3237+}
3238+
3239+/* Compute a (partial) cost for rtx X. Return true if the complete
3240+ cost has been computed, and false if subexpressions should be
3241+ scanned. In either case, *TOTAL contains the cost result. */
3242+
3243+static bool
3244+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
3245+ bool speed ATTRIBUTE_UNUSED)
3246+{
3247+ enum machine_mode mode = GET_MODE (x);
3248+
3249+ switch (code)
3250+ {
3251+ case CONST_INT:
3252+ /* Very short constants often fold into instructions so
3253+ we pretend that they don't cost anything! This is
3254+ really important as regards zero values as otherwise
3255+ the compiler has a nasty habit of wanting to reuse
3256+ zeroes that are in regs but that tends to pessimize
3257+ the code. */
3258+ if (satisfies_constraint_I (x))
3259+ {
3260+ *total = 0;
3261+ return true;
3262+ }
3263+
3264+ /* Bit clearing costs nothing */
3265+ if (outer_code == AND
3266+ && exact_log2 (~INTVAL (x)) != -1)
3267+ {
3268+ *total = 0;
3269+ return true;
3270+ }
3271+
3272+ /* Masking the lower set of bits costs nothing. */
3273+ if (outer_code == AND
3274+ && exact_log2 (INTVAL (x) + 1) != -1)
3275+ {
3276+ *total = 0;
3277+ return true;
3278+ }
3279+
3280+ /* Bit setting costs nothing. */
3281+ if (outer_code == IOR
3282+ && exact_log2 (INTVAL (x)) != -1)
3283+ {
3284+ *total = 0;
3285+ return true;
3286+ }
3287+
3288+ /* Larger constants that can be loaded via movei aren't too
3289+ bad. If we're just doing a set they cost nothing extra. */
3290+ if (satisfies_constraint_N (x))
3291+ {
3292+ if (mode == DImode)
3293+ *total = COSTS_N_INSNS (2);
3294+ else
3295+ *total = COSTS_N_INSNS (1);
3296+ return true;
3297+ }
3298+
3299+ if (mode == DImode)
3300+ *total = COSTS_N_INSNS (5);
3301+ else
3302+ *total = COSTS_N_INSNS (3);
3303+ return true;
3304+
3305+ case CONST_DOUBLE:
3306+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
3307+ so their cost is very high. */
3308+ *total = COSTS_N_INSNS (6);
3309+ return true;
3310+
3311+ case CONST:
3312+ case SYMBOL_REF:
3313+ case MEM:
3314+ *total = 0;
3315+ return true;
3316+
3317+ case IF_THEN_ELSE:
3318+ *total = COSTS_N_INSNS (1);
3319+ return true;
3320+
3321+ case LABEL_REF:
3322+ case HIGH:
3323+ case LO_SUM:
3324+ case BSWAP:
3325+ case PLUS:
3326+ case MINUS:
3327+ case AND:
3328+ case IOR:
3329+ case XOR:
3330+ case ASHIFT:
3331+ case ASHIFTRT:
3332+ case LSHIFTRT:
3333+ case NEG:
3334+ case NOT:
3335+ case SIGN_EXTEND:
3336+ case ZERO_EXTEND:
3337+ case ZERO_EXTRACT:
3338+ if (outer_code == SET)
3339+ {
3340+ if (mode == DImode)
3341+ *total = COSTS_N_INSNS (2);
3342+ else
3343+ *total = COSTS_N_INSNS (1);
3344+ }
3345+ return true;
3346+
3347+ case COMPARE:
3348+ if (outer_code == SET)
3349+ {
3350+ if (GET_MODE (XEXP (x, 0)) == DImode
3351+ || GET_MODE (XEXP (x, 1)) == DImode)
3352+ *total = COSTS_N_INSNS (2);
3353+ else
3354+ *total = COSTS_N_INSNS (1);
3355+ }
3356+ return true;
3357+
3358+ case UMOD:
3359+ case UDIV:
3360+ case MOD:
3361+ case DIV:
3362+ if (outer_code == SET)
3363+ {
3364+ if (mode == DImode)
3365+ *total = COSTS_N_INSNS (600);
3366+ else
3367+ *total = COSTS_N_INSNS (200);
3368+ }
3369+ return true;
3370+
3371+ case MULT:
3372+ if (outer_code == SET)
3373+ {
3374+ if (! ubicom32_v4)
3375+ {
3376+ if (mode == DImode)
3377+ *total = COSTS_N_INSNS (15);
3378+ else
3379+ *total = COSTS_N_INSNS (5);
3380+ }
3381+ else
3382+ {
3383+ if (mode == DImode)
3384+ *total = COSTS_N_INSNS (6);
3385+ else
3386+ *total = COSTS_N_INSNS (2);
3387+ }
3388+ }
3389+ return true;
3390+
3391+ case UNSPEC:
3392+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
3393+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
3394+ *total = 0;
3395+ return true;
3396+
3397+ default:
3398+ return false;
3399+ }
3400+}
3401+
3402+/* Return 1 if ADDR can have different meanings depending on the machine
3403+ mode of the memory reference it is used for or if the address is
3404+ valid for some modes but not others.
3405+
3406+ Autoincrement and autodecrement addresses typically have
3407+ mode-dependent effects because the amount of the increment or
3408+ decrement is the size of the operand being addressed. Some machines
3409+ have other mode-dependent addresses. Many RISC machines have no
3410+ mode-dependent addresses.
3411+
3412+ You may assume that ADDR is a valid address for the machine. */
3413+
3414+int
3415+ubicom32_mode_dependent_address_p (rtx addr)
3416+{
3417+ if (GET_CODE (addr) == POST_INC
3418+ || GET_CODE (addr) == PRE_INC
3419+ || GET_CODE (addr) == POST_DEC
3420+ || GET_CODE (addr) == PRE_DEC
3421+ || GET_CODE (addr) == POST_MODIFY
3422+ || GET_CODE (addr) == PRE_MODIFY)
3423+ return 1;
3424+
3425+ return 0;
3426+}
3427+
3428+static void
3429+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3430+{
3431+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
3432+ get_frame_size (), crtl->args.pretend_args_size,
3433+ save_regs_size, crtl->outgoing_args_size,
3434+ current_function_is_leaf ? "leaf" : "nonleaf");
3435+}
3436+
3437+static void
3438+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
3439+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3440+{
3441+ ubicom32_reorg_completed = 0;
3442+}
3443+
3444+static void
3445+ubicom32_machine_dependent_reorg (void)
3446+{
3447+#if 0 /* Commenting out this optimization until it is fixed */
3448+ if (optimize)
3449+ {
3450+ compute_bb_for_insn ();
3451+
3452+ /* Do a very simple CSE pass over just the hard registers. */
3453+ reload_cse_regs (get_insns ());
3454+
3455+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
3456+ Remove any EH edges associated with them. */
3457+ if (flag_non_call_exceptions)
3458+ purge_all_dead_edges ();
3459+ }
3460+#endif
3461+ ubicom32_reorg_completed = 1;
3462+}
3463+
3464+void
3465+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
3466+{
3467+ rtx note;
3468+ int mostly_false_jump;
3469+ rtx xoperands[2];
3470+ rtx cc_reg;
3471+
3472+ note = find_reg_note (insn, REG_BR_PROB, 0);
3473+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
3474+ <= REG_BR_PROB_BASE / 2);
3475+
3476+ xoperands[0] = target;
3477+ xoperands[1] = cond;
3478+ cc_reg = XEXP (cond, 0);
3479+
3480+ if (GET_MODE (cc_reg) == CCWmode
3481+ || GET_MODE (cc_reg) == CCWZmode
3482+ || GET_MODE (cc_reg) == CCWZNmode)
3483+ {
3484+ if (mostly_false_jump)
3485+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
3486+ else
3487+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
3488+ return;
3489+ }
3490+
3491+ if (GET_MODE (cc_reg) == CCSmode
3492+ || GET_MODE (cc_reg) == CCSZmode
3493+ || GET_MODE (cc_reg) == CCSZNmode)
3494+ {
3495+ if (mostly_false_jump)
3496+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
3497+ else
3498+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
3499+ return;
3500+ }
3501+
3502+ abort ();
3503+}
3504+
3505+/* Return non-zero if FUNC is a naked function. */
3506+
3507+static int
3508+ubicom32_naked_function_p (void)
3509+{
3510+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
3511+}
3512+
3513+/* Return an RTX indicating where the return address to the
3514+ calling function can be found. */
3515+rtx
3516+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
3517+{
3518+ if (count != 0)
3519+ return NULL_RTX;
3520+
3521+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
3522+}
3523+
3524+/*
3525+ * ubicom32_readonly_data_section: This routtine handles code
3526+ * at the start of readonly data sections
3527+ */
3528+static void
3529+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
3530+{
3531+ static int num = 0;
3532+ if (in_section == readonly_data_section){
3533+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
3534+ if (flag_data_sections){
3535+ fprintf (asm_out_file, ".rodata%d", num);
3536+ fprintf (asm_out_file, ",\"a\"");
3537+ }
3538+ fprintf (asm_out_file, "\n");
3539+ }
3540+ num++;
3541+}
3542+
3543+/*
3544+ * ubicom32_text_section: not in readonly section
3545+ */
3546+static void
3547+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
3548+{
3549+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
3550+}
3551+
3552+/*
3553+ * ubicom32_data_section: not in readonly section
3554+ */
3555+static void
3556+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
3557+{
3558+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
3559+}
3560+
3561+/*
3562+ * ubicom32_asm_init_sections: This routine implements special
3563+ * section handling
3564+ */
3565+static void
3566+ubicom32_asm_init_sections(void)
3567+{
3568+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
3569+
3570+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
3571+
3572+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
3573+}
3574+
3575+/*
3576+ * ubicom32_profiler: This routine would call
3577+ * mcount to support prof and gprof if mcount
3578+ * was supported. Currently, do nothing.
3579+ */
3580+void
3581+ubicom32_profiler(void)
3582+{
3583+}
3584+
3585+/* Initialise the builtin functions. Start by initialising
3586+ descriptions of different types of functions (e.g., void fn(int),
3587+ int fn(void)), and then use these to define the builtins. */
3588+static void
3589+ubicom32_init_builtins (void)
3590+{
3591+ tree endlink;
3592+ tree short_unsigned_endlink;
3593+ tree unsigned_endlink;
3594+ tree short_unsigned_ftype_short_unsigned;
3595+ tree unsigned_ftype_unsigned;
3596+
3597+ endlink = void_list_node;
3598+
3599+ short_unsigned_endlink
3600+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
3601+
3602+ unsigned_endlink
3603+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
3604+
3605+ short_unsigned_ftype_short_unsigned
3606+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
3607+
3608+ unsigned_ftype_unsigned
3609+ = build_function_type (unsigned_type_node, unsigned_endlink);
3610+
3611+ /* Initialise the byte swap function. */
3612+ add_builtin_function ("__builtin_ubicom32_swapb_2",
3613+ short_unsigned_ftype_short_unsigned,
3614+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
3615+ BUILT_IN_MD, NULL,
3616+ NULL_TREE);
3617+
3618+ /* Initialise the byte swap function. */
3619+ add_builtin_function ("__builtin_ubicom32_swapb_4",
3620+ unsigned_ftype_unsigned,
3621+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
3622+ BUILT_IN_MD, NULL,
3623+ NULL_TREE);
3624+}
3625+
3626+/* Given a builtin function taking 2 operands (i.e., target + source),
3627+ emit the RTL for the underlying instruction. */
3628+static rtx
3629+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
3630+{
3631+ tree arg0;
3632+ rtx op0, pat;
3633+ enum machine_mode tmode, mode0;
3634+
3635+ /* Grab the incoming argument and emit its RTL. */
3636+ arg0 = TREE_VALUE (arglist);
3637+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3638+
3639+ /* Determine the modes of the instruction operands. */
3640+ tmode = insn_data[icode].operand[0].mode;
3641+ mode0 = insn_data[icode].operand[1].mode;
3642+
3643+ /* Ensure that the incoming argument RTL is in a register of the
3644+ correct mode. */
3645+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3646+ op0 = copy_to_mode_reg (mode0, op0);
3647+
3648+ /* If there isn't a suitable target, emit a target register. */
3649+ if (target == 0
3650+ || GET_MODE (target) != tmode
3651+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3652+ target = gen_reg_rtx (tmode);
3653+
3654+ /* Emit and return the new instruction. */
3655+ pat = GEN_FCN (icode) (target, op0);
3656+ if (!pat)
3657+ return 0;
3658+ emit_insn (pat);
3659+
3660+ return target;
3661+}
3662+
3663+/* Expand a call to a builtin function. */
3664+static rtx
3665+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3666+ enum machine_mode mode ATTRIBUTE_UNUSED,
3667+ int ignore ATTRIBUTE_UNUSED)
3668+{
3669+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3670+ tree arglist = CALL_EXPR_ARGS(exp);
3671+ int fcode = DECL_FUNCTION_CODE (fndecl);
3672+
3673+ switch (fcode)
3674+ {
3675+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3676+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
3677+
3678+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3679+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
3680+
3681+ default:
3682+ gcc_unreachable();
3683+ }
3684+
3685+ /* Should really do something sensible here. */
3686+ return NULL_RTX;
3687+}
3688+
3689+/* Fold any constant argument for a swapb.2 instruction. */
3690+static tree
3691+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
3692+{
3693+ tree arg0;
3694+
3695+ arg0 = TREE_VALUE (arglist);
3696+
3697+ /* Optimize constant value. */
3698+ if (TREE_CODE (arg0) == INTEGER_CST)
3699+ {
3700+ HOST_WIDE_INT v;
3701+ HOST_WIDE_INT res;
3702+
3703+ v = TREE_INT_CST_LOW (arg0);
3704+ res = ((v >> 8) & 0xff)
3705+ | ((v & 0xff) << 8);
3706+
3707+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
3708+ }
3709+
3710+ return NULL_TREE;
3711+}
3712+
3713+/* Fold any constant argument for a swapb.4 instruction. */
3714+static tree
3715+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
3716+{
3717+ tree arg0;
3718+
3719+ arg0 = TREE_VALUE (arglist);
3720+
3721+ /* Optimize constant value. */
3722+ if (TREE_CODE (arg0) == INTEGER_CST)
3723+ {
3724+ unsigned HOST_WIDE_INT v;
3725+ unsigned HOST_WIDE_INT res;
3726+
3727+ v = TREE_INT_CST_LOW (arg0);
3728+ res = ((v >> 24) & 0xff)
3729+ | (((v >> 16) & 0xff) << 8)
3730+ | (((v >> 8) & 0xff) << 16)
3731+ | ((v & 0xff) << 24);
3732+
3733+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
3734+ }
3735+
3736+ return NULL_TREE;
3737+}
3738+
3739+/* Fold any constant arguments for builtin functions. */
3740+static tree
3741+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
3742+{
3743+ switch (DECL_FUNCTION_CODE (fndecl))
3744+ {
3745+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3746+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
3747+
3748+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3749+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
3750+
3751+ default:
3752+ return NULL;
3753+ }
3754+}
3755+
3756+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
3757+ tell the assembler to generate pointers to function descriptors in
3758+ some cases. */
3759+static bool
3760+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
3761+{
3762+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
3763+ {
3764+ if (GET_CODE (value) == SYMBOL_REF
3765+ && SYMBOL_REF_FUNCTION_P (value))
3766+ {
3767+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
3768+ output_addr_const (asm_out_file, value);
3769+ fputs (")\n", asm_out_file);
3770+ return true;
3771+ }
3772+
3773+ if (!aligned_p)
3774+ {
3775+ /* We've set the unaligned SI op to NULL, so we always have to
3776+ handle the unaligned case here. */
3777+ assemble_integer_with_op ("\t.4byte\t", value);
3778+ return true;
3779+ }
3780+ }
3781+
3782+ return default_assemble_integer (value, size, aligned_p);
3783+}
3784+
3785+/* If the constant I can be constructed by shifting a source-1 immediate
3786+ by a constant number of bits then return the bit count. If not
3787+ return 0. */
3788+
3789+int
3790+ubicom32_shiftable_const_int (int i)
3791+{
3792+ int shift = 0;
3793+
3794+ /* Note that any constant that can be represented as an immediate to
3795+ a movei instruction is automatically ignored here in the interests
3796+ of the clarity of the output asm code. */
3797+ if (i >= -32768 && i <= 32767)
3798+ return 0;
3799+
3800+ /* Find the number of trailing zeroes. We could use __builtin_ctz
3801+ here but it's not obvious if this is supported on all build
3802+ compilers so we err on the side of caution. */
3803+ if ((i & 0xffff) == 0)
3804+ {
3805+ shift += 16;
3806+ i >>= 16;
3807+ }
3808+
3809+ if ((i & 0xff) == 0)
3810+ {
3811+ shift += 8;
3812+ i >>= 8;
3813+ }
3814+
3815+ if ((i & 0xf) == 0)
3816+ {
3817+ shift += 4;
3818+ i >>= 4;
3819+ }
3820+
3821+ if ((i & 0x3) == 0)
3822+ {
3823+ shift += 2;
3824+ i >>= 2;
3825+ }
3826+
3827+ if ((i & 0x1) == 0)
3828+ {
3829+ shift += 1;
3830+ i >>= 1;
3831+ }
3832+
3833+ if (i >= -128 && i <= 127)
3834+ return shift;
3835+
3836+ return 0;
3837+}
3838+
3839--- /dev/null
3840@@ -0,0 +1,1564 @@
3841+/* Definitions of target machine for Ubicom32
3842+
3843+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3844+ 2009 Free Software Foundation, Inc.
3845+ Contributed by Ubicom, Inc.
3846+
3847+ This file is part of GCC.
3848+
3849+ GCC is free software; you can redistribute it and/or modify it
3850+ under the terms of the GNU General Public License as published
3851+ by the Free Software Foundation; either version 3, or (at your
3852+ option) any later version.
3853+
3854+ GCC is distributed in the hope that it will be useful, but WITHOUT
3855+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3856+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
3857+ License for more details.
3858+
3859+ You should have received a copy of the GNU General Public License
3860+ along with GCC; see the file COPYING3. If not see
3861+ <http://www.gnu.org/licenses/>. */
3862+
3863+
3864+
3865+#define OBJECT_FORMAT_ELF
3866+
3867+/* Run-time target specifications. */
3868+
3869+/* Target CPU builtins. */
3870+#define TARGET_CPU_CPP_BUILTINS() \
3871+ do \
3872+ { \
3873+ builtin_define_std ("__UBICOM32__"); \
3874+ builtin_define_std ("__ubicom32__"); \
3875+ \
3876+ if (TARGET_FDPIC) \
3877+ { \
3878+ builtin_define ("__UBICOM32_FDPIC__"); \
3879+ builtin_define ("__FDPIC__"); \
3880+ } \
3881+ } \
3882+ while (0)
3883+
3884+#ifndef TARGET_DEFAULT
3885+#define TARGET_DEFAULT 0
3886+#endif
3887+
3888+extern int ubicom32_case_values_threshold;
3889+
3890+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
3891+extern int ubicom32_v3;
3892+
3893+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
3894+extern int ubicom32_v4;
3895+
3896+extern int ubicom32_stack_size;
3897+
3898+/* Flag for whether we can use calli instead of ret in returns. */
3899+extern int ubicom32_can_use_calli_to_ret;
3900+
3901+/* This macro is a C statement to print on `stderr' a string describing the
3902+ particular machine description choice. Every machine description should
3903+ define `TARGET_VERSION'. */
3904+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
3905+
3906+/* We don't need a frame pointer to debug things. Doing this means
3907+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
3908+#define CAN_DEBUG_WITHOUT_FP
3909+
3910+/* We need to handle processor-specific options. */
3911+#define OVERRIDE_OPTIONS ubicom32_override_options ()
3912+
3913+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
3914+ ubicom32_optimization_options (LEVEL, SIZE)
3915+
3916+/* For Ubicom32 the least significant bit has the lowest bit number
3917+ so we define this to be 0. */
3918+#define BITS_BIG_ENDIAN 0
3919+
3920+/* For Ubicom32 the most significant byte in a word has the lowest
3921+ number. */
3922+#define BYTES_BIG_ENDIAN 1
3923+
3924+/* For Ubicom32, in a multiword object, the most signifant word has the
3925+ lowest number. */
3926+#define WORDS_BIG_ENDIAN 1
3927+
3928+/* Ubicom32 has 8 bits per byte. */
3929+#define BITS_PER_UNIT 8
3930+
3931+/* Ubicom32 has 32 bits per word. */
3932+#define BITS_PER_WORD 32
3933+
3934+/* Width of a word, in units (bytes). */
3935+#define UNITS_PER_WORD 4
3936+
3937+/* Width of a pointer, in bits. */
3938+#define POINTER_SIZE 32
3939+
3940+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
3941+ SImode. */
3942+#define Pmode SImode
3943+
3944+/* Normal alignment required for function parameters on the stack, in
3945+ bits. */
3946+#define PARM_BOUNDARY 32
3947+
3948+/* We need to maintain the stack on a 32-bit boundary. */
3949+#define STACK_BOUNDARY 32
3950+
3951+/* Alignment required for a function entry point, in bits. */
3952+#define FUNCTION_BOUNDARY 32
3953+
3954+/* Alias for the machine mode used for memory references to functions being
3955+ called, in `call' RTL expressions. We use byte-oriented addresses
3956+ here. */
3957+#define FUNCTION_MODE QImode
3958+
3959+/* Biggest alignment that any data type can require on this machine,
3960+ in bits. */
3961+#define BIGGEST_ALIGNMENT 32
3962+
3963+/* this default to BIGGEST_ALIGNMENT unless defined */
3964+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
3965+#undef MAX_OFILE_ALIGNMENT
3966+#define MAX_OFILE_ALIGNMENT (128 * 8)
3967+
3968+/* Alignment in bits to be given to a structure bit field that follows an empty
3969+ field such as `int : 0;'. */
3970+#define EMPTY_FIELD_BOUNDARY 32
3971+
3972+/* All structures must be a multiple of 32 bits in size. */
3973+#define STRUCTURE_SIZE_BOUNDARY 32
3974+
3975+/* A bit-field declared as `int' forces `int' alignment for the struct. */
3976+#define PCC_BITFIELD_TYPE_MATTERS 1
3977+
3978+/* For Ubicom32 we absolutely require that data be aligned with nominal
3979+ alignment. */
3980+#define STRICT_ALIGNMENT 1
3981+
3982+/* Make strcpy of constants fast. */
3983+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
3984+ (TREE_CODE (EXP) == STRING_CST \
3985+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
3986+
3987+/* Define this macro as an expression for the alignment of a structure
3988+ (given by STRUCT as a tree node) if the alignment computed in the
3989+ usual way is COMPUTED and the alignment explicitly specified was
3990+ SPECIFIED. */
3991+#define DATA_ALIGNMENT(TYPE, ALIGN) \
3992+ ((((ALIGN) < BITS_PER_WORD) \
3993+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
3994+ || TREE_CODE (TYPE) == UNION_TYPE \
3995+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
3996+
3997+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
3998+
3999+/* For Ubicom32 we default to unsigned chars. */
4000+#define DEFAULT_SIGNED_CHAR 0
4001+
4002+/* Machine-specific data register numbers. */
4003+#define FIRST_DATA_REGNUM 0
4004+#define D10_REGNUM 10
4005+#define D11_REGNUM 11
4006+#define D12_REGNUM 12
4007+#define D13_REGNUM 13
4008+#define LAST_DATA_REGNUM 15
4009+
4010+/* Machine-specific address register numbers. */
4011+#define FIRST_ADDRESS_REGNUM 16
4012+#define LAST_ADDRESS_REGNUM 22
4013+
4014+/* Register numbers used for passing a function's static chain pointer. If
4015+ register windows are used, the register number as seen by the called
4016+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
4017+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
4018+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
4019+
4020+ The static chain register need not be a fixed register.
4021+
4022+ If the static chain is passed in memory, these macros should not be defined;
4023+ instead, the next two macros should be defined. */
4024+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
4025+
4026+/* The register number of the frame pointer register, which is used to access
4027+ automatic variables in the stack frame. We generally eliminate this anyway
4028+ for Ubicom32 but we make it A6 by default. */
4029+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
4030+
4031+/* The register number of the stack pointer register, which is also be a
4032+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
4033+ have a hardware requirement about which register this is, but by convention
4034+ we use A7. */
4035+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
4036+
4037+/* Machine-specific accumulator register numbers. */
4038+#define ACC0_HI_REGNUM 24
4039+#define ACC0_LO_REGNUM 25
4040+#define ACC1_HI_REGNUM 26
4041+#define ACC1_LO_REGNUM 27
4042+
4043+/* source3 register number */
4044+#define SOURCE3_REGNUM 28
4045+
4046+/* The register number of the arg pointer register, which is used to access the
4047+ function's argument list. On some machines, this is the same as the frame
4048+ pointer register. On some machines, the hardware determines which register
4049+ this is. On other machines, you can choose any register you wish for this
4050+ purpose. If this is not the same register as the frame pointer register,
4051+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
4052+ arrange to be able to eliminate it. */
4053+#define ARG_POINTER_REGNUM 29
4054+
4055+/* Pseudo-reg for condition code. */
4056+#define CC_REGNUM 30
4057+
4058+/* Interrupt set/clear registers. */
4059+#define INT_SET0_REGNUM 31
4060+#define INT_SET1_REGNUM 32
4061+#define INT_CLR0_REGNUM 33
4062+#define INT_CLR1_REGNUM 34
4063+
4064+/* Scratchpad registers. */
4065+#define SCRATCHPAD0_REGNUM 35
4066+#define SCRATCHPAD1_REGNUM 36
4067+#define SCRATCHPAD2_REGNUM 37
4068+#define SCRATCHPAD3_REGNUM 38
4069+
4070+/* FDPIC register. */
4071+#define FDPIC_REGNUM 16
4072+
4073+/* Number of hardware registers known to the compiler. They receive numbers 0
4074+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
4075+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
4076+#define FIRST_PSEUDO_REGISTER 39
4077+
4078+/* An initializer that says which registers are used for fixed purposes all
4079+ throughout the compiled code and are therefore not available for general
4080+ allocation. These would include the stack pointer, the frame pointer
4081+ (except on machines where that can be used as a general register when no
4082+ frame pointer is needed), the program counter on machines where that is
4083+ considered one of the addressable registers, and any other numbered register
4084+ with a standard use.
4085+
4086+ This information is expressed as a sequence of numbers, separated by commas
4087+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
4088+ otherwise.
4089+
4090+ The table initialized from this macro, and the table initialized by the
4091+ following one, may be overridden at run time either automatically, by the
4092+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
4093+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
4094+#define FIXED_REGISTERS \
4095+ { \
4096+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
4097+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
4098+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
4099+ 0, 0, /* acc0 hi/lo */ \
4100+ 0, 0, /* acc1 hi/lo */ \
4101+ 0, /* source3 */ \
4102+ 1, /* arg */ \
4103+ 1, /* cc */ \
4104+ 1, 1, /* int_set[01] */ \
4105+ 1, 1, /* int_clr[01] */ \
4106+ 1, 1, 1, 1 /* scratchpad[0123] */ \
4107+ }
4108+
4109+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
4110+ general) by function calls as well as for fixed registers. This macro
4111+ therefore identifies the registers that are not available for general
4112+ allocation of values that must live across function calls.
4113+
4114+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
4115+ saves it on function entry and restores it on function exit, if the register
4116+ is used within the function. */
4117+#define CALL_USED_REGISTERS \
4118+ { \
4119+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
4120+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
4121+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
4122+ 1, 1, /* acc0 hi/lo */ \
4123+ 1, 1, /* acc1 hi/lo */ \
4124+ 1, /* source3 */ \
4125+ 1, /* arg */ \
4126+ 1, /* cc */ \
4127+ 1, 1, /* int_set[01] */ \
4128+ 1, 1, /* int_clr[01] */ \
4129+ 1, 1, 1, 1 /* scratchpad[0123] */ \
4130+ }
4131+
4132+/* How to refer to registers in assembler output.
4133+ This sequence is indexed by compiler's hard-register-number (see above). */
4134+
4135+/* A C initializer containing the assembler's names for the machine registers,
4136+ each one as a C string constant. This is what translates register numbers
4137+ in the compiler into assembler language. */
4138+#define REGISTER_NAMES \
4139+ { \
4140+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
4141+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
4142+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
4143+ "acc0_hi", "acc0_lo", \
4144+ "acc1_hi", "acc1_lo", \
4145+ "source3", \
4146+ "arg", \
4147+ "cc", \
4148+ "int_set0", "int_set1", \
4149+ "int_clr0", "int_clr1", \
4150+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
4151+ }
4152+
4153+#define CONDITIONAL_REGISTER_USAGE \
4154+ ubicom32_conditional_register_usage ();
4155+
4156+/* Order of allocation of registers. */
4157+
4158+/* If defined, an initializer for a vector of integers, containing the numbers
4159+ of hard registers in the order in which GNU CC should prefer to use them
4160+ (from most preferred to least).
4161+
4162+ For Ubicom32 we try using caller-clobbered data registers first, then
4163+ callee-saved data registers, then caller-clobbered address registers,
4164+ then callee-saved address registers and finally everything else.
4165+
4166+ The caller-clobbered registers are usually slightly cheaper to use because
4167+ there's no need to save/restore. */
4168+#define REG_ALLOC_ORDER \
4169+ { \
4170+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
4171+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
4172+ 14, /* d14 */ \
4173+ 10, 11, 12, 13, /* d10 - d13 */ \
4174+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
4175+ 17, 18, 22, /* a1, a2, a6 */ \
4176+ 24, 25, /* acc0 hi/lo */ \
4177+ 26, 27, /* acc0 hi/lo */ \
4178+ 28 /* source3 */ \
4179+ }
4180+
4181+/* C expression for the number of consecutive hard registers, starting at
4182+ register number REGNO, required to hold a value of mode MODE. */
4183+#define HARD_REGNO_NREGS(REGNO, MODE) \
4184+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4185+
4186+/* Most registers can hold QImode, HImode and SImode values but we have to
4187+ be able to indicate any hard registers that cannot hold values with some
4188+ modes. */
4189+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
4190+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
4191+
4192+/* We can rename most registers aside from the FDPIC register if we're using
4193+ FDPIC. */
4194+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
4195+
4196+/* A C expression that is nonzero if it is desirable to choose register
4197+ allocation so as to avoid move instructions between a value of mode MODE1
4198+ and a value of mode MODE2.
4199+
4200+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
4201+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
4202+ zero. */
4203+#define MODES_TIEABLE_P(MODE1, MODE2) 1
4204+
4205+/* An enumeral type that must be defined with all the register class names as
4206+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
4207+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
4208+ which is not a register class but rather tells how many classes there are.
4209+
4210+ Each register class has a number, which is the value of casting the class
4211+ name to type `int'. The number serves as an index in many of the tables
4212+ described below. */
4213+
4214+enum reg_class
4215+{
4216+ NO_REGS,
4217+ DATA_REGS,
4218+ FDPIC_REG,
4219+ ADDRESS_REGS,
4220+ ALL_ADDRESS_REGS,
4221+ ACC_LO_REGS,
4222+ ACC_REGS,
4223+ CC_REG,
4224+ DATA_ACC_REGS,
4225+ SOURCE3_REG,
4226+ SPECIAL_REGS,
4227+ GENERAL_REGS,
4228+ ALL_REGS,
4229+ LIM_REG_CLASSES
4230+};
4231+
4232+/* The number of distinct register classes. */
4233+#define N_REG_CLASSES (int) LIM_REG_CLASSES
4234+
4235+/* An initializer containing the names of the register classes as C string
4236+ constants. These names are used in writing some of the debugging dumps. */
4237+
4238+#define REG_CLASS_NAMES \
4239+{ \
4240+ "NO_REGS", \
4241+ "DATA_REGS", \
4242+ "FDPIC_REG", \
4243+ "ADDRESS_REGS", \
4244+ "ALL_ADDRESS_REGS", \
4245+ "ACC_LO_REGS", \
4246+ "ACC_REGS", \
4247+ "CC_REG", \
4248+ "DATA_ACC_REGS", \
4249+ "SOURCE3_REG", \
4250+ "SPECIAL_REGS", \
4251+ "GENERAL_REGS", \
4252+ "ALL_REGS", \
4253+ "LIM_REGS" \
4254+}
4255+
4256+/* An initializer containing the contents of the register classes, as integers
4257+ which are bit masks. The Nth integer specifies the contents of class N.
4258+ The way the integer MASK is interpreted is that register R is in the class
4259+ if `MASK & (1 << R)' is 1.
4260+
4261+ When the machine has more than 32 registers, an integer does not suffice.
4262+ Then the integers are replaced by sub-initializers, braced groupings
4263+ containing several integers. Each sub-initializer must be suitable as an
4264+ initializer for the type `HARD_REG_SET' which is defined in
4265+ `hard-reg-set.h'. */
4266+#define REG_CLASS_CONTENTS \
4267+{ \
4268+ {0x00000000, 0x00000000}, /* No regs */ \
4269+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
4270+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
4271+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
4272+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
4273+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
4274+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
4275+ {0x40000000, 0x00000000}, /* CC_REG */ \
4276+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
4277+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
4278+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
4279+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
4280+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
4281+}
4282+
4283+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
4284+
4285+/* A C expression whose value is a register class containing hard register
4286+ REGNO. In general there is more than one such class; choose a class which
4287+ is "minimal", meaning that no smaller class also contains the register. */
4288+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
4289+
4290+#define IRA_COVER_CLASSES \
4291+{ \
4292+ GENERAL_REGS, \
4293+ LIM_REG_CLASSES \
4294+}
4295+
4296+/* Ubicom32 base registers must be address registers since addresses can
4297+ only be reached via address registers. */
4298+#define BASE_REG_CLASS ALL_ADDRESS_REGS
4299+
4300+/* Ubicom32 index registers must be data registers since we cannot add
4301+ two address registers together to form an address. */
4302+#define INDEX_REG_CLASS DATA_REGS
4303+
4304+/* A C expression which is nonzero if register number NUM is suitable for use
4305+ as a base register in operand addresses. It may be either a suitable hard
4306+ register or a pseudo register that has been allocated such a hard register. */
4307+
4308+#ifndef REG_OK_STRICT
4309+#define REGNO_OK_FOR_BASE_P(regno) \
4310+ ubicom32_regno_ok_for_base_p (regno, 0)
4311+#else
4312+#define REGNO_OK_FOR_BASE_P(regno) \
4313+ ubicom32_regno_ok_for_base_p (regno, 1)
4314+#endif
4315+
4316+/* A C expression which is nonzero if register number NUM is suitable for use
4317+ as an index register in operand addresses. It may be either a suitable hard
4318+ register or a pseudo register that has been allocated such a hard register.
4319+
4320+ The difference between an index register and a base register is that the
4321+ index register may be scaled. If an address involves the sum of two
4322+ registers, neither one of them scaled, then either one may be labeled the
4323+ "base" and the other the "index"; but whichever labeling is used must fit
4324+ the machine's constraints of which registers may serve in each capacity.
4325+ The compiler will try both labelings, looking for one that is valid, and
4326+ will reload one or both registers only if neither labeling works. */
4327+#ifndef REG_OK_STRICT
4328+#define REGNO_OK_FOR_INDEX_P(regno) \
4329+ ubicom32_regno_ok_for_index_p (regno, 0)
4330+#else
4331+#define REGNO_OK_FOR_INDEX_P(regno) \
4332+ ubicom32_regno_ok_for_index_p (regno, 1)
4333+#endif
4334+
4335+/* Attempt to restrict the register class we need to copy value X intoto the
4336+ would-be register class CLASS. Most things are fine for Ubicom32 but we
4337+ have to restrict certain types of address loads. */
4338+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
4339+ ubicom32_preferred_reload_class (X, CLASS)
4340+
4341+/* A C expression for the maximum number of consecutive registers of
4342+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
4343+ is pretty much identical to HARD_REGNO_NREGS. */
4344+#define CLASS_MAX_NREGS(CLASS, MODE) \
4345+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4346+
4347+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
4348+ - i.e. it moves to a smaller address. */
4349+#define STACK_GROWS_DOWNWARD 1
4350+
4351+/* Offset from the frame pointer to the first local variable slot to
4352+ be allocated. */
4353+#define STARTING_FRAME_OFFSET 0
4354+
4355+/* Offset from the argument pointer register to the first argument's
4356+ address. */
4357+#define FIRST_PARM_OFFSET(FNDECL) 0
4358+
4359+/* A C expression whose value is RTL representing the value of the return
4360+ address for the frame COUNT steps up from the current frame, after the
4361+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
4362+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
4363+ defined.
4364+
4365+ The value of the expression must always be the correct address when COUNT is
4366+ zero, but may be `NULL_RTX' if there is not way to determine the return
4367+ address of other frames. */
4368+#define RETURN_ADDR_RTX(COUNT, FRAME) \
4369+ ubicom32_return_addr_rtx (COUNT, FRAME)
4370+
4371+/* Register That Address the Stack Frame. */
4372+
4373+/* We don't actually require a frame pointer in most functions with the
4374+ Ubicom32 architecture so we allow it to be eliminated. */
4375+#define FRAME_POINTER_REQUIRED 0
4376+
4377+/* Macro that defines a table of register pairs used to eliminate unecessary
4378+ registers that point into the stack frame.
4379+
4380+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
4381+ so we allow the arg pointer to be replaced by either the frame pointer or
4382+ the stack pointer. We also allow the frame pointer to be replaced by
4383+ the stack pointer. */
4384+#define ELIMINABLE_REGS \
4385+{ \
4386+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
4387+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
4388+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
4389+}
4390+
4391+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
4392+ above. */
4393+#define CAN_ELIMINATE(FROM, TO) 1
4394+
4395+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
4396+ initial difference between the specified pair of registers. This macro must
4397+ be defined if `ELIMINABLE_REGS' is defined. */
4398+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
4399+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
4400+
4401+/* If defined, the maximum amount of space required for outgoing arguments will
4402+ be computed and placed into the variable
4403+ `current_function_outgoing_args_size'. No space will be pushed onto the
4404+ stack for each call; instead, the function prologue should increase the
4405+ stack frame size by this amount.
4406+
4407+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
4408+ proper. */
4409+#define ACCUMULATE_OUTGOING_ARGS 1
4410+
4411+/* Define this macro if functions should assume that stack space has been
4412+ allocated for arguments even when their values are passed in registers.
4413+
4414+ The value of this macro is the size, in bytes, of the area reserved for
4415+ arguments passed in registers for the function represented by FNDECL.
4416+
4417+ This space can be allocated by the caller, or be a part of the
4418+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
4419+ which. */
4420+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
4421+
4422+/* A C expression that should indicate the number of bytes of its own arguments
4423+ that a function pops on returning, or 0 if the function pops no arguments
4424+ and the caller must therefore pop them all after the function returns.
4425+
4426+ FUNDECL is a C variable whose value is a tree node that describes the
4427+ function in question. Normally it is a node of type `FUNCTION_DECL' that
4428+ describes the declaration of the function. From this it is possible to
4429+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
4430+
4431+ FUNTYPE is a C variable whose value is a tree node that describes the
4432+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
4433+ describes the data type of the function. From this it is possible to obtain
4434+ the data types of the value and arguments (if known).
4435+
4436+ When a call to a library function is being considered, FUNTYPE will contain
4437+ an identifier node for the library function. Thus, if you need to
4438+ distinguish among various library functions, you can do so by their names.
4439+ Note that "library function" in this context means a function used to
4440+ perform arithmetic, whose name is known specially in the compiler and was
4441+ not mentioned in the C code being compiled.
4442+
4443+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
4444+ variable number of bytes is passed, it is zero, and argument popping will
4445+ always be the responsibility of the calling function.
4446+
4447+ On the Vax, all functions always pop their arguments, so the definition of
4448+ this macro is STACK-SIZE. On the 68000, using the standard calling
4449+ convention, no functions pop their arguments, so the value of the macro is
4450+ always 0 in this case. But an alternative calling convention is available
4451+ in which functions that take a fixed number of arguments pop them but other
4452+ functions (such as `printf') pop nothing (the caller pops all). When this
4453+ convention is in use, FUNTYPE is examined to determine whether a function
4454+ takes a fixed number of arguments. */
4455+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
4456+
4457+/* A C expression that controls whether a function argument is passed in a
4458+ register, and which register.
4459+
4460+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
4461+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
4462+ arguments so far passed in registers; MODE, the machine mode of the argument;
4463+ TYPE, the data type of the argument as a tree node or 0 if that is not known
4464+ (which happens for C support library functions); and NAMED, which is 1 for an
4465+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
4466+ called function's prototype.
4467+
4468+ The value of the expression should either be a `reg' RTX for the hard
4469+ register in which to pass the argument, or zero to pass the argument on the
4470+ stack.
4471+
4472+ For machines like the Vax and 68000, where normally all arguments are
4473+ pushed, zero suffices as a definition.
4474+
4475+ The usual way to make the ANSI library `stdarg.h' work on a machine where
4476+ some arguments are usually passed in registers, is to cause nameless
4477+ arguments to be passed on the stack instead. This is done by making
4478+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
4479+
4480+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
4481+ this macro to determine if this argument is of a type that must be passed in
4482+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
4483+ returns non-zero for such an argument, the compiler will abort. If
4484+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
4485+ stack and then loaded into a register. */
4486+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
4487+ function_arg (&CUM, MODE, TYPE, NAMED)
4488+
4489+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
4490+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
4491+
4492+/* A C expression for the number of words, at the beginning of an argument,
4493+ must be put in registers. The value must be zero for arguments that are
4494+ passed entirely in registers or that are entirely pushed on the stack.
4495+
4496+ On some machines, certain arguments must be passed partially in registers
4497+ and partially in memory. On these machines, typically the first N words of
4498+ arguments are passed in registers, and the rest on the stack. If a
4499+ multi-word argument (a `double' or a structure) crosses that boundary, its
4500+ first few words must be passed in registers and the rest must be pushed.
4501+ This macro tells the compiler when this occurs, and how many of the words
4502+ should go in registers.
4503+
4504+ `FUNCTION_ARG' for these arguments should return the first register to be
4505+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
4506+ the called function. */
4507+
4508+/* A C expression that indicates when an argument must be passed by reference.
4509+ If nonzero for an argument, a copy of that argument is made in memory and a
4510+ pointer to the argument is passed instead of the argument itself. The
4511+ pointer is passed in whatever way is appropriate for passing a pointer to
4512+ that type.
4513+
4514+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
4515+ definition of this macro might be
4516+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
4517+ MUST_PASS_IN_STACK (MODE, TYPE) */
4518+
4519+/* If defined, a C expression that indicates when it is the called function's
4520+ responsibility to make a copy of arguments passed by invisible reference.
4521+ Normally, the caller makes a copy and passes the address of the copy to the
4522+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
4523+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
4524+ the "live" value. The called function must not modify this value. If it
4525+ can be determined that the value won't be modified, it need not make a copy;
4526+ otherwise a copy must be made. */
4527+
4528+/* A C type for declaring a variable that is used as the first argument of
4529+ `FUNCTION_ARG' and other related values. For some target machines, the type
4530+ `int' suffices and can hold the number of bytes of argument so far.
4531+
4532+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
4533+ that have been passed on the stack. The compiler has other variables to
4534+ keep track of that. For target machines on which all arguments are passed
4535+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
4536+ however, the data structure must exist and should not be empty, so use
4537+ `int'. */
4538+struct cum_arg
4539+{
4540+ int nbytes;
4541+ int reg;
4542+ int stdarg;
4543+};
4544+#define CUMULATIVE_ARGS struct cum_arg
4545+
4546+/* A C statement (sans semicolon) for initializing the variable CUM for the
4547+ state at the beginning of the argument list. The variable has type
4548+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
4549+ of the function which will receive the args, or 0 if the args are to a
4550+ compiler support library function. The value of INDIRECT is nonzero when
4551+ processing an indirect call, for example a call through a function pointer.
4552+ The value of INDIRECT is zero for a call to an explicitly named function, a
4553+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
4554+ arguments for the function being compiled.
4555+
4556+ When processing a call to a compiler support library function, LIBNAME
4557+ identifies which one. It is a `symbol_ref' rtx which contains the name of
4558+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
4559+ being processed. Thus, each time this macro is called, either LIBNAME or
4560+ FNTYPE is nonzero, but never both of them at once. */
4561+
4562+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
4563+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
4564+
4565+/* A C statement (sans semicolon) to update the summarizer variable CUM to
4566+ advance past an argument in the argument list. The values MODE, TYPE and
4567+ NAMED describe that argument. Once this is done, the variable CUM is
4568+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
4569+
4570+ This macro need not do anything if the argument in question was passed on
4571+ the stack. The compiler knows how to track the amount of stack space used
4572+ for arguments without any special help. */
4573+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
4574+ ((CUM).nbytes += ((MODE) != BLKmode \
4575+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
4576+ : (int_size_in_bytes (TYPE) + 3) & ~3))
4577+
4578+/* For the Ubicom32 we define the upper function argument register here. */
4579+#define UBICOM32_FUNCTION_ARG_REGS 10
4580+
4581+/* A C expression that is nonzero if REGNO is the number of a hard register in
4582+ which function arguments are sometimes passed. This does *not* include
4583+ implicit arguments such as the static chain and the structure-value address.
4584+ On many machines, no registers can be used for this purpose since all
4585+ function arguments are pushed on the stack. */
4586+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
4587+
4588+
4589+/* How Scalar Function Values are Returned. */
4590+
4591+/* The number of the hard register that is used to return a scalar value from a
4592+ function call. */
4593+#define RETURN_VALUE_REGNUM 0
4594+
4595+/* A C expression to create an RTX representing the place where a function
4596+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
4597+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
4598+ represent that type. On many machines, only the mode is relevant.
4599+ (Actually, on most machines, scalar values are returned in the same place
4600+ regardless of mode).
4601+
4602+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
4603+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
4604+
4605+ If the precise function being called is known, FUNC is a tree node
4606+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
4607+ possible to use a different value-returning convention for specific
4608+ functions when all their calls are known.
4609+
4610+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
4611+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
4612+ related macros, below. */
4613+#define FUNCTION_VALUE(VALTYPE, FUNC) \
4614+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
4615+
4616+/* A C expression to create an RTX representing the place where a library
4617+ function returns a value of mode MODE.
4618+
4619+ Note that "library function" in this context means a compiler support
4620+ routine, used to perform arithmetic, whose name is known specially by the
4621+ compiler and was not mentioned in the C code being compiled.
4622+
4623+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
4624+ types, because none of the library functions returns such types. */
4625+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
4626+
4627+/* A C expression that is nonzero if REGNO is the number of a hard register in
4628+ which the values of called function may come back.
4629+
4630+ A register whose use for returning values is limited to serving as the
4631+ second of a pair (for a value of type `double', say) need not be recognized
4632+ by this macro. So for most machines, this definition suffices:
4633+
4634+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
4635+
4636+ If the machine has register windows, so that the caller and the called
4637+ function use different registers for the return value, this macro should
4638+ recognize only the caller's register numbers. */
4639+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
4640+
4641+
4642+/* How Large Values are Returned. */
4643+
4644+/* A C expression which can inhibit the returning of certain function values in
4645+ registers, based on the type of value. A nonzero value says to return the
4646+ function value in memory, just as large structures are always returned.
4647+ Here TYPE will be a C expression of type `tree', representing the data type
4648+ of the value.
4649+
4650+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
4651+ Also, the option `-fpcc-struct-return' takes effect regardless of this
4652+ macro. On most systems, it is possible to leave the macro undefined; this
4653+ causes a default definition to be used, whose value is the constant 1 for
4654+ `BLKmode' values, and 0 otherwise.
4655+
4656+ Do not use this macro to indicate that structures and unions should always
4657+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
4658+ to indicate this. */
4659+#define RETURN_IN_MEMORY(TYPE) \
4660+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
4661+
4662+/* Define this macro to be 1 if all structure and union return values must be
4663+ in memory. Since this results in slower code, this should be defined only
4664+ if needed for compatibility with other compilers or with an ABI. If you
4665+ define this macro to be 0, then the conventions used for structure and union
4666+ return values are decided by the `RETURN_IN_MEMORY' macro.
4667+
4668+ If not defined, this defaults to the value 1. */
4669+#define DEFAULT_PCC_STRUCT_RETURN 0
4670+
4671+/* If the structure value address is not passed in a register, define
4672+ `STRUCT_VALUE' as an expression returning an RTX for the place
4673+ where the address is passed. If it returns 0, the address is
4674+ passed as an "invisible" first argument. */
4675+#define STRUCT_VALUE 0
4676+
4677+/* Define this macro as a C expression that is nonzero if the return
4678+ instruction or the function epilogue ignores the value of the stack pointer;
4679+ in other words, if it is safe to delete an instruction to adjust the stack
4680+ pointer before a return from the function.
4681+
4682+ Note that this macro's value is relevant only for functions for which frame
4683+ pointers are maintained. It is never safe to delete a final stack
4684+ adjustment in a function that has no frame pointer, and the compiler knows
4685+ this regardless of `EXIT_IGNORE_STACK'. */
4686+#define EXIT_IGNORE_STACK 1
4687+
4688+/* A C statement or compound statement to output to FILE some assembler code to
4689+ call the profiling subroutine `mcount'. Before calling, the assembler code
4690+ must load the address of a counter variable into a register where `mcount'
4691+ expects to find the address. The name of this variable is `LP' followed by
4692+ the number LABELNO, so you would generate the name using `LP%d' in a
4693+ `fprintf'.
4694+
4695+ The details of how the address should be passed to `mcount' are determined
4696+ by your operating system environment, not by GNU CC. To figure them out,
4697+ compile a small program for profiling using the system's installed C
4698+ compiler and look at the assembler code that results.
4699+
4700+ This declaration must be present, but it can be an abort if profiling is
4701+ not implemented. */
4702+
4703+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
4704+
4705+/* A C statement to output, on the stream FILE, assembler code for a block of
4706+ data that contains the constant parts of a trampoline. This code should not
4707+ include a label--the label is taken care of automatically. */
4708+#if 0
4709+#define TRAMPOLINE_TEMPLATE(FILE) \
4710+ do { \
4711+ fprintf (FILE, "\tadd -4,sp\n"); \
4712+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
4713+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
4714+ fprintf (FILE, "\tadd 4,sp\n"); \
4715+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
4716+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
4717+ fprintf (FILE, "\tjmp (a0)\n"); \
4718+ fprintf (FILE, "\t.long 0\n"); \
4719+ fprintf (FILE, "\t.long 0\n"); \
4720+ } while (0)
4721+#endif
4722+
4723+/* A C expression for the size in bytes of the trampoline, as an integer. */
4724+#define TRAMPOLINE_SIZE 0x1b
4725+
4726+/* Alignment required for trampolines, in bits.
4727+
4728+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
4729+ aligning trampolines. */
4730+#define TRAMPOLINE_ALIGNMENT 32
4731+
4732+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
4733+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
4734+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
4735+ should be passed to the function when it is called. */
4736+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
4737+{ \
4738+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
4739+ (CXT)); \
4740+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
4741+ (FNADDR)); \
4742+}
4743+
4744+/* Ubicom32 supports pre and post increment/decrement addressing. */
4745+#define HAVE_POST_INCREMENT 1
4746+#define HAVE_PRE_INCREMENT 1
4747+#define HAVE_POST_DECREMENT 1
4748+#define HAVE_PRE_DECREMENT 1
4749+
4750+/* Ubicom32 supports pre and post address side-effects with constants
4751+ other than the size of the memory operand. */
4752+#define HAVE_PRE_MODIFY_DISP 1
4753+#define HAVE_POST_MODIFY_DISP 1
4754+
4755+/* A C expression that is 1 if the RTX X is a constant which is a valid
4756+ address. On most machines, this can be defined as `CONSTANT_P (X)',
4757+ but a few machines are more restrictive in which constant addresses
4758+ are supported.
4759+
4760+ `CONSTANT_P' accepts integer-values expressions whose values are not
4761+ explicitly known, such as `symbol_ref', `label_ref', and `high'
4762+ expressions and `const' arithmetic expressions, in addition to
4763+ `const_int' and `const_double' expressions. */
4764+#define CONSTANT_ADDRESS_P(X) \
4765+ (GET_CODE (X) == LABEL_REF \
4766+ || (GET_CODE (X) == CONST \
4767+ && GET_CODE (XEXP (X, 0)) == PLUS \
4768+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
4769+
4770+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
4771+ One is always an address register while a second, optional, one may be a
4772+ data register. */
4773+#define MAX_REGS_PER_ADDRESS 2
4774+
4775+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
4776+ RTX) is a legitimate memory address on the target machine for a memory
4777+ operand of mode MODE.
4778+
4779+ It usually pays to define several simpler macros to serve as subroutines for
4780+ this one. Otherwise it may be too complicated to understand.
4781+
4782+ This macro must exist in two variants: a strict variant and a non-strict
4783+ one. The strict variant is used in the reload pass. It must be defined so
4784+ that any pseudo-register that has not been allocated a hard register is
4785+ considered a memory reference. In contexts where some kind of register is
4786+ required, a pseudo-register with no hard register must be rejected.
4787+
4788+ The non-strict variant is used in other passes. It must be defined to
4789+ accept all pseudo-registers in every context where some kind of register is
4790+ required.
4791+
4792+ Compiler source files that want to use the strict variant of this macro
4793+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
4794+ conditional to define the strict variant in that case and the non-strict
4795+ variant otherwise.
4796+
4797+ Subroutines to check for acceptable registers for various purposes (one for
4798+ base registers, one for index registers, and so on) are typically among the
4799+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
4800+ subroutine macros need have two variants; the higher levels of macros may be
4801+ the same whether strict or not.
4802+
4803+ Normally, constant addresses which are the sum of a `symbol_ref' and an
4804+ integer are stored inside a `const' RTX to mark them as constant.
4805+ Therefore, there is no need to recognize such sums specifically as
4806+ legitimate addresses. Normally you would simply recognize any `const' as
4807+ legitimate.
4808+
4809+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
4810+ are not marked with `const'. It assumes that a naked `plus' indicates
4811+ indexing. If so, then you *must* reject such naked constant sums as
4812+ illegitimate addresses, so that none of them will be given to
4813+ `PRINT_OPERAND_ADDRESS'.
4814+
4815+ On some machines, whether a symbolic address is legitimate depends on the
4816+ section that the address refers to. On these machines, define the macro
4817+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
4818+ then check for it here. When you see a `const', you will have to look
4819+ inside it to find the `symbol_ref' in order to determine the section.
4820+
4821+ The best way to modify the name string is by adding text to the beginning,
4822+ with suitable punctuation to prevent any ambiguity. Allocate the new name
4823+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
4824+ remove and decode the added text and output the name accordingly, and define
4825+ `STRIP_NAME_ENCODING' to access the original name string.
4826+
4827+ You can check the information stored here into the `symbol_ref' in the
4828+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
4829+ `PRINT_OPERAND_ADDRESS'. */
4830+/* On the ubicom32, the value in the address register must be
4831+ in the same memory space/segment as the effective address.
4832+
4833+ This is problematical for reload since it does not understand
4834+ that base+index != index+base in a memory reference. */
4835+
4836+#ifdef REG_OK_STRICT
4837+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4838+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
4839+#else
4840+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4841+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
4842+#endif
4843+
4844+/* Try machine-dependent ways of modifying an illegitimate address
4845+ to be legitimate. If we find one, return the new, valid address.
4846+ This macro is used in only one place: `memory_address' in explow.c.
4847+
4848+ OLDX is the address as it was before break_out_memory_refs was called.
4849+ In some cases it is useful to look at this to decide what needs to be done.
4850+
4851+ MODE and WIN are passed so that this macro can use
4852+ GO_IF_LEGITIMATE_ADDRESS.
4853+
4854+ It is always safe for this macro to do nothing. It exists to recognize
4855+ opportunities to optimize the output.
4856+
4857+ On RS/6000, first check for the sum of a register with a constant
4858+ integer that is out of range. If so, generate code to add the
4859+ constant with the low-order 16 bits masked to the register and force
4860+ this result into another register (this can be done with `cau').
4861+ Then generate an address of REG+(CONST&0xffff), allowing for the
4862+ possibility of bit 16 being a one.
4863+
4864+ Then check for the sum of a register and something not constant, try to
4865+ load the other things into a register and return the sum. */
4866+
4867+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
4868+{ \
4869+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
4870+ if (result != NULL_RTX) \
4871+ { \
4872+ (X) = result; \
4873+ goto WIN; \
4874+ } \
4875+}
4876+
4877+/* Try a machine-dependent way of reloading an illegitimate address
4878+ operand. If we find one, push the reload and jump to WIN. This
4879+ macro is used in only one place: `find_reloads_address' in reload.c. */
4880+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
4881+{ \
4882+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
4883+ if (new_rtx) \
4884+ { \
4885+ (AD) = new_rtx; \
4886+ goto WIN; \
4887+ } \
4888+}
4889+
4890+/* A C statement or compound statement with a conditional `goto LABEL;'
4891+ executed if memory address X (an RTX) can have different meanings depending
4892+ on the machine mode of the memory reference it is used for or if the address
4893+ is valid for some modes but not others.
4894+
4895+ Autoincrement and autodecrement addresses typically have mode-dependent
4896+ effects because the amount of the increment or decrement is the size of the
4897+ operand being addressed. Some machines have other mode-dependent addresses.
4898+ Many RISC machines have no mode-dependent addresses.
4899+
4900+ You may assume that ADDR is a valid address for the machine. */
4901+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
4902+ if (ubicom32_mode_dependent_address_p (ADDR)) \
4903+ goto LABEL;
4904+
4905+/* A C expression that is nonzero if X is a legitimate constant for an
4906+ immediate operand on the target machine. You can assume that X
4907+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
4908+ a suitable definition for this macro on machines where anything
4909+ `CONSTANT_P' is valid. */
4910+#define LEGITIMATE_CONSTANT_P(X) \
4911+ ubicom32_legitimate_constant_p ((X))
4912+
4913+/* Moves between registers are pretty-much single instructions for
4914+ Ubicom32. We make this the default "2" that gcc likes. */
4915+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
4916+
4917+/* This is a little bit of magic from the S390 port that wins 2% on code
4918+ size when building the Linux kernel! Unfortunately while it wins on
4919+ that size the user-space apps built using FD-PIC don't improve and the
4920+ performance is lower because we put more pressure on the caches. We may
4921+ want this back on some future CPU that has higher cache performance. */
4922+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
4923+
4924+/* Moves between registers and memory are more expensive than between
4925+ registers because we have caches and write buffers that slow things
4926+ down! */
4927+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
4928+
4929+/* A fall-through branch is very low cost but anything that changes the PC
4930+ incurs a major pipeline hazard. We don't make the full extent of this
4931+ hazard visible because we hope that multiple threads will absorb much
4932+ of the cost and so we don't want a jump being replaced with, say, 7
4933+ instructions. */
4934+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
4935+ ((PREDICTABLE_P) ? 1 : 3)
4936+
4937+/* Define this macro as a C expression which is nonzero if accessing less than
4938+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
4939+ word of memory, i.e., if such access require more than one instruction or if
4940+ there is no difference in cost between byte and (aligned) word loads.
4941+
4942+ When this macro is not defined, the compiler will access a field by finding
4943+ the smallest containing object; when it is defined, a fullword load will be
4944+ used if alignment permits. Unless bytes accesses are faster than word
4945+ accesses, using word accesses is preferable since it may eliminate
4946+ subsequent memory access if subsequent accesses occur to other fields in the
4947+ same word of the structure, but to different bytes. */
4948+#define SLOW_BYTE_ACCESS 0
4949+
4950+/* The number of scalar move insns which should be generated instead of a
4951+ string move insn or a library call. Increasing the value will always make
4952+ code faster, but eventually incurs high cost in increased code size.
4953+
4954+ If you don't define this, a reasonable default is used. */
4955+/* According to expr.c, a value of around 6 should minimize code size. */
4956+#define MOVE_RATIO(SPEED) 6
4957+
4958+/* We're much better off calling a constant function address with the
4959+ Ubicom32 architecture because we have an opcode for doing so. Don't
4960+ let the compiler extract function addresses as common subexpressions
4961+ into an address register. */
4962+#define NO_FUNCTION_CSE
4963+
4964+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
4965+
4966+#define REVERSIBLE_CC_MODE(MODE) 1
4967+
4968+/* Canonicalize a comparison from one we don't have to one we do have. */
4969+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
4970+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
4971+
4972+/* Dividing the output into sections. */
4973+
4974+/* A C expression whose value is a string containing the assembler operation
4975+ that should precede instructions and read-only data. Normally `".text"' is
4976+ right. */
4977+#define TEXT_SECTION_ASM_OP "\t.section .text"
4978+
4979+/* A C expression whose value is a string containing the assembler operation to
4980+ identify the following data as writable initialized data. Normally
4981+ `".data"' is right. */
4982+#define DATA_SECTION_ASM_OP "\t.section .data"
4983+
4984+
4985+/* If defined, a C expression whose value is a string containing the
4986+ assembler operation to identify the following data as
4987+ uninitialized global data. If not defined, and neither
4988+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
4989+ uninitialized global data will be output in the data section if
4990+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
4991+ used. */
4992+#define BSS_SECTION_ASM_OP "\t.section .bss"
4993+
4994+/* This is how we tell the assembler that a symbol is weak. */
4995+
4996+#define ASM_WEAKEN_LABEL(FILE, NAME) \
4997+ do \
4998+ { \
4999+ fputs ("\t.weak\t", (FILE)); \
5000+ assemble_name ((FILE), (NAME)); \
5001+ fputc ('\n', (FILE)); \
5002+ } \
5003+ while (0)
5004+
5005+/* The Overall Framework of an Assembler File. */
5006+
5007+#undef SET_ASM_OP
5008+#define SET_ASM_OP "\t.set\t"
5009+
5010+/* A C string constant describing how to begin a comment in the target
5011+ assembler language. The compiler assumes that the comment will end at the
5012+ end of the line. */
5013+#define ASM_COMMENT_START ";"
5014+
5015+/* A C string constant for text to be output before each `asm' statement or
5016+ group of consecutive ones. Normally this is `"#APP"', which is a comment
5017+ that has no effect on most assemblers but tells the GNU assembler that it
5018+ must check the lines that follow for all valid assembler constructs. */
5019+#define ASM_APP_ON "#APP\n"
5020+
5021+/* A C string constant for text to be output after each `asm' statement or
5022+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
5023+ GNU assembler to resume making the time-saving assumptions that are valid
5024+ for ordinary compiler output. */
5025+#define ASM_APP_OFF "#NO_APP\n"
5026+
5027+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
5028+ explicit argument. If you define this macro, it is used in place of
5029+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
5030+ alignment of the variable. The alignment is specified as the number of
5031+ bits.
5032+
5033+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
5034+ defining this macro. */
5035+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
5036+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
5037+
5038+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
5039+ newly allocated string made from the string NAME and the number NUMBER, with
5040+ some suitable punctuation added. Use `alloca' to get space for the string.
5041+
5042+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
5043+ an assembler label for an internal static variable whose name is NAME.
5044+ Therefore, the string must be such as to result in valid assembler code.
5045+ The argument NUMBER is different each time this macro is executed; it
5046+ prevents conflicts between similarly-named internal static variables in
5047+ different scopes.
5048+
5049+ Ideally this string should not be a valid C identifier, to prevent any
5050+ conflict with the user's own symbols. Most assemblers allow periods or
5051+ percent signs in assembler symbols; putting at least one of these between
5052+ the name and the number will suffice. */
5053+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
5054+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
5055+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
5056+
5057+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
5058+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
5059+/* A C statement to store into the string STRING a label whose name
5060+ is made from the string PREFIX and the number NUM.
5061+
5062+ This string, when output subsequently by `assemble_name', should
5063+ produce the output that `(*targetm.asm_out.internal_label)' would produce
5064+ with the same PREFIX and NUM.
5065+
5066+ If the string begins with `*', then `assemble_name' will output
5067+ the rest of the string unchanged. It is often convenient for
5068+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
5069+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
5070+ output the string, and may change it. (Of course,
5071+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
5072+ you should know what it does on your machine.) */
5073+
5074+/* This says how to output assembler code to declare an
5075+ uninitialized external linkage data object. Under SVR4,
5076+ the linker seems to want the alignment of data objects
5077+ to depend on their types. We do exactly that here. */
5078+
5079+#define COMMON_ASM_OP "\t.comm\t"
5080+
5081+#undef ASM_OUTPUT_COMMON
5082+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
5083+ do \
5084+ { \
5085+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
5086+ assemble_name ((FILE), (NAME)); \
5087+ fprintf ((FILE), ", %u\n", (SIZE)); \
5088+ } \
5089+ while (0)
5090+
5091+/* This says how to output assembler code to declare an
5092+ uninitialized internal linkage data object. Under SVR4,
5093+ the linker seems to want the alignment of data objects
5094+ to depend on their types. We do exactly that here. */
5095+#define LOCAL_ASM_OP "\t.lcomm\t"
5096+
5097+#undef ASM_OUTPUT_LOCAL
5098+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
5099+ do \
5100+ { \
5101+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
5102+ assemble_name ((FILE), (NAME)); \
5103+ fprintf ((FILE), ", %u\n", (SIZE)); \
5104+ } \
5105+ while (0)
5106+
5107+/* Globalizing directive for a label. */
5108+#define GLOBAL_ASM_OP ".global\t"
5109+
5110+/* Output the operand of an instruction. */
5111+#define PRINT_OPERAND(FILE, X, CODE) \
5112+ ubicom32_print_operand(FILE, X, CODE)
5113+
5114+/* Output the address of an operand. */
5115+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
5116+ ubicom32_print_operand_address (FILE, ADDR)
5117+
5118+/* A C expression to output to STREAM some assembler code which will push hard
5119+ register number REGNO onto the stack. The code need not be optimal, since
5120+ this macro is used only when profiling. */
5121+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
5122+
5123+/* A C expression to output to STREAM some assembler code which will pop hard
5124+ register number REGNO off of the stack. The code need not be optimal, since
5125+ this macro is used only when profiling. */
5126+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
5127+
5128+/* This macro should be provided on machines where the addresses in a dispatch
5129+ table are relative to the table's own address.
5130+
5131+ The definition should be a C statement to output to the stdio stream STREAM
5132+ an assembler pseudo-instruction to generate a difference between two labels.
5133+ VALUE and REL are the numbers of two internal labels. The definitions of
5134+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
5135+ printed in the same way here. For example,
5136+
5137+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
5138+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
5139+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
5140+
5141+/* This macro should be provided on machines where the addresses in a dispatch
5142+ table are absolute.
5143+
5144+ The definition should be a C statement to output to the stdio stream STREAM
5145+ an assembler pseudo-instruction to generate a reference to a label. VALUE
5146+ is the number of an internal label whose definition is output using
5147+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
5148+
5149+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
5150+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
5151+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
5152+
5153+/* Switch into a generic section. */
5154+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
5155+
5156+/* Assembler Commands for Alignment. */
5157+
5158+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
5159+/* A C statement to output to the stdio stream STREAM an assembler
5160+ instruction to advance the location counter by NBYTES bytes.
5161+ Those bytes should be zero when loaded. NBYTES will be a C
5162+ expression of type `int'. */
5163+
5164+/* A C statement to output to the stdio stream STREAM an assembler command to
5165+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
5166+ will be a C expression of type `int'. */
5167+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
5168+ if ((LOG) != 0) \
5169+ fprintf (FILE, "\t.align %d\n", (LOG))
5170+
5171+/* A C expression that returns the DBX register number for the compiler
5172+ register number REGNO. In simple cases, the value of this expression may be
5173+ REGNO itself. But sometimes there are some registers that the compiler
5174+ knows about and DBX does not, or vice versa. In such cases, some register
5175+ may need to have one number in the compiler and another for DBX.
5176+
5177+ If two registers have consecutive numbers inside GNU CC, and they can be
5178+ used as a pair to hold a multiword value, then they *must* have consecutive
5179+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
5180+ will be unable to access such a pair, because they expect register pairs to
5181+ be consecutive in their own numbering scheme.
5182+
5183+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
5184+ preserve register pairs, then what you must do instead is redefine the
5185+ actual register numbering scheme.
5186+
5187+ This declaration is required. */
5188+#define DBX_REGISTER_NUMBER(REGNO) REGNO
5189+
5190+/* A C expression that returns the integer offset value for an automatic
5191+ variable having address X (an RTL expression). The default computation
5192+ assumes that X is based on the frame-pointer and gives the offset from the
5193+ frame-pointer. This is required for targets that produce debugging output
5194+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
5195+ to be eliminated when the `-g' options is used. */
5196+#define DEBUGGER_AUTO_OFFSET(X) \
5197+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
5198+ + (frame_pointer_needed \
5199+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
5200+ STACK_POINTER_REGNUM)))
5201+
5202+/* A C expression that returns the integer offset value for an argument having
5203+ address X (an RTL expression). The nominal offset is OFFSET. */
5204+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
5205+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
5206+ + (frame_pointer_needed \
5207+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
5208+ STACK_POINTER_REGNUM)))
5209+
5210+/* A C expression that returns the type of debugging output GNU CC produces
5211+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
5212+ for GNU CC to support more than one format of debugging output. Currently,
5213+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
5214+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
5215+
5216+ The value of this macro only affects the default debugging output; the user
5217+ can always get a specific type of output by using `-gstabs', `-gcoff',
5218+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
5219+
5220+ Defined in svr4.h.
5221+*/
5222+#undef PREFERRED_DEBUGGING_TYPE
5223+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
5224+
5225+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
5226+ output in response to the `-g' option.
5227+
5228+ To support optional call frame debugging information, you must also define
5229+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
5230+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
5231+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
5232+ don't.
5233+
5234+ Defined in svr4.h. */
5235+
5236+#define DWARF2_DEBUGGING_INFO 1
5237+/*#define DWARF2_UNWIND_INFO 1*/
5238+#define DWARF2_UNWIND_INFO 0
5239+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
5240+#define INCOMING_FRAME_SP_OFFSET 0
5241+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
5242+#define EH_RETURN_FIRST 9
5243+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
5244+
5245+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
5246+ location used to store the amount to ajdust the stack. This is
5247+ usually a registers that is available from end of the function's body
5248+ to the end of the epilogue. Thus, this cannot be a register used as a
5249+ temporary by the epilogue.
5250+
5251+ This must be an integer register. */
5252+#define EH_RETURN_STACKADJ_REGNO 11
5253+#define EH_RETURN_STACKADJ_RTX \
5254+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
5255+
5256+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
5257+ location used to store the address the processor should jump to
5258+ catch exception. This is usually a registers that is available from
5259+ end of the function's body to the end of the epilogue. Thus, this
5260+ cannot be a register used as a temporary by the epilogue.
5261+
5262+ This must be an address register. */
5263+#define EH_RETURN_HANDLER_REGNO 18
5264+#define EH_RETURN_HANDLER_RTX \
5265+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
5266+
5267+/* #define DWARF2_DEBUGGING_INFO */
5268+
5269+/* Define this macro if GNU CC should produce dwarf version 2-style
5270+ line numbers. This usually requires extending the assembler to
5271+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
5272+ assembler configuration header files. */
5273+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
5274+
5275+
5276+/* An alias for a machine mode name. This is the machine mode that elements
5277+ of a jump-table have. */
5278+#define CASE_VECTOR_MODE Pmode
5279+
5280+/* Smallest number of different values for which it is best to use a
5281+ jump-table instead of a tree of conditional branches. For most Ubicom32
5282+ targets this is quite small, but for the v1 architecture implementations
5283+ we had very little data memory and so heavily prefer the tree approach
5284+ rather than the jump tables. */
5285+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
5286+
5287+/* Register operations within the Ubicom32 architecture always operate on
5288+ the whole register word and not just the sub-bits required for the opcode
5289+ mode size. */
5290+#define WORD_REGISTER_OPERATIONS
5291+
5292+/* The maximum number of bytes that a single instruction can move quickly from
5293+ memory to memory. */
5294+#define MOVE_MAX 4
5295+
5296+/* A C expression that is nonzero if on this machine the number of bits
5297+ actually used for the count of a shift operation is equal to the number of
5298+ bits needed to represent the size of the object being shifted. When this
5299+ macro is non-zero, the compiler will assume that it is safe to omit a
5300+ sign-extend, zero-extend, and certain bitwise `and' instructions that
5301+ truncates the count of a shift operation. On machines that have
5302+ instructions that act on bitfields at variable positions, which may include
5303+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
5304+ deletion of truncations of the values that serve as arguments to bitfield
5305+ instructions.
5306+
5307+ If both types of instructions truncate the count (for shifts) and position
5308+ (for bitfield operations), or if no variable-position bitfield instructions
5309+ exist, you should define this macro.
5310+
5311+ However, on some machines, such as the 80386 and the 680x0, truncation only
5312+ applies to shift operations and not the (real or pretended) bitfield
5313+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
5314+ Instead, add patterns to the `md' file that include the implied truncation
5315+ of the shift instructions.
5316+
5317+ You need not define this macro if it would always have the value of zero. */
5318+#define SHIFT_COUNT_TRUNCATED 1
5319+
5320+/* A C expression which is nonzero if on this machine it is safe to "convert"
5321+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
5322+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
5323+
5324+ On many machines, this expression can be 1.
5325+
5326+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
5327+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
5328+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
5329+ things. */
5330+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
5331+
5332+/* A C string constant that tells the GNU CC driver program options to pass
5333+ to the assembler. It can also specify how to translate options you give
5334+ to GNU CC into options for GNU CC to pass to the assembler. See the
5335+ file `sun3.h' for an example of this.
5336+
5337+ Defined in svr4.h. */
5338+#undef ASM_SPEC
5339+#define ASM_SPEC \
5340+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
5341+
5342+#define LINK_SPEC "\
5343+%{h*} %{v:-V} \
5344+%{b} \
5345+%{mfdpic:-melf32ubicom32fdpic -z text} \
5346+%{static:-dn -Bstatic} \
5347+%{shared:-G -Bdynamic} \
5348+%{symbolic:-Bsymbolic} \
5349+%{G*} \
5350+%{YP,*} \
5351+%{Qy:} %{!Qn:-Qy}"
5352+
5353+#undef STARTFILE_SPEC
5354+#undef ENDFILE_SPEC
5355+
5356+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
5357+
5358+#undef LIB_SPEC
5359+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
5360+
5361+#undef HAVE_GAS_SHF_MERGE
5362+#define HAVE_GAS_SHF_MERGE 0
5363+
5364+#define HANDLE_SYSV_PRAGMA 1
5365+#undef HANDLE_PRAGMA_PACK
5366+
5367+typedef void (*ubicom32_func_ptr) (void);
5368+
5369+/* Define builtins for selected special-purpose instructions. */
5370+enum ubicom32_builtins
5371+{
5372+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
5373+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
5374+};
5375+
5376+extern rtx ubicom32_compare_op0;
5377+extern rtx ubicom32_compare_op1;
5378+
5379+#define TYPE_ASM_OP "\t.type\t"
5380+#define TYPE_OPERAND_FMT "@%s"
5381+
5382+#ifndef ASM_DECLARE_RESULT
5383+#define ASM_DECLARE_RESULT(FILE, RESULT)
5384+#endif
5385+
5386+/* These macros generate the special .type and .size directives which
5387+ are used to set the corresponding fields of the linker symbol table
5388+ entries in an ELF object file under SVR4. These macros also output
5389+ the starting labels for the relevant functions/objects. */
5390+
5391+/* Write the extra assembler code needed to declare a function properly.
5392+ Some svr4 assemblers need to also have something extra said about the
5393+ function's return value. We allow for that here. */
5394+
5395+#ifndef ASM_DECLARE_FUNCTION_NAME
5396+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
5397+ do \
5398+ { \
5399+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
5400+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
5401+ ASM_OUTPUT_LABEL (FILE, NAME); \
5402+ } \
5403+ while (0)
5404+#endif
5405--- /dev/null
5406@@ -0,0 +1,3753 @@
5407+; GCC machine description for Ubicom32
5408+;
5409+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
5410+; Foundation, Inc.
5411+; Contributed by Ubicom, Inc.
5412+;
5413+; This file is part of GCC.
5414+;
5415+; GCC is free software; you can redistribute it and/or modify
5416+; it under the terms of the GNU General Public License as published by
5417+; the Free Software Foundation; either version 3, or (at your option)
5418+; any later version.
5419+;
5420+; GCC is distributed in the hope that it will be useful,
5421+; but WITHOUT ANY WARRANTY; without even the implied warranty of
5422+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5423+; GNU General Public License for more details.
5424+;
5425+; You should have received a copy of the GNU General Public License
5426+; along with GCC; see the file COPYING3. If not see
5427+; <http://www.gnu.org/licenses/>.
5428+
5429+(define_constants
5430+ [(AUX_DATA_REGNO 15)
5431+ (LINK_REGNO 21)
5432+ (SP_REGNO 23)
5433+ (ACC0_HI_REGNO 24)
5434+ (ACC1_HI_REGNO 26)
5435+ (CC_REGNO 30)])
5436+
5437+(define_constants
5438+ [(UNSPEC_FDPIC_GOT 0)
5439+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
5440+
5441+(define_constants
5442+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
5443+
5444+;; Types of instructions (for scheduling purposes).
5445+
5446+(define_attr "type" "mul,addr,other"
5447+ (const_string "other"))
5448+
5449+; Define instruction scheduling characteristics. We can only issue
5450+; one instruction per clock so we don't need to define CPU units.
5451+;
5452+(define_automaton "ubicom32")
5453+
5454+(define_cpu_unit "i_pipeline" "ubicom32");
5455+
5456+; We have a 4 cycle hazard associated with address calculations which
5457+; seems rather tricky to avoid so we go with a defensive assumption
5458+; that almost anything can be used to generate addresses.
5459+;
5460+;(define_insn_reservation "ubicom32_other" 4
5461+; (eq_attr "type" "other")
5462+; "i_pipeline")
5463+
5464+; Some moves don't generate hazards.
5465+;
5466+;(define_insn_reservation "ubicom32_addr" 1
5467+; (eq_attr "type" "addr")
5468+; "i_pipeline")
5469+
5470+; We need 3 cycles between a multiply instruction and any use of the
5471+; matching accumulator register(s).
5472+;
5473+(define_insn_reservation "ubicom32_mul" 4
5474+ (eq_attr "type" "mul")
5475+ "i_pipeline")
5476+
5477+(define_attr "length" ""
5478+ (const_int 4))
5479+
5480+(include "predicates.md")
5481+(include "constraints.md")
5482+
5483+; 8-bit move with no change to the flags reg.
5484+;
5485+(define_insn "movqi"
5486+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
5487+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
5488+ ""
5489+ "move.1\\t%0, %1")
5490+
5491+; Combiner-generated 8-bit move with the zero flag set accordingly.
5492+;
5493+(define_insn "movqi_ccszn"
5494+ [(set (reg CC_REGNO)
5495+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
5496+ (const_int 0)))
5497+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
5498+ (match_dup 0))]
5499+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
5500+ "ext.1\\t%1, %0")
5501+
5502+; Combine isn't very good at merging some types of operations so we
5503+; have to make do with a peephole. It's not as effective but it's better
5504+; than doing nothing.
5505+;
5506+(define_peephole2
5507+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
5508+ (match_operand:QI 1 "nonimmediate_operand" ""))
5509+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5510+ (match_operator 3 "ubicom32_compare_operator"
5511+ [(match_dup 0)
5512+ (const_int 0)]))]
5513+ "(GET_MODE (operands[2]) == CCSZNmode
5514+ || GET_MODE (operands[2]) == CCSZmode)"
5515+ [(parallel
5516+ [(set (match_dup 2)
5517+ (match_op_dup 3
5518+ [(match_dup 1)
5519+ (const_int 0)]))
5520+ (set (match_dup 0)
5521+ (match_dup 1))])]
5522+ "")
5523+
5524+; Combine isn't very good at merging some types of operations so we
5525+; have to make do with a peephole. It's not as effective but it's better
5526+; than doing nothing.
5527+;
5528+(define_peephole2
5529+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
5530+ (match_operand:QI 1 "nonimmediate_operand" ""))
5531+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5532+ (match_operator 3 "ubicom32_compare_operator"
5533+ [(match_dup 1)
5534+ (const_int 0)]))]
5535+ "(GET_MODE (operands[2]) == CCSZNmode
5536+ || GET_MODE (operands[2]) == CCSZmode)"
5537+ [(parallel
5538+ [(set (match_dup 2)
5539+ (match_op_dup 3
5540+ [(match_dup 1)
5541+ (const_int 0)]))
5542+ (set (match_dup 0)
5543+ (match_dup 1))])]
5544+ "")
5545+
5546+; 16-bit move with no change to the flags reg.
5547+;
5548+(define_insn "movhi"
5549+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5550+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
5551+ ""
5552+ "*
5553+ {
5554+ if (CONST_INT_P (operands[1]))
5555+ return \"movei\\t%0, %1\";
5556+
5557+ return \"move.2\\t%0, %1\";
5558+ }")
5559+
5560+; Combiner-generated 16-bit move with the zero flag set accordingly.
5561+;
5562+(define_insn "movhi_ccszn"
5563+ [(set (reg CC_REGNO)
5564+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
5565+ (const_int 0)))
5566+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
5567+ (match_dup 0))]
5568+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
5569+ "ext.2\\t%1, %0")
5570+
5571+; Combine isn't very good at merging some types of operations so we
5572+; have to make do with a peephole. It's not as effective but it's better
5573+; than doing nothing.
5574+;
5575+(define_peephole2
5576+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
5577+ (match_operand:HI 1 "nonimmediate_operand" ""))
5578+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5579+ (match_operator 3 "ubicom32_compare_operator"
5580+ [(match_dup 0)
5581+ (const_int 0)]))]
5582+ "(GET_MODE (operands[2]) == CCSZNmode
5583+ || GET_MODE (operands[2]) == CCSZmode)"
5584+ [(parallel
5585+ [(set (match_dup 2)
5586+ (match_op_dup 3
5587+ [(match_dup 1)
5588+ (const_int 0)]))
5589+ (set (match_dup 0)
5590+ (match_dup 1))])]
5591+ "")
5592+
5593+; Combine isn't very good at merging some types of operations so we
5594+; have to make do with a peephole. It's not as effective but it's better
5595+; than doing nothing.
5596+;
5597+(define_peephole2
5598+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
5599+ (match_operand:HI 1 "nonimmediate_operand" ""))
5600+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5601+ (match_operator 3 "ubicom32_compare_operator"
5602+ [(match_dup 1)
5603+ (const_int 0)]))]
5604+ "(GET_MODE (operands[2]) == CCSZNmode
5605+ || GET_MODE (operands[2]) == CCSZmode)"
5606+ [(parallel
5607+ [(set (match_dup 2)
5608+ (match_op_dup 3
5609+ [(match_dup 1)
5610+ (const_int 0)]))
5611+ (set (match_dup 0)
5612+ (match_dup 1))])]
5613+ "")
5614+
5615+; 32-bit move with no change to the flags reg.
5616+;
5617+(define_expand "movsi"
5618+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5619+ (match_operand:SI 1 "general_operand" ""))]
5620+ ""
5621+ "{
5622+ /* Convert any complexities in operand 1 into something that can just
5623+ fall into the default expander code. */
5624+ ubicom32_expand_movsi (operands);
5625+ }")
5626+
5627+(define_insn "movsi_high"
5628+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
5629+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
5630+ ""
5631+ "moveai\\t%0, #%%hi(%E1)")
5632+
5633+(define_insn "movsi_lo_sum"
5634+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5635+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
5636+ (match_operand:SI 2 "immediate_operand" "s")))]
5637+ ""
5638+ "lea.1\\t%0, %%lo(%E2)(%1)")
5639+
5640+(define_insn "movsi_internal"
5641+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5642+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
5643+ ""
5644+ "*
5645+ {
5646+ if (CONST_INT_P (operands[1]))
5647+ {
5648+ ubicom32_emit_move_const_int (operands[0], operands[1]);
5649+ return \"\";
5650+ }
5651+
5652+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
5653+ {
5654+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
5655+
5656+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
5657+ return \"\";
5658+ }
5659+
5660+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
5661+ && register_operand (operands[1], VOIDmode))
5662+ {
5663+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
5664+ return \"lea.1\\t%0, 0(%1)\";
5665+
5666+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
5667+ if (ubicom32_v4)
5668+ return \"movea\\t%0, %1\";
5669+
5670+ return \"move.4\\t%0, %1\";
5671+ }
5672+
5673+ return \"move.4\\t%0, %1\";
5674+ }")
5675+
5676+; If we're not dependent on the state of the condition codes we can construct
5677+; constants of value 2^n by using a bset.
5678+;
5679+(define_peephole2
5680+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5681+ (match_operand:SI 1 "const_int_operand" ""))]
5682+ "(exact_log2 (INTVAL (operands[1])) > 14
5683+ && peep2_regno_dead_p (0, CC_REGNO))"
5684+ [(parallel
5685+ [(set (match_dup 0)
5686+ (ior:SI (const_int 0)
5687+ (match_dup 1)))
5688+ (clobber (reg:CC CC_REGNO))])]
5689+ "")
5690+
5691+; If we're not dependent on the state of the condition codes we can construct
5692+; constants of value ~(2^n) by using a bclr.
5693+;
5694+(define_peephole2
5695+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5696+ (match_operand:SI 1 "const_int_operand" ""))]
5697+ "(exact_log2 (~INTVAL (operands[1])) > 14
5698+ && peep2_regno_dead_p (0, CC_REGNO))"
5699+ [(parallel
5700+ [(set (match_dup 0)
5701+ (and:SI (const_int -1)
5702+ (match_dup 1)))
5703+ (clobber (reg:CC CC_REGNO))])]
5704+ "")
5705+
5706+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
5707+; we can use swapb.4!
5708+;
5709+(define_peephole2
5710+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5711+ (match_operand:SI 1 "const_int_operand" ""))]
5712+ "(ubicom32_v4
5713+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
5714+ && (INTVAL (operands[1]) & 0xffffffff) != 0
5715+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
5716+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
5717+ [(set (match_dup 0)
5718+ (bswap:SI (match_dup 2)))]
5719+ "{
5720+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
5721+ }")
5722+
5723+; If this is a write of a constant to memory look to see if we can usefully
5724+; transform this into 2 smaller writes.
5725+;
5726+(define_peephole2
5727+ [(set (match_operand:SI 0 "memory_operand" "")
5728+ (match_operand:SI 1 "const_int_operand" ""))]
5729+ "! satisfies_constraint_I (operands[1])
5730+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
5731+ [(set (match_dup 4) (match_dup 2))
5732+ (set (match_dup 5) (match_dup 3))]
5733+ "{
5734+ rtx low_hword_addr;
5735+
5736+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5737+ operands[3] = gen_lowpart (HImode, operands[1]);
5738+
5739+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
5740+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
5741+
5742+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
5743+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
5744+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
5745+ }")
5746+
5747+; If we're writing memory and we've not found a better way to do this then
5748+; try loading into a D register and then copying to memory. This will
5749+; perform the fewest possible memory read/writes.
5750+;
5751+(define_peephole2
5752+ [(match_scratch:SI 2 "d")
5753+ (set (match_operand:SI 0 "memory_operand" "")
5754+ (match_operand:SI 1 "const_int_operand" ""))]
5755+ "! satisfies_constraint_I (operands[1])"
5756+ [(set (match_dup 2) (match_dup 1))
5757+ (set (match_dup 0) (match_dup 2))]
5758+ "")
5759+
5760+; If we're not dependent on the state of the condition codes we can construct
5761+; constants of value (2^n - 1) by using an lsr.4.
5762+;
5763+(define_peephole2
5764+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5765+ (match_operand:SI 1 "const_int_operand" ""))]
5766+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5767+ && peep2_regno_dead_p (0, CC_REGNO))"
5768+ [(parallel
5769+ [(set (match_dup 0)
5770+ (lshiftrt:SI (const_int -1)
5771+ (match_dup 2)))
5772+ (clobber (reg:CC CC_REGNO))])]
5773+ "{
5774+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5775+ }")
5776+
5777+; If we're not dependent on the state of the condition codes we can construct
5778+; constants of value (2^n - 1) by using an lsr.4.
5779+;
5780+(define_peephole2
5781+ [(match_scratch:SI 2 "d")
5782+ (set (match_operand:SI 0 "nonimmediate_operand" "")
5783+ (match_operand:SI 1 "const_int_operand" ""))]
5784+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5785+ && peep2_regno_dead_p (0, CC_REGNO))"
5786+ [(parallel
5787+ [(set (match_dup 2)
5788+ (lshiftrt:SI (const_int -1)
5789+ (match_dup 3)))
5790+ (clobber (reg:CC CC_REGNO))])
5791+ (set (match_dup 0)
5792+ (match_dup 2))]
5793+ "{
5794+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5795+ }")
5796+
5797+; If we're not dependent on the state of the condition codes we can construct
5798+; some other constants by using an lsl.4 to shift 7 bits left by some
5799+; constant.
5800+;
5801+(define_peephole2
5802+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5803+ (match_operand:SI 1 "const_int_operand" ""))]
5804+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5805+ && peep2_regno_dead_p (0, CC_REGNO))"
5806+ [(parallel
5807+ [(set (match_dup 0)
5808+ (ashift:SI (match_dup 2)
5809+ (match_dup 3)))
5810+ (clobber (reg:CC CC_REGNO))])]
5811+ "{
5812+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5813+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
5814+ operands[3] = GEN_INT (shift);
5815+ }")
5816+
5817+; If we're not dependent on the state of the condition codes we can construct
5818+; some other constants by using an lsl.4 to shift 7 bits left by some
5819+; constant.
5820+;
5821+(define_peephole2
5822+ [(match_scratch:SI 2 "d")
5823+ (set (match_operand:SI 0 "nonimmediate_operand" "")
5824+ (match_operand:SI 1 "const_int_operand" ""))]
5825+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5826+ && peep2_regno_dead_p (0, CC_REGNO))"
5827+ [(parallel
5828+ [(set (match_dup 2)
5829+ (ashift:SI (match_dup 3)
5830+ (match_dup 4)))
5831+ (clobber (reg:CC CC_REGNO))])
5832+ (set (match_dup 0)
5833+ (match_dup 2))]
5834+ "{
5835+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5836+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
5837+ operands[4] = GEN_INT (shift);
5838+ }")
5839+
5840+; For some 16-bit unsigned constants that have bit 15 set we can use
5841+; swapb.2!
5842+;
5843+; Note that the movsi code emits the same sequence but by using a peephole2
5844+; we split the pattern early enough to allow instruction scheduling to
5845+; occur.
5846+;
5847+(define_peephole2
5848+ [(set (match_operand:SI 0 "register_operand" "")
5849+ (match_operand:SI 1 "const_int_operand" ""))]
5850+ "(ubicom32_v4
5851+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
5852+ [(set (match_dup 0)
5853+ (zero_extend:SI (bswap:HI (match_dup 2))))]
5854+ "{
5855+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
5856+ if (i >= 0x80)
5857+ i -= 0x100;
5858+ operands[2] = GEN_INT (i);
5859+ }")
5860+
5861+; In general for a 16-bit unsigned constant that has bit 15 set
5862+; then we need a movei/move.2 pair unless we can represent it
5863+; via just a move.2.
5864+;
5865+(define_peephole2
5866+ [(set (match_operand:SI 0 "register_operand" "")
5867+ (match_operand:SI 1 "const_int_operand" ""))]
5868+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
5869+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
5870+ [(set (match_dup 2)
5871+ (match_dup 1))
5872+ (set (match_dup 0)
5873+ (zero_extend:SI (match_dup 2)))]
5874+ "{
5875+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
5876+ }")
5877+
5878+; If we're not dependent on the state of the condition codes we can construct
5879+; 32-bit constants that have bits 16 through 31 set to arbitrary values
5880+; and have bits 0 through 15 set to something representable as a default
5881+; source-1 immediate - we use movei/shmrg.2
5882+;
5883+(define_peephole2
5884+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5885+ (match_operand:SI 1 "const_int_operand" ""))]
5886+ "(((INTVAL (operands[1]) >= 0x8000
5887+ && INTVAL (operands[1]) < 0xff80)
5888+ || INTVAL (operands[1]) >= 0x10000
5889+ || INTVAL (operands[1]) < -0x8000)
5890+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5891+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
5892+ && peep2_regno_dead_p (0, CC_REGNO))"
5893+ [(set (match_dup 0)
5894+ (match_dup 2))
5895+ (parallel
5896+ [(set (match_dup 0)
5897+ (ior:SI
5898+ (ashift:SI (match_dup 0)
5899+ (const_int 16))
5900+ (zero_extend:SI
5901+ (match_dup 3))))
5902+ (clobber (reg:CC CC_REGNO))])]
5903+ "{
5904+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5905+ operands[3] = gen_lowpart (HImode, operands[1]);
5906+ }")
5907+
5908+; Exactly the same as the peephole2 preceding except that this targets a
5909+; general register instead of D register. Hopefully the later optimization
5910+; passes will notice that the value ended up in a D register first here
5911+; and eliminate away the other register!
5912+;
5913+(define_peephole2
5914+ [(match_scratch:SI 2 "d")
5915+ (set (match_operand:SI 0 "register_operand" "")
5916+ (match_operand:SI 1 "const_int_operand" ""))]
5917+ "(((INTVAL (operands[1]) >= 0x8000
5918+ && INTVAL (operands[1]) < 0xff80)
5919+ || INTVAL (operands[1]) >= 0x10000
5920+ || INTVAL (operands[1]) < -0x8000)
5921+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5922+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
5923+ && peep2_regno_dead_p (0, CC_REGNO))"
5924+ [(set (match_dup 2)
5925+ (match_dup 3))
5926+ (parallel
5927+ [(set (match_dup 2)
5928+ (ior:SI
5929+ (ashift:SI (match_dup 2)
5930+ (const_int 16))
5931+ (zero_extend:SI
5932+ (match_dup 4))))
5933+ (clobber (reg:CC CC_REGNO))])
5934+ (set (match_dup 0)
5935+ (match_dup 2))]
5936+ "{
5937+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
5938+ operands[4] = gen_lowpart (HImode, operands[1]);
5939+ }")
5940+
5941+; If we have a load of a large integer constant which does not have bit 31
5942+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
5943+; instead. This avoids constructing it in 3 instructions on the stack.
5944+;
5945+; Note that we have to be careful not to match anything that matches
5946+; something we can do in a single instruction! There aren't many such
5947+; constants but there are some.
5948+;
5949+(define_peephole2
5950+ [(match_scratch:SI 2 "a")
5951+ (set (match_operand:SI 0 "register_operand" "")
5952+ (match_operand:SI 1 "const_int_operand" ""))]
5953+ "(! (INTVAL (operands[1]) & 0x80000000)
5954+ && ((INTVAL (operands[1]) >= 0x8000
5955+ && INTVAL (operands[1]) < 0xff80)
5956+ || INTVAL (operands[1]) >= 0x10000))"
5957+ [(set (match_dup 2)
5958+ (match_dup 3))
5959+ (set (match_dup 0)
5960+ (plus:SI (match_dup 2)
5961+ (match_dup 4)))]
5962+ "{
5963+ HOST_WIDE_INT i = INTVAL (operands[1]);
5964+ operands[3] = GEN_INT (i & 0xffffff80);
5965+ operands[4] = GEN_INT (i & 0x7f);
5966+ }")
5967+
5968+; If we're not dependent on the state of the condition codes we can construct
5969+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
5970+;
5971+(define_peephole2
5972+ [(match_scratch:HI 2 "d")
5973+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5974+ (match_operand:SI 1 "const_int_operand" ""))
5975+ (match_dup 2)]
5976+ "(INTVAL (operands[1]) & 0x80000000
5977+ && INTVAL (operands[1]) < -0x8000
5978+ && peep2_regno_dead_p (0, CC_REGNO))"
5979+ [(set (match_dup 0)
5980+ (match_dup 3))
5981+ (set (match_dup 2)
5982+ (match_dup 4))
5983+ (parallel
5984+ [(set (match_dup 0)
5985+ (ior:SI
5986+ (ashift:SI (match_dup 0)
5987+ (const_int 16))
5988+ (zero_extend:SI
5989+ (match_dup 2))))
5990+ (clobber (reg:CC CC_REGNO))])]
5991+ "{
5992+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
5993+ operands[4] = gen_lowpart (HImode, operands[1]);
5994+ }")
5995+
5996+; Exactly the same as the peephole2 preceding except that this targets a
5997+; general register instead of D register. Hopefully the later optimization
5998+; passes will notice that the value ended up in a D register first here
5999+; and eliminate away the other register!
6000+;
6001+(define_peephole2
6002+ [(match_scratch:SI 2 "d")
6003+ (match_scratch:HI 3 "d")
6004+ (set (match_operand:SI 0 "register_operand" "")
6005+ (match_operand:SI 1 "const_int_operand" ""))
6006+ (match_dup 3)]
6007+ "(INTVAL (operands[1]) & 0x80000000
6008+ && INTVAL (operands[1]) < -0x8000
6009+ && peep2_regno_dead_p (0, CC_REGNO))"
6010+ [(set (match_dup 2)
6011+ (match_dup 4))
6012+ (set (match_dup 3)
6013+ (match_dup 5))
6014+ (parallel
6015+ [(set (match_dup 2)
6016+ (ior:SI
6017+ (ashift:SI (match_dup 2)
6018+ (const_int 16))
6019+ (zero_extend:SI
6020+ (match_dup 3))))
6021+ (clobber (reg:CC CC_REGNO))])
6022+ (set (match_dup 0)
6023+ (match_dup 2))]
6024+ "{
6025+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
6026+ operands[5] = gen_lowpart (HImode, operands[1]);
6027+ }")
6028+
6029+(define_insn "movsi_fdpic_got_offset"
6030+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6031+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
6032+ ""
6033+ "movei\\t%0, %1")
6034+
6035+; The explicit MEM inside the UNSPEC prevents the compiler from moving
6036+; the load before a branch after a NULL test, or before a store that
6037+; initializes a function descriptor.
6038+
6039+(define_insn_and_split "load_fdpic_funcdesc"
6040+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
6041+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
6042+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
6043+ ""
6044+ "#"
6045+ "reload_completed"
6046+ [(set (match_dup 0)
6047+ (mem:SI (match_dup 1)))])
6048+
6049+; Combiner-generated 32-bit move with the zero flag set accordingly.
6050+;
6051+(define_insn "movsi_ccwzn"
6052+ [(set (reg CC_REGNO)
6053+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
6054+ (const_int 0)))
6055+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
6056+ (match_dup 0))]
6057+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6058+ "@
6059+ lsl.4\\t%1, %0, #0
6060+ add.4\\t%1, #0, %0")
6061+
6062+; Combiner-generated 32-bit move with all flags set accordingly.
6063+;
6064+(define_insn "movsi_ccw"
6065+ [(set (reg CC_REGNO)
6066+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6067+ (const_int 0)))
6068+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
6069+ (match_dup 0))]
6070+ "ubicom32_match_cc_mode(insn, CCWmode)"
6071+ "add.4\\t%1, #0, %0")
6072+
6073+; Combine isn't very good at merging some types of operations so we
6074+; have to make do with a peephole. It's not as effective but it's better
6075+; than doing nothing.
6076+;
6077+(define_peephole2
6078+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
6079+ (match_operand:SI 1 "nonimmediate_operand" ""))
6080+ (parallel
6081+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6082+ (match_operator 3 "ubicom32_compare_operator"
6083+ [(match_dup 0)
6084+ (const_int 0)]))
6085+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6086+ "(GET_MODE (operands[2]) == CCWZNmode
6087+ || GET_MODE (operands[2]) == CCWZmode)"
6088+ [(parallel
6089+ [(set (match_dup 2)
6090+ (match_op_dup 3
6091+ [(match_dup 1)
6092+ (const_int 0)]))
6093+ (set (match_dup 0)
6094+ (match_dup 1))])]
6095+ "")
6096+
6097+; Combine isn't very good at merging some types of operations so we
6098+; have to make do with a peephole. It's not as effective but it's better
6099+; than doing nothing.
6100+;
6101+(define_peephole2
6102+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
6103+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
6104+ (parallel
6105+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6106+ (match_operator 3 "ubicom32_compare_operator"
6107+ [(match_dup 1)
6108+ (const_int 0)]))
6109+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6110+ "(GET_MODE (operands[2]) == CCWZNmode
6111+ || GET_MODE (operands[2]) == CCWZmode)"
6112+ [(parallel
6113+ [(set (match_dup 2)
6114+ (match_op_dup 3
6115+ [(match_dup 1)
6116+ (const_int 0)]))
6117+ (set (match_dup 0)
6118+ (match_dup 1))])]
6119+ "")
6120+
6121+; Combine isn't very good at merging some types of operations so we
6122+; have to make do with a peephole. It's not as effective but it's better
6123+; than doing nothing.
6124+;
6125+(define_peephole2
6126+ [(set (match_operand:SI 0 "register_operand" "")
6127+ (match_operand:SI 1 "nonimmediate_operand" ""))
6128+ (parallel
6129+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6130+ (match_operator 3 "ubicom32_compare_operator"
6131+ [(match_dup 0)
6132+ (const_int 0)]))
6133+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
6134+ (match_dup 0))])]
6135+ "(peep2_reg_dead_p (2, operands[0])
6136+ && (GET_MODE (operands[2]) == CCWZNmode
6137+ || GET_MODE (operands[2]) == CCWZmode))"
6138+ [(parallel
6139+ [(set (match_dup 2)
6140+ (match_op_dup 3
6141+ [(match_dup 1)
6142+ (const_int 0)]))
6143+ (set (match_dup 4)
6144+ (match_dup 1))])]
6145+ "")
6146+
6147+; Register renaming may make a general reg into a D reg in which case
6148+; we may be able to simplify a compare.
6149+;
6150+(define_peephole2
6151+ [(set (match_operand:SI 0 "register_operand" "")
6152+ (match_operand:SI 1 "nonimmediate_operand" ""))
6153+ (parallel
6154+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6155+ (match_operator 3 "ubicom32_compare_operator"
6156+ [(match_dup 0)
6157+ (const_int 0)]))
6158+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6159+ "(peep2_reg_dead_p (2, operands[0])
6160+ && (GET_MODE (operands[2]) == CCWZNmode
6161+ || GET_MODE (operands[2]) == CCWZmode))"
6162+ [(parallel
6163+ [(set (match_dup 2)
6164+ (match_op_dup 3
6165+ [(match_dup 1)
6166+ (const_int 0)]))
6167+ (clobber (match_dup 4))])]
6168+ "")
6169+
6170+(define_insn_and_split "movdi"
6171+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6172+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
6173+ ""
6174+ "#"
6175+ "reload_completed"
6176+ [(set (match_dup 2) (match_dup 3))
6177+ (set (match_dup 4) (match_dup 5))]
6178+ "{
6179+ rtx dest_low;
6180+ rtx src_low;
6181+
6182+ dest_low = gen_lowpart (SImode, operands[0]);
6183+ src_low = gen_lowpart (SImode, operands[1]);
6184+
6185+ if (REG_P (operands[0])
6186+ && REG_P (operands[1])
6187+ && REGNO (operands[0]) < REGNO (operands[1]))
6188+ {
6189+ operands[2] = gen_highpart (SImode, operands[0]);
6190+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6191+ operands[4] = dest_low;
6192+ operands[5] = src_low;
6193+ }
6194+ else if (reg_mentioned_p (dest_low, src_low))
6195+ {
6196+ operands[2] = gen_highpart (SImode, operands[0]);
6197+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6198+ operands[4] = dest_low;
6199+ operands[5] = src_low;
6200+ }
6201+ else
6202+ {
6203+ operands[2] = dest_low;
6204+ operands[3] = src_low;
6205+ operands[4] = gen_highpart (SImode, operands[0]);
6206+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6207+ }
6208+ }"
6209+ [(set_attr "length" "8")])
6210+
6211+; Combiner-generated 64-bit move with all flags set accordingly.
6212+;
6213+(define_insn "movdi_ccwzn"
6214+ [(set (reg CC_REGNO)
6215+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6216+ (const_int 0)))
6217+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6218+ (match_dup 0))
6219+ (clobber (match_scratch:SI 2 "=X, d, d"))]
6220+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6221+ "*
6222+ {
6223+ operands[3] = gen_lowpart (SImode, operands[0]);
6224+ operands[4] = gen_lowpart (SImode, operands[1]);
6225+ operands[5] = gen_highpart (SImode, operands[0]);
6226+ operands[6] = gen_highpart (SImode, operands[1]);
6227+
6228+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
6229+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6230+
6231+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6232+ }"
6233+ [(set_attr "length" "8")])
6234+
6235+(define_insn "movdi_ccw"
6236+ [(set (reg CC_REGNO)
6237+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6238+ (const_int 0)))
6239+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6240+ (match_dup 0))
6241+ (clobber (match_scratch:SI 2 "=X, d, d"))]
6242+ "ubicom32_match_cc_mode(insn, CCWmode)"
6243+ "*
6244+ {
6245+ operands[3] = gen_lowpart (SImode, operands[0]);
6246+ operands[4] = gen_lowpart (SImode, operands[1]);
6247+ operands[5] = gen_highpart (SImode, operands[0]);
6248+ operands[6] = gen_highpart (SImode, operands[1]);
6249+
6250+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
6251+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6252+
6253+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6254+ }"
6255+ [(set_attr "length" "8")])
6256+
6257+(define_insn "movsf"
6258+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
6259+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
6260+ ""
6261+ "*
6262+ {
6263+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
6264+ {
6265+ HOST_WIDE_INT val;
6266+ REAL_VALUE_TYPE rv;
6267+
6268+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6269+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
6270+
6271+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
6272+ return \"\";
6273+ }
6274+
6275+ return \"move.4\\t%0, %1\";
6276+ }")
6277+
6278+(define_insn "zero_extendqihi2"
6279+ [(set (match_operand:HI 0 "register_operand" "=r")
6280+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6281+ ""
6282+ "move.1\\t%0, %1")
6283+
6284+(define_insn "zero_extendqisi2"
6285+ [(set (match_operand:SI 0 "register_operand" "=r")
6286+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6287+ ""
6288+ "move.1\\t%0, %1")
6289+
6290+(define_insn "zero_extendqisi2_ccwz_1"
6291+ [(set (reg CC_REGNO)
6292+ (compare
6293+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
6294+ (const_int 0)))
6295+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6296+ (zero_extend:SI (match_dup 1)))]
6297+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6298+ "shmrg.1\\t%0, %1, #0")
6299+
6300+(define_insn "zero_extendhisi2"
6301+ [(set (match_operand:SI 0 "register_operand" "=r")
6302+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6303+ ""
6304+ "move.2\\t%0, %1")
6305+
6306+(define_insn "zero_extendhisi2_ccwz_1"
6307+ [(set (reg CC_REGNO)
6308+ (compare
6309+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
6310+ (const_int 0)))
6311+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6312+ (zero_extend:SI (match_dup 1)))]
6313+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6314+ "shmrg.2\\t%0, %1, #0")
6315+
6316+(define_insn_and_split "zero_extendqidi2"
6317+ [(set (match_operand:DI 0 "register_operand" "=r")
6318+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6319+ ""
6320+ "#"
6321+ "reload_completed"
6322+ [(set (match_dup 2)
6323+ (zero_extend:SI (match_dup 1)))
6324+ (set (match_dup 3)
6325+ (const_int 0))]
6326+ "{
6327+ operands[2] = gen_lowpart (SImode, operands[0]);
6328+ operands[3] = gen_highpart (SImode, operands[0]);
6329+ }"
6330+ [(set_attr "length" "8")])
6331+
6332+(define_insn_and_split "zero_extendhidi2"
6333+ [(set (match_operand:DI 0 "register_operand" "=r")
6334+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6335+ ""
6336+ "#"
6337+ "reload_completed"
6338+ [(set (match_dup 2)
6339+ (zero_extend:SI (match_dup 1)))
6340+ (set (match_dup 3)
6341+ (const_int 0))]
6342+ "{
6343+ operands[2] = gen_lowpart (SImode, operands[0]);
6344+ operands[3] = gen_highpart (SImode, operands[0]);
6345+ }"
6346+ [(set_attr "length" "8")])
6347+
6348+(define_insn_and_split "zero_extendsidi2"
6349+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
6350+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6351+ ""
6352+ "#"
6353+ "reload_completed"
6354+ [(set (match_dup 2)
6355+ (match_dup 1))
6356+ (set (match_dup 3)
6357+ (const_int 0))]
6358+ "{
6359+ operands[2] = gen_lowpart (SImode, operands[0]);
6360+ operands[3] = gen_highpart (SImode, operands[0]);
6361+ }"
6362+ [(set_attr "length" "8")])
6363+
6364+(define_insn "extendqihi2"
6365+ [(set (match_operand:HI 0 "register_operand" "=r")
6366+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6367+ (clobber (reg:CC CC_REGNO))]
6368+ ""
6369+ "ext.1\\t%0, %1")
6370+
6371+(define_insn "extendqisi2"
6372+ [(set (match_operand:SI 0 "register_operand" "=r")
6373+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6374+ (clobber (reg:CC CC_REGNO))]
6375+ ""
6376+ "ext.1\\t%0, %1")
6377+
6378+(define_insn "extendhisi2"
6379+ [(set (match_operand:SI 0 "register_operand" "=r")
6380+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
6381+ (clobber (reg:CC CC_REGNO))]
6382+ ""
6383+ "ext.2\\t%0, %1")
6384+
6385+(define_insn_and_split "extendsidi2"
6386+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
6387+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
6388+ (clobber (reg:CC CC_REGNO))]
6389+ ""
6390+ "#"
6391+ "reload_completed"
6392+ [(set (match_dup 2)
6393+ (match_dup 1))
6394+ (parallel
6395+ [(set (match_dup 3)
6396+ (ashiftrt:SI (match_dup 2)
6397+ (const_int 31)))
6398+ (clobber (reg:CC CC_REGNO))])]
6399+ "{
6400+ operands[2] = gen_lowpart (SImode, operands[0]);
6401+ operands[3] = gen_highpart (SImode, operands[0]);
6402+ }"
6403+ [(set_attr "length" "8")])
6404+
6405+(define_insn "bswaphi"
6406+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6407+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6408+ "(ubicom32_v4)"
6409+ "swapb.2\\t%0, %1");
6410+
6411+(define_insn "bswaphisi"
6412+ [(set (match_operand:SI 0 "register_operand" "=r")
6413+ (zero_extend:SI
6414+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
6415+ "(ubicom32_v4)"
6416+ "swapb.2\\t%0, %1");
6417+
6418+(define_insn "bswapsi"
6419+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6420+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
6421+ "(ubicom32_v4)"
6422+ "swapb.4\\t%0, %1");
6423+
6424+(define_insn "tstqi_ext1"
6425+ [(set (reg CC_REGNO)
6426+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
6427+ (const_int 0)))]
6428+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6429+ "ext.1\\t#0, %0")
6430+
6431+(define_expand "cmpqi"
6432+ [(set (reg CC_REGNO)
6433+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
6434+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
6435+ "(ubicom32_v4)"
6436+ "{
6437+ ubicom32_compare_op0 = operands[0];
6438+ ubicom32_compare_op1 = operands[1];
6439+ DONE;
6440+ }")
6441+
6442+(define_insn "sub1_ccs"
6443+ [(set (reg CC_REGNO)
6444+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
6445+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6446+ "(ubicom32_v4)"
6447+ "sub.1\\t#0, %0, %1")
6448+
6449+; If we're testing for equality we don't have to worry about reversing conditions.
6450+;
6451+(define_insn "sub1_ccsz_1"
6452+ [(set (reg:CCSZ CC_REGNO)
6453+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
6454+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6455+ "(ubicom32_v4)"
6456+ "sub.1\\t#0, %0, %1")
6457+
6458+(define_insn "sub1_ccsz_2"
6459+ [(set (reg:CCSZ CC_REGNO)
6460+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
6461+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
6462+ "(ubicom32_v4)"
6463+ "sub.1\\t#0, %1, %0")
6464+
6465+; When the combiner runs it doesn't have any insight into whether or not an argument
6466+; to a compare is spilled to the stack and therefore can't swap the comparison in
6467+; an attempt to use sub.1 more effectively. We peephole this case here.
6468+;
6469+(define_peephole2
6470+ [(set (match_operand:QI 0 "register_operand" "")
6471+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
6472+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6473+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
6474+ (match_dup 0)))
6475+ (set (pc)
6476+ (if_then_else (match_operator 4 "comparison_operator"
6477+ [(match_dup 2)
6478+ (const_int 0)])
6479+ (label_ref (match_operand 5 "" ""))
6480+ (pc)))]
6481+ "(peep2_reg_dead_p (2, operands[0])
6482+ && peep2_regno_dead_p (3, CC_REGNO))"
6483+ [(set (match_dup 2)
6484+ (compare (match_dup 1)
6485+ (match_dup 3)))
6486+ (set (pc)
6487+ (if_then_else (match_op_dup 6
6488+ [(match_dup 2)
6489+ (const_int 0)])
6490+ (label_ref (match_dup 5))
6491+ (pc)))]
6492+ "{
6493+ rtx cc_reg;
6494+
6495+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6496+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6497+ GET_MODE (operands[4]),
6498+ cc_reg,
6499+ const0_rtx);
6500+ }")
6501+
6502+(define_insn "tsthi_ext2"
6503+ [(set (reg CC_REGNO)
6504+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6505+ (const_int 0)))]
6506+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6507+ "ext.2\\t#0, %0")
6508+
6509+(define_expand "cmphi"
6510+ [(set (reg CC_REGNO)
6511+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
6512+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
6513+ ""
6514+ "{
6515+ do
6516+ {
6517+ /* Is this a cmpi? */
6518+ if (CONST_INT_P (operands[1]))
6519+ break;
6520+
6521+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
6522+ if (! ubicom32_data_register_operand (operands[1], HImode))
6523+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
6524+ }
6525+ while (0);
6526+
6527+ ubicom32_compare_op0 = operands[0];
6528+ ubicom32_compare_op1 = operands[1];
6529+ DONE;
6530+ }")
6531+
6532+(define_insn "cmpi"
6533+ [(set (reg CC_REGNO)
6534+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6535+ (match_operand 1 "const_int_operand" "N")))]
6536+ ""
6537+ "cmpi\\t%0, %1")
6538+
6539+(define_insn "sub2_ccs"
6540+ [(set (reg CC_REGNO)
6541+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
6542+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6543+ ""
6544+ "sub.2\\t#0, %0, %1")
6545+
6546+; If we're testing for equality we don't have to worry about reversing conditions.
6547+;
6548+(define_insn "sub2_ccsz_1"
6549+ [(set (reg:CCSZ CC_REGNO)
6550+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
6551+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6552+ ""
6553+ "sub.2\\t#0, %0, %1")
6554+
6555+(define_insn "sub2_ccsz_2"
6556+ [(set (reg:CCSZ CC_REGNO)
6557+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
6558+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6559+ ""
6560+ "sub.2\\t#0, %1, %0")
6561+
6562+; When the combiner runs it doesn't have any insight into whether or not an argument
6563+; to a compare is spilled to the stack and therefore can't swap the comparison in
6564+; an attempt to use sub.2 more effectively. We peephole this case here.
6565+;
6566+(define_peephole2
6567+ [(set (match_operand:HI 0 "register_operand" "")
6568+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
6569+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6570+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
6571+ (match_dup 0)))
6572+ (set (pc)
6573+ (if_then_else (match_operator 4 "comparison_operator"
6574+ [(match_dup 2)
6575+ (const_int 0)])
6576+ (label_ref (match_operand 5 "" ""))
6577+ (pc)))]
6578+ "(peep2_reg_dead_p (2, operands[0])
6579+ && peep2_regno_dead_p (3, CC_REGNO))"
6580+ [(set (match_dup 2)
6581+ (compare (match_dup 1)
6582+ (match_dup 3)))
6583+ (set (pc)
6584+ (if_then_else (match_op_dup 6
6585+ [(match_dup 2)
6586+ (const_int 0)])
6587+ (label_ref (match_dup 5))
6588+ (pc)))]
6589+ "{
6590+ rtx cc_reg;
6591+
6592+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6593+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6594+ GET_MODE (operands[4]),
6595+ cc_reg,
6596+ const0_rtx);
6597+ }")
6598+
6599+(define_insn_and_split "tstsi_lsl4"
6600+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
6601+ (match_operator 1 "ubicom32_compare_operator"
6602+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
6603+ (const_int 0)]))]
6604+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6605+ "#"
6606+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6607+ [(parallel
6608+ [(set (match_dup 0)
6609+ (match_op_dup 1
6610+ [(match_dup 2)
6611+ (const_int 0)]))
6612+ (clobber (match_dup 3))])]
6613+ "{
6614+ operands[3] = gen_reg_rtx (SImode);
6615+ }")
6616+
6617+(define_insn "tstsi_lsl4_d"
6618+ [(set (reg CC_REGNO)
6619+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6620+ (const_int 0)))
6621+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6622+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6623+ "lsl.4\\t%1, %0, #0")
6624+
6625+; Comparison for equality with -1.
6626+;
6627+(define_insn "cmpsi_not4_ccwz"
6628+ [(set (reg CC_REGNO)
6629+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6630+ (const_int -1)))]
6631+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6632+ "not.4\\t#0, %0")
6633+
6634+(define_expand "cmpsi"
6635+ [(set (reg CC_REGNO)
6636+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
6637+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
6638+ ""
6639+ "{
6640+ do
6641+ {
6642+ /* Is this a cmpi? We can't take a memory address as cmpi takes
6643+ 16-bit operands. */
6644+ if (register_operand (operands[0], SImode)
6645+ && CONST_INT_P (operands[1])
6646+ && satisfies_constraint_N (operands[1]))
6647+ break;
6648+
6649+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
6650+ if (! ubicom32_data_register_operand (operands[1], SImode))
6651+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
6652+ }
6653+ while (0);
6654+
6655+ ubicom32_compare_op0 = operands[0];
6656+ ubicom32_compare_op1 = operands[1];
6657+ DONE;
6658+ }")
6659+
6660+(define_insn "cmpsi_cmpi"
6661+ [(set (reg CC_REGNO)
6662+ (compare (match_operand:SI 0 "register_operand" "r")
6663+ (match_operand 1 "const_int_operand" "N")))]
6664+ "(satisfies_constraint_N (operands[1]))"
6665+ "cmpi\\t%0, %1")
6666+
6667+(define_insn "cmpsi_sub4"
6668+ [(set (reg CC_REGNO)
6669+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
6670+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6671+ ""
6672+ "sub.4\\t#0, %0, %1")
6673+
6674+; If we're testing for equality we don't have to worry about reversing conditions.
6675+;
6676+(define_insn "cmpsi_sub4_ccwz_1"
6677+ [(set (reg CC_REGNO)
6678+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6679+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6680+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6681+ "sub.4\\t#0, %0, %1")
6682+
6683+(define_insn "cmpsi_sub4_ccwz_2"
6684+ [(set (reg CC_REGNO)
6685+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6686+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6687+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6688+ "sub.4\\t#0, %1, %0")
6689+
6690+; When the combiner runs it doesn't have any insight into whether or not an argument
6691+; to a compare is spilled to the stack and therefore can't swap the comparison in
6692+; an attempt to use sub.4 more effectively. We peephole this case here.
6693+;
6694+(define_peephole2
6695+ [(set (match_operand:SI 0 "register_operand" "")
6696+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
6697+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6698+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
6699+ (match_dup 0)))
6700+ (set (pc)
6701+ (if_then_else (match_operator 4 "comparison_operator"
6702+ [(match_dup 2)
6703+ (const_int 0)])
6704+ (label_ref (match_operand 5 "" ""))
6705+ (pc)))]
6706+ "(peep2_reg_dead_p (2, operands[0])
6707+ && peep2_regno_dead_p (3, CC_REGNO))"
6708+ [(set (match_dup 2)
6709+ (compare (match_dup 1)
6710+ (match_dup 3)))
6711+ (set (pc)
6712+ (if_then_else (match_op_dup 6
6713+ [(match_dup 2)
6714+ (const_int 0)])
6715+ (label_ref (match_dup 5))
6716+ (pc)))]
6717+ "{
6718+ rtx cc_reg;
6719+
6720+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6721+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6722+ GET_MODE (operands[4]),
6723+ cc_reg,
6724+ const0_rtx);
6725+ }")
6726+
6727+(define_insn_and_split "tstdi_or4"
6728+ [(set (reg:CCWZ CC_REGNO)
6729+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6730+ (const_int 0)))]
6731+ ""
6732+ "#"
6733+ ""
6734+ [(parallel
6735+ [(set (reg:CCWZ CC_REGNO)
6736+ (compare:CCWZ (match_dup 0)
6737+ (const_int 0)))
6738+ (clobber (match_dup 1))])]
6739+ "{
6740+ operands[1] = gen_reg_rtx (SImode);
6741+ }")
6742+
6743+(define_insn "tstdi_or4_d"
6744+ [(set (reg:CCWZ CC_REGNO)
6745+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6746+ (const_int 0)))
6747+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6748+ ""
6749+ "*
6750+ {
6751+ operands[2] = gen_lowpart (SImode, operands[0]);
6752+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
6753+
6754+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
6755+ return \"or.4\\t#0, %2, %3\";
6756+
6757+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
6758+ }"
6759+ [(set_attr "length" "8")])
6760+
6761+(define_expand "cmpdi"
6762+ [(set (reg CC_REGNO)
6763+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
6764+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
6765+ ""
6766+ "{
6767+ ubicom32_compare_op0 = operands[0];
6768+ ubicom32_compare_op1 = operands[1];
6769+ DONE;
6770+ }")
6771+
6772+(define_insn "cmpdi_sub4subc"
6773+ [(set (reg CC_REGNO)
6774+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
6775+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
6776+ ""
6777+ "*
6778+ {
6779+ operands[2] = gen_lowpart (SImode, operands[0]);
6780+ operands[3] = gen_lowpart (SImode, operands[1]);
6781+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
6782+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6783+
6784+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
6785+ }"
6786+ [(set_attr "length" "8")])
6787+
6788+; When the combiner runs it doesn't have any insight into whether or not an argument
6789+; to a compare is spilled to the stack and therefore can't swap the comparison in
6790+; an attempt to use sub.4/subc more effectively. We peephole this case here.
6791+;
6792+(define_peephole2
6793+ [(set (match_operand:DI 0 "register_operand" "")
6794+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
6795+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6796+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
6797+ (match_dup 0)))
6798+ (set (pc)
6799+ (if_then_else (match_operator 4 "comparison_operator"
6800+ [(match_dup 2)
6801+ (const_int 0)])
6802+ (label_ref (match_operand 5 "" ""))
6803+ (pc)))]
6804+ "(peep2_reg_dead_p (2, operands[0])
6805+ && peep2_regno_dead_p (3, CC_REGNO))"
6806+ [(set (match_dup 2)
6807+ (compare (match_dup 1)
6808+ (match_dup 3)))
6809+ (set (pc)
6810+ (if_then_else (match_op_dup 6
6811+ [(match_dup 2)
6812+ (const_int 0)])
6813+ (label_ref (match_dup 5))
6814+ (pc)))]
6815+ "{
6816+ rtx cc_reg;
6817+
6818+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6819+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6820+ GET_MODE (operands[4]),
6821+ cc_reg,
6822+ const0_rtx);
6823+ }")
6824+
6825+(define_insn "btst"
6826+ [(set (reg:CCWZ CC_REGNO)
6827+ (compare:CCWZ
6828+ (zero_extract:SI
6829+ (match_operand:SI 0 "nonimmediate_operand" "rm")
6830+ (const_int 1)
6831+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
6832+ (const_int 0)))]
6833+ ""
6834+ "btst\\t%0, %1")
6835+
6836+(define_insn "bfextu_ccwz_null"
6837+ [(set (reg:CCWZ CC_REGNO)
6838+ (compare:CCWZ
6839+ (zero_extract:SI
6840+ (match_operand:SI 0 "nonimmediate_operand" "rm")
6841+ (match_operand 1 "const_int_operand" "M")
6842+ (const_int 0))
6843+ (const_int 0)))
6844+ (clobber (match_scratch:SI 2 "=d"))]
6845+ ""
6846+ "bfextu\\t%2, %0, %1")
6847+
6848+(define_expand "addqi3"
6849+ [(parallel
6850+ [(set (match_operand:QI 0 "memory_operand" "")
6851+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6852+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
6853+ (clobber (reg:CC CC_REGNO))])]
6854+ "(ubicom32_v4)"
6855+ "{
6856+ if (!memory_operand (operands[0], QImode))
6857+ FAIL;
6858+
6859+ /* If we have a non-data reg for operand 1 then prefer that over
6860+ a CONST_INT in operand 2. */
6861+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6862+ && CONST_INT_P (operands[2]))
6863+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
6864+
6865+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6866+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
6867+ }")
6868+
6869+(define_insn "addqi3_add1"
6870+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
6871+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
6872+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
6873+ (clobber (reg:CC CC_REGNO))]
6874+ "(ubicom32_v4)"
6875+ "@
6876+ add.1\\t%0, %2, %1
6877+ add.1\\t%0, %1, %2")
6878+
6879+(define_insn "addqi3_add1_ccszn_null"
6880+ [(set (reg CC_REGNO)
6881+ (compare
6882+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
6883+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
6884+ "(ubicom32_v4
6885+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
6886+ "@
6887+ add.1\\t#0, %1, %0
6888+ add.1\\t#0, %0, %1")
6889+
6890+(define_expand "addhi3"
6891+ [(parallel
6892+ [(set (match_operand:HI 0 "memory_operand" "")
6893+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6894+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
6895+ (clobber (reg:CC CC_REGNO))])]
6896+ ""
6897+ "{
6898+ if (!memory_operand (operands[0], HImode))
6899+ FAIL;
6900+
6901+ /* If we have a non-data reg for operand 1 then prefer that over
6902+ a CONST_INT in operand 2. */
6903+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6904+ && CONST_INT_P (operands[2]))
6905+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
6906+
6907+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6908+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
6909+ }")
6910+
6911+(define_insn "addhi3_add2"
6912+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
6913+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
6914+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
6915+ (clobber (reg:CC CC_REGNO))]
6916+ ""
6917+ "@
6918+ add.2\\t%0, %2, %1
6919+ add.2\\t%0, %1, %2")
6920+
6921+(define_insn "addhi3_add2_ccszn_null"
6922+ [(set (reg CC_REGNO)
6923+ (compare
6924+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
6925+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
6926+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6927+ "@
6928+ add.2\\t#0, %1, %0
6929+ add.2\\t#0, %0, %1")
6930+
6931+(define_expand "addsi3"
6932+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
6933+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6934+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
6935+ ""
6936+ "{
6937+ ubicom32_expand_addsi3 (operands);
6938+ DONE;
6939+ }")
6940+
6941+; We start with an instruction pattern that can do all sorts of interesting
6942+; things but we split out any uses of lea or pdec instructions because
6943+; those instructions don't clobber the condition codes.
6944+;
6945+(define_insn_and_split "addsi3_1"
6946+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
6947+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
6948+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
6949+ (clobber (reg:CC CC_REGNO))]
6950+ ""
6951+ "@
6952+ #
6953+ #
6954+ #
6955+ #
6956+ #
6957+ add.4\\t%0, %2, %1
6958+ add.4\\t%0, %1, %2"
6959+ "(reload_completed
6960+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
6961+ [(set (match_dup 0)
6962+ (plus:SI (match_dup 1)
6963+ (match_dup 2)))]
6964+ ""
6965+)
6966+
6967+(define_insn "addsi3_1_ccwzn"
6968+ [(set (reg CC_REGNO)
6969+ (compare
6970+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
6971+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
6972+ (const_int 0)))
6973+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
6974+ (plus:SI (match_dup 1)
6975+ (match_dup 2)))]
6976+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6977+ "@
6978+ add.4\\t%0, %2, %1
6979+ add.4\\t%0, %1, %2")
6980+
6981+(define_insn "addsi3_1_ccwzn_null"
6982+ [(set (reg CC_REGNO)
6983+ (compare
6984+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
6985+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
6986+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6987+ "@
6988+ add.4\\t#0, %1, %0
6989+ add.4\\t#0, %0, %1")
6990+
6991+(define_insn_and_split "addsi3_2"
6992+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
6993+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
6994+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
6995+ ""
6996+ "@
6997+ lea.4\\t%0, %E2(%1)
6998+ lea.2\\t%0, %E2(%1)
6999+ lea.1\\t%0, %E2(%1)
7000+ pdec\\t%0, %n2(%1)
7001+ lea.1\\t%0, (%1,%2)
7002+ #"
7003+ "(reload_completed
7004+ && ! satisfies_constraint_L (operands[2])
7005+ && ! satisfies_constraint_K (operands[2])
7006+ && ! satisfies_constraint_J (operands[2])
7007+ && ! satisfies_constraint_P (operands[2])
7008+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
7009+ [(set (reg:SI AUX_DATA_REGNO)
7010+ (match_dup 2))
7011+ (set (match_dup 0)
7012+ (plus:SI (match_dup 1)
7013+ (reg:SI AUX_DATA_REGNO)))]
7014+ ""
7015+)
7016+
7017+(define_insn "lea_2"
7018+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7019+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7020+ (const_int 2))
7021+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7022+ ""
7023+ "lea.2\\t%0, (%2,%1)")
7024+
7025+(define_insn "lea_4"
7026+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7027+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7028+ (const_int 4))
7029+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7030+ ""
7031+ "lea.4\\t%0, (%2,%1)")
7032+
7033+(define_expand "adddi3"