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

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

Archive Download this file



interactive