Root/toolchain/gcc/patches/4.4.2/600-ubicom_support.patch

1--- a/config.sub
2+++ b/config.sub
3@@ -283,6 +283,7 @@ case $basic_machine in
4     | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
5     | spu | strongarm \
6     | tahoe | thumb | tic4x | tic80 | tron \
7+ | ubicom32 \
8     | v850 | v850e \
9     | ubicom32 \
10     | we32k \
11@@ -367,6 +368,7 @@ case $basic_machine in
12     | tahoe-* | thumb-* \
13     | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
14     | tron-* \
15+ | ubicom32-* \
16     | v850-* | v850e-* | vax-* \
17     | ubicom32-* \
18     | we32k-* \
19--- a/configure
20+++ b/configure
21@@ -2688,6 +2688,9 @@ case "${target}" in
22   ip2k-*-*)
23     noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
24     ;;
25+ ubicom32-*-*)
26+ noconfigdirs="$noconfigdirs target-libffi"
27+ ;;
28   *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
29     noconfigdirs="$noconfigdirs target-newlib target-libgloss"
30     ;;
31--- /dev/null
32+++ b/gcc/config/ubicom32/constraints.md
33@@ -0,0 +1,149 @@
34+; Constraint definitions for Ubicom32
35+
36+; Copyright (C) 2009 Free Software Foundation, Inc.
37+; Contributed by Ubicom, Inc.
38+
39+; This file is part of GCC.
40+
41+; GCC is free software; you can redistribute it and/or modify it
42+; under the terms of the GNU General Public License as published
43+; by the Free Software Foundation; either version 3, or (at your
44+; option) any later version.
45+
46+; GCC is distributed in the hope that it will be useful, but WITHOUT
47+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
49+; License for more details.
50+
51+; You should have received a copy of the GNU General Public License
52+; along with GCC; see the file COPYING3. If not see
53+; <http://www.gnu.org/licenses/>.
54+
55+(define_register_constraint "a" "ALL_ADDRESS_REGS"
56+ "An An register.")
57+
58+(define_register_constraint "d" "DATA_REGS"
59+ "A Dn register.")
60+
61+(define_register_constraint "h" "ACC_REGS"
62+ "An accumulator register.")
63+
64+(define_register_constraint "l" "ACC_LO_REGS"
65+ "An accn_lo register.")
66+
67+(define_register_constraint "Z" "FDPIC_REG"
68+ "The FD-PIC GOT pointer: A0.")
69+
70+(define_constraint "I"
71+ "An 8-bit signed constant value."
72+ (and (match_code "const_int")
73+ (match_test "(ival >= -128) && (ival <= 127)")))
74+
75+(define_constraint "Q"
76+ "An 8-bit signed constant value represented as unsigned."
77+ (and (match_code "const_int")
78+ (match_test "(ival >= 0x00) && (ival <= 0xff)")))
79+
80+(define_constraint "R"
81+ "An 8-bit signed constant value represented as unsigned."
82+ (and (match_code "const_int")
83+ (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
84+
85+(define_constraint "J"
86+ "A 7-bit unsigned constant value."
87+ (and (match_code "const_int")
88+ (match_test "(ival >= 0) && (ival <= 127)")))
89+
90+(define_constraint "K"
91+ "A 7-bit unsigned constant value shifted << 1."
92+ (and (match_code "const_int")
93+ (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
94+
95+(define_constraint "L"
96+ "A 7-bit unsigned constant value shifted << 2."
97+ (and (match_code "const_int")
98+ (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
99+
100+(define_constraint "M"
101+ "A 5-bit unsigned constant value."
102+ (and (match_code "const_int")
103+ (match_test "(ival >= 0) && (ival <= 31)")))
104+
105+(define_constraint "N"
106+ "A signed 16 bit constant value."
107+ (and (match_code "const_int")
108+ (match_test "(ival >= -32768) && (ival <= 32767)")))
109+
110+(define_constraint "O"
111+ "An exact bitmask of contiguous 1 bits starting at bit 0."
112+ (and (match_code "const_int")
113+ (match_test "exact_log2 (ival + 1) != -1")))
114+
115+(define_constraint "P"
116+ "A 7-bit negative constant value shifted << 2."
117+ (and (match_code "const_int")
118+ (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
119+
120+(define_constraint "S"
121+ "A symbolic reference."
122+ (match_code "symbol_ref"))
123+
124+(define_constraint "Y"
125+ "An FD-PIC symbolic reference."
126+ (and (match_test "TARGET_FDPIC")
127+ (match_test "GET_CODE (op) == UNSPEC")
128+ (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
129+ (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
130+
131+(define_memory_constraint "T1"
132+ "A memory operand that can be used for .1 instruction."
133+ (and (match_test "memory_operand (op, GET_MODE(op))")
134+ (match_test "GET_MODE (op) == QImode")))
135+
136+(define_memory_constraint "T2"
137+ "A memory operand that can be used for .2 instruction."
138+ (and (match_test "memory_operand (op, GET_MODE(op))")
139+ (match_test "GET_MODE (op) == HImode")))
140+
141+(define_memory_constraint "T4"
142+ "A memory operand that can be used for .4 instruction."
143+ (and (match_test "memory_operand (op, GET_MODE(op))")
144+ (ior (match_test "GET_MODE (op) == SImode")
145+ (match_test "GET_MODE (op) == DImode")
146+ (match_test "GET_MODE (op) == SFmode"))))
147+
148+(define_memory_constraint "U1"
149+ "An offsettable memory operand that can be used for .1 instruction."
150+ (and (match_test "memory_operand (op, GET_MODE(op))")
151+ (match_test "GET_MODE (op) == QImode")
152+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
153+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
154+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
155+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
156+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
157+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
158+
159+(define_memory_constraint "U2"
160+ "An offsettable memory operand that can be used for .2 instruction."
161+ (and (match_test "memory_operand (op, GET_MODE(op))")
162+ (match_test "GET_MODE (op) == HImode")
163+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
164+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
165+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
166+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
167+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
168+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
169+
170+(define_memory_constraint "U4"
171+ "An offsettable memory operand that can be used for .4 instruction."
172+ (and (match_test "memory_operand (op, GET_MODE(op))")
173+ (ior (match_test "GET_MODE (op) == SImode")
174+ (match_test "GET_MODE (op) == DImode")
175+ (match_test "GET_MODE (op) == SFmode"))
176+ (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
177+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
178+ (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
179+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
180+ (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
181+ (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
182+
183--- /dev/null
184+++ b/gcc/config/ubicom32/crti.S
185@@ -0,0 +1,54 @@
186+/* Specialized code needed to support construction and destruction of
187+ file-scope objects in C++ and Java code, and to support exception handling.
188+ Copyright (C) 1999 Free Software Foundation, Inc.
189+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
190+
191+This file is part of GCC.
192+
193+GCC is free software; you can redistribute it and/or modify
194+it under the terms of the GNU General Public License as published by
195+the Free Software Foundation; either version 2, or (at your option)
196+any later version.
197+
198+GCC is distributed in the hope that it will be useful,
199+but WITHOUT ANY WARRANTY; without even the implied warranty of
200+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201+GNU General Public License for more details.
202+
203+You should have received a copy of the GNU General Public License
204+along with GCC; see the file COPYING. If not, write to
205+the Free Software Foundation, 59 Temple Place - Suite 330,
206+Boston, MA 02111-1307, USA. */
207+
208+/* As a special exception, if you link this library with files
209+ compiled with GCC to produce an executable, this does not cause
210+ the resulting executable to be covered by the GNU General Public License.
211+ This exception does not however invalidate any other reasons why
212+ the executable file might be covered by the GNU General Public License. */
213+
214+/*
215+ * This file just supplies function prologues for the .init and .fini
216+ * sections. It is linked in before crtbegin.o.
217+ */
218+ .file "crti.o"
219+ .ident "GNU C crti.o"
220+
221+ .section .init
222+ .align 2
223+ .globl _init
224+ .type _init, @function
225+_init:
226+ move.4 -4(sp)++, a5
227+#ifdef __UBICOM32_FDPIC__
228+ move.4 -4(sp)++, a0
229+#endif
230+
231+ .section .fini
232+ .align 2
233+ .globl _fini
234+ .type _fini, @function
235+_fini:
236+ move.4 -4(sp)++, a5
237+#ifdef __UBICOM32_FDPIC__
238+ move.4 -4(sp)++, a0
239+#endif
240--- /dev/null
241+++ b/gcc/config/ubicom32/crtn.S
242@@ -0,0 +1,47 @@
243+/* Specialized code needed to support construction and destruction of
244+ file-scope objects in C++ and Java code, and to support exception handling.
245+ Copyright (C) 1999 Free Software Foundation, Inc.
246+ Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
247+
248+This file is part of GCC.
249+
250+GCC is free software; you can redistribute it and/or modify
251+it under the terms of the GNU General Public License as published by
252+the Free Software Foundation; either version 2, or (at your option)
253+any later version.
254+
255+GCC is distributed in the hope that it will be useful,
256+but WITHOUT ANY WARRANTY; without even the implied warranty of
257+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
258+GNU General Public License for more details.
259+
260+You should have received a copy of the GNU General Public License
261+along with GCC; see the file COPYING. If not, write to
262+the Free Software Foundation, 59 Temple Place - Suite 330,
263+Boston, MA 02111-1307, USA. */
264+
265+/* As a special exception, if you link this library with files
266+ compiled with GCC to produce an executable, this does not cause
267+ the resulting executable to be covered by the GNU General Public License.
268+ This exception does not however invalidate any other reasons why
269+ the executable file might be covered by the GNU General Public License. */
270+
271+/*
272+ * This file supplies function epilogues for the .init and .fini sections.
273+ * It is linked in after all other files.
274+ */
275+
276+ .file "crtn.o"
277+ .ident "GNU C crtn.o"
278+
279+ .section .init
280+#ifdef __UBICOM32_FDPIC__
281+ move.4 a0, (sp)4++
282+#endif
283+ ret (sp)4++
284+
285+ .section .fini
286+#ifdef __UBICOM32_FDPIC__
287+ move.4 a0, (sp)4++
288+#endif
289+ ret (sp)4++
290--- /dev/null
291+++ b/gcc/config/ubicom32/elf.h
292@@ -0,0 +1,29 @@
293+#undef STARTFILE_SPEC
294+#define STARTFILE_SPEC "\
295+%{msim:%{!shared:crt0%O%s}} \
296+crti%O%s crtbegin%O%s"
297+
298+#undef ENDFILE_SPEC
299+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
300+
301+#ifdef __UBICOM32_FDPIC__
302+#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
303+ asm (SECTION_OP); \
304+ asm ("move.4 a0, 0(sp);\n\t" \
305+ "call a5," USER_LABEL_PREFIX #FUNC ";"); \
306+ asm (TEXT_SECTION_ASM_OP);
307+#endif
308+
309+#undef SUBTARGET_DRIVER_SELF_SPECS
310+#define SUBTARGET_DRIVER_SELF_SPECS \
311+ "%{mfdpic:-msim} "
312+
313+#define NO_IMPLICIT_EXTERN_C
314+
315+/*
316+ * We need this to compile crtbegin/crtend. This should really be picked
317+ * up from elfos.h but at the moment including elfos.h causes other more
318+ * serous linker issues.
319+ */
320+#define INIT_SECTION_ASM_OP "\t.section\t.init"
321+#define FINI_SECTION_ASM_OP "\t.section\t.fini"
322--- /dev/null
323+++ b/gcc/config/ubicom32/linux.h
324@@ -0,0 +1,80 @@
325+/* Definitions of target machine for Ubicom32-uclinux
326+
327+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
328+ 2009 Free Software Foundation, Inc.
329+ Contributed by Ubicom, Inc.
330+
331+ This file is part of GCC.
332+
333+ GCC is free software; you can redistribute it and/or modify it
334+ under the terms of the GNU General Public License as published
335+ by the Free Software Foundation; either version 3, or (at your
336+ option) any later version.
337+
338+ GCC is distributed in the hope that it will be useful, but WITHOUT
339+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
340+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
341+ License for more details.
342+
343+ You should have received a copy of the GNU General Public License
344+ along with GCC; see the file COPYING3. If not see
345+ <http://www.gnu.org/licenses/>. */
346+
347+/* Don't assume anything about the header files. */
348+#define NO_IMPLICIT_EXTERN_C
349+
350+#undef LIB_SPEC
351+#define LIB_SPEC \
352+ "%{pthread:-lpthread} " \
353+ "-lc"
354+
355+#undef LINK_GCC_C_SEQUENCE_SPEC
356+#define LINK_GCC_C_SEQUENCE_SPEC \
357+ "%{static:--start-group} %G %L %{static:--end-group} " \
358+ "%{!static: %G}"
359+
360+#undef STARTFILE_SPEC
361+#define STARTFILE_SPEC \
362+ "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
363+ "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
364+
365+#undef ENDFILE_SPEC
366+#define ENDFILE_SPEC \
367+ "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
368+
369+/* taken from linux.h */
370+/* The GNU C++ standard library requires that these macros be defined. */
371+#undef CPLUSPLUS_CPP_SPEC
372+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
373+
374+#define TARGET_OS_CPP_BUILTINS() \
375+ do { \
376+ builtin_define_std ("__UBICOM32__"); \
377+ builtin_define_std ("__ubicom32__"); \
378+ builtin_define ("__gnu_linux__"); \
379+ builtin_define_std ("linux"); \
380+ builtin_define_std ("unix"); \
381+ builtin_assert ("system=linux"); \
382+ builtin_assert ("system=unix"); \
383+ builtin_assert ("system=posix"); \
384+ } while (0)
385+
386+#define OBJECT_FORMAT_ELF
387+
388+
389+#undef DRIVER_SELF_SPECS
390+#define DRIVER_SELF_SPECS \
391+ "%{!mno-fdpic:-mfdpic}"
392+
393+#undef LINK_SPEC
394+#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
395+ %{static:-dn -Bstatic} \
396+ %{shared:-G -Bdynamic} \
397+ %{!shared: %{!static: \
398+ %{rdynamic:-export-dynamic} \
399+ %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
400+ %{static}} "
401+
402+/*
403+#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
404+*/
405--- /dev/null
406+++ b/gcc/config/ubicom32/predicates.md
407@@ -0,0 +1,327 @@
408+; Predicate definitions for Ubicom32.
409+
410+; Copyright (C) 2009 Free Software Foundation, Inc.
411+; Contributed by Ubicom, Inc.
412+
413+; This file is part of GCC.
414+
415+; GCC is free software; you can redistribute it and/or modify it
416+; under the terms of the GNU General Public License as published
417+; by the Free Software Foundation; either version 3, or (at your
418+; option) any later version.
419+
420+; GCC is distributed in the hope that it will be useful, but WITHOUT
421+; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
422+; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
423+; License for more details.
424+
425+; You should have received a copy of the GNU General Public License
426+; along with GCC; see the file COPYING3. If not see
427+; <http://www.gnu.org/licenses/>.
428+
429+(define_predicate "ubicom32_move_operand"
430+ (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
431+{
432+ if (CONST_INT_P (op))
433+ return true;
434+
435+ if (GET_CODE (op) == CONST_DOUBLE)
436+ return true;
437+
438+ if (GET_CODE (op) == CONST)
439+ return memory_address_p (mode, op);
440+
441+ if (GET_MODE (op) != mode)
442+ return false;
443+
444+ if (MEM_P (op))
445+ return memory_address_p (mode, XEXP (op, 0));
446+
447+ if (GET_CODE (op) == SUBREG) {
448+ op = SUBREG_REG (op);
449+
450+ if (REG_P (op))
451+ return true;
452+
453+ if (! MEM_P (op))
454+ return false;
455+
456+ /* Paradoxical SUBREG. */
457+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
458+ return false;
459+
460+ return memory_address_p (GET_MODE (op), XEXP (op, 0));
461+ }
462+
463+ return register_operand (op, mode);
464+})
465+
466+;; Returns true if OP is either a symbol reference or a sum of a
467+;; symbol reference and a constant.
468+
469+(define_predicate "ubicom32_symbolic_address_operand"
470+ (match_code "symbol_ref, label_ref, const")
471+{
472+ switch (GET_CODE (op))
473+ {
474+ case SYMBOL_REF:
475+ case LABEL_REF:
476+ return true;
477+
478+ case CONST:
479+ op = XEXP (op, 0);
480+ return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
481+ || GET_CODE (XEXP (op, 0)) == LABEL_REF)
482+ && CONST_INT_P (XEXP (op, 1)));
483+
484+ default:
485+ return false;
486+ }
487+})
488+
489+;; Return true if operand is the uClinux FD-PIC register.
490+
491+(define_predicate "ubicom32_fdpic_operand"
492+ (match_code "reg")
493+{
494+ if (! TARGET_FDPIC)
495+ return false;
496+
497+ if (!REG_P (op))
498+ return false;
499+
500+ if (GET_MODE (op) != mode && mode != VOIDmode)
501+ return false;
502+
503+ if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
504+ return false;
505+
506+ return true;
507+})
508+
509+(define_predicate "ubicom32_fdpic_got_offset_operand"
510+ (match_code "unspec")
511+{
512+ if (! TARGET_FDPIC)
513+ return false;
514+
515+ if (GET_CODE (op) != UNSPEC)
516+ return false;
517+
518+ if (XINT (op, 1) != UNSPEC_FDPIC_GOT
519+ && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
520+ return false;
521+
522+ return true;
523+})
524+
525+(define_predicate "ubicom32_arith_operand"
526+ (match_code "subreg, reg, const_int, lo_sum, mem")
527+{
528+ return (ubicom32_move_operand (op, mode)
529+ && ! ubicom32_symbolic_address_operand (op, mode)
530+ && (! CONST_INT_P (op)
531+ || satisfies_constraint_I (op)));
532+})
533+
534+(define_predicate "ubicom32_arith_operand_dot1"
535+ (match_code "subreg, reg, const_int, lo_sum, mem")
536+{
537+ return (ubicom32_move_operand (op, mode)
538+ && ! ubicom32_symbolic_address_operand (op, mode)
539+ && (! CONST_INT_P (op)
540+ || satisfies_constraint_Q (op)));
541+})
542+
543+(define_predicate "ubicom32_arith_operand_dot2"
544+ (match_code "subreg, reg, const_int, lo_sum, mem")
545+{
546+ return (ubicom32_move_operand (op, mode)
547+ && ! ubicom32_symbolic_address_operand (op, mode)
548+ && (! CONST_INT_P (op)
549+ || satisfies_constraint_R (op)));
550+})
551+
552+(define_predicate "ubicom32_compare_operand"
553+ (match_code "subreg, reg, const_int, lo_sum, mem")
554+{
555+ return (ubicom32_move_operand (op, mode)
556+ && ! ubicom32_symbolic_address_operand (op, mode)
557+ && (! CONST_INT_P (op)
558+ || satisfies_constraint_N (op)));
559+})
560+
561+(define_predicate "ubicom32_compare_operator"
562+ (match_code "compare"))
563+
564+(define_predicate "ubicom32_and_or_si3_operand"
565+ (match_code "subreg, reg, const_int, lo_sum, mem")
566+{
567+ return (ubicom32_arith_operand (op, mode)
568+ || (CONST_INT_P (op)
569+ && ((exact_log2 (INTVAL (op) + 1) != -1
570+ && exact_log2 (INTVAL (op) + 1) <= 31)
571+ || (exact_log2 (INTVAL (op)) != -1
572+ && exact_log2 (INTVAL (op)) <= 31)
573+ || (exact_log2 (~INTVAL (op)) != -1
574+ && exact_log2 (~INTVAL (op)) <= 31))));
575+})
576+
577+(define_predicate "ubicom32_and_or_hi3_operand"
578+ (match_code "subreg, reg, const_int, lo_sum, mem")
579+{
580+ return (ubicom32_arith_operand (op, mode)
581+ || (CONST_INT_P (op)
582+ && exact_log2 (INTVAL (op) + 1) != -1
583+ && exact_log2 (INTVAL (op) + 1) <= 15));
584+})
585+
586+(define_predicate "ubicom32_mem_or_address_register_operand"
587+ (match_code "subreg, reg, mem")
588+{
589+ unsigned int regno;
590+
591+ if (MEM_P (op)
592+ && memory_operand (op, mode))
593+ return true;
594+
595+ if (REG_P (op))
596+ regno = REGNO (op);
597+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
598+ {
599+ int offset;
600+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
601+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
602+ else
603+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
604+ GET_MODE (SUBREG_REG (op)),
605+ SUBREG_BYTE (op),
606+ GET_MODE (op));
607+ regno = REGNO (SUBREG_REG (op)) + offset;
608+ }
609+ else
610+ return false;
611+
612+ return (regno >= FIRST_PSEUDO_REGISTER
613+ || REGNO_REG_CLASS (regno) == FDPIC_REG
614+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
615+})
616+
617+(define_predicate "ubicom32_data_register_operand"
618+ (match_code "subreg, reg")
619+{
620+ unsigned int regno;
621+
622+ if (REG_P (op))
623+ regno = REGNO (op);
624+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
625+ {
626+ int offset;
627+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
628+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
629+ else
630+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
631+ GET_MODE (SUBREG_REG (op)),
632+ SUBREG_BYTE (op),
633+ GET_MODE (op));
634+ regno = REGNO (SUBREG_REG (op)) + offset;
635+ }
636+ else
637+ return false;
638+
639+ return ((regno >= FIRST_PSEUDO_REGISTER
640+ && regno != REGNO (virtual_stack_vars_rtx))
641+ || REGNO_REG_CLASS (regno) == DATA_REGS);
642+})
643+
644+(define_predicate "ubicom32_address_register_operand"
645+ (match_code "subreg, reg")
646+{
647+ unsigned int regno;
648+
649+ if (REG_P (op))
650+ regno = REGNO (op);
651+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
652+ {
653+ int offset;
654+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
655+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
656+ else
657+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
658+ GET_MODE (SUBREG_REG (op)),
659+ SUBREG_BYTE (op),
660+ GET_MODE (op));
661+ regno = REGNO (SUBREG_REG (op)) + offset;
662+ }
663+ else
664+ return false;
665+
666+ return (regno >= FIRST_PSEUDO_REGISTER
667+ || REGNO_REG_CLASS (regno) == FDPIC_REG
668+ || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
669+})
670+
671+(define_predicate "ubicom32_acc_lo_register_operand"
672+ (match_code "subreg, reg")
673+{
674+ unsigned int regno;
675+
676+ if (REG_P (op))
677+ regno = REGNO (op);
678+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
679+ {
680+ int offset;
681+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
682+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
683+ else
684+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
685+ GET_MODE (SUBREG_REG (op)),
686+ SUBREG_BYTE (op),
687+ GET_MODE (op));
688+ regno = REGNO (SUBREG_REG (op)) + offset;
689+ }
690+ else
691+ return false;
692+
693+ return ((regno >= FIRST_PSEUDO_REGISTER
694+ && regno != REGNO (virtual_stack_vars_rtx))
695+ || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
696+})
697+
698+(define_predicate "ubicom32_acc_hi_register_operand"
699+ (match_code "subreg, reg")
700+{
701+ unsigned int regno;
702+
703+ if (REG_P (op))
704+ regno = REGNO (op);
705+ else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
706+ {
707+ int offset;
708+ if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
709+ offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
710+ else
711+ offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
712+ GET_MODE (SUBREG_REG (op)),
713+ SUBREG_BYTE (op),
714+ GET_MODE (op));
715+ regno = REGNO (SUBREG_REG (op)) + offset;
716+ }
717+ else
718+ return false;
719+
720+ return ((regno >= FIRST_PSEUDO_REGISTER
721+ && regno != REGNO (virtual_stack_vars_rtx))
722+ || REGNO_REG_CLASS (regno) == ACC_REGS);
723+})
724+
725+(define_predicate "ubicom32_call_address_operand"
726+ (match_code "symbol_ref, subreg, reg")
727+{
728+ return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
729+})
730+
731+(define_special_predicate "ubicom32_cc_register_operand"
732+ (and (match_code "reg")
733+ (match_test "REGNO (op) == CC_REGNUM")))
734+
735--- /dev/null
736+++ b/gcc/config/ubicom32/t-ubicom32
737@@ -0,0 +1,52 @@
738+# Name of assembly file containing libgcc1 functions.
739+# This entry must be present, but it can be empty if the target does
740+# not need any assembler functions to support its code generation.
741+CROSS_LIBGCC1 =
742+
743+# Alternatively if assembler functions *are* needed then define the
744+# entries below:
745+# CROSS_LIBGCC1 = libgcc1-asm.a
746+
747+LIB2FUNCS_EXTRA = \
748+ $(srcdir)/config/udivmodsi4.c \
749+ $(srcdir)/config/divmod.c \
750+ $(srcdir)/config/udivmod.c
751+
752+# If any special flags are necessary when building libgcc2 put them here.
753+#
754+# TARGET_LIBGCC2_CFLAGS =
755+
756+# We want fine grained libraries, so use the new code to build the
757+# floating point emulation libraries.
758+FPBIT = fp-bit.c
759+DPBIT = dp-bit.c
760+
761+fp-bit.c: $(srcdir)/config/fp-bit.c
762+ echo '#define FLOAT' > fp-bit.c
763+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
764+
765+dp-bit.c: $(srcdir)/config/fp-bit.c
766+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
767+
768+# Commented out to speed up compiler development!
769+#
770+# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
771+# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
772+
773+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
774+MULTILIB_OPTIONS += mfdpic
775+MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
776+MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
777+
778+# Assemble startup files.
779+$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
780+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
781+ -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
782+
783+$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
784+ $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
785+ -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
786+
787+# these parts are required because uClibc ldso needs them to link.
788+# they are not in the specfile so they will not be included automatically.
789+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
790--- /dev/null
791+++ b/gcc/config/ubicom32/t-ubicom32-linux
792@@ -0,0 +1,35 @@
793+# Name of assembly file containing libgcc1 functions.
794+# This entry must be present, but it can be empty if the target does
795+# not need any assembler functions to support its code generation.
796+CROSS_LIBGCC1 =
797+
798+# Alternatively if assembler functions *are* needed then define the
799+# entries below:
800+# CROSS_LIBGCC1 = libgcc1-asm.a
801+
802+LIB2FUNCS_EXTRA = \
803+ $(srcdir)/config/udivmodsi4.c \
804+ $(srcdir)/config/divmod.c \
805+ $(srcdir)/config/udivmod.c
806+
807+# If any special flags are necessary when building libgcc2 put them here.
808+#
809+# TARGET_LIBGCC2_CFLAGS =
810+
811+# We want fine grained libraries, so use the new code to build the
812+# floating point emulation libraries.
813+FPBIT = fp-bit.c
814+DPBIT = dp-bit.c
815+
816+fp-bit.c: $(srcdir)/config/fp-bit.c
817+ echo '#define FLOAT' > fp-bit.c
818+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
819+
820+dp-bit.c: $(srcdir)/config/fp-bit.c
821+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
822+
823+# We only support v3 and v4 ISAs for uClinux.
824+
825+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
826+
827+#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
828--- /dev/null
829+++ b/gcc/config/ubicom32/t-ubicom32-uclinux
830@@ -0,0 +1,35 @@
831+# Name of assembly file containing libgcc1 functions.
832+# This entry must be present, but it can be empty if the target does
833+# not need any assembler functions to support its code generation.
834+CROSS_LIBGCC1 =
835+
836+# Alternatively if assembler functions *are* needed then define the
837+# entries below:
838+# CROSS_LIBGCC1 = libgcc1-asm.a
839+
840+LIB2FUNCS_EXTRA = \
841+ $(srcdir)/config/udivmodsi4.c \
842+ $(srcdir)/config/divmod.c \
843+ $(srcdir)/config/udivmod.c
844+
845+# If any special flags are necessary when building libgcc2 put them here.
846+#
847+# TARGET_LIBGCC2_CFLAGS =
848+
849+# We want fine grained libraries, so use the new code to build the
850+# floating point emulation libraries.
851+FPBIT = fp-bit.c
852+DPBIT = dp-bit.c
853+
854+fp-bit.c: $(srcdir)/config/fp-bit.c
855+ echo '#define FLOAT' > fp-bit.c
856+ cat $(srcdir)/config/fp-bit.c >> fp-bit.c
857+
858+dp-bit.c: $(srcdir)/config/fp-bit.c
859+ cat $(srcdir)/config/fp-bit.c > dp-bit.c
860+
861+# We only support v3 and v4 ISAs for uClinux.
862+
863+MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
864+
865+EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
866--- /dev/null
867+++ b/gcc/config/ubicom32/ubicom32-modes.def
868@@ -0,0 +1,30 @@
869+/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
870+ Copyright (C) 2009 Free Software Foundation, Inc.
871+ Contributed by Ubicom, Inc.
872+
873+ This file is part of GCC.
874+
875+ GCC is free software; you can redistribute it and/or modify it
876+ under the terms of the GNU General Public License as published
877+ by the Free Software Foundation; either version 3, or (at your
878+ option) any later version.
879+
880+ GCC is distributed in the hope that it will be useful, but WITHOUT
881+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
882+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
883+ License for more details.
884+
885+ You should have received a copy of the GNU General Public License
886+ along with GCC; see the file COPYING3. If not see
887+ <http://www.gnu.org/licenses/>. */
888+
889+/* Some insns set all condition code flags, some only set the Z and N flags, and
890+ some only set the Z flag. */
891+
892+CC_MODE (CCW);
893+CC_MODE (CCWZN);
894+CC_MODE (CCWZ);
895+CC_MODE (CCS);
896+CC_MODE (CCSZN);
897+CC_MODE (CCSZ);
898+
899--- /dev/null
900+++ b/gcc/config/ubicom32/ubicom32-protos.h
901@@ -0,0 +1,84 @@
902+/* Function prototypes for Ubicom IP3000.
903+
904+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
905+ 2009 Free Software Foundation, Inc.
906+ Contributed by Ubicom, Inc.
907+
908+ This file is part of GNU CC.
909+
910+ GNU CC is free software; you can redistribute it and/or modify it under
911+ the terms of the GNU General Public License as published by the Free
912+ Software Foundation; either version 2, or (at your option) any later
913+ version.
914+
915+ GNU CC is distributed in the hope that it will be useful, but WITHOUT
916+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
917+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
918+ for more details.
919+
920+ You should have received a copy of the GNU General Public License along
921+ with GNU CC; see the file COPYING. If not, write to the Free Software
922+ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
923+
924+#ifdef RTX_CODE
925+
926+#ifdef TREE_CODE
927+extern void ubicom32_va_start (tree, rtx);
928+#endif /* TREE_CODE */
929+
930+extern void ubicom32_print_operand (FILE *, rtx, int);
931+extern void ubicom32_print_operand_address (FILE *, rtx);
932+
933+extern void ubicom32_conditional_register_usage (void);
934+extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
935+extern int ubicom32_regno_ok_for_index_p (int, int);
936+extern void ubicom32_expand_movsi (rtx *);
937+extern void ubicom32_expand_addsi3 (rtx *);
938+extern int ubicom32_emit_mult_sequence (rtx *);
939+extern void ubicom32_emit_move_const_int (rtx, rtx);
940+extern bool ubicom32_legitimate_constant_p (rtx);
941+extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
942+extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
943+extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
944+extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
945+extern int ubicom32_mode_dependent_address_p (rtx);
946+extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
947+extern void ubicom32_expand_eh_return (rtx *);
948+extern void ubicom32_expand_call_fdpic (rtx *);
949+extern void ubicom32_expand_call_value_fdpic (rtx *);
950+extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
951+extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
952+extern int ubicom32_shiftable_const_int (int);
953+#endif /* RTX_CODE */
954+
955+#ifdef TREE_CODE
956+extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
957+ tree fntype,
958+ struct rtx_def *libname,
959+ int indirect);
960+extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
961+ enum machine_mode, tree, int);
962+extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
963+ enum machine_mode,
964+ tree, int);
965+extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
966+ enum machine_mode, tree, int);
967+extern struct rtx_def *ubicom32_va_arg (tree, tree);
968+extern int ubicom32_reg_parm_stack_space (tree);
969+#endif /* TREE_CODE */
970+
971+extern struct rtx_def * ubicom32_builtin_saveregs (void);
972+extern void asm_file_start (FILE *);
973+extern void ubicom32_expand_prologue (void);
974+extern void ubicom32_expand_epilogue (void);
975+extern int ubicom32_initial_elimination_offset (int, int);
976+extern int ubicom32_regno_ok_for_base_p (int, int);
977+extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
978+extern int ubicom32_can_use_return_insn_p (void);
979+extern rtx ubicom32_return_addr_rtx (int, rtx);
980+extern void ubicom32_optimization_options (int, int);
981+extern void ubicom32_override_options (void);
982+extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
983+
984+extern int ubicom32_reorg_completed;
985+
986--- /dev/null
987+++ b/gcc/config/ubicom32/ubicom32.c
988@@ -0,0 +1,2881 @@
989+/* Subroutines for insn-output.c for Ubicom32
990+
991+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
992+ 2009 Free Software Foundation, Inc.
993+ Contributed by Ubicom, Inc.
994+
995+ This file is part of GCC.
996+
997+ GCC is free software; you can redistribute it and/or modify it
998+ under the terms of the GNU General Public License as published
999+ by the Free Software Foundation; either version 3, or (at your
1000+ option) any later version.
1001+
1002+ GCC is distributed in the hope that it will be useful, but WITHOUT
1003+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1004+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1005+ License for more details.
1006+
1007+ You should have received a copy of the GNU General Public License
1008+ along with GCC; see the file COPYING3. If not see
1009+ <http://www.gnu.org/licenses/>. */
1010+
1011+#include "config.h"
1012+#include "system.h"
1013+#include "coretypes.h"
1014+#include "tm.h"
1015+#include "rtl.h"
1016+#include "tree.h"
1017+#include "regs.h"
1018+#include "hard-reg-set.h"
1019+#include "real.h"
1020+#include "insn-config.h"
1021+#include "conditions.h"
1022+#include "insn-flags.h"
1023+#include "output.h"
1024+#include "insn-attr.h"
1025+#include "insn-codes.h"
1026+#include "flags.h"
1027+#include "recog.h"
1028+#include "expr.h"
1029+#include "function.h"
1030+#include "obstack.h"
1031+#include "toplev.h"
1032+#include "tm_p.h"
1033+#include "tm-constrs.h"
1034+#include "basic-block.h"
1035+#include "integrate.h"
1036+#include "target.h"
1037+#include "target-def.h"
1038+#include "reload.h"
1039+#include "df.h"
1040+#include "langhooks.h"
1041+#include "optabs.h"
1042+
1043+static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
1044+static void ubicom32_layout_frame (void);
1045+static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
1046+static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
1047+static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
1048+static bool ubicom32_fixed_condition_code_regs (unsigned int *,
1049+ unsigned int *);
1050+static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
1051+ enum machine_mode);
1052+static int ubicom32_naked_function_p (void);
1053+static void ubicom32_machine_dependent_reorg (void);
1054+static bool ubicom32_assemble_integer (rtx, unsigned int, int);
1055+static void ubicom32_asm_init_sections (void);
1056+static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
1057+ bool);
1058+static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1059+ enum machine_mode mode, const_tree type,
1060+ bool named ATTRIBUTE_UNUSED);
1061+static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1062+ enum machine_mode mode, const_tree type,
1063+ bool named ATTRIBUTE_UNUSED);
1064+
1065+static bool ubicom32_return_in_memory (const_tree type,
1066+ const_tree fntype ATTRIBUTE_UNUSED);
1067+static bool ubicom32_is_base_reg (rtx, int);
1068+static void ubicom32_init_builtins (void);
1069+static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1070+static tree ubicom32_fold_builtin (tree, tree, bool);
1071+static int ubicom32_get_valid_offset_mask (enum machine_mode);
1072+static bool ubicom32_cannot_force_const_mem (rtx);
1073+
1074+/* Case values threshold */
1075+int ubicom32_case_values_threshold = 6;
1076+
1077+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
1078+int ubicom32_v3 = 1;
1079+
1080+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
1081+int ubicom32_v4 = 1;
1082+
1083+/* Valid attributes:
1084+ naked - don't generate function prologue/epilogue and `ret' command. */
1085+const struct attribute_spec ubicom32_attribute_table[] =
1086+{
1087+ /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1088+ { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
1089+ { NULL, 0, 0, false, false, false, NULL }
1090+};
1091+
1092+#undef TARGET_ASM_FUNCTION_PROLOGUE
1093+#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
1094+
1095+#undef TARGET_ASM_FUNCTION_EPILOGUE
1096+#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
1097+
1098+#undef TARGET_ATTRIBUTE_TABLE
1099+#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
1100+
1101+/* All addresses cost the same amount. */
1102+#undef TARGET_ADDRESS_COST
1103+#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1104+
1105+#undef TARGET_RTX_COSTS
1106+#define TARGET_RTX_COSTS ubicom32_rtx_costs
1107+
1108+#undef TARGET_FIXED_CONDITION_CODE_REGS
1109+#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
1110+
1111+#undef TARGET_CC_MODES_COMPATIBLE
1112+#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
1113+
1114+#undef TARGET_MACHINE_DEPENDENT_REORG
1115+#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
1116+
1117+#undef TARGET_ASM_INTEGER
1118+#define TARGET_ASM_INTEGER ubicom32_assemble_integer
1119+
1120+#undef TARGET_ASM_INIT_SECTIONS
1121+#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
1122+
1123+#undef TARGET_ARG_PARTIAL_BYTES
1124+#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
1125+
1126+#undef TARGET_PASS_BY_REFERENCE
1127+#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
1128+
1129+#undef TARGET_CALLEE_COPIES
1130+#define TARGET_CALLEE_COPIES ubicom32_callee_copies
1131+
1132+#undef TARGET_RETURN_IN_MEMORY
1133+#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
1134+
1135+#undef TARGET_INIT_BUILTINS
1136+#define TARGET_INIT_BUILTINS ubicom32_init_builtins
1137+
1138+#undef TARGET_EXPAND_BUILTIN
1139+#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
1140+
1141+#undef TARGET_FOLD_BUILTIN
1142+#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
1143+
1144+#undef TARGET_CANNOT_FORCE_CONST_MEM
1145+#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
1146+
1147+struct gcc_target targetm = TARGET_INITIALIZER;
1148+
1149+static char save_regs[FIRST_PSEUDO_REGISTER];
1150+static int nregs;
1151+static int frame_size;
1152+int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
1153+int ubicom32_can_use_calli_to_ret;
1154+
1155+#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
1156+#define ROUND_CALL_BLOCK_SIZE(BYTES) \
1157+ (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
1158+
1159+/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
1160+ must report the mode of the memory reference from PRINT_OPERAND to
1161+ PRINT_OPERAND_ADDRESS. */
1162+enum machine_mode output_memory_reference_mode;
1163+
1164+/* Flag for some split insns from the ubicom32.md. */
1165+int ubicom32_reorg_completed;
1166+
1167+enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
1168+{
1169+ DATA_REGS,
1170+ DATA_REGS,
1171+ DATA_REGS,
1172+ DATA_REGS,
1173+ DATA_REGS,
1174+ DATA_REGS,
1175+ DATA_REGS,
1176+ DATA_REGS,
1177+ DATA_REGS,
1178+ DATA_REGS,
1179+ DATA_REGS,
1180+ DATA_REGS,
1181+ DATA_REGS,
1182+ DATA_REGS,
1183+ DATA_REGS,
1184+ DATA_REGS,
1185+ FDPIC_REG,
1186+ ADDRESS_REGS,
1187+ ADDRESS_REGS,
1188+ ADDRESS_REGS,
1189+ ADDRESS_REGS,
1190+ ADDRESS_REGS,
1191+ ADDRESS_REGS,
1192+ ADDRESS_REGS,
1193+ ACC_REGS,
1194+ ACC_LO_REGS,
1195+ ACC_REGS,
1196+ ACC_LO_REGS,
1197+ SOURCE3_REG,
1198+ ADDRESS_REGS,
1199+ NO_REGS, /* CC_REG must be NO_REGS */
1200+ SPECIAL_REGS,
1201+ SPECIAL_REGS,
1202+ SPECIAL_REGS,
1203+ SPECIAL_REGS,
1204+ SPECIAL_REGS,
1205+ SPECIAL_REGS,
1206+ SPECIAL_REGS,
1207+ SPECIAL_REGS
1208+};
1209+
1210+rtx ubicom32_compare_op0;
1211+rtx ubicom32_compare_op1;
1212+
1213+/* Handle command line option overrides. */
1214+
1215+void
1216+ubicom32_override_options (void)
1217+{
1218+ flag_pic = 0;
1219+
1220+ if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
1221+ /* If we have a version 1 architecture then we want to avoid using jump
1222+ tables. */
1223+ ubicom32_case_values_threshold = 30000;
1224+ ubicom32_v3 = 0;
1225+ ubicom32_v4 = 0;
1226+ } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
1227+ ubicom32_v3 = 0;
1228+ ubicom32_v4 = 0;
1229+ } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
1230+ ubicom32_v3 = 1;
1231+ ubicom32_v4 = 0;
1232+ } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
1233+ ubicom32_v3 = 1;
1234+ ubicom32_v4 = 1;
1235+ }
1236+
1237+ /* There is no single unaligned SI op for PIC code. Sometimes we
1238+ need to use ".4byte" and sometimes we need to use ".picptr".
1239+ See ubicom32_assemble_integer for details. */
1240+ if (TARGET_FDPIC)
1241+ targetm.asm_out.unaligned_op.si = 0;
1242+}
1243+
1244+void
1245+ubicom32_conditional_register_usage (void)
1246+{
1247+ /* If we're using the old ipOS ABI we need to make D10 through D13
1248+ caller-clobbered. */
1249+ if (TARGET_IPOS_ABI)
1250+ {
1251+ call_used_regs[D10_REGNUM] = 1;
1252+ call_used_regs[D11_REGNUM] = 1;
1253+ call_used_regs[D12_REGNUM] = 1;
1254+ call_used_regs[D13_REGNUM] = 1;
1255+ }
1256+}
1257+
1258+/* We have some number of optimizations that don't really work for the Ubicom32
1259+ architecture so we deal with them here. */
1260+
1261+void
1262+ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
1263+ int size ATTRIBUTE_UNUSED)
1264+{
1265+ /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
1266+ architecture - it tends to turn things that would happily use pre/post
1267+ increment/decrement into operations involving unecessary loop
1268+ indicies. */
1269+ flag_ivopts = 0;
1270+
1271+ /* We have problems where DSE at the RTL level misses partial stores
1272+ to the stack. For now we disable it to avoid this. */
1273+ flag_dse = 0;
1274+}
1275+
1276+/* Print operand X using operand code CODE to assembly language output file
1277+ FILE. */
1278+
1279+void
1280+ubicom32_print_operand (FILE *file, rtx x, int code)
1281+{
1282+ switch (code)
1283+ {
1284+ case 'A':
1285+ /* Identify the correct accumulator to use. */
1286+ if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
1287+ fprintf (file, "acc0");
1288+ else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
1289+ fprintf (file, "acc1");
1290+ else
1291+ abort ();
1292+ break;
1293+
1294+ case 'b':
1295+ case 'B':
1296+ {
1297+ enum machine_mode mode;
1298+
1299+ mode = GET_MODE (XEXP (x, 0));
1300+
1301+ /* These are normal and reversed branches. */
1302+ switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
1303+ {
1304+ case NE:
1305+ fprintf (file, "ne");
1306+ break;
1307+
1308+ case EQ:
1309+ fprintf (file, "eq");
1310+ break;
1311+
1312+ case GE:
1313+ if (mode == CCSZNmode || mode == CCWZNmode)
1314+ fprintf (file, "pl");
1315+ else
1316+ fprintf (file, "ge");
1317+ break;
1318+
1319+ case GT:
1320+ fprintf (file, "gt");
1321+ break;
1322+
1323+ case LE:
1324+ fprintf (file, "le");
1325+ break;
1326+
1327+ case LT:
1328+ if (mode == CCSZNmode || mode == CCWZNmode)
1329+ fprintf (file, "mi");
1330+ else
1331+ fprintf (file, "lt");
1332+ break;
1333+
1334+ case GEU:
1335+ fprintf (file, "cs");
1336+ break;
1337+
1338+ case GTU:
1339+ fprintf (file, "hi");
1340+ break;
1341+
1342+ case LEU:
1343+ fprintf (file, "ls");
1344+ break;
1345+
1346+ case LTU:
1347+ fprintf (file, "cc");
1348+ break;
1349+
1350+ default:
1351+ abort ();
1352+ }
1353+ }
1354+ break;
1355+
1356+ case 'C':
1357+ /* This is used for the operand to a call instruction;
1358+ if it's a REG, enclose it in parens, else output
1359+ the operand normally. */
1360+ if (REG_P (x))
1361+ {
1362+ fputc ('(', file);
1363+ ubicom32_print_operand (file, x, 0);
1364+ fputc (')', file);
1365+ }
1366+ else
1367+ ubicom32_print_operand (file, x, 0);
1368+ break;
1369+
1370+ case 'd':
1371+ /* Bit operations we need bit numbers. */
1372+ fprintf (file, "%d", exact_log2 (INTVAL (x)));
1373+ break;
1374+
1375+ case 'D':
1376+ /* Bit operations we need bit numbers. */
1377+ fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
1378+ break;
1379+
1380+ case 'E':
1381+ /* For lea, which we use to add address registers.
1382+ We don't want the '#' on a constant. */
1383+ if (CONST_INT_P (x))
1384+ {
1385+ fprintf (file, "%ld", INTVAL (x));
1386+ break;
1387+ }
1388+ /* FALL THROUGH */
1389+
1390+ default:
1391+ switch (GET_CODE (x))
1392+ {
1393+ case MEM:
1394+ output_memory_reference_mode = GET_MODE (x);
1395+ output_address (XEXP (x, 0));
1396+ break;
1397+
1398+ case PLUS:
1399+ output_address (x);
1400+ break;
1401+
1402+ case REG:
1403+ fprintf (file, "%s", reg_names[REGNO (x)]);
1404+ break;
1405+
1406+ case SUBREG:
1407+ fprintf (file, "%s", reg_names[subreg_regno (x)]);
1408+ break;
1409+
1410+ /* This will only be single precision.... */
1411+ case CONST_DOUBLE:
1412+ {
1413+ unsigned long val;
1414+ REAL_VALUE_TYPE rv;
1415+
1416+ REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1417+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1418+ fprintf (file, "0x%lx", val);
1419+ break;
1420+ }
1421+
1422+ case CONST_INT:
1423+ case SYMBOL_REF:
1424+ case CONST:
1425+ case LABEL_REF:
1426+ case CODE_LABEL:
1427+ case LO_SUM:
1428+ ubicom32_print_operand_address (file, x);
1429+ break;
1430+
1431+ case HIGH:
1432+ fprintf (file, "#%%hi(");
1433+ ubicom32_print_operand_address (file, XEXP (x, 0));
1434+ fprintf (file, ")");
1435+ break;
1436+
1437+ case UNSPEC:
1438+ switch (XINT (x, 1))
1439+ {
1440+ case UNSPEC_FDPIC_GOT:
1441+ fprintf (file, "#%%got_lo(");
1442+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1443+ fprintf (file, ")");
1444+ break;
1445+
1446+ case UNSPEC_FDPIC_GOT_FUNCDESC:
1447+ fprintf (file, "#%%got_funcdesc_lo(");
1448+ ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1449+ fprintf (file, ")");
1450+ break;
1451+
1452+ default:
1453+ abort ();
1454+ }
1455+ break;
1456+
1457+ default:
1458+ abort ();
1459+ }
1460+ break;
1461+ }
1462+}
1463+
1464+/* Output assembly language output for the address ADDR to FILE. */
1465+
1466+void
1467+ubicom32_print_operand_address (FILE *file, rtx addr)
1468+{
1469+ switch (GET_CODE (addr))
1470+ {
1471+ case POST_INC:
1472+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1473+ fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
1474+ break;
1475+
1476+ case PRE_INC:
1477+ fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
1478+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1479+ fprintf (file, "++");
1480+ break;
1481+
1482+ case POST_DEC:
1483+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1484+ fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
1485+ break;
1486+
1487+ case PRE_DEC:
1488+ fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
1489+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1490+ fprintf (file, "++");
1491+ break;
1492+
1493+ case POST_MODIFY:
1494+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1495+ fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
1496+ break;
1497+
1498+ case PRE_MODIFY:
1499+ fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
1500+ ubicom32_print_operand_address (file, XEXP (addr, 0));
1501+ fprintf (file, "++");
1502+ break;
1503+
1504+ case REG:
1505+ fputc ('(', file);
1506+ fprintf (file, "%s", reg_names[REGNO (addr)]);
1507+ fputc (')', file);
1508+ break;
1509+
1510+ case PLUS:
1511+ {
1512+ rtx base = XEXP (addr, 0);
1513+ rtx index = XEXP (addr, 1);
1514+
1515+ /* Switch around addresses of the form index * scaling + base. */
1516+ if (! ubicom32_is_base_reg (base, 1))
1517+ {
1518+ rtx tmp = base;
1519+ base = index;
1520+ index = tmp;
1521+ }
1522+
1523+ if (CONST_INT_P (index))
1524+ {
1525+ fprintf (file, "%ld", INTVAL (index));
1526+ fputc ('(', file);
1527+ fputs (reg_names[REGNO (base)], file);
1528+ }
1529+ else if (GET_CODE (index) == MULT
1530+ || REG_P (index))
1531+ {
1532+ if (GET_CODE (index) == MULT)
1533+ index = XEXP (index, 0);
1534+ fputc ('(', file);
1535+ fputs (reg_names[REGNO (base)], file);
1536+ fputc (',', file);
1537+ fputs (reg_names[REGNO (index)], file);
1538+ }
1539+ else
1540+ abort ();
1541+
1542+ fputc (')', file);
1543+ break;
1544+ }
1545+
1546+ case LO_SUM:
1547+ fprintf (file, "%%lo(");
1548+ ubicom32_print_operand (file, XEXP (addr, 1), 'L');
1549+ fprintf (file, ")(");
1550+ ubicom32_print_operand (file, XEXP (addr, 0), 0);
1551+ fprintf (file, ")");
1552+ break;
1553+
1554+ case CONST_INT:
1555+ fputc ('#', file);
1556+ output_addr_const (file, addr);
1557+ break;
1558+
1559+ default:
1560+ output_addr_const (file, addr);
1561+ break;
1562+ }
1563+}
1564+
1565+/* X and Y are two things to compare using CODE. Emit the compare insn and
1566+ return the rtx for the cc reg in the proper mode. */
1567+
1568+rtx
1569+ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
1570+{
1571+ enum machine_mode mode = SELECT_CC_MODE (code, x, y);
1572+ rtx cc_reg;
1573+
1574+ cc_reg = gen_rtx_REG (mode, CC_REGNUM);
1575+
1576+ emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
1577+ gen_rtx_COMPARE (mode, x, y)));
1578+
1579+ return cc_reg;
1580+}
1581+
1582+/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1583+ return the mode to be used for the comparison. */
1584+
1585+enum machine_mode
1586+ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1587+{
1588+ /* Is this a short compare? */
1589+ if (GET_MODE (x) == QImode
1590+ || GET_MODE (x) == HImode
1591+ || GET_MODE (y) == QImode
1592+ || GET_MODE (y) == HImode)
1593+ {
1594+ switch (op)
1595+ {
1596+ case EQ :
1597+ case NE :
1598+ return CCSZmode;
1599+
1600+ case GE:
1601+ case LT:
1602+ if (y == const0_rtx)
1603+ return CCSZNmode;
1604+
1605+ default :
1606+ return CCSmode;
1607+ }
1608+ }
1609+
1610+ /* We have a word compare. */
1611+ switch (op)
1612+ {
1613+ case EQ :
1614+ case NE :
1615+ return CCWZmode;
1616+
1617+ case GE :
1618+ case LT :
1619+ if (y == const0_rtx)
1620+ return CCWZNmode;
1621+
1622+ default :
1623+ return CCWmode;
1624+ }
1625+}
1626+
1627+/* Return TRUE or FALSE depending on whether the first SET in INSN
1628+ has source and destination with matching CC modes, and that the
1629+ CC mode is at least as constrained as REQ_MODE. */
1630+bool
1631+ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
1632+{
1633+ rtx set;
1634+ enum machine_mode set_mode;
1635+
1636+ set = PATTERN (insn);
1637+ if (GET_CODE (set) == PARALLEL)
1638+ set = XVECEXP (set, 0, 0);
1639+ gcc_assert (GET_CODE (set) == SET);
1640+ gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
1641+
1642+ /* SET_MODE is the mode we have in the instruction. This must either
1643+ be the same or less restrictive that the required mode REQ_MODE. */
1644+ set_mode = GET_MODE (SET_DEST (set));
1645+
1646+ switch (req_mode)
1647+ {
1648+ case CCSZmode:
1649+ if (set_mode != CCSZmode)
1650+ return 0;
1651+ break;
1652+
1653+ case CCSZNmode:
1654+ if (set_mode != CCSZmode
1655+ && set_mode != CCSZNmode)
1656+ return 0;
1657+ break;
1658+
1659+ case CCSmode:
1660+ if (set_mode != CCSmode
1661+ && set_mode != CCSZmode
1662+ && set_mode != CCSZNmode)
1663+ return 0;
1664+ break;
1665+
1666+ case CCWZmode:
1667+ if (set_mode != CCWZmode)
1668+ return 0;
1669+ break;
1670+
1671+ case CCWZNmode:
1672+ if (set_mode != CCWZmode
1673+ && set_mode != CCWZNmode)
1674+ return 0;
1675+ break;
1676+
1677+ case CCWmode:
1678+ if (set_mode != CCWmode
1679+ && set_mode != CCWZmode
1680+ && set_mode != CCWZNmode)
1681+ return 0;
1682+ break;
1683+
1684+ default:
1685+ gcc_unreachable ();
1686+ }
1687+
1688+ return (GET_MODE (SET_SRC (set)) == set_mode);
1689+}
1690+
1691+/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1692+ that we can implement more efficiently. */
1693+
1694+void
1695+ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
1696+{
1697+ /* If we have a REG and a MEM then compare the MEM with the REG and not
1698+ the other way round. */
1699+ if (REG_P (*op0) && MEM_P (*op1))
1700+ {
1701+ rtx tem = *op0;
1702+ *op0 = *op1;
1703+ *op1 = tem;
1704+ *code = swap_condition (*code);
1705+ return;
1706+ }
1707+
1708+ /* If we have a REG and a CONST_INT then we may want to reverse things
1709+ if the constant can be represented as an "I" constraint. */
1710+ if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
1711+ {
1712+ rtx tem = *op0;
1713+ *op0 = *op1;
1714+ *op1 = tem;
1715+ *code = swap_condition (*code);
1716+ return;
1717+ }
1718+}
1719+
1720+/* Return the fixed registers used for condition codes. */
1721+
1722+static bool
1723+ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
1724+{
1725+ *p1 = CC_REGNUM;
1726+ *p2 = INVALID_REGNUM;
1727+
1728+ return true;
1729+}
1730+
1731+/* If two condition code modes are compatible, return a condition code
1732+ mode which is compatible with both. Otherwise, return
1733+ VOIDmode. */
1734+
1735+static enum machine_mode
1736+ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
1737+{
1738+ if (m1 == m2)
1739+ return m1;
1740+
1741+ if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
1742+ return VOIDmode;
1743+
1744+ switch (m1)
1745+ {
1746+ case CCWmode:
1747+ if (m2 == CCWZNmode || m2 == CCWZmode)
1748+ return m1;
1749+
1750+ return VOIDmode;
1751+
1752+ case CCWZNmode:
1753+ if (m2 == CCWmode)
1754+ return m2;
1755+
1756+ if (m2 == CCWZmode)
1757+ return m1;
1758+
1759+ return VOIDmode;
1760+
1761+ case CCWZmode:
1762+ if (m2 == CCWmode || m2 == CCWZNmode)
1763+ return m2;
1764+
1765+ return VOIDmode;
1766+
1767+ case CCSmode:
1768+ if (m2 == CCSZNmode || m2 == CCSZmode)
1769+ return m1;
1770+
1771+ return VOIDmode;
1772+
1773+ case CCSZNmode:
1774+ if (m2 == CCSmode)
1775+ return m2;
1776+
1777+ if (m2 == CCSZmode)
1778+ return m1;
1779+
1780+ return VOIDmode;
1781+
1782+ case CCSZmode:
1783+ if (m2 == CCSmode || m2 == CCSZNmode)
1784+ return m2;
1785+
1786+ return VOIDmode;
1787+
1788+ default:
1789+ gcc_unreachable ();
1790+ }
1791+}
1792+
1793+static rtx
1794+ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
1795+{
1796+ int unspec;
1797+ rtx got_offs;
1798+ rtx got_offs_scaled;
1799+ rtx plus_scaled;
1800+ rtx tmp;
1801+ rtx new_rtx;
1802+
1803+ gcc_assert (reg != 0);
1804+
1805+ if (GET_CODE (orig) == SYMBOL_REF
1806+ && SYMBOL_REF_FUNCTION_P (orig))
1807+ unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
1808+ else
1809+ unspec = UNSPEC_FDPIC_GOT;
1810+
1811+ got_offs = gen_reg_rtx (SImode);
1812+ tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
1813+ emit_move_insn (got_offs, tmp);
1814+
1815+ got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
1816+ plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
1817+ new_rtx = gen_const_mem (Pmode, plus_scaled);
1818+ emit_move_insn (reg, new_rtx);
1819+
1820+ return reg;
1821+}
1822+
1823+static rtx
1824+ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
1825+{
1826+ rtx addr = orig;
1827+ rtx new_rtx = orig;
1828+
1829+ if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1830+ {
1831+ rtx base;
1832+
1833+ if (GET_CODE (addr) == CONST)
1834+ {
1835+ addr = XEXP (addr, 0);
1836+ gcc_assert (GET_CODE (addr) == PLUS);
1837+ }
1838+
1839+ base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
1840+ return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
1841+ }
1842+
1843+ return new_rtx;
1844+}
1845+
1846+/* Code generation. */
1847+
1848+void
1849+ubicom32_expand_movsi (rtx *operands)
1850+{
1851+ if (GET_CODE (operands[1]) == SYMBOL_REF
1852+ || (GET_CODE (operands[1]) == CONST
1853+ && GET_CODE (XEXP (operands[1], 0)) == PLUS
1854+ && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
1855+ || CONSTANT_ADDRESS_P (operands[1]))
1856+ {
1857+ if (TARGET_FDPIC)
1858+ {
1859+ rtx tmp;
1860+ rtx fdpic_reg;
1861+
1862+ gcc_assert (can_create_pseudo_p ());
1863+ tmp = gen_reg_rtx (Pmode);
1864+ fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
1865+ if (GET_CODE (operands[1]) == SYMBOL_REF
1866+ || GET_CODE (operands[1]) == LABEL_REF)
1867+ operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
1868+ else
1869+ operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
1870+ }
1871+ else
1872+ {
1873+ rtx tmp;
1874+ enum machine_mode mode;
1875+
1876+ /* We want to avoid reusing operand 0 if we can because it limits
1877+ our ability to optimize later. */
1878+ tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
1879+
1880+ mode = GET_MODE (operands[0]);
1881+ emit_insn (gen_rtx_SET (VOIDmode, tmp,
1882+ gen_rtx_HIGH (mode, operands[1])));
1883+ operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
1884+ if (can_create_pseudo_p() && ! REG_P (operands[0]))
1885+ {
1886+ tmp = gen_reg_rtx (mode);
1887+ emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
1888+ operands[1] = tmp;
1889+ }
1890+ }
1891+ }
1892+}
1893+
1894+/* Emit code for addsi3. */
1895+
1896+void
1897+ubicom32_expand_addsi3 (rtx *operands)
1898+{
1899+ rtx op, clob;
1900+
1901+ if (can_create_pseudo_p ())
1902+ {
1903+ /* If we have a non-data reg for operand 1 then prefer that over
1904+ a CONST_INT in operand 2. */
1905+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
1906+ && CONST_INT_P (operands[2]))
1907+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
1908+
1909+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
1910+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
1911+ }
1912+
1913+ /* Emit the instruction. */
1914+
1915+ op = gen_rtx_SET (VOIDmode, operands[0],
1916+ gen_rtx_PLUS (SImode, operands[1], operands[2]));
1917+
1918+ if (! can_create_pseudo_p ())
1919+ {
1920+ /* Reload doesn't know about the flags register, and doesn't know that
1921+ it doesn't want to clobber it. We can only do this with PLUS. */
1922+ emit_insn (op);
1923+ }
1924+ else
1925+ {
1926+ clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1927+ emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1928+ }
1929+}
1930+
1931+/* Emit code for mulsi3. Return 1 if we have generated all the code
1932+ necessary to do the multiplication. */
1933+
1934+int
1935+ubicom32_emit_mult_sequence (rtx *operands)
1936+{
1937+ if (! ubicom32_v4)
1938+ {
1939+ rtx a1, a1_1, a2;
1940+ rtx b1, b1_1, b2;
1941+ rtx mac_lo_rtx;
1942+ rtx t1, t2, t3;
1943+
1944+ /* Give up if we cannot create new pseudos. */
1945+ if (!can_create_pseudo_p())
1946+ return 0;
1947+
1948+ /* Synthesize 32-bit multiplication using 16-bit operations:
1949+
1950+ a1 = highpart (a)
1951+ a2 = lowpart (a)
1952+
1953+ b1 = highpart (b)
1954+ b2 = lowpart (b)
1955+
1956+ c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1957+ = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1958+ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
1959+ Signed Signed Unsigned */
1960+
1961+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
1962+ {
1963+ rtx op1;
1964+
1965+ op1 = gen_reg_rtx (SImode);
1966+ emit_move_insn (op1, operands[1]);
1967+ operands[1] = op1;
1968+ }
1969+
1970+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
1971+ {
1972+ rtx op2;
1973+
1974+ op2 = gen_reg_rtx (SImode);
1975+ emit_move_insn (op2, operands[2]);
1976+ operands[2] = op2;
1977+ }
1978+
1979+ /* a1 = highpart (a) */
1980+ a1 = gen_reg_rtx (HImode);
1981+ a1_1 = gen_reg_rtx (SImode);
1982+ emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
1983+ emit_move_insn (a1, gen_lowpart (HImode, a1_1));
1984+
1985+ /* a2 = lowpart (a) */
1986+ a2 = gen_reg_rtx (HImode);
1987+ emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
1988+
1989+ /* b1 = highpart (b) */
1990+ b1 = gen_reg_rtx (HImode);
1991+ b1_1 = gen_reg_rtx (SImode);
1992+ emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
1993+ emit_move_insn (b1, gen_lowpart (HImode, b1_1));
1994+
1995+ /* b2 = lowpart (b) */
1996+ b2 = gen_reg_rtx (HImode);
1997+ emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
1998+
1999+ /* t1 = (a1 * b2) << 16 */
2000+ t1 = gen_reg_rtx (SImode);
2001+ mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
2002+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
2003+ emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
2004+
2005+ /* t2 = (a2 * b1) << 16 */
2006+ t2 = gen_reg_rtx (SImode);
2007+ emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
2008+ emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
2009+
2010+ /* mac_lo = a2 * b2 */
2011+ emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
2012+
2013+ /* t3 = t1 + t2 */
2014+ t3 = gen_reg_rtx (SImode);
2015+ emit_insn (gen_addsi3 (t3, t1, t2));
2016+
2017+ /* c = t3 + mac_lo_rtx */
2018+ emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
2019+
2020+ return 1;
2021+ }
2022+ else
2023+ {
2024+ rtx acc_rtx;
2025+
2026+ /* Give up if we cannot create new pseudos. */
2027+ if (!can_create_pseudo_p())
2028+ return 0;
2029+
2030+ if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
2031+ {
2032+ rtx op1;
2033+
2034+ op1 = gen_reg_rtx (SImode);
2035+ emit_move_insn (op1, operands[1]);
2036+ operands[1] = op1;
2037+ }
2038+
2039+ if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
2040+ {
2041+ rtx op2;
2042+
2043+ op2 = gen_reg_rtx (SImode);
2044+ emit_move_insn (op2, operands[2]);
2045+ operands[2] = op2;
2046+ }
2047+
2048+ acc_rtx = gen_reg_rtx (DImode);
2049+ emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
2050+ emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
2051+
2052+ return 1;
2053+ }
2054+}
2055+
2056+/* Move the integer value VAL into OPERANDS[0]. */
2057+
2058+void
2059+ubicom32_emit_move_const_int (rtx dest, rtx imm)
2060+{
2061+ rtx xoperands[2];
2062+
2063+ xoperands[0] = dest;
2064+ xoperands[1] = imm;
2065+
2066+ /* Treat mem destinations separately. Values must be explicitly sign
2067+ extended. */
2068+ if (MEM_P (dest))
2069+ {
2070+ rtx low_hword_mem;
2071+ rtx low_hword_addr;
2072+
2073+ /* Emit shorter sequence for signed 7-bit quantities. */
2074+ if (satisfies_constraint_I (imm))
2075+ {
2076+ output_asm_insn ("move.4\t%0, %1", xoperands);
2077+ return;
2078+ }
2079+
2080+ /* Special case for pushing constants. */
2081+ if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
2082+ && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
2083+ {
2084+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2085+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2086+ return;
2087+ }
2088+
2089+ /* See if we can add 2 to the original address. This is only
2090+ possible if the original address is of the form REG or
2091+ REG+const. */
2092+ low_hword_addr = plus_constant (XEXP (dest, 0), 2);
2093+ if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
2094+ {
2095+ low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
2096+ MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
2097+ output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
2098+ xoperands[0] = low_hword_mem;
2099+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2100+ return;
2101+ }
2102+
2103+ /* The original address is too complex. We need to use a
2104+ scratch memory by (sp) and move that to the original
2105+ destination. */
2106+ if (! reg_mentioned_p (stack_pointer_rtx, dest))
2107+ {
2108+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2109+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2110+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2111+ return;
2112+ }
2113+
2114+ /* Our address mentions the stack pointer so we need to
2115+ use our scratch data register here as well as scratch
2116+ memory. */
2117+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2118+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2119+ output_asm_insn ("move.4\td15, (sp)4++", xoperands);
2120+ output_asm_insn ("move.4\t%0, d15", xoperands);
2121+ return;
2122+ }
2123+
2124+ /* Move into registers are zero extended by default. */
2125+ if (! REG_P (dest))
2126+ abort ();
2127+
2128+ if (satisfies_constraint_N (imm))
2129+ {
2130+ output_asm_insn ("movei\t%0, %1", xoperands);
2131+ return;
2132+ }
2133+
2134+ if (INTVAL (xoperands[1]) >= 0xff80
2135+ && INTVAL (xoperands[1]) < 0x10000)
2136+ {
2137+ xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
2138+ output_asm_insn ("move.2\t%0, %1", xoperands);
2139+ return;
2140+ }
2141+
2142+ if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
2143+ || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
2144+ && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
2145+ {
2146+ output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
2147+ if ((INTVAL (xoperands[1]) & 0x7f) != 0)
2148+ output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
2149+ return;
2150+ }
2151+
2152+ if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
2153+ {
2154+ output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2155+ output_asm_insn ("move.2\t%0, %0", xoperands);
2156+ return;
2157+ }
2158+
2159+ /* This is very expensive. The constant is so large that we
2160+ need to use the stack to do the load. */
2161+ output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2162+ output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2163+ output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2164+}
2165+
2166+/* Stack layout. Prologue/Epilogue. */
2167+
2168+static int save_regs_size;
2169+
2170+static void
2171+ubicom32_layout_frame (void)
2172+{
2173+ int regno;
2174+
2175+ memset ((char *) &save_regs[0], 0, sizeof (save_regs));
2176+ nregs = 0;
2177+ frame_size = get_frame_size ();
2178+
2179+ if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
2180+ {
2181+ save_regs[FRAME_POINTER_REGNUM] = 1;
2182+ ++nregs;
2183+ }
2184+
2185+ if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
2186+ ubicom32_can_use_calli_to_ret = 1;
2187+ else
2188+ {
2189+ ubicom32_can_use_calli_to_ret = 0;
2190+ save_regs[LINK_REGNO] = 1;
2191+ ++nregs;
2192+ }
2193+
2194+ /* Figure out which register(s) needs to be saved. */
2195+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
2196+ if (df_regs_ever_live_p(regno)
2197+ && ! call_used_regs[regno]
2198+ && ! fixed_regs[regno]
2199+ && ! save_regs[regno])
2200+ {
2201+ save_regs[regno] = 1;
2202+ ++nregs;
2203+ }
2204+
2205+ save_regs_size = 4 * nregs;
2206+}
2207+
2208+static void
2209+ubicom32_emit_add_movsi (int regno, int adj)
2210+{
2211+ rtx x;
2212+ rtx reg = gen_rtx_REG (SImode, regno);
2213+
2214+ adj += 4;
2215+ if (adj > 8 * 4)
2216+ {
2217+ x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2218+ GEN_INT (-adj)));
2219+ RTX_FRAME_RELATED_P (x) = 1;
2220+ x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
2221+ }
2222+ else
2223+ {
2224+ rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
2225+ gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2226+ GEN_INT (-adj)));
2227+ x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
2228+ }
2229+ RTX_FRAME_RELATED_P (x) = 1;
2230+}
2231+
2232+void
2233+ubicom32_expand_prologue (void)
2234+{
2235+ rtx x;
2236+ int regno;
2237+ int outgoing_args_size = crtl->outgoing_args_size;
2238+ int adj;
2239+
2240+ if (ubicom32_naked_function_p ())
2241+ return;
2242+
2243+ ubicom32_builtin_saveregs ();
2244+
2245+ ubicom32_layout_frame ();
2246+ adj = (outgoing_args_size + get_frame_size () + save_regs_size
2247+ + crtl->args.pretend_args_size);
2248+
2249+ if (!adj)
2250+ ;
2251+ else if (outgoing_args_size + save_regs_size < 508
2252+ && get_frame_size () + save_regs_size > 508)
2253+ {
2254+ int i = 0;
2255+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2256+ GEN_INT (-adj));
2257+ x = emit_insn (x);
2258+ RTX_FRAME_RELATED_P (x) = 1;
2259+
2260+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2261+ if (save_regs[regno] && regno != LINK_REGNO)
2262+ {
2263+ x = gen_rtx_MEM (SImode,
2264+ gen_rtx_PLUS (Pmode,
2265+ stack_pointer_rtx,
2266+ GEN_INT (i * 4 + outgoing_args_size)));
2267+ x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
2268+ RTX_FRAME_RELATED_P (x) = 1;
2269+ ++i;
2270+ }
2271+ if (save_regs[LINK_REGNO])
2272+ {
2273+ x = gen_rtx_MEM (SImode,
2274+ gen_rtx_PLUS (Pmode,
2275+ stack_pointer_rtx,
2276+ GEN_INT (i * 4 + outgoing_args_size)));
2277+ x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
2278+ RTX_FRAME_RELATED_P (x) = 1;
2279+ }
2280+ }
2281+ else
2282+ {
2283+ int regno;
2284+ int adj = get_frame_size () + crtl->args.pretend_args_size;
2285+ int i = 0;
2286+
2287+ if (save_regs[LINK_REGNO])
2288+ {
2289+ ubicom32_emit_add_movsi (LINK_REGNO, adj);
2290+ ++i;
2291+ }
2292+
2293+ for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
2294+ if (save_regs[regno] && regno != LINK_REGNO)
2295+ {
2296+ if (i)
2297+ {
2298+ rtx mem = gen_rtx_MEM (SImode,
2299+ gen_rtx_PRE_DEC (Pmode,
2300+ stack_pointer_rtx));
2301+ x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
2302+ RTX_FRAME_RELATED_P (x) = 1;
2303+ }
2304+ else
2305+ ubicom32_emit_add_movsi (regno, adj);
2306+ ++i;
2307+ }
2308+
2309+ if (outgoing_args_size || (!i && adj))
2310+ {
2311+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2312+ GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
2313+ x = emit_insn (x);
2314+ RTX_FRAME_RELATED_P (x) = 1;
2315+ }
2316+ }
2317+
2318+ if (frame_pointer_needed)
2319+ {
2320+ int fp_adj = save_regs_size + outgoing_args_size;
2321+ x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
2322+ GEN_INT (fp_adj));
2323+ x = emit_insn (x);
2324+ RTX_FRAME_RELATED_P (x) = 1;
2325+ }
2326+}
2327+
2328+void
2329+ubicom32_expand_epilogue (void)
2330+{
2331+ rtx x;
2332+ int regno;
2333+ int outgoing_args_size = crtl->outgoing_args_size;
2334+ int adj;
2335+ int i;
2336+
2337+ if (ubicom32_naked_function_p ())
2338+ {
2339+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
2340+ LINK_REGNO)));
2341+ return;
2342+ }
2343+
2344+ if (cfun->calls_alloca)
2345+ {
2346+ x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
2347+ GEN_INT (-save_regs_size));
2348+ emit_insn (x);
2349+ outgoing_args_size = 0;
2350+ }
2351+
2352+ if (outgoing_args_size)
2353+ {
2354+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2355+ GEN_INT (outgoing_args_size));
2356+ emit_insn (x);
2357+ }
2358+
2359+ i = 0;
2360+ for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2361+ if (save_regs[regno] && regno != LINK_REGNO)
2362+ {
2363+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2364+ emit_move_insn (gen_rtx_REG (SImode, regno), x);
2365+ ++i;
2366+ }
2367+
2368+ /* Do we have to adjust the stack after we've finished restoring regs? */
2369+ adj = get_frame_size() + crtl->args.pretend_args_size;
2370+ if (cfun->stdarg)
2371+ adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2372+
2373+#if 0
2374+ if (crtl->calls_eh_return && 0)
2375+ {
2376+ if (save_regs[LINK_REGNO])
2377+ {
2378+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2379+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2380+ }
2381+
2382+ if (adj)
2383+ {
2384+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2385+ GEN_INT (adj));
2386+ x = emit_insn (x);
2387+ }
2388+
2389+ /* Perform the additional bump for __throw. */
2390+ emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2391+ EH_RETURN_STACKADJ_RTX));
2392+ emit_jump_insn (gen_eh_return_internal ());
2393+ return;
2394+ }
2395+#endif
2396+
2397+ if (save_regs[LINK_REGNO])
2398+ {
2399+ if (adj >= 4 && adj <= (6 * 4))
2400+ {
2401+ x = GEN_INT (adj + 4);
2402+ emit_jump_insn (gen_return_from_post_modify_sp (x));
2403+ return;
2404+ }
2405+
2406+ if (adj == 0)
2407+ {
2408+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2409+ emit_jump_insn (gen_return_internal (x));
2410+ return;
2411+ }
2412+
2413+ x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2414+ emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2415+ }
2416+
2417+ if (adj)
2418+ {
2419+ x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2420+ GEN_INT (adj));
2421+ x = emit_insn (x);
2422+ adj = 0;
2423+ }
2424+
2425+ /* Given that we've just done all the hard work here we may as well use
2426+ a calli to return. */
2427+ ubicom32_can_use_calli_to_ret = 1;
2428+ emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
2429+}
2430+
2431+void
2432+ubicom32_expand_call_fdpic (rtx *operands)
2433+{
2434+ rtx c;
2435+ rtx addr;
2436+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2437+
2438+ addr = XEXP (operands[0], 0);
2439+
2440+ c = gen_call_fdpic (addr, operands[1], fdpic_reg);
2441+ emit_call_insn (c);
2442+}
2443+
2444+void
2445+ubicom32_expand_call_value_fdpic (rtx *operands)
2446+{
2447+ rtx c;
2448+ rtx addr;
2449+ rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2450+
2451+ addr = XEXP (operands[1], 0);
2452+
2453+ c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
2454+ emit_call_insn (c);
2455+}
2456+
2457+void
2458+ubicom32_expand_eh_return (rtx *operands)
2459+{
2460+ if (REG_P (operands[0])
2461+ || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
2462+ {
2463+ rtx sp = EH_RETURN_STACKADJ_RTX;
2464+ emit_move_insn (sp, operands[0]);
2465+ operands[0] = sp;
2466+ }
2467+
2468+ if (REG_P (operands[1])
2469+ || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
2470+ {
2471+ rtx ra = EH_RETURN_HANDLER_RTX;
2472+ emit_move_insn (ra, operands[1]);
2473+ operands[1] = ra;
2474+ }
2475+}
2476+
2477+/* Compute the offsets between eliminable registers. */
2478+
2479+int
2480+ubicom32_initial_elimination_offset (int from, int to)
2481+{
2482+ ubicom32_layout_frame ();
2483+ if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2484+ return save_regs_size + crtl->outgoing_args_size;
2485+
2486+ if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
2487+ return get_frame_size ()/* + save_regs_size */;
2488+
2489+ if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2490+ return get_frame_size ()
2491+ + crtl->outgoing_args_size
2492+ + save_regs_size;
2493+
2494+ return 0;
2495+}
2496+
2497+/* Return 1 if it is appropriate to emit `ret' instructions in the
2498+ body of a function. Do this only if the epilogue is simple, needing a
2499+ couple of insns. Prior to reloading, we can't tell how many registers
2500+ must be saved, so return 0 then. Return 0 if there is no frame
2501+ marker to de-allocate.
2502+
2503+ If NON_SAVING_SETJMP is defined and true, then it is not possible
2504+ for the epilogue to be simple, so return 0. This is a special case
2505+ since NON_SAVING_SETJMP will not cause regs_ever_live to change
2506+ until final, but jump_optimize may need to know sooner if a
2507+ `return' is OK. */
2508+
2509+int
2510+ubicom32_can_use_return_insn_p (void)
2511+{
2512+ if (! reload_completed || frame_pointer_needed)
2513+ return 0;
2514+
2515+ return 1;
2516+}
2517+
2518+/* Attributes and CC handling. */
2519+
2520+/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2521+ struct attribute_spec.handler. */
2522+static tree
2523+ubicom32_handle_fndecl_attribute (tree *node, tree name,
2524+ tree args ATTRIBUTE_UNUSED,
2525+ int flags ATTRIBUTE_UNUSED,
2526+ bool *no_add_attrs)
2527+{
2528+ if (TREE_CODE (*node) != FUNCTION_DECL)
2529+ {
2530+ warning ("'%s' attribute only applies to functions",
2531+ IDENTIFIER_POINTER (name));
2532+ *no_add_attrs = true;
2533+ }
2534+
2535+ return NULL_TREE;
2536+}
2537+
2538+/* A C expression that places additional restrictions on the register class to
2539+ use when it is necessary to copy value X into a register in class CLASS.
2540+ The value is a register class; perhaps CLASS, or perhaps another, smaller
2541+ class. On many machines, the following definition is safe:
2542+
2543+ #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
2544+
2545+ Sometimes returning a more restrictive class makes better code. For
2546+ example, on the 68000, when X is an integer constant that is in range for a
2547+ `moveq' instruction, the value of this macro is always `DATA_REGS' as long
2548+ as CLASS includes the data registers. Requiring a data register guarantees
2549+ that a `moveq' will be used.
2550+
2551+ If X is a `const_double', by returning `NO_REGS' you can force X into a
2552+ memory constant. This is useful on certain machines where immediate
2553+ floating values cannot be loaded into certain kinds of registers. */
2554+
2555+enum reg_class
2556+ubicom32_preferred_reload_class (rtx x, enum reg_class class)
2557+{
2558+ /* If a symbolic constant, HIGH or a PLUS is reloaded,
2559+ it is most likely being used as an address, so
2560+ prefer ADDRESS_REGS. If 'class' is not a superset
2561+ of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
2562+ if (GET_CODE (x) == PLUS
2563+ || GET_CODE (x) == HIGH
2564+ || GET_CODE (x) == LABEL_REF
2565+ || GET_CODE (x) == SYMBOL_REF
2566+ || GET_CODE (x) == CONST)
2567+ {
2568+ if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
2569+ return ALL_ADDRESS_REGS;
2570+
2571+ return NO_REGS;
2572+ }
2573+
2574+ return class;
2575+}
2576+
2577+/* Function arguments and varargs. */
2578+
2579+int
2580+ubicom32_reg_parm_stack_space (tree fndecl)
2581+{
2582+ return 0;
2583+
2584+ if (fndecl
2585+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
2586+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
2587+ != void_type_node))
2588+ return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2589+
2590+ return 0;
2591+}
2592+
2593+/* Flush the argument registers to the stack for a stdarg function;
2594+ return the new argument pointer. */
2595+
2596+rtx
2597+ubicom32_builtin_saveregs (void)
2598+{
2599+ int regno;
2600+
2601+ if (! cfun->stdarg)
2602+ return 0;
2603+
2604+ for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
2605+ emit_move_insn (gen_rtx_MEM (SImode,
2606+ gen_rtx_PRE_DEC (SImode,
2607+ stack_pointer_rtx)),
2608+ gen_rtx_REG (SImode, regno));
2609+
2610+ return stack_pointer_rtx;
2611+}
2612+
2613+void
2614+ubicom32_va_start (tree valist, rtx nextarg)
2615+{
2616+ std_expand_builtin_va_start (valist, nextarg);
2617+}
2618+
2619+rtx
2620+ubicom32_va_arg (tree valist, tree type)
2621+{
2622+ HOST_WIDE_INT size, rsize;
2623+ tree addr, incr, tmp;
2624+ rtx addr_rtx;
2625+ int indirect = 0;
2626+
2627+ /* Round up sizeof(type) to a word. */
2628+ size = int_size_in_bytes (type);
2629+ rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
2630+
2631+ /* Large types are passed by reference. */
2632+ if (size > 8)
2633+ {
2634+ indirect = 1;
2635+ size = rsize = UNITS_PER_WORD;
2636+ }
2637+
2638+ incr = valist;
2639+ addr = incr = save_expr (incr);
2640+
2641+ /* FIXME Nat's version - is it correct? */
2642+ tmp = fold_convert (ptr_type_node, size_int (rsize));
2643+ tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
2644+ incr = fold (tmp);
2645+
2646+ /* FIXME Nat's version - is it correct? */
2647+ incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
2648+
2649+ TREE_SIDE_EFFECTS (incr) = 1;
2650+ expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
2651+
2652+ addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
2653+
2654+ if (size < UNITS_PER_WORD)
2655+ emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
2656+ GEN_INT (UNITS_PER_WORD - size)));
2657+
2658+ if (indirect)
2659+ {
2660+ addr_rtx = force_reg (Pmode, addr_rtx);
2661+ addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
2662+ set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
2663+ }
2664+
2665+ return addr_rtx;
2666+}
2667+
2668+void
2669+init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2670+ int indirect ATTRIBUTE_UNUSED)
2671+{
2672+ cum->nbytes = 0;
2673+
2674+ if (!libname)
2675+ {
2676+ cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
2677+ && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2678+ != void_type_node));
2679+ }
2680+}
2681+
2682+/* Return an RTX to represent where a value in mode MODE will be passed
2683+ to a function. If the result is 0, the argument will be pushed. */
2684+
2685+rtx
2686+function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2687+ int named ATTRIBUTE_UNUSED)
2688+{
2689+ rtx result = 0;
2690+ int size, align;
2691+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
2692+
2693+ /* Figure out the size of the object to be passed. */
2694+ if (mode == BLKmode)
2695+ size = int_size_in_bytes (type);
2696+ else
2697+ size = GET_MODE_SIZE (mode);
2698+
2699+ /* Figure out the alignment of the object to be passed. */
2700+ align = size;
2701+
2702+ cum->nbytes = (cum->nbytes + 3) & ~3;
2703+
2704+ /* Don't pass this arg via a register if all the argument registers
2705+ are used up. */
2706+ if (cum->nbytes >= nregs * UNITS_PER_WORD)
2707+ return 0;
2708+
2709+ /* Don't pass this arg via a register if it would be split between
2710+ registers and memory. */
2711+ result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
2712+
2713+ return result;
2714+}
2715+
2716+rtx
2717+function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2718+ int named ATTRIBUTE_UNUSED)
2719+{
2720+ if (cfun->stdarg)
2721+ return 0;
2722+
2723+ return function_arg (cum, mode, type, named);
2724+}
2725+
2726+
2727+/* Implement hook TARGET_ARG_PARTIAL_BYTES.
2728+
2729+ Returns the number of bytes at the beginning of an argument that
2730+ must be put in registers. The value must be zero for arguments
2731+ that are passed entirely in registers or that are entirely pushed
2732+ on the stack. */
2733+static int
2734+ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2735+ tree type, bool named ATTRIBUTE_UNUSED)
2736+{
2737+ int size, diff;
2738+
2739+ int nregs = UBICOM32_FUNCTION_ARG_REGS;
2740+
2741+ /* round up to full word */
2742+ cum->nbytes = (cum->nbytes + 3) & ~3;
2743+
2744+ if (targetm.calls.pass_by_reference (cum, mode, type, named))
2745+ return 0;
2746+
2747+ /* number of bytes left in registers */
2748+ diff = nregs*UNITS_PER_WORD - cum->nbytes;
2749+
2750+ /* regs all used up */
2751+ if (diff <= 0)
2752+ return 0;
2753+
2754+ /* Figure out the size of the object to be passed. */
2755+ if (mode == BLKmode)
2756+ size = int_size_in_bytes (type);
2757+ else
2758+ size = GET_MODE_SIZE (mode);
2759+
2760+ /* enough space left in regs for size */
2761+ if (size <= diff)
2762+ return 0;
2763+
2764+ /* put diff bytes in regs and rest on stack */
2765+ return diff;
2766+
2767+}
2768+
2769+static bool
2770+ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2771+ enum machine_mode mode, const_tree type,
2772+ bool named ATTRIBUTE_UNUSED)
2773+{
2774+ int size;
2775+
2776+ if (type)
2777+ size = int_size_in_bytes (type);
2778+ else
2779+ size = GET_MODE_SIZE (mode);
2780+
2781+ return size <= 0 || size > 8;
2782+}
2783+
2784+static bool
2785+ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2786+ enum machine_mode mode, const_tree type,
2787+ bool named ATTRIBUTE_UNUSED)
2788+{
2789+ int size;
2790+
2791+ if (type)
2792+ size = int_size_in_bytes (type);
2793+ else
2794+ size = GET_MODE_SIZE (mode);
2795+
2796+ return size <= 0 || size > 8;
2797+}
2798+
2799+static bool
2800+ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2801+{
2802+ int size, mode;
2803+
2804+ if (!type)
2805+ return true;
2806+
2807+ size = int_size_in_bytes(type);
2808+ if (size > 8)
2809+ return true;
2810+
2811+ mode = TYPE_MODE(type);
2812+ if (mode == BLKmode)
2813+ return true;
2814+
2815+ return false;
2816+}
2817+
2818+/* Return true if a given register number REGNO is acceptable for machine
2819+ mode MODE. */
2820+bool
2821+ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
2822+{
2823+ /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
2824+ if (! ubicom32_v3)
2825+ {
2826+ if (regno == ACC0_HI_REGNUM)
2827+ return (mode == QImode || mode == HImode);
2828+ }
2829+
2830+ /* Only the flags reg can hold CCmode. */
2831+ if (GET_MODE_CLASS (mode) == MODE_CC)
2832+ return regno == CC_REGNUM;
2833+
2834+ /* We restrict the choice of DImode registers to only being address,
2835+ data or accumulator regs. We also restrict them to only start on
2836+ even register numbers so we never have to worry about partial
2837+ overlaps between operands in instructions. */
2838+ if (GET_MODE_SIZE (mode) > 4)
2839+ {
2840+ switch (REGNO_REG_CLASS (regno))
2841+ {
2842+ case ADDRESS_REGS:
2843+ case DATA_REGS:
2844+ case ACC_REGS:
2845+ return (regno & 1) == 0;
2846+
2847+ default:
2848+ return false;
2849+ }
2850+ }
2851+
2852+ return true;
2853+}
2854+
2855+/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
2856+ and check its validity for a certain class.
2857+ We have two alternate definitions for each of them.
2858+ The usual definition accepts all pseudo regs; the other rejects
2859+ them unless they have been allocated suitable hard regs.
2860+ The symbol REG_OK_STRICT causes the latter definition to be used.
2861+
2862+ Most source files want to accept pseudo regs in the hope that
2863+ they will get allocated to the class that the insn wants them to be in.
2864+ Source files for reload pass need to be strict.
2865+ After reload, it makes no difference, since pseudo regs have
2866+ been eliminated by then.
2867+
2868+ These assume that REGNO is a hard or pseudo reg number.
2869+ They give nonzero only if REGNO is a hard reg of the suitable class
2870+ or a pseudo reg currently allocated to a suitable hard reg.
2871+ Since they use reg_renumber, they are safe only once reg_renumber
2872+ has been allocated, which happens in local-alloc.c. */
2873+
2874+int
2875+ubicom32_regno_ok_for_base_p (int regno, int strict)
2876+{
2877+ if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
2878+ || (!strict
2879+ && (regno >= FIRST_PSEUDO_REGISTER
2880+ || regno == ARG_POINTER_REGNUM))
2881+ || (strict && (reg_renumber
2882+ && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
2883+ && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
2884+ return 1;
2885+
2886+ return 0;
2887+}
2888+
2889+int
2890+ubicom32_regno_ok_for_index_p (int regno, int strict)
2891+{
2892+ if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
2893+ || (!strict && regno >= FIRST_PSEUDO_REGISTER)
2894+ || (strict && (reg_renumber
2895+ && reg_renumber[regno] >= FIRST_DATA_REGNUM
2896+ && reg_renumber[regno] <= LAST_DATA_REGNUM)))
2897+ return 1;
2898+
2899+ return 0;
2900+}
2901+
2902+/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
2903+ registers should be accepted. Accept either REG or SUBREG where a
2904+ register is valid. */
2905+
2906+static bool
2907+ubicom32_is_index_reg (rtx x, int strict)
2908+{
2909+ if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
2910+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
2911+ && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
2912+ return true;
2913+
2914+ return false;
2915+}
2916+
2917+/* Return 1 if X is a valid index for a memory address. */
2918+
2919+static bool
2920+ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
2921+{
2922+ /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
2923+ or 4 depending on mode. */
2924+ if (CONST_INT_P (x))
2925+ {
2926+ switch (mode)
2927+ {
2928+ case QImode:
2929+ return satisfies_constraint_J (x);
2930+
2931+ case HImode:
2932+ return satisfies_constraint_K (x);
2933+
2934+ case SImode:
2935+ case SFmode:
2936+ return satisfies_constraint_L (x);
2937+
2938+ case DImode:
2939+ return satisfies_constraint_L (x)
2940+ && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
2941+
2942+ default:
2943+ return false;
2944+ }
2945+ }
2946+
2947+ if (mode != SImode && mode != HImode && mode != QImode)
2948+ return false;
2949+
2950+ /* Register index scaled by mode of operand: REG + REG * modesize.
2951+ Valid scaled index registers are:
2952+
2953+ SImode (mult (dreg) 4))
2954+ HImode (mult (dreg) 2))
2955+ QImode (mult (dreg) 1)) */
2956+ if (GET_CODE (x) == MULT
2957+ && ubicom32_is_index_reg (XEXP (x, 0), strict)
2958+ && CONST_INT_P (XEXP (x, 1))
2959+ && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
2960+ return true;
2961+
2962+ /* REG + REG addressing is allowed for QImode. */
2963+ if (ubicom32_is_index_reg (x, strict) && mode == QImode)
2964+ return true;
2965+
2966+ return false;
2967+}
2968+
2969+static bool
2970+ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
2971+{
2972+ if (offs < 0)
2973+ return false;
2974+
2975+ switch (mode)
2976+ {
2977+ case QImode:
2978+ return offs <= 127;
2979+
2980+ case HImode:
2981+ return offs <= 254;
2982+
2983+ case SImode:
2984+ case SFmode:
2985+ return offs <= 508;
2986+
2987+ case DImode:
2988+ return offs <= 504;
2989+
2990+ default:
2991+ return false;
2992+ }
2993+}
2994+
2995+static int
2996+ubicom32_get_valid_offset_mask (enum machine_mode mode)
2997+{
2998+ switch (mode)
2999+ {
3000+ case QImode:
3001+ return 127;
3002+
3003+ case HImode:
3004+ return 255;
3005+
3006+ case SImode:
3007+ case SFmode:
3008+ return 511;
3009+
3010+ case DImode:
3011+ return 255;
3012+
3013+ default:
3014+ return 0;
3015+ }
3016+}
3017+
3018+/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
3019+ registers should be accepted. Accept either REG or SUBREG where a
3020+ register is valid. */
3021+
3022+static bool
3023+ubicom32_is_base_reg (rtx x, int strict)
3024+{
3025+ if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
3026+ || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
3027+ && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
3028+ return true;
3029+
3030+ return false;
3031+}
3032+
3033+static bool
3034+ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
3035+{
3036+ return TARGET_FDPIC;
3037+}
3038+
3039+/* Determine if X is a legitimate constant. */
3040+
3041+bool
3042+ubicom32_legitimate_constant_p (rtx x)
3043+{
3044+ /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
3045+ a constant can be entered into reg_equiv_constant[]. If we return true,
3046+ reload can create new instances of the constant whenever it likes.
3047+
3048+ The idea is therefore to accept as many constants as possible (to give
3049+ reload more freedom) while rejecting constants that can only be created
3050+ at certain times. In particular, anything with a symbolic component will
3051+ require use of the pseudo FDPIC register, which is only available before
3052+ reload. */
3053+ if (TARGET_FDPIC)
3054+ {
3055+ if (GET_CODE (x) == SYMBOL_REF
3056+ || (GET_CODE (x) == CONST
3057+ && GET_CODE (XEXP (x, 0)) == PLUS
3058+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
3059+ || CONSTANT_ADDRESS_P (x))
3060+ return false;
3061+
3062+ return true;
3063+ }
3064+
3065+ /* For non-PIC code anything goes! */
3066+ return true;
3067+}
3068+
3069+/* Address validation. */
3070+
3071+bool
3072+ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
3073+{
3074+ if (TARGET_DEBUG_ADDRESS)
3075+ {
3076+ fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
3077+ (strict) ? " (STRICT)" : "");
3078+ debug_rtx (x);
3079+ }
3080+
3081+ if (CONSTANT_ADDRESS_P (x))
3082+ return false;
3083+
3084+ if (ubicom32_is_base_reg (x, strict))
3085+ return true;
3086+
3087+ if ((GET_CODE (x) == POST_INC
3088+ || GET_CODE (x) == PRE_INC
3089+ || GET_CODE (x) == POST_DEC
3090+ || GET_CODE (x) == PRE_DEC)
3091+ && REG_P (XEXP (x, 0))
3092+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3093+ && mode != DImode)
3094+ return true;
3095+
3096+ if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
3097+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3098+ && GET_CODE (XEXP (x, 1)) == PLUS
3099+ && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
3100+ && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3101+ && mode != DImode)
3102+ {
3103+ HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
3104+ switch (mode)
3105+ {
3106+ case QImode:
3107+ return disp >= -8 && disp <= 7;
3108+
3109+ case HImode:
3110+ return disp >= -16 && disp <= 14 && ! (disp & 1);
3111+
3112+ case SImode:
3113+ return disp >= -32 && disp <= 28 && ! (disp & 3);
3114+
3115+ default:
3116+ return false;
3117+ }
3118+ }
3119+
3120+ /* Accept base + index * scale. */
3121+ if (GET_CODE (x) == PLUS
3122+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3123+ && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
3124+ return true;
3125+
3126+ /* Accept index * scale + base. */
3127+ if (GET_CODE (x) == PLUS
3128+ && ubicom32_is_base_reg (XEXP (x, 1), strict)
3129+ && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
3130+ return true;
3131+
3132+ if (! TARGET_FDPIC)
3133+ {
3134+ /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
3135+ displacement operand:
3136+
3137+ moveai a1, #%hi(SYM)
3138+ move.4 d3, %lo(SYM)(a1) */
3139+ if (GET_CODE (x) == LO_SUM
3140+ && ubicom32_is_base_reg (XEXP (x, 0), strict)
3141+ && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
3142+ || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
3143+ && mode != DImode)
3144+ return true;
3145+ }
3146+
3147+ if (TARGET_DEBUG_ADDRESS)
3148+ fprintf (stderr, "\nNot a legitimate address.\n");
3149+
3150+ return false;
3151+}
3152+
3153+rtx
3154+ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3155+ enum machine_mode mode)
3156+{
3157+ if (mode == BLKmode)
3158+ return NULL_RTX;
3159+
3160+ if (GET_CODE (x) == PLUS
3161+ && REG_P (XEXP (x, 0))
3162+ && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
3163+ && CONST_INT_P (XEXP (x, 1))
3164+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
3165+ {
3166+ rtx base;
3167+ rtx plus;
3168+ rtx new_rtx;
3169+ HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3170+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3171+ HOST_WIDE_INT high = val ^ low;
3172+
3173+ if (val < 0)
3174+ return NULL_RTX;
3175+
3176+ if (! low)
3177+ return NULL_RTX;
3178+
3179+ /* Reload the high part into a base reg; leave the low part
3180+ in the mem directly. */
3181+ base = XEXP (x, 0);
3182+ if (! ubicom32_is_base_reg (base, 0))
3183+ base = copy_to_mode_reg (Pmode, base);
3184+
3185+ plus = expand_simple_binop (Pmode, PLUS,
3186+ gen_int_mode (high, Pmode),
3187+ base, NULL, 0, OPTAB_WIDEN);
3188+ new_rtx = plus_constant (plus, low);
3189+
3190+ return new_rtx;
3191+ }
3192+
3193+ return NULL_RTX;
3194+}
3195+
3196+/* Try a machine-dependent way of reloading an illegitimate address AD
3197+ operand. If we find one, push the reload and and return the new address.
3198+
3199+ MODE is the mode of the enclosing MEM. OPNUM is the operand number
3200+ and TYPE is the reload type of the current reload. */
3201+
3202+rtx
3203+ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
3204+ int opnum, int type)
3205+{
3206+ /* Is this an address that we've already fixed up? If it is then
3207+ recognize it and move on. */
3208+ if (GET_CODE (ad) == PLUS
3209+ && GET_CODE (XEXP (ad, 0)) == PLUS
3210+ && REG_P (XEXP (XEXP (ad, 0), 0))
3211+ && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
3212+ && CONST_INT_P (XEXP (ad, 1)))
3213+ {
3214+ push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
3215+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3216+ opnum, (enum reload_type) type);
3217+ return ad;
3218+ }
3219+
3220+ /* Have we got an address where the offset is simply out of range? If
3221+ yes then reload the range as a high part and smaller offset. */
3222+ if (GET_CODE (ad) == PLUS
3223+ && REG_P (XEXP (ad, 0))
3224+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3225+ && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
3226+ && CONST_INT_P (XEXP (ad, 1))
3227+ && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
3228+ {
3229+ rtx temp;
3230+ rtx new_rtx;
3231+
3232+ HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
3233+ HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3234+ HOST_WIDE_INT high = val ^ low;
3235+
3236+ /* Reload the high part into a base reg; leave the low part
3237+ in the mem directly. */
3238+ temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
3239+ new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
3240+
3241+ push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
3242+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3243+ opnum, (enum reload_type) type);
3244+ return new_rtx;
3245+ }
3246+
3247+ /* If we're presented with an pre/post inc/dec then we must force this
3248+ to be done in an address register. The register allocator should
3249+ work this out for itself but at times ends up trying to use the wrong
3250+ class. If we get the wrong class then reload will end up generating
3251+ at least 3 instructions whereas this way we can hopefully keep it to
3252+ just 2. */
3253+ if ((GET_CODE (ad) == POST_INC
3254+ || GET_CODE (ad) == PRE_INC
3255+ || GET_CODE (ad) == POST_DEC
3256+ || GET_CODE (ad) == PRE_DEC)
3257+ && REG_P (XEXP (ad, 0))
3258+ && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3259+ && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
3260+ {
3261+ push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
3262+ BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
3263+ opnum, RELOAD_OTHER);
3264+ return ad;
3265+ }
3266+
3267+ return NULL_RTX;
3268+}
3269+
3270+/* Compute a (partial) cost for rtx X. Return true if the complete
3271+ cost has been computed, and false if subexpressions should be
3272+ scanned. In either case, *TOTAL contains the cost result. */
3273+
3274+static bool
3275+ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
3276+ bool speed ATTRIBUTE_UNUSED)
3277+{
3278+ enum machine_mode mode = GET_MODE (x);
3279+
3280+ switch (code)
3281+ {
3282+ case CONST_INT:
3283+ /* Very short constants often fold into instructions so
3284+ we pretend that they don't cost anything! This is
3285+ really important as regards zero values as otherwise
3286+ the compiler has a nasty habit of wanting to reuse
3287+ zeroes that are in regs but that tends to pessimize
3288+ the code. */
3289+ if (satisfies_constraint_I (x))
3290+ {
3291+ *total = 0;
3292+ return true;
3293+ }
3294+
3295+ /* Bit clearing costs nothing */
3296+ if (outer_code == AND
3297+ && exact_log2 (~INTVAL (x)) != -1)
3298+ {
3299+ *total = 0;
3300+ return true;
3301+ }
3302+
3303+ /* Masking the lower set of bits costs nothing. */
3304+ if (outer_code == AND
3305+ && exact_log2 (INTVAL (x) + 1) != -1)
3306+ {
3307+ *total = 0;
3308+ return true;
3309+ }
3310+
3311+ /* Bit setting costs nothing. */
3312+ if (outer_code == IOR
3313+ && exact_log2 (INTVAL (x)) != -1)
3314+ {
3315+ *total = 0;
3316+ return true;
3317+ }
3318+
3319+ /* Larger constants that can be loaded via movei aren't too
3320+ bad. If we're just doing a set they cost nothing extra. */
3321+ if (satisfies_constraint_N (x))
3322+ {
3323+ if (mode == DImode)
3324+ *total = COSTS_N_INSNS (2);
3325+ else
3326+ *total = COSTS_N_INSNS (1);
3327+ return true;
3328+ }
3329+
3330+ if (mode == DImode)
3331+ *total = COSTS_N_INSNS (5);
3332+ else
3333+ *total = COSTS_N_INSNS (3);
3334+ return true;
3335+
3336+ case CONST_DOUBLE:
3337+ /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
3338+ so their cost is very high. */
3339+ *total = COSTS_N_INSNS (6);
3340+ return true;
3341+
3342+ case CONST:
3343+ case SYMBOL_REF:
3344+ case MEM:
3345+ *total = 0;
3346+ return true;
3347+
3348+ case IF_THEN_ELSE:
3349+ *total = COSTS_N_INSNS (1);
3350+ return true;
3351+
3352+ case LABEL_REF:
3353+ case HIGH:
3354+ case LO_SUM:
3355+ case BSWAP:
3356+ case PLUS:
3357+ case MINUS:
3358+ case AND:
3359+ case IOR:
3360+ case XOR:
3361+ case ASHIFT:
3362+ case ASHIFTRT:
3363+ case LSHIFTRT:
3364+ case NEG:
3365+ case NOT:
3366+ case SIGN_EXTEND:
3367+ case ZERO_EXTEND:
3368+ case ZERO_EXTRACT:
3369+ if (outer_code == SET)
3370+ {
3371+ if (mode == DImode)
3372+ *total = COSTS_N_INSNS (2);
3373+ else
3374+ *total = COSTS_N_INSNS (1);
3375+ }
3376+ return true;
3377+
3378+ case COMPARE:
3379+ if (outer_code == SET)
3380+ {
3381+ if (GET_MODE (XEXP (x, 0)) == DImode
3382+ || GET_MODE (XEXP (x, 1)) == DImode)
3383+ *total = COSTS_N_INSNS (2);
3384+ else
3385+ *total = COSTS_N_INSNS (1);
3386+ }
3387+ return true;
3388+
3389+ case UMOD:
3390+ case UDIV:
3391+ case MOD:
3392+ case DIV:
3393+ if (outer_code == SET)
3394+ {
3395+ if (mode == DImode)
3396+ *total = COSTS_N_INSNS (600);
3397+ else
3398+ *total = COSTS_N_INSNS (200);
3399+ }
3400+ return true;
3401+
3402+ case MULT:
3403+ if (outer_code == SET)
3404+ {
3405+ if (! ubicom32_v4)
3406+ {
3407+ if (mode == DImode)
3408+ *total = COSTS_N_INSNS (15);
3409+ else
3410+ *total = COSTS_N_INSNS (5);
3411+ }
3412+ else
3413+ {
3414+ if (mode == DImode)
3415+ *total = COSTS_N_INSNS (6);
3416+ else
3417+ *total = COSTS_N_INSNS (2);
3418+ }
3419+ }
3420+ return true;
3421+
3422+ case UNSPEC:
3423+ if (XINT (x, 1) == UNSPEC_FDPIC_GOT
3424+ || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
3425+ *total = 0;
3426+ return true;
3427+
3428+ default:
3429+ return false;
3430+ }
3431+}
3432+
3433+/* Return 1 if ADDR can have different meanings depending on the machine
3434+ mode of the memory reference it is used for or if the address is
3435+ valid for some modes but not others.
3436+
3437+ Autoincrement and autodecrement addresses typically have
3438+ mode-dependent effects because the amount of the increment or
3439+ decrement is the size of the operand being addressed. Some machines
3440+ have other mode-dependent addresses. Many RISC machines have no
3441+ mode-dependent addresses.
3442+
3443+ You may assume that ADDR is a valid address for the machine. */
3444+
3445+int
3446+ubicom32_mode_dependent_address_p (rtx addr)
3447+{
3448+ if (GET_CODE (addr) == POST_INC
3449+ || GET_CODE (addr) == PRE_INC
3450+ || GET_CODE (addr) == POST_DEC
3451+ || GET_CODE (addr) == PRE_DEC
3452+ || GET_CODE (addr) == POST_MODIFY
3453+ || GET_CODE (addr) == PRE_MODIFY)
3454+ return 1;
3455+
3456+ return 0;
3457+}
3458+
3459+static void
3460+ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3461+{
3462+ fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
3463+ get_frame_size (), crtl->args.pretend_args_size,
3464+ save_regs_size, crtl->outgoing_args_size,
3465+ current_function_is_leaf ? "leaf" : "nonleaf");
3466+}
3467+
3468+static void
3469+ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
3470+ HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3471+{
3472+ ubicom32_reorg_completed = 0;
3473+}
3474+
3475+static void
3476+ubicom32_machine_dependent_reorg (void)
3477+{
3478+#if 0 /* Commenting out this optimization until it is fixed */
3479+ if (optimize)
3480+ {
3481+ compute_bb_for_insn ();
3482+
3483+ /* Do a very simple CSE pass over just the hard registers. */
3484+ reload_cse_regs (get_insns ());
3485+
3486+ /* Reload_cse_regs can eliminate potentially-trapping MEMs.
3487+ Remove any EH edges associated with them. */
3488+ if (flag_non_call_exceptions)
3489+ purge_all_dead_edges ();
3490+ }
3491+#endif
3492+ ubicom32_reorg_completed = 1;
3493+}
3494+
3495+void
3496+ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
3497+{
3498+ rtx note;
3499+ int mostly_false_jump;
3500+ rtx xoperands[2];
3501+ rtx cc_reg;
3502+
3503+ note = find_reg_note (insn, REG_BR_PROB, 0);
3504+ mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
3505+ <= REG_BR_PROB_BASE / 2);
3506+
3507+ xoperands[0] = target;
3508+ xoperands[1] = cond;
3509+ cc_reg = XEXP (cond, 0);
3510+
3511+ if (GET_MODE (cc_reg) == CCWmode
3512+ || GET_MODE (cc_reg) == CCWZmode
3513+ || GET_MODE (cc_reg) == CCWZNmode)
3514+ {
3515+ if (mostly_false_jump)
3516+ output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
3517+ else
3518+ output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
3519+ return;
3520+ }
3521+
3522+ if (GET_MODE (cc_reg) == CCSmode
3523+ || GET_MODE (cc_reg) == CCSZmode
3524+ || GET_MODE (cc_reg) == CCSZNmode)
3525+ {
3526+ if (mostly_false_jump)
3527+ output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
3528+ else
3529+ output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
3530+ return;
3531+ }
3532+
3533+ abort ();
3534+}
3535+
3536+/* Return non-zero if FUNC is a naked function. */
3537+
3538+static int
3539+ubicom32_naked_function_p (void)
3540+{
3541+ return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
3542+}
3543+
3544+/* Return an RTX indicating where the return address to the
3545+ calling function can be found. */
3546+rtx
3547+ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
3548+{
3549+ if (count != 0)
3550+ return NULL_RTX;
3551+
3552+ return get_hard_reg_initial_val (Pmode, LINK_REGNO);
3553+}
3554+
3555+/*
3556+ * ubicom32_readonly_data_section: This routtine handles code
3557+ * at the start of readonly data sections
3558+ */
3559+static void
3560+ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
3561+{
3562+ static int num = 0;
3563+ if (in_section == readonly_data_section){
3564+ fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
3565+ if (flag_data_sections){
3566+ fprintf (asm_out_file, ".rodata%d", num);
3567+ fprintf (asm_out_file, ",\"a\"");
3568+ }
3569+ fprintf (asm_out_file, "\n");
3570+ }
3571+ num++;
3572+}
3573+
3574+/*
3575+ * ubicom32_text_section: not in readonly section
3576+ */
3577+static void
3578+ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
3579+{
3580+ fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
3581+}
3582+
3583+/*
3584+ * ubicom32_data_section: not in readonly section
3585+ */
3586+static void
3587+ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
3588+{
3589+ fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
3590+}
3591+
3592+/*
3593+ * ubicom32_asm_init_sections: This routine implements special
3594+ * section handling
3595+ */
3596+static void
3597+ubicom32_asm_init_sections(void)
3598+{
3599+ text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
3600+
3601+ data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
3602+
3603+ readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
3604+}
3605+
3606+/*
3607+ * ubicom32_profiler: This routine would call
3608+ * mcount to support prof and gprof if mcount
3609+ * was supported. Currently, do nothing.
3610+ */
3611+void
3612+ubicom32_profiler(void)
3613+{
3614+}
3615+
3616+/* Initialise the builtin functions. Start by initialising
3617+ descriptions of different types of functions (e.g., void fn(int),
3618+ int fn(void)), and then use these to define the builtins. */
3619+static void
3620+ubicom32_init_builtins (void)
3621+{
3622+ tree endlink;
3623+ tree short_unsigned_endlink;
3624+ tree unsigned_endlink;
3625+ tree short_unsigned_ftype_short_unsigned;
3626+ tree unsigned_ftype_unsigned;
3627+
3628+ endlink = void_list_node;
3629+
3630+ short_unsigned_endlink
3631+ = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
3632+
3633+ unsigned_endlink
3634+ = tree_cons (NULL_TREE, unsigned_type_node, endlink);
3635+
3636+ short_unsigned_ftype_short_unsigned
3637+ = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
3638+
3639+ unsigned_ftype_unsigned
3640+ = build_function_type (unsigned_type_node, unsigned_endlink);
3641+
3642+ /* Initialise the byte swap function. */
3643+ add_builtin_function ("__builtin_ubicom32_swapb_2",
3644+ short_unsigned_ftype_short_unsigned,
3645+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
3646+ BUILT_IN_MD, NULL,
3647+ NULL_TREE);
3648+
3649+ /* Initialise the byte swap function. */
3650+ add_builtin_function ("__builtin_ubicom32_swapb_4",
3651+ unsigned_ftype_unsigned,
3652+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
3653+ BUILT_IN_MD, NULL,
3654+ NULL_TREE);
3655+}
3656+
3657+/* Given a builtin function taking 2 operands (i.e., target + source),
3658+ emit the RTL for the underlying instruction. */
3659+static rtx
3660+ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
3661+{
3662+ tree arg0;
3663+ rtx op0, pat;
3664+ enum machine_mode tmode, mode0;
3665+
3666+ /* Grab the incoming argument and emit its RTL. */
3667+ arg0 = TREE_VALUE (arglist);
3668+ op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3669+
3670+ /* Determine the modes of the instruction operands. */
3671+ tmode = insn_data[icode].operand[0].mode;
3672+ mode0 = insn_data[icode].operand[1].mode;
3673+
3674+ /* Ensure that the incoming argument RTL is in a register of the
3675+ correct mode. */
3676+ if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3677+ op0 = copy_to_mode_reg (mode0, op0);
3678+
3679+ /* If there isn't a suitable target, emit a target register. */
3680+ if (target == 0
3681+ || GET_MODE (target) != tmode
3682+ || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3683+ target = gen_reg_rtx (tmode);
3684+
3685+ /* Emit and return the new instruction. */
3686+ pat = GEN_FCN (icode) (target, op0);
3687+ if (!pat)
3688+ return 0;
3689+ emit_insn (pat);
3690+
3691+ return target;
3692+}
3693+
3694+/* Expand a call to a builtin function. */
3695+static rtx
3696+ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3697+ enum machine_mode mode ATTRIBUTE_UNUSED,
3698+ int ignore ATTRIBUTE_UNUSED)
3699+{
3700+ tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3701+ tree arglist = CALL_EXPR_ARGS(exp);
3702+ int fcode = DECL_FUNCTION_CODE (fndecl);
3703+
3704+ switch (fcode)
3705+ {
3706+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3707+ return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
3708+
3709+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3710+ return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
3711+
3712+ default:
3713+ gcc_unreachable();
3714+ }
3715+
3716+ /* Should really do something sensible here. */
3717+ return NULL_RTX;
3718+}
3719+
3720+/* Fold any constant argument for a swapb.2 instruction. */
3721+static tree
3722+ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
3723+{
3724+ tree arg0;
3725+
3726+ arg0 = TREE_VALUE (arglist);
3727+
3728+ /* Optimize constant value. */
3729+ if (TREE_CODE (arg0) == INTEGER_CST)
3730+ {
3731+ HOST_WIDE_INT v;
3732+ HOST_WIDE_INT res;
3733+
3734+ v = TREE_INT_CST_LOW (arg0);
3735+ res = ((v >> 8) & 0xff)
3736+ | ((v & 0xff) << 8);
3737+
3738+ return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
3739+ }
3740+
3741+ return NULL_TREE;
3742+}
3743+
3744+/* Fold any constant argument for a swapb.4 instruction. */
3745+static tree
3746+ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
3747+{
3748+ tree arg0;
3749+
3750+ arg0 = TREE_VALUE (arglist);
3751+
3752+ /* Optimize constant value. */
3753+ if (TREE_CODE (arg0) == INTEGER_CST)
3754+ {
3755+ unsigned HOST_WIDE_INT v;
3756+ unsigned HOST_WIDE_INT res;
3757+
3758+ v = TREE_INT_CST_LOW (arg0);
3759+ res = ((v >> 24) & 0xff)
3760+ | (((v >> 16) & 0xff) << 8)
3761+ | (((v >> 8) & 0xff) << 16)
3762+ | ((v & 0xff) << 24);
3763+
3764+ return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
3765+ }
3766+
3767+ return NULL_TREE;
3768+}
3769+
3770+/* Fold any constant arguments for builtin functions. */
3771+static tree
3772+ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
3773+{
3774+ switch (DECL_FUNCTION_CODE (fndecl))
3775+ {
3776+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3777+ return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
3778+
3779+ case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3780+ return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
3781+
3782+ default:
3783+ return NULL;
3784+ }
3785+}
3786+
3787+/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
3788+ tell the assembler to generate pointers to function descriptors in
3789+ some cases. */
3790+static bool
3791+ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
3792+{
3793+ if (TARGET_FDPIC && size == UNITS_PER_WORD)
3794+ {
3795+ if (GET_CODE (value) == SYMBOL_REF
3796+ && SYMBOL_REF_FUNCTION_P (value))
3797+ {
3798+ fputs ("\t.picptr\t%funcdesc(", asm_out_file);
3799+ output_addr_const (asm_out_file, value);
3800+ fputs (")\n", asm_out_file);
3801+ return true;
3802+ }
3803+
3804+ if (!aligned_p)
3805+ {
3806+ /* We've set the unaligned SI op to NULL, so we always have to
3807+ handle the unaligned case here. */
3808+ assemble_integer_with_op ("\t.4byte\t", value);
3809+ return true;
3810+ }
3811+ }
3812+
3813+ return default_assemble_integer (value, size, aligned_p);
3814+}
3815+
3816+/* If the constant I can be constructed by shifting a source-1 immediate
3817+ by a constant number of bits then return the bit count. If not
3818+ return 0. */
3819+
3820+int
3821+ubicom32_shiftable_const_int (int i)
3822+{
3823+ int shift = 0;
3824+
3825+ /* Note that any constant that can be represented as an immediate to
3826+ a movei instruction is automatically ignored here in the interests
3827+ of the clarity of the output asm code. */
3828+ if (i >= -32768 && i <= 32767)
3829+ return 0;
3830+
3831+ /* Find the number of trailing zeroes. We could use __builtin_ctz
3832+ here but it's not obvious if this is supported on all build
3833+ compilers so we err on the side of caution. */
3834+ if ((i & 0xffff) == 0)
3835+ {
3836+ shift += 16;
3837+ i >>= 16;
3838+ }
3839+
3840+ if ((i & 0xff) == 0)
3841+ {
3842+ shift += 8;
3843+ i >>= 8;
3844+ }
3845+
3846+ if ((i & 0xf) == 0)
3847+ {
3848+ shift += 4;
3849+ i >>= 4;
3850+ }
3851+
3852+ if ((i & 0x3) == 0)
3853+ {
3854+ shift += 2;
3855+ i >>= 2;
3856+ }
3857+
3858+ if ((i & 0x1) == 0)
3859+ {
3860+ shift += 1;
3861+ i >>= 1;
3862+ }
3863+
3864+ if (i >= -128 && i <= 127)
3865+ return shift;
3866+
3867+ return 0;
3868+}
3869+
3870--- /dev/null
3871+++ b/gcc/config/ubicom32/ubicom32.h
3872@@ -0,0 +1,1564 @@
3873+/* Definitions of target machine for Ubicom32
3874+
3875+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3876+ 2009 Free Software Foundation, Inc.
3877+ Contributed by Ubicom, Inc.
3878+
3879+ This file is part of GCC.
3880+
3881+ GCC is free software; you can redistribute it and/or modify it
3882+ under the terms of the GNU General Public License as published
3883+ by the Free Software Foundation; either version 3, or (at your
3884+ option) any later version.
3885+
3886+ GCC is distributed in the hope that it will be useful, but WITHOUT
3887+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3888+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
3889+ License for more details.
3890+
3891+ You should have received a copy of the GNU General Public License
3892+ along with GCC; see the file COPYING3. If not see
3893+ <http://www.gnu.org/licenses/>. */
3894+
3895+
3896+
3897+#define OBJECT_FORMAT_ELF
3898+
3899+/* Run-time target specifications. */
3900+
3901+/* Target CPU builtins. */
3902+#define TARGET_CPU_CPP_BUILTINS() \
3903+ do \
3904+ { \
3905+ builtin_define_std ("__UBICOM32__"); \
3906+ builtin_define_std ("__ubicom32__"); \
3907+ \
3908+ if (TARGET_FDPIC) \
3909+ { \
3910+ builtin_define ("__UBICOM32_FDPIC__"); \
3911+ builtin_define ("__FDPIC__"); \
3912+ } \
3913+ } \
3914+ while (0)
3915+
3916+#ifndef TARGET_DEFAULT
3917+#define TARGET_DEFAULT 0
3918+#endif
3919+
3920+extern int ubicom32_case_values_threshold;
3921+
3922+/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
3923+extern int ubicom32_v3;
3924+
3925+/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
3926+extern int ubicom32_v4;
3927+
3928+extern int ubicom32_stack_size;
3929+
3930+/* Flag for whether we can use calli instead of ret in returns. */
3931+extern int ubicom32_can_use_calli_to_ret;
3932+
3933+/* This macro is a C statement to print on `stderr' a string describing the
3934+ particular machine description choice. Every machine description should
3935+ define `TARGET_VERSION'. */
3936+#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
3937+
3938+/* We don't need a frame pointer to debug things. Doing this means
3939+ that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
3940+#define CAN_DEBUG_WITHOUT_FP
3941+
3942+/* We need to handle processor-specific options. */
3943+#define OVERRIDE_OPTIONS ubicom32_override_options ()
3944+
3945+#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
3946+ ubicom32_optimization_options (LEVEL, SIZE)
3947+
3948+/* For Ubicom32 the least significant bit has the lowest bit number
3949+ so we define this to be 0. */
3950+#define BITS_BIG_ENDIAN 0
3951+
3952+/* For Ubicom32 the most significant byte in a word has the lowest
3953+ number. */
3954+#define BYTES_BIG_ENDIAN 1
3955+
3956+/* For Ubicom32, in a multiword object, the most signifant word has the
3957+ lowest number. */
3958+#define WORDS_BIG_ENDIAN 1
3959+
3960+/* Ubicom32 has 8 bits per byte. */
3961+#define BITS_PER_UNIT 8
3962+
3963+/* Ubicom32 has 32 bits per word. */
3964+#define BITS_PER_WORD 32
3965+
3966+/* Width of a word, in units (bytes). */
3967+#define UNITS_PER_WORD 4
3968+
3969+/* Width of a pointer, in bits. */
3970+#define POINTER_SIZE 32
3971+
3972+/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
3973+ SImode. */
3974+#define Pmode SImode
3975+
3976+/* Normal alignment required for function parameters on the stack, in
3977+ bits. */
3978+#define PARM_BOUNDARY 32
3979+
3980+/* We need to maintain the stack on a 32-bit boundary. */
3981+#define STACK_BOUNDARY 32
3982+
3983+/* Alignment required for a function entry point, in bits. */
3984+#define FUNCTION_BOUNDARY 32
3985+
3986+/* Alias for the machine mode used for memory references to functions being
3987+ called, in `call' RTL expressions. We use byte-oriented addresses
3988+ here. */
3989+#define FUNCTION_MODE QImode
3990+
3991+/* Biggest alignment that any data type can require on this machine,
3992+ in bits. */
3993+#define BIGGEST_ALIGNMENT 32
3994+
3995+/* this default to BIGGEST_ALIGNMENT unless defined */
3996+/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
3997+#undef MAX_OFILE_ALIGNMENT
3998+#define MAX_OFILE_ALIGNMENT (128 * 8)
3999+
4000+/* Alignment in bits to be given to a structure bit field that follows an empty
4001+ field such as `int : 0;'. */
4002+#define EMPTY_FIELD_BOUNDARY 32
4003+
4004+/* All structures must be a multiple of 32 bits in size. */
4005+#define STRUCTURE_SIZE_BOUNDARY 32
4006+
4007+/* A bit-field declared as `int' forces `int' alignment for the struct. */
4008+#define PCC_BITFIELD_TYPE_MATTERS 1
4009+
4010+/* For Ubicom32 we absolutely require that data be aligned with nominal
4011+ alignment. */
4012+#define STRICT_ALIGNMENT 1
4013+
4014+/* Make strcpy of constants fast. */
4015+#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
4016+ (TREE_CODE (EXP) == STRING_CST \
4017+ && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
4018+
4019+/* Define this macro as an expression for the alignment of a structure
4020+ (given by STRUCT as a tree node) if the alignment computed in the
4021+ usual way is COMPUTED and the alignment explicitly specified was
4022+ SPECIFIED. */
4023+#define DATA_ALIGNMENT(TYPE, ALIGN) \
4024+ ((((ALIGN) < BITS_PER_WORD) \
4025+ && (TREE_CODE (TYPE) == ARRAY_TYPE \
4026+ || TREE_CODE (TYPE) == UNION_TYPE \
4027+ || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
4028+
4029+#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
4030+
4031+/* For Ubicom32 we default to unsigned chars. */
4032+#define DEFAULT_SIGNED_CHAR 0
4033+
4034+/* Machine-specific data register numbers. */
4035+#define FIRST_DATA_REGNUM 0
4036+#define D10_REGNUM 10
4037+#define D11_REGNUM 11
4038+#define D12_REGNUM 12
4039+#define D13_REGNUM 13
4040+#define LAST_DATA_REGNUM 15
4041+
4042+/* Machine-specific address register numbers. */
4043+#define FIRST_ADDRESS_REGNUM 16
4044+#define LAST_ADDRESS_REGNUM 22
4045+
4046+/* Register numbers used for passing a function's static chain pointer. If
4047+ register windows are used, the register number as seen by the called
4048+ function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
4049+ seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
4050+ are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
4051+
4052+ The static chain register need not be a fixed register.
4053+
4054+ If the static chain is passed in memory, these macros should not be defined;
4055+ instead, the next two macros should be defined. */
4056+#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
4057+
4058+/* The register number of the frame pointer register, which is used to access
4059+ automatic variables in the stack frame. We generally eliminate this anyway
4060+ for Ubicom32 but we make it A6 by default. */
4061+#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
4062+
4063+/* The register number of the stack pointer register, which is also be a
4064+ fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
4065+ have a hardware requirement about which register this is, but by convention
4066+ we use A7. */
4067+#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
4068+
4069+/* Machine-specific accumulator register numbers. */
4070+#define ACC0_HI_REGNUM 24
4071+#define ACC0_LO_REGNUM 25
4072+#define ACC1_HI_REGNUM 26
4073+#define ACC1_LO_REGNUM 27
4074+
4075+/* source3 register number */
4076+#define SOURCE3_REGNUM 28
4077+
4078+/* The register number of the arg pointer register, which is used to access the
4079+ function's argument list. On some machines, this is the same as the frame
4080+ pointer register. On some machines, the hardware determines which register
4081+ this is. On other machines, you can choose any register you wish for this
4082+ purpose. If this is not the same register as the frame pointer register,
4083+ then you must mark it as a fixed register according to `FIXED_REGISTERS', or
4084+ arrange to be able to eliminate it. */
4085+#define ARG_POINTER_REGNUM 29
4086+
4087+/* Pseudo-reg for condition code. */
4088+#define CC_REGNUM 30
4089+
4090+/* Interrupt set/clear registers. */
4091+#define INT_SET0_REGNUM 31
4092+#define INT_SET1_REGNUM 32
4093+#define INT_CLR0_REGNUM 33
4094+#define INT_CLR1_REGNUM 34
4095+
4096+/* Scratchpad registers. */
4097+#define SCRATCHPAD0_REGNUM 35
4098+#define SCRATCHPAD1_REGNUM 36
4099+#define SCRATCHPAD2_REGNUM 37
4100+#define SCRATCHPAD3_REGNUM 38
4101+
4102+/* FDPIC register. */
4103+#define FDPIC_REGNUM 16
4104+
4105+/* Number of hardware registers known to the compiler. They receive numbers 0
4106+ through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
4107+ really is assigned the number `FIRST_PSEUDO_REGISTER'. */
4108+#define FIRST_PSEUDO_REGISTER 39
4109+
4110+/* An initializer that says which registers are used for fixed purposes all
4111+ throughout the compiled code and are therefore not available for general
4112+ allocation. These would include the stack pointer, the frame pointer
4113+ (except on machines where that can be used as a general register when no
4114+ frame pointer is needed), the program counter on machines where that is
4115+ considered one of the addressable registers, and any other numbered register
4116+ with a standard use.
4117+
4118+ This information is expressed as a sequence of numbers, separated by commas
4119+ and surrounded by braces. The Nth number is 1 if register N is fixed, 0
4120+ otherwise.
4121+
4122+ The table initialized from this macro, and the table initialized by the
4123+ following one, may be overridden at run time either automatically, by the
4124+ actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
4125+ command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
4126+#define FIXED_REGISTERS \
4127+ { \
4128+ 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
4129+ 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
4130+ 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
4131+ 0, 0, /* acc0 hi/lo */ \
4132+ 0, 0, /* acc1 hi/lo */ \
4133+ 0, /* source3 */ \
4134+ 1, /* arg */ \
4135+ 1, /* cc */ \
4136+ 1, 1, /* int_set[01] */ \
4137+ 1, 1, /* int_clr[01] */ \
4138+ 1, 1, 1, 1 /* scratchpad[0123] */ \
4139+ }
4140+
4141+/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
4142+ general) by function calls as well as for fixed registers. This macro
4143+ therefore identifies the registers that are not available for general
4144+ allocation of values that must live across function calls.
4145+
4146+ If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
4147+ saves it on function entry and restores it on function exit, if the register
4148+ is used within the function. */
4149+#define CALL_USED_REGISTERS \
4150+ { \
4151+ 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
4152+ 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
4153+ 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
4154+ 1, 1, /* acc0 hi/lo */ \
4155+ 1, 1, /* acc1 hi/lo */ \
4156+ 1, /* source3 */ \
4157+ 1, /* arg */ \
4158+ 1, /* cc */ \
4159+ 1, 1, /* int_set[01] */ \
4160+ 1, 1, /* int_clr[01] */ \
4161+ 1, 1, 1, 1 /* scratchpad[0123] */ \
4162+ }
4163+
4164+/* How to refer to registers in assembler output.
4165+ This sequence is indexed by compiler's hard-register-number (see above). */
4166+
4167+/* A C initializer containing the assembler's names for the machine registers,
4168+ each one as a C string constant. This is what translates register numbers
4169+ in the compiler into assembler language. */
4170+#define REGISTER_NAMES \
4171+ { \
4172+ "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
4173+ "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
4174+ "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
4175+ "acc0_hi", "acc0_lo", \
4176+ "acc1_hi", "acc1_lo", \
4177+ "source3", \
4178+ "arg", \
4179+ "cc", \
4180+ "int_set0", "int_set1", \
4181+ "int_clr0", "int_clr1", \
4182+ "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
4183+ }
4184+
4185+#define CONDITIONAL_REGISTER_USAGE \
4186+ ubicom32_conditional_register_usage ();
4187+
4188+/* Order of allocation of registers. */
4189+
4190+/* If defined, an initializer for a vector of integers, containing the numbers
4191+ of hard registers in the order in which GNU CC should prefer to use them
4192+ (from most preferred to least).
4193+
4194+ For Ubicom32 we try using caller-clobbered data registers first, then
4195+ callee-saved data registers, then caller-clobbered address registers,
4196+ then callee-saved address registers and finally everything else.
4197+
4198+ The caller-clobbered registers are usually slightly cheaper to use because
4199+ there's no need to save/restore. */
4200+#define REG_ALLOC_ORDER \
4201+ { \
4202+ 0, 1, 2, 3, 4, /* d0 - d4 */ \
4203+ 5, 6, 7, 8, 9, /* d5 - d9 */ \
4204+ 14, /* d14 */ \
4205+ 10, 11, 12, 13, /* d10 - d13 */ \
4206+ 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
4207+ 17, 18, 22, /* a1, a2, a6 */ \
4208+ 24, 25, /* acc0 hi/lo */ \
4209+ 26, 27, /* acc0 hi/lo */ \
4210+ 28 /* source3 */ \
4211+ }
4212+
4213+/* C expression for the number of consecutive hard registers, starting at
4214+ register number REGNO, required to hold a value of mode MODE. */
4215+#define HARD_REGNO_NREGS(REGNO, MODE) \
4216+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4217+
4218+/* Most registers can hold QImode, HImode and SImode values but we have to
4219+ be able to indicate any hard registers that cannot hold values with some
4220+ modes. */
4221+#define HARD_REGNO_MODE_OK(REGNO, MODE) \
4222+ ubicom32_hard_regno_mode_ok(REGNO, MODE)
4223+
4224+/* We can rename most registers aside from the FDPIC register if we're using
4225+ FDPIC. */
4226+#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
4227+
4228+/* A C expression that is nonzero if it is desirable to choose register
4229+ allocation so as to avoid move instructions between a value of mode MODE1
4230+ and a value of mode MODE2.
4231+
4232+ If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
4233+ ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
4234+ zero. */
4235+#define MODES_TIEABLE_P(MODE1, MODE2) 1
4236+
4237+/* An enumeral type that must be defined with all the register class names as
4238+ enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
4239+ register class, followed by one more enumeral value, `LIM_REG_CLASSES',
4240+ which is not a register class but rather tells how many classes there are.
4241+
4242+ Each register class has a number, which is the value of casting the class
4243+ name to type `int'. The number serves as an index in many of the tables
4244+ described below. */
4245+
4246+enum reg_class
4247+{
4248+ NO_REGS,
4249+ DATA_REGS,
4250+ FDPIC_REG,
4251+ ADDRESS_REGS,
4252+ ALL_ADDRESS_REGS,
4253+ ACC_LO_REGS,
4254+ ACC_REGS,
4255+ CC_REG,
4256+ DATA_ACC_REGS,
4257+ SOURCE3_REG,
4258+ SPECIAL_REGS,
4259+ GENERAL_REGS,
4260+ ALL_REGS,
4261+ LIM_REG_CLASSES
4262+};
4263+
4264+/* The number of distinct register classes. */
4265+#define N_REG_CLASSES (int) LIM_REG_CLASSES
4266+
4267+/* An initializer containing the names of the register classes as C string
4268+ constants. These names are used in writing some of the debugging dumps. */
4269+
4270+#define REG_CLASS_NAMES \
4271+{ \
4272+ "NO_REGS", \
4273+ "DATA_REGS", \
4274+ "FDPIC_REG", \
4275+ "ADDRESS_REGS", \
4276+ "ALL_ADDRESS_REGS", \
4277+ "ACC_LO_REGS", \
4278+ "ACC_REGS", \
4279+ "CC_REG", \
4280+ "DATA_ACC_REGS", \
4281+ "SOURCE3_REG", \
4282+ "SPECIAL_REGS", \
4283+ "GENERAL_REGS", \
4284+ "ALL_REGS", \
4285+ "LIM_REGS" \
4286+}
4287+
4288+/* An initializer containing the contents of the register classes, as integers
4289+ which are bit masks. The Nth integer specifies the contents of class N.
4290+ The way the integer MASK is interpreted is that register R is in the class
4291+ if `MASK & (1 << R)' is 1.
4292+
4293+ When the machine has more than 32 registers, an integer does not suffice.
4294+ Then the integers are replaced by sub-initializers, braced groupings
4295+ containing several integers. Each sub-initializer must be suitable as an
4296+ initializer for the type `HARD_REG_SET' which is defined in
4297+ `hard-reg-set.h'. */
4298+#define REG_CLASS_CONTENTS \
4299+{ \
4300+ {0x00000000, 0x00000000}, /* No regs */ \
4301+ {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
4302+ {0x00010000, 0x00000000}, /* FDPIC_REG */ \
4303+ {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
4304+ {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
4305+ {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
4306+ {0x0f000000, 0x00000000}, /* ACC_REGS */ \
4307+ {0x40000000, 0x00000000}, /* CC_REG */ \
4308+ {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
4309+ {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
4310+ {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
4311+ {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
4312+ {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
4313+}
4314+
4315+extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
4316+
4317+/* A C expression whose value is a register class containing hard register
4318+ REGNO. In general there is more than one such class; choose a class which
4319+ is "minimal", meaning that no smaller class also contains the register. */
4320+#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
4321+
4322+#define IRA_COVER_CLASSES \
4323+{ \
4324+ GENERAL_REGS, \
4325+ LIM_REG_CLASSES \
4326+}
4327+
4328+/* Ubicom32 base registers must be address registers since addresses can
4329+ only be reached via address registers. */
4330+#define BASE_REG_CLASS ALL_ADDRESS_REGS
4331+
4332+/* Ubicom32 index registers must be data registers since we cannot add
4333+ two address registers together to form an address. */
4334+#define INDEX_REG_CLASS DATA_REGS
4335+
4336+/* A C expression which is nonzero if register number NUM is suitable for use
4337+ as a base register in operand addresses. It may be either a suitable hard
4338+ register or a pseudo register that has been allocated such a hard register. */
4339+
4340+#ifndef REG_OK_STRICT
4341+#define REGNO_OK_FOR_BASE_P(regno) \
4342+ ubicom32_regno_ok_for_base_p (regno, 0)
4343+#else
4344+#define REGNO_OK_FOR_BASE_P(regno) \
4345+ ubicom32_regno_ok_for_base_p (regno, 1)
4346+#endif
4347+
4348+/* A C expression which is nonzero if register number NUM is suitable for use
4349+ as an index register in operand addresses. It may be either a suitable hard
4350+ register or a pseudo register that has been allocated such a hard register.
4351+
4352+ The difference between an index register and a base register is that the
4353+ index register may be scaled. If an address involves the sum of two
4354+ registers, neither one of them scaled, then either one may be labeled the
4355+ "base" and the other the "index"; but whichever labeling is used must fit
4356+ the machine's constraints of which registers may serve in each capacity.
4357+ The compiler will try both labelings, looking for one that is valid, and
4358+ will reload one or both registers only if neither labeling works. */
4359+#ifndef REG_OK_STRICT
4360+#define REGNO_OK_FOR_INDEX_P(regno) \
4361+ ubicom32_regno_ok_for_index_p (regno, 0)
4362+#else
4363+#define REGNO_OK_FOR_INDEX_P(regno) \
4364+ ubicom32_regno_ok_for_index_p (regno, 1)
4365+#endif
4366+
4367+/* Attempt to restrict the register class we need to copy value X intoto the
4368+ would-be register class CLASS. Most things are fine for Ubicom32 but we
4369+ have to restrict certain types of address loads. */
4370+#define PREFERRED_RELOAD_CLASS(X, CLASS) \
4371+ ubicom32_preferred_reload_class (X, CLASS)
4372+
4373+/* A C expression for the maximum number of consecutive registers of
4374+ class CLASS needed to hold a value of mode MODE. For Ubicom32 this
4375+ is pretty much identical to HARD_REGNO_NREGS. */
4376+#define CLASS_MAX_NREGS(CLASS, MODE) \
4377+ ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4378+
4379+/* For Ubicom32 the stack grows downwards when we push a word onto the stack
4380+ - i.e. it moves to a smaller address. */
4381+#define STACK_GROWS_DOWNWARD 1
4382+
4383+/* Offset from the frame pointer to the first local variable slot to
4384+ be allocated. */
4385+#define STARTING_FRAME_OFFSET 0
4386+
4387+/* Offset from the argument pointer register to the first argument's
4388+ address. */
4389+#define FIRST_PARM_OFFSET(FNDECL) 0
4390+
4391+/* A C expression whose value is RTL representing the value of the return
4392+ address for the frame COUNT steps up from the current frame, after the
4393+ prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
4394+ pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
4395+ defined.
4396+
4397+ The value of the expression must always be the correct address when COUNT is
4398+ zero, but may be `NULL_RTX' if there is not way to determine the return
4399+ address of other frames. */
4400+#define RETURN_ADDR_RTX(COUNT, FRAME) \
4401+ ubicom32_return_addr_rtx (COUNT, FRAME)
4402+
4403+/* Register That Address the Stack Frame. */
4404+
4405+/* We don't actually require a frame pointer in most functions with the
4406+ Ubicom32 architecture so we allow it to be eliminated. */
4407+#define FRAME_POINTER_REQUIRED 0
4408+
4409+/* Macro that defines a table of register pairs used to eliminate unecessary
4410+ registers that point into the stack frame.
4411+
4412+ For Ubicom32 we don't generally need an arg pointer of a frame pointer
4413+ so we allow the arg pointer to be replaced by either the frame pointer or
4414+ the stack pointer. We also allow the frame pointer to be replaced by
4415+ the stack pointer. */
4416+#define ELIMINABLE_REGS \
4417+{ \
4418+ {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
4419+ {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
4420+ {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
4421+}
4422+
4423+/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
4424+ above. */
4425+#define CAN_ELIMINATE(FROM, TO) 1
4426+
4427+/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
4428+ initial difference between the specified pair of registers. This macro must
4429+ be defined if `ELIMINABLE_REGS' is defined. */
4430+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
4431+ (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
4432+
4433+/* If defined, the maximum amount of space required for outgoing arguments will
4434+ be computed and placed into the variable
4435+ `current_function_outgoing_args_size'. No space will be pushed onto the
4436+ stack for each call; instead, the function prologue should increase the
4437+ stack frame size by this amount.
4438+
4439+ Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
4440+ proper. */
4441+#define ACCUMULATE_OUTGOING_ARGS 1
4442+
4443+/* Define this macro if functions should assume that stack space has been
4444+ allocated for arguments even when their values are passed in registers.
4445+
4446+ The value of this macro is the size, in bytes, of the area reserved for
4447+ arguments passed in registers for the function represented by FNDECL.
4448+
4449+ This space can be allocated by the caller, or be a part of the
4450+ machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
4451+ which. */
4452+#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
4453+
4454+/* A C expression that should indicate the number of bytes of its own arguments
4455+ that a function pops on returning, or 0 if the function pops no arguments
4456+ and the caller must therefore pop them all after the function returns.
4457+
4458+ FUNDECL is a C variable whose value is a tree node that describes the
4459+ function in question. Normally it is a node of type `FUNCTION_DECL' that
4460+ describes the declaration of the function. From this it is possible to
4461+ obtain the DECL_MACHINE_ATTRIBUTES of the function.
4462+
4463+ FUNTYPE is a C variable whose value is a tree node that describes the
4464+ function in question. Normally it is a node of type `FUNCTION_TYPE' that
4465+ describes the data type of the function. From this it is possible to obtain
4466+ the data types of the value and arguments (if known).
4467+
4468+ When a call to a library function is being considered, FUNTYPE will contain
4469+ an identifier node for the library function. Thus, if you need to
4470+ distinguish among various library functions, you can do so by their names.
4471+ Note that "library function" in this context means a function used to
4472+ perform arithmetic, whose name is known specially in the compiler and was
4473+ not mentioned in the C code being compiled.
4474+
4475+ STACK-SIZE is the number of bytes of arguments passed on the stack. If a
4476+ variable number of bytes is passed, it is zero, and argument popping will
4477+ always be the responsibility of the calling function.
4478+
4479+ On the Vax, all functions always pop their arguments, so the definition of
4480+ this macro is STACK-SIZE. On the 68000, using the standard calling
4481+ convention, no functions pop their arguments, so the value of the macro is
4482+ always 0 in this case. But an alternative calling convention is available
4483+ in which functions that take a fixed number of arguments pop them but other
4484+ functions (such as `printf') pop nothing (the caller pops all). When this
4485+ convention is in use, FUNTYPE is examined to determine whether a function
4486+ takes a fixed number of arguments. */
4487+#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
4488+
4489+/* A C expression that controls whether a function argument is passed in a
4490+ register, and which register.
4491+
4492+ The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
4493+ defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
4494+ arguments so far passed in registers; MODE, the machine mode of the argument;
4495+ TYPE, the data type of the argument as a tree node or 0 if that is not known
4496+ (which happens for C support library functions); and NAMED, which is 1 for an
4497+ ordinary argument and 0 for nameless arguments that correspond to `...' in the
4498+ called function's prototype.
4499+
4500+ The value of the expression should either be a `reg' RTX for the hard
4501+ register in which to pass the argument, or zero to pass the argument on the
4502+ stack.
4503+
4504+ For machines like the Vax and 68000, where normally all arguments are
4505+ pushed, zero suffices as a definition.
4506+
4507+ The usual way to make the ANSI library `stdarg.h' work on a machine where
4508+ some arguments are usually passed in registers, is to cause nameless
4509+ arguments to be passed on the stack instead. This is done by making
4510+ `FUNCTION_ARG' return 0 whenever NAMED is 0.
4511+
4512+ You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
4513+ this macro to determine if this argument is of a type that must be passed in
4514+ the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
4515+ returns non-zero for such an argument, the compiler will abort. If
4516+ `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
4517+ stack and then loaded into a register. */
4518+#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
4519+ function_arg (&CUM, MODE, TYPE, NAMED)
4520+
4521+#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
4522+ function_incoming_arg (&CUM, MODE, TYPE, NAMED)
4523+
4524+/* A C expression for the number of words, at the beginning of an argument,
4525+ must be put in registers. The value must be zero for arguments that are
4526+ passed entirely in registers or that are entirely pushed on the stack.
4527+
4528+ On some machines, certain arguments must be passed partially in registers
4529+ and partially in memory. On these machines, typically the first N words of
4530+ arguments are passed in registers, and the rest on the stack. If a
4531+ multi-word argument (a `double' or a structure) crosses that boundary, its
4532+ first few words must be passed in registers and the rest must be pushed.
4533+ This macro tells the compiler when this occurs, and how many of the words
4534+ should go in registers.
4535+
4536+ `FUNCTION_ARG' for these arguments should return the first register to be
4537+ used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
4538+ the called function. */
4539+
4540+/* A C expression that indicates when an argument must be passed by reference.
4541+ If nonzero for an argument, a copy of that argument is made in memory and a
4542+ pointer to the argument is passed instead of the argument itself. The
4543+ pointer is passed in whatever way is appropriate for passing a pointer to
4544+ that type.
4545+
4546+ On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
4547+ definition of this macro might be
4548+ #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
4549+ MUST_PASS_IN_STACK (MODE, TYPE) */
4550+
4551+/* If defined, a C expression that indicates when it is the called function's
4552+ responsibility to make a copy of arguments passed by invisible reference.
4553+ Normally, the caller makes a copy and passes the address of the copy to the
4554+ routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
4555+ nonzero, the caller does not make a copy. Instead, it passes a pointer to
4556+ the "live" value. The called function must not modify this value. If it
4557+ can be determined that the value won't be modified, it need not make a copy;
4558+ otherwise a copy must be made. */
4559+
4560+/* A C type for declaring a variable that is used as the first argument of
4561+ `FUNCTION_ARG' and other related values. For some target machines, the type
4562+ `int' suffices and can hold the number of bytes of argument so far.
4563+
4564+ There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
4565+ that have been passed on the stack. The compiler has other variables to
4566+ keep track of that. For target machines on which all arguments are passed
4567+ on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
4568+ however, the data structure must exist and should not be empty, so use
4569+ `int'. */
4570+struct cum_arg
4571+{
4572+ int nbytes;
4573+ int reg;
4574+ int stdarg;
4575+};
4576+#define CUMULATIVE_ARGS struct cum_arg
4577+
4578+/* A C statement (sans semicolon) for initializing the variable CUM for the
4579+ state at the beginning of the argument list. The variable has type
4580+ `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
4581+ of the function which will receive the args, or 0 if the args are to a
4582+ compiler support library function. The value of INDIRECT is nonzero when
4583+ processing an indirect call, for example a call through a function pointer.
4584+ The value of INDIRECT is zero for a call to an explicitly named function, a
4585+ library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
4586+ arguments for the function being compiled.
4587+
4588+ When processing a call to a compiler support library function, LIBNAME
4589+ identifies which one. It is a `symbol_ref' rtx which contains the name of
4590+ the function, as a string. LIBNAME is 0 when an ordinary C function call is
4591+ being processed. Thus, each time this macro is called, either LIBNAME or
4592+ FNTYPE is nonzero, but never both of them at once. */
4593+
4594+#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
4595+ init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
4596+
4597+/* A C statement (sans semicolon) to update the summarizer variable CUM to
4598+ advance past an argument in the argument list. The values MODE, TYPE and
4599+ NAMED describe that argument. Once this is done, the variable CUM is
4600+ suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
4601+
4602+ This macro need not do anything if the argument in question was passed on
4603+ the stack. The compiler knows how to track the amount of stack space used
4604+ for arguments without any special help. */
4605+#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
4606+ ((CUM).nbytes += ((MODE) != BLKmode \
4607+ ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
4608+ : (int_size_in_bytes (TYPE) + 3) & ~3))
4609+
4610+/* For the Ubicom32 we define the upper function argument register here. */
4611+#define UBICOM32_FUNCTION_ARG_REGS 10
4612+
4613+/* A C expression that is nonzero if REGNO is the number of a hard register in
4614+ which function arguments are sometimes passed. This does *not* include
4615+ implicit arguments such as the static chain and the structure-value address.
4616+ On many machines, no registers can be used for this purpose since all
4617+ function arguments are pushed on the stack. */
4618+#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
4619+
4620+
4621+/* How Scalar Function Values are Returned. */
4622+
4623+/* The number of the hard register that is used to return a scalar value from a
4624+ function call. */
4625+#define RETURN_VALUE_REGNUM 0
4626+
4627+/* A C expression to create an RTX representing the place where a function
4628+ returns a value of data type VALTYPE. VALTYPE is a tree node representing a
4629+ data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
4630+ represent that type. On many machines, only the mode is relevant.
4631+ (Actually, on most machines, scalar values are returned in the same place
4632+ regardless of mode).
4633+
4634+ If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
4635+ rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
4636+
4637+ If the precise function being called is known, FUNC is a tree node
4638+ (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
4639+ possible to use a different value-returning convention for specific
4640+ functions when all their calls are known.
4641+
4642+ `FUNCTION_VALUE' is not used for return vales with aggregate data types,
4643+ because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
4644+ related macros, below. */
4645+#define FUNCTION_VALUE(VALTYPE, FUNC) \
4646+ gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
4647+
4648+/* A C expression to create an RTX representing the place where a library
4649+ function returns a value of mode MODE.
4650+
4651+ Note that "library function" in this context means a compiler support
4652+ routine, used to perform arithmetic, whose name is known specially by the
4653+ compiler and was not mentioned in the C code being compiled.
4654+
4655+ The definition of `LIBRARY_VALUE' need not be concerned aggregate data
4656+ types, because none of the library functions returns such types. */
4657+#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
4658+
4659+/* A C expression that is nonzero if REGNO is the number of a hard register in
4660+ which the values of called function may come back.
4661+
4662+ A register whose use for returning values is limited to serving as the
4663+ second of a pair (for a value of type `double', say) need not be recognized
4664+ by this macro. So for most machines, this definition suffices:
4665+
4666+ #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
4667+
4668+ If the machine has register windows, so that the caller and the called
4669+ function use different registers for the return value, this macro should
4670+ recognize only the caller's register numbers. */
4671+#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
4672+
4673+
4674+/* How Large Values are Returned. */
4675+
4676+/* A C expression which can inhibit the returning of certain function values in
4677+ registers, based on the type of value. A nonzero value says to return the
4678+ function value in memory, just as large structures are always returned.
4679+ Here TYPE will be a C expression of type `tree', representing the data type
4680+ of the value.
4681+
4682+ Note that values of mode `BLKmode' must be explicitly handled by this macro.
4683+ Also, the option `-fpcc-struct-return' takes effect regardless of this
4684+ macro. On most systems, it is possible to leave the macro undefined; this
4685+ causes a default definition to be used, whose value is the constant 1 for
4686+ `BLKmode' values, and 0 otherwise.
4687+
4688+ Do not use this macro to indicate that structures and unions should always
4689+ be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
4690+ to indicate this. */
4691+#define RETURN_IN_MEMORY(TYPE) \
4692+ (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
4693+
4694+/* Define this macro to be 1 if all structure and union return values must be
4695+ in memory. Since this results in slower code, this should be defined only
4696+ if needed for compatibility with other compilers or with an ABI. If you
4697+ define this macro to be 0, then the conventions used for structure and union
4698+ return values are decided by the `RETURN_IN_MEMORY' macro.
4699+
4700+ If not defined, this defaults to the value 1. */
4701+#define DEFAULT_PCC_STRUCT_RETURN 0
4702+
4703+/* If the structure value address is not passed in a register, define
4704+ `STRUCT_VALUE' as an expression returning an RTX for the place
4705+ where the address is passed. If it returns 0, the address is
4706+ passed as an "invisible" first argument. */
4707+#define STRUCT_VALUE 0
4708+
4709+/* Define this macro as a C expression that is nonzero if the return
4710+ instruction or the function epilogue ignores the value of the stack pointer;
4711+ in other words, if it is safe to delete an instruction to adjust the stack
4712+ pointer before a return from the function.
4713+
4714+ Note that this macro's value is relevant only for functions for which frame
4715+ pointers are maintained. It is never safe to delete a final stack
4716+ adjustment in a function that has no frame pointer, and the compiler knows
4717+ this regardless of `EXIT_IGNORE_STACK'. */
4718+#define EXIT_IGNORE_STACK 1
4719+
4720+/* A C statement or compound statement to output to FILE some assembler code to
4721+ call the profiling subroutine `mcount'. Before calling, the assembler code
4722+ must load the address of a counter variable into a register where `mcount'
4723+ expects to find the address. The name of this variable is `LP' followed by
4724+ the number LABELNO, so you would generate the name using `LP%d' in a
4725+ `fprintf'.
4726+
4727+ The details of how the address should be passed to `mcount' are determined
4728+ by your operating system environment, not by GNU CC. To figure them out,
4729+ compile a small program for profiling using the system's installed C
4730+ compiler and look at the assembler code that results.
4731+
4732+ This declaration must be present, but it can be an abort if profiling is
4733+ not implemented. */
4734+
4735+#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
4736+
4737+/* A C statement to output, on the stream FILE, assembler code for a block of
4738+ data that contains the constant parts of a trampoline. This code should not
4739+ include a label--the label is taken care of automatically. */
4740+#if 0
4741+#define TRAMPOLINE_TEMPLATE(FILE) \
4742+ do { \
4743+ fprintf (FILE, "\tadd -4,sp\n"); \
4744+ fprintf (FILE, "\t.long 0x0004fffa\n"); \
4745+ fprintf (FILE, "\tmov (0,sp),a0\n"); \
4746+ fprintf (FILE, "\tadd 4,sp\n"); \
4747+ fprintf (FILE, "\tmov (13,a0),a1\n"); \
4748+ fprintf (FILE, "\tmov (17,a0),a0\n"); \
4749+ fprintf (FILE, "\tjmp (a0)\n"); \
4750+ fprintf (FILE, "\t.long 0\n"); \
4751+ fprintf (FILE, "\t.long 0\n"); \
4752+ } while (0)
4753+#endif
4754+
4755+/* A C expression for the size in bytes of the trampoline, as an integer. */
4756+#define TRAMPOLINE_SIZE 0x1b
4757+
4758+/* Alignment required for trampolines, in bits.
4759+
4760+ If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
4761+ aligning trampolines. */
4762+#define TRAMPOLINE_ALIGNMENT 32
4763+
4764+/* A C statement to initialize the variable parts of a trampoline. ADDR is an
4765+ RTX for the address of the trampoline; FNADDR is an RTX for the address of
4766+ the nested function; STATIC_CHAIN is an RTX for the static chain value that
4767+ should be passed to the function when it is called. */
4768+#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
4769+{ \
4770+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
4771+ (CXT)); \
4772+ emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
4773+ (FNADDR)); \
4774+}
4775+
4776+/* Ubicom32 supports pre and post increment/decrement addressing. */
4777+#define HAVE_POST_INCREMENT 1
4778+#define HAVE_PRE_INCREMENT 1
4779+#define HAVE_POST_DECREMENT 1
4780+#define HAVE_PRE_DECREMENT 1
4781+
4782+/* Ubicom32 supports pre and post address side-effects with constants
4783+ other than the size of the memory operand. */
4784+#define HAVE_PRE_MODIFY_DISP 1
4785+#define HAVE_POST_MODIFY_DISP 1
4786+
4787+/* A C expression that is 1 if the RTX X is a constant which is a valid
4788+ address. On most machines, this can be defined as `CONSTANT_P (X)',
4789+ but a few machines are more restrictive in which constant addresses
4790+ are supported.
4791+
4792+ `CONSTANT_P' accepts integer-values expressions whose values are not
4793+ explicitly known, such as `symbol_ref', `label_ref', and `high'
4794+ expressions and `const' arithmetic expressions, in addition to
4795+ `const_int' and `const_double' expressions. */
4796+#define CONSTANT_ADDRESS_P(X) \
4797+ (GET_CODE (X) == LABEL_REF \
4798+ || (GET_CODE (X) == CONST \
4799+ && GET_CODE (XEXP (X, 0)) == PLUS \
4800+ && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
4801+
4802+/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
4803+ One is always an address register while a second, optional, one may be a
4804+ data register. */
4805+#define MAX_REGS_PER_ADDRESS 2
4806+
4807+/* A C compound statement with a conditional `goto LABEL;' executed if X (an
4808+ RTX) is a legitimate memory address on the target machine for a memory
4809+ operand of mode MODE.
4810+
4811+ It usually pays to define several simpler macros to serve as subroutines for
4812+ this one. Otherwise it may be too complicated to understand.
4813+
4814+ This macro must exist in two variants: a strict variant and a non-strict
4815+ one. The strict variant is used in the reload pass. It must be defined so
4816+ that any pseudo-register that has not been allocated a hard register is
4817+ considered a memory reference. In contexts where some kind of register is
4818+ required, a pseudo-register with no hard register must be rejected.
4819+
4820+ The non-strict variant is used in other passes. It must be defined to
4821+ accept all pseudo-registers in every context where some kind of register is
4822+ required.
4823+
4824+ Compiler source files that want to use the strict variant of this macro
4825+ define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
4826+ conditional to define the strict variant in that case and the non-strict
4827+ variant otherwise.
4828+
4829+ Subroutines to check for acceptable registers for various purposes (one for
4830+ base registers, one for index registers, and so on) are typically among the
4831+ subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
4832+ subroutine macros need have two variants; the higher levels of macros may be
4833+ the same whether strict or not.
4834+
4835+ Normally, constant addresses which are the sum of a `symbol_ref' and an
4836+ integer are stored inside a `const' RTX to mark them as constant.
4837+ Therefore, there is no need to recognize such sums specifically as
4838+ legitimate addresses. Normally you would simply recognize any `const' as
4839+ legitimate.
4840+
4841+ Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
4842+ are not marked with `const'. It assumes that a naked `plus' indicates
4843+ indexing. If so, then you *must* reject such naked constant sums as
4844+ illegitimate addresses, so that none of them will be given to
4845+ `PRINT_OPERAND_ADDRESS'.
4846+
4847+ On some machines, whether a symbolic address is legitimate depends on the
4848+ section that the address refers to. On these machines, define the macro
4849+ `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
4850+ then check for it here. When you see a `const', you will have to look
4851+ inside it to find the `symbol_ref' in order to determine the section.
4852+
4853+ The best way to modify the name string is by adding text to the beginning,
4854+ with suitable punctuation to prevent any ambiguity. Allocate the new name
4855+ in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
4856+ remove and decode the added text and output the name accordingly, and define
4857+ `STRIP_NAME_ENCODING' to access the original name string.
4858+
4859+ You can check the information stored here into the `symbol_ref' in the
4860+ definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
4861+ `PRINT_OPERAND_ADDRESS'. */
4862+/* On the ubicom32, the value in the address register must be
4863+ in the same memory space/segment as the effective address.
4864+
4865+ This is problematical for reload since it does not understand
4866+ that base+index != index+base in a memory reference. */
4867+
4868+#ifdef REG_OK_STRICT
4869+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4870+ if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
4871+#else
4872+#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4873+ if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
4874+#endif
4875+
4876+/* Try machine-dependent ways of modifying an illegitimate address
4877+ to be legitimate. If we find one, return the new, valid address.
4878+ This macro is used in only one place: `memory_address' in explow.c.
4879+
4880+ OLDX is the address as it was before break_out_memory_refs was called.
4881+ In some cases it is useful to look at this to decide what needs to be done.
4882+
4883+ MODE and WIN are passed so that this macro can use
4884+ GO_IF_LEGITIMATE_ADDRESS.
4885+
4886+ It is always safe for this macro to do nothing. It exists to recognize
4887+ opportunities to optimize the output.
4888+
4889+ On RS/6000, first check for the sum of a register with a constant
4890+ integer that is out of range. If so, generate code to add the
4891+ constant with the low-order 16 bits masked to the register and force
4892+ this result into another register (this can be done with `cau').
4893+ Then generate an address of REG+(CONST&0xffff), allowing for the
4894+ possibility of bit 16 being a one.
4895+
4896+ Then check for the sum of a register and something not constant, try to
4897+ load the other things into a register and return the sum. */
4898+
4899+#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
4900+{ \
4901+ rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
4902+ if (result != NULL_RTX) \
4903+ { \
4904+ (X) = result; \
4905+ goto WIN; \
4906+ } \
4907+}
4908+
4909+/* Try a machine-dependent way of reloading an illegitimate address
4910+ operand. If we find one, push the reload and jump to WIN. This
4911+ macro is used in only one place: `find_reloads_address' in reload.c. */
4912+#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
4913+{ \
4914+ rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
4915+ if (new_rtx) \
4916+ { \
4917+ (AD) = new_rtx; \
4918+ goto WIN; \
4919+ } \
4920+}
4921+
4922+/* A C statement or compound statement with a conditional `goto LABEL;'
4923+ executed if memory address X (an RTX) can have different meanings depending
4924+ on the machine mode of the memory reference it is used for or if the address
4925+ is valid for some modes but not others.
4926+
4927+ Autoincrement and autodecrement addresses typically have mode-dependent
4928+ effects because the amount of the increment or decrement is the size of the
4929+ operand being addressed. Some machines have other mode-dependent addresses.
4930+ Many RISC machines have no mode-dependent addresses.
4931+
4932+ You may assume that ADDR is a valid address for the machine. */
4933+#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
4934+ if (ubicom32_mode_dependent_address_p (ADDR)) \
4935+ goto LABEL;
4936+
4937+/* A C expression that is nonzero if X is a legitimate constant for an
4938+ immediate operand on the target machine. You can assume that X
4939+ satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
4940+ a suitable definition for this macro on machines where anything
4941+ `CONSTANT_P' is valid. */
4942+#define LEGITIMATE_CONSTANT_P(X) \
4943+ ubicom32_legitimate_constant_p ((X))
4944+
4945+/* Moves between registers are pretty-much single instructions for
4946+ Ubicom32. We make this the default "2" that gcc likes. */
4947+#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
4948+
4949+/* This is a little bit of magic from the S390 port that wins 2% on code
4950+ size when building the Linux kernel! Unfortunately while it wins on
4951+ that size the user-space apps built using FD-PIC don't improve and the
4952+ performance is lower because we put more pressure on the caches. We may
4953+ want this back on some future CPU that has higher cache performance. */
4954+/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
4955+
4956+/* Moves between registers and memory are more expensive than between
4957+ registers because we have caches and write buffers that slow things
4958+ down! */
4959+#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
4960+
4961+/* A fall-through branch is very low cost but anything that changes the PC
4962+ incurs a major pipeline hazard. We don't make the full extent of this
4963+ hazard visible because we hope that multiple threads will absorb much
4964+ of the cost and so we don't want a jump being replaced with, say, 7
4965+ instructions. */
4966+#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
4967+ ((PREDICTABLE_P) ? 1 : 3)
4968+
4969+/* Define this macro as a C expression which is nonzero if accessing less than
4970+ a word of memory (i.e. a `char' or a `short') is no faster than accessing a
4971+ word of memory, i.e., if such access require more than one instruction or if
4972+ there is no difference in cost between byte and (aligned) word loads.
4973+
4974+ When this macro is not defined, the compiler will access a field by finding
4975+ the smallest containing object; when it is defined, a fullword load will be
4976+ used if alignment permits. Unless bytes accesses are faster than word
4977+ accesses, using word accesses is preferable since it may eliminate
4978+ subsequent memory access if subsequent accesses occur to other fields in the
4979+ same word of the structure, but to different bytes. */
4980+#define SLOW_BYTE_ACCESS 0
4981+
4982+/* The number of scalar move insns which should be generated instead of a
4983+ string move insn or a library call. Increasing the value will always make
4984+ code faster, but eventually incurs high cost in increased code size.
4985+
4986+ If you don't define this, a reasonable default is used. */
4987+/* According to expr.c, a value of around 6 should minimize code size. */
4988+#define MOVE_RATIO(SPEED) 6
4989+
4990+/* We're much better off calling a constant function address with the
4991+ Ubicom32 architecture because we have an opcode for doing so. Don't
4992+ let the compiler extract function addresses as common subexpressions
4993+ into an address register. */
4994+#define NO_FUNCTION_CSE
4995+
4996+#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
4997+
4998+#define REVERSIBLE_CC_MODE(MODE) 1
4999+
5000+/* Canonicalize a comparison from one we don't have to one we do have. */
5001+#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
5002+ ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
5003+
5004+/* Dividing the output into sections. */
5005+
5006+/* A C expression whose value is a string containing the assembler operation
5007+ that should precede instructions and read-only data. Normally `".text"' is
5008+ right. */
5009+#define TEXT_SECTION_ASM_OP "\t.section .text"
5010+
5011+/* A C expression whose value is a string containing the assembler operation to
5012+ identify the following data as writable initialized data. Normally
5013+ `".data"' is right. */
5014+#define DATA_SECTION_ASM_OP "\t.section .data"
5015+
5016+
5017+/* If defined, a C expression whose value is a string containing the
5018+ assembler operation to identify the following data as
5019+ uninitialized global data. If not defined, and neither
5020+ `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
5021+ uninitialized global data will be output in the data section if
5022+ `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
5023+ used. */
5024+#define BSS_SECTION_ASM_OP "\t.section .bss"
5025+
5026+/* This is how we tell the assembler that a symbol is weak. */
5027+
5028+#define ASM_WEAKEN_LABEL(FILE, NAME) \
5029+ do \
5030+ { \
5031+ fputs ("\t.weak\t", (FILE)); \
5032+ assemble_name ((FILE), (NAME)); \
5033+ fputc ('\n', (FILE)); \
5034+ } \
5035+ while (0)
5036+
5037+/* The Overall Framework of an Assembler File. */
5038+
5039+#undef SET_ASM_OP
5040+#define SET_ASM_OP "\t.set\t"
5041+
5042+/* A C string constant describing how to begin a comment in the target
5043+ assembler language. The compiler assumes that the comment will end at the
5044+ end of the line. */
5045+#define ASM_COMMENT_START ";"
5046+
5047+/* A C string constant for text to be output before each `asm' statement or
5048+ group of consecutive ones. Normally this is `"#APP"', which is a comment
5049+ that has no effect on most assemblers but tells the GNU assembler that it
5050+ must check the lines that follow for all valid assembler constructs. */
5051+#define ASM_APP_ON "#APP\n"
5052+
5053+/* A C string constant for text to be output after each `asm' statement or
5054+ group of consecutive ones. Normally this is `"#NO_APP"', which tells the
5055+ GNU assembler to resume making the time-saving assumptions that are valid
5056+ for ordinary compiler output. */
5057+#define ASM_APP_OFF "#NO_APP\n"
5058+
5059+/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
5060+ explicit argument. If you define this macro, it is used in place of
5061+ `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
5062+ alignment of the variable. The alignment is specified as the number of
5063+ bits.
5064+
5065+ Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
5066+ defining this macro. */
5067+#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
5068+ asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
5069+
5070+/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
5071+ newly allocated string made from the string NAME and the number NUMBER, with
5072+ some suitable punctuation added. Use `alloca' to get space for the string.
5073+
5074+ The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
5075+ an assembler label for an internal static variable whose name is NAME.
5076+ Therefore, the string must be such as to result in valid assembler code.
5077+ The argument NUMBER is different each time this macro is executed; it
5078+ prevents conflicts between similarly-named internal static variables in
5079+ different scopes.
5080+
5081+ Ideally this string should not be a valid C identifier, to prevent any
5082+ conflict with the user's own symbols. Most assemblers allow periods or
5083+ percent signs in assembler symbols; putting at least one of these between
5084+ the name and the number will suffice. */
5085+#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
5086+ ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
5087+ sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
5088+
5089+#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
5090+ sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
5091+/* A C statement to store into the string STRING a label whose name
5092+ is made from the string PREFIX and the number NUM.
5093+
5094+ This string, when output subsequently by `assemble_name', should
5095+ produce the output that `(*targetm.asm_out.internal_label)' would produce
5096+ with the same PREFIX and NUM.
5097+
5098+ If the string begins with `*', then `assemble_name' will output
5099+ the rest of the string unchanged. It is often convenient for
5100+ `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
5101+ string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
5102+ output the string, and may change it. (Of course,
5103+ `ASM_OUTPUT_LABELREF' is also part of your machine description, so
5104+ you should know what it does on your machine.) */
5105+
5106+/* This says how to output assembler code to declare an
5107+ uninitialized external linkage data object. Under SVR4,
5108+ the linker seems to want the alignment of data objects
5109+ to depend on their types. We do exactly that here. */
5110+
5111+#define COMMON_ASM_OP "\t.comm\t"
5112+
5113+#undef ASM_OUTPUT_COMMON
5114+#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
5115+ do \
5116+ { \
5117+ fprintf ((FILE), "%s", COMMON_ASM_OP); \
5118+ assemble_name ((FILE), (NAME)); \
5119+ fprintf ((FILE), ", %u\n", (SIZE)); \
5120+ } \
5121+ while (0)
5122+
5123+/* This says how to output assembler code to declare an
5124+ uninitialized internal linkage data object. Under SVR4,
5125+ the linker seems to want the alignment of data objects
5126+ to depend on their types. We do exactly that here. */
5127+#define LOCAL_ASM_OP "\t.lcomm\t"
5128+
5129+#undef ASM_OUTPUT_LOCAL
5130+#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
5131+ do \
5132+ { \
5133+ fprintf ((FILE), "%s", LOCAL_ASM_OP); \
5134+ assemble_name ((FILE), (NAME)); \
5135+ fprintf ((FILE), ", %u\n", (SIZE)); \
5136+ } \
5137+ while (0)
5138+
5139+/* Globalizing directive for a label. */
5140+#define GLOBAL_ASM_OP ".global\t"
5141+
5142+/* Output the operand of an instruction. */
5143+#define PRINT_OPERAND(FILE, X, CODE) \
5144+ ubicom32_print_operand(FILE, X, CODE)
5145+
5146+/* Output the address of an operand. */
5147+#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
5148+ ubicom32_print_operand_address (FILE, ADDR)
5149+
5150+/* A C expression to output to STREAM some assembler code which will push hard
5151+ register number REGNO onto the stack. The code need not be optimal, since
5152+ this macro is used only when profiling. */
5153+#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
5154+
5155+/* A C expression to output to STREAM some assembler code which will pop hard
5156+ register number REGNO off of the stack. The code need not be optimal, since
5157+ this macro is used only when profiling. */
5158+#define ASM_OUTPUT_REG_POP(FILE, REGNO)
5159+
5160+/* This macro should be provided on machines where the addresses in a dispatch
5161+ table are relative to the table's own address.
5162+
5163+ The definition should be a C statement to output to the stdio stream STREAM
5164+ an assembler pseudo-instruction to generate a difference between two labels.
5165+ VALUE and REL are the numbers of two internal labels. The definitions of
5166+ these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
5167+ printed in the same way here. For example,
5168+
5169+ fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
5170+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
5171+ fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
5172+
5173+/* This macro should be provided on machines where the addresses in a dispatch
5174+ table are absolute.
5175+
5176+ The definition should be a C statement to output to the stdio stream STREAM
5177+ an assembler pseudo-instruction to generate a reference to a label. VALUE
5178+ is the number of an internal label whose definition is output using
5179+ `ASM_OUTPUT_INTERNAL_LABEL'. For example,
5180+
5181+ fprintf (STREAM, "\t.word L%d\n", VALUE) */
5182+#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
5183+ fprintf (STREAM, "\t.word .L%d\n", VALUE)
5184+
5185+/* Switch into a generic section. */
5186+#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
5187+
5188+/* Assembler Commands for Alignment. */
5189+
5190+#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
5191+/* A C statement to output to the stdio stream STREAM an assembler
5192+ instruction to advance the location counter by NBYTES bytes.
5193+ Those bytes should be zero when loaded. NBYTES will be a C
5194+ expression of type `int'. */
5195+
5196+/* A C statement to output to the stdio stream STREAM an assembler command to
5197+ advance the location counter to a multiple of 2 to the POWER bytes. POWER
5198+ will be a C expression of type `int'. */
5199+#define ASM_OUTPUT_ALIGN(FILE, LOG) \
5200+ if ((LOG) != 0) \
5201+ fprintf (FILE, "\t.align %d\n", (LOG))
5202+
5203+/* A C expression that returns the DBX register number for the compiler
5204+ register number REGNO. In simple cases, the value of this expression may be
5205+ REGNO itself. But sometimes there are some registers that the compiler
5206+ knows about and DBX does not, or vice versa. In such cases, some register
5207+ may need to have one number in the compiler and another for DBX.
5208+
5209+ If two registers have consecutive numbers inside GNU CC, and they can be
5210+ used as a pair to hold a multiword value, then they *must* have consecutive
5211+ numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
5212+ will be unable to access such a pair, because they expect register pairs to
5213+ be consecutive in their own numbering scheme.
5214+
5215+ If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
5216+ preserve register pairs, then what you must do instead is redefine the
5217+ actual register numbering scheme.
5218+
5219+ This declaration is required. */
5220+#define DBX_REGISTER_NUMBER(REGNO) REGNO
5221+
5222+/* A C expression that returns the integer offset value for an automatic
5223+ variable having address X (an RTL expression). The default computation
5224+ assumes that X is based on the frame-pointer and gives the offset from the
5225+ frame-pointer. This is required for targets that produce debugging output
5226+ for DBX or COFF-style debugging output for SDB and allow the frame-pointer
5227+ to be eliminated when the `-g' options is used. */
5228+#define DEBUGGER_AUTO_OFFSET(X) \
5229+ ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
5230+ + (frame_pointer_needed \
5231+ ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
5232+ STACK_POINTER_REGNUM)))
5233+
5234+/* A C expression that returns the integer offset value for an argument having
5235+ address X (an RTL expression). The nominal offset is OFFSET. */
5236+#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
5237+ ((GET_CODE (X) == PLUS ? OFFSET : 0) \
5238+ + (frame_pointer_needed \
5239+ ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
5240+ STACK_POINTER_REGNUM)))
5241+
5242+/* A C expression that returns the type of debugging output GNU CC produces
5243+ when the user specifies `-g' or `-ggdb'. Define this if you have arranged
5244+ for GNU CC to support more than one format of debugging output. Currently,
5245+ the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
5246+ `DWARF2_DEBUG', and `XCOFF_DEBUG'.
5247+
5248+ The value of this macro only affects the default debugging output; the user
5249+ can always get a specific type of output by using `-gstabs', `-gcoff',
5250+ `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
5251+
5252+ Defined in svr4.h.
5253+*/
5254+#undef PREFERRED_DEBUGGING_TYPE
5255+#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
5256+
5257+/* Define this macro if GNU CC should produce dwarf version 2 format debugging
5258+ output in response to the `-g' option.
5259+
5260+ To support optional call frame debugging information, you must also define
5261+ `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
5262+ prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
5263+ and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
5264+ don't.
5265+
5266+ Defined in svr4.h. */
5267+
5268+#define DWARF2_DEBUGGING_INFO 1
5269+/*#define DWARF2_UNWIND_INFO 1*/
5270+#define DWARF2_UNWIND_INFO 0
5271+#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
5272+#define INCOMING_FRAME_SP_OFFSET 0
5273+#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
5274+#define EH_RETURN_FIRST 9
5275+#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
5276+
5277+/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
5278+ location used to store the amount to ajdust the stack. This is
5279+ usually a registers that is available from end of the function's body
5280+ to the end of the epilogue. Thus, this cannot be a register used as a
5281+ temporary by the epilogue.
5282+
5283+ This must be an integer register. */
5284+#define EH_RETURN_STACKADJ_REGNO 11
5285+#define EH_RETURN_STACKADJ_RTX \
5286+ gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
5287+
5288+/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
5289+ location used to store the address the processor should jump to
5290+ catch exception. This is usually a registers that is available from
5291+ end of the function's body to the end of the epilogue. Thus, this
5292+ cannot be a register used as a temporary by the epilogue.
5293+
5294+ This must be an address register. */
5295+#define EH_RETURN_HANDLER_REGNO 18
5296+#define EH_RETURN_HANDLER_RTX \
5297+ gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
5298+
5299+/* #define DWARF2_DEBUGGING_INFO */
5300+
5301+/* Define this macro if GNU CC should produce dwarf version 2-style
5302+ line numbers. This usually requires extending the assembler to
5303+ support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
5304+ assembler configuration header files. */
5305+/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
5306+
5307+
5308+/* An alias for a machine mode name. This is the machine mode that elements
5309+ of a jump-table have. */
5310+#define CASE_VECTOR_MODE Pmode
5311+
5312+/* Smallest number of different values for which it is best to use a
5313+ jump-table instead of a tree of conditional branches. For most Ubicom32
5314+ targets this is quite small, but for the v1 architecture implementations
5315+ we had very little data memory and so heavily prefer the tree approach
5316+ rather than the jump tables. */
5317+#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
5318+
5319+/* Register operations within the Ubicom32 architecture always operate on
5320+ the whole register word and not just the sub-bits required for the opcode
5321+ mode size. */
5322+#define WORD_REGISTER_OPERATIONS
5323+
5324+/* The maximum number of bytes that a single instruction can move quickly from
5325+ memory to memory. */
5326+#define MOVE_MAX 4
5327+
5328+/* A C expression that is nonzero if on this machine the number of bits
5329+ actually used for the count of a shift operation is equal to the number of
5330+ bits needed to represent the size of the object being shifted. When this
5331+ macro is non-zero, the compiler will assume that it is safe to omit a
5332+ sign-extend, zero-extend, and certain bitwise `and' instructions that
5333+ truncates the count of a shift operation. On machines that have
5334+ instructions that act on bitfields at variable positions, which may include
5335+ `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
5336+ deletion of truncations of the values that serve as arguments to bitfield
5337+ instructions.
5338+
5339+ If both types of instructions truncate the count (for shifts) and position
5340+ (for bitfield operations), or if no variable-position bitfield instructions
5341+ exist, you should define this macro.
5342+
5343+ However, on some machines, such as the 80386 and the 680x0, truncation only
5344+ applies to shift operations and not the (real or pretended) bitfield
5345+ operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
5346+ Instead, add patterns to the `md' file that include the implied truncation
5347+ of the shift instructions.
5348+
5349+ You need not define this macro if it would always have the value of zero. */
5350+#define SHIFT_COUNT_TRUNCATED 1
5351+
5352+/* A C expression which is nonzero if on this machine it is safe to "convert"
5353+ an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
5354+ than INPREC) by merely operating on it as if it had only OUTPREC bits.
5355+
5356+ On many machines, this expression can be 1.
5357+
5358+ When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
5359+ which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
5360+ case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
5361+ things. */
5362+#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
5363+
5364+/* A C string constant that tells the GNU CC driver program options to pass
5365+ to the assembler. It can also specify how to translate options you give
5366+ to GNU CC into options for GNU CC to pass to the assembler. See the
5367+ file `sun3.h' for an example of this.
5368+
5369+ Defined in svr4.h. */
5370+#undef ASM_SPEC
5371+#define ASM_SPEC \
5372+ "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
5373+
5374+#define LINK_SPEC "\
5375+%{h*} %{v:-V} \
5376+%{b} \
5377+%{mfdpic:-melf32ubicom32fdpic -z text} \
5378+%{static:-dn -Bstatic} \
5379+%{shared:-G -Bdynamic} \
5380+%{symbolic:-Bsymbolic} \
5381+%{G*} \
5382+%{YP,*} \
5383+%{Qy:} %{!Qn:-Qy}"
5384+
5385+#undef STARTFILE_SPEC
5386+#undef ENDFILE_SPEC
5387+
5388+/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
5389+
5390+#undef LIB_SPEC
5391+#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
5392+
5393+#undef HAVE_GAS_SHF_MERGE
5394+#define HAVE_GAS_SHF_MERGE 0
5395+
5396+#define HANDLE_SYSV_PRAGMA 1
5397+#undef HANDLE_PRAGMA_PACK
5398+
5399+typedef void (*ubicom32_func_ptr) (void);
5400+
5401+/* Define builtins for selected special-purpose instructions. */
5402+enum ubicom32_builtins
5403+{
5404+ UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
5405+ UBICOM32_BUILTIN_UBICOM32_SWAPB_4
5406+};
5407+
5408+extern rtx ubicom32_compare_op0;
5409+extern rtx ubicom32_compare_op1;
5410+
5411+#define TYPE_ASM_OP "\t.type\t"
5412+#define TYPE_OPERAND_FMT "@%s"
5413+
5414+#ifndef ASM_DECLARE_RESULT
5415+#define ASM_DECLARE_RESULT(FILE, RESULT)
5416+#endif
5417+
5418+/* These macros generate the special .type and .size directives which
5419+ are used to set the corresponding fields of the linker symbol table
5420+ entries in an ELF object file under SVR4. These macros also output
5421+ the starting labels for the relevant functions/objects. */
5422+
5423+/* Write the extra assembler code needed to declare a function properly.
5424+ Some svr4 assemblers need to also have something extra said about the
5425+ function's return value. We allow for that here. */
5426+
5427+#ifndef ASM_DECLARE_FUNCTION_NAME
5428+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
5429+ do \
5430+ { \
5431+ ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
5432+ ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
5433+ ASM_OUTPUT_LABEL (FILE, NAME); \
5434+ } \
5435+ while (0)
5436+#endif
5437--- /dev/null
5438+++ b/gcc/config/ubicom32/ubicom32.md
5439@@ -0,0 +1,3753 @@
5440+; GCC machine description for Ubicom32
5441+;
5442+; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
5443+; Foundation, Inc.
5444+; Contributed by Ubicom, Inc.
5445+;
5446+; This file is part of GCC.
5447+;
5448+; GCC is free software; you can redistribute it and/or modify
5449+; it under the terms of the GNU General Public License as published by
5450+; the Free Software Foundation; either version 3, or (at your option)
5451+; any later version.
5452+;
5453+; GCC is distributed in the hope that it will be useful,
5454+; but WITHOUT ANY WARRANTY; without even the implied warranty of
5455+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5456+; GNU General Public License for more details.
5457+;
5458+; You should have received a copy of the GNU General Public License
5459+; along with GCC; see the file COPYING3. If not see
5460+; <http://www.gnu.org/licenses/>.
5461+
5462+(define_constants
5463+ [(AUX_DATA_REGNO 15)
5464+ (LINK_REGNO 21)
5465+ (SP_REGNO 23)
5466+ (ACC0_HI_REGNO 24)
5467+ (ACC1_HI_REGNO 26)
5468+ (CC_REGNO 30)])
5469+
5470+(define_constants
5471+ [(UNSPEC_FDPIC_GOT 0)
5472+ (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
5473+
5474+(define_constants
5475+ [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
5476+
5477+;; Types of instructions (for scheduling purposes).
5478+
5479+(define_attr "type" "mul,addr,other"
5480+ (const_string "other"))
5481+
5482+; Define instruction scheduling characteristics. We can only issue
5483+; one instruction per clock so we don't need to define CPU units.
5484+;
5485+(define_automaton "ubicom32")
5486+
5487+(define_cpu_unit "i_pipeline" "ubicom32");
5488+
5489+; We have a 4 cycle hazard associated with address calculations which
5490+; seems rather tricky to avoid so we go with a defensive assumption
5491+; that almost anything can be used to generate addresses.
5492+;
5493+;(define_insn_reservation "ubicom32_other" 4
5494+; (eq_attr "type" "other")
5495+; "i_pipeline")
5496+
5497+; Some moves don't generate hazards.
5498+;
5499+;(define_insn_reservation "ubicom32_addr" 1
5500+; (eq_attr "type" "addr")
5501+; "i_pipeline")
5502+
5503+; We need 3 cycles between a multiply instruction and any use of the
5504+; matching accumulator register(s).
5505+;
5506+(define_insn_reservation "ubicom32_mul" 4
5507+ (eq_attr "type" "mul")
5508+ "i_pipeline")
5509+
5510+(define_attr "length" ""
5511+ (const_int 4))
5512+
5513+(include "predicates.md")
5514+(include "constraints.md")
5515+
5516+; 8-bit move with no change to the flags reg.
5517+;
5518+(define_insn "movqi"
5519+ [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
5520+ (match_operand:QI 1 "ubicom32_move_operand" "g"))]
5521+ ""
5522+ "move.1\\t%0, %1")
5523+
5524+; Combiner-generated 8-bit move with the zero flag set accordingly.
5525+;
5526+(define_insn "movqi_ccszn"
5527+ [(set (reg CC_REGNO)
5528+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
5529+ (const_int 0)))
5530+ (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
5531+ (match_dup 0))]
5532+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
5533+ "ext.1\\t%1, %0")
5534+
5535+; Combine isn't very good at merging some types of operations so we
5536+; have to make do with a peephole. It's not as effective but it's better
5537+; than doing nothing.
5538+;
5539+(define_peephole2
5540+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
5541+ (match_operand:QI 1 "nonimmediate_operand" ""))
5542+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5543+ (match_operator 3 "ubicom32_compare_operator"
5544+ [(match_dup 0)
5545+ (const_int 0)]))]
5546+ "(GET_MODE (operands[2]) == CCSZNmode
5547+ || GET_MODE (operands[2]) == CCSZmode)"
5548+ [(parallel
5549+ [(set (match_dup 2)
5550+ (match_op_dup 3
5551+ [(match_dup 1)
5552+ (const_int 0)]))
5553+ (set (match_dup 0)
5554+ (match_dup 1))])]
5555+ "")
5556+
5557+; Combine isn't very good at merging some types of operations so we
5558+; have to make do with a peephole. It's not as effective but it's better
5559+; than doing nothing.
5560+;
5561+(define_peephole2
5562+ [(set (match_operand:QI 0 "nonimmediate_operand" "")
5563+ (match_operand:QI 1 "nonimmediate_operand" ""))
5564+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5565+ (match_operator 3 "ubicom32_compare_operator"
5566+ [(match_dup 1)
5567+ (const_int 0)]))]
5568+ "(GET_MODE (operands[2]) == CCSZNmode
5569+ || GET_MODE (operands[2]) == CCSZmode)"
5570+ [(parallel
5571+ [(set (match_dup 2)
5572+ (match_op_dup 3
5573+ [(match_dup 1)
5574+ (const_int 0)]))
5575+ (set (match_dup 0)
5576+ (match_dup 1))])]
5577+ "")
5578+
5579+; 16-bit move with no change to the flags reg.
5580+;
5581+(define_insn "movhi"
5582+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5583+ (match_operand:HI 1 "ubicom32_move_operand" "g"))]
5584+ ""
5585+ "*
5586+ {
5587+ if (CONST_INT_P (operands[1]))
5588+ return \"movei\\t%0, %1\";
5589+
5590+ return \"move.2\\t%0, %1\";
5591+ }")
5592+
5593+; Combiner-generated 16-bit move with the zero flag set accordingly.
5594+;
5595+(define_insn "movhi_ccszn"
5596+ [(set (reg CC_REGNO)
5597+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
5598+ (const_int 0)))
5599+ (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
5600+ (match_dup 0))]
5601+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
5602+ "ext.2\\t%1, %0")
5603+
5604+; Combine isn't very good at merging some types of operations so we
5605+; have to make do with a peephole. It's not as effective but it's better
5606+; than doing nothing.
5607+;
5608+(define_peephole2
5609+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
5610+ (match_operand:HI 1 "nonimmediate_operand" ""))
5611+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5612+ (match_operator 3 "ubicom32_compare_operator"
5613+ [(match_dup 0)
5614+ (const_int 0)]))]
5615+ "(GET_MODE (operands[2]) == CCSZNmode
5616+ || GET_MODE (operands[2]) == CCSZmode)"
5617+ [(parallel
5618+ [(set (match_dup 2)
5619+ (match_op_dup 3
5620+ [(match_dup 1)
5621+ (const_int 0)]))
5622+ (set (match_dup 0)
5623+ (match_dup 1))])]
5624+ "")
5625+
5626+; Combine isn't very good at merging some types of operations so we
5627+; have to make do with a peephole. It's not as effective but it's better
5628+; than doing nothing.
5629+;
5630+(define_peephole2
5631+ [(set (match_operand:HI 0 "nonimmediate_operand" "")
5632+ (match_operand:HI 1 "nonimmediate_operand" ""))
5633+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
5634+ (match_operator 3 "ubicom32_compare_operator"
5635+ [(match_dup 1)
5636+ (const_int 0)]))]
5637+ "(GET_MODE (operands[2]) == CCSZNmode
5638+ || GET_MODE (operands[2]) == CCSZmode)"
5639+ [(parallel
5640+ [(set (match_dup 2)
5641+ (match_op_dup 3
5642+ [(match_dup 1)
5643+ (const_int 0)]))
5644+ (set (match_dup 0)
5645+ (match_dup 1))])]
5646+ "")
5647+
5648+; 32-bit move with no change to the flags reg.
5649+;
5650+(define_expand "movsi"
5651+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5652+ (match_operand:SI 1 "general_operand" ""))]
5653+ ""
5654+ "{
5655+ /* Convert any complexities in operand 1 into something that can just
5656+ fall into the default expander code. */
5657+ ubicom32_expand_movsi (operands);
5658+ }")
5659+
5660+(define_insn "movsi_high"
5661+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
5662+ (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
5663+ ""
5664+ "moveai\\t%0, #%%hi(%E1)")
5665+
5666+(define_insn "movsi_lo_sum"
5667+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5668+ (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
5669+ (match_operand:SI 2 "immediate_operand" "s")))]
5670+ ""
5671+ "lea.1\\t%0, %%lo(%E2)(%1)")
5672+
5673+(define_insn "movsi_internal"
5674+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5675+ (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
5676+ ""
5677+ "*
5678+ {
5679+ if (CONST_INT_P (operands[1]))
5680+ {
5681+ ubicom32_emit_move_const_int (operands[0], operands[1]);
5682+ return \"\";
5683+ }
5684+
5685+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
5686+ {
5687+ HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
5688+
5689+ ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
5690+ return \"\";
5691+ }
5692+
5693+ if (ubicom32_address_register_operand (operands[0], VOIDmode)
5694+ && register_operand (operands[1], VOIDmode))
5695+ {
5696+ if (ubicom32_address_register_operand (operands[1], VOIDmode))
5697+ return \"lea.1\\t%0, 0(%1)\";
5698+
5699+ /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
5700+ if (ubicom32_v4)
5701+ return \"movea\\t%0, %1\";
5702+
5703+ return \"move.4\\t%0, %1\";
5704+ }
5705+
5706+ return \"move.4\\t%0, %1\";
5707+ }")
5708+
5709+; If we're not dependent on the state of the condition codes we can construct
5710+; constants of value 2^n by using a bset.
5711+;
5712+(define_peephole2
5713+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5714+ (match_operand:SI 1 "const_int_operand" ""))]
5715+ "(exact_log2 (INTVAL (operands[1])) > 14
5716+ && peep2_regno_dead_p (0, CC_REGNO))"
5717+ [(parallel
5718+ [(set (match_dup 0)
5719+ (ior:SI (const_int 0)
5720+ (match_dup 1)))
5721+ (clobber (reg:CC CC_REGNO))])]
5722+ "")
5723+
5724+; If we're not dependent on the state of the condition codes we can construct
5725+; constants of value ~(2^n) by using a bclr.
5726+;
5727+(define_peephole2
5728+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5729+ (match_operand:SI 1 "const_int_operand" ""))]
5730+ "(exact_log2 (~INTVAL (operands[1])) > 14
5731+ && peep2_regno_dead_p (0, CC_REGNO))"
5732+ [(parallel
5733+ [(set (match_dup 0)
5734+ (and:SI (const_int -1)
5735+ (match_dup 1)))
5736+ (clobber (reg:CC CC_REGNO))])]
5737+ "")
5738+
5739+; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
5740+; we can use swapb.4!
5741+;
5742+(define_peephole2
5743+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
5744+ (match_operand:SI 1 "const_int_operand" ""))]
5745+ "(ubicom32_v4
5746+ && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
5747+ && (INTVAL (operands[1]) & 0xffffffff) != 0
5748+ && ((INTVAL (operands[1]) & 0x80ffffff) == 0
5749+ || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
5750+ [(set (match_dup 0)
5751+ (bswap:SI (match_dup 2)))]
5752+ "{
5753+ operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
5754+ }")
5755+
5756+; If this is a write of a constant to memory look to see if we can usefully
5757+; transform this into 2 smaller writes.
5758+;
5759+(define_peephole2
5760+ [(set (match_operand:SI 0 "memory_operand" "")
5761+ (match_operand:SI 1 "const_int_operand" ""))]
5762+ "! satisfies_constraint_I (operands[1])
5763+ && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
5764+ [(set (match_dup 4) (match_dup 2))
5765+ (set (match_dup 5) (match_dup 3))]
5766+ "{
5767+ rtx low_hword_addr;
5768+
5769+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5770+ operands[3] = gen_lowpart (HImode, operands[1]);
5771+
5772+ operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
5773+ MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
5774+
5775+ low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
5776+ operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
5777+ MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
5778+ }")
5779+
5780+; If we're writing memory and we've not found a better way to do this then
5781+; try loading into a D register and then copying to memory. This will
5782+; perform the fewest possible memory read/writes.
5783+;
5784+(define_peephole2
5785+ [(match_scratch:SI 2 "d")
5786+ (set (match_operand:SI 0 "memory_operand" "")
5787+ (match_operand:SI 1 "const_int_operand" ""))]
5788+ "! satisfies_constraint_I (operands[1])"
5789+ [(set (match_dup 2) (match_dup 1))
5790+ (set (match_dup 0) (match_dup 2))]
5791+ "")
5792+
5793+; If we're not dependent on the state of the condition codes we can construct
5794+; constants of value (2^n - 1) by using an lsr.4.
5795+;
5796+(define_peephole2
5797+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5798+ (match_operand:SI 1 "const_int_operand" ""))]
5799+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5800+ && peep2_regno_dead_p (0, CC_REGNO))"
5801+ [(parallel
5802+ [(set (match_dup 0)
5803+ (lshiftrt:SI (const_int -1)
5804+ (match_dup 2)))
5805+ (clobber (reg:CC CC_REGNO))])]
5806+ "{
5807+ operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5808+ }")
5809+
5810+; If we're not dependent on the state of the condition codes we can construct
5811+; constants of value (2^n - 1) by using an lsr.4.
5812+;
5813+(define_peephole2
5814+ [(match_scratch:SI 2 "d")
5815+ (set (match_operand:SI 0 "nonimmediate_operand" "")
5816+ (match_operand:SI 1 "const_int_operand" ""))]
5817+ "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5818+ && peep2_regno_dead_p (0, CC_REGNO))"
5819+ [(parallel
5820+ [(set (match_dup 2)
5821+ (lshiftrt:SI (const_int -1)
5822+ (match_dup 3)))
5823+ (clobber (reg:CC CC_REGNO))])
5824+ (set (match_dup 0)
5825+ (match_dup 2))]
5826+ "{
5827+ operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5828+ }")
5829+
5830+; If we're not dependent on the state of the condition codes we can construct
5831+; some other constants by using an lsl.4 to shift 7 bits left by some
5832+; constant.
5833+;
5834+(define_peephole2
5835+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5836+ (match_operand:SI 1 "const_int_operand" ""))]
5837+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5838+ && peep2_regno_dead_p (0, CC_REGNO))"
5839+ [(parallel
5840+ [(set (match_dup 0)
5841+ (ashift:SI (match_dup 2)
5842+ (match_dup 3)))
5843+ (clobber (reg:CC CC_REGNO))])]
5844+ "{
5845+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5846+ operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
5847+ operands[3] = GEN_INT (shift);
5848+ }")
5849+
5850+; If we're not dependent on the state of the condition codes we can construct
5851+; some other constants by using an lsl.4 to shift 7 bits left by some
5852+; constant.
5853+;
5854+(define_peephole2
5855+ [(match_scratch:SI 2 "d")
5856+ (set (match_operand:SI 0 "nonimmediate_operand" "")
5857+ (match_operand:SI 1 "const_int_operand" ""))]
5858+ "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5859+ && peep2_regno_dead_p (0, CC_REGNO))"
5860+ [(parallel
5861+ [(set (match_dup 2)
5862+ (ashift:SI (match_dup 3)
5863+ (match_dup 4)))
5864+ (clobber (reg:CC CC_REGNO))])
5865+ (set (match_dup 0)
5866+ (match_dup 2))]
5867+ "{
5868+ int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5869+ operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
5870+ operands[4] = GEN_INT (shift);
5871+ }")
5872+
5873+; For some 16-bit unsigned constants that have bit 15 set we can use
5874+; swapb.2!
5875+;
5876+; Note that the movsi code emits the same sequence but by using a peephole2
5877+; we split the pattern early enough to allow instruction scheduling to
5878+; occur.
5879+;
5880+(define_peephole2
5881+ [(set (match_operand:SI 0 "register_operand" "")
5882+ (match_operand:SI 1 "const_int_operand" ""))]
5883+ "(ubicom32_v4
5884+ && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
5885+ [(set (match_dup 0)
5886+ (zero_extend:SI (bswap:HI (match_dup 2))))]
5887+ "{
5888+ HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
5889+ if (i >= 0x80)
5890+ i -= 0x100;
5891+ operands[2] = GEN_INT (i);
5892+ }")
5893+
5894+; In general for a 16-bit unsigned constant that has bit 15 set
5895+; then we need a movei/move.2 pair unless we can represent it
5896+; via just a move.2.
5897+;
5898+(define_peephole2
5899+ [(set (match_operand:SI 0 "register_operand" "")
5900+ (match_operand:SI 1 "const_int_operand" ""))]
5901+ "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
5902+ && (INTVAL (operands[1]) & 0xffff) < 0xff80"
5903+ [(set (match_dup 2)
5904+ (match_dup 1))
5905+ (set (match_dup 0)
5906+ (zero_extend:SI (match_dup 2)))]
5907+ "{
5908+ operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
5909+ }")
5910+
5911+; If we're not dependent on the state of the condition codes we can construct
5912+; 32-bit constants that have bits 16 through 31 set to arbitrary values
5913+; and have bits 0 through 15 set to something representable as a default
5914+; source-1 immediate - we use movei/shmrg.2
5915+;
5916+(define_peephole2
5917+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5918+ (match_operand:SI 1 "const_int_operand" ""))]
5919+ "(((INTVAL (operands[1]) >= 0x8000
5920+ && INTVAL (operands[1]) < 0xff80)
5921+ || INTVAL (operands[1]) >= 0x10000
5922+ || INTVAL (operands[1]) < -0x8000)
5923+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5924+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
5925+ && peep2_regno_dead_p (0, CC_REGNO))"
5926+ [(set (match_dup 0)
5927+ (match_dup 2))
5928+ (parallel
5929+ [(set (match_dup 0)
5930+ (ior:SI
5931+ (ashift:SI (match_dup 0)
5932+ (const_int 16))
5933+ (zero_extend:SI
5934+ (match_dup 3))))
5935+ (clobber (reg:CC CC_REGNO))])]
5936+ "{
5937+ operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5938+ operands[3] = gen_lowpart (HImode, operands[1]);
5939+ }")
5940+
5941+; Exactly the same as the peephole2 preceding except that this targets a
5942+; general register instead of D register. Hopefully the later optimization
5943+; passes will notice that the value ended up in a D register first here
5944+; and eliminate away the other register!
5945+;
5946+(define_peephole2
5947+ [(match_scratch:SI 2 "d")
5948+ (set (match_operand:SI 0 "register_operand" "")
5949+ (match_operand:SI 1 "const_int_operand" ""))]
5950+ "(((INTVAL (operands[1]) >= 0x8000
5951+ && INTVAL (operands[1]) < 0xff80)
5952+ || INTVAL (operands[1]) >= 0x10000
5953+ || INTVAL (operands[1]) < -0x8000)
5954+ && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5955+ || (INTVAL (operands[1]) & 0xffff) < 0x80)
5956+ && peep2_regno_dead_p (0, CC_REGNO))"
5957+ [(set (match_dup 2)
5958+ (match_dup 3))
5959+ (parallel
5960+ [(set (match_dup 2)
5961+ (ior:SI
5962+ (ashift:SI (match_dup 2)
5963+ (const_int 16))
5964+ (zero_extend:SI
5965+ (match_dup 4))))
5966+ (clobber (reg:CC CC_REGNO))])
5967+ (set (match_dup 0)
5968+ (match_dup 2))]
5969+ "{
5970+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
5971+ operands[4] = gen_lowpart (HImode, operands[1]);
5972+ }")
5973+
5974+; If we have a load of a large integer constant which does not have bit 31
5975+; set and we have a spare A reg then construct it with a moveai/lea.1 pair
5976+; instead. This avoids constructing it in 3 instructions on the stack.
5977+;
5978+; Note that we have to be careful not to match anything that matches
5979+; something we can do in a single instruction! There aren't many such
5980+; constants but there are some.
5981+;
5982+(define_peephole2
5983+ [(match_scratch:SI 2 "a")
5984+ (set (match_operand:SI 0 "register_operand" "")
5985+ (match_operand:SI 1 "const_int_operand" ""))]
5986+ "(! (INTVAL (operands[1]) & 0x80000000)
5987+ && ((INTVAL (operands[1]) >= 0x8000
5988+ && INTVAL (operands[1]) < 0xff80)
5989+ || INTVAL (operands[1]) >= 0x10000))"
5990+ [(set (match_dup 2)
5991+ (match_dup 3))
5992+ (set (match_dup 0)
5993+ (plus:SI (match_dup 2)
5994+ (match_dup 4)))]
5995+ "{
5996+ HOST_WIDE_INT i = INTVAL (operands[1]);
5997+ operands[3] = GEN_INT (i & 0xffffff80);
5998+ operands[4] = GEN_INT (i & 0x7f);
5999+ }")
6000+
6001+; If we're not dependent on the state of the condition codes we can construct
6002+; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
6003+;
6004+(define_peephole2
6005+ [(match_scratch:HI 2 "d")
6006+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
6007+ (match_operand:SI 1 "const_int_operand" ""))
6008+ (match_dup 2)]
6009+ "(INTVAL (operands[1]) & 0x80000000
6010+ && INTVAL (operands[1]) < -0x8000
6011+ && peep2_regno_dead_p (0, CC_REGNO))"
6012+ [(set (match_dup 0)
6013+ (match_dup 3))
6014+ (set (match_dup 2)
6015+ (match_dup 4))
6016+ (parallel
6017+ [(set (match_dup 0)
6018+ (ior:SI
6019+ (ashift:SI (match_dup 0)
6020+ (const_int 16))
6021+ (zero_extend:SI
6022+ (match_dup 2))))
6023+ (clobber (reg:CC CC_REGNO))])]
6024+ "{
6025+ operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
6026+ operands[4] = gen_lowpart (HImode, operands[1]);
6027+ }")
6028+
6029+; Exactly the same as the peephole2 preceding except that this targets a
6030+; general register instead of D register. Hopefully the later optimization
6031+; passes will notice that the value ended up in a D register first here
6032+; and eliminate away the other register!
6033+;
6034+(define_peephole2
6035+ [(match_scratch:SI 2 "d")
6036+ (match_scratch:HI 3 "d")
6037+ (set (match_operand:SI 0 "register_operand" "")
6038+ (match_operand:SI 1 "const_int_operand" ""))
6039+ (match_dup 3)]
6040+ "(INTVAL (operands[1]) & 0x80000000
6041+ && INTVAL (operands[1]) < -0x8000
6042+ && peep2_regno_dead_p (0, CC_REGNO))"
6043+ [(set (match_dup 2)
6044+ (match_dup 4))
6045+ (set (match_dup 3)
6046+ (match_dup 5))
6047+ (parallel
6048+ [(set (match_dup 2)
6049+ (ior:SI
6050+ (ashift:SI (match_dup 2)
6051+ (const_int 16))
6052+ (zero_extend:SI
6053+ (match_dup 3))))
6054+ (clobber (reg:CC CC_REGNO))])
6055+ (set (match_dup 0)
6056+ (match_dup 2))]
6057+ "{
6058+ operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
6059+ operands[5] = gen_lowpart (HImode, operands[1]);
6060+ }")
6061+
6062+(define_insn "movsi_fdpic_got_offset"
6063+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6064+ (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
6065+ ""
6066+ "movei\\t%0, %1")
6067+
6068+; The explicit MEM inside the UNSPEC prevents the compiler from moving
6069+; the load before a branch after a NULL test, or before a store that
6070+; initializes a function descriptor.
6071+
6072+(define_insn_and_split "load_fdpic_funcdesc"
6073+ [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
6074+ (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
6075+ UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
6076+ ""
6077+ "#"
6078+ "reload_completed"
6079+ [(set (match_dup 0)
6080+ (mem:SI (match_dup 1)))])
6081+
6082+; Combiner-generated 32-bit move with the zero flag set accordingly.
6083+;
6084+(define_insn "movsi_ccwzn"
6085+ [(set (reg CC_REGNO)
6086+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
6087+ (const_int 0)))
6088+ (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
6089+ (match_dup 0))]
6090+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6091+ "@
6092+ lsl.4\\t%1, %0, #0
6093+ add.4\\t%1, #0, %0")
6094+
6095+; Combiner-generated 32-bit move with all flags set accordingly.
6096+;
6097+(define_insn "movsi_ccw"
6098+ [(set (reg CC_REGNO)
6099+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6100+ (const_int 0)))
6101+ (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
6102+ (match_dup 0))]
6103+ "ubicom32_match_cc_mode(insn, CCWmode)"
6104+ "add.4\\t%1, #0, %0")
6105+
6106+; Combine isn't very good at merging some types of operations so we
6107+; have to make do with a peephole. It's not as effective but it's better
6108+; than doing nothing.
6109+;
6110+(define_peephole2
6111+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
6112+ (match_operand:SI 1 "nonimmediate_operand" ""))
6113+ (parallel
6114+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6115+ (match_operator 3 "ubicom32_compare_operator"
6116+ [(match_dup 0)
6117+ (const_int 0)]))
6118+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6119+ "(GET_MODE (operands[2]) == CCWZNmode
6120+ || GET_MODE (operands[2]) == CCWZmode)"
6121+ [(parallel
6122+ [(set (match_dup 2)
6123+ (match_op_dup 3
6124+ [(match_dup 1)
6125+ (const_int 0)]))
6126+ (set (match_dup 0)
6127+ (match_dup 1))])]
6128+ "")
6129+
6130+; Combine isn't very good at merging some types of operations so we
6131+; have to make do with a peephole. It's not as effective but it's better
6132+; than doing nothing.
6133+;
6134+(define_peephole2
6135+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
6136+ (match_operand:SI 1 "ubicom32_data_register_operand" ""))
6137+ (parallel
6138+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6139+ (match_operator 3 "ubicom32_compare_operator"
6140+ [(match_dup 1)
6141+ (const_int 0)]))
6142+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6143+ "(GET_MODE (operands[2]) == CCWZNmode
6144+ || GET_MODE (operands[2]) == CCWZmode)"
6145+ [(parallel
6146+ [(set (match_dup 2)
6147+ (match_op_dup 3
6148+ [(match_dup 1)
6149+ (const_int 0)]))
6150+ (set (match_dup 0)
6151+ (match_dup 1))])]
6152+ "")
6153+
6154+; Combine isn't very good at merging some types of operations so we
6155+; have to make do with a peephole. It's not as effective but it's better
6156+; than doing nothing.
6157+;
6158+(define_peephole2
6159+ [(set (match_operand:SI 0 "register_operand" "")
6160+ (match_operand:SI 1 "nonimmediate_operand" ""))
6161+ (parallel
6162+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6163+ (match_operator 3 "ubicom32_compare_operator"
6164+ [(match_dup 0)
6165+ (const_int 0)]))
6166+ (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
6167+ (match_dup 0))])]
6168+ "(peep2_reg_dead_p (2, operands[0])
6169+ && (GET_MODE (operands[2]) == CCWZNmode
6170+ || GET_MODE (operands[2]) == CCWZmode))"
6171+ [(parallel
6172+ [(set (match_dup 2)
6173+ (match_op_dup 3
6174+ [(match_dup 1)
6175+ (const_int 0)]))
6176+ (set (match_dup 4)
6177+ (match_dup 1))])]
6178+ "")
6179+
6180+; Register renaming may make a general reg into a D reg in which case
6181+; we may be able to simplify a compare.
6182+;
6183+(define_peephole2
6184+ [(set (match_operand:SI 0 "register_operand" "")
6185+ (match_operand:SI 1 "nonimmediate_operand" ""))
6186+ (parallel
6187+ [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6188+ (match_operator 3 "ubicom32_compare_operator"
6189+ [(match_dup 0)
6190+ (const_int 0)]))
6191+ (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6192+ "(peep2_reg_dead_p (2, operands[0])
6193+ && (GET_MODE (operands[2]) == CCWZNmode
6194+ || GET_MODE (operands[2]) == CCWZmode))"
6195+ [(parallel
6196+ [(set (match_dup 2)
6197+ (match_op_dup 3
6198+ [(match_dup 1)
6199+ (const_int 0)]))
6200+ (clobber (match_dup 4))])]
6201+ "")
6202+
6203+(define_insn_and_split "movdi"
6204+ [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6205+ (match_operand:DI 1 "general_operand" "rmi,ri"))]
6206+ ""
6207+ "#"
6208+ "reload_completed"
6209+ [(set (match_dup 2) (match_dup 3))
6210+ (set (match_dup 4) (match_dup 5))]
6211+ "{
6212+ rtx dest_low;
6213+ rtx src_low;
6214+
6215+ dest_low = gen_lowpart (SImode, operands[0]);
6216+ src_low = gen_lowpart (SImode, operands[1]);
6217+
6218+ if (REG_P (operands[0])
6219+ && REG_P (operands[1])
6220+ && REGNO (operands[0]) < REGNO (operands[1]))
6221+ {
6222+ operands[2] = gen_highpart (SImode, operands[0]);
6223+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6224+ operands[4] = dest_low;
6225+ operands[5] = src_low;
6226+ }
6227+ else if (reg_mentioned_p (dest_low, src_low))
6228+ {
6229+ operands[2] = gen_highpart (SImode, operands[0]);
6230+ operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6231+ operands[4] = dest_low;
6232+ operands[5] = src_low;
6233+ }
6234+ else
6235+ {
6236+ operands[2] = dest_low;
6237+ operands[3] = src_low;
6238+ operands[4] = gen_highpart (SImode, operands[0]);
6239+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6240+ }
6241+ }"
6242+ [(set_attr "length" "8")])
6243+
6244+; Combiner-generated 64-bit move with all flags set accordingly.
6245+;
6246+(define_insn "movdi_ccwzn"
6247+ [(set (reg CC_REGNO)
6248+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6249+ (const_int 0)))
6250+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6251+ (match_dup 0))
6252+ (clobber (match_scratch:SI 2 "=X, d, d"))]
6253+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6254+ "*
6255+ {
6256+ operands[3] = gen_lowpart (SImode, operands[0]);
6257+ operands[4] = gen_lowpart (SImode, operands[1]);
6258+ operands[5] = gen_highpart (SImode, operands[0]);
6259+ operands[6] = gen_highpart (SImode, operands[1]);
6260+
6261+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
6262+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6263+
6264+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6265+ }"
6266+ [(set_attr "length" "8")])
6267+
6268+(define_insn "movdi_ccw"
6269+ [(set (reg CC_REGNO)
6270+ (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6271+ (const_int 0)))
6272+ (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6273+ (match_dup 0))
6274+ (clobber (match_scratch:SI 2 "=X, d, d"))]
6275+ "ubicom32_match_cc_mode(insn, CCWmode)"
6276+ "*
6277+ {
6278+ operands[3] = gen_lowpart (SImode, operands[0]);
6279+ operands[4] = gen_lowpart (SImode, operands[1]);
6280+ operands[5] = gen_highpart (SImode, operands[0]);
6281+ operands[6] = gen_highpart (SImode, operands[1]);
6282+
6283+ if (ubicom32_data_register_operand (operands[0], VOIDmode))
6284+ return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6285+
6286+ return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6287+ }"
6288+ [(set_attr "length" "8")])
6289+
6290+(define_insn "movsf"
6291+ [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
6292+ (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
6293+ ""
6294+ "*
6295+ {
6296+ if (GET_CODE (operands[1]) == CONST_DOUBLE)
6297+ {
6298+ HOST_WIDE_INT val;
6299+ REAL_VALUE_TYPE rv;
6300+
6301+ REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6302+ REAL_VALUE_TO_TARGET_SINGLE (rv, val);
6303+
6304+ ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
6305+ return \"\";
6306+ }
6307+
6308+ return \"move.4\\t%0, %1\";
6309+ }")
6310+
6311+(define_insn "zero_extendqihi2"
6312+ [(set (match_operand:HI 0 "register_operand" "=r")
6313+ (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6314+ ""
6315+ "move.1\\t%0, %1")
6316+
6317+(define_insn "zero_extendqisi2"
6318+ [(set (match_operand:SI 0 "register_operand" "=r")
6319+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6320+ ""
6321+ "move.1\\t%0, %1")
6322+
6323+(define_insn "zero_extendqisi2_ccwz_1"
6324+ [(set (reg CC_REGNO)
6325+ (compare
6326+ (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
6327+ (const_int 0)))
6328+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6329+ (zero_extend:SI (match_dup 1)))]
6330+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6331+ "shmrg.1\\t%0, %1, #0")
6332+
6333+(define_insn "zero_extendhisi2"
6334+ [(set (match_operand:SI 0 "register_operand" "=r")
6335+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6336+ ""
6337+ "move.2\\t%0, %1")
6338+
6339+(define_insn "zero_extendhisi2_ccwz_1"
6340+ [(set (reg CC_REGNO)
6341+ (compare
6342+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
6343+ (const_int 0)))
6344+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6345+ (zero_extend:SI (match_dup 1)))]
6346+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6347+ "shmrg.2\\t%0, %1, #0")
6348+
6349+(define_insn_and_split "zero_extendqidi2"
6350+ [(set (match_operand:DI 0 "register_operand" "=r")
6351+ (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6352+ ""
6353+ "#"
6354+ "reload_completed"
6355+ [(set (match_dup 2)
6356+ (zero_extend:SI (match_dup 1)))
6357+ (set (match_dup 3)
6358+ (const_int 0))]
6359+ "{
6360+ operands[2] = gen_lowpart (SImode, operands[0]);
6361+ operands[3] = gen_highpart (SImode, operands[0]);
6362+ }"
6363+ [(set_attr "length" "8")])
6364+
6365+(define_insn_and_split "zero_extendhidi2"
6366+ [(set (match_operand:DI 0 "register_operand" "=r")
6367+ (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6368+ ""
6369+ "#"
6370+ "reload_completed"
6371+ [(set (match_dup 2)
6372+ (zero_extend:SI (match_dup 1)))
6373+ (set (match_dup 3)
6374+ (const_int 0))]
6375+ "{
6376+ operands[2] = gen_lowpart (SImode, operands[0]);
6377+ operands[3] = gen_highpart (SImode, operands[0]);
6378+ }"
6379+ [(set_attr "length" "8")])
6380+
6381+(define_insn_and_split "zero_extendsidi2"
6382+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
6383+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6384+ ""
6385+ "#"
6386+ "reload_completed"
6387+ [(set (match_dup 2)
6388+ (match_dup 1))
6389+ (set (match_dup 3)
6390+ (const_int 0))]
6391+ "{
6392+ operands[2] = gen_lowpart (SImode, operands[0]);
6393+ operands[3] = gen_highpart (SImode, operands[0]);
6394+ }"
6395+ [(set_attr "length" "8")])
6396+
6397+(define_insn "extendqihi2"
6398+ [(set (match_operand:HI 0 "register_operand" "=r")
6399+ (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6400+ (clobber (reg:CC CC_REGNO))]
6401+ ""
6402+ "ext.1\\t%0, %1")
6403+
6404+(define_insn "extendqisi2"
6405+ [(set (match_operand:SI 0 "register_operand" "=r")
6406+ (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6407+ (clobber (reg:CC CC_REGNO))]
6408+ ""
6409+ "ext.1\\t%0, %1")
6410+
6411+(define_insn "extendhisi2"
6412+ [(set (match_operand:SI 0 "register_operand" "=r")
6413+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
6414+ (clobber (reg:CC CC_REGNO))]
6415+ ""
6416+ "ext.2\\t%0, %1")
6417+
6418+(define_insn_and_split "extendsidi2"
6419+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
6420+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
6421+ (clobber (reg:CC CC_REGNO))]
6422+ ""
6423+ "#"
6424+ "reload_completed"
6425+ [(set (match_dup 2)
6426+ (match_dup 1))
6427+ (parallel
6428+ [(set (match_dup 3)
6429+ (ashiftrt:SI (match_dup 2)
6430+ (const_int 31)))
6431+ (clobber (reg:CC CC_REGNO))])]
6432+ "{
6433+ operands[2] = gen_lowpart (SImode, operands[0]);
6434+ operands[3] = gen_highpart (SImode, operands[0]);
6435+ }"
6436+ [(set_attr "length" "8")])
6437+
6438+(define_insn "bswaphi"
6439+ [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6440+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6441+ "(ubicom32_v4)"
6442+ "swapb.2\\t%0, %1");
6443+
6444+(define_insn "bswaphisi"
6445+ [(set (match_operand:SI 0 "register_operand" "=r")
6446+ (zero_extend:SI
6447+ (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
6448+ "(ubicom32_v4)"
6449+ "swapb.2\\t%0, %1");
6450+
6451+(define_insn "bswapsi"
6452+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6453+ (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
6454+ "(ubicom32_v4)"
6455+ "swapb.4\\t%0, %1");
6456+
6457+(define_insn "tstqi_ext1"
6458+ [(set (reg CC_REGNO)
6459+ (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
6460+ (const_int 0)))]
6461+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6462+ "ext.1\\t#0, %0")
6463+
6464+(define_expand "cmpqi"
6465+ [(set (reg CC_REGNO)
6466+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
6467+ (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
6468+ "(ubicom32_v4)"
6469+ "{
6470+ ubicom32_compare_op0 = operands[0];
6471+ ubicom32_compare_op1 = operands[1];
6472+ DONE;
6473+ }")
6474+
6475+(define_insn "sub1_ccs"
6476+ [(set (reg CC_REGNO)
6477+ (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
6478+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6479+ "(ubicom32_v4)"
6480+ "sub.1\\t#0, %0, %1")
6481+
6482+; If we're testing for equality we don't have to worry about reversing conditions.
6483+;
6484+(define_insn "sub1_ccsz_1"
6485+ [(set (reg:CCSZ CC_REGNO)
6486+ (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
6487+ (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6488+ "(ubicom32_v4)"
6489+ "sub.1\\t#0, %0, %1")
6490+
6491+(define_insn "sub1_ccsz_2"
6492+ [(set (reg:CCSZ CC_REGNO)
6493+ (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
6494+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
6495+ "(ubicom32_v4)"
6496+ "sub.1\\t#0, %1, %0")
6497+
6498+; When the combiner runs it doesn't have any insight into whether or not an argument
6499+; to a compare is spilled to the stack and therefore can't swap the comparison in
6500+; an attempt to use sub.1 more effectively. We peephole this case here.
6501+;
6502+(define_peephole2
6503+ [(set (match_operand:QI 0 "register_operand" "")
6504+ (match_operand:QI 1 "ubicom32_arith_operand" ""))
6505+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6506+ (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
6507+ (match_dup 0)))
6508+ (set (pc)
6509+ (if_then_else (match_operator 4 "comparison_operator"
6510+ [(match_dup 2)
6511+ (const_int 0)])
6512+ (label_ref (match_operand 5 "" ""))
6513+ (pc)))]
6514+ "(peep2_reg_dead_p (2, operands[0])
6515+ && peep2_regno_dead_p (3, CC_REGNO))"
6516+ [(set (match_dup 2)
6517+ (compare (match_dup 1)
6518+ (match_dup 3)))
6519+ (set (pc)
6520+ (if_then_else (match_op_dup 6
6521+ [(match_dup 2)
6522+ (const_int 0)])
6523+ (label_ref (match_dup 5))
6524+ (pc)))]
6525+ "{
6526+ rtx cc_reg;
6527+
6528+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6529+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6530+ GET_MODE (operands[4]),
6531+ cc_reg,
6532+ const0_rtx);
6533+ }")
6534+
6535+(define_insn "tsthi_ext2"
6536+ [(set (reg CC_REGNO)
6537+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6538+ (const_int 0)))]
6539+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6540+ "ext.2\\t#0, %0")
6541+
6542+(define_expand "cmphi"
6543+ [(set (reg CC_REGNO)
6544+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
6545+ (match_operand:HI 1 "ubicom32_compare_operand" "")))]
6546+ ""
6547+ "{
6548+ do
6549+ {
6550+ /* Is this a cmpi? */
6551+ if (CONST_INT_P (operands[1]))
6552+ break;
6553+
6554+ /* Must be a sub.2 - if necessary copy an operand into a reg. */
6555+ if (! ubicom32_data_register_operand (operands[1], HImode))
6556+ operands[1] = copy_to_mode_reg (HImode, operands[1]);
6557+ }
6558+ while (0);
6559+
6560+ ubicom32_compare_op0 = operands[0];
6561+ ubicom32_compare_op1 = operands[1];
6562+ DONE;
6563+ }")
6564+
6565+(define_insn "cmpi"
6566+ [(set (reg CC_REGNO)
6567+ (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6568+ (match_operand 1 "const_int_operand" "N")))]
6569+ ""
6570+ "cmpi\\t%0, %1")
6571+
6572+(define_insn "sub2_ccs"
6573+ [(set (reg CC_REGNO)
6574+ (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
6575+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6576+ ""
6577+ "sub.2\\t#0, %0, %1")
6578+
6579+; If we're testing for equality we don't have to worry about reversing conditions.
6580+;
6581+(define_insn "sub2_ccsz_1"
6582+ [(set (reg:CCSZ CC_REGNO)
6583+ (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
6584+ (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6585+ ""
6586+ "sub.2\\t#0, %0, %1")
6587+
6588+(define_insn "sub2_ccsz_2"
6589+ [(set (reg:CCSZ CC_REGNO)
6590+ (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
6591+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6592+ ""
6593+ "sub.2\\t#0, %1, %0")
6594+
6595+; When the combiner runs it doesn't have any insight into whether or not an argument
6596+; to a compare is spilled to the stack and therefore can't swap the comparison in
6597+; an attempt to use sub.2 more effectively. We peephole this case here.
6598+;
6599+(define_peephole2
6600+ [(set (match_operand:HI 0 "register_operand" "")
6601+ (match_operand:HI 1 "ubicom32_arith_operand" ""))
6602+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6603+ (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
6604+ (match_dup 0)))
6605+ (set (pc)
6606+ (if_then_else (match_operator 4 "comparison_operator"
6607+ [(match_dup 2)
6608+ (const_int 0)])
6609+ (label_ref (match_operand 5 "" ""))
6610+ (pc)))]
6611+ "(peep2_reg_dead_p (2, operands[0])
6612+ && peep2_regno_dead_p (3, CC_REGNO))"
6613+ [(set (match_dup 2)
6614+ (compare (match_dup 1)
6615+ (match_dup 3)))
6616+ (set (pc)
6617+ (if_then_else (match_op_dup 6
6618+ [(match_dup 2)
6619+ (const_int 0)])
6620+ (label_ref (match_dup 5))
6621+ (pc)))]
6622+ "{
6623+ rtx cc_reg;
6624+
6625+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6626+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6627+ GET_MODE (operands[4]),
6628+ cc_reg,
6629+ const0_rtx);
6630+ }")
6631+
6632+(define_insn_and_split "tstsi_lsl4"
6633+ [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
6634+ (match_operator 1 "ubicom32_compare_operator"
6635+ [(match_operand:SI 2 "nonimmediate_operand" "rm")
6636+ (const_int 0)]))]
6637+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6638+ "#"
6639+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6640+ [(parallel
6641+ [(set (match_dup 0)
6642+ (match_op_dup 1
6643+ [(match_dup 2)
6644+ (const_int 0)]))
6645+ (clobber (match_dup 3))])]
6646+ "{
6647+ operands[3] = gen_reg_rtx (SImode);
6648+ }")
6649+
6650+(define_insn "tstsi_lsl4_d"
6651+ [(set (reg CC_REGNO)
6652+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6653+ (const_int 0)))
6654+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6655+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
6656+ "lsl.4\\t%1, %0, #0")
6657+
6658+; Comparison for equality with -1.
6659+;
6660+(define_insn "cmpsi_not4_ccwz"
6661+ [(set (reg CC_REGNO)
6662+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6663+ (const_int -1)))]
6664+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6665+ "not.4\\t#0, %0")
6666+
6667+(define_expand "cmpsi"
6668+ [(set (reg CC_REGNO)
6669+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
6670+ (match_operand:SI 1 "ubicom32_compare_operand" "")))]
6671+ ""
6672+ "{
6673+ do
6674+ {
6675+ /* Is this a cmpi? We can't take a memory address as cmpi takes
6676+ 16-bit operands. */
6677+ if (register_operand (operands[0], SImode)
6678+ && CONST_INT_P (operands[1])
6679+ && satisfies_constraint_N (operands[1]))
6680+ break;
6681+
6682+ /* Must be a sub.4 - if necessary copy an operand into a reg. */
6683+ if (! ubicom32_data_register_operand (operands[1], SImode))
6684+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
6685+ }
6686+ while (0);
6687+
6688+ ubicom32_compare_op0 = operands[0];
6689+ ubicom32_compare_op1 = operands[1];
6690+ DONE;
6691+ }")
6692+
6693+(define_insn "cmpsi_cmpi"
6694+ [(set (reg CC_REGNO)
6695+ (compare (match_operand:SI 0 "register_operand" "r")
6696+ (match_operand 1 "const_int_operand" "N")))]
6697+ "(satisfies_constraint_N (operands[1]))"
6698+ "cmpi\\t%0, %1")
6699+
6700+(define_insn "cmpsi_sub4"
6701+ [(set (reg CC_REGNO)
6702+ (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
6703+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6704+ ""
6705+ "sub.4\\t#0, %0, %1")
6706+
6707+; If we're testing for equality we don't have to worry about reversing conditions.
6708+;
6709+(define_insn "cmpsi_sub4_ccwz_1"
6710+ [(set (reg CC_REGNO)
6711+ (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6712+ (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6713+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6714+ "sub.4\\t#0, %0, %1")
6715+
6716+(define_insn "cmpsi_sub4_ccwz_2"
6717+ [(set (reg CC_REGNO)
6718+ (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6719+ (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6720+ "ubicom32_match_cc_mode(insn, CCWZmode)"
6721+ "sub.4\\t#0, %1, %0")
6722+
6723+; When the combiner runs it doesn't have any insight into whether or not an argument
6724+; to a compare is spilled to the stack and therefore can't swap the comparison in
6725+; an attempt to use sub.4 more effectively. We peephole this case here.
6726+;
6727+(define_peephole2
6728+ [(set (match_operand:SI 0 "register_operand" "")
6729+ (match_operand:SI 1 "ubicom32_arith_operand" ""))
6730+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6731+ (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
6732+ (match_dup 0)))
6733+ (set (pc)
6734+ (if_then_else (match_operator 4 "comparison_operator"
6735+ [(match_dup 2)
6736+ (const_int 0)])
6737+ (label_ref (match_operand 5 "" ""))
6738+ (pc)))]
6739+ "(peep2_reg_dead_p (2, operands[0])
6740+ && peep2_regno_dead_p (3, CC_REGNO))"
6741+ [(set (match_dup 2)
6742+ (compare (match_dup 1)
6743+ (match_dup 3)))
6744+ (set (pc)
6745+ (if_then_else (match_op_dup 6
6746+ [(match_dup 2)
6747+ (const_int 0)])
6748+ (label_ref (match_dup 5))
6749+ (pc)))]
6750+ "{
6751+ rtx cc_reg;
6752+
6753+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6754+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6755+ GET_MODE (operands[4]),
6756+ cc_reg,
6757+ const0_rtx);
6758+ }")
6759+
6760+(define_insn_and_split "tstdi_or4"
6761+ [(set (reg:CCWZ CC_REGNO)
6762+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6763+ (const_int 0)))]
6764+ ""
6765+ "#"
6766+ ""
6767+ [(parallel
6768+ [(set (reg:CCWZ CC_REGNO)
6769+ (compare:CCWZ (match_dup 0)
6770+ (const_int 0)))
6771+ (clobber (match_dup 1))])]
6772+ "{
6773+ operands[1] = gen_reg_rtx (SImode);
6774+ }")
6775+
6776+(define_insn "tstdi_or4_d"
6777+ [(set (reg:CCWZ CC_REGNO)
6778+ (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6779+ (const_int 0)))
6780+ (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6781+ ""
6782+ "*
6783+ {
6784+ operands[2] = gen_lowpart (SImode, operands[0]);
6785+ operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
6786+
6787+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
6788+ return \"or.4\\t#0, %2, %3\";
6789+
6790+ return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
6791+ }"
6792+ [(set_attr "length" "8")])
6793+
6794+(define_expand "cmpdi"
6795+ [(set (reg CC_REGNO)
6796+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
6797+ (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
6798+ ""
6799+ "{
6800+ ubicom32_compare_op0 = operands[0];
6801+ ubicom32_compare_op1 = operands[1];
6802+ DONE;
6803+ }")
6804+
6805+(define_insn "cmpdi_sub4subc"
6806+ [(set (reg CC_REGNO)
6807+ (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
6808+ (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
6809+ ""
6810+ "*
6811+ {
6812+ operands[2] = gen_lowpart (SImode, operands[0]);
6813+ operands[3] = gen_lowpart (SImode, operands[1]);
6814+ operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
6815+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6816+
6817+ return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
6818+ }"
6819+ [(set_attr "length" "8")])
6820+
6821+; When the combiner runs it doesn't have any insight into whether or not an argument
6822+; to a compare is spilled to the stack and therefore can't swap the comparison in
6823+; an attempt to use sub.4/subc more effectively. We peephole this case here.
6824+;
6825+(define_peephole2
6826+ [(set (match_operand:DI 0 "register_operand" "")
6827+ (match_operand:DI 1 "ubicom32_arith_operand" ""))
6828+ (set (match_operand 2 "ubicom32_cc_register_operand" "")
6829+ (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
6830+ (match_dup 0)))
6831+ (set (pc)
6832+ (if_then_else (match_operator 4 "comparison_operator"
6833+ [(match_dup 2)
6834+ (const_int 0)])
6835+ (label_ref (match_operand 5 "" ""))
6836+ (pc)))]
6837+ "(peep2_reg_dead_p (2, operands[0])
6838+ && peep2_regno_dead_p (3, CC_REGNO))"
6839+ [(set (match_dup 2)
6840+ (compare (match_dup 1)
6841+ (match_dup 3)))
6842+ (set (pc)
6843+ (if_then_else (match_op_dup 6
6844+ [(match_dup 2)
6845+ (const_int 0)])
6846+ (label_ref (match_dup 5))
6847+ (pc)))]
6848+ "{
6849+ rtx cc_reg;
6850+
6851+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6852+ operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6853+ GET_MODE (operands[4]),
6854+ cc_reg,
6855+ const0_rtx);
6856+ }")
6857+
6858+(define_insn "btst"
6859+ [(set (reg:CCWZ CC_REGNO)
6860+ (compare:CCWZ
6861+ (zero_extract:SI
6862+ (match_operand:SI 0 "nonimmediate_operand" "rm")
6863+ (const_int 1)
6864+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
6865+ (const_int 0)))]
6866+ ""
6867+ "btst\\t%0, %1")
6868+
6869+(define_insn "bfextu_ccwz_null"
6870+ [(set (reg:CCWZ CC_REGNO)
6871+ (compare:CCWZ
6872+ (zero_extract:SI
6873+ (match_operand:SI 0 "nonimmediate_operand" "rm")
6874+ (match_operand 1 "const_int_operand" "M")
6875+ (const_int 0))
6876+ (const_int 0)))
6877+ (clobber (match_scratch:SI 2 "=d"))]
6878+ ""
6879+ "bfextu\\t%2, %0, %1")
6880+
6881+(define_expand "addqi3"
6882+ [(parallel
6883+ [(set (match_operand:QI 0 "memory_operand" "")
6884+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6885+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
6886+ (clobber (reg:CC CC_REGNO))])]
6887+ "(ubicom32_v4)"
6888+ "{
6889+ if (!memory_operand (operands[0], QImode))
6890+ FAIL;
6891+
6892+ /* If we have a non-data reg for operand 1 then prefer that over
6893+ a CONST_INT in operand 2. */
6894+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6895+ && CONST_INT_P (operands[2]))
6896+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
6897+
6898+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6899+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
6900+ }")
6901+
6902+(define_insn "addqi3_add1"
6903+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
6904+ (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
6905+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
6906+ (clobber (reg:CC CC_REGNO))]
6907+ "(ubicom32_v4)"
6908+ "@
6909+ add.1\\t%0, %2, %1
6910+ add.1\\t%0, %1, %2")
6911+
6912+(define_insn "addqi3_add1_ccszn_null"
6913+ [(set (reg CC_REGNO)
6914+ (compare
6915+ (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
6916+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
6917+ "(ubicom32_v4
6918+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
6919+ "@
6920+ add.1\\t#0, %1, %0
6921+ add.1\\t#0, %0, %1")
6922+
6923+(define_expand "addhi3"
6924+ [(parallel
6925+ [(set (match_operand:HI 0 "memory_operand" "")
6926+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6927+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
6928+ (clobber (reg:CC CC_REGNO))])]
6929+ ""
6930+ "{
6931+ if (!memory_operand (operands[0], HImode))
6932+ FAIL;
6933+
6934+ /* If we have a non-data reg for operand 1 then prefer that over
6935+ a CONST_INT in operand 2. */
6936+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6937+ && CONST_INT_P (operands[2]))
6938+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
6939+
6940+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6941+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
6942+ }")
6943+
6944+(define_insn "addhi3_add2"
6945+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
6946+ (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
6947+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
6948+ (clobber (reg:CC CC_REGNO))]
6949+ ""
6950+ "@
6951+ add.2\\t%0, %2, %1
6952+ add.2\\t%0, %1, %2")
6953+
6954+(define_insn "addhi3_add2_ccszn_null"
6955+ [(set (reg CC_REGNO)
6956+ (compare
6957+ (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
6958+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
6959+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
6960+ "@
6961+ add.2\\t#0, %1, %0
6962+ add.2\\t#0, %0, %1")
6963+
6964+(define_expand "addsi3"
6965+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
6966+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6967+ (match_operand:SI 2 "ubicom32_move_operand" "")))]
6968+ ""
6969+ "{
6970+ ubicom32_expand_addsi3 (operands);
6971+ DONE;
6972+ }")
6973+
6974+; We start with an instruction pattern that can do all sorts of interesting
6975+; things but we split out any uses of lea or pdec instructions because
6976+; those instructions don't clobber the condition codes.
6977+;
6978+(define_insn_and_split "addsi3_1"
6979+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
6980+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
6981+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
6982+ (clobber (reg:CC CC_REGNO))]
6983+ ""
6984+ "@
6985+ #
6986+ #
6987+ #
6988+ #
6989+ #
6990+ add.4\\t%0, %2, %1
6991+ add.4\\t%0, %1, %2"
6992+ "(reload_completed
6993+ && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
6994+ [(set (match_dup 0)
6995+ (plus:SI (match_dup 1)
6996+ (match_dup 2)))]
6997+ ""
6998+)
6999+
7000+(define_insn "addsi3_1_ccwzn"
7001+ [(set (reg CC_REGNO)
7002+ (compare
7003+ (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7004+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7005+ (const_int 0)))
7006+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7007+ (plus:SI (match_dup 1)
7008+ (match_dup 2)))]
7009+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7010+ "@
7011+ add.4\\t%0, %2, %1
7012+ add.4\\t%0, %1, %2")
7013+
7014+(define_insn "addsi3_1_ccwzn_null"
7015+ [(set (reg CC_REGNO)
7016+ (compare
7017+ (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
7018+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
7019+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7020+ "@
7021+ add.4\\t#0, %1, %0
7022+ add.4\\t#0, %0, %1")
7023+
7024+(define_insn_and_split "addsi3_2"
7025+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
7026+ (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
7027+ (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
7028+ ""
7029+ "@
7030+ lea.4\\t%0, %E2(%1)
7031+ lea.2\\t%0, %E2(%1)
7032+ lea.1\\t%0, %E2(%1)
7033+ pdec\\t%0, %n2(%1)
7034+ lea.1\\t%0, (%1,%2)
7035+ #"
7036+ "(reload_completed
7037+ && ! satisfies_constraint_L (operands[2])
7038+ && ! satisfies_constraint_K (operands[2])
7039+ && ! satisfies_constraint_J (operands[2])
7040+ && ! satisfies_constraint_P (operands[2])
7041+ && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
7042+ [(set (reg:SI AUX_DATA_REGNO)
7043+ (match_dup 2))
7044+ (set (match_dup 0)
7045+ (plus:SI (match_dup 1)
7046+ (reg:SI AUX_DATA_REGNO)))]
7047+ ""
7048+)
7049+
7050+(define_insn "lea_2"
7051+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7052+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7053+ (const_int 2))
7054+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7055+ ""
7056+ "lea.2\\t%0, (%2,%1)")
7057+
7058+(define_insn "lea_4"
7059+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7060+ (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7061+ (const_int 4))
7062+ (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7063+ ""
7064+ "lea.4\\t%0, (%2,%1)")
7065+
7066+(define_expand "adddi3"
7067+ [(parallel
7068+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
7069+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7070+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
7071+ (clobber (reg:CC CC_REGNO))])]
7072+ ""
7073+ "{
7074+ /* If we have a non-data reg for operand 1 then prefer that over
7075+ a CONST_INT in operand 2. */
7076+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7077+ && CONST_INT_P (operands[2]))
7078+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7079+
7080+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7081+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7082+ }")
7083+
7084+; We construct a 64-bit add from 32-bit operations. Note that we use the
7085+; & constraint to prevent overlapping registers being allocated. We do
7086+; allow identical registers though as that won't break anything.
7087+;
7088+(define_insn "adddi3_add4addc"
7089+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
7090+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7091+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
7092+ (clobber (reg:CC CC_REGNO))]
7093+ ""
7094+ "*
7095+ {
7096+ operands[3] = gen_lowpart (SImode, operands[0]);
7097+ operands[4] = gen_lowpart (SImode, operands[1]);
7098+ operands[5] = gen_lowpart (SImode, operands[2]);
7099+ operands[6] = gen_highpart (SImode, operands[0]);
7100+ operands[7] = gen_highpart (SImode, operands[1]);
7101+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7102+
7103+ if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
7104+ return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
7105+
7106+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
7107+ }"
7108+ [(set_attr "length" "8")])
7109+
7110+(define_insn "adddi3_ccwz"
7111+ [(set (reg CC_REGNO)
7112+ (compare
7113+ (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7114+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
7115+ (const_int 0)))
7116+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
7117+ (plus:DI (match_dup 1)
7118+ (match_dup 2)))]
7119+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7120+ "*
7121+ {
7122+ operands[3] = gen_lowpart (SImode, operands[0]);
7123+ operands[6] = gen_highpart (SImode, operands[0]);
7124+
7125+ if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
7126+ {
7127+ operands[4] = gen_lowpart (SImode, operands[1]);
7128+ operands[5] = gen_lowpart (SImode, operands[2]);
7129+ operands[7] = gen_highpart (SImode, operands[1]);
7130+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7131+ }
7132+ else
7133+ {
7134+ operands[4] = gen_lowpart (SImode, operands[2]);
7135+ operands[5] = gen_lowpart (SImode, operands[1]);
7136+ operands[7] = gen_highpart (SImode, operands[2]);
7137+ operands[8] = gen_highpart (SImode, operands[1]);
7138+ }
7139+
7140+ return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
7141+ }"
7142+ [(set_attr "length" "8")])
7143+
7144+(define_insn "adddi3_ccwz_null"
7145+ [(set (reg CC_REGNO)
7146+ (compare
7147+ (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
7148+ (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
7149+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7150+ "*
7151+ {
7152+ if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
7153+ {
7154+ operands[2] = gen_lowpart (SImode, operands[0]);
7155+ operands[3] = gen_lowpart (SImode, operands[1]);
7156+ operands[4] = gen_highpart (SImode, operands[0]);
7157+ operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
7158+ }
7159+ else
7160+ {
7161+ operands[2] = gen_lowpart (SImode, operands[1]);
7162+ operands[3] = gen_lowpart (SImode, operands[0]);
7163+ operands[4] = gen_highpart (SImode, operands[1]);
7164+ operands[5] = gen_highpart (SImode, operands[0]);
7165+ }
7166+
7167+ return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
7168+ }"
7169+ [(set_attr "length" "8")])
7170+
7171+(define_expand "subqi3"
7172+ [(parallel
7173+ [(set (match_operand:QI 0 "memory_operand" "")
7174+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
7175+ (match_operand:QI 2 "ubicom32_data_register_operand" "")))
7176+ (clobber (reg:CC CC_REGNO))])]
7177+ "(ubicom32_v4)"
7178+ "{
7179+ if (!memory_operand (operands[0], QImode))
7180+ FAIL;
7181+ }")
7182+
7183+(define_insn "subqi3_sub1"
7184+ [(set (match_operand:QI 0 "memory_operand" "=m")
7185+ (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
7186+ (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
7187+ (clobber (reg:CC CC_REGNO))]
7188+ "(ubicom32_v4)"
7189+ "sub.1\\t%0, %1, %2")
7190+
7191+(define_expand "subhi3"
7192+ [(parallel
7193+ [(set (match_operand:HI 0 "memory_operand" "")
7194+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
7195+ (match_operand:HI 2 "ubicom32_data_register_operand" "")))
7196+ (clobber (reg:CC CC_REGNO))])]
7197+ "(ubicom32_v4)"
7198+ "{
7199+ if (!memory_operand (operands[0], HImode))
7200+ FAIL;
7201+ }")
7202+
7203+(define_insn "subhi3_sub2"
7204+ [(set (match_operand:HI 0 "memory_operand" "=m")
7205+ (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
7206+ (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
7207+ (clobber (reg:CC CC_REGNO))]
7208+ ""
7209+ "sub.2\\t%0, %1, %2")
7210+
7211+(define_insn "subsi3"
7212+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7213+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
7214+ (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
7215+ (clobber (reg:CC CC_REGNO))]
7216+ ""
7217+ "sub.4\\t%0, %1, %2")
7218+
7219+(define_insn "subsi3_ccwz"
7220+ [(set (reg CC_REGNO)
7221+ (compare
7222+ (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
7223+ (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
7224+ (const_int 0)))
7225+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7226+ (minus:SI (match_dup 1)
7227+ (match_dup 2)))]
7228+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7229+ "sub.4\\t%0, %1, %2")
7230+
7231+; We construct a 64-bit add from 32-bit operations. Note that we use the
7232+; & constraint to prevent overlapping registers being allocated. We do
7233+; allow identical registers though as that won't break anything.
7234+;
7235+(define_insn "subdi3"
7236+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
7237+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
7238+ (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
7239+ (clobber (reg:CC CC_REGNO))]
7240+ ""
7241+ "*
7242+ {
7243+ operands[3] = gen_lowpart (SImode, operands[0]);
7244+ operands[4] = gen_lowpart (SImode, operands[1]);
7245+ operands[5] = gen_lowpart (SImode, operands[2]);
7246+ operands[6] = gen_highpart (SImode, operands[0]);
7247+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
7248+ operands[8] = gen_highpart (SImode, operands[2]);
7249+
7250+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
7251+ }"
7252+ [(set_attr "length" "8")])
7253+
7254+(define_insn "subdi3_ccwz"
7255+ [(set (reg CC_REGNO)
7256+ (compare
7257+ (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
7258+ (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
7259+ (const_int 0)))
7260+ (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
7261+ (minus:DI (match_dup 1)
7262+ (match_dup 2)))]
7263+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7264+ "*
7265+ {
7266+ operands[3] = gen_lowpart (SImode, operands[0]);
7267+ operands[4] = gen_lowpart (SImode, operands[1]);
7268+ operands[5] = gen_lowpart (SImode, operands[2]);
7269+ operands[6] = gen_highpart (SImode, operands[0]);
7270+ operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
7271+ operands[8] = gen_highpart (SImode, operands[2]);
7272+
7273+ return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
7274+ }"
7275+ [(set_attr "length" "8")])
7276+
7277+;(define_insn "negqi2"
7278+; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
7279+; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
7280+; (clobber (reg:CC CC_REGNO))]
7281+; "(ubicom32_v4)"
7282+; "sub.1\\t%0, #0, %1")
7283+
7284+;(define_insn "neghi2"
7285+; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7286+; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
7287+; (clobber (reg:CC CC_REGNO))]
7288+; ""
7289+; "sub.2\\t%0, #0, %1")
7290+
7291+(define_insn "negsi2"
7292+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7293+ (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
7294+ (clobber (reg:CC CC_REGNO))]
7295+ ""
7296+ "sub.4\\t%0, #0, %1")
7297+
7298+(define_insn_and_split "negdi2"
7299+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
7300+ (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
7301+ (clobber (reg:CC CC_REGNO))]
7302+ ""
7303+ "#"
7304+ "reload_completed"
7305+ [(parallel [(set (match_dup 0)
7306+ (minus:DI (const_int 0)
7307+ (match_dup 1)))
7308+ (clobber (reg:CC CC_REGNO))])]
7309+ ""
7310+ [(set_attr "length" "8")])
7311+
7312+(define_insn "umulhisi3"
7313+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
7314+ (mult:SI
7315+ (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
7316+ (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
7317+ (clobber (reg:HI ACC0_HI_REGNO))
7318+ (clobber (reg:HI ACC1_HI_REGNO))]
7319+ ""
7320+ "@
7321+ mulu\\t%A0, %2, %1
7322+ mulu\\t%A0, %1, %2"
7323+ [(set_attr "type" "mul,mul")])
7324+
7325+(define_insn "mulhisi3"
7326+ [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
7327+ (mult:SI
7328+ (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
7329+ (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
7330+ (clobber (reg:HI ACC0_HI_REGNO))
7331+ (clobber (reg:HI ACC1_HI_REGNO))]
7332+ ""
7333+ "@
7334+ muls\\t%A0, %2, %1
7335+ muls\\t%A0, %1, %2"
7336+ [(set_attr "type" "mul,mul")])
7337+
7338+(define_expand "mulsi3"
7339+ [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
7340+ (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
7341+ (match_operand:SI 2 "ubicom32_arith_operand" "")))]
7342+ ""
7343+ "{
7344+ if (ubicom32_emit_mult_sequence (operands))
7345+ DONE;
7346+ }")
7347+
7348+(define_insn "umulsidi3"
7349+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
7350+ (mult:DI
7351+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
7352+ (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
7353+ "(ubicom32_v4)"
7354+ "@
7355+ mulu.4\\t%A0, %2, %1
7356+ mulu.4\\t%A0, %1, %2"
7357+ [(set_attr "type" "mul,mul")])
7358+
7359+(define_peephole2
7360+ [(set (match_operand:SI 0 "register_operand" "")
7361+ (match_operand:SI 1 "nonimmediate_operand" ""))
7362+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7363+ (mult:DI
7364+ (zero_extend:DI (match_dup 0))
7365+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
7366+ "(peep2_reg_dead_p (2, operands[0])
7367+ || REGNO (operands[0]) == REGNO (operands[2])
7368+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7369+ && ! rtx_equal_p (operands[0], operands[3])"
7370+ [(set (match_dup 2)
7371+ (mult:DI
7372+ (zero_extend:DI (match_dup 1))
7373+ (zero_extend:DI (match_dup 3))))]
7374+ "")
7375+
7376+(define_peephole2
7377+ [(set (match_operand:SI 0 "register_operand" "")
7378+ (match_operand:SI 1 "nonimmediate_operand" ""))
7379+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7380+ (mult:DI
7381+ (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
7382+ (zero_extend:DI (match_dup 0))))]
7383+ "(peep2_reg_dead_p (2, operands[0])
7384+ || REGNO (operands[0]) == REGNO (operands[2])
7385+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7386+ && ! rtx_equal_p (operands[0], operands[3])"
7387+ [(set (match_dup 2)
7388+ (mult:DI
7389+ (zero_extend:DI (match_dup 1))
7390+ (zero_extend:DI (match_dup 3))))]
7391+ "")
7392+
7393+(define_insn "umulsidi3_const"
7394+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
7395+ (mult:DI
7396+ (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
7397+ (match_operand 2 "const_int_operand" "I")))]
7398+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
7399+ "mulu.4\\t%A0, %2, %1"
7400+ [(set_attr "type" "mul")])
7401+
7402+(define_insn "mulsidi3"
7403+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
7404+ (mult:DI
7405+ (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
7406+ (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
7407+ "(ubicom32_v4)"
7408+ "@
7409+ muls.4\\t%A0, %2, %1
7410+ muls.4\\t%A0, %1, %2"
7411+ [(set_attr "type" "mul,mul")])
7412+
7413+(define_peephole2
7414+ [(set (match_operand:SI 0 "register_operand" "")
7415+ (match_operand:SI 1 "nonimmediate_operand" ""))
7416+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7417+ (mult:DI
7418+ (sign_extend:DI (match_dup 0))
7419+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
7420+ "(peep2_reg_dead_p (2, operands[0])
7421+ || REGNO (operands[0]) == REGNO (operands[2])
7422+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7423+ && ! rtx_equal_p (operands[0], operands[3])"
7424+ [(set (match_dup 2)
7425+ (mult:DI
7426+ (sign_extend:DI (match_dup 1))
7427+ (sign_extend:DI (match_dup 3))))]
7428+ "")
7429+
7430+(define_peephole2
7431+ [(set (match_operand:SI 0 "register_operand" "")
7432+ (match_operand:SI 1 "nonimmediate_operand" ""))
7433+ (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7434+ (mult:DI
7435+ (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
7436+ (sign_extend:DI (match_dup 0))))]
7437+ "(peep2_reg_dead_p (2, operands[0])
7438+ || REGNO (operands[0]) == REGNO (operands[2])
7439+ || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7440+ && ! rtx_equal_p (operands[0], operands[3])"
7441+ [(set (match_dup 2)
7442+ (mult:DI
7443+ (sign_extend:DI (match_dup 1))
7444+ (sign_extend:DI (match_dup 3))))]
7445+ "")
7446+
7447+(define_insn "mulsidi3_const"
7448+ [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
7449+ (mult:DI
7450+ (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
7451+ (match_operand 2 "const_int_operand" "I")))]
7452+ "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
7453+ "muls.4\\t%A0, %2, %1"
7454+ [(set_attr "type" "mul")])
7455+
7456+(define_expand "andqi3"
7457+ [(parallel
7458+ [(set (match_operand:QI 0 "memory_operand" "")
7459+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
7460+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
7461+ (clobber (reg:CC CC_REGNO))])]
7462+ "(ubicom32_v4)"
7463+ "{
7464+ if (!memory_operand (operands[0], QImode))
7465+ FAIL;
7466+
7467+ /* If we have a non-data reg for operand 1 then prefer that over
7468+ a CONST_INT in operand 2. */
7469+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7470+ && CONST_INT_P (operands[2]))
7471+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
7472+
7473+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7474+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
7475+ }")
7476+
7477+(define_insn "andqi3_and1"
7478+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
7479+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7480+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
7481+ (clobber (reg:CC CC_REGNO))]
7482+ "(ubicom32_v4)"
7483+ "@
7484+ and.1\\t%0, %2, %1
7485+ and.1\\t%0, %1, %2")
7486+
7487+(define_insn "andqi3_and1_ccszn"
7488+ [(set (reg CC_REGNO)
7489+ (compare
7490+ (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7491+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
7492+ (const_int 0)))
7493+ (set (match_operand:QI 0 "memory_operand" "=m, m")
7494+ (and:QI (match_dup 1)
7495+ (match_dup 2)))]
7496+ "(ubicom32_v4
7497+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
7498+ "@
7499+ and.1\\t%0, %2, %1
7500+ and.1\\t%0, %1, %2")
7501+
7502+(define_insn "andqi3_and1_ccszn_null"
7503+ [(set (reg CC_REGNO)
7504+ (compare
7505+ (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
7506+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
7507+ (const_int 0)))]
7508+ "(ubicom32_v4
7509+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
7510+ "@
7511+ and.1\\t#0, %1, %0
7512+ and.1\\t#0, %0, %1")
7513+
7514+(define_insn "and1_ccszn_null_1"
7515+ [(set (reg CC_REGNO)
7516+ (compare
7517+ (subreg:QI
7518+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
7519+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
7520+ 3)
7521+ (const_int 0)))]
7522+ "(ubicom32_v4
7523+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
7524+ "and.1\\t#0, %1, %0")
7525+
7526+(define_insn "and1_ccszn_null_2"
7527+ [(set (reg CC_REGNO)
7528+ (compare
7529+ (subreg:QI
7530+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
7531+ (subreg:SI
7532+ (match_operand:QI 1 "memory_operand" "m")
7533+ 0))
7534+ 3)
7535+ (const_int 0)))]
7536+ "(ubicom32_v4
7537+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
7538+ "and.1\\t#0, %1, %0")
7539+
7540+(define_insn "and1_ccszn_null_3"
7541+ [(set (reg CC_REGNO)
7542+ (compare
7543+ (subreg:QI
7544+ (and:SI (subreg:SI
7545+ (match_operand:QI 0 "memory_operand" "m")
7546+ 0)
7547+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
7548+ 3)
7549+ (const_int 0)))]
7550+ "(ubicom32_v4
7551+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
7552+ "and.1\\t#0, %0, %1")
7553+
7554+(define_expand "andhi3"
7555+ [(parallel
7556+ [(set (match_operand:HI 0 "memory_operand" "")
7557+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
7558+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
7559+ (clobber (reg:CC CC_REGNO))])]
7560+ ""
7561+ "{
7562+ if (!memory_operand (operands[0], HImode))
7563+ FAIL;
7564+
7565+ /* If we have a non-data reg for operand 1 then prefer that over
7566+ a CONST_INT in operand 2. */
7567+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7568+ && CONST_INT_P (operands[2]))
7569+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
7570+
7571+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7572+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
7573+ }")
7574+
7575+(define_insn "andhi3_and2"
7576+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
7577+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7578+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
7579+ (clobber (reg:CC CC_REGNO))]
7580+ ""
7581+ "@
7582+ and.2\\t%0, %2, %1
7583+ and.2\\t%0, %1, %2")
7584+
7585+(define_insn "andhi3_and2_ccszn"
7586+ [(set (reg CC_REGNO)
7587+ (compare
7588+ (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7589+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
7590+ (const_int 0)))
7591+ (set (match_operand:HI 0 "memory_operand" "=m, m")
7592+ (and:HI (match_dup 1)
7593+ (match_dup 2)))]
7594+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
7595+ "@
7596+ and.2\\t%0, %2, %1
7597+ and.2\\t%0, %1, %2")
7598+
7599+(define_insn "andhi3_and2_ccszn_null"
7600+ [(set (reg CC_REGNO)
7601+ (compare
7602+ (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
7603+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
7604+ (const_int 0)))]
7605+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
7606+ "@
7607+ and.2\\t#0, %1, %0
7608+ and.2\\t#0, %0, %1")
7609+
7610+(define_insn "and2_ccszn_null_1"
7611+ [(set (reg CC_REGNO)
7612+ (compare
7613+ (subreg:HI
7614+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
7615+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
7616+ 2)
7617+ (const_int 0)))]
7618+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
7619+ "and.2\\t#0, %1, %0")
7620+
7621+(define_insn "and2_ccszn_null_2"
7622+ [(set (reg CC_REGNO)
7623+ (compare
7624+ (subreg:HI
7625+ (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
7626+ (subreg:SI
7627+ (match_operand:HI 1 "memory_operand" "m")
7628+ 0))
7629+ 2)
7630+ (const_int 0)))]
7631+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
7632+ "and.2\\t#0, %1, %0")
7633+
7634+(define_insn "and2_ccszn_null_3"
7635+ [(set (reg CC_REGNO)
7636+ (compare
7637+ (subreg:HI
7638+ (and:SI (subreg:SI
7639+ (match_operand:HI 0 "memory_operand" "m")
7640+ 0)
7641+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
7642+ 2)
7643+ (const_int 0)))]
7644+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
7645+ "and.2\\t#0, %0, %1")
7646+
7647+(define_expand "andsi3"
7648+ [(parallel
7649+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
7650+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7651+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
7652+ (clobber (reg:CC CC_REGNO))])]
7653+ ""
7654+ "{
7655+ do
7656+ {
7657+ /* Is this a bfextu? */
7658+ if (ubicom32_data_register_operand (operands[0], SImode)
7659+ && CONST_INT_P (operands[2])
7660+ && exact_log2 (INTVAL (operands[2]) + 1) != -1)
7661+ break;
7662+
7663+ /* Is this a bclr? */
7664+ if (CONST_INT_P (operands[2])
7665+ && exact_log2 (~INTVAL (operands[2])) != -1)
7666+ break;
7667+
7668+ /* Must be an and.4 */
7669+ if (!ubicom32_data_register_operand (operands[1], SImode))
7670+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
7671+
7672+ if (!ubicom32_arith_operand (operands[2], SImode))
7673+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
7674+ }
7675+ while (0);
7676+ }")
7677+
7678+(define_insn "andsi3_bfextu"
7679+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
7680+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
7681+ (match_operand:SI 2 "const_int_operand" "O")))
7682+ (clobber (reg:CC CC_REGNO))]
7683+ "(satisfies_constraint_O (operands[2]))"
7684+ "*
7685+ {
7686+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
7687+
7688+ return \"bfextu\\t%0, %1, %3\";
7689+ }")
7690+
7691+(define_insn "andsi3_bfextu_ccwz"
7692+ [(set (reg CC_REGNO)
7693+ (compare
7694+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
7695+ (match_operand:SI 2 "const_int_operand" "O"))
7696+ (const_int 0)))
7697+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
7698+ (and:SI (match_dup 1)
7699+ (match_dup 2)))]
7700+ "(satisfies_constraint_O (operands[2])
7701+ && ubicom32_match_cc_mode(insn, CCWZmode))"
7702+ "*
7703+ {
7704+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
7705+
7706+ return \"bfextu\\t%0, %1, %3\";
7707+ }")
7708+
7709+(define_insn "andsi3_bfextu_ccwz_null"
7710+ [(set (reg CC_REGNO)
7711+ (compare
7712+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
7713+ (match_operand:SI 1 "const_int_operand" "O"))
7714+ (const_int 0)))
7715+ (clobber (match_scratch:SI 2 "=d"))]
7716+ "(satisfies_constraint_O (operands[1])
7717+ && ubicom32_match_cc_mode(insn, CCWZmode))"
7718+ "*
7719+ {
7720+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
7721+
7722+ return \"bfextu\\t%2, %0, %3\";
7723+ }")
7724+
7725+(define_insn "andsi3_bclr"
7726+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7727+ (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
7728+ (match_operand:SI 2 "const_int_operand" "n")))
7729+ (clobber (reg:CC CC_REGNO))]
7730+ "(exact_log2 (~INTVAL (operands[2])) != -1)"
7731+ "bclr\\t%0, %1, #%D2")
7732+
7733+(define_insn "andsi3_and4"
7734+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7735+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7736+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
7737+ (clobber (reg:CC CC_REGNO))]
7738+ ""
7739+ "@
7740+ and.4\\t%0, %2, %1
7741+ and.4\\t%0, %1, %2")
7742+
7743+(define_insn "andsi3_and4_ccwzn"
7744+ [(set (reg CC_REGNO)
7745+ (compare
7746+ (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7747+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7748+ (const_int 0)))
7749+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7750+ (and:SI (match_dup 1)
7751+ (match_dup 2)))]
7752+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7753+ "@
7754+ and.4\\t%0, %2, %1
7755+ and.4\\t%0, %1, %2")
7756+
7757+(define_insn "andsi3_and4_ccwzn_null"
7758+ [(set (reg CC_REGNO)
7759+ (compare
7760+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
7761+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
7762+ (const_int 0)))]
7763+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7764+ "@
7765+ and.4\\t#0, %1, %0
7766+ and.4\\t#0, %0, %1")
7767+
7768+(define_insn "andsi3_lsr4_ccwz_null"
7769+ [(set (reg CC_REGNO)
7770+ (compare
7771+ (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
7772+ (match_operand:SI 1 "const_int_operand" "n"))
7773+ (const_int 0)))
7774+ (clobber (match_scratch:SI 2 "=d"))]
7775+ "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
7776+ && ubicom32_match_cc_mode(insn, CCWZmode))"
7777+ "*
7778+ {
7779+ operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
7780+
7781+ return \"lsr.4\\t%2, %0, %3\";
7782+ }")
7783+
7784+; We really would like the combiner to recognize this scenario and deal with
7785+; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
7786+; into QImode operations and we can't match them in any useful way.
7787+;
7788+(define_peephole2
7789+ [(set (match_operand:SI 0 "register_operand" "")
7790+ (match_operand:SI 1 "const_int_operand" ""))
7791+ (set (reg:CCWZ CC_REGNO)
7792+ (compare:CCWZ
7793+ (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
7794+ (match_dup 0))
7795+ (const_int 0)))]
7796+ "(exact_log2 (INTVAL (operands[1])) != -1
7797+ && peep2_reg_dead_p (2, operands[0]))"
7798+ [(set (reg:CCWZ CC_REGNO)
7799+ (compare:CCWZ
7800+ (zero_extract:SI
7801+ (match_dup 2)
7802+ (const_int 1)
7803+ (match_dup 3))
7804+ (const_int 0)))]
7805+ "{
7806+ operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
7807+ }")
7808+
7809+(define_expand "anddi3"
7810+ [(parallel
7811+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
7812+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7813+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
7814+ (clobber (reg:CC CC_REGNO))])]
7815+ ""
7816+ "{
7817+ /* If we have a non-data reg for operand 1 then prefer that over
7818+ a CONST_INT in operand 2. */
7819+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7820+ && CONST_INT_P (operands[2]))
7821+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7822+
7823+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7824+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7825+ }")
7826+
7827+(define_insn_and_split "anddi3_and4"
7828+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
7829+ (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7830+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
7831+ (clobber (reg:CC CC_REGNO))]
7832+ ""
7833+ "#"
7834+ "reload_completed"
7835+ [(parallel [(set (match_dup 3)
7836+ (and:SI (match_dup 4)
7837+ (match_dup 5)))
7838+ (clobber (reg:CC CC_REGNO))])
7839+ (parallel [(set (match_dup 6)
7840+ (and:SI (match_dup 7)
7841+ (match_dup 8)))
7842+ (clobber (reg:CC CC_REGNO))])]
7843+ "{
7844+ operands[3] = gen_lowpart (SImode, operands[0]);
7845+ operands[4] = gen_lowpart (SImode, operands[1]);
7846+ operands[5] = gen_lowpart (SImode, operands[2]);
7847+ operands[6] = gen_highpart (SImode, operands[0]);
7848+ operands[7] = gen_highpart (SImode, operands[1]);
7849+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7850+ }"
7851+ [(set_attr "length" "8")])
7852+
7853+(define_expand "iorqi3"
7854+ [(parallel
7855+ [(set (match_operand:QI 0 "memory_operand" "")
7856+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
7857+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
7858+ (clobber (reg:CC CC_REGNO))])]
7859+ "(ubicom32_v4)"
7860+ "{
7861+ if (!memory_operand (operands[0], QImode))
7862+ FAIL;
7863+
7864+ /* If we have a non-data reg for operand 1 then prefer that over
7865+ a CONST_INT in operand 2. */
7866+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7867+ && CONST_INT_P (operands[2]))
7868+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
7869+
7870+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7871+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
7872+ }")
7873+
7874+(define_insn "iorqi3_or1"
7875+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
7876+ (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7877+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
7878+ (clobber (reg:CC CC_REGNO))]
7879+ "(ubicom32_v4)"
7880+ "@
7881+ or.1\\t%0, %2, %1
7882+ or.1\\t%0, %1, %2")
7883+
7884+(define_expand "iorhi3"
7885+ [(parallel
7886+ [(set (match_operand:HI 0 "memory_operand" "")
7887+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
7888+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
7889+ (clobber (reg:CC CC_REGNO))])]
7890+ ""
7891+ "{
7892+ if (!memory_operand (operands[0], HImode))
7893+ FAIL;
7894+
7895+ /* If we have a non-data reg for operand 1 then prefer that over
7896+ a CONST_INT in operand 2. */
7897+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7898+ && CONST_INT_P (operands[2]))
7899+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
7900+
7901+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7902+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
7903+ }")
7904+
7905+(define_insn "iorhi3_or2"
7906+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
7907+ (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7908+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
7909+ (clobber (reg:CC CC_REGNO))]
7910+ ""
7911+ "@
7912+ or.2\\t%0, %2, %1
7913+ or.2\\t%0, %1, %2")
7914+
7915+(define_expand "iorsi3"
7916+ [(parallel
7917+ [(set (match_operand:SI 0 "nonimmediate_operand" "")
7918+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
7919+ (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
7920+ (clobber (reg:CC CC_REGNO))])]
7921+ ""
7922+ "{
7923+ do
7924+ {
7925+ /* Is this a bset? */
7926+ if (CONST_INT_P (operands[2])
7927+ && exact_log2 (INTVAL (operands[2])) != -1)
7928+ break;
7929+
7930+ /* Must be an or.4 */
7931+ if (!ubicom32_data_register_operand (operands[1], SImode))
7932+ operands[1] = copy_to_mode_reg (SImode, operands[1]);
7933+
7934+ if (!ubicom32_arith_operand (operands[2], SImode))
7935+ operands[2] = copy_to_mode_reg (SImode, operands[2]);
7936+ }
7937+ while (0);
7938+ }")
7939+
7940+(define_insn "iorsi3_bset"
7941+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7942+ (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
7943+ (match_operand 2 "const_int_operand" "n")))
7944+ (clobber (reg:CC CC_REGNO))]
7945+ "(exact_log2 (INTVAL (operands[2])) != -1)"
7946+ "bset\\t%0, %1, #%d2")
7947+
7948+(define_insn "iorsi3_or4"
7949+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7950+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7951+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
7952+ (clobber (reg:CC CC_REGNO))]
7953+ ""
7954+ "@
7955+ or.4\\t%0, %2, %1
7956+ or.4\\t%0, %1, %2")
7957+
7958+(define_insn "iorsi3_ccwzn"
7959+ [(set (reg CC_REGNO)
7960+ (compare
7961+ (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7962+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7963+ (const_int 0)))
7964+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7965+ (ior:SI (match_dup 1)
7966+ (match_dup 2)))]
7967+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7968+ "@
7969+ or.4\\t%0, %2, %1
7970+ or.4\\t%0, %1, %2")
7971+
7972+(define_insn "iorsi3_ccwzn_null"
7973+ [(set (reg CC_REGNO)
7974+ (compare
7975+ (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
7976+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
7977+ (const_int 0)))]
7978+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
7979+ "@
7980+ or.4\\t#0, %1, %0
7981+ or.4\\t#0, %0, %1")
7982+
7983+(define_expand "iordi3"
7984+ [(parallel
7985+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
7986+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
7987+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
7988+ (clobber (reg:CC CC_REGNO))])]
7989+ ""
7990+ "{
7991+ /* If we have a non-data reg for operand 1 then prefer that over
7992+ a CONST_INT in operand 2. */
7993+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7994+ && CONST_INT_P (operands[2]))
7995+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7996+
7997+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7998+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
7999+ }")
8000+
8001+(define_insn_and_split "iordi3_or4"
8002+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
8003+ (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
8004+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
8005+ (clobber (reg:CC CC_REGNO))]
8006+ ""
8007+ "#"
8008+ "reload_completed"
8009+ [(parallel [(set (match_dup 3)
8010+ (ior:SI (match_dup 4)
8011+ (match_dup 5)))
8012+ (clobber (reg:CC CC_REGNO))])
8013+ (parallel [(set (match_dup 6)
8014+ (ior:SI (match_dup 7)
8015+ (match_dup 8)))
8016+ (clobber (reg:CC CC_REGNO))])]
8017+ "{
8018+ operands[3] = gen_lowpart (SImode, operands[0]);
8019+ operands[4] = gen_lowpart (SImode, operands[1]);
8020+ operands[5] = gen_lowpart (SImode, operands[2]);
8021+ operands[6] = gen_highpart (SImode, operands[0]);
8022+ operands[7] = gen_highpart (SImode, operands[1]);
8023+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
8024+ }"
8025+ [(set_attr "length" "8")])
8026+
8027+(define_expand "xorqi3"
8028+ [(parallel
8029+ [(set (match_operand:QI 0 "memory_operand" "")
8030+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8031+ (match_operand:QI 2 "ubicom32_arith_operand" "")))
8032+ (clobber (reg:CC CC_REGNO))])]
8033+ "(ubicom32_v4)"
8034+ "{
8035+ if (!memory_operand (operands[0], QImode))
8036+ FAIL;
8037+
8038+ /* If we have a non-data reg for operand 1 then prefer that over
8039+ a CONST_INT in operand 2. */
8040+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8041+ && CONST_INT_P (operands[2]))
8042+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
8043+
8044+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8045+ operands[2] = copy_to_mode_reg (QImode, operands[2]);
8046+ }")
8047+
8048+(define_insn "xorqi3_xor1"
8049+ [(set (match_operand:QI 0 "memory_operand" "=m, m")
8050+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
8051+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
8052+ (clobber (reg:CC CC_REGNO))]
8053+ "(ubicom32_v4)"
8054+ "@
8055+ xor.1\\t%0, %2, %1
8056+ xor.1\\t%0, %1, %2")
8057+
8058+(define_insn "xorqi3_xor1_ccszn"
8059+ [(set (reg CC_REGNO)
8060+ (compare
8061+ (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
8062+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
8063+ (const_int 0)))
8064+ (set (match_operand:QI 0 "memory_operand" "=m, m")
8065+ (xor:QI (match_dup 1)
8066+ (match_dup 2)))]
8067+ "(ubicom32_v4
8068+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
8069+ "@
8070+ xor.1\\t%0, %2, %1
8071+ xor.1\\t%0, %1, %2")
8072+
8073+(define_insn "xorqi3_xor1_ccszn_null"
8074+ [(set (reg CC_REGNO)
8075+ (compare
8076+ (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
8077+ (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
8078+ (const_int 0)))]
8079+ "(ubicom32_v4
8080+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
8081+ "@
8082+ xor.1\\t#0, %1, %0
8083+ xor.1\\t#0, %0, %1")
8084+
8085+(define_insn "xor1_ccszn_null_1"
8086+ [(set (reg CC_REGNO)
8087+ (compare
8088+ (subreg:QI
8089+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
8090+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
8091+ 3)
8092+ (const_int 0)))]
8093+ "(ubicom32_v4
8094+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
8095+ "xor.1\\t#0, %1, %0")
8096+
8097+(define_insn "xor1_ccszn_null_2"
8098+ [(set (reg CC_REGNO)
8099+ (compare
8100+ (subreg:QI
8101+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
8102+ (subreg:SI
8103+ (match_operand:QI 1 "memory_operand" "m")
8104+ 0))
8105+ 3)
8106+ (const_int 0)))]
8107+ "(ubicom32_v4
8108+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
8109+ "xor.1\\t#0, %1, %0")
8110+
8111+(define_insn "xor1_ccwzn_null_3"
8112+ [(set (reg CC_REGNO)
8113+ (compare
8114+ (subreg:QI
8115+ (xor:SI (subreg:SI
8116+ (match_operand:QI 0 "memory_operand" "m")
8117+ 0)
8118+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
8119+ 3)
8120+ (const_int 0)))]
8121+ "(ubicom32_v4
8122+ && ubicom32_match_cc_mode(insn, CCSZNmode))"
8123+ "xor.1\\t#0, %0, %1")
8124+
8125+(define_expand "xorhi3"
8126+ [(parallel
8127+ [(set (match_operand:HI 0 "memory_operand" "")
8128+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8129+ (match_operand:HI 2 "ubicom32_arith_operand" "")))
8130+ (clobber (reg:CC CC_REGNO))])]
8131+ ""
8132+ "{
8133+ if (!memory_operand (operands[0], HImode))
8134+ FAIL;
8135+
8136+ /* If we have a non-data reg for operand 1 then prefer that over
8137+ a CONST_INT in operand 2. */
8138+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8139+ && CONST_INT_P (operands[2]))
8140+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
8141+
8142+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8143+ operands[2] = copy_to_mode_reg (HImode, operands[2]);
8144+ }")
8145+
8146+(define_insn "xorhi3_xor2"
8147+ [(set (match_operand:HI 0 "memory_operand" "=m, m")
8148+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
8149+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
8150+ (clobber (reg:CC CC_REGNO))]
8151+ ""
8152+ "@
8153+ xor.2\\t%0, %2, %1
8154+ xor.2\\t%0, %1, %2")
8155+
8156+(define_insn "xorhi3_xor2_ccszn"
8157+ [(set (reg CC_REGNO)
8158+ (compare
8159+ (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
8160+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
8161+ (const_int 0)))
8162+ (set (match_operand:HI 0 "memory_operand" "=m, m")
8163+ (xor:HI (match_dup 1)
8164+ (match_dup 2)))]
8165+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
8166+ "@
8167+ xor.2\\t%0, %2, %1
8168+ xor.2\\t%0, %1, %2")
8169+
8170+(define_insn "xorhi3_xor2_ccszn_null"
8171+ [(set (reg CC_REGNO)
8172+ (compare
8173+ (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
8174+ (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
8175+ (const_int 0)))]
8176+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
8177+ "@
8178+ xor.2\\t#0, %1, %0
8179+ xor.2\\t#0, %0, %1")
8180+
8181+(define_insn "xor2_ccszn_null_1"
8182+ [(set (reg CC_REGNO)
8183+ (compare
8184+ (subreg:HI
8185+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
8186+ (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
8187+ 2)
8188+ (const_int 0)))]
8189+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
8190+ "xor.2\\t#0, %1, %0")
8191+
8192+(define_insn "xor2_ccszn_null_2"
8193+ [(set (reg CC_REGNO)
8194+ (compare
8195+ (subreg:HI
8196+ (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
8197+ (subreg:SI
8198+ (match_operand:HI 1 "memory_operand" "m")
8199+ 0))
8200+ 2)
8201+ (const_int 0)))]
8202+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
8203+ "xor.2\\t#0, %1, %0")
8204+
8205+(define_insn "xor2_ccszn_null_3"
8206+ [(set (reg CC_REGNO)
8207+ (compare
8208+ (subreg:HI
8209+ (xor:SI (subreg:SI
8210+ (match_operand:HI 0 "memory_operand" "m")
8211+ 0)
8212+ (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
8213+ 2)
8214+ (const_int 0)))]
8215+ "ubicom32_match_cc_mode(insn, CCSZNmode)"
8216+ "xor.2\\t#0, %0, %1")
8217+
8218+(define_insn "xorsi3"
8219+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8220+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
8221+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
8222+ (clobber (reg:CC CC_REGNO))]
8223+ ""
8224+ "@
8225+ xor.4\\t%0, %2, %1
8226+ xor.4\\t%0, %1, %2")
8227+
8228+(define_insn "xorsi3_ccwzn"
8229+ [(set (reg CC_REGNO)
8230+ (compare
8231+ (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
8232+ (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
8233+ (const_int 0)))
8234+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8235+ (xor:SI (match_dup 1)
8236+ (match_dup 2)))]
8237+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8238+ "@
8239+ xor.4\\t%0, %2, %1
8240+ xor.4\\t%0, %1, %2")
8241+
8242+(define_insn "xorsi3_ccwzn_null"
8243+ [(set (reg CC_REGNO)
8244+ (compare
8245+ (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
8246+ (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
8247+ (const_int 0)))]
8248+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8249+ "@
8250+ xor.4\\t#0, %1, %0
8251+ xor.4\\t#0, %0, %1")
8252+
8253+(define_expand "xordi3"
8254+ [(parallel
8255+ [(set (match_operand:DI 0 "nonimmediate_operand" "")
8256+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8257+ (match_operand:DI 2 "ubicom32_arith_operand" "")))
8258+ (clobber (reg:CC CC_REGNO))])]
8259+ ""
8260+ "{
8261+ /* If we have a non-data reg for operand 1 then prefer that over
8262+ a CONST_INT in operand 2. */
8263+ if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8264+ && CONST_INT_P (operands[2]))
8265+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
8266+
8267+ if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8268+ operands[2] = copy_to_mode_reg (DImode, operands[2]);
8269+ }")
8270+
8271+(define_insn_and_split "xordi3_xor4"
8272+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
8273+ (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
8274+ (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
8275+ (clobber (reg:CC CC_REGNO))]
8276+ ""
8277+ "#"
8278+ "reload_completed"
8279+ [(parallel [(set (match_dup 3)
8280+ (xor:SI (match_dup 4)
8281+ (match_dup 5)))
8282+ (clobber (reg:CC CC_REGNO))])
8283+ (parallel [(set (match_dup 6)
8284+ (xor:SI (match_dup 7)
8285+ (match_dup 8)))
8286+ (clobber (reg:CC CC_REGNO))])]
8287+ "{
8288+ operands[3] = gen_lowpart (SImode, operands[0]);
8289+ operands[4] = gen_lowpart (SImode, operands[1]);
8290+ operands[5] = gen_lowpart (SImode, operands[2]);
8291+ operands[6] = gen_highpart (SImode, operands[0]);
8292+ operands[7] = gen_highpart (SImode, operands[1]);
8293+ operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
8294+ }"
8295+ [(set_attr "length" "8")])
8296+
8297+(define_insn "not2_2"
8298+ [(set (match_operand:HI 0 "memory_operand" "=m")
8299+ (subreg:HI
8300+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
8301+ 2))
8302+ (clobber (reg:CC CC_REGNO))]
8303+ ""
8304+ "not.2\\t%0, %1")
8305+
8306+(define_insn "one_cmplsi2"
8307+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8308+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
8309+ (clobber (reg:CC CC_REGNO))]
8310+ ""
8311+ "not.4\\t%0, %1")
8312+
8313+(define_insn "one_cmplsi2_ccwzn"
8314+ [(set (reg CC_REGNO)
8315+ (compare
8316+ (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
8317+ (const_int 0)))
8318+ (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8319+ (not:SI (match_dup 1)))]
8320+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8321+ "not.4\\t%0, %1")
8322+
8323+(define_insn "one_cmplsi2_ccwzn_null"
8324+ [(set (reg CC_REGNO)
8325+ (compare
8326+ (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
8327+ (const_int 0)))]
8328+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8329+ "not.4\\t#0, %0")
8330+
8331+(define_insn_and_split "one_cmpldi2"
8332+ [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
8333+ (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
8334+ (clobber (reg:CC CC_REGNO))]
8335+ ""
8336+ "#"
8337+ ""
8338+ [(parallel [(set (match_dup 2)
8339+ (not:SI (match_dup 3)))
8340+ (clobber (reg:CC CC_REGNO))])
8341+ (parallel [(set (match_dup 4)
8342+ (not:SI (match_dup 5)))
8343+ (clobber (reg:CC CC_REGNO))])]
8344+ "{
8345+ operands[2] = gen_lowpart (SImode, operands[0]);
8346+ operands[3] = gen_lowpart (SImode, operands[1]);
8347+ operands[4] = gen_highpart (SImode, operands[0]);
8348+ operands[5] = gen_highpart (SImode, operands[1]);
8349+ }"
8350+ [(set_attr "length" "8")])
8351+
8352+; Conditional jump instructions
8353+
8354+(define_expand "beq"
8355+ [(set (pc)
8356+ (if_then_else (eq (match_dup 1)
8357+ (const_int 0))
8358+ (label_ref (match_operand 0 "" ""))
8359+ (pc)))]
8360+ ""
8361+ "{
8362+ operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
8363+ ubicom32_compare_op1);
8364+ }")
8365+
8366+(define_expand "bne"
8367+ [(set (pc)
8368+ (if_then_else (ne (match_dup 1)
8369+ (const_int 0))
8370+ (label_ref (match_operand 0 "" ""))
8371+ (pc)))]
8372+ ""
8373+ "{
8374+ operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
8375+ ubicom32_compare_op1);
8376+ }")
8377+
8378+(define_expand "bgt"
8379+ [(set (pc)
8380+ (if_then_else (gt (match_dup 1)
8381+ (const_int 0))
8382+ (label_ref (match_operand 0 "" ""))
8383+ (pc)))]
8384+ ""
8385+ "{
8386+ operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
8387+ ubicom32_compare_op1);
8388+ }")
8389+
8390+(define_expand "ble"
8391+ [(set (pc)
8392+ (if_then_else (le (match_dup 1)
8393+ (const_int 0))
8394+ (label_ref (match_operand 0 "" ""))
8395+ (pc)))]
8396+ ""
8397+ "{
8398+ operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
8399+ ubicom32_compare_op1);
8400+ }")
8401+
8402+(define_expand "bge"
8403+ [(set (pc)
8404+ (if_then_else (ge (match_dup 1)
8405+ (const_int 0))
8406+ (label_ref (match_operand 0 "" ""))
8407+ (pc)))]
8408+ ""
8409+ "{
8410+ operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
8411+ ubicom32_compare_op1);
8412+ }")
8413+
8414+(define_expand "blt"
8415+ [(set (pc)
8416+ (if_then_else (lt (match_dup 1)
8417+ (const_int 0))
8418+ (label_ref (match_operand 0 "" ""))
8419+ (pc)))]
8420+ ""
8421+ "{
8422+ operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
8423+ ubicom32_compare_op1);
8424+ }")
8425+
8426+(define_expand "bgtu"
8427+ [(set (pc)
8428+ (if_then_else (gtu (match_dup 1)
8429+ (const_int 0))
8430+ (label_ref (match_operand 0 "" ""))
8431+ (pc)))]
8432+ ""
8433+ "{
8434+ operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
8435+ ubicom32_compare_op1);
8436+ }")
8437+
8438+(define_expand "bleu"
8439+ [(set (pc)
8440+ (if_then_else (leu (match_dup 1)
8441+ (const_int 0))
8442+ (label_ref (match_operand 0 "" ""))
8443+ (pc)))]
8444+ ""
8445+ "{
8446+ operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
8447+ ubicom32_compare_op1);
8448+ }")
8449+
8450+(define_expand "bgeu"
8451+ [(set (pc)
8452+ (if_then_else (geu (match_dup 1)
8453+ (const_int 0))
8454+ (label_ref (match_operand 0 "" ""))
8455+ (pc)))]
8456+ ""
8457+ "{
8458+ operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
8459+ ubicom32_compare_op1);
8460+ }")
8461+
8462+(define_expand "bltu"
8463+ [(set (pc)
8464+ (if_then_else (ltu (match_dup 1)
8465+ (const_int 0))
8466+ (label_ref (match_operand 0 "" ""))
8467+ (pc)))]
8468+ ""
8469+ "{
8470+ operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
8471+ ubicom32_compare_op1);
8472+ }")
8473+
8474+(define_insn "jcc"
8475+ [(set (pc)
8476+ (if_then_else (match_operator 1 "comparison_operator"
8477+ [(match_operand 2 "ubicom32_cc_register_operand" "")
8478+ (const_int 0)])
8479+ (label_ref (match_operand 0 "" ""))
8480+ (pc)))]
8481+ ""
8482+ "*
8483+ {
8484+ ubicom32_output_cond_jump (insn, operands[1], operands[0]);
8485+ return \"\";
8486+ }")
8487+
8488+; Reverse branch - reverse our comparison condition so that we can
8489+; branch in the opposite sense.
8490+;
8491+(define_insn_and_split "jcc_reverse"
8492+ [(set (pc)
8493+ (if_then_else (match_operator 1 "comparison_operator"
8494+ [(match_operand 2 "ubicom32_cc_register_operand" "")
8495+ (const_int 0)])
8496+ (pc)
8497+ (label_ref (match_operand 0 "" ""))))]
8498+ ""
8499+ "#"
8500+ "reload_completed"
8501+ [(set (pc)
8502+ (if_then_else (match_dup 3)
8503+ (label_ref (match_dup 0))
8504+ (pc)))]
8505+ "{
8506+ rtx cc_reg;
8507+
8508+ cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
8509+ operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
8510+ GET_MODE (operands[1]),
8511+ cc_reg,
8512+ const0_rtx);
8513+ }")
8514+
8515+(define_insn "jump"
8516+ [(set (pc)
8517+ (label_ref (match_operand 0 "" "")))]
8518+ ""
8519+ "jmpt\\t%l0")
8520+
8521+(define_expand "indirect_jump"
8522+ [(parallel [(set (pc)
8523+ (match_operand:SI 0 "register_operand" ""))
8524+ (clobber (match_dup 0))])]
8525+ ""
8526+ "")
8527+
8528+(define_insn "indirect_jump_internal"
8529+ [(set (pc)
8530+ (match_operand:SI 0 "register_operand" "a"))
8531+ (clobber (match_dup 0))]
8532+ ""
8533+ "calli\\t%0,0(%0)")
8534+
8535+; Program Space: The table contains instructions, typically jumps.
8536+; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
8537+; <Jump Table is Here> ;An -> Here.
8538+; LEA Ak, (An,Dn) ;Ak -> Table Entry
8539+; JMP/CALL (Ak)
8540+
8541+(define_expand "tablejump"
8542+ [(parallel [(set (pc)
8543+ (match_operand:SI 0 "nonimmediate_operand" ""))
8544+ (use (label_ref (match_operand 1 "" "")))])]
8545+ ""
8546+ "")
8547+
8548+(define_insn "tablejump_internal"
8549+ [(set (pc)
8550+ (match_operand:SI 0 "nonimmediate_operand" "rm"))
8551+ (use (label_ref (match_operand 1 "" "")))]
8552+ ""
8553+ "ret\\t%0")
8554+
8555+; Call subroutine with no return value.
8556+;
8557+(define_expand "call"
8558+ [(call (match_operand:QI 0 "general_operand" "")
8559+ (match_operand:SI 1 "general_operand" ""))]
8560+ ""
8561+ "{
8562+ if (TARGET_FDPIC)
8563+ {
8564+ ubicom32_expand_call_fdpic (operands);
8565+ DONE;
8566+ }
8567+
8568+ if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
8569+ XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8570+ }")
8571+
8572+; We expand to a simple form that doesn't clobber the link register and
8573+; then split to a form that does. This allows the RTL optimizers that
8574+; run before the splitter to have the opportunity to eliminate the call
8575+; without marking A5 as being clobbered and this in turn avoids saves
8576+; and returns in a number of cases.
8577+;
8578+(define_insn_and_split "call_1"
8579+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8580+ (match_operand:SI 1 "general_operand" "g,g"))]
8581+ "! TARGET_FDPIC"
8582+ "#"
8583+ ""
8584+ [(parallel
8585+ [(call (mem:QI (match_dup 0))
8586+ (match_dup 1))
8587+ (clobber (reg:SI LINK_REGNO))])]
8588+ "")
8589+
8590+(define_insn "call_slow"
8591+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8592+ (match_operand:SI 1 "general_operand" "g,g"))
8593+ (clobber (reg:SI LINK_REGNO))]
8594+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
8595+ "@
8596+ calli\\ta5, 0(%0)
8597+ moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
8598+
8599+(define_insn "call_fast"
8600+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8601+ (match_operand:SI 1 "general_operand" "g,g"))
8602+ (clobber (reg:SI LINK_REGNO))]
8603+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
8604+ "@
8605+ calli\\ta5, 0(%0)
8606+ call\\ta5, %C0")
8607+
8608+; We expand to a simple form that doesn't clobber the link register and
8609+; then split to a form that does. This allows the RTL optimizers that
8610+; run before the splitter to have the opportunity to eliminate the call
8611+; without marking A5 as being clobbered and this in turn avoids saves
8612+; and returns in a number of cases.
8613+;
8614+(define_insn_and_split "call_fdpic"
8615+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8616+ (match_operand:SI 1 "general_operand" "g,g"))
8617+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
8618+ "TARGET_FDPIC"
8619+ "#"
8620+ ""
8621+ [(parallel
8622+ [(call (mem:QI (match_dup 0))
8623+ (match_dup 1))
8624+ (use (match_dup 2))
8625+ (clobber (reg:SI LINK_REGNO))])]
8626+ "")
8627+
8628+(define_insn "call_fdpic_clobber"
8629+ [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8630+ (match_operand:SI 1 "general_operand" "g,g"))
8631+ (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
8632+ (clobber (reg:SI LINK_REGNO))]
8633+ "TARGET_FDPIC"
8634+ "@
8635+ move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
8636+ call\\ta5, %C0")
8637+
8638+; Call subroutine, returning value in operand 0
8639+; (which must be a hard register).
8640+;
8641+(define_expand "call_value"
8642+ [(set (match_operand 0 "" "")
8643+ (call (match_operand:QI 1 "general_operand" "")
8644+ (match_operand:SI 2 "general_operand" "")))]
8645+ ""
8646+ "{
8647+ if (TARGET_FDPIC)
8648+ {
8649+ ubicom32_expand_call_value_fdpic (operands);
8650+ DONE;
8651+ }
8652+
8653+ if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
8654+ XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8655+ }")
8656+
8657+; We expand to a simple form that doesn't clobber the link register and
8658+; then split to a form that does. This allows the RTL optimizers that
8659+; run before the splitter to have the opportunity to eliminate the call
8660+; without marking A5 as being clobbered and this in turn avoids saves
8661+; and returns in a number of cases.
8662+;
8663+(define_insn_and_split "call_value_1"
8664+ [(set (match_operand 0 "register_operand" "=r,r")
8665+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8666+ (match_operand:SI 2 "general_operand" "g,g")))]
8667+ "! TARGET_FDPIC"
8668+ "#"
8669+ ""
8670+ [(parallel
8671+ [(set (match_dup 0)
8672+ (call (mem:QI (match_dup 1))
8673+ (match_dup 2)))
8674+ (clobber (reg:SI LINK_REGNO))])]
8675+ "")
8676+
8677+(define_insn "call_value_slow"
8678+ [(set (match_operand 0 "register_operand" "=r,r")
8679+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8680+ (match_operand:SI 2 "general_operand" "g,g")))
8681+ (clobber (reg:SI LINK_REGNO))]
8682+ "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
8683+ "@
8684+ calli\\ta5, 0(%1)
8685+ moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
8686+
8687+(define_insn "call_value_fast"
8688+ [(set (match_operand 0 "register_operand" "=r,r")
8689+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8690+ (match_operand:SI 2 "general_operand" "g,g")))
8691+ (clobber (reg:SI LINK_REGNO))]
8692+ "(! TARGET_FDPIC && TARGET_FASTCALL)"
8693+ "@
8694+ calli\\ta5, 0(%1)
8695+ call\\ta5, %C1")
8696+
8697+; We expand to a simple form that doesn't clobber the link register and
8698+; then split to a form that does. This allows the RTL optimizers that
8699+; run before the splitter to have the opportunity to eliminate the call
8700+; without marking A5 as being clobbered and this in turn avoids saves
8701+; and returns in a number of cases.
8702+;
8703+(define_insn_and_split "call_value_fdpic"
8704+ [(set (match_operand 0 "register_operand" "=r,r")
8705+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8706+ (match_operand:SI 2 "general_operand" "g,g")))
8707+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
8708+ "TARGET_FDPIC"
8709+ "#"
8710+ ""
8711+ [(parallel
8712+ [(set (match_dup 0)
8713+ (call (mem:QI (match_dup 1))
8714+ (match_dup 2)))
8715+ (use (match_dup 3))
8716+ (clobber (reg:SI LINK_REGNO))])]
8717+ "")
8718+
8719+(define_insn "call_value_fdpic_clobber"
8720+ [(set (match_operand 0 "register_operand" "=r,r")
8721+ (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8722+ (match_operand:SI 2 "general_operand" "g,g")))
8723+ (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
8724+ (clobber (reg:SI LINK_REGNO))]
8725+ "TARGET_FDPIC"
8726+ "@
8727+ move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
8728+ call\\ta5, %C1")
8729+
8730+(define_expand "untyped_call"
8731+ [(parallel [(call (match_operand 0 "" "")
8732+ (const_int 0))
8733+ (match_operand 1 "" "")
8734+ (match_operand 2 "" "")])]
8735+ ""
8736+ "{
8737+ int i;
8738+
8739+ emit_call_insn (gen_call (operands[0], const0_rtx));
8740+
8741+ for (i = 0; i < XVECLEN (operands[2], 0); i++)
8742+ {
8743+ rtx set = XVECEXP (operands[2], 0, i);
8744+ emit_move_insn (SET_DEST (set), SET_SRC (set));
8745+ }
8746+ DONE;
8747+ }")
8748+
8749+(define_insn "lsl1_1"
8750+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8751+ (ashift:SI (subreg:SI
8752+ (match_operand:QI 1 "memory_operand" "m")
8753+ 0)
8754+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8755+ (clobber (reg:CC CC_REGNO))]
8756+ "(ubicom32_v4)"
8757+ "lsl.1\\t%0, %1, %2")
8758+
8759+; The combiner gets rather creative about left shifts of sub-word memory
8760+; operands because it's uncertain about whether the memory is sign or
8761+; zero extended. It only wants zero-extended behaviour and so throws
8762+; in an extra and operation.
8763+;
8764+(define_insn "lsl1_2"
8765+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8766+ (and:SI
8767+ (ashift:SI (subreg:SI
8768+ (match_operand:QI 1 "memory_operand" "m")
8769+ 0)
8770+ (match_operand:SI 2 "const_int_operand" "M"))
8771+ (match_operand:SI 3 "const_int_operand" "n")))
8772+ (clobber (reg:CC CC_REGNO))]
8773+ "(ubicom32_v4
8774+ && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
8775+ "lsl.1\\t%0, %1, %2")
8776+
8777+(define_insn "lsl2_1"
8778+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8779+ (ashift:SI (subreg:SI
8780+ (match_operand:HI 1 "memory_operand" "m")
8781+ 0)
8782+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8783+ (clobber (reg:CC CC_REGNO))]
8784+ "(ubicom32_v4)"
8785+ "lsl.2\\t%0, %1, %2")
8786+
8787+; The combiner gets rather creative about left shifts of sub-word memory
8788+; operands because it's uncertain about whether the memory is sign or
8789+; zero extended. It only wants zero-extended behaviour and so throws
8790+; in an extra and operation.
8791+;
8792+(define_insn "lsl2_2"
8793+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8794+ (and:SI
8795+ (ashift:SI (subreg:SI
8796+ (match_operand:HI 1 "memory_operand" "m")
8797+ 0)
8798+ (match_operand:SI 2 "const_int_operand" "M"))
8799+ (match_operand:SI 3 "const_int_operand" "n")))
8800+ (clobber (reg:CC CC_REGNO))]
8801+ "(ubicom32_v4
8802+ && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
8803+ "lsl.2\\t%0, %1, %2")
8804+
8805+(define_insn "ashlsi3"
8806+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8807+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8808+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8809+ (clobber (reg:CC CC_REGNO))]
8810+ ""
8811+ "lsl.4\\t%0, %1, %2")
8812+
8813+(define_insn "lshlsi3_ccwz"
8814+ [(set (reg CC_REGNO)
8815+ (compare
8816+ (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8817+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8818+ (const_int 0)))
8819+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8820+ (ashift:SI (match_dup 1)
8821+ (match_dup 2)))]
8822+ "ubicom32_match_cc_mode(insn, CCWZmode)"
8823+ "lsl.4\\t%0, %1, %2")
8824+
8825+(define_insn "lshlsi3_ccwz_null"
8826+ [(set (reg CC_REGNO)
8827+ (compare
8828+ (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
8829+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8830+ (const_int 0)))
8831+ (clobber (match_scratch:SI 2 "=d"))]
8832+ "ubicom32_match_cc_mode(insn, CCWZmode)"
8833+ "lsl.4\\t%2, %0, %1")
8834+
8835+; The combiner finds this canonical form for what is in essence a right
8836+; shift.
8837+;
8838+(define_insn "asr1_2"
8839+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8840+ (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
8841+ (match_operand:SI 2 "const_int_operand" "M")
8842+ (match_operand:SI 3 "const_int_operand" "M")))
8843+ (clobber (reg:CC CC_REGNO))]
8844+ "(ubicom32_v4
8845+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
8846+ "asr.1\\t%0, %1, %3")
8847+
8848+; The combiner finds this canonical form for what is in essence a right
8849+; shift.
8850+;
8851+(define_insn "asr2_2"
8852+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8853+ (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
8854+ (match_operand:SI 2 "const_int_operand" "M")
8855+ (match_operand:SI 3 "const_int_operand" "M")))
8856+ (clobber (reg:CC CC_REGNO))]
8857+ "(ubicom32_v4
8858+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
8859+ "asr.2\\t%0, %1, %3")
8860+
8861+(define_insn "ashrsi3"
8862+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8863+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
8864+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8865+ (clobber (reg:CC CC_REGNO))]
8866+ ""
8867+ "asr.4\\t%0, %1, %2")
8868+
8869+(define_insn "ashrsi3_ccwzn"
8870+ [(set (reg CC_REGNO)
8871+ (compare
8872+ (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
8873+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8874+ (const_int 0)))
8875+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8876+ (ashiftrt:SI (match_dup 1)
8877+ (match_dup 2)))]
8878+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8879+ "asr.4\\t%0, %1, %2")
8880+
8881+(define_insn "ashrsi3_ccwzn_null"
8882+ [(set (reg CC_REGNO)
8883+ (compare
8884+ (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
8885+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8886+ (const_int 0)))
8887+ (clobber (match_scratch:SI 2 "=d"))]
8888+ "ubicom32_match_cc_mode(insn, CCWZNmode)"
8889+ "asr.4\\t%2, %0, %1")
8890+
8891+(define_insn "lsr1_1"
8892+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8893+ (lshiftrt:SI (subreg:SI
8894+ (match_operand:QI 1 "memory_operand" "m")
8895+ 0)
8896+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8897+ (clobber (reg:CC CC_REGNO))]
8898+ "(ubicom32_v4)"
8899+ "lsr.1\\t%0, %1, %2")
8900+
8901+; The combiner finds this canonical form for what is in essence a right
8902+; shift.
8903+;
8904+(define_insn "lsr1_2"
8905+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8906+ (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
8907+ (match_operand:SI 2 "const_int_operand" "M")
8908+ (match_operand:SI 3 "const_int_operand" "M")))
8909+ (clobber (reg:CC CC_REGNO))]
8910+ "(ubicom32_v4
8911+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
8912+ "lsr.1\\t%0, %1, %3")
8913+
8914+(define_insn "lsr2_1"
8915+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8916+ (lshiftrt:SI (subreg:SI
8917+ (match_operand:HI 1 "memory_operand" "m")
8918+ 0)
8919+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8920+ (clobber (reg:CC CC_REGNO))]
8921+ "(ubicom32_v4)"
8922+ "lsr.2\\t%0, %1, %2")
8923+
8924+; The combiner finds this canonical form for what is in essence a right
8925+; shift.
8926+;
8927+(define_insn "lsr2_2"
8928+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8929+ (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
8930+ (match_operand:SI 2 "const_int_operand" "M")
8931+ (match_operand:SI 3 "const_int_operand" "M")))
8932+ (clobber (reg:CC CC_REGNO))]
8933+ "(ubicom32_v4
8934+ && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
8935+ "lsr.2\\t%0, %1, %3")
8936+
8937+(define_insn "lshrsi3"
8938+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8939+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8940+ (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8941+ (clobber (reg:CC CC_REGNO))]
8942+ ""
8943+ "lsr.4\\t%0, %1, %2")
8944+
8945+(define_insn "lshrsi3_ccwz"
8946+ [(set (reg CC_REGNO)
8947+ (compare
8948+ (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8949+ (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8950+ (const_int 0)))
8951+ (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8952+ (lshiftrt:SI (match_dup 1)
8953+ (match_dup 2)))]
8954+ "ubicom32_match_cc_mode(insn, CCWZmode)"
8955+ "lsr.4\\t%0, %1, %2")
8956+
8957+(define_insn "lshrsi3_ccwz_null"
8958+ [(set (reg CC_REGNO)
8959+ (compare
8960+ (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
8961+ (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8962+ (const_int 0)))
8963+ (clobber (match_scratch:SI 2 "=d"))]
8964+ "ubicom32_match_cc_mode(insn, CCWZmode)"
8965+ "lsr.4\\t%2, %0, %1")
8966+
8967+(define_expand "prologue"
8968+ [(const_int 0)]
8969+ ""
8970+ "{
8971+ ubicom32_expand_prologue ();
8972+ DONE;
8973+ }")
8974+
8975+(define_expand "epilogue"
8976+ [(return)]
8977+ ""
8978+ "{
8979+ ubicom32_expand_epilogue ();
8980+ DONE;
8981+ }")
8982+
8983+(define_expand "return"
8984+ [(return)]
8985+ ""
8986+ "{
8987+ ubicom32_expand_epilogue ();
8988+ DONE;
8989+ }")
8990+
8991+(define_expand "_eh_return"
8992+ [(use (match_operand:SI 0 "register_operand" "r"))
8993+ (use (match_operand:SI 1 "register_operand" "r"))]
8994+ ""
8995+ "{
8996+ ubicom32_expand_eh_return (operands);
8997+ DONE;
8998+ }")
8999+
9000+; XXX - it looks almost certain that we could make return_internal use a Dn
9001+; register too. In that instance we'd have to use a ret instruction
9002+; rather than a calli but it might save cycles.
9003+;
9004+(define_insn "return_internal"
9005+ [(const_int 2)
9006+ (return)
9007+ (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
9008+ ""
9009+ "*
9010+ {
9011+ if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
9012+ && ubicom32_can_use_calli_to_ret)
9013+ return \"calli\\t%0, 0(%0)\";
9014+
9015+ return \"ret\\t%0\";
9016+ }")
9017+
9018+(define_insn "return_from_post_modify_sp"
9019+ [(parallel
9020+ [(const_int 2)
9021+ (return)
9022+ (use (mem:SI (post_modify:SI
9023+ (reg:SI SP_REGNO)
9024+ (plus:SI (reg:SI SP_REGNO)
9025+ (match_operand:SI 0 "const_int_operand" "n")))))])]
9026+ "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
9027+ "ret\\t(sp)%E0++")
9028+
9029+;(define_insn "eh_return_internal"
9030+; [(const_int 4)
9031+; (return)
9032+; (use (reg:SI 34))]
9033+; ""
9034+; "ret\\ta2")
9035+
9036+; No operation, needed in case the user uses -g but not -O.
9037+(define_expand "nop"
9038+ [(const_int 0)]
9039+ ""
9040+ "")
9041+
9042+(define_insn "nop_internal"
9043+ [(const_int 0)]
9044+ ""
9045+ "nop")
9046+
9047+; The combiner will generate this pattern given shift and add operations.
9048+; The canonical form that the combiner wants to use appears to be multiplies
9049+; instead of shifts even if the compiled sources use shifts.
9050+;
9051+(define_insn "shmrg1_add"
9052+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9053+ (plus:SI
9054+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9055+ (const_int 256))
9056+ (zero_extend:SI
9057+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
9058+ (clobber (reg:CC CC_REGNO))]
9059+ ""
9060+ "shmrg.1\\t%0, %2, %1")
9061+
9062+; The combiner will generate this pattern given shift and or operations.
9063+;
9064+(define_insn "shmrg1_ior"
9065+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9066+ (ior:SI
9067+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9068+ (const_int 8))
9069+ (zero_extend:SI
9070+ (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
9071+ (clobber (reg:CC CC_REGNO))]
9072+ ""
9073+ "shmrg.1\\t%0, %2, %1")
9074+
9075+; The combiner will generate this pattern given shift and add operations.
9076+; The canonical form that the combiner wants to use appears to be multiplies
9077+; instead of shifts even if the compiled sources use shifts.
9078+;
9079+(define_insn "shmrg2_add"
9080+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9081+ (plus:SI
9082+ (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9083+ (const_int 65536))
9084+ (zero_extend:SI
9085+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
9086+ (clobber (reg:CC CC_REGNO))]
9087+ ""
9088+ "shmrg.2\\t%0, %2, %1")
9089+
9090+; The combiner will generate this pattern given shift and or operations.
9091+;
9092+(define_insn "shmrg2_ior"
9093+ [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9094+ (ior:SI
9095+ (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9096+ (const_int 16))
9097+ (zero_extend:SI
9098+ (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
9099+ (clobber (reg:CC CC_REGNO))]
9100+ ""
9101+ "shmrg.2\\t%0, %2, %1")
9102+
9103+; Match the case where we load a word from the stack but then discard the
9104+; upper 16 bits. We turn this into a zero-extended load of that useful
9105+; 16 bits direct from the stack where possible.
9106+;
9107+
9108+; XXX - do these peephole2 ops actually work after the CCmode conversion?
9109+(define_peephole2
9110+ [(set (match_operand:SI 0 "register_operand" "")
9111+ (mem:SI (plus:SI (reg:SI SP_REGNO)
9112+ (match_operand:SI 1 "const_int_operand" ""))))
9113+ (set (match_operand:SI 2 "nonimmediate_operand" "")
9114+ (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
9115+ "(INTVAL (operands[1]) <= 252
9116+ && REGNO (operands[3]) == REGNO (operands[0])
9117+ && ((peep2_reg_dead_p (2, operands[0])
9118+ && ! reg_mentioned_p (operands[0], operands[2]))
9119+ || rtx_equal_p (operands[0], operands[2])))"
9120+ [(set (match_dup 2)
9121+ (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
9122+ (match_dup 4)))))]
9123+ "{
9124+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
9125+ }")
9126+
9127+; Match the case where we load a word from the stack but then discard the
9128+; upper 16 bits. We turn this into a 16-bit load of that useful
9129+; 16 bits direct from the stack where possible.
9130+;
9131+(define_peephole2
9132+ [(set (match_operand:SI 0 "register_operand" "")
9133+ (mem:SI (plus:SI (reg:SI SP_REGNO)
9134+ (match_operand:SI 1 "const_int_operand" ""))))
9135+ (set (match_operand:HI 2 "nonimmediate_operand" "")
9136+ (match_operand:HI 3 "register_operand" ""))]
9137+ "(INTVAL (operands[1]) <= 252
9138+ && REGNO (operands[3]) == REGNO (operands[0])
9139+ && ((peep2_reg_dead_p (2, operands[0])
9140+ && ! reg_mentioned_p (operands[0], operands[2]))
9141+ || rtx_equal_p (operands[0], operands[2])))"
9142+ [(set (match_dup 2)
9143+ (mem:HI (plus:SI (reg:SI SP_REGNO)
9144+ (match_dup 4))))]
9145+ "{
9146+ operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
9147+ }")
9148+
9149+; Match the case where we load a word from the stack but then discard the
9150+; upper 24 bits. We turn this into a zero-extended load of that useful
9151+; 8 bits direct from the stack where possible.
9152+;
9153+(define_peephole2
9154+ [(set (match_operand:SI 0 "register_operand" "")
9155+ (mem:SI (plus:SI (reg:SI SP_REGNO)
9156+ (match_operand:SI 1 "const_int_operand" ""))))
9157+ (set (match_operand:SI 2 "nonimmediate_operand" "")
9158+ (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
9159+ "(INTVAL (operands[1]) <= 124
9160+ && REGNO (operands[3]) == REGNO (operands[0])
9161+ && ((peep2_reg_dead_p (2, operands[0])
9162+ && ! reg_mentioned_p (operands[0], operands[2]))
9163+ || rtx_equal_p (operands[0], operands[2])))"
9164+ [(set (match_dup 2)
9165+ (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
9166+ (match_dup 4)))))]
9167+ "{
9168+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
9169+ }")
9170+
9171+; Match the case where we load a word from the stack but then discard the
9172+; upper 24 bits. We turn this into an 8-bit load of that useful
9173+; 8 bits direct from the stack where possible.
9174+;
9175+(define_peephole2
9176+ [(set (match_operand:SI 0 "register_operand" "")
9177+ (mem:SI (plus:SI (reg:SI SP_REGNO)
9178+ (match_operand:SI 1 "const_int_operand" ""))))
9179+ (set (match_operand:QI 2 "nonimmediate_operand" "")
9180+ (match_operand:QI 3 "register_operand" ""))]
9181+ "(INTVAL (operands[1]) <= 124
9182+ && REGNO (operands[3]) == REGNO (operands[0])
9183+ && ((peep2_reg_dead_p (2, operands[0])
9184+ && ! reg_mentioned_p (operands[0], operands[2]))
9185+ || rtx_equal_p (operands[0], operands[2])))"
9186+ [(set (match_dup 2)
9187+ (mem:QI (plus:SI (reg:SI SP_REGNO)
9188+ (match_dup 4))))]
9189+ "{
9190+ operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
9191+ }")
9192+
9193--- /dev/null
9194+++ b/gcc/config/ubicom32/ubicom32.opt
9195@@ -0,0 +1,27 @@
9196+mdebug-address
9197+Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
9198+Debug addresses
9199+
9200+mdebug-context
9201+Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
9202+Debug contexts
9203+
9204+march=
9205+Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
9206+Specify the name of the target architecture
9207+
9208+mfdpic
9209+Target Report Mask(FDPIC)
9210+Enable Function Descriptor PIC mode
9211+
9212+minline-plt
9213+Target Report Mask(INLINE_PLT)
9214+Enable inlining of PLT in function calls
9215+
9216+mfastcall
9217+Target Report Mask(FASTCALL)
9218+Enable default fast (call) calling sequence for smaller applications
9219+
9220+mipos-abi
9221+Target Report Mask(IPOS_ABI)
9222+Enable the ipOS ABI in which D10-D13 are caller-clobbered
9223--- /dev/null
9224+++ b/gcc/config/ubicom32/uclinux.h
9225@@ -0,0 +1,67 @@
9226+/* Definitions of target machine for Ubicom32-uclinux
9227+
9228+ Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
9229+ 2009 Free Software Foundation, Inc.
9230+ Contributed by Ubicom, Inc.
9231+
9232+ This file is part of GCC.
9233+
9234+ GCC is free software; you can redistribute it and/or modify it
9235+ under the terms of the GNU General Public License as published
9236+ by the Free Software Foundation; either version 3, or (at your
9237+ option) any later version.
9238+
9239+ GCC is distributed in the hope that it will be useful, but WITHOUT
9240+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9241+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
9242+ License for more details.
9243+
9244+ You should have received a copy of the GNU General Public License
9245+ along with GCC; see the file COPYING3. If not see
9246+ <http://www.gnu.org/licenses/>. */
9247+
9248+/* Don't assume anything about the header files. */
9249+#define NO_IMPLICIT_EXTERN_C
9250+
9251+#undef LIB_SPEC
9252+#define LIB_SPEC \
9253+ "%{pthread:-lpthread} " \
9254+ "%{!shared:%{!symbolic: -lc}} "
9255+
9256+
9257+#undef LINK_GCC_C_SEQUENCE_SPEC
9258+#define LINK_GCC_C_SEQUENCE_SPEC \
9259+ "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
9260+
9261+#undef STARTFILE_SPEC
9262+#define STARTFILE_SPEC \
9263+ "%{!shared: crt1%O%s}" \
9264+ " crti%O%s crtbegin%O%s"
9265+
9266+#undef ENDFILE_SPEC
9267+#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
9268+
9269+/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
9270+ we want to support both flat and ELF output. */
9271+#define OBJECT_FORMAT_FLAT
9272+
9273+#undef DRIVER_SELF_SPECS
9274+#define DRIVER_SELF_SPECS \
9275+ "%{!mno-fastcall:-mfastcall}"
9276+
9277+/* taken from linux.h */
9278+/* The GNU C++ standard library requires that these macros be defined. */
9279+#undef CPLUSPLUS_CPP_SPEC
9280+#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
9281+
9282+#define TARGET_OS_CPP_BUILTINS() \
9283+ do { \
9284+ builtin_define_std ("__UBICOM32__"); \
9285+ builtin_define_std ("__ubicom32__"); \
9286+ builtin_define ("__gnu_linux__"); \
9287+ builtin_define_std ("linux"); \
9288+ builtin_define_std ("unix"); \
9289+ builtin_assert ("system=linux"); \
9290+ builtin_assert ("system=unix"); \
9291+ builtin_assert ("system=posix"); \
9292+ } while (0)
9293--- /dev/null
9294+++ b/gcc/config/ubicom32/xm-ubicom32.h
9295@@ -0,0 +1,36 @@
9296+/* Configuration for Ubicom's Ubicom32 architecture.
9297+ Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
9298+ Foundation, Inc.
9299+ Contributed by Ubicom Inc.
9300+
9301+This file is part of GNU CC.
9302+
9303+GNU CC is free software; you can redistribute it and/or modify
9304+it under the terms of the GNU General Public License as published by
9305+the Free Software Foundation; either version 2, or (at your option)
9306+any later version.
9307+
9308+GNU CC is distributed in the hope that it will be useful,
9309+but WITHOUT ANY WARRANTY; without even the implied warranty of
9310+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9311+GNU General Public License for more details.
9312+
9313+You should have received a copy of the GNU General Public License
9314+along with GNU CC; see the file COPYING. If not, write to
9315+the Free Software Foundation, 59 Temple Place - Suite 330,
9316+Boston, MA 02111-1307, USA. */
9317+
9318+/* #defines that need visibility everywhere. */
9319+#define FALSE 0
9320+#define TRUE 1
9321+
9322+/* This describes the machine the compiler is hosted on. */
9323+#define HOST_BITS_PER_CHAR 8
9324+#define HOST_BITS_PER_SHORT 16
9325+#define HOST_BITS_PER_INT 32
9326+#define HOST_BITS_PER_LONG 32
9327+#define HOST_BITS_PER_LONGLONG 64
9328+
9329+/* Arguments to use with `exit'. */
9330+#define SUCCESS_EXIT_CODE 0
9331+#define FATAL_EXIT_CODE 33
9332--- a/gcc/config.gcc
9333+++ b/gcc/config.gcc
9334@@ -2314,6 +2314,34 @@ spu-*-elf*)
9335     c_target_objs="${c_target_objs} spu-c.o"
9336     cxx_target_objs="${cxx_target_objs} spu-c.o"
9337     ;;
9338+ubicom32-*-elf)
9339+ xm_file=ubicom32/xm-ubicom32.h
9340+ tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
9341+ tmake_file=ubicom32/t-ubicom32
9342+ ;;
9343+ubicom32-*-uclinux*)
9344+ xm_file=ubicom32/xm-ubicom32.h
9345+ tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
9346+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
9347+ extra_options="${extra_options} linux.opt"
9348+ tmake_file=ubicom32/t-ubicom32-uclinux
9349+ use_collect2=no
9350+ ;;
9351+ubicom32-*-linux-uclibc)
9352+ xm_file=ubicom32/xm-ubicom32.h
9353+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
9354+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
9355+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
9356+ use_collect2=no
9357+ ;;
9358+ubicom32-*-linux*)
9359+ xm_file=ubicom32/xm-ubicom32.h
9360+ tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
9361+ tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
9362+ tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
9363+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
9364+ use_collect2=no
9365+ ;;
9366 v850e1-*-*)
9367     target_cpu_default="TARGET_CPU_v850e1"
9368     tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
9369--- a/libgcc/config.host
9370+++ b/libgcc/config.host
9371@@ -551,6 +551,15 @@ sparc64-*-netbsd*)
9372     ;;
9373 spu-*-elf*)
9374     ;;
9375+ubicom32*-*-elf*)
9376+ ;;
9377+ubicom32*-*-uclinux*)
9378+ ;;
9379+ubicom32*-*-linux*)
9380+ # No need to build crtbeginT.o on uClibc systems. Should probably
9381+ # be moved to the OS specific section above.
9382+ extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
9383+ ;;
9384 v850e1-*-*)
9385     ;;
9386 v850e-*-*)
9387

Archive Download this file



interactive