3 @@ -283,6 +283,7 @@ case $basic_machine in
4 | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
6 | tahoe | thumb | tic4x | tic80 | tron \
11 @@ -367,6 +368,7 @@ case $basic_machine in
13 | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
16 | v850-* | v850e-* | vax-* \
21 @@ -2688,6 +2688,9 @@ case "${target}" in
23 noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
26 + noconfigdirs="$noconfigdirs target-libffi"
28 *-*-linux* | *-*-gnu* | *-*-k*bsd*-gnu | *-*-kopensolaris*-gnu)
29 noconfigdirs="$noconfigdirs target-newlib target-libgloss"
32 +++ b/gcc/config/ubicom32/constraints.md
34 +; Constraint definitions for Ubicom32
36 +; Copyright (C) 2009 Free Software Foundation, Inc.
37 +; Contributed by Ubicom, Inc.
39 +; This file is part of GCC.
41 +; GCC is free software; you can redistribute it and/or modify it
42 +; under the terms of the GNU General Public License as published
43 +; by the Free Software Foundation; either version 3, or (at your
44 +; option) any later version.
46 +; GCC is distributed in the hope that it will be useful, but WITHOUT
47 +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
48 +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
49 +; License for more details.
51 +; You should have received a copy of the GNU General Public License
52 +; along with GCC; see the file COPYING3. If not see
53 +; <http://www.gnu.org/licenses/>.
55 +(define_register_constraint "a" "ALL_ADDRESS_REGS"
58 +(define_register_constraint "d" "DATA_REGS"
61 +(define_register_constraint "h" "ACC_REGS"
62 + "An accumulator register.")
64 +(define_register_constraint "l" "ACC_LO_REGS"
65 + "An accn_lo register.")
67 +(define_register_constraint "Z" "FDPIC_REG"
68 + "The FD-PIC GOT pointer: A0.")
70 +(define_constraint "I"
71 + "An 8-bit signed constant value."
72 + (and (match_code "const_int")
73 + (match_test "(ival >= -128) && (ival <= 127)")))
75 +(define_constraint "Q"
76 + "An 8-bit signed constant value represented as unsigned."
77 + (and (match_code "const_int")
78 + (match_test "(ival >= 0x00) && (ival <= 0xff)")))
80 +(define_constraint "R"
81 + "An 8-bit signed constant value represented as unsigned."
82 + (and (match_code "const_int")
83 + (match_test "((ival >= 0x0000) && (ival <= 0x007f)) || ((ival >= 0xff80) && (ival <= 0xffff))")))
85 +(define_constraint "J"
86 + "A 7-bit unsigned constant value."
87 + (and (match_code "const_int")
88 + (match_test "(ival >= 0) && (ival <= 127)")))
90 +(define_constraint "K"
91 + "A 7-bit unsigned constant value shifted << 1."
92 + (and (match_code "const_int")
93 + (match_test "(ival >= 0) && (ival <= 254) && ((ival & 1) == 0)")))
95 +(define_constraint "L"
96 + "A 7-bit unsigned constant value shifted << 2."
97 + (and (match_code "const_int")
98 + (match_test "(ival >= 0) && (ival <= 508) && ((ival & 3) == 0)")))
100 +(define_constraint "M"
101 + "A 5-bit unsigned constant value."
102 + (and (match_code "const_int")
103 + (match_test "(ival >= 0) && (ival <= 31)")))
105 +(define_constraint "N"
106 + "A signed 16 bit constant value."
107 + (and (match_code "const_int")
108 + (match_test "(ival >= -32768) && (ival <= 32767)")))
110 +(define_constraint "O"
111 + "An exact bitmask of contiguous 1 bits starting at bit 0."
112 + (and (match_code "const_int")
113 + (match_test "exact_log2 (ival + 1) != -1")))
115 +(define_constraint "P"
116 + "A 7-bit negative constant value shifted << 2."
117 + (and (match_code "const_int")
118 + (match_test "(ival >= -504) && (ival <= 0) && ((ival & 3) == 0)")))
120 +(define_constraint "S"
121 + "A symbolic reference."
122 + (match_code "symbol_ref"))
124 +(define_constraint "Y"
125 + "An FD-PIC symbolic reference."
126 + (and (match_test "TARGET_FDPIC")
127 + (match_test "GET_CODE (op) == UNSPEC")
128 + (ior (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT")
129 + (match_test "XINT (op, 1) == UNSPEC_FDPIC_GOT_FUNCDESC"))))
131 +(define_memory_constraint "T1"
132 + "A memory operand that can be used for .1 instruction."
133 + (and (match_test "memory_operand (op, GET_MODE(op))")
134 + (match_test "GET_MODE (op) == QImode")))
136 +(define_memory_constraint "T2"
137 + "A memory operand that can be used for .2 instruction."
138 + (and (match_test "memory_operand (op, GET_MODE(op))")
139 + (match_test "GET_MODE (op) == HImode")))
141 +(define_memory_constraint "T4"
142 + "A memory operand that can be used for .4 instruction."
143 + (and (match_test "memory_operand (op, GET_MODE(op))")
144 + (ior (match_test "GET_MODE (op) == SImode")
145 + (match_test "GET_MODE (op) == DImode")
146 + (match_test "GET_MODE (op) == SFmode"))))
148 +(define_memory_constraint "U1"
149 + "An offsettable memory operand that can be used for .1 instruction."
150 + (and (match_test "memory_operand (op, GET_MODE(op))")
151 + (match_test "GET_MODE (op) == QImode")
152 + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
153 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
154 + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
155 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
156 + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
157 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
159 +(define_memory_constraint "U2"
160 + "An offsettable memory operand that can be used for .2 instruction."
161 + (and (match_test "memory_operand (op, GET_MODE(op))")
162 + (match_test "GET_MODE (op) == HImode")
163 + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
164 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
165 + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
166 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
167 + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
168 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
170 +(define_memory_constraint "U4"
171 + "An offsettable memory operand that can be used for .4 instruction."
172 + (and (match_test "memory_operand (op, GET_MODE(op))")
173 + (ior (match_test "GET_MODE (op) == SImode")
174 + (match_test "GET_MODE (op) == DImode")
175 + (match_test "GET_MODE (op) == SFmode"))
176 + (match_test "GET_CODE (XEXP (op, 0)) != POST_INC")
177 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_INC")
178 + (match_test "GET_CODE (XEXP (op, 0)) != POST_DEC")
179 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_DEC")
180 + (match_test "GET_CODE (XEXP (op, 0)) != POST_MODIFY")
181 + (match_test "GET_CODE (XEXP (op, 0)) != PRE_MODIFY")))
184 +++ b/gcc/config/ubicom32/crti.S
186 +/* Specialized code needed to support construction and destruction of
187 + file-scope objects in C++ and Java code, and to support exception handling.
188 + Copyright (C) 1999 Free Software Foundation, Inc.
189 + Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
191 +This file is part of GCC.
193 +GCC is free software; you can redistribute it and/or modify
194 +it under the terms of the GNU General Public License as published by
195 +the Free Software Foundation; either version 2, or (at your option)
198 +GCC is distributed in the hope that it will be useful,
199 +but WITHOUT ANY WARRANTY; without even the implied warranty of
200 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
201 +GNU General Public License for more details.
203 +You should have received a copy of the GNU General Public License
204 +along with GCC; see the file COPYING. If not, write to
205 +the Free Software Foundation, 59 Temple Place - Suite 330,
206 +Boston, MA 02111-1307, USA. */
208 +/* As a special exception, if you link this library with files
209 + compiled with GCC to produce an executable, this does not cause
210 + the resulting executable to be covered by the GNU General Public License.
211 + This exception does not however invalidate any other reasons why
212 + the executable file might be covered by the GNU General Public License. */
215 + * This file just supplies function prologues for the .init and .fini
216 + * sections. It is linked in before crtbegin.o.
219 + .ident "GNU C crti.o"
224 + .type _init, @function
226 + move.4 -4(sp)++, a5
227 +#ifdef __UBICOM32_FDPIC__
228 + move.4 -4(sp)++, a0
234 + .type _fini, @function
236 + move.4 -4(sp)++, a5
237 +#ifdef __UBICOM32_FDPIC__
238 + move.4 -4(sp)++, a0
241 +++ b/gcc/config/ubicom32/crtn.S
243 +/* Specialized code needed to support construction and destruction of
244 + file-scope objects in C++ and Java code, and to support exception handling.
245 + Copyright (C) 1999 Free Software Foundation, Inc.
246 + Contributed by Charles-Antoine Gauthier (charles.gauthier@iit.nrc.ca).
248 +This file is part of GCC.
250 +GCC is free software; you can redistribute it and/or modify
251 +it under the terms of the GNU General Public License as published by
252 +the Free Software Foundation; either version 2, or (at your option)
255 +GCC is distributed in the hope that it will be useful,
256 +but WITHOUT ANY WARRANTY; without even the implied warranty of
257 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
258 +GNU General Public License for more details.
260 +You should have received a copy of the GNU General Public License
261 +along with GCC; see the file COPYING. If not, write to
262 +the Free Software Foundation, 59 Temple Place - Suite 330,
263 +Boston, MA 02111-1307, USA. */
265 +/* As a special exception, if you link this library with files
266 + compiled with GCC to produce an executable, this does not cause
267 + the resulting executable to be covered by the GNU General Public License.
268 + This exception does not however invalidate any other reasons why
269 + the executable file might be covered by the GNU General Public License. */
272 + * This file supplies function epilogues for the .init and .fini sections.
273 + * It is linked in after all other files.
277 + .ident "GNU C crtn.o"
280 +#ifdef __UBICOM32_FDPIC__
286 +#ifdef __UBICOM32_FDPIC__
291 +++ b/gcc/config/ubicom32/elf.h
293 +#undef STARTFILE_SPEC
294 +#define STARTFILE_SPEC "\
295 +%{msim:%{!shared:crt0%O%s}} \
296 +crti%O%s crtbegin%O%s"
299 +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
301 +#ifdef __UBICOM32_FDPIC__
302 +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
303 + asm (SECTION_OP); \
304 + asm ("move.4 a0, 0(sp);\n\t" \
305 + "call a5," USER_LABEL_PREFIX #FUNC ";"); \
306 + asm (TEXT_SECTION_ASM_OP);
309 +#undef SUBTARGET_DRIVER_SELF_SPECS
310 +#define SUBTARGET_DRIVER_SELF_SPECS \
313 +#define NO_IMPLICIT_EXTERN_C
316 + * We need this to compile crtbegin/crtend. This should really be picked
317 + * up from elfos.h but at the moment including elfos.h causes other more
318 + * serous linker issues.
320 +#define INIT_SECTION_ASM_OP "\t.section\t.init"
321 +#define FINI_SECTION_ASM_OP "\t.section\t.fini"
323 +++ b/gcc/config/ubicom32/linux.h
325 +/* Definitions of target machine for Ubicom32-uclinux
327 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
328 + 2009 Free Software Foundation, Inc.
329 + Contributed by Ubicom, Inc.
331 + This file is part of GCC.
333 + GCC is free software; you can redistribute it and/or modify it
334 + under the terms of the GNU General Public License as published
335 + by the Free Software Foundation; either version 3, or (at your
336 + option) any later version.
338 + GCC is distributed in the hope that it will be useful, but WITHOUT
339 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
340 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
341 + License for more details.
343 + You should have received a copy of the GNU General Public License
344 + along with GCC; see the file COPYING3. If not see
345 + <http://www.gnu.org/licenses/>. */
347 +/* Don't assume anything about the header files. */
348 +#define NO_IMPLICIT_EXTERN_C
352 + "%{pthread:-lpthread} " \
355 +#undef LINK_GCC_C_SEQUENCE_SPEC
356 +#define LINK_GCC_C_SEQUENCE_SPEC \
357 + "%{static:--start-group} %G %L %{static:--end-group} " \
360 +#undef STARTFILE_SPEC
361 +#define STARTFILE_SPEC \
362 + "%{!shared: %{pg|p|profile:gcrt1%O%s;pie:Scrt1%O%s;:crt1%O%s}} " \
363 + "crtreloc%O%s crti%O%s %{shared|pie:crtbeginS%O%s;:crtbegin%O%s}"
366 +#define ENDFILE_SPEC \
367 + "%{shared|pie:crtendS%O%s;:crtend%O%s} crtn%O%s"
369 +/* taken from linux.h */
370 +/* The GNU C++ standard library requires that these macros be defined. */
371 +#undef CPLUSPLUS_CPP_SPEC
372 +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
374 +#define TARGET_OS_CPP_BUILTINS() \
376 + builtin_define_std ("__UBICOM32__"); \
377 + builtin_define_std ("__ubicom32__"); \
378 + builtin_define ("__gnu_linux__"); \
379 + builtin_define_std ("linux"); \
380 + builtin_define_std ("unix"); \
381 + builtin_assert ("system=linux"); \
382 + builtin_assert ("system=unix"); \
383 + builtin_assert ("system=posix"); \
386 +#define OBJECT_FORMAT_ELF
389 +#undef DRIVER_SELF_SPECS
390 +#define DRIVER_SELF_SPECS \
391 + "%{!mno-fdpic:-mfdpic}"
394 +#define LINK_SPEC "%{mfdpic: -m elf32ubicom32fdpic -z text } %{shared} %{pie} \
395 + %{static:-dn -Bstatic} \
396 + %{shared:-G -Bdynamic} \
397 + %{!shared: %{!static: \
398 + %{rdynamic:-export-dynamic} \
399 + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0}} \
403 +#define MD_UNWIND_SUPPORT "config/bfin/linux-unwind.h"
406 +++ b/gcc/config/ubicom32/predicates.md
408 +; Predicate definitions for Ubicom32.
410 +; Copyright (C) 2009 Free Software Foundation, Inc.
411 +; Contributed by Ubicom, Inc.
413 +; This file is part of GCC.
415 +; GCC is free software; you can redistribute it and/or modify it
416 +; under the terms of the GNU General Public License as published
417 +; by the Free Software Foundation; either version 3, or (at your
418 +; option) any later version.
420 +; GCC is distributed in the hope that it will be useful, but WITHOUT
421 +; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
422 +; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
423 +; License for more details.
425 +; You should have received a copy of the GNU General Public License
426 +; along with GCC; see the file COPYING3. If not see
427 +; <http://www.gnu.org/licenses/>.
429 +(define_predicate "ubicom32_move_operand"
430 + (match_code "const_int, const_double, const, mem, subreg, reg, lo_sum")
432 + if (CONST_INT_P (op))
435 + if (GET_CODE (op) == CONST_DOUBLE)
438 + if (GET_CODE (op) == CONST)
439 + return memory_address_p (mode, op);
441 + if (GET_MODE (op) != mode)
445 + return memory_address_p (mode, XEXP (op, 0));
447 + if (GET_CODE (op) == SUBREG) {
448 + op = SUBREG_REG (op);
456 + /* Paradoxical SUBREG. */
457 + if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (op)))
460 + return memory_address_p (GET_MODE (op), XEXP (op, 0));
463 + return register_operand (op, mode);
466 +;; Returns true if OP is either a symbol reference or a sum of a
467 +;; symbol reference and a constant.
469 +(define_predicate "ubicom32_symbolic_address_operand"
470 + (match_code "symbol_ref, label_ref, const")
472 + switch (GET_CODE (op))
480 + return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
481 + || GET_CODE (XEXP (op, 0)) == LABEL_REF)
482 + && CONST_INT_P (XEXP (op, 1)));
489 +;; Return true if operand is the uClinux FD-PIC register.
491 +(define_predicate "ubicom32_fdpic_operand"
494 + if (! TARGET_FDPIC)
500 + if (GET_MODE (op) != mode && mode != VOIDmode)
503 + if (REGNO (op) != FDPIC_REGNUM && REGNO (op) < FIRST_PSEUDO_REGISTER)
509 +(define_predicate "ubicom32_fdpic_got_offset_operand"
510 + (match_code "unspec")
512 + if (! TARGET_FDPIC)
515 + if (GET_CODE (op) != UNSPEC)
518 + if (XINT (op, 1) != UNSPEC_FDPIC_GOT
519 + && XINT (op, 1) != UNSPEC_FDPIC_GOT_FUNCDESC)
525 +(define_predicate "ubicom32_arith_operand"
526 + (match_code "subreg, reg, const_int, lo_sum, mem")
528 + return (ubicom32_move_operand (op, mode)
529 + && ! ubicom32_symbolic_address_operand (op, mode)
530 + && (! CONST_INT_P (op)
531 + || satisfies_constraint_I (op)));
534 +(define_predicate "ubicom32_arith_operand_dot1"
535 + (match_code "subreg, reg, const_int, lo_sum, mem")
537 + return (ubicom32_move_operand (op, mode)
538 + && ! ubicom32_symbolic_address_operand (op, mode)
539 + && (! CONST_INT_P (op)
540 + || satisfies_constraint_Q (op)));
543 +(define_predicate "ubicom32_arith_operand_dot2"
544 + (match_code "subreg, reg, const_int, lo_sum, mem")
546 + return (ubicom32_move_operand (op, mode)
547 + && ! ubicom32_symbolic_address_operand (op, mode)
548 + && (! CONST_INT_P (op)
549 + || satisfies_constraint_R (op)));
552 +(define_predicate "ubicom32_compare_operand"
553 + (match_code "subreg, reg, const_int, lo_sum, mem")
555 + return (ubicom32_move_operand (op, mode)
556 + && ! ubicom32_symbolic_address_operand (op, mode)
557 + && (! CONST_INT_P (op)
558 + || satisfies_constraint_N (op)));
561 +(define_predicate "ubicom32_compare_operator"
562 + (match_code "compare"))
564 +(define_predicate "ubicom32_and_or_si3_operand"
565 + (match_code "subreg, reg, const_int, lo_sum, mem")
567 + return (ubicom32_arith_operand (op, mode)
568 + || (CONST_INT_P (op)
569 + && ((exact_log2 (INTVAL (op) + 1) != -1
570 + && exact_log2 (INTVAL (op) + 1) <= 31)
571 + || (exact_log2 (INTVAL (op)) != -1
572 + && exact_log2 (INTVAL (op)) <= 31)
573 + || (exact_log2 (~INTVAL (op)) != -1
574 + && exact_log2 (~INTVAL (op)) <= 31))));
577 +(define_predicate "ubicom32_and_or_hi3_operand"
578 + (match_code "subreg, reg, const_int, lo_sum, mem")
580 + return (ubicom32_arith_operand (op, mode)
581 + || (CONST_INT_P (op)
582 + && exact_log2 (INTVAL (op) + 1) != -1
583 + && exact_log2 (INTVAL (op) + 1) <= 15));
586 +(define_predicate "ubicom32_mem_or_address_register_operand"
587 + (match_code "subreg, reg, mem")
589 + unsigned int regno;
592 + && memory_operand (op, mode))
596 + regno = REGNO (op);
597 + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
600 + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
601 + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
603 + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
604 + GET_MODE (SUBREG_REG (op)),
607 + regno = REGNO (SUBREG_REG (op)) + offset;
612 + return (regno >= FIRST_PSEUDO_REGISTER
613 + || REGNO_REG_CLASS (regno) == FDPIC_REG
614 + || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
617 +(define_predicate "ubicom32_data_register_operand"
618 + (match_code "subreg, reg")
620 + unsigned int regno;
623 + regno = REGNO (op);
624 + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
627 + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
628 + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
630 + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
631 + GET_MODE (SUBREG_REG (op)),
634 + regno = REGNO (SUBREG_REG (op)) + offset;
639 + return ((regno >= FIRST_PSEUDO_REGISTER
640 + && regno != REGNO (virtual_stack_vars_rtx))
641 + || REGNO_REG_CLASS (regno) == DATA_REGS);
644 +(define_predicate "ubicom32_address_register_operand"
645 + (match_code "subreg, reg")
647 + unsigned int regno;
650 + regno = REGNO (op);
651 + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
654 + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
655 + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
657 + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
658 + GET_MODE (SUBREG_REG (op)),
661 + regno = REGNO (SUBREG_REG (op)) + offset;
666 + return (regno >= FIRST_PSEUDO_REGISTER
667 + || REGNO_REG_CLASS (regno) == FDPIC_REG
668 + || REGNO_REG_CLASS (regno) == ADDRESS_REGS);
671 +(define_predicate "ubicom32_acc_lo_register_operand"
672 + (match_code "subreg, reg")
674 + unsigned int regno;
677 + regno = REGNO (op);
678 + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
681 + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
682 + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
684 + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
685 + GET_MODE (SUBREG_REG (op)),
688 + regno = REGNO (SUBREG_REG (op)) + offset;
693 + return ((regno >= FIRST_PSEUDO_REGISTER
694 + && regno != REGNO (virtual_stack_vars_rtx))
695 + || REGNO_REG_CLASS (regno) == ACC_LO_REGS);
698 +(define_predicate "ubicom32_acc_hi_register_operand"
699 + (match_code "subreg, reg")
701 + unsigned int regno;
704 + regno = REGNO (op);
705 + else if (GET_CODE (op) == SUBREG && REG_P (SUBREG_REG (op)))
708 + if (REGNO (SUBREG_REG (op)) >= FIRST_PSEUDO_REGISTER)
709 + offset = SUBREG_BYTE (op) / (GET_MODE_SIZE (GET_MODE (op)));
711 + offset = subreg_regno_offset (REGNO (SUBREG_REG (op)),
712 + GET_MODE (SUBREG_REG (op)),
715 + regno = REGNO (SUBREG_REG (op)) + offset;
720 + return ((regno >= FIRST_PSEUDO_REGISTER
721 + && regno != REGNO (virtual_stack_vars_rtx))
722 + || REGNO_REG_CLASS (regno) == ACC_REGS);
725 +(define_predicate "ubicom32_call_address_operand"
726 + (match_code "symbol_ref, subreg, reg")
728 + return (GET_CODE (op) == SYMBOL_REF || REG_P (op));
731 +(define_special_predicate "ubicom32_cc_register_operand"
732 + (and (match_code "reg")
733 + (match_test "REGNO (op) == CC_REGNUM")))
736 +++ b/gcc/config/ubicom32/t-ubicom32
738 +# Name of assembly file containing libgcc1 functions.
739 +# This entry must be present, but it can be empty if the target does
740 +# not need any assembler functions to support its code generation.
743 +# Alternatively if assembler functions *are* needed then define the
745 +# CROSS_LIBGCC1 = libgcc1-asm.a
748 + $(srcdir)/config/udivmodsi4.c \
749 + $(srcdir)/config/divmod.c \
750 + $(srcdir)/config/udivmod.c
752 +# If any special flags are necessary when building libgcc2 put them here.
754 +# TARGET_LIBGCC2_CFLAGS =
756 +# We want fine grained libraries, so use the new code to build the
757 +# floating point emulation libraries.
761 +fp-bit.c: $(srcdir)/config/fp-bit.c
762 + echo '#define FLOAT' > fp-bit.c
763 + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
765 +dp-bit.c: $(srcdir)/config/fp-bit.c
766 + cat $(srcdir)/config/fp-bit.c > dp-bit.c
768 +# Commented out to speed up compiler development!
770 +# MULTILIB_OPTIONS = march=ubicom32v1/march=ubicom32v2/march=ubicom32v3/march=ubicom32v4
771 +# MULTILIB_DIRNAMES = ubicom32v1 ubicom32v2 ubicom32v3 ubicom32v4
773 +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
774 +MULTILIB_OPTIONS += mfdpic
775 +MULTILIB_OPTIONS += mno-ipos-abi/mipos-abi
776 +MULTILIB_OPTIONS += fno-leading-underscore/fleading-underscore
778 +# Assemble startup files.
779 +$(T)crti.o: $(srcdir)/config/ubicom32/crti.S $(GCC_PASSES)
780 + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
781 + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crti.S
783 +$(T)crtn.o: $(srcdir)/config/ubicom32/crtn.S $(GCC_PASSES)
784 + $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
785 + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/ubicom32/crtn.S
787 +# these parts are required because uClibc ldso needs them to link.
788 +# they are not in the specfile so they will not be included automatically.
789 +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o crti.o crtn.o
791 +++ b/gcc/config/ubicom32/t-ubicom32-linux
793 +# Name of assembly file containing libgcc1 functions.
794 +# This entry must be present, but it can be empty if the target does
795 +# not need any assembler functions to support its code generation.
798 +# Alternatively if assembler functions *are* needed then define the
800 +# CROSS_LIBGCC1 = libgcc1-asm.a
803 + $(srcdir)/config/udivmodsi4.c \
804 + $(srcdir)/config/divmod.c \
805 + $(srcdir)/config/udivmod.c
807 +# If any special flags are necessary when building libgcc2 put them here.
809 +# TARGET_LIBGCC2_CFLAGS =
811 +# We want fine grained libraries, so use the new code to build the
812 +# floating point emulation libraries.
816 +fp-bit.c: $(srcdir)/config/fp-bit.c
817 + echo '#define FLOAT' > fp-bit.c
818 + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
820 +dp-bit.c: $(srcdir)/config/fp-bit.c
821 + cat $(srcdir)/config/fp-bit.c > dp-bit.c
823 +# We only support v3 and v4 ISAs for uClinux.
825 +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
827 +#EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o crtbeginS.o crtendS.o
829 +++ b/gcc/config/ubicom32/t-ubicom32-uclinux
831 +# Name of assembly file containing libgcc1 functions.
832 +# This entry must be present, but it can be empty if the target does
833 +# not need any assembler functions to support its code generation.
836 +# Alternatively if assembler functions *are* needed then define the
838 +# CROSS_LIBGCC1 = libgcc1-asm.a
841 + $(srcdir)/config/udivmodsi4.c \
842 + $(srcdir)/config/divmod.c \
843 + $(srcdir)/config/udivmod.c
845 +# If any special flags are necessary when building libgcc2 put them here.
847 +# TARGET_LIBGCC2_CFLAGS =
849 +# We want fine grained libraries, so use the new code to build the
850 +# floating point emulation libraries.
854 +fp-bit.c: $(srcdir)/config/fp-bit.c
855 + echo '#define FLOAT' > fp-bit.c
856 + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
858 +dp-bit.c: $(srcdir)/config/fp-bit.c
859 + cat $(srcdir)/config/fp-bit.c > dp-bit.c
861 +# We only support v3 and v4 ISAs for uClinux.
863 +MULTILIB_OPTIONS = march=ubicom32v3/march=ubicom32v4
865 +EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o # crtbeginS.o crtendS.o
867 +++ b/gcc/config/ubicom32/ubicom32-modes.def
869 +/* Definitions of target machine for GNU compiler, Ubicom32 architecture.
870 + Copyright (C) 2009 Free Software Foundation, Inc.
871 + Contributed by Ubicom, Inc.
873 + This file is part of GCC.
875 + GCC is free software; you can redistribute it and/or modify it
876 + under the terms of the GNU General Public License as published
877 + by the Free Software Foundation; either version 3, or (at your
878 + option) any later version.
880 + GCC is distributed in the hope that it will be useful, but WITHOUT
881 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
882 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
883 + License for more details.
885 + You should have received a copy of the GNU General Public License
886 + along with GCC; see the file COPYING3. If not see
887 + <http://www.gnu.org/licenses/>. */
889 +/* Some insns set all condition code flags, some only set the Z and N flags, and
890 + some only set the Z flag. */
900 +++ b/gcc/config/ubicom32/ubicom32-protos.h
902 +/* Function prototypes for Ubicom IP3000.
904 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
905 + 2009 Free Software Foundation, Inc.
906 + Contributed by Ubicom, Inc.
908 + This file is part of GNU CC.
910 + GNU CC is free software; you can redistribute it and/or modify it under
911 + the terms of the GNU General Public License as published by the Free
912 + Software Foundation; either version 2, or (at your option) any later
915 + GNU CC is distributed in the hope that it will be useful, but WITHOUT
916 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
917 + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
920 + You should have received a copy of the GNU General Public License along
921 + with GNU CC; see the file COPYING. If not, write to the Free Software
922 + Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
927 +extern void ubicom32_va_start (tree, rtx);
928 +#endif /* TREE_CODE */
930 +extern void ubicom32_print_operand (FILE *, rtx, int);
931 +extern void ubicom32_print_operand_address (FILE *, rtx);
933 +extern void ubicom32_conditional_register_usage (void);
934 +extern enum reg_class ubicom32_preferred_reload_class (rtx, enum reg_class);
935 +extern int ubicom32_regno_ok_for_index_p (int, int);
936 +extern void ubicom32_expand_movsi (rtx *);
937 +extern void ubicom32_expand_addsi3 (rtx *);
938 +extern int ubicom32_emit_mult_sequence (rtx *);
939 +extern void ubicom32_emit_move_const_int (rtx, rtx);
940 +extern bool ubicom32_legitimate_constant_p (rtx);
941 +extern bool ubicom32_legitimate_address_p (enum machine_mode, rtx, int);
942 +extern rtx ubicom32_legitimize_address (rtx, rtx, enum machine_mode);
943 +extern rtx ubicom32_legitimize_reload_address (rtx, enum machine_mode, int, int);
944 +extern void ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1);
945 +extern int ubicom32_mode_dependent_address_p (rtx);
946 +extern void ubicom32_output_cond_jump (rtx, rtx, rtx);
947 +extern void ubicom32_expand_eh_return (rtx *);
948 +extern void ubicom32_expand_call_fdpic (rtx *);
949 +extern void ubicom32_expand_call_value_fdpic (rtx *);
950 +extern enum machine_mode ubicom32_select_cc_mode (RTX_CODE, rtx, rtx);
951 +extern rtx ubicom32_gen_compare_reg (RTX_CODE, rtx, rtx);
952 +extern int ubicom32_shiftable_const_int (int);
953 +#endif /* RTX_CODE */
956 +extern void init_cumulative_args (CUMULATIVE_ARGS *cum,
958 + struct rtx_def *libname,
960 +extern struct rtx_def *function_arg (CUMULATIVE_ARGS *,
961 + enum machine_mode, tree, int);
962 +extern struct rtx_def *function_incoming_arg (CUMULATIVE_ARGS *,
965 +extern int function_arg_partial_nregs (CUMULATIVE_ARGS *,
966 + enum machine_mode, tree, int);
967 +extern struct rtx_def *ubicom32_va_arg (tree, tree);
968 +extern int ubicom32_reg_parm_stack_space (tree);
969 +#endif /* TREE_CODE */
971 +extern struct rtx_def * ubicom32_builtin_saveregs (void);
972 +extern void asm_file_start (FILE *);
973 +extern void ubicom32_expand_prologue (void);
974 +extern void ubicom32_expand_epilogue (void);
975 +extern int ubicom32_initial_elimination_offset (int, int);
976 +extern int ubicom32_regno_ok_for_base_p (int, int);
977 +extern bool ubicom32_hard_regno_mode_ok (unsigned int, enum machine_mode);
978 +extern int ubicom32_can_use_return_insn_p (void);
979 +extern rtx ubicom32_return_addr_rtx (int, rtx);
980 +extern void ubicom32_optimization_options (int, int);
981 +extern void ubicom32_override_options (void);
982 +extern bool ubicom32_match_cc_mode (rtx, enum machine_mode);
984 +extern int ubicom32_reorg_completed;
987 +++ b/gcc/config/ubicom32/ubicom32.c
989 +/* Subroutines for insn-output.c for Ubicom32
991 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
992 + 2009 Free Software Foundation, Inc.
993 + Contributed by Ubicom, Inc.
995 + This file is part of GCC.
997 + GCC is free software; you can redistribute it and/or modify it
998 + under the terms of the GNU General Public License as published
999 + by the Free Software Foundation; either version 3, or (at your
1000 + option) any later version.
1002 + GCC is distributed in the hope that it will be useful, but WITHOUT
1003 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
1004 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
1005 + License for more details.
1007 + You should have received a copy of the GNU General Public License
1008 + along with GCC; see the file COPYING3. If not see
1009 + <http://www.gnu.org/licenses/>. */
1011 +#include "config.h"
1012 +#include "system.h"
1013 +#include "coretypes.h"
1018 +#include "hard-reg-set.h"
1020 +#include "insn-config.h"
1021 +#include "conditions.h"
1022 +#include "insn-flags.h"
1023 +#include "output.h"
1024 +#include "insn-attr.h"
1025 +#include "insn-codes.h"
1029 +#include "function.h"
1030 +#include "obstack.h"
1031 +#include "toplev.h"
1033 +#include "tm-constrs.h"
1034 +#include "basic-block.h"
1035 +#include "integrate.h"
1036 +#include "target.h"
1037 +#include "target-def.h"
1038 +#include "reload.h"
1040 +#include "langhooks.h"
1041 +#include "optabs.h"
1043 +static tree ubicom32_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
1044 +static void ubicom32_layout_frame (void);
1045 +static void ubicom32_function_prologue (FILE *, HOST_WIDE_INT);
1046 +static void ubicom32_function_epilogue (FILE *, HOST_WIDE_INT);
1047 +static bool ubicom32_rtx_costs (rtx, int, int, int *, bool speed);
1048 +static bool ubicom32_fixed_condition_code_regs (unsigned int *,
1050 +static enum machine_mode ubicom32_cc_modes_compatible (enum machine_mode,
1051 + enum machine_mode);
1052 +static int ubicom32_naked_function_p (void);
1053 +static void ubicom32_machine_dependent_reorg (void);
1054 +static bool ubicom32_assemble_integer (rtx, unsigned int, int);
1055 +static void ubicom32_asm_init_sections (void);
1056 +static int ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,tree,
1058 +static bool ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1059 + enum machine_mode mode, const_tree type,
1060 + bool named ATTRIBUTE_UNUSED);
1061 +static bool ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
1062 + enum machine_mode mode, const_tree type,
1063 + bool named ATTRIBUTE_UNUSED);
1065 +static bool ubicom32_return_in_memory (const_tree type,
1066 + const_tree fntype ATTRIBUTE_UNUSED);
1067 +static bool ubicom32_is_base_reg (rtx, int);
1068 +static void ubicom32_init_builtins (void);
1069 +static rtx ubicom32_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
1070 +static tree ubicom32_fold_builtin (tree, tree, bool);
1071 +static int ubicom32_get_valid_offset_mask (enum machine_mode);
1072 +static bool ubicom32_cannot_force_const_mem (rtx);
1074 +/* Case values threshold */
1075 +int ubicom32_case_values_threshold = 6;
1077 +/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
1078 +int ubicom32_v3 = 1;
1080 +/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
1081 +int ubicom32_v4 = 1;
1083 +/* Valid attributes:
1084 + naked - don't generate function prologue/epilogue and `ret' command. */
1085 +const struct attribute_spec ubicom32_attribute_table[] =
1087 + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
1088 + { "naked", 0, 0, true, false, false, ubicom32_handle_fndecl_attribute },
1089 + { NULL, 0, 0, false, false, false, NULL }
1092 +#undef TARGET_ASM_FUNCTION_PROLOGUE
1093 +#define TARGET_ASM_FUNCTION_PROLOGUE ubicom32_function_prologue
1095 +#undef TARGET_ASM_FUNCTION_EPILOGUE
1096 +#define TARGET_ASM_FUNCTION_EPILOGUE ubicom32_function_epilogue
1098 +#undef TARGET_ATTRIBUTE_TABLE
1099 +#define TARGET_ATTRIBUTE_TABLE ubicom32_attribute_table
1101 +/* All addresses cost the same amount. */
1102 +#undef TARGET_ADDRESS_COST
1103 +#define TARGET_ADDRESS_COST hook_int_rtx_bool_0
1105 +#undef TARGET_RTX_COSTS
1106 +#define TARGET_RTX_COSTS ubicom32_rtx_costs
1108 +#undef TARGET_FIXED_CONDITION_CODE_REGS
1109 +#define TARGET_FIXED_CONDITION_CODE_REGS ubicom32_fixed_condition_code_regs
1111 +#undef TARGET_CC_MODES_COMPATIBLE
1112 +#define TARGET_CC_MODES_COMPATIBLE ubicom32_cc_modes_compatible
1114 +#undef TARGET_MACHINE_DEPENDENT_REORG
1115 +#define TARGET_MACHINE_DEPENDENT_REORG ubicom32_machine_dependent_reorg
1117 +#undef TARGET_ASM_INTEGER
1118 +#define TARGET_ASM_INTEGER ubicom32_assemble_integer
1120 +#undef TARGET_ASM_INIT_SECTIONS
1121 +#define TARGET_ASM_INIT_SECTIONS ubicom32_asm_init_sections
1123 +#undef TARGET_ARG_PARTIAL_BYTES
1124 +#define TARGET_ARG_PARTIAL_BYTES ubicom32_arg_partial_bytes
1126 +#undef TARGET_PASS_BY_REFERENCE
1127 +#define TARGET_PASS_BY_REFERENCE ubicom32_pass_by_reference
1129 +#undef TARGET_CALLEE_COPIES
1130 +#define TARGET_CALLEE_COPIES ubicom32_callee_copies
1132 +#undef TARGET_RETURN_IN_MEMORY
1133 +#define TARGET_RETURN_IN_MEMORY ubicom32_return_in_memory
1135 +#undef TARGET_INIT_BUILTINS
1136 +#define TARGET_INIT_BUILTINS ubicom32_init_builtins
1138 +#undef TARGET_EXPAND_BUILTIN
1139 +#define TARGET_EXPAND_BUILTIN ubicom32_expand_builtin
1141 +#undef TARGET_FOLD_BUILTIN
1142 +#define TARGET_FOLD_BUILTIN ubicom32_fold_builtin
1144 +#undef TARGET_CANNOT_FORCE_CONST_MEM
1145 +#define TARGET_CANNOT_FORCE_CONST_MEM ubicom32_cannot_force_const_mem
1147 +struct gcc_target targetm = TARGET_INITIALIZER;
1149 +static char save_regs[FIRST_PSEUDO_REGISTER];
1151 +static int frame_size;
1152 +int ubicom32_stack_size = 0; /* size of allocated stack (including frame) */
1153 +int ubicom32_can_use_calli_to_ret;
1155 +#define STACK_UNIT_BOUNDARY (STACK_BOUNDARY / BITS_PER_UNIT)
1156 +#define ROUND_CALL_BLOCK_SIZE(BYTES) \
1157 + (((BYTES) + (STACK_UNIT_BOUNDARY - 1)) & ~(STACK_UNIT_BOUNDARY - 1))
1159 +/* In case of a PRE_INC, POST_INC, PRE_DEC, POST_DEC memory reference, we
1160 + must report the mode of the memory reference from PRINT_OPERAND to
1161 + PRINT_OPERAND_ADDRESS. */
1162 +enum machine_mode output_memory_reference_mode;
1164 +/* Flag for some split insns from the ubicom32.md. */
1165 +int ubicom32_reorg_completed;
1167 +enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER] =
1199 + NO_REGS, /* CC_REG must be NO_REGS */
1210 +rtx ubicom32_compare_op0;
1211 +rtx ubicom32_compare_op1;
1213 +/* Handle command line option overrides. */
1216 +ubicom32_override_options (void)
1220 + if (strcmp (ubicom32_arch_name, "ubicom32v1") == 0) {
1221 + /* If we have a version 1 architecture then we want to avoid using jump
1223 + ubicom32_case_values_threshold = 30000;
1226 + } else if (strcmp (ubicom32_arch_name, "ubicom32v2") == 0) {
1229 + } else if (strcmp (ubicom32_arch_name, "ubicom32v3") == 0) {
1232 + } else if (strcmp (ubicom32_arch_name, "ubicom32v4") == 0) {
1237 + /* There is no single unaligned SI op for PIC code. Sometimes we
1238 + need to use ".4byte" and sometimes we need to use ".picptr".
1239 + See ubicom32_assemble_integer for details. */
1241 + targetm.asm_out.unaligned_op.si = 0;
1245 +ubicom32_conditional_register_usage (void)
1247 + /* If we're using the old ipOS ABI we need to make D10 through D13
1248 + caller-clobbered. */
1249 + if (TARGET_IPOS_ABI)
1251 + call_used_regs[D10_REGNUM] = 1;
1252 + call_used_regs[D11_REGNUM] = 1;
1253 + call_used_regs[D12_REGNUM] = 1;
1254 + call_used_regs[D13_REGNUM] = 1;
1258 +/* We have some number of optimizations that don't really work for the Ubicom32
1259 + architecture so we deal with them here. */
1262 +ubicom32_optimization_options (int level ATTRIBUTE_UNUSED,
1263 + int size ATTRIBUTE_UNUSED)
1265 + /* The tree IVOPTs pass seems to do really bad things for the Ubicom32
1266 + architecture - it tends to turn things that would happily use pre/post
1267 + increment/decrement into operations involving unecessary loop
1271 + /* We have problems where DSE at the RTL level misses partial stores
1272 + to the stack. For now we disable it to avoid this. */
1276 +/* Print operand X using operand code CODE to assembly language output file
1280 +ubicom32_print_operand (FILE *file, rtx x, int code)
1285 + /* Identify the correct accumulator to use. */
1286 + if (REGNO (x) == ACC0_HI_REGNUM || REGNO (x) == ACC0_LO_REGNUM)
1287 + fprintf (file, "acc0");
1288 + else if (REGNO (x) == ACC1_HI_REGNUM || REGNO (x) == ACC1_LO_REGNUM)
1289 + fprintf (file, "acc1");
1297 + enum machine_mode mode;
1299 + mode = GET_MODE (XEXP (x, 0));
1301 + /* These are normal and reversed branches. */
1302 + switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
1305 + fprintf (file, "ne");
1309 + fprintf (file, "eq");
1313 + if (mode == CCSZNmode || mode == CCWZNmode)
1314 + fprintf (file, "pl");
1316 + fprintf (file, "ge");
1320 + fprintf (file, "gt");
1324 + fprintf (file, "le");
1328 + if (mode == CCSZNmode || mode == CCWZNmode)
1329 + fprintf (file, "mi");
1331 + fprintf (file, "lt");
1335 + fprintf (file, "cs");
1339 + fprintf (file, "hi");
1343 + fprintf (file, "ls");
1347 + fprintf (file, "cc");
1357 + /* This is used for the operand to a call instruction;
1358 + if it's a REG, enclose it in parens, else output
1359 + the operand normally. */
1362 + fputc ('(', file);
1363 + ubicom32_print_operand (file, x, 0);
1364 + fputc (')', file);
1367 + ubicom32_print_operand (file, x, 0);
1371 + /* Bit operations we need bit numbers. */
1372 + fprintf (file, "%d", exact_log2 (INTVAL (x)));
1376 + /* Bit operations we need bit numbers. */
1377 + fprintf (file, "%d", exact_log2 (~ INTVAL (x)));
1381 + /* For lea, which we use to add address registers.
1382 + We don't want the '#' on a constant. */
1383 + if (CONST_INT_P (x))
1385 + fprintf (file, "%ld", INTVAL (x));
1388 + /* FALL THROUGH */
1391 + switch (GET_CODE (x))
1394 + output_memory_reference_mode = GET_MODE (x);
1395 + output_address (XEXP (x, 0));
1399 + output_address (x);
1403 + fprintf (file, "%s", reg_names[REGNO (x)]);
1407 + fprintf (file, "%s", reg_names[subreg_regno (x)]);
1410 + /* This will only be single precision.... */
1411 + case CONST_DOUBLE:
1413 + unsigned long val;
1414 + REAL_VALUE_TYPE rv;
1416 + REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1417 + REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1418 + fprintf (file, "0x%lx", val);
1428 + ubicom32_print_operand_address (file, x);
1432 + fprintf (file, "#%%hi(");
1433 + ubicom32_print_operand_address (file, XEXP (x, 0));
1434 + fprintf (file, ")");
1438 + switch (XINT (x, 1))
1440 + case UNSPEC_FDPIC_GOT:
1441 + fprintf (file, "#%%got_lo(");
1442 + ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1443 + fprintf (file, ")");
1446 + case UNSPEC_FDPIC_GOT_FUNCDESC:
1447 + fprintf (file, "#%%got_funcdesc_lo(");
1448 + ubicom32_print_operand_address (file, XVECEXP (x, 0, 0));
1449 + fprintf (file, ")");
1464 +/* Output assembly language output for the address ADDR to FILE. */
1467 +ubicom32_print_operand_address (FILE *file, rtx addr)
1469 + switch (GET_CODE (addr))
1472 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1473 + fprintf (file, "%d++", GET_MODE_SIZE (output_memory_reference_mode));
1477 + fprintf (file, "%d", GET_MODE_SIZE (output_memory_reference_mode));
1478 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1479 + fprintf (file, "++");
1483 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1484 + fprintf (file, "%d++", -GET_MODE_SIZE (output_memory_reference_mode));
1488 + fprintf (file, "%d", -GET_MODE_SIZE (output_memory_reference_mode));
1489 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1490 + fprintf (file, "++");
1494 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1495 + fprintf (file, "%ld++", INTVAL (XEXP (XEXP (addr,1), 1)));
1499 + fprintf (file, "%ld", INTVAL (XEXP (XEXP (addr,1), 1)));
1500 + ubicom32_print_operand_address (file, XEXP (addr, 0));
1501 + fprintf (file, "++");
1505 + fputc ('(', file);
1506 + fprintf (file, "%s", reg_names[REGNO (addr)]);
1507 + fputc (')', file);
1512 + rtx base = XEXP (addr, 0);
1513 + rtx index = XEXP (addr, 1);
1515 + /* Switch around addresses of the form index * scaling + base. */
1516 + if (! ubicom32_is_base_reg (base, 1))
1523 + if (CONST_INT_P (index))
1525 + fprintf (file, "%ld", INTVAL (index));
1526 + fputc ('(', file);
1527 + fputs (reg_names[REGNO (base)], file);
1529 + else if (GET_CODE (index) == MULT
1532 + if (GET_CODE (index) == MULT)
1533 + index = XEXP (index, 0);
1534 + fputc ('(', file);
1535 + fputs (reg_names[REGNO (base)], file);
1536 + fputc (',', file);
1537 + fputs (reg_names[REGNO (index)], file);
1542 + fputc (')', file);
1547 + fprintf (file, "%%lo(");
1548 + ubicom32_print_operand (file, XEXP (addr, 1), 'L');
1549 + fprintf (file, ")(");
1550 + ubicom32_print_operand (file, XEXP (addr, 0), 0);
1551 + fprintf (file, ")");
1555 + fputc ('#', file);
1556 + output_addr_const (file, addr);
1560 + output_addr_const (file, addr);
1565 +/* X and Y are two things to compare using CODE. Emit the compare insn and
1566 + return the rtx for the cc reg in the proper mode. */
1569 +ubicom32_gen_compare_reg (enum rtx_code code, rtx x, rtx y)
1571 + enum machine_mode mode = SELECT_CC_MODE (code, x, y);
1574 + cc_reg = gen_rtx_REG (mode, CC_REGNUM);
1576 + emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
1577 + gen_rtx_COMPARE (mode, x, y)));
1582 +/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1583 + return the mode to be used for the comparison. */
1586 +ubicom32_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1588 + /* Is this a short compare? */
1589 + if (GET_MODE (x) == QImode
1590 + || GET_MODE (x) == HImode
1591 + || GET_MODE (y) == QImode
1592 + || GET_MODE (y) == HImode)
1602 + if (y == const0_rtx)
1610 + /* We have a word compare. */
1619 + if (y == const0_rtx)
1627 +/* Return TRUE or FALSE depending on whether the first SET in INSN
1628 + has source and destination with matching CC modes, and that the
1629 + CC mode is at least as constrained as REQ_MODE. */
1631 +ubicom32_match_cc_mode (rtx insn, enum machine_mode req_mode)
1634 + enum machine_mode set_mode;
1636 + set = PATTERN (insn);
1637 + if (GET_CODE (set) == PARALLEL)
1638 + set = XVECEXP (set, 0, 0);
1639 + gcc_assert (GET_CODE (set) == SET);
1640 + gcc_assert (GET_CODE (SET_SRC (set)) == COMPARE);
1642 + /* SET_MODE is the mode we have in the instruction. This must either
1643 + be the same or less restrictive that the required mode REQ_MODE. */
1644 + set_mode = GET_MODE (SET_DEST (set));
1649 + if (set_mode != CCSZmode)
1654 + if (set_mode != CCSZmode
1655 + && set_mode != CCSZNmode)
1660 + if (set_mode != CCSmode
1661 + && set_mode != CCSZmode
1662 + && set_mode != CCSZNmode)
1667 + if (set_mode != CCWZmode)
1672 + if (set_mode != CCWZmode
1673 + && set_mode != CCWZNmode)
1678 + if (set_mode != CCWmode
1679 + && set_mode != CCWZmode
1680 + && set_mode != CCWZNmode)
1685 + gcc_unreachable ();
1688 + return (GET_MODE (SET_SRC (set)) == set_mode);
1691 +/* Replace the comparison OP0 CODE OP1 by a semantically equivalent one
1692 + that we can implement more efficiently. */
1695 +ubicom32_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1)
1697 + /* If we have a REG and a MEM then compare the MEM with the REG and not
1698 + the other way round. */
1699 + if (REG_P (*op0) && MEM_P (*op1))
1704 + *code = swap_condition (*code);
1708 + /* If we have a REG and a CONST_INT then we may want to reverse things
1709 + if the constant can be represented as an "I" constraint. */
1710 + if (REG_P (*op0) && CONST_INT_P (*op1) && satisfies_constraint_I (*op1))
1715 + *code = swap_condition (*code);
1720 +/* Return the fixed registers used for condition codes. */
1723 +ubicom32_fixed_condition_code_regs (unsigned int *p1, unsigned int *p2)
1726 + *p2 = INVALID_REGNUM;
1731 +/* If two condition code modes are compatible, return a condition code
1732 + mode which is compatible with both. Otherwise, return
1735 +static enum machine_mode
1736 +ubicom32_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
1741 + if (GET_MODE_CLASS (m1) != MODE_CC || GET_MODE_CLASS (m2) != MODE_CC)
1747 + if (m2 == CCWZNmode || m2 == CCWZmode)
1753 + if (m2 == CCWmode)
1756 + if (m2 == CCWZmode)
1762 + if (m2 == CCWmode || m2 == CCWZNmode)
1768 + if (m2 == CCSZNmode || m2 == CCSZmode)
1774 + if (m2 == CCSmode)
1777 + if (m2 == CCSZmode)
1783 + if (m2 == CCSmode || m2 == CCSZNmode)
1789 + gcc_unreachable ();
1794 +ubicom32_legitimize_fdpic_address_symbol (rtx orig, rtx reg, rtx fdpic_reg)
1798 + rtx got_offs_scaled;
1803 + gcc_assert (reg != 0);
1805 + if (GET_CODE (orig) == SYMBOL_REF
1806 + && SYMBOL_REF_FUNCTION_P (orig))
1807 + unspec = UNSPEC_FDPIC_GOT_FUNCDESC;
1809 + unspec = UNSPEC_FDPIC_GOT;
1811 + got_offs = gen_reg_rtx (SImode);
1812 + tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, orig), unspec);
1813 + emit_move_insn (got_offs, tmp);
1815 + got_offs_scaled = gen_rtx_MULT (SImode, got_offs, GEN_INT (4));
1816 + plus_scaled = gen_rtx_PLUS (Pmode, fdpic_reg, got_offs_scaled);
1817 + new_rtx = gen_const_mem (Pmode, plus_scaled);
1818 + emit_move_insn (reg, new_rtx);
1824 +ubicom32_legitimize_fdpic_address (rtx orig, rtx reg, rtx fdpic_reg)
1827 + rtx new_rtx = orig;
1829 + if (GET_CODE (addr) == CONST || GET_CODE (addr) == PLUS)
1833 + if (GET_CODE (addr) == CONST)
1835 + addr = XEXP (addr, 0);
1836 + gcc_assert (GET_CODE (addr) == PLUS);
1839 + base = ubicom32_legitimize_fdpic_address_symbol (XEXP (addr, 0), reg, fdpic_reg);
1840 + return gen_rtx_PLUS (Pmode, base, XEXP (addr, 1));
1846 +/* Code generation. */
1849 +ubicom32_expand_movsi (rtx *operands)
1851 + if (GET_CODE (operands[1]) == SYMBOL_REF
1852 + || (GET_CODE (operands[1]) == CONST
1853 + && GET_CODE (XEXP (operands[1], 0)) == PLUS
1854 + && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == SYMBOL_REF)
1855 + || CONSTANT_ADDRESS_P (operands[1]))
1862 + gcc_assert (can_create_pseudo_p ());
1863 + tmp = gen_reg_rtx (Pmode);
1864 + fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
1865 + if (GET_CODE (operands[1]) == SYMBOL_REF
1866 + || GET_CODE (operands[1]) == LABEL_REF)
1867 + operands[1] = ubicom32_legitimize_fdpic_address_symbol (operands[1], tmp, fdpic_reg);
1869 + operands[1] = ubicom32_legitimize_fdpic_address (operands[1], tmp, fdpic_reg);
1874 + enum machine_mode mode;
1876 + /* We want to avoid reusing operand 0 if we can because it limits
1877 + our ability to optimize later. */
1878 + tmp = ! can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
1880 + mode = GET_MODE (operands[0]);
1881 + emit_insn (gen_rtx_SET (VOIDmode, tmp,
1882 + gen_rtx_HIGH (mode, operands[1])));
1883 + operands[1] = gen_rtx_LO_SUM (mode, tmp, operands[1]);
1884 + if (can_create_pseudo_p() && ! REG_P (operands[0]))
1886 + tmp = gen_reg_rtx (mode);
1887 + emit_insn (gen_rtx_SET (VOIDmode, tmp, operands[1]));
1888 + operands[1] = tmp;
1894 +/* Emit code for addsi3. */
1897 +ubicom32_expand_addsi3 (rtx *operands)
1901 + if (can_create_pseudo_p ())
1903 + /* If we have a non-data reg for operand 1 then prefer that over
1904 + a CONST_INT in operand 2. */
1905 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
1906 + && CONST_INT_P (operands[2]))
1907 + operands[2] = copy_to_mode_reg (SImode, operands[2]);
1909 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
1910 + operands[2] = copy_to_mode_reg (SImode, operands[2]);
1913 + /* Emit the instruction. */
1915 + op = gen_rtx_SET (VOIDmode, operands[0],
1916 + gen_rtx_PLUS (SImode, operands[1], operands[2]));
1918 + if (! can_create_pseudo_p ())
1920 + /* Reload doesn't know about the flags register, and doesn't know that
1921 + it doesn't want to clobber it. We can only do this with PLUS. */
1926 + clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM));
1927 + emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, op, clob)));
1931 +/* Emit code for mulsi3. Return 1 if we have generated all the code
1932 + necessary to do the multiplication. */
1935 +ubicom32_emit_mult_sequence (rtx *operands)
1937 + if (! ubicom32_v4)
1944 + /* Give up if we cannot create new pseudos. */
1945 + if (!can_create_pseudo_p())
1948 + /* Synthesize 32-bit multiplication using 16-bit operations:
1956 + c = (a1 * b1) << 32 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1957 + = 0 + (a1 * b2) << 16 + (a2 * b1) << 16 + a2 * b2
1958 + ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^
1959 + Signed Signed Unsigned */
1961 + if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
1965 + op1 = gen_reg_rtx (SImode);
1966 + emit_move_insn (op1, operands[1]);
1967 + operands[1] = op1;
1970 + if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
1974 + op2 = gen_reg_rtx (SImode);
1975 + emit_move_insn (op2, operands[2]);
1976 + operands[2] = op2;
1979 + /* a1 = highpart (a) */
1980 + a1 = gen_reg_rtx (HImode);
1981 + a1_1 = gen_reg_rtx (SImode);
1982 + emit_insn (gen_ashrsi3 (a1_1, operands[1], GEN_INT (16)));
1983 + emit_move_insn (a1, gen_lowpart (HImode, a1_1));
1985 + /* a2 = lowpart (a) */
1986 + a2 = gen_reg_rtx (HImode);
1987 + emit_move_insn (a2, gen_lowpart (HImode, operands[1]));
1989 + /* b1 = highpart (b) */
1990 + b1 = gen_reg_rtx (HImode);
1991 + b1_1 = gen_reg_rtx (SImode);
1992 + emit_insn (gen_ashrsi3 (b1_1, operands[2], GEN_INT (16)));
1993 + emit_move_insn (b1, gen_lowpart (HImode, b1_1));
1995 + /* b2 = lowpart (b) */
1996 + b2 = gen_reg_rtx (HImode);
1997 + emit_move_insn (b2, gen_lowpart (HImode, operands[2]));
1999 + /* t1 = (a1 * b2) << 16 */
2000 + t1 = gen_reg_rtx (SImode);
2001 + mac_lo_rtx = gen_rtx_REG (SImode, ACC0_LO_REGNUM);
2002 + emit_insn (gen_mulhisi3 (mac_lo_rtx, a1, b2));
2003 + emit_insn (gen_ashlsi3 (t1, mac_lo_rtx, GEN_INT (16)));
2005 + /* t2 = (a2 * b1) << 16 */
2006 + t2 = gen_reg_rtx (SImode);
2007 + emit_insn (gen_mulhisi3 (mac_lo_rtx, a2, b1));
2008 + emit_insn (gen_ashlsi3 (t2, mac_lo_rtx, GEN_INT (16)));
2010 + /* mac_lo = a2 * b2 */
2011 + emit_insn (gen_umulhisi3 (mac_lo_rtx, a2, b2));
2013 + /* t3 = t1 + t2 */
2014 + t3 = gen_reg_rtx (SImode);
2015 + emit_insn (gen_addsi3 (t3, t1, t2));
2017 + /* c = t3 + mac_lo_rtx */
2018 + emit_insn (gen_addsi3 (operands[0], mac_lo_rtx, t3));
2026 + /* Give up if we cannot create new pseudos. */
2027 + if (!can_create_pseudo_p())
2030 + if (!ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
2034 + op1 = gen_reg_rtx (SImode);
2035 + emit_move_insn (op1, operands[1]);
2036 + operands[1] = op1;
2039 + if (!ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
2043 + op2 = gen_reg_rtx (SImode);
2044 + emit_move_insn (op2, operands[2]);
2045 + operands[2] = op2;
2048 + acc_rtx = gen_reg_rtx (DImode);
2049 + emit_insn (gen_umulsidi3 (acc_rtx, operands[1], operands[2]));
2050 + emit_move_insn (operands[0], gen_lowpart (SImode, acc_rtx));
2056 +/* Move the integer value VAL into OPERANDS[0]. */
2059 +ubicom32_emit_move_const_int (rtx dest, rtx imm)
2063 + xoperands[0] = dest;
2064 + xoperands[1] = imm;
2066 + /* Treat mem destinations separately. Values must be explicitly sign
2070 + rtx low_hword_mem;
2071 + rtx low_hword_addr;
2073 + /* Emit shorter sequence for signed 7-bit quantities. */
2074 + if (satisfies_constraint_I (imm))
2076 + output_asm_insn ("move.4\t%0, %1", xoperands);
2080 + /* Special case for pushing constants. */
2081 + if (GET_CODE (XEXP (dest, 0)) == PRE_DEC
2082 + && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx)
2084 + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2085 + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2089 + /* See if we can add 2 to the original address. This is only
2090 + possible if the original address is of the form REG or
2092 + low_hword_addr = plus_constant (XEXP (dest, 0), 2);
2093 + if (ubicom32_legitimate_address_p (HImode, low_hword_addr, 1))
2095 + low_hword_mem = gen_rtx_MEM (HImode, low_hword_addr);
2096 + MEM_COPY_ATTRIBUTES (low_hword_mem, dest);
2097 + output_asm_insn ("movei\t%0, #%%hi(%E1)", xoperands);
2098 + xoperands[0] = low_hword_mem;
2099 + output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2103 + /* The original address is too complex. We need to use a
2104 + scratch memory by (sp) and move that to the original
2106 + if (! reg_mentioned_p (stack_pointer_rtx, dest))
2108 + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2109 + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2110 + output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2114 + /* Our address mentions the stack pointer so we need to
2115 + use our scratch data register here as well as scratch
2117 + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2118 + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2119 + output_asm_insn ("move.4\td15, (sp)4++", xoperands);
2120 + output_asm_insn ("move.4\t%0, d15", xoperands);
2124 + /* Move into registers are zero extended by default. */
2125 + if (! REG_P (dest))
2128 + if (satisfies_constraint_N (imm))
2130 + output_asm_insn ("movei\t%0, %1", xoperands);
2134 + if (INTVAL (xoperands[1]) >= 0xff80
2135 + && INTVAL (xoperands[1]) < 0x10000)
2137 + xoperands[1] = GEN_INT (INTVAL (xoperands[1]) - 0x10000);
2138 + output_asm_insn ("move.2\t%0, %1", xoperands);
2142 + if ((REGNO_REG_CLASS (REGNO (xoperands[0])) == ADDRESS_REGS
2143 + || REGNO_REG_CLASS (REGNO (xoperands[0])) == FDPIC_REG)
2144 + && ((INTVAL (xoperands[1]) & 0x80000000) == 0))
2146 + output_asm_insn ("moveai\t%0, #%%hi(%E1)", xoperands);
2147 + if ((INTVAL (xoperands[1]) & 0x7f) != 0)
2148 + output_asm_insn ("lea.1\t%0, %%lo(%E1)(%0)", xoperands);
2152 + if ((INTVAL (xoperands[1]) & 0xffff0000) == 0)
2154 + output_asm_insn ("movei\t%0, #%%lo(%E1)", xoperands);
2155 + output_asm_insn ("move.2\t%0, %0", xoperands);
2159 + /* This is very expensive. The constant is so large that we
2160 + need to use the stack to do the load. */
2161 + output_asm_insn ("movei\t-4(sp)++, #%%hi(%E1)", xoperands);
2162 + output_asm_insn ("movei\t2(sp), #%%lo(%E1)", xoperands);
2163 + output_asm_insn ("move.4\t%0, (sp)4++", xoperands);
2166 +/* Stack layout. Prologue/Epilogue. */
2168 +static int save_regs_size;
2171 +ubicom32_layout_frame (void)
2175 + memset ((char *) &save_regs[0], 0, sizeof (save_regs));
2177 + frame_size = get_frame_size ();
2179 + if (frame_pointer_needed || df_regs_ever_live_p (FRAME_POINTER_REGNUM))
2181 + save_regs[FRAME_POINTER_REGNUM] = 1;
2185 + if (current_function_is_leaf && ! df_regs_ever_live_p (LINK_REGNO))
2186 + ubicom32_can_use_calli_to_ret = 1;
2189 + ubicom32_can_use_calli_to_ret = 0;
2190 + save_regs[LINK_REGNO] = 1;
2194 + /* Figure out which register(s) needs to be saved. */
2195 + for (regno = 0; regno <= LAST_ADDRESS_REGNUM; regno++)
2196 + if (df_regs_ever_live_p(regno)
2197 + && ! call_used_regs[regno]
2198 + && ! fixed_regs[regno]
2199 + && ! save_regs[regno])
2201 + save_regs[regno] = 1;
2205 + save_regs_size = 4 * nregs;
2209 +ubicom32_emit_add_movsi (int regno, int adj)
2212 + rtx reg = gen_rtx_REG (SImode, regno);
2217 + x = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2219 + RTX_FRAME_RELATED_P (x) = 1;
2220 + x = emit_move_insn (gen_rtx_MEM (SImode, stack_pointer_rtx), reg);
2224 + rtx addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx,
2225 + gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2227 + x = emit_move_insn (gen_rtx_MEM (SImode, addr), reg);
2229 + RTX_FRAME_RELATED_P (x) = 1;
2233 +ubicom32_expand_prologue (void)
2237 + int outgoing_args_size = crtl->outgoing_args_size;
2240 + if (ubicom32_naked_function_p ())
2243 + ubicom32_builtin_saveregs ();
2245 + ubicom32_layout_frame ();
2246 + adj = (outgoing_args_size + get_frame_size () + save_regs_size
2247 + + crtl->args.pretend_args_size);
2251 + else if (outgoing_args_size + save_regs_size < 508
2252 + && get_frame_size () + save_regs_size > 508)
2255 + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2257 + x = emit_insn (x);
2258 + RTX_FRAME_RELATED_P (x) = 1;
2260 + for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2261 + if (save_regs[regno] && regno != LINK_REGNO)
2263 + x = gen_rtx_MEM (SImode,
2264 + gen_rtx_PLUS (Pmode,
2265 + stack_pointer_rtx,
2266 + GEN_INT (i * 4 + outgoing_args_size)));
2267 + x = emit_move_insn (x, gen_rtx_REG (SImode, regno));
2268 + RTX_FRAME_RELATED_P (x) = 1;
2271 + if (save_regs[LINK_REGNO])
2273 + x = gen_rtx_MEM (SImode,
2274 + gen_rtx_PLUS (Pmode,
2275 + stack_pointer_rtx,
2276 + GEN_INT (i * 4 + outgoing_args_size)));
2277 + x = emit_move_insn (x, gen_rtx_REG (SImode, LINK_REGNO));
2278 + RTX_FRAME_RELATED_P (x) = 1;
2284 + int adj = get_frame_size () + crtl->args.pretend_args_size;
2287 + if (save_regs[LINK_REGNO])
2289 + ubicom32_emit_add_movsi (LINK_REGNO, adj);
2293 + for (regno = 0; regno <= LAST_ADDRESS_REGNUM; ++regno)
2294 + if (save_regs[regno] && regno != LINK_REGNO)
2298 + rtx mem = gen_rtx_MEM (SImode,
2299 + gen_rtx_PRE_DEC (Pmode,
2300 + stack_pointer_rtx));
2301 + x = emit_move_insn (mem, gen_rtx_REG (SImode, regno));
2302 + RTX_FRAME_RELATED_P (x) = 1;
2305 + ubicom32_emit_add_movsi (regno, adj);
2309 + if (outgoing_args_size || (!i && adj))
2311 + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2312 + GEN_INT (-outgoing_args_size - (i ? 0 : adj)));
2313 + x = emit_insn (x);
2314 + RTX_FRAME_RELATED_P (x) = 1;
2318 + if (frame_pointer_needed)
2320 + int fp_adj = save_regs_size + outgoing_args_size;
2321 + x = gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
2322 + GEN_INT (fp_adj));
2323 + x = emit_insn (x);
2324 + RTX_FRAME_RELATED_P (x) = 1;
2329 +ubicom32_expand_epilogue (void)
2333 + int outgoing_args_size = crtl->outgoing_args_size;
2337 + if (ubicom32_naked_function_p ())
2339 + emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode,
2344 + if (cfun->calls_alloca)
2346 + x = gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
2347 + GEN_INT (-save_regs_size));
2349 + outgoing_args_size = 0;
2352 + if (outgoing_args_size)
2354 + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2355 + GEN_INT (outgoing_args_size));
2360 + for (regno = LAST_ADDRESS_REGNUM; regno >= 0; --regno)
2361 + if (save_regs[regno] && regno != LINK_REGNO)
2363 + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2364 + emit_move_insn (gen_rtx_REG (SImode, regno), x);
2368 + /* Do we have to adjust the stack after we've finished restoring regs? */
2369 + adj = get_frame_size() + crtl->args.pretend_args_size;
2371 + adj += UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2374 + if (crtl->calls_eh_return && 0)
2376 + if (save_regs[LINK_REGNO])
2378 + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2379 + emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2384 + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2386 + x = emit_insn (x);
2389 + /* Perform the additional bump for __throw. */
2390 + emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2391 + EH_RETURN_STACKADJ_RTX));
2392 + emit_jump_insn (gen_eh_return_internal ());
2397 + if (save_regs[LINK_REGNO])
2399 + if (adj >= 4 && adj <= (6 * 4))
2401 + x = GEN_INT (adj + 4);
2402 + emit_jump_insn (gen_return_from_post_modify_sp (x));
2408 + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2409 + emit_jump_insn (gen_return_internal (x));
2413 + x = gen_rtx_MEM (SImode, gen_rtx_POST_INC (Pmode, stack_pointer_rtx));
2414 + emit_move_insn (gen_rtx_REG (SImode, LINK_REGNO), x);
2419 + x = gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2421 + x = emit_insn (x);
2425 + /* Given that we've just done all the hard work here we may as well use
2426 + a calli to return. */
2427 + ubicom32_can_use_calli_to_ret = 1;
2428 + emit_jump_insn (gen_return_internal (gen_rtx_REG (SImode, LINK_REGNO)));
2432 +ubicom32_expand_call_fdpic (rtx *operands)
2436 + rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2438 + addr = XEXP (operands[0], 0);
2440 + c = gen_call_fdpic (addr, operands[1], fdpic_reg);
2441 + emit_call_insn (c);
2445 +ubicom32_expand_call_value_fdpic (rtx *operands)
2449 + rtx fdpic_reg = get_hard_reg_initial_val (SImode, FDPIC_REGNUM);
2451 + addr = XEXP (operands[1], 0);
2453 + c = gen_call_value_fdpic (operands[0], addr, operands[2], fdpic_reg);
2454 + emit_call_insn (c);
2458 +ubicom32_expand_eh_return (rtx *operands)
2460 + if (REG_P (operands[0])
2461 + || REGNO (operands[0]) != EH_RETURN_STACKADJ_REGNO)
2463 + rtx sp = EH_RETURN_STACKADJ_RTX;
2464 + emit_move_insn (sp, operands[0]);
2468 + if (REG_P (operands[1])
2469 + || REGNO (operands[1]) != EH_RETURN_HANDLER_REGNO)
2471 + rtx ra = EH_RETURN_HANDLER_RTX;
2472 + emit_move_insn (ra, operands[1]);
2477 +/* Compute the offsets between eliminable registers. */
2480 +ubicom32_initial_elimination_offset (int from, int to)
2482 + ubicom32_layout_frame ();
2483 + if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2484 + return save_regs_size + crtl->outgoing_args_size;
2486 + if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
2487 + return get_frame_size ()/* + save_regs_size */;
2489 + if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
2490 + return get_frame_size ()
2491 + + crtl->outgoing_args_size
2497 +/* Return 1 if it is appropriate to emit `ret' instructions in the
2498 + body of a function. Do this only if the epilogue is simple, needing a
2499 + couple of insns. Prior to reloading, we can't tell how many registers
2500 + must be saved, so return 0 then. Return 0 if there is no frame
2501 + marker to de-allocate.
2503 + If NON_SAVING_SETJMP is defined and true, then it is not possible
2504 + for the epilogue to be simple, so return 0. This is a special case
2505 + since NON_SAVING_SETJMP will not cause regs_ever_live to change
2506 + until final, but jump_optimize may need to know sooner if a
2507 + `return' is OK. */
2510 +ubicom32_can_use_return_insn_p (void)
2512 + if (! reload_completed || frame_pointer_needed)
2518 +/* Attributes and CC handling. */
2520 +/* Handle an attribute requiring a FUNCTION_DECL; arguments as in
2521 + struct attribute_spec.handler. */
2523 +ubicom32_handle_fndecl_attribute (tree *node, tree name,
2524 + tree args ATTRIBUTE_UNUSED,
2525 + int flags ATTRIBUTE_UNUSED,
2526 + bool *no_add_attrs)
2528 + if (TREE_CODE (*node) != FUNCTION_DECL)
2530 + warning ("'%s' attribute only applies to functions",
2531 + IDENTIFIER_POINTER (name));
2532 + *no_add_attrs = true;
2538 +/* A C expression that places additional restrictions on the register class to
2539 + use when it is necessary to copy value X into a register in class CLASS.
2540 + The value is a register class; perhaps CLASS, or perhaps another, smaller
2541 + class. On many machines, the following definition is safe:
2543 + #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
2545 + Sometimes returning a more restrictive class makes better code. For
2546 + example, on the 68000, when X is an integer constant that is in range for a
2547 + `moveq' instruction, the value of this macro is always `DATA_REGS' as long
2548 + as CLASS includes the data registers. Requiring a data register guarantees
2549 + that a `moveq' will be used.
2551 + If X is a `const_double', by returning `NO_REGS' you can force X into a
2552 + memory constant. This is useful on certain machines where immediate
2553 + floating values cannot be loaded into certain kinds of registers. */
2556 +ubicom32_preferred_reload_class (rtx x, enum reg_class class)
2558 + /* If a symbolic constant, HIGH or a PLUS is reloaded,
2559 + it is most likely being used as an address, so
2560 + prefer ADDRESS_REGS. If 'class' is not a superset
2561 + of ADDRESS_REGS, e.g. DATA_REGS, then reject this reload. */
2562 + if (GET_CODE (x) == PLUS
2563 + || GET_CODE (x) == HIGH
2564 + || GET_CODE (x) == LABEL_REF
2565 + || GET_CODE (x) == SYMBOL_REF
2566 + || GET_CODE (x) == CONST)
2568 + if (reg_class_subset_p (ALL_ADDRESS_REGS, class))
2569 + return ALL_ADDRESS_REGS;
2577 +/* Function arguments and varargs. */
2580 +ubicom32_reg_parm_stack_space (tree fndecl)
2585 + && TYPE_ARG_TYPES (TREE_TYPE (fndecl)) != 0
2586 + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))))
2587 + != void_type_node))
2588 + return UBICOM32_FUNCTION_ARG_REGS * UNITS_PER_WORD;
2593 +/* Flush the argument registers to the stack for a stdarg function;
2594 + return the new argument pointer. */
2597 +ubicom32_builtin_saveregs (void)
2601 + if (! cfun->stdarg)
2604 + for (regno = UBICOM32_FUNCTION_ARG_REGS - 1; regno >= 0; --regno)
2605 + emit_move_insn (gen_rtx_MEM (SImode,
2606 + gen_rtx_PRE_DEC (SImode,
2607 + stack_pointer_rtx)),
2608 + gen_rtx_REG (SImode, regno));
2610 + return stack_pointer_rtx;
2614 +ubicom32_va_start (tree valist, rtx nextarg)
2616 + std_expand_builtin_va_start (valist, nextarg);
2620 +ubicom32_va_arg (tree valist, tree type)
2622 + HOST_WIDE_INT size, rsize;
2623 + tree addr, incr, tmp;
2627 + /* Round up sizeof(type) to a word. */
2628 + size = int_size_in_bytes (type);
2629 + rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
2631 + /* Large types are passed by reference. */
2635 + size = rsize = UNITS_PER_WORD;
2639 + addr = incr = save_expr (incr);
2641 + /* FIXME Nat's version - is it correct? */
2642 + tmp = fold_convert (ptr_type_node, size_int (rsize));
2643 + tmp = build2 (PLUS_EXPR, ptr_type_node, incr, tmp);
2644 + incr = fold (tmp);
2646 + /* FIXME Nat's version - is it correct? */
2647 + incr = build2 (MODIFY_EXPR, ptr_type_node, valist, incr);
2649 + TREE_SIDE_EFFECTS (incr) = 1;
2650 + expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
2652 + addr_rtx = expand_expr (addr, NULL, Pmode, EXPAND_NORMAL);
2654 + if (size < UNITS_PER_WORD)
2655 + emit_insn (gen_addsi3 (addr_rtx, addr_rtx,
2656 + GEN_INT (UNITS_PER_WORD - size)));
2660 + addr_rtx = force_reg (Pmode, addr_rtx);
2661 + addr_rtx = gen_rtx_MEM (Pmode, addr_rtx);
2662 + set_mem_alias_set (addr_rtx, get_varargs_alias_set ());
2669 +init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2670 + int indirect ATTRIBUTE_UNUSED)
2676 + cum->stdarg = (TYPE_ARG_TYPES (fntype) != 0
2677 + && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
2678 + != void_type_node));
2682 +/* Return an RTX to represent where a value in mode MODE will be passed
2683 + to a function. If the result is 0, the argument will be pushed. */
2686 +function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2687 + int named ATTRIBUTE_UNUSED)
2691 + int nregs = UBICOM32_FUNCTION_ARG_REGS;
2693 + /* Figure out the size of the object to be passed. */
2694 + if (mode == BLKmode)
2695 + size = int_size_in_bytes (type);
2697 + size = GET_MODE_SIZE (mode);
2699 + /* Figure out the alignment of the object to be passed. */
2702 + cum->nbytes = (cum->nbytes + 3) & ~3;
2704 + /* Don't pass this arg via a register if all the argument registers
2706 + if (cum->nbytes >= nregs * UNITS_PER_WORD)
2709 + /* Don't pass this arg via a register if it would be split between
2710 + registers and memory. */
2711 + result = gen_rtx_REG (mode, cum->nbytes / UNITS_PER_WORD);
2717 +function_incoming_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
2718 + int named ATTRIBUTE_UNUSED)
2723 + return function_arg (cum, mode, type, named);
2727 +/* Implement hook TARGET_ARG_PARTIAL_BYTES.
2729 + Returns the number of bytes at the beginning of an argument that
2730 + must be put in registers. The value must be zero for arguments
2731 + that are passed entirely in registers or that are entirely pushed
2734 +ubicom32_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
2735 + tree type, bool named ATTRIBUTE_UNUSED)
2739 + int nregs = UBICOM32_FUNCTION_ARG_REGS;
2741 + /* round up to full word */
2742 + cum->nbytes = (cum->nbytes + 3) & ~3;
2744 + if (targetm.calls.pass_by_reference (cum, mode, type, named))
2747 + /* number of bytes left in registers */
2748 + diff = nregs*UNITS_PER_WORD - cum->nbytes;
2750 + /* regs all used up */
2754 + /* Figure out the size of the object to be passed. */
2755 + if (mode == BLKmode)
2756 + size = int_size_in_bytes (type);
2758 + size = GET_MODE_SIZE (mode);
2760 + /* enough space left in regs for size */
2764 + /* put diff bytes in regs and rest on stack */
2770 +ubicom32_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2771 + enum machine_mode mode, const_tree type,
2772 + bool named ATTRIBUTE_UNUSED)
2777 + size = int_size_in_bytes (type);
2779 + size = GET_MODE_SIZE (mode);
2781 + return size <= 0 || size > 8;
2785 +ubicom32_callee_copies (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2786 + enum machine_mode mode, const_tree type,
2787 + bool named ATTRIBUTE_UNUSED)
2792 + size = int_size_in_bytes (type);
2794 + size = GET_MODE_SIZE (mode);
2796 + return size <= 0 || size > 8;
2800 +ubicom32_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
2807 + size = int_size_in_bytes(type);
2811 + mode = TYPE_MODE(type);
2812 + if (mode == BLKmode)
2818 +/* Return true if a given register number REGNO is acceptable for machine
2821 +ubicom32_hard_regno_mode_ok (unsigned int regno, enum machine_mode mode)
2823 + /* If we're not at least a v3 ISA then ACC0_HI is only 16 bits. */
2824 + if (! ubicom32_v3)
2826 + if (regno == ACC0_HI_REGNUM)
2827 + return (mode == QImode || mode == HImode);
2830 + /* Only the flags reg can hold CCmode. */
2831 + if (GET_MODE_CLASS (mode) == MODE_CC)
2832 + return regno == CC_REGNUM;
2834 + /* We restrict the choice of DImode registers to only being address,
2835 + data or accumulator regs. We also restrict them to only start on
2836 + even register numbers so we never have to worry about partial
2837 + overlaps between operands in instructions. */
2838 + if (GET_MODE_SIZE (mode) > 4)
2840 + switch (REGNO_REG_CLASS (regno))
2842 + case ADDRESS_REGS:
2845 + return (regno & 1) == 0;
2855 +/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
2856 + and check its validity for a certain class.
2857 + We have two alternate definitions for each of them.
2858 + The usual definition accepts all pseudo regs; the other rejects
2859 + them unless they have been allocated suitable hard regs.
2860 + The symbol REG_OK_STRICT causes the latter definition to be used.
2862 + Most source files want to accept pseudo regs in the hope that
2863 + they will get allocated to the class that the insn wants them to be in.
2864 + Source files for reload pass need to be strict.
2865 + After reload, it makes no difference, since pseudo regs have
2866 + been eliminated by then.
2868 + These assume that REGNO is a hard or pseudo reg number.
2869 + They give nonzero only if REGNO is a hard reg of the suitable class
2870 + or a pseudo reg currently allocated to a suitable hard reg.
2871 + Since they use reg_renumber, they are safe only once reg_renumber
2872 + has been allocated, which happens in local-alloc.c. */
2875 +ubicom32_regno_ok_for_base_p (int regno, int strict)
2877 + if ((regno >= FIRST_ADDRESS_REGNUM && regno <= STACK_POINTER_REGNUM)
2879 + && (regno >= FIRST_PSEUDO_REGISTER
2880 + || regno == ARG_POINTER_REGNUM))
2881 + || (strict && (reg_renumber
2882 + && reg_renumber[regno] >= FIRST_ADDRESS_REGNUM
2883 + && reg_renumber[regno] <= STACK_POINTER_REGNUM)))
2890 +ubicom32_regno_ok_for_index_p (int regno, int strict)
2892 + if ((regno >= FIRST_DATA_REGNUM && regno <= LAST_DATA_REGNUM)
2893 + || (!strict && regno >= FIRST_PSEUDO_REGISTER)
2894 + || (strict && (reg_renumber
2895 + && reg_renumber[regno] >= FIRST_DATA_REGNUM
2896 + && reg_renumber[regno] <= LAST_DATA_REGNUM)))
2902 +/* Returns 1 if X is a valid index register. STRICT is 1 if only hard
2903 + registers should be accepted. Accept either REG or SUBREG where a
2904 + register is valid. */
2907 +ubicom32_is_index_reg (rtx x, int strict)
2909 + if ((REG_P (x) && ubicom32_regno_ok_for_index_p (REGNO (x), strict))
2910 + || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
2911 + && ubicom32_regno_ok_for_index_p (REGNO (SUBREG_REG (x)), strict)))
2917 +/* Return 1 if X is a valid index for a memory address. */
2920 +ubicom32_is_index_expr (enum machine_mode mode, rtx x, int strict)
2922 + /* Immediate index must be an unsigned 7-bit offset multiple of 1, 2
2923 + or 4 depending on mode. */
2924 + if (CONST_INT_P (x))
2929 + return satisfies_constraint_J (x);
2932 + return satisfies_constraint_K (x);
2936 + return satisfies_constraint_L (x);
2939 + return satisfies_constraint_L (x)
2940 + && satisfies_constraint_L (GEN_INT (INTVAL (x) + 4));
2947 + if (mode != SImode && mode != HImode && mode != QImode)
2950 + /* Register index scaled by mode of operand: REG + REG * modesize.
2951 + Valid scaled index registers are:
2953 + SImode (mult (dreg) 4))
2954 + HImode (mult (dreg) 2))
2955 + QImode (mult (dreg) 1)) */
2956 + if (GET_CODE (x) == MULT
2957 + && ubicom32_is_index_reg (XEXP (x, 0), strict)
2958 + && CONST_INT_P (XEXP (x, 1))
2959 + && INTVAL (XEXP (x, 1)) == (HOST_WIDE_INT)GET_MODE_SIZE (mode))
2962 + /* REG + REG addressing is allowed for QImode. */
2963 + if (ubicom32_is_index_reg (x, strict) && mode == QImode)
2970 +ubicom32_is_valid_offset (enum machine_mode mode, HOST_WIDE_INT offs)
2978 + return offs <= 127;
2981 + return offs <= 254;
2985 + return offs <= 508;
2988 + return offs <= 504;
2996 +ubicom32_get_valid_offset_mask (enum machine_mode mode)
3018 +/* Returns 1 if X is a valid base register. STRICT is 1 if only hard
3019 + registers should be accepted. Accept either REG or SUBREG where a
3020 + register is valid. */
3023 +ubicom32_is_base_reg (rtx x, int strict)
3025 + if ((REG_P (x) && ubicom32_regno_ok_for_base_p (REGNO (x), strict))
3026 + || (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
3027 + && ubicom32_regno_ok_for_base_p (REGNO (SUBREG_REG (x)), strict)))
3034 +ubicom32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
3036 + return TARGET_FDPIC;
3039 +/* Determine if X is a legitimate constant. */
3042 +ubicom32_legitimate_constant_p (rtx x)
3044 + /* Among its other duties, LEGITIMATE_CONSTANT_P decides whether
3045 + a constant can be entered into reg_equiv_constant[]. If we return true,
3046 + reload can create new instances of the constant whenever it likes.
3048 + The idea is therefore to accept as many constants as possible (to give
3049 + reload more freedom) while rejecting constants that can only be created
3050 + at certain times. In particular, anything with a symbolic component will
3051 + require use of the pseudo FDPIC register, which is only available before
3055 + if (GET_CODE (x) == SYMBOL_REF
3056 + || (GET_CODE (x) == CONST
3057 + && GET_CODE (XEXP (x, 0)) == PLUS
3058 + && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
3059 + || CONSTANT_ADDRESS_P (x))
3065 + /* For non-PIC code anything goes! */
3069 +/* Address validation. */
3072 +ubicom32_legitimate_address_p (enum machine_mode mode, rtx x, int strict)
3074 + if (TARGET_DEBUG_ADDRESS)
3076 + fprintf (stderr, "\n==> GO_IF_LEGITIMATE_ADDRESS%s\n",
3077 + (strict) ? " (STRICT)" : "");
3081 + if (CONSTANT_ADDRESS_P (x))
3084 + if (ubicom32_is_base_reg (x, strict))
3087 + if ((GET_CODE (x) == POST_INC
3088 + || GET_CODE (x) == PRE_INC
3089 + || GET_CODE (x) == POST_DEC
3090 + || GET_CODE (x) == PRE_DEC)
3091 + && REG_P (XEXP (x, 0))
3092 + && ubicom32_is_base_reg (XEXP (x, 0), strict)
3093 + && mode != DImode)
3096 + if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
3097 + && ubicom32_is_base_reg (XEXP (x, 0), strict)
3098 + && GET_CODE (XEXP (x, 1)) == PLUS
3099 + && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
3100 + && CONST_INT_P (XEXP (XEXP (x, 1), 1))
3101 + && mode != DImode)
3103 + HOST_WIDE_INT disp = INTVAL (XEXP (XEXP (x, 1), 1));
3107 + return disp >= -8 && disp <= 7;
3110 + return disp >= -16 && disp <= 14 && ! (disp & 1);
3113 + return disp >= -32 && disp <= 28 && ! (disp & 3);
3120 + /* Accept base + index * scale. */
3121 + if (GET_CODE (x) == PLUS
3122 + && ubicom32_is_base_reg (XEXP (x, 0), strict)
3123 + && ubicom32_is_index_expr (mode, XEXP (x, 1), strict))
3126 + /* Accept index * scale + base. */
3127 + if (GET_CODE (x) == PLUS
3128 + && ubicom32_is_base_reg (XEXP (x, 1), strict)
3129 + && ubicom32_is_index_expr (mode, XEXP (x, 0), strict))
3132 + if (! TARGET_FDPIC)
3134 + /* Accept (lo_sum (reg) (symbol_ref)) that can be used as a mem+7bits
3135 + displacement operand:
3137 + moveai a1, #%hi(SYM)
3138 + move.4 d3, %lo(SYM)(a1) */
3139 + if (GET_CODE (x) == LO_SUM
3140 + && ubicom32_is_base_reg (XEXP (x, 0), strict)
3141 + && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF
3142 + || GET_CODE (XEXP (x, 1)) == LABEL_REF /* FIXME: wrong */)
3143 + && mode != DImode)
3147 + if (TARGET_DEBUG_ADDRESS)
3148 + fprintf (stderr, "\nNot a legitimate address.\n");
3154 +ubicom32_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
3155 + enum machine_mode mode)
3157 + if (mode == BLKmode)
3160 + if (GET_CODE (x) == PLUS
3161 + && REG_P (XEXP (x, 0))
3162 + && ! REGNO_PTR_FRAME_P (REGNO (XEXP (x, 0)))
3163 + && CONST_INT_P (XEXP (x, 1))
3164 + && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (x, 1))))
3169 + HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
3170 + HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3171 + HOST_WIDE_INT high = val ^ low;
3179 + /* Reload the high part into a base reg; leave the low part
3180 + in the mem directly. */
3181 + base = XEXP (x, 0);
3182 + if (! ubicom32_is_base_reg (base, 0))
3183 + base = copy_to_mode_reg (Pmode, base);
3185 + plus = expand_simple_binop (Pmode, PLUS,
3186 + gen_int_mode (high, Pmode),
3187 + base, NULL, 0, OPTAB_WIDEN);
3188 + new_rtx = plus_constant (plus, low);
3196 +/* Try a machine-dependent way of reloading an illegitimate address AD
3197 + operand. If we find one, push the reload and and return the new address.
3199 + MODE is the mode of the enclosing MEM. OPNUM is the operand number
3200 + and TYPE is the reload type of the current reload. */
3203 +ubicom32_legitimize_reload_address (rtx ad, enum machine_mode mode,
3204 + int opnum, int type)
3206 + /* Is this an address that we've already fixed up? If it is then
3207 + recognize it and move on. */
3208 + if (GET_CODE (ad) == PLUS
3209 + && GET_CODE (XEXP (ad, 0)) == PLUS
3210 + && REG_P (XEXP (XEXP (ad, 0), 0))
3211 + && CONST_INT_P (XEXP (XEXP (ad, 0), 1))
3212 + && CONST_INT_P (XEXP (ad, 1)))
3214 + push_reload (XEXP (ad, 0), NULL_RTX, &XEXP (ad, 0), NULL,
3215 + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3216 + opnum, (enum reload_type) type);
3220 + /* Have we got an address where the offset is simply out of range? If
3221 + yes then reload the range as a high part and smaller offset. */
3222 + if (GET_CODE (ad) == PLUS
3223 + && REG_P (XEXP (ad, 0))
3224 + && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3225 + && REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0)))
3226 + && CONST_INT_P (XEXP (ad, 1))
3227 + && ! ubicom32_is_valid_offset (mode, INTVAL (XEXP (ad, 1))))
3232 + HOST_WIDE_INT val = INTVAL (XEXP (ad, 1));
3233 + HOST_WIDE_INT low = val & ubicom32_get_valid_offset_mask (mode);
3234 + HOST_WIDE_INT high = val ^ low;
3236 + /* Reload the high part into a base reg; leave the low part
3237 + in the mem directly. */
3238 + temp = gen_rtx_PLUS (Pmode, XEXP (ad, 0), GEN_INT (high));
3239 + new_rtx = gen_rtx_PLUS (Pmode, temp, GEN_INT (low));
3241 + push_reload (XEXP (new_rtx, 0), NULL_RTX, &XEXP (new_rtx, 0), NULL,
3242 + BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
3243 + opnum, (enum reload_type) type);
3247 + /* If we're presented with an pre/post inc/dec then we must force this
3248 + to be done in an address register. The register allocator should
3249 + work this out for itself but at times ends up trying to use the wrong
3250 + class. If we get the wrong class then reload will end up generating
3251 + at least 3 instructions whereas this way we can hopefully keep it to
3253 + if ((GET_CODE (ad) == POST_INC
3254 + || GET_CODE (ad) == PRE_INC
3255 + || GET_CODE (ad) == POST_DEC
3256 + || GET_CODE (ad) == PRE_DEC)
3257 + && REG_P (XEXP (ad, 0))
3258 + && REGNO (XEXP (ad, 0)) < FIRST_PSEUDO_REGISTER
3259 + && ! REGNO_OK_FOR_BASE_P (REGNO (XEXP (ad, 0))))
3261 + push_reload (XEXP (ad, 0), XEXP (ad, 0), &XEXP (ad, 0), &XEXP (ad, 0),
3262 + BASE_REG_CLASS, GET_MODE (XEXP (ad, 0)), GET_MODE (XEXP (ad, 0)), 0, 0,
3263 + opnum, RELOAD_OTHER);
3270 +/* Compute a (partial) cost for rtx X. Return true if the complete
3271 + cost has been computed, and false if subexpressions should be
3272 + scanned. In either case, *TOTAL contains the cost result. */
3275 +ubicom32_rtx_costs (rtx x, int code, int outer_code, int *total,
3276 + bool speed ATTRIBUTE_UNUSED)
3278 + enum machine_mode mode = GET_MODE (x);
3283 + /* Very short constants often fold into instructions so
3284 + we pretend that they don't cost anything! This is
3285 + really important as regards zero values as otherwise
3286 + the compiler has a nasty habit of wanting to reuse
3287 + zeroes that are in regs but that tends to pessimize
3289 + if (satisfies_constraint_I (x))
3295 + /* Bit clearing costs nothing */
3296 + if (outer_code == AND
3297 + && exact_log2 (~INTVAL (x)) != -1)
3303 + /* Masking the lower set of bits costs nothing. */
3304 + if (outer_code == AND
3305 + && exact_log2 (INTVAL (x) + 1) != -1)
3311 + /* Bit setting costs nothing. */
3312 + if (outer_code == IOR
3313 + && exact_log2 (INTVAL (x)) != -1)
3319 + /* Larger constants that can be loaded via movei aren't too
3320 + bad. If we're just doing a set they cost nothing extra. */
3321 + if (satisfies_constraint_N (x))
3323 + if (mode == DImode)
3324 + *total = COSTS_N_INSNS (2);
3326 + *total = COSTS_N_INSNS (1);
3330 + if (mode == DImode)
3331 + *total = COSTS_N_INSNS (5);
3333 + *total = COSTS_N_INSNS (3);
3336 + case CONST_DOUBLE:
3337 + /* We don't optimize CONST_DOUBLEs well nor do we relax them well,
3338 + so their cost is very high. */
3339 + *total = COSTS_N_INSNS (6);
3348 + case IF_THEN_ELSE:
3349 + *total = COSTS_N_INSNS (1);
3368 + case ZERO_EXTRACT:
3369 + if (outer_code == SET)
3371 + if (mode == DImode)
3372 + *total = COSTS_N_INSNS (2);
3374 + *total = COSTS_N_INSNS (1);
3379 + if (outer_code == SET)
3381 + if (GET_MODE (XEXP (x, 0)) == DImode
3382 + || GET_MODE (XEXP (x, 1)) == DImode)
3383 + *total = COSTS_N_INSNS (2);
3385 + *total = COSTS_N_INSNS (1);
3393 + if (outer_code == SET)
3395 + if (mode == DImode)
3396 + *total = COSTS_N_INSNS (600);
3398 + *total = COSTS_N_INSNS (200);
3403 + if (outer_code == SET)
3405 + if (! ubicom32_v4)
3407 + if (mode == DImode)
3408 + *total = COSTS_N_INSNS (15);
3410 + *total = COSTS_N_INSNS (5);
3414 + if (mode == DImode)
3415 + *total = COSTS_N_INSNS (6);
3417 + *total = COSTS_N_INSNS (2);
3423 + if (XINT (x, 1) == UNSPEC_FDPIC_GOT
3424 + || XINT (x, 1) == UNSPEC_FDPIC_GOT_FUNCDESC)
3433 +/* Return 1 if ADDR can have different meanings depending on the machine
3434 + mode of the memory reference it is used for or if the address is
3435 + valid for some modes but not others.
3437 + Autoincrement and autodecrement addresses typically have
3438 + mode-dependent effects because the amount of the increment or
3439 + decrement is the size of the operand being addressed. Some machines
3440 + have other mode-dependent addresses. Many RISC machines have no
3441 + mode-dependent addresses.
3443 + You may assume that ADDR is a valid address for the machine. */
3446 +ubicom32_mode_dependent_address_p (rtx addr)
3448 + if (GET_CODE (addr) == POST_INC
3449 + || GET_CODE (addr) == PRE_INC
3450 + || GET_CODE (addr) == POST_DEC
3451 + || GET_CODE (addr) == PRE_DEC
3452 + || GET_CODE (addr) == POST_MODIFY
3453 + || GET_CODE (addr) == PRE_MODIFY)
3460 +ubicom32_function_prologue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3462 + fprintf (file, "/* frame/pretend: %ld/%d save_regs: %d out_args: %d %s */\n",
3463 + get_frame_size (), crtl->args.pretend_args_size,
3464 + save_regs_size, crtl->outgoing_args_size,
3465 + current_function_is_leaf ? "leaf" : "nonleaf");
3469 +ubicom32_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
3470 + HOST_WIDE_INT size ATTRIBUTE_UNUSED)
3472 + ubicom32_reorg_completed = 0;
3476 +ubicom32_machine_dependent_reorg (void)
3478 +#if 0 /* Commenting out this optimization until it is fixed */
3481 + compute_bb_for_insn ();
3483 + /* Do a very simple CSE pass over just the hard registers. */
3484 + reload_cse_regs (get_insns ());
3486 + /* Reload_cse_regs can eliminate potentially-trapping MEMs.
3487 + Remove any EH edges associated with them. */
3488 + if (flag_non_call_exceptions)
3489 + purge_all_dead_edges ();
3492 + ubicom32_reorg_completed = 1;
3496 +ubicom32_output_cond_jump (rtx insn, rtx cond, rtx target)
3499 + int mostly_false_jump;
3503 + note = find_reg_note (insn, REG_BR_PROB, 0);
3504 + mostly_false_jump = !note || (INTVAL (XEXP (note, 0))
3505 + <= REG_BR_PROB_BASE / 2);
3507 + xoperands[0] = target;
3508 + xoperands[1] = cond;
3509 + cc_reg = XEXP (cond, 0);
3511 + if (GET_MODE (cc_reg) == CCWmode
3512 + || GET_MODE (cc_reg) == CCWZmode
3513 + || GET_MODE (cc_reg) == CCWZNmode)
3515 + if (mostly_false_jump)
3516 + output_asm_insn ("jmp%b1.w.f\t%0", xoperands);
3518 + output_asm_insn ("jmp%b1.w.t\t%0", xoperands);
3522 + if (GET_MODE (cc_reg) == CCSmode
3523 + || GET_MODE (cc_reg) == CCSZmode
3524 + || GET_MODE (cc_reg) == CCSZNmode)
3526 + if (mostly_false_jump)
3527 + output_asm_insn ("jmp%b1.s.f\t%0", xoperands);
3529 + output_asm_insn ("jmp%b1.s.t\t%0", xoperands);
3536 +/* Return non-zero if FUNC is a naked function. */
3539 +ubicom32_naked_function_p (void)
3541 + return lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE;
3544 +/* Return an RTX indicating where the return address to the
3545 + calling function can be found. */
3547 +ubicom32_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
3552 + return get_hard_reg_initial_val (Pmode, LINK_REGNO);
3556 + * ubicom32_readonly_data_section: This routtine handles code
3557 + * at the start of readonly data sections
3560 +ubicom32_readonly_data_section (const void *data ATTRIBUTE_UNUSED)
3562 + static int num = 0;
3563 + if (in_section == readonly_data_section){
3564 + fprintf (asm_out_file, "%s", DATA_SECTION_ASM_OP);
3565 + if (flag_data_sections){
3566 + fprintf (asm_out_file, ".rodata%d", num);
3567 + fprintf (asm_out_file, ",\"a\"");
3569 + fprintf (asm_out_file, "\n");
3575 + * ubicom32_text_section: not in readonly section
3578 +ubicom32_text_section(const void *data ATTRIBUTE_UNUSED)
3580 + fprintf (asm_out_file, "%s\n", TEXT_SECTION_ASM_OP);
3584 + * ubicom32_data_section: not in readonly section
3587 +ubicom32_data_section(const void *data ATTRIBUTE_UNUSED)
3589 + fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP);
3593 + * ubicom32_asm_init_sections: This routine implements special
3594 + * section handling
3597 +ubicom32_asm_init_sections(void)
3599 + text_section = get_unnamed_section(SECTION_CODE, ubicom32_text_section, NULL);
3601 + data_section = get_unnamed_section(SECTION_WRITE, ubicom32_data_section, NULL);
3603 + readonly_data_section = get_unnamed_section(0, ubicom32_readonly_data_section, NULL);
3607 + * ubicom32_profiler: This routine would call
3608 + * mcount to support prof and gprof if mcount
3609 + * was supported. Currently, do nothing.
3612 +ubicom32_profiler(void)
3616 +/* Initialise the builtin functions. Start by initialising
3617 + descriptions of different types of functions (e.g., void fn(int),
3618 + int fn(void)), and then use these to define the builtins. */
3620 +ubicom32_init_builtins (void)
3623 + tree short_unsigned_endlink;
3624 + tree unsigned_endlink;
3625 + tree short_unsigned_ftype_short_unsigned;
3626 + tree unsigned_ftype_unsigned;
3628 + endlink = void_list_node;
3630 + short_unsigned_endlink
3631 + = tree_cons (NULL_TREE, short_unsigned_type_node, endlink);
3634 + = tree_cons (NULL_TREE, unsigned_type_node, endlink);
3636 + short_unsigned_ftype_short_unsigned
3637 + = build_function_type (short_unsigned_type_node, short_unsigned_endlink);
3639 + unsigned_ftype_unsigned
3640 + = build_function_type (unsigned_type_node, unsigned_endlink);
3642 + /* Initialise the byte swap function. */
3643 + add_builtin_function ("__builtin_ubicom32_swapb_2",
3644 + short_unsigned_ftype_short_unsigned,
3645 + UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
3646 + BUILT_IN_MD, NULL,
3649 + /* Initialise the byte swap function. */
3650 + add_builtin_function ("__builtin_ubicom32_swapb_4",
3651 + unsigned_ftype_unsigned,
3652 + UBICOM32_BUILTIN_UBICOM32_SWAPB_4,
3653 + BUILT_IN_MD, NULL,
3657 +/* Given a builtin function taking 2 operands (i.e., target + source),
3658 + emit the RTL for the underlying instruction. */
3660 +ubicom32_expand_builtin_2op (enum insn_code icode, tree arglist, rtx target)
3664 + enum machine_mode tmode, mode0;
3666 + /* Grab the incoming argument and emit its RTL. */
3667 + arg0 = TREE_VALUE (arglist);
3668 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
3670 + /* Determine the modes of the instruction operands. */
3671 + tmode = insn_data[icode].operand[0].mode;
3672 + mode0 = insn_data[icode].operand[1].mode;
3674 + /* Ensure that the incoming argument RTL is in a register of the
3676 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
3677 + op0 = copy_to_mode_reg (mode0, op0);
3679 + /* If there isn't a suitable target, emit a target register. */
3681 + || GET_MODE (target) != tmode
3682 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
3683 + target = gen_reg_rtx (tmode);
3685 + /* Emit and return the new instruction. */
3686 + pat = GEN_FCN (icode) (target, op0);
3694 +/* Expand a call to a builtin function. */
3696 +ubicom32_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
3697 + enum machine_mode mode ATTRIBUTE_UNUSED,
3698 + int ignore ATTRIBUTE_UNUSED)
3700 + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3701 + tree arglist = CALL_EXPR_ARGS(exp);
3702 + int fcode = DECL_FUNCTION_CODE (fndecl);
3706 + case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3707 + return ubicom32_expand_builtin_2op (CODE_FOR_bswaphi, arglist, target);
3709 + case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3710 + return ubicom32_expand_builtin_2op (CODE_FOR_bswapsi, arglist, target);
3713 + gcc_unreachable();
3716 + /* Should really do something sensible here. */
3720 +/* Fold any constant argument for a swapb.2 instruction. */
3722 +ubicom32_fold_builtin_ubicom32_swapb_2 (tree fndecl, tree arglist)
3726 + arg0 = TREE_VALUE (arglist);
3728 + /* Optimize constant value. */
3729 + if (TREE_CODE (arg0) == INTEGER_CST)
3732 + HOST_WIDE_INT res;
3734 + v = TREE_INT_CST_LOW (arg0);
3735 + res = ((v >> 8) & 0xff)
3736 + | ((v & 0xff) << 8);
3738 + return build_int_cst (TREE_TYPE (TREE_TYPE (fndecl)), res);
3744 +/* Fold any constant argument for a swapb.4 instruction. */
3746 +ubicom32_fold_builtin_ubicom32_swapb_4 (tree fndecl, tree arglist)
3750 + arg0 = TREE_VALUE (arglist);
3752 + /* Optimize constant value. */
3753 + if (TREE_CODE (arg0) == INTEGER_CST)
3755 + unsigned HOST_WIDE_INT v;
3756 + unsigned HOST_WIDE_INT res;
3758 + v = TREE_INT_CST_LOW (arg0);
3759 + res = ((v >> 24) & 0xff)
3760 + | (((v >> 16) & 0xff) << 8)
3761 + | (((v >> 8) & 0xff) << 16)
3762 + | ((v & 0xff) << 24);
3764 + return build_int_cst_wide (TREE_TYPE (TREE_TYPE (fndecl)), res, 0);
3770 +/* Fold any constant arguments for builtin functions. */
3772 +ubicom32_fold_builtin (tree fndecl, tree arglist, bool ignore ATTRIBUTE_UNUSED)
3774 + switch (DECL_FUNCTION_CODE (fndecl))
3776 + case UBICOM32_BUILTIN_UBICOM32_SWAPB_2:
3777 + return ubicom32_fold_builtin_ubicom32_swapb_2 (fndecl, arglist);
3779 + case UBICOM32_BUILTIN_UBICOM32_SWAPB_4:
3780 + return ubicom32_fold_builtin_ubicom32_swapb_4 (fndecl, arglist);
3787 +/* Implementation of TARGET_ASM_INTEGER. When using FD-PIC, we need to
3788 + tell the assembler to generate pointers to function descriptors in
3791 +ubicom32_assemble_integer (rtx value, unsigned int size, int aligned_p)
3793 + if (TARGET_FDPIC && size == UNITS_PER_WORD)
3795 + if (GET_CODE (value) == SYMBOL_REF
3796 + && SYMBOL_REF_FUNCTION_P (value))
3798 + fputs ("\t.picptr\t%funcdesc(", asm_out_file);
3799 + output_addr_const (asm_out_file, value);
3800 + fputs (")\n", asm_out_file);
3806 + /* We've set the unaligned SI op to NULL, so we always have to
3807 + handle the unaligned case here. */
3808 + assemble_integer_with_op ("\t.4byte\t", value);
3813 + return default_assemble_integer (value, size, aligned_p);
3816 +/* If the constant I can be constructed by shifting a source-1 immediate
3817 + by a constant number of bits then return the bit count. If not
3821 +ubicom32_shiftable_const_int (int i)
3825 + /* Note that any constant that can be represented as an immediate to
3826 + a movei instruction is automatically ignored here in the interests
3827 + of the clarity of the output asm code. */
3828 + if (i >= -32768 && i <= 32767)
3831 + /* Find the number of trailing zeroes. We could use __builtin_ctz
3832 + here but it's not obvious if this is supported on all build
3833 + compilers so we err on the side of caution. */
3834 + if ((i & 0xffff) == 0)
3840 + if ((i & 0xff) == 0)
3846 + if ((i & 0xf) == 0)
3852 + if ((i & 0x3) == 0)
3858 + if ((i & 0x1) == 0)
3864 + if (i >= -128 && i <= 127)
3871 +++ b/gcc/config/ubicom32/ubicom32.h
3873 +/* Definitions of target machine for Ubicom32
3875 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
3876 + 2009 Free Software Foundation, Inc.
3877 + Contributed by Ubicom, Inc.
3879 + This file is part of GCC.
3881 + GCC is free software; you can redistribute it and/or modify it
3882 + under the terms of the GNU General Public License as published
3883 + by the Free Software Foundation; either version 3, or (at your
3884 + option) any later version.
3886 + GCC is distributed in the hope that it will be useful, but WITHOUT
3887 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
3888 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
3889 + License for more details.
3891 + You should have received a copy of the GNU General Public License
3892 + along with GCC; see the file COPYING3. If not see
3893 + <http://www.gnu.org/licenses/>. */
3897 +#define OBJECT_FORMAT_ELF
3899 +/* Run-time target specifications. */
3901 +/* Target CPU builtins. */
3902 +#define TARGET_CPU_CPP_BUILTINS() \
3905 + builtin_define_std ("__UBICOM32__"); \
3906 + builtin_define_std ("__ubicom32__"); \
3908 + if (TARGET_FDPIC) \
3910 + builtin_define ("__UBICOM32_FDPIC__"); \
3911 + builtin_define ("__FDPIC__"); \
3916 +#ifndef TARGET_DEFAULT
3917 +#define TARGET_DEFAULT 0
3920 +extern int ubicom32_case_values_threshold;
3922 +/* Nonzero if this chip supports the Ubicom32 v3 ISA. */
3923 +extern int ubicom32_v3;
3925 +/* Nonzero if this chip supports the Ubicom32 v4 ISA. */
3926 +extern int ubicom32_v4;
3928 +extern int ubicom32_stack_size;
3930 +/* Flag for whether we can use calli instead of ret in returns. */
3931 +extern int ubicom32_can_use_calli_to_ret;
3933 +/* This macro is a C statement to print on `stderr' a string describing the
3934 + particular machine description choice. Every machine description should
3935 + define `TARGET_VERSION'. */
3936 +#define TARGET_VERSION fprintf (stderr, " (UBICOM32)");
3938 +/* We don't need a frame pointer to debug things. Doing this means
3939 + that gcc can turn on -fomit-frame-pointer when '-O' is specified. */
3940 +#define CAN_DEBUG_WITHOUT_FP
3942 +/* We need to handle processor-specific options. */
3943 +#define OVERRIDE_OPTIONS ubicom32_override_options ()
3945 +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) \
3946 + ubicom32_optimization_options (LEVEL, SIZE)
3948 +/* For Ubicom32 the least significant bit has the lowest bit number
3949 + so we define this to be 0. */
3950 +#define BITS_BIG_ENDIAN 0
3952 +/* For Ubicom32 the most significant byte in a word has the lowest
3954 +#define BYTES_BIG_ENDIAN 1
3956 +/* For Ubicom32, in a multiword object, the most signifant word has the
3958 +#define WORDS_BIG_ENDIAN 1
3960 +/* Ubicom32 has 8 bits per byte. */
3961 +#define BITS_PER_UNIT 8
3963 +/* Ubicom32 has 32 bits per word. */
3964 +#define BITS_PER_WORD 32
3966 +/* Width of a word, in units (bytes). */
3967 +#define UNITS_PER_WORD 4
3969 +/* Width of a pointer, in bits. */
3970 +#define POINTER_SIZE 32
3972 +/* Alias for pointers. Ubicom32 is a 32-bit architecture so we use
3974 +#define Pmode SImode
3976 +/* Normal alignment required for function parameters on the stack, in
3978 +#define PARM_BOUNDARY 32
3980 +/* We need to maintain the stack on a 32-bit boundary. */
3981 +#define STACK_BOUNDARY 32
3983 +/* Alignment required for a function entry point, in bits. */
3984 +#define FUNCTION_BOUNDARY 32
3986 +/* Alias for the machine mode used for memory references to functions being
3987 + called, in `call' RTL expressions. We use byte-oriented addresses
3989 +#define FUNCTION_MODE QImode
3991 +/* Biggest alignment that any data type can require on this machine,
3993 +#define BIGGEST_ALIGNMENT 32
3995 +/* this default to BIGGEST_ALIGNMENT unless defined */
3996 +/* ART: What's the correct value here? Default is (((unsigned int)1<<28)*8)*/
3997 +#undef MAX_OFILE_ALIGNMENT
3998 +#define MAX_OFILE_ALIGNMENT (128 * 8)
4000 +/* Alignment in bits to be given to a structure bit field that follows an empty
4001 + field such as `int : 0;'. */
4002 +#define EMPTY_FIELD_BOUNDARY 32
4004 +/* All structures must be a multiple of 32 bits in size. */
4005 +#define STRUCTURE_SIZE_BOUNDARY 32
4007 +/* A bit-field declared as `int' forces `int' alignment for the struct. */
4008 +#define PCC_BITFIELD_TYPE_MATTERS 1
4010 +/* For Ubicom32 we absolutely require that data be aligned with nominal
4012 +#define STRICT_ALIGNMENT 1
4014 +/* Make strcpy of constants fast. */
4015 +#define CONSTANT_ALIGNMENT(EXP, ALIGN) \
4016 + (TREE_CODE (EXP) == STRING_CST \
4017 + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
4019 +/* Define this macro as an expression for the alignment of a structure
4020 + (given by STRUCT as a tree node) if the alignment computed in the
4021 + usual way is COMPUTED and the alignment explicitly specified was
4023 +#define DATA_ALIGNMENT(TYPE, ALIGN) \
4024 + ((((ALIGN) < BITS_PER_WORD) \
4025 + && (TREE_CODE (TYPE) == ARRAY_TYPE \
4026 + || TREE_CODE (TYPE) == UNION_TYPE \
4027 + || TREE_CODE (TYPE) == RECORD_TYPE)) ? BITS_PER_WORD : (ALIGN))
4029 +#define LOCAL_ALIGNMENT(TYPE,ALIGN) DATA_ALIGNMENT(TYPE,ALIGN)
4031 +/* For Ubicom32 we default to unsigned chars. */
4032 +#define DEFAULT_SIGNED_CHAR 0
4034 +/* Machine-specific data register numbers. */
4035 +#define FIRST_DATA_REGNUM 0
4036 +#define D10_REGNUM 10
4037 +#define D11_REGNUM 11
4038 +#define D12_REGNUM 12
4039 +#define D13_REGNUM 13
4040 +#define LAST_DATA_REGNUM 15
4042 +/* Machine-specific address register numbers. */
4043 +#define FIRST_ADDRESS_REGNUM 16
4044 +#define LAST_ADDRESS_REGNUM 22
4046 +/* Register numbers used for passing a function's static chain pointer. If
4047 + register windows are used, the register number as seen by the called
4048 + function is `STATIC_CHAIN_INCOMING_REGNUM', while the register number as
4049 + seen by the calling function is `STATIC_CHAIN_REGNUM'. If these registers
4050 + are the same, `STATIC_CHAIN_INCOMING_REGNUM' need not be defined.
4052 + The static chain register need not be a fixed register.
4054 + If the static chain is passed in memory, these macros should not be defined;
4055 + instead, the next two macros should be defined. */
4056 +#define STATIC_CHAIN_REGNUM (FIRST_ADDRESS_REGNUM + 1)
4058 +/* The register number of the frame pointer register, which is used to access
4059 + automatic variables in the stack frame. We generally eliminate this anyway
4060 + for Ubicom32 but we make it A6 by default. */
4061 +#define FRAME_POINTER_REGNUM (LAST_ADDRESS_REGNUM)
4063 +/* The register number of the stack pointer register, which is also be a
4064 + fixed register according to `FIXED_REGISTERS'. For Ubicom32 we don't
4065 + have a hardware requirement about which register this is, but by convention
4067 +#define STACK_POINTER_REGNUM (LAST_ADDRESS_REGNUM + 1)
4069 +/* Machine-specific accumulator register numbers. */
4070 +#define ACC0_HI_REGNUM 24
4071 +#define ACC0_LO_REGNUM 25
4072 +#define ACC1_HI_REGNUM 26
4073 +#define ACC1_LO_REGNUM 27
4075 +/* source3 register number */
4076 +#define SOURCE3_REGNUM 28
4078 +/* The register number of the arg pointer register, which is used to access the
4079 + function's argument list. On some machines, this is the same as the frame
4080 + pointer register. On some machines, the hardware determines which register
4081 + this is. On other machines, you can choose any register you wish for this
4082 + purpose. If this is not the same register as the frame pointer register,
4083 + then you must mark it as a fixed register according to `FIXED_REGISTERS', or
4084 + arrange to be able to eliminate it. */
4085 +#define ARG_POINTER_REGNUM 29
4087 +/* Pseudo-reg for condition code. */
4088 +#define CC_REGNUM 30
4090 +/* Interrupt set/clear registers. */
4091 +#define INT_SET0_REGNUM 31
4092 +#define INT_SET1_REGNUM 32
4093 +#define INT_CLR0_REGNUM 33
4094 +#define INT_CLR1_REGNUM 34
4096 +/* Scratchpad registers. */
4097 +#define SCRATCHPAD0_REGNUM 35
4098 +#define SCRATCHPAD1_REGNUM 36
4099 +#define SCRATCHPAD2_REGNUM 37
4100 +#define SCRATCHPAD3_REGNUM 38
4102 +/* FDPIC register. */
4103 +#define FDPIC_REGNUM 16
4105 +/* Number of hardware registers known to the compiler. They receive numbers 0
4106 + through `FIRST_PSEUDO_REGISTER-1'; thus, the first pseudo register's number
4107 + really is assigned the number `FIRST_PSEUDO_REGISTER'. */
4108 +#define FIRST_PSEUDO_REGISTER 39
4110 +/* An initializer that says which registers are used for fixed purposes all
4111 + throughout the compiled code and are therefore not available for general
4112 + allocation. These would include the stack pointer, the frame pointer
4113 + (except on machines where that can be used as a general register when no
4114 + frame pointer is needed), the program counter on machines where that is
4115 + considered one of the addressable registers, and any other numbered register
4116 + with a standard use.
4118 + This information is expressed as a sequence of numbers, separated by commas
4119 + and surrounded by braces. The Nth number is 1 if register N is fixed, 0
4122 + The table initialized from this macro, and the table initialized by the
4123 + following one, may be overridden at run time either automatically, by the
4124 + actions of the macro `CONDITIONAL_REGISTER_USAGE', or by the user with the
4125 + command options `-ffixed-REG', `-fcall-used-REG' and `-fcall-saved-REG'. */
4126 +#define FIXED_REGISTERS \
4128 + 0, 0, 0, 0, 0, 0, 0, 0, /* d0 - d7 */ \
4129 + 0, 0, 0, 0, 0, 0, 0, 1, /* d8 - d15 */ \
4130 + 0, 0, 0, 0, 0, 0, 0, 1, /* a0 - a7 */ \
4131 + 0, 0, /* acc0 hi/lo */ \
4132 + 0, 0, /* acc1 hi/lo */ \
4133 + 0, /* source3 */ \
4136 + 1, 1, /* int_set[01] */ \
4137 + 1, 1, /* int_clr[01] */ \
4138 + 1, 1, 1, 1 /* scratchpad[0123] */ \
4141 +/* Like `FIXED_REGISTERS' but has 1 for each register that is clobbered (in
4142 + general) by function calls as well as for fixed registers. This macro
4143 + therefore identifies the registers that are not available for general
4144 + allocation of values that must live across function calls.
4146 + If a register has 0 in `CALL_USED_REGISTERS', the compiler automatically
4147 + saves it on function entry and restores it on function exit, if the register
4148 + is used within the function. */
4149 +#define CALL_USED_REGISTERS \
4151 + 1, 1, 1, 1, 1, 1, 1, 1, /* d0 - d7 */ \
4152 + 1, 1, 0, 0, 0, 0, 1, 1, /* d8 - d15 */ \
4153 + 1, 0, 0, 1, 1, 1, 0, 1, /* a0 - a7 */ \
4154 + 1, 1, /* acc0 hi/lo */ \
4155 + 1, 1, /* acc1 hi/lo */ \
4156 + 1, /* source3 */ \
4159 + 1, 1, /* int_set[01] */ \
4160 + 1, 1, /* int_clr[01] */ \
4161 + 1, 1, 1, 1 /* scratchpad[0123] */ \
4164 +/* How to refer to registers in assembler output.
4165 + This sequence is indexed by compiler's hard-register-number (see above). */
4167 +/* A C initializer containing the assembler's names for the machine registers,
4168 + each one as a C string constant. This is what translates register numbers
4169 + in the compiler into assembler language. */
4170 +#define REGISTER_NAMES \
4172 + "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
4173 + "d8", "d9", "d10", "d11", "d12", "d13", "d14", "d15", \
4174 + "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp", \
4175 + "acc0_hi", "acc0_lo", \
4176 + "acc1_hi", "acc1_lo", \
4180 + "int_set0", "int_set1", \
4181 + "int_clr0", "int_clr1", \
4182 + "scratchpad0", "scratchpad1", "scratchpad2", "scratchpad3" \
4185 +#define CONDITIONAL_REGISTER_USAGE \
4186 + ubicom32_conditional_register_usage ();
4188 +/* Order of allocation of registers. */
4190 +/* If defined, an initializer for a vector of integers, containing the numbers
4191 + of hard registers in the order in which GNU CC should prefer to use them
4192 + (from most preferred to least).
4194 + For Ubicom32 we try using caller-clobbered data registers first, then
4195 + callee-saved data registers, then caller-clobbered address registers,
4196 + then callee-saved address registers and finally everything else.
4198 + The caller-clobbered registers are usually slightly cheaper to use because
4199 + there's no need to save/restore. */
4200 +#define REG_ALLOC_ORDER \
4202 + 0, 1, 2, 3, 4, /* d0 - d4 */ \
4203 + 5, 6, 7, 8, 9, /* d5 - d9 */ \
4205 + 10, 11, 12, 13, /* d10 - d13 */ \
4206 + 19, 20, 16, 21, /* a3, a4, a0, a5 */ \
4207 + 17, 18, 22, /* a1, a2, a6 */ \
4208 + 24, 25, /* acc0 hi/lo */ \
4209 + 26, 27, /* acc0 hi/lo */ \
4210 + 28 /* source3 */ \
4213 +/* C expression for the number of consecutive hard registers, starting at
4214 + register number REGNO, required to hold a value of mode MODE. */
4215 +#define HARD_REGNO_NREGS(REGNO, MODE) \
4216 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4218 +/* Most registers can hold QImode, HImode and SImode values but we have to
4219 + be able to indicate any hard registers that cannot hold values with some
4221 +#define HARD_REGNO_MODE_OK(REGNO, MODE) \
4222 + ubicom32_hard_regno_mode_ok(REGNO, MODE)
4224 +/* We can rename most registers aside from the FDPIC register if we're using
4226 +#define HARD_REGNO_RENAME_OK(from, to) (TARGET_FDPIC ? ((to) != FDPIC_REGNUM) : 1)
4228 +/* A C expression that is nonzero if it is desirable to choose register
4229 + allocation so as to avoid move instructions between a value of mode MODE1
4230 + and a value of mode MODE2.
4232 + If `HARD_REGNO_MODE_OK (R, MODE1)' and `HARD_REGNO_MODE_OK (R, MODE2)' are
4233 + ever different for any R, then `MODES_TIEABLE_P (MODE1, MODE2)' must be
4235 +#define MODES_TIEABLE_P(MODE1, MODE2) 1
4237 +/* An enumeral type that must be defined with all the register class names as
4238 + enumeral values. `NO_REGS' must be first. `ALL_REGS' must be the last
4239 + register class, followed by one more enumeral value, `LIM_REG_CLASSES',
4240 + which is not a register class but rather tells how many classes there are.
4242 + Each register class has a number, which is the value of casting the class
4243 + name to type `int'. The number serves as an index in many of the tables
4244 + described below. */
4264 +/* The number of distinct register classes. */
4265 +#define N_REG_CLASSES (int) LIM_REG_CLASSES
4267 +/* An initializer containing the names of the register classes as C string
4268 + constants. These names are used in writing some of the debugging dumps. */
4270 +#define REG_CLASS_NAMES \
4276 + "ALL_ADDRESS_REGS", \
4280 + "DATA_ACC_REGS", \
4288 +/* An initializer containing the contents of the register classes, as integers
4289 + which are bit masks. The Nth integer specifies the contents of class N.
4290 + The way the integer MASK is interpreted is that register R is in the class
4291 + if `MASK & (1 << R)' is 1.
4293 + When the machine has more than 32 registers, an integer does not suffice.
4294 + Then the integers are replaced by sub-initializers, braced groupings
4295 + containing several integers. Each sub-initializer must be suitable as an
4296 + initializer for the type `HARD_REG_SET' which is defined in
4297 + `hard-reg-set.h'. */
4298 +#define REG_CLASS_CONTENTS \
4300 + {0x00000000, 0x00000000}, /* No regs */ \
4301 + {0x0000ffff, 0x00000000}, /* DATA_REGS */ \
4302 + {0x00010000, 0x00000000}, /* FDPIC_REG */ \
4303 + {0x20fe0000, 0x00000000}, /* ADDRESS_REGS */ \
4304 + {0x20ff0000, 0x00000000}, /* ALL_ADDRESS_REGS */ \
4305 + {0x0a000000, 0x00000000}, /* ACC_LO_REGS */ \
4306 + {0x0f000000, 0x00000000}, /* ACC_REGS */ \
4307 + {0x40000000, 0x00000000}, /* CC_REG */ \
4308 + {0x0f00ffff, 0x00000000}, /* DATA_ACC_REGS */ \
4309 + {0x10000000, 0x00000000}, /* SOURGE3_REG */ \
4310 + {0x80000000, 0x0000007f}, /* SPECIAL_REGS */ \
4311 + {0xbfffffff, 0x0000007f}, /* GENERAL_REGS */ \
4312 + {0xbfffffff, 0x0000007f} /* ALL_REGS */ \
4315 +extern enum reg_class const ubicom32_regclass_map[FIRST_PSEUDO_REGISTER];
4317 +/* A C expression whose value is a register class containing hard register
4318 + REGNO. In general there is more than one such class; choose a class which
4319 + is "minimal", meaning that no smaller class also contains the register. */
4320 +#define REGNO_REG_CLASS(REGNO) (ubicom32_regclass_map[REGNO])
4322 +#define IRA_COVER_CLASSES \
4328 +/* Ubicom32 base registers must be address registers since addresses can
4329 + only be reached via address registers. */
4330 +#define BASE_REG_CLASS ALL_ADDRESS_REGS
4332 +/* Ubicom32 index registers must be data registers since we cannot add
4333 + two address registers together to form an address. */
4334 +#define INDEX_REG_CLASS DATA_REGS
4336 +/* A C expression which is nonzero if register number NUM is suitable for use
4337 + as a base register in operand addresses. It may be either a suitable hard
4338 + register or a pseudo register that has been allocated such a hard register. */
4340 +#ifndef REG_OK_STRICT
4341 +#define REGNO_OK_FOR_BASE_P(regno) \
4342 + ubicom32_regno_ok_for_base_p (regno, 0)
4344 +#define REGNO_OK_FOR_BASE_P(regno) \
4345 + ubicom32_regno_ok_for_base_p (regno, 1)
4348 +/* A C expression which is nonzero if register number NUM is suitable for use
4349 + as an index register in operand addresses. It may be either a suitable hard
4350 + register or a pseudo register that has been allocated such a hard register.
4352 + The difference between an index register and a base register is that the
4353 + index register may be scaled. If an address involves the sum of two
4354 + registers, neither one of them scaled, then either one may be labeled the
4355 + "base" and the other the "index"; but whichever labeling is used must fit
4356 + the machine's constraints of which registers may serve in each capacity.
4357 + The compiler will try both labelings, looking for one that is valid, and
4358 + will reload one or both registers only if neither labeling works. */
4359 +#ifndef REG_OK_STRICT
4360 +#define REGNO_OK_FOR_INDEX_P(regno) \
4361 + ubicom32_regno_ok_for_index_p (regno, 0)
4363 +#define REGNO_OK_FOR_INDEX_P(regno) \
4364 + ubicom32_regno_ok_for_index_p (regno, 1)
4367 +/* Attempt to restrict the register class we need to copy value X intoto the
4368 + would-be register class CLASS. Most things are fine for Ubicom32 but we
4369 + have to restrict certain types of address loads. */
4370 +#define PREFERRED_RELOAD_CLASS(X, CLASS) \
4371 + ubicom32_preferred_reload_class (X, CLASS)
4373 +/* A C expression for the maximum number of consecutive registers of
4374 + class CLASS needed to hold a value of mode MODE. For Ubicom32 this
4375 + is pretty much identical to HARD_REGNO_NREGS. */
4376 +#define CLASS_MAX_NREGS(CLASS, MODE) \
4377 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
4379 +/* For Ubicom32 the stack grows downwards when we push a word onto the stack
4380 + - i.e. it moves to a smaller address. */
4381 +#define STACK_GROWS_DOWNWARD 1
4383 +/* Offset from the frame pointer to the first local variable slot to
4385 +#define STARTING_FRAME_OFFSET 0
4387 +/* Offset from the argument pointer register to the first argument's
4389 +#define FIRST_PARM_OFFSET(FNDECL) 0
4391 +/* A C expression whose value is RTL representing the value of the return
4392 + address for the frame COUNT steps up from the current frame, after the
4393 + prologue. FRAMEADDR is the frame pointer of the COUNT frame, or the frame
4394 + pointer of the COUNT - 1 frame if `RETURN_ADDR_IN_PREVIOUS_FRAME' is
4397 + The value of the expression must always be the correct address when COUNT is
4398 + zero, but may be `NULL_RTX' if there is not way to determine the return
4399 + address of other frames. */
4400 +#define RETURN_ADDR_RTX(COUNT, FRAME) \
4401 + ubicom32_return_addr_rtx (COUNT, FRAME)
4403 +/* Register That Address the Stack Frame. */
4405 +/* We don't actually require a frame pointer in most functions with the
4406 + Ubicom32 architecture so we allow it to be eliminated. */
4407 +#define FRAME_POINTER_REQUIRED 0
4409 +/* Macro that defines a table of register pairs used to eliminate unecessary
4410 + registers that point into the stack frame.
4412 + For Ubicom32 we don't generally need an arg pointer of a frame pointer
4413 + so we allow the arg pointer to be replaced by either the frame pointer or
4414 + the stack pointer. We also allow the frame pointer to be replaced by
4415 + the stack pointer. */
4416 +#define ELIMINABLE_REGS \
4418 + {ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
4419 + {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
4420 + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM} \
4423 +/* Let the compiler know that we want to use the ELIMINABLE_REGS macro
4425 +#define CAN_ELIMINATE(FROM, TO) 1
4427 +/* This macro is similar to `INITIAL_FRAME_POINTER_OFFSET'. It specifies the
4428 + initial difference between the specified pair of registers. This macro must
4429 + be defined if `ELIMINABLE_REGS' is defined. */
4430 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
4431 + (OFFSET) = ubicom32_initial_elimination_offset (FROM, TO)
4433 +/* If defined, the maximum amount of space required for outgoing arguments will
4434 + be computed and placed into the variable
4435 + `current_function_outgoing_args_size'. No space will be pushed onto the
4436 + stack for each call; instead, the function prologue should increase the
4437 + stack frame size by this amount.
4439 + Defining both `PUSH_ROUNDING' and `ACCUMULATE_OUTGOING_ARGS' is not
4441 +#define ACCUMULATE_OUTGOING_ARGS 1
4443 +/* Define this macro if functions should assume that stack space has been
4444 + allocated for arguments even when their values are passed in registers.
4446 + The value of this macro is the size, in bytes, of the area reserved for
4447 + arguments passed in registers for the function represented by FNDECL.
4449 + This space can be allocated by the caller, or be a part of the
4450 + machine-dependent stack frame: `OUTGOING_REG_PARM_STACK_SPACE' says
4452 +#define REG_PARM_STACK_SPACE(FNDECL) ubicom32_reg_parm_stack_space(FNDECL)
4454 +/* A C expression that should indicate the number of bytes of its own arguments
4455 + that a function pops on returning, or 0 if the function pops no arguments
4456 + and the caller must therefore pop them all after the function returns.
4458 + FUNDECL is a C variable whose value is a tree node that describes the
4459 + function in question. Normally it is a node of type `FUNCTION_DECL' that
4460 + describes the declaration of the function. From this it is possible to
4461 + obtain the DECL_MACHINE_ATTRIBUTES of the function.
4463 + FUNTYPE is a C variable whose value is a tree node that describes the
4464 + function in question. Normally it is a node of type `FUNCTION_TYPE' that
4465 + describes the data type of the function. From this it is possible to obtain
4466 + the data types of the value and arguments (if known).
4468 + When a call to a library function is being considered, FUNTYPE will contain
4469 + an identifier node for the library function. Thus, if you need to
4470 + distinguish among various library functions, you can do so by their names.
4471 + Note that "library function" in this context means a function used to
4472 + perform arithmetic, whose name is known specially in the compiler and was
4473 + not mentioned in the C code being compiled.
4475 + STACK-SIZE is the number of bytes of arguments passed on the stack. If a
4476 + variable number of bytes is passed, it is zero, and argument popping will
4477 + always be the responsibility of the calling function.
4479 + On the Vax, all functions always pop their arguments, so the definition of
4480 + this macro is STACK-SIZE. On the 68000, using the standard calling
4481 + convention, no functions pop their arguments, so the value of the macro is
4482 + always 0 in this case. But an alternative calling convention is available
4483 + in which functions that take a fixed number of arguments pop them but other
4484 + functions (such as `printf') pop nothing (the caller pops all). When this
4485 + convention is in use, FUNTYPE is examined to determine whether a function
4486 + takes a fixed number of arguments. */
4487 +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
4489 +/* A C expression that controls whether a function argument is passed in a
4490 + register, and which register.
4492 + The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes (in a way
4493 + defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE) all of the previous
4494 + arguments so far passed in registers; MODE, the machine mode of the argument;
4495 + TYPE, the data type of the argument as a tree node or 0 if that is not known
4496 + (which happens for C support library functions); and NAMED, which is 1 for an
4497 + ordinary argument and 0 for nameless arguments that correspond to `...' in the
4498 + called function's prototype.
4500 + The value of the expression should either be a `reg' RTX for the hard
4501 + register in which to pass the argument, or zero to pass the argument on the
4504 + For machines like the Vax and 68000, where normally all arguments are
4505 + pushed, zero suffices as a definition.
4507 + The usual way to make the ANSI library `stdarg.h' work on a machine where
4508 + some arguments are usually passed in registers, is to cause nameless
4509 + arguments to be passed on the stack instead. This is done by making
4510 + `FUNCTION_ARG' return 0 whenever NAMED is 0.
4512 + You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the definition of
4513 + this macro to determine if this argument is of a type that must be passed in
4514 + the stack. If `REG_PARM_STACK_SPACE' is not defined and `FUNCTION_ARG'
4515 + returns non-zero for such an argument, the compiler will abort. If
4516 + `REG_PARM_STACK_SPACE' is defined, the argument will be computed in the
4517 + stack and then loaded into a register. */
4518 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
4519 + function_arg (&CUM, MODE, TYPE, NAMED)
4521 +#define FUNCTION_INCOMING_ARG(CUM, MODE, TYPE, NAMED) \
4522 + function_incoming_arg (&CUM, MODE, TYPE, NAMED)
4524 +/* A C expression for the number of words, at the beginning of an argument,
4525 + must be put in registers. The value must be zero for arguments that are
4526 + passed entirely in registers or that are entirely pushed on the stack.
4528 + On some machines, certain arguments must be passed partially in registers
4529 + and partially in memory. On these machines, typically the first N words of
4530 + arguments are passed in registers, and the rest on the stack. If a
4531 + multi-word argument (a `double' or a structure) crosses that boundary, its
4532 + first few words must be passed in registers and the rest must be pushed.
4533 + This macro tells the compiler when this occurs, and how many of the words
4534 + should go in registers.
4536 + `FUNCTION_ARG' for these arguments should return the first register to be
4537 + used by the caller for this argument; likewise `FUNCTION_INCOMING_ARG', for
4538 + the called function. */
4540 +/* A C expression that indicates when an argument must be passed by reference.
4541 + If nonzero for an argument, a copy of that argument is made in memory and a
4542 + pointer to the argument is passed instead of the argument itself. The
4543 + pointer is passed in whatever way is appropriate for passing a pointer to
4546 + On machines where `REG_PARM_STACK_SPACE' is not defined, a suitable
4547 + definition of this macro might be
4548 + #define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
4549 + MUST_PASS_IN_STACK (MODE, TYPE) */
4551 +/* If defined, a C expression that indicates when it is the called function's
4552 + responsibility to make a copy of arguments passed by invisible reference.
4553 + Normally, the caller makes a copy and passes the address of the copy to the
4554 + routine being called. When FUNCTION_ARG_CALLEE_COPIES is defined and is
4555 + nonzero, the caller does not make a copy. Instead, it passes a pointer to
4556 + the "live" value. The called function must not modify this value. If it
4557 + can be determined that the value won't be modified, it need not make a copy;
4558 + otherwise a copy must be made. */
4560 +/* A C type for declaring a variable that is used as the first argument of
4561 + `FUNCTION_ARG' and other related values. For some target machines, the type
4562 + `int' suffices and can hold the number of bytes of argument so far.
4564 + There is no need to record in `CUMULATIVE_ARGS' anything about the arguments
4565 + that have been passed on the stack. The compiler has other variables to
4566 + keep track of that. For target machines on which all arguments are passed
4567 + on the stack, there is no need to store anything in `CUMULATIVE_ARGS';
4568 + however, the data structure must exist and should not be empty, so use
4576 +#define CUMULATIVE_ARGS struct cum_arg
4578 +/* A C statement (sans semicolon) for initializing the variable CUM for the
4579 + state at the beginning of the argument list. The variable has type
4580 + `CUMULATIVE_ARGS'. The value of FNTYPE is the tree node for the data type
4581 + of the function which will receive the args, or 0 if the args are to a
4582 + compiler support library function. The value of INDIRECT is nonzero when
4583 + processing an indirect call, for example a call through a function pointer.
4584 + The value of INDIRECT is zero for a call to an explicitly named function, a
4585 + library function call, or when `INIT_CUMULATIVE_ARGS' is used to find
4586 + arguments for the function being compiled.
4588 + When processing a call to a compiler support library function, LIBNAME
4589 + identifies which one. It is a `symbol_ref' rtx which contains the name of
4590 + the function, as a string. LIBNAME is 0 when an ordinary C function call is
4591 + being processed. Thus, each time this macro is called, either LIBNAME or
4592 + FNTYPE is nonzero, but never both of them at once. */
4594 +#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT, NAMED_ARGS) \
4595 + init_cumulative_args (&(CUM), FNTYPE, LIBNAME, INDIRECT);
4597 +/* A C statement (sans semicolon) to update the summarizer variable CUM to
4598 + advance past an argument in the argument list. The values MODE, TYPE and
4599 + NAMED describe that argument. Once this is done, the variable CUM is
4600 + suitable for analyzing the *following* argument with `FUNCTION_ARG', etc.
4602 + This macro need not do anything if the argument in question was passed on
4603 + the stack. The compiler knows how to track the amount of stack space used
4604 + for arguments without any special help. */
4605 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
4606 + ((CUM).nbytes += ((MODE) != BLKmode \
4607 + ? (GET_MODE_SIZE (MODE) + 3) & ~3 \
4608 + : (int_size_in_bytes (TYPE) + 3) & ~3))
4610 +/* For the Ubicom32 we define the upper function argument register here. */
4611 +#define UBICOM32_FUNCTION_ARG_REGS 10
4613 +/* A C expression that is nonzero if REGNO is the number of a hard register in
4614 + which function arguments are sometimes passed. This does *not* include
4615 + implicit arguments such as the static chain and the structure-value address.
4616 + On many machines, no registers can be used for this purpose since all
4617 + function arguments are pushed on the stack. */
4618 +#define FUNCTION_ARG_REGNO_P(N) ((N) < UBICOM32_FUNCTION_ARG_REGS)
4621 +/* How Scalar Function Values are Returned. */
4623 +/* The number of the hard register that is used to return a scalar value from a
4625 +#define RETURN_VALUE_REGNUM 0
4627 +/* A C expression to create an RTX representing the place where a function
4628 + returns a value of data type VALTYPE. VALTYPE is a tree node representing a
4629 + data type. Write `TYPE_MODE (VALTYPE)' to get the machine mode used to
4630 + represent that type. On many machines, only the mode is relevant.
4631 + (Actually, on most machines, scalar values are returned in the same place
4632 + regardless of mode).
4634 + If `PROMOTE_FUNCTION_RETURN' is defined, you must apply the same promotion
4635 + rules specified in `PROMOTE_MODE' if VALTYPE is a scalar type.
4637 + If the precise function being called is known, FUNC is a tree node
4638 + (`FUNCTION_DECL') for it; otherwise, FUNC is a null pointer. This makes it
4639 + possible to use a different value-returning convention for specific
4640 + functions when all their calls are known.
4642 + `FUNCTION_VALUE' is not used for return vales with aggregate data types,
4643 + because these are returned in another way. See `STRUCT_VALUE_REGNUM' and
4644 + related macros, below. */
4645 +#define FUNCTION_VALUE(VALTYPE, FUNC) \
4646 + gen_rtx_REG (TYPE_MODE (VALTYPE), FIRST_DATA_REGNUM)
4648 +/* A C expression to create an RTX representing the place where a library
4649 + function returns a value of mode MODE.
4651 + Note that "library function" in this context means a compiler support
4652 + routine, used to perform arithmetic, whose name is known specially by the
4653 + compiler and was not mentioned in the C code being compiled.
4655 + The definition of `LIBRARY_VALUE' need not be concerned aggregate data
4656 + types, because none of the library functions returns such types. */
4657 +#define LIBCALL_VALUE(MODE) gen_rtx_REG (MODE, FIRST_DATA_REGNUM)
4659 +/* A C expression that is nonzero if REGNO is the number of a hard register in
4660 + which the values of called function may come back.
4662 + A register whose use for returning values is limited to serving as the
4663 + second of a pair (for a value of type `double', say) need not be recognized
4664 + by this macro. So for most machines, this definition suffices:
4666 + #define FUNCTION_VALUE_REGNO_P(N) ((N) == RETURN)
4668 + If the machine has register windows, so that the caller and the called
4669 + function use different registers for the return value, this macro should
4670 + recognize only the caller's register numbers. */
4671 +#define FUNCTION_VALUE_REGNO_P(N) ((N) == FIRST_DATA_REGNUM)
4674 +/* How Large Values are Returned. */
4676 +/* A C expression which can inhibit the returning of certain function values in
4677 + registers, based on the type of value. A nonzero value says to return the
4678 + function value in memory, just as large structures are always returned.
4679 + Here TYPE will be a C expression of type `tree', representing the data type
4682 + Note that values of mode `BLKmode' must be explicitly handled by this macro.
4683 + Also, the option `-fpcc-struct-return' takes effect regardless of this
4684 + macro. On most systems, it is possible to leave the macro undefined; this
4685 + causes a default definition to be used, whose value is the constant 1 for
4686 + `BLKmode' values, and 0 otherwise.
4688 + Do not use this macro to indicate that structures and unions should always
4689 + be returned in memory. You should instead use `DEFAULT_PCC_STRUCT_RETURN'
4690 + to indicate this. */
4691 +#define RETURN_IN_MEMORY(TYPE) \
4692 + (int_size_in_bytes (TYPE) > 8 || TYPE_MODE (TYPE) == BLKmode)
4694 +/* Define this macro to be 1 if all structure and union return values must be
4695 + in memory. Since this results in slower code, this should be defined only
4696 + if needed for compatibility with other compilers or with an ABI. If you
4697 + define this macro to be 0, then the conventions used for structure and union
4698 + return values are decided by the `RETURN_IN_MEMORY' macro.
4700 + If not defined, this defaults to the value 1. */
4701 +#define DEFAULT_PCC_STRUCT_RETURN 0
4703 +/* If the structure value address is not passed in a register, define
4704 + `STRUCT_VALUE' as an expression returning an RTX for the place
4705 + where the address is passed. If it returns 0, the address is
4706 + passed as an "invisible" first argument. */
4707 +#define STRUCT_VALUE 0
4709 +/* Define this macro as a C expression that is nonzero if the return
4710 + instruction or the function epilogue ignores the value of the stack pointer;
4711 + in other words, if it is safe to delete an instruction to adjust the stack
4712 + pointer before a return from the function.
4714 + Note that this macro's value is relevant only for functions for which frame
4715 + pointers are maintained. It is never safe to delete a final stack
4716 + adjustment in a function that has no frame pointer, and the compiler knows
4717 + this regardless of `EXIT_IGNORE_STACK'. */
4718 +#define EXIT_IGNORE_STACK 1
4720 +/* A C statement or compound statement to output to FILE some assembler code to
4721 + call the profiling subroutine `mcount'. Before calling, the assembler code
4722 + must load the address of a counter variable into a register where `mcount'
4723 + expects to find the address. The name of this variable is `LP' followed by
4724 + the number LABELNO, so you would generate the name using `LP%d' in a
4727 + The details of how the address should be passed to `mcount' are determined
4728 + by your operating system environment, not by GNU CC. To figure them out,
4729 + compile a small program for profiling using the system's installed C
4730 + compiler and look at the assembler code that results.
4732 + This declaration must be present, but it can be an abort if profiling is
4733 + not implemented. */
4735 +#define FUNCTION_PROFILER(file, labelno) ubicom32_profiler(file, labelno)
4737 +/* A C statement to output, on the stream FILE, assembler code for a block of
4738 + data that contains the constant parts of a trampoline. This code should not
4739 + include a label--the label is taken care of automatically. */
4741 +#define TRAMPOLINE_TEMPLATE(FILE) \
4743 + fprintf (FILE, "\tadd -4,sp\n"); \
4744 + fprintf (FILE, "\t.long 0x0004fffa\n"); \
4745 + fprintf (FILE, "\tmov (0,sp),a0\n"); \
4746 + fprintf (FILE, "\tadd 4,sp\n"); \
4747 + fprintf (FILE, "\tmov (13,a0),a1\n"); \
4748 + fprintf (FILE, "\tmov (17,a0),a0\n"); \
4749 + fprintf (FILE, "\tjmp (a0)\n"); \
4750 + fprintf (FILE, "\t.long 0\n"); \
4751 + fprintf (FILE, "\t.long 0\n"); \
4755 +/* A C expression for the size in bytes of the trampoline, as an integer. */
4756 +#define TRAMPOLINE_SIZE 0x1b
4758 +/* Alignment required for trampolines, in bits.
4760 + If you don't define this macro, the value of `BIGGEST_ALIGNMENT' is used for
4761 + aligning trampolines. */
4762 +#define TRAMPOLINE_ALIGNMENT 32
4764 +/* A C statement to initialize the variable parts of a trampoline. ADDR is an
4765 + RTX for the address of the trampoline; FNADDR is an RTX for the address of
4766 + the nested function; STATIC_CHAIN is an RTX for the static chain value that
4767 + should be passed to the function when it is called. */
4768 +#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
4770 + emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x14)), \
4772 + emit_move_insn (gen_rtx_MEM (SImode, plus_constant ((TRAMP), 0x18)), \
4776 +/* Ubicom32 supports pre and post increment/decrement addressing. */
4777 +#define HAVE_POST_INCREMENT 1
4778 +#define HAVE_PRE_INCREMENT 1
4779 +#define HAVE_POST_DECREMENT 1
4780 +#define HAVE_PRE_DECREMENT 1
4782 +/* Ubicom32 supports pre and post address side-effects with constants
4783 + other than the size of the memory operand. */
4784 +#define HAVE_PRE_MODIFY_DISP 1
4785 +#define HAVE_POST_MODIFY_DISP 1
4787 +/* A C expression that is 1 if the RTX X is a constant which is a valid
4788 + address. On most machines, this can be defined as `CONSTANT_P (X)',
4789 + but a few machines are more restrictive in which constant addresses
4792 + `CONSTANT_P' accepts integer-values expressions whose values are not
4793 + explicitly known, such as `symbol_ref', `label_ref', and `high'
4794 + expressions and `const' arithmetic expressions, in addition to
4795 + `const_int' and `const_double' expressions. */
4796 +#define CONSTANT_ADDRESS_P(X) \
4797 + (GET_CODE (X) == LABEL_REF \
4798 + || (GET_CODE (X) == CONST \
4799 + && GET_CODE (XEXP (X, 0)) == PLUS \
4800 + && GET_CODE (XEXP (XEXP (X, 0), 0)) == LABEL_REF))
4802 +/* Ubicom32 supports a maximum of 2 registers in a valid memory address.
4803 + One is always an address register while a second, optional, one may be a
4805 +#define MAX_REGS_PER_ADDRESS 2
4807 +/* A C compound statement with a conditional `goto LABEL;' executed if X (an
4808 + RTX) is a legitimate memory address on the target machine for a memory
4809 + operand of mode MODE.
4811 + It usually pays to define several simpler macros to serve as subroutines for
4812 + this one. Otherwise it may be too complicated to understand.
4814 + This macro must exist in two variants: a strict variant and a non-strict
4815 + one. The strict variant is used in the reload pass. It must be defined so
4816 + that any pseudo-register that has not been allocated a hard register is
4817 + considered a memory reference. In contexts where some kind of register is
4818 + required, a pseudo-register with no hard register must be rejected.
4820 + The non-strict variant is used in other passes. It must be defined to
4821 + accept all pseudo-registers in every context where some kind of register is
4824 + Compiler source files that want to use the strict variant of this macro
4825 + define the macro `REG_OK_STRICT'. You should use an `#ifdef REG_OK_STRICT'
4826 + conditional to define the strict variant in that case and the non-strict
4827 + variant otherwise.
4829 + Subroutines to check for acceptable registers for various purposes (one for
4830 + base registers, one for index registers, and so on) are typically among the
4831 + subroutines used to define `GO_IF_LEGITIMATE_ADDRESS'. Then only these
4832 + subroutine macros need have two variants; the higher levels of macros may be
4833 + the same whether strict or not.
4835 + Normally, constant addresses which are the sum of a `symbol_ref' and an
4836 + integer are stored inside a `const' RTX to mark them as constant.
4837 + Therefore, there is no need to recognize such sums specifically as
4838 + legitimate addresses. Normally you would simply recognize any `const' as
4841 + Usually `PRINT_OPERAND_ADDRESS' is not prepared to handle constant sums that
4842 + are not marked with `const'. It assumes that a naked `plus' indicates
4843 + indexing. If so, then you *must* reject such naked constant sums as
4844 + illegitimate addresses, so that none of them will be given to
4845 + `PRINT_OPERAND_ADDRESS'.
4847 + On some machines, whether a symbolic address is legitimate depends on the
4848 + section that the address refers to. On these machines, define the macro
4849 + `ENCODE_SECTION_INFO' to store the information into the `symbol_ref', and
4850 + then check for it here. When you see a `const', you will have to look
4851 + inside it to find the `symbol_ref' in order to determine the section.
4853 + The best way to modify the name string is by adding text to the beginning,
4854 + with suitable punctuation to prevent any ambiguity. Allocate the new name
4855 + in `saveable_obstack'. You will have to modify `ASM_OUTPUT_LABELREF' to
4856 + remove and decode the added text and output the name accordingly, and define
4857 + `STRIP_NAME_ENCODING' to access the original name string.
4859 + You can check the information stored here into the `symbol_ref' in the
4860 + definitions of the macros `GO_IF_LEGITIMATE_ADDRESS' and
4861 + `PRINT_OPERAND_ADDRESS'. */
4862 +/* On the ubicom32, the value in the address register must be
4863 + in the same memory space/segment as the effective address.
4865 + This is problematical for reload since it does not understand
4866 + that base+index != index+base in a memory reference. */
4868 +#ifdef REG_OK_STRICT
4869 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4870 + if (ubicom32_legitimate_address_p (MODE, X, 1)) goto ADDR;
4872 +#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
4873 + if (ubicom32_legitimate_address_p (MODE, X, 0)) goto ADDR;
4876 +/* Try machine-dependent ways of modifying an illegitimate address
4877 + to be legitimate. If we find one, return the new, valid address.
4878 + This macro is used in only one place: `memory_address' in explow.c.
4880 + OLDX is the address as it was before break_out_memory_refs was called.
4881 + In some cases it is useful to look at this to decide what needs to be done.
4883 + MODE and WIN are passed so that this macro can use
4884 + GO_IF_LEGITIMATE_ADDRESS.
4886 + It is always safe for this macro to do nothing. It exists to recognize
4887 + opportunities to optimize the output.
4889 + On RS/6000, first check for the sum of a register with a constant
4890 + integer that is out of range. If so, generate code to add the
4891 + constant with the low-order 16 bits masked to the register and force
4892 + this result into another register (this can be done with `cau').
4893 + Then generate an address of REG+(CONST&0xffff), allowing for the
4894 + possibility of bit 16 being a one.
4896 + Then check for the sum of a register and something not constant, try to
4897 + load the other things into a register and return the sum. */
4899 +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
4901 + rtx result = ubicom32_legitimize_address ((X), (OLDX), (MODE)); \
4902 + if (result != NULL_RTX) \
4909 +/* Try a machine-dependent way of reloading an illegitimate address
4910 + operand. If we find one, push the reload and jump to WIN. This
4911 + macro is used in only one place: `find_reloads_address' in reload.c. */
4912 +#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
4914 + rtx new_rtx = ubicom32_legitimize_reload_address ((AD), (MODE), (OPNUM), (int)(TYPE)); \
4922 +/* A C statement or compound statement with a conditional `goto LABEL;'
4923 + executed if memory address X (an RTX) can have different meanings depending
4924 + on the machine mode of the memory reference it is used for or if the address
4925 + is valid for some modes but not others.
4927 + Autoincrement and autodecrement addresses typically have mode-dependent
4928 + effects because the amount of the increment or decrement is the size of the
4929 + operand being addressed. Some machines have other mode-dependent addresses.
4930 + Many RISC machines have no mode-dependent addresses.
4932 + You may assume that ADDR is a valid address for the machine. */
4933 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
4934 + if (ubicom32_mode_dependent_address_p (ADDR)) \
4937 +/* A C expression that is nonzero if X is a legitimate constant for an
4938 + immediate operand on the target machine. You can assume that X
4939 + satisfies `CONSTANT_P', so you need not check this. In fact, `1' is
4940 + a suitable definition for this macro on machines where anything
4941 + `CONSTANT_P' is valid. */
4942 +#define LEGITIMATE_CONSTANT_P(X) \
4943 + ubicom32_legitimate_constant_p ((X))
4945 +/* Moves between registers are pretty-much single instructions for
4946 + Ubicom32. We make this the default "2" that gcc likes. */
4947 +#define REGISTER_MOVE_COST(MODE, FROM, TO) 2
4949 +/* This is a little bit of magic from the S390 port that wins 2% on code
4950 + size when building the Linux kernel! Unfortunately while it wins on
4951 + that size the user-space apps built using FD-PIC don't improve and the
4952 + performance is lower because we put more pressure on the caches. We may
4953 + want this back on some future CPU that has higher cache performance. */
4954 +/* #define IRA_HARD_REGNO_ADD_COST_MULTIPLIER(regno) 0.5 */
4956 +/* Moves between registers and memory are more expensive than between
4957 + registers because we have caches and write buffers that slow things
4959 +#define MEMORY_MOVE_COST(MODE, CLASS, IN) 2
4961 +/* A fall-through branch is very low cost but anything that changes the PC
4962 + incurs a major pipeline hazard. We don't make the full extent of this
4963 + hazard visible because we hope that multiple threads will absorb much
4964 + of the cost and so we don't want a jump being replaced with, say, 7
4966 +#define BRANCH_COST(SPEED_P, PREDICTABLE_P) \
4967 + ((PREDICTABLE_P) ? 1 : 3)
4969 +/* Define this macro as a C expression which is nonzero if accessing less than
4970 + a word of memory (i.e. a `char' or a `short') is no faster than accessing a
4971 + word of memory, i.e., if such access require more than one instruction or if
4972 + there is no difference in cost between byte and (aligned) word loads.
4974 + When this macro is not defined, the compiler will access a field by finding
4975 + the smallest containing object; when it is defined, a fullword load will be
4976 + used if alignment permits. Unless bytes accesses are faster than word
4977 + accesses, using word accesses is preferable since it may eliminate
4978 + subsequent memory access if subsequent accesses occur to other fields in the
4979 + same word of the structure, but to different bytes. */
4980 +#define SLOW_BYTE_ACCESS 0
4982 +/* The number of scalar move insns which should be generated instead of a
4983 + string move insn or a library call. Increasing the value will always make
4984 + code faster, but eventually incurs high cost in increased code size.
4986 + If you don't define this, a reasonable default is used. */
4987 +/* According to expr.c, a value of around 6 should minimize code size. */
4988 +#define MOVE_RATIO(SPEED) 6
4990 +/* We're much better off calling a constant function address with the
4991 + Ubicom32 architecture because we have an opcode for doing so. Don't
4992 + let the compiler extract function addresses as common subexpressions
4993 + into an address register. */
4994 +#define NO_FUNCTION_CSE
4996 +#define SELECT_CC_MODE(OP, X, Y) ubicom32_select_cc_mode (OP, X, Y)
4998 +#define REVERSIBLE_CC_MODE(MODE) 1
5000 +/* Canonicalize a comparison from one we don't have to one we do have. */
5001 +#define CANONICALIZE_COMPARISON(CODE, OP0, OP1) \
5002 + ubicom32_canonicalize_comparison (&(CODE), &(OP0), &(OP1))
5004 +/* Dividing the output into sections. */
5006 +/* A C expression whose value is a string containing the assembler operation
5007 + that should precede instructions and read-only data. Normally `".text"' is
5009 +#define TEXT_SECTION_ASM_OP "\t.section .text"
5011 +/* A C expression whose value is a string containing the assembler operation to
5012 + identify the following data as writable initialized data. Normally
5013 + `".data"' is right. */
5014 +#define DATA_SECTION_ASM_OP "\t.section .data"
5017 +/* If defined, a C expression whose value is a string containing the
5018 + assembler operation to identify the following data as
5019 + uninitialized global data. If not defined, and neither
5020 + `ASM_OUTPUT_BSS' nor `ASM_OUTPUT_ALIGNED_BSS' are defined,
5021 + uninitialized global data will be output in the data section if
5022 + `-fno-common' is passed, otherwise `ASM_OUTPUT_COMMON' will be
5024 +#define BSS_SECTION_ASM_OP "\t.section .bss"
5026 +/* This is how we tell the assembler that a symbol is weak. */
5028 +#define ASM_WEAKEN_LABEL(FILE, NAME) \
5031 + fputs ("\t.weak\t", (FILE)); \
5032 + assemble_name ((FILE), (NAME)); \
5033 + fputc ('\n', (FILE)); \
5037 +/* The Overall Framework of an Assembler File. */
5040 +#define SET_ASM_OP "\t.set\t"
5042 +/* A C string constant describing how to begin a comment in the target
5043 + assembler language. The compiler assumes that the comment will end at the
5044 + end of the line. */
5045 +#define ASM_COMMENT_START ";"
5047 +/* A C string constant for text to be output before each `asm' statement or
5048 + group of consecutive ones. Normally this is `"#APP"', which is a comment
5049 + that has no effect on most assemblers but tells the GNU assembler that it
5050 + must check the lines that follow for all valid assembler constructs. */
5051 +#define ASM_APP_ON "#APP\n"
5053 +/* A C string constant for text to be output after each `asm' statement or
5054 + group of consecutive ones. Normally this is `"#NO_APP"', which tells the
5055 + GNU assembler to resume making the time-saving assumptions that are valid
5056 + for ordinary compiler output. */
5057 +#define ASM_APP_OFF "#NO_APP\n"
5059 +/* Like `ASM_OUTPUT_BSS' except takes the required alignment as a separate,
5060 + explicit argument. If you define this macro, it is used in place of
5061 + `ASM_OUTPUT_BSS', and gives you more flexibility in handling the required
5062 + alignment of the variable. The alignment is specified as the number of
5065 + Try to use function `asm_output_aligned_bss' defined in file `varasm.c' when
5066 + defining this macro. */
5067 +#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
5068 + asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
5070 +/* A C expression to assign to OUTVAR (which is a variable of type `char *') a
5071 + newly allocated string made from the string NAME and the number NUMBER, with
5072 + some suitable punctuation added. Use `alloca' to get space for the string.
5074 + The string will be used as an argument to `ASM_OUTPUT_LABELREF' to produce
5075 + an assembler label for an internal static variable whose name is NAME.
5076 + Therefore, the string must be such as to result in valid assembler code.
5077 + The argument NUMBER is different each time this macro is executed; it
5078 + prevents conflicts between similarly-named internal static variables in
5081 + Ideally this string should not be a valid C identifier, to prevent any
5082 + conflict with the user's own symbols. Most assemblers allow periods or
5083 + percent signs in assembler symbols; putting at least one of these between
5084 + the name and the number will suffice. */
5085 +#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
5086 + ((OUTPUT) = (char *) alloca (strlen ((NAME)) + 10), \
5087 + sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
5089 +#define ASM_GENERATE_INTERNAL_LABEL(STRING, PREFIX, NUM) \
5090 + sprintf (STRING, "*.%s%ld", PREFIX, (long)(NUM))
5091 +/* A C statement to store into the string STRING a label whose name
5092 + is made from the string PREFIX and the number NUM.
5094 + This string, when output subsequently by `assemble_name', should
5095 + produce the output that `(*targetm.asm_out.internal_label)' would produce
5096 + with the same PREFIX and NUM.
5098 + If the string begins with `*', then `assemble_name' will output
5099 + the rest of the string unchanged. It is often convenient for
5100 + `ASM_GENERATE_INTERNAL_LABEL' to use `*' in this way. If the
5101 + string doesn't start with `*', then `ASM_OUTPUT_LABELREF' gets to
5102 + output the string, and may change it. (Of course,
5103 + `ASM_OUTPUT_LABELREF' is also part of your machine description, so
5104 + you should know what it does on your machine.) */
5106 +/* This says how to output assembler code to declare an
5107 + uninitialized external linkage data object. Under SVR4,
5108 + the linker seems to want the alignment of data objects
5109 + to depend on their types. We do exactly that here. */
5111 +#define COMMON_ASM_OP "\t.comm\t"
5113 +#undef ASM_OUTPUT_COMMON
5114 +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
5117 + fprintf ((FILE), "%s", COMMON_ASM_OP); \
5118 + assemble_name ((FILE), (NAME)); \
5119 + fprintf ((FILE), ", %u\n", (SIZE)); \
5123 +/* This says how to output assembler code to declare an
5124 + uninitialized internal linkage data object. Under SVR4,
5125 + the linker seems to want the alignment of data objects
5126 + to depend on their types. We do exactly that here. */
5127 +#define LOCAL_ASM_OP "\t.lcomm\t"
5129 +#undef ASM_OUTPUT_LOCAL
5130 +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
5133 + fprintf ((FILE), "%s", LOCAL_ASM_OP); \
5134 + assemble_name ((FILE), (NAME)); \
5135 + fprintf ((FILE), ", %u\n", (SIZE)); \
5139 +/* Globalizing directive for a label. */
5140 +#define GLOBAL_ASM_OP ".global\t"
5142 +/* Output the operand of an instruction. */
5143 +#define PRINT_OPERAND(FILE, X, CODE) \
5144 + ubicom32_print_operand(FILE, X, CODE)
5146 +/* Output the address of an operand. */
5147 +#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
5148 + ubicom32_print_operand_address (FILE, ADDR)
5150 +/* A C expression to output to STREAM some assembler code which will push hard
5151 + register number REGNO onto the stack. The code need not be optimal, since
5152 + this macro is used only when profiling. */
5153 +#define ASM_OUTPUT_REG_PUSH(FILE, REGNO)
5155 +/* A C expression to output to STREAM some assembler code which will pop hard
5156 + register number REGNO off of the stack. The code need not be optimal, since
5157 + this macro is used only when profiling. */
5158 +#define ASM_OUTPUT_REG_POP(FILE, REGNO)
5160 +/* This macro should be provided on machines where the addresses in a dispatch
5161 + table are relative to the table's own address.
5163 + The definition should be a C statement to output to the stdio stream STREAM
5164 + an assembler pseudo-instruction to generate a difference between two labels.
5165 + VALUE and REL are the numbers of two internal labels. The definitions of
5166 + these labels are output using `ASM_OUTPUT_INTERNAL_LABEL', and they must be
5167 + printed in the same way here. For example,
5169 + fprintf (STREAM, "\t.word L%d-L%d\n", VALUE, REL) */
5170 +#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
5171 + fprintf (FILE, "\t%s .L%d-.L%d\n", ".long", VALUE, REL)
5173 +/* This macro should be provided on machines where the addresses in a dispatch
5174 + table are absolute.
5176 + The definition should be a C statement to output to the stdio stream STREAM
5177 + an assembler pseudo-instruction to generate a reference to a label. VALUE
5178 + is the number of an internal label whose definition is output using
5179 + `ASM_OUTPUT_INTERNAL_LABEL'. For example,
5181 + fprintf (STREAM, "\t.word L%d\n", VALUE) */
5182 +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
5183 + fprintf (STREAM, "\t.word .L%d\n", VALUE)
5185 +/* Switch into a generic section. */
5186 +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
5188 +/* Assembler Commands for Alignment. */
5190 +#define ASM_OUTPUT_SKIP(STREAM, N) fprintf (STREAM, "\t.skip %d,0\n", N)
5191 +/* A C statement to output to the stdio stream STREAM an assembler
5192 + instruction to advance the location counter by NBYTES bytes.
5193 + Those bytes should be zero when loaded. NBYTES will be a C
5194 + expression of type `int'. */
5196 +/* A C statement to output to the stdio stream STREAM an assembler command to
5197 + advance the location counter to a multiple of 2 to the POWER bytes. POWER
5198 + will be a C expression of type `int'. */
5199 +#define ASM_OUTPUT_ALIGN(FILE, LOG) \
5201 + fprintf (FILE, "\t.align %d\n", (LOG))
5203 +/* A C expression that returns the DBX register number for the compiler
5204 + register number REGNO. In simple cases, the value of this expression may be
5205 + REGNO itself. But sometimes there are some registers that the compiler
5206 + knows about and DBX does not, or vice versa. In such cases, some register
5207 + may need to have one number in the compiler and another for DBX.
5209 + If two registers have consecutive numbers inside GNU CC, and they can be
5210 + used as a pair to hold a multiword value, then they *must* have consecutive
5211 + numbers after renumbering with `DBX_REGISTER_NUMBER'. Otherwise, debuggers
5212 + will be unable to access such a pair, because they expect register pairs to
5213 + be consecutive in their own numbering scheme.
5215 + If you find yourself defining `DBX_REGISTER_NUMBER' in way that does not
5216 + preserve register pairs, then what you must do instead is redefine the
5217 + actual register numbering scheme.
5219 + This declaration is required. */
5220 +#define DBX_REGISTER_NUMBER(REGNO) REGNO
5222 +/* A C expression that returns the integer offset value for an automatic
5223 + variable having address X (an RTL expression). The default computation
5224 + assumes that X is based on the frame-pointer and gives the offset from the
5225 + frame-pointer. This is required for targets that produce debugging output
5226 + for DBX or COFF-style debugging output for SDB and allow the frame-pointer
5227 + to be eliminated when the `-g' options is used. */
5228 +#define DEBUGGER_AUTO_OFFSET(X) \
5229 + ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
5230 + + (frame_pointer_needed \
5231 + ? 0 : -initial_elimination_offset (FRAME_POINTER_REGNUM, \
5232 + STACK_POINTER_REGNUM)))
5234 +/* A C expression that returns the integer offset value for an argument having
5235 + address X (an RTL expression). The nominal offset is OFFSET. */
5236 +#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
5237 + ((GET_CODE (X) == PLUS ? OFFSET : 0) \
5238 + + (frame_pointer_needed \
5239 + ? 0 : -initial_elimination_offset (ARG_POINTER_REGNUM, \
5240 + STACK_POINTER_REGNUM)))
5242 +/* A C expression that returns the type of debugging output GNU CC produces
5243 + when the user specifies `-g' or `-ggdb'. Define this if you have arranged
5244 + for GNU CC to support more than one format of debugging output. Currently,
5245 + the allowable values are `DBX_DEBUG', `SDB_DEBUG', `DWARF_DEBUG',
5246 + `DWARF2_DEBUG', and `XCOFF_DEBUG'.
5248 + The value of this macro only affects the default debugging output; the user
5249 + can always get a specific type of output by using `-gstabs', `-gcoff',
5250 + `-gdwarf-1', `-gdwarf-2', or `-gxcoff'.
5252 + Defined in svr4.h.
5254 +#undef PREFERRED_DEBUGGING_TYPE
5255 +#define PREFERRED_DEBUGGING_TYPE DWARF2_DEBUG
5257 +/* Define this macro if GNU CC should produce dwarf version 2 format debugging
5258 + output in response to the `-g' option.
5260 + To support optional call frame debugging information, you must also define
5261 + `INCOMING_RETURN_ADDR_RTX' and either set `RTX_FRAME_RELATED_P' on the
5262 + prologue insns if you use RTL for the prologue, or call `dwarf2out_def_cfa'
5263 + and `dwarf2out_reg_save' as appropriate from `FUNCTION_PROLOGUE' if you
5266 + Defined in svr4.h. */
5268 +#define DWARF2_DEBUGGING_INFO 1
5269 +/*#define DWARF2_UNWIND_INFO 1*/
5270 +#define DWARF2_UNWIND_INFO 0
5271 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LINK_REGNO)
5272 +#define INCOMING_FRAME_SP_OFFSET 0
5273 +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM (LINK_REGNO)
5274 +#define EH_RETURN_FIRST 9
5275 +#define EH_RETURN_DATA_REGNO(N) ((N) < 2 ? (N) + EH_RETURN_FIRST : INVALID_REGNUM)
5277 +/* The EH_RETURN_STACKADJ_RTX macro returns RTL which describes the
5278 + location used to store the amount to ajdust the stack. This is
5279 + usually a registers that is available from end of the function's body
5280 + to the end of the epilogue. Thus, this cannot be a register used as a
5281 + temporary by the epilogue.
5283 + This must be an integer register. */
5284 +#define EH_RETURN_STACKADJ_REGNO 11
5285 +#define EH_RETURN_STACKADJ_RTX \
5286 + gen_rtx_REG (Pmode, EH_RETURN_STACKADJ_REGNO)
5288 +/* The EH_RETURN_HANDLER_RTX macro returns RTL which describes the
5289 + location used to store the address the processor should jump to
5290 + catch exception. This is usually a registers that is available from
5291 + end of the function's body to the end of the epilogue. Thus, this
5292 + cannot be a register used as a temporary by the epilogue.
5294 + This must be an address register. */
5295 +#define EH_RETURN_HANDLER_REGNO 18
5296 +#define EH_RETURN_HANDLER_RTX \
5297 + gen_rtx_REG (Pmode, EH_RETURN_HANDLER_REGNO)
5299 +/* #define DWARF2_DEBUGGING_INFO */
5301 +/* Define this macro if GNU CC should produce dwarf version 2-style
5302 + line numbers. This usually requires extending the assembler to
5303 + support them, and #defining DWARF2_LINE_MIN_INSN_LENGTH in the
5304 + assembler configuration header files. */
5305 +/* #define DWARF2_ASM_LINE_DEBUG_INFO 1 */
5308 +/* An alias for a machine mode name. This is the machine mode that elements
5309 + of a jump-table have. */
5310 +#define CASE_VECTOR_MODE Pmode
5312 +/* Smallest number of different values for which it is best to use a
5313 + jump-table instead of a tree of conditional branches. For most Ubicom32
5314 + targets this is quite small, but for the v1 architecture implementations
5315 + we had very little data memory and so heavily prefer the tree approach
5316 + rather than the jump tables. */
5317 +#define CASE_VALUES_THRESHOLD ubicom32_case_values_threshold
5319 +/* Register operations within the Ubicom32 architecture always operate on
5320 + the whole register word and not just the sub-bits required for the opcode
5322 +#define WORD_REGISTER_OPERATIONS
5324 +/* The maximum number of bytes that a single instruction can move quickly from
5325 + memory to memory. */
5328 +/* A C expression that is nonzero if on this machine the number of bits
5329 + actually used for the count of a shift operation is equal to the number of
5330 + bits needed to represent the size of the object being shifted. When this
5331 + macro is non-zero, the compiler will assume that it is safe to omit a
5332 + sign-extend, zero-extend, and certain bitwise `and' instructions that
5333 + truncates the count of a shift operation. On machines that have
5334 + instructions that act on bitfields at variable positions, which may include
5335 + `bit test' instructions, a nonzero `SHIFT_COUNT_TRUNCATED' also enables
5336 + deletion of truncations of the values that serve as arguments to bitfield
5339 + If both types of instructions truncate the count (for shifts) and position
5340 + (for bitfield operations), or if no variable-position bitfield instructions
5341 + exist, you should define this macro.
5343 + However, on some machines, such as the 80386 and the 680x0, truncation only
5344 + applies to shift operations and not the (real or pretended) bitfield
5345 + operations. Define `SHIFT_COUNT_TRUNCATED' to be zero on such machines.
5346 + Instead, add patterns to the `md' file that include the implied truncation
5347 + of the shift instructions.
5349 + You need not define this macro if it would always have the value of zero. */
5350 +#define SHIFT_COUNT_TRUNCATED 1
5352 +/* A C expression which is nonzero if on this machine it is safe to "convert"
5353 + an integer of INPREC bits to one of OUTPREC bits (where OUTPREC is smaller
5354 + than INPREC) by merely operating on it as if it had only OUTPREC bits.
5356 + On many machines, this expression can be 1.
5358 + When `TRULY_NOOP_TRUNCATION' returns 1 for a pair of sizes for modes for
5359 + which `MODES_TIEABLE_P' is 0, suboptimal code can result. If this is the
5360 + case, making `TRULY_NOOP_TRUNCATION' return 0 in such cases may improve
5362 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
5364 +/* A C string constant that tells the GNU CC driver program options to pass
5365 + to the assembler. It can also specify how to translate options you give
5366 + to GNU CC into options for GNU CC to pass to the assembler. See the
5367 + file `sun3.h' for an example of this.
5369 + Defined in svr4.h. */
5372 + "%{march=*:-m%*} %{!march=*:-mubicom32v4} %{mfdpic:-mfdpic}"
5374 +#define LINK_SPEC "\
5377 +%{mfdpic:-melf32ubicom32fdpic -z text} \
5378 +%{static:-dn -Bstatic} \
5379 +%{shared:-G -Bdynamic} \
5380 +%{symbolic:-Bsymbolic} \
5385 +#undef STARTFILE_SPEC
5386 +#undef ENDFILE_SPEC
5388 +/* The svr4.h LIB_SPEC with -leval and --*group tacked on */
5391 +#define LIB_SPEC "%{!shared:%{!symbolic:--start-group -lc -leval -lgcc --end-group}}"
5393 +#undef HAVE_GAS_SHF_MERGE
5394 +#define HAVE_GAS_SHF_MERGE 0
5396 +#define HANDLE_SYSV_PRAGMA 1
5397 +#undef HANDLE_PRAGMA_PACK
5399 +typedef void (*ubicom32_func_ptr) (void);
5401 +/* Define builtins for selected special-purpose instructions. */
5402 +enum ubicom32_builtins
5404 + UBICOM32_BUILTIN_UBICOM32_SWAPB_2,
5405 + UBICOM32_BUILTIN_UBICOM32_SWAPB_4
5408 +extern rtx ubicom32_compare_op0;
5409 +extern rtx ubicom32_compare_op1;
5411 +#define TYPE_ASM_OP "\t.type\t"
5412 +#define TYPE_OPERAND_FMT "@%s"
5414 +#ifndef ASM_DECLARE_RESULT
5415 +#define ASM_DECLARE_RESULT(FILE, RESULT)
5418 +/* These macros generate the special .type and .size directives which
5419 + are used to set the corresponding fields of the linker symbol table
5420 + entries in an ELF object file under SVR4. These macros also output
5421 + the starting labels for the relevant functions/objects. */
5423 +/* Write the extra assembler code needed to declare a function properly.
5424 + Some svr4 assemblers need to also have something extra said about the
5425 + function's return value. We allow for that here. */
5427 +#ifndef ASM_DECLARE_FUNCTION_NAME
5428 +#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
5431 + ASM_OUTPUT_TYPE_DIRECTIVE (FILE, NAME, "function"); \
5432 + ASM_DECLARE_RESULT (FILE, DECL_RESULT (DECL)); \
5433 + ASM_OUTPUT_LABEL (FILE, NAME); \
5438 +++ b/gcc/config/ubicom32/ubicom32.md
5440 +; GCC machine description for Ubicom32
5442 +; Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
5444 +; Contributed by Ubicom, Inc.
5446 +; This file is part of GCC.
5448 +; GCC is free software; you can redistribute it and/or modify
5449 +; it under the terms of the GNU General Public License as published by
5450 +; the Free Software Foundation; either version 3, or (at your option)
5451 +; any later version.
5453 +; GCC is distributed in the hope that it will be useful,
5454 +; but WITHOUT ANY WARRANTY; without even the implied warranty of
5455 +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5456 +; GNU General Public License for more details.
5458 +; You should have received a copy of the GNU General Public License
5459 +; along with GCC; see the file COPYING3. If not see
5460 +; <http://www.gnu.org/licenses/>.
5463 + [(AUX_DATA_REGNO 15)
5466 + (ACC0_HI_REGNO 24)
5467 + (ACC1_HI_REGNO 26)
5471 + [(UNSPEC_FDPIC_GOT 0)
5472 + (UNSPEC_FDPIC_GOT_FUNCDESC 1)])
5475 + [(UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC 0)])
5477 +;; Types of instructions (for scheduling purposes).
5479 +(define_attr "type" "mul,addr,other"
5480 + (const_string "other"))
5482 +; Define instruction scheduling characteristics. We can only issue
5483 +; one instruction per clock so we don't need to define CPU units.
5485 +(define_automaton "ubicom32")
5487 +(define_cpu_unit "i_pipeline" "ubicom32");
5489 +; We have a 4 cycle hazard associated with address calculations which
5490 +; seems rather tricky to avoid so we go with a defensive assumption
5491 +; that almost anything can be used to generate addresses.
5493 +;(define_insn_reservation "ubicom32_other" 4
5494 +; (eq_attr "type" "other")
5497 +; Some moves don't generate hazards.
5499 +;(define_insn_reservation "ubicom32_addr" 1
5500 +; (eq_attr "type" "addr")
5503 +; We need 3 cycles between a multiply instruction and any use of the
5504 +; matching accumulator register(s).
5506 +(define_insn_reservation "ubicom32_mul" 4
5507 + (eq_attr "type" "mul")
5510 +(define_attr "length" ""
5513 +(include "predicates.md")
5514 +(include "constraints.md")
5516 +; 8-bit move with no change to the flags reg.
5518 +(define_insn "movqi"
5519 + [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
5520 + (match_operand:QI 1 "ubicom32_move_operand" "g"))]
5522 + "move.1\\t%0, %1")
5524 +; Combiner-generated 8-bit move with the zero flag set accordingly.
5526 +(define_insn "movqi_ccszn"
5527 + [(set (reg CC_REGNO)
5528 + (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
5530 + (set (match_operand:QI 1 "nonimmediate_operand" "=rm")
5532 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
5535 +; Combine isn't very good at merging some types of operations so we
5536 +; have to make do with a peephole. It's not as effective but it's better
5537 +; than doing nothing.
5540 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
5541 + (match_operand:QI 1 "nonimmediate_operand" ""))
5542 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
5543 + (match_operator 3 "ubicom32_compare_operator"
5546 + "(GET_MODE (operands[2]) == CCSZNmode
5547 + || GET_MODE (operands[2]) == CCSZmode)"
5549 + [(set (match_dup 2)
5553 + (set (match_dup 0)
5557 +; Combine isn't very good at merging some types of operations so we
5558 +; have to make do with a peephole. It's not as effective but it's better
5559 +; than doing nothing.
5562 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
5563 + (match_operand:QI 1 "nonimmediate_operand" ""))
5564 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
5565 + (match_operator 3 "ubicom32_compare_operator"
5568 + "(GET_MODE (operands[2]) == CCSZNmode
5569 + || GET_MODE (operands[2]) == CCSZmode)"
5571 + [(set (match_dup 2)
5575 + (set (match_dup 0)
5579 +; 16-bit move with no change to the flags reg.
5581 +(define_insn "movhi"
5582 + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
5583 + (match_operand:HI 1 "ubicom32_move_operand" "g"))]
5587 + if (CONST_INT_P (operands[1]))
5588 + return \"movei\\t%0, %1\";
5590 + return \"move.2\\t%0, %1\";
5593 +; Combiner-generated 16-bit move with the zero flag set accordingly.
5595 +(define_insn "movhi_ccszn"
5596 + [(set (reg CC_REGNO)
5597 + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
5599 + (set (match_operand:HI 1 "nonimmediate_operand" "=rm")
5601 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
5604 +; Combine isn't very good at merging some types of operations so we
5605 +; have to make do with a peephole. It's not as effective but it's better
5606 +; than doing nothing.
5609 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
5610 + (match_operand:HI 1 "nonimmediate_operand" ""))
5611 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
5612 + (match_operator 3 "ubicom32_compare_operator"
5615 + "(GET_MODE (operands[2]) == CCSZNmode
5616 + || GET_MODE (operands[2]) == CCSZmode)"
5618 + [(set (match_dup 2)
5622 + (set (match_dup 0)
5626 +; Combine isn't very good at merging some types of operations so we
5627 +; have to make do with a peephole. It's not as effective but it's better
5628 +; than doing nothing.
5631 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
5632 + (match_operand:HI 1 "nonimmediate_operand" ""))
5633 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
5634 + (match_operator 3 "ubicom32_compare_operator"
5637 + "(GET_MODE (operands[2]) == CCSZNmode
5638 + || GET_MODE (operands[2]) == CCSZmode)"
5640 + [(set (match_dup 2)
5644 + (set (match_dup 0)
5648 +; 32-bit move with no change to the flags reg.
5650 +(define_expand "movsi"
5651 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
5652 + (match_operand:SI 1 "general_operand" ""))]
5655 + /* Convert any complexities in operand 1 into something that can just
5656 + fall into the default expander code. */
5657 + ubicom32_expand_movsi (operands);
5660 +(define_insn "movsi_high"
5661 + [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
5662 + (high:SI (match_operand:SI 1 "ubicom32_symbolic_address_operand" "s")))]
5664 + "moveai\\t%0, #%%hi(%E1)")
5666 +(define_insn "movsi_lo_sum"
5667 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5668 + (lo_sum:SI (match_operand:SI 1 "ubicom32_address_register_operand" "a")
5669 + (match_operand:SI 2 "immediate_operand" "s")))]
5671 + "lea.1\\t%0, %%lo(%E2)(%1)")
5673 +(define_insn "movsi_internal"
5674 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5675 + (match_operand:SI 1 "ubicom32_move_operand" "rmnY"))]
5679 + if (CONST_INT_P (operands[1]))
5681 + ubicom32_emit_move_const_int (operands[0], operands[1]);
5685 + if (GET_CODE (operands[1]) == CONST_DOUBLE)
5687 + HOST_WIDE_INT i = CONST_DOUBLE_LOW (operands[1]);
5689 + ubicom32_emit_move_const_int (operands[0], GEN_INT (i));
5693 + if (ubicom32_address_register_operand (operands[0], VOIDmode)
5694 + && register_operand (operands[1], VOIDmode))
5696 + if (ubicom32_address_register_operand (operands[1], VOIDmode))
5697 + return \"lea.1\\t%0, 0(%1)\";
5699 + /* Use movea here to utilize the hazard bypass in the >= v4 ISA. */
5701 + return \"movea\\t%0, %1\";
5703 + return \"move.4\\t%0, %1\";
5706 + return \"move.4\\t%0, %1\";
5709 +; If we're not dependent on the state of the condition codes we can construct
5710 +; constants of value 2^n by using a bset.
5713 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
5714 + (match_operand:SI 1 "const_int_operand" ""))]
5715 + "(exact_log2 (INTVAL (operands[1])) > 14
5716 + && peep2_regno_dead_p (0, CC_REGNO))"
5718 + [(set (match_dup 0)
5719 + (ior:SI (const_int 0)
5721 + (clobber (reg:CC CC_REGNO))])]
5724 +; If we're not dependent on the state of the condition codes we can construct
5725 +; constants of value ~(2^n) by using a bclr.
5728 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
5729 + (match_operand:SI 1 "const_int_operand" ""))]
5730 + "(exact_log2 (~INTVAL (operands[1])) > 14
5731 + && peep2_regno_dead_p (0, CC_REGNO))"
5733 + [(set (match_dup 0)
5734 + (and:SI (const_int -1)
5736 + (clobber (reg:CC CC_REGNO))])]
5739 +; For 32-bit constants that have bits 0 through 24 and bit 31 set the same
5740 +; we can use swapb.4!
5743 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
5744 + (match_operand:SI 1 "const_int_operand" ""))]
5746 + && (INTVAL (operands[1]) & 0xffffffff) != 0xffffffff
5747 + && (INTVAL (operands[1]) & 0xffffffff) != 0
5748 + && ((INTVAL (operands[1]) & 0x80ffffff) == 0
5749 + || (INTVAL (operands[1]) & 0x80ffffff) == 0x80ffffff))"
5750 + [(set (match_dup 0)
5751 + (bswap:SI (match_dup 2)))]
5753 + operands[2] = GEN_INT (INTVAL (operands[1]) >> 24);
5756 +; If this is a write of a constant to memory look to see if we can usefully
5757 +; transform this into 2 smaller writes.
5760 + [(set (match_operand:SI 0 "memory_operand" "")
5761 + (match_operand:SI 1 "const_int_operand" ""))]
5762 + "! satisfies_constraint_I (operands[1])
5763 + && ubicom32_legitimate_address_p (HImode, plus_constant (XEXP (operands[0], 0), 2), 1)"
5764 + [(set (match_dup 4) (match_dup 2))
5765 + (set (match_dup 5) (match_dup 3))]
5767 + rtx low_hword_addr;
5769 + operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5770 + operands[3] = gen_lowpart (HImode, operands[1]);
5772 + operands[4] = gen_rtx_MEM (HImode, XEXP (operands[0], 0));
5773 + MEM_COPY_ATTRIBUTES (operands[4], operands[0]);
5775 + low_hword_addr = plus_constant (XEXP (operands[0], 0), 2);
5776 + operands[5] = gen_rtx_MEM (HImode, low_hword_addr);
5777 + MEM_COPY_ATTRIBUTES (operands[5], operands[0]);
5780 +; If we're writing memory and we've not found a better way to do this then
5781 +; try loading into a D register and then copying to memory. This will
5782 +; perform the fewest possible memory read/writes.
5785 + [(match_scratch:SI 2 "d")
5786 + (set (match_operand:SI 0 "memory_operand" "")
5787 + (match_operand:SI 1 "const_int_operand" ""))]
5788 + "! satisfies_constraint_I (operands[1])"
5789 + [(set (match_dup 2) (match_dup 1))
5790 + (set (match_dup 0) (match_dup 2))]
5793 +; If we're not dependent on the state of the condition codes we can construct
5794 +; constants of value (2^n - 1) by using an lsr.4.
5797 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5798 + (match_operand:SI 1 "const_int_operand" ""))]
5799 + "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5800 + && peep2_regno_dead_p (0, CC_REGNO))"
5802 + [(set (match_dup 0)
5803 + (lshiftrt:SI (const_int -1)
5805 + (clobber (reg:CC CC_REGNO))])]
5807 + operands[2] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5810 +; If we're not dependent on the state of the condition codes we can construct
5811 +; constants of value (2^n - 1) by using an lsr.4.
5814 + [(match_scratch:SI 2 "d")
5815 + (set (match_operand:SI 0 "nonimmediate_operand" "")
5816 + (match_operand:SI 1 "const_int_operand" ""))]
5817 + "(exact_log2 (INTVAL (operands[1]) + 1) > 14
5818 + && peep2_regno_dead_p (0, CC_REGNO))"
5820 + [(set (match_dup 2)
5821 + (lshiftrt:SI (const_int -1)
5823 + (clobber (reg:CC CC_REGNO))])
5824 + (set (match_dup 0)
5827 + operands[3] = GEN_INT (32 - exact_log2 (INTVAL (operands[1]) + 1));
5830 +; If we're not dependent on the state of the condition codes we can construct
5831 +; some other constants by using an lsl.4 to shift 7 bits left by some
5835 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5836 + (match_operand:SI 1 "const_int_operand" ""))]
5837 + "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5838 + && peep2_regno_dead_p (0, CC_REGNO))"
5840 + [(set (match_dup 0)
5841 + (ashift:SI (match_dup 2)
5843 + (clobber (reg:CC CC_REGNO))])]
5845 + int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5846 + operands[2] = GEN_INT (INTVAL (operands[1]) >> shift);
5847 + operands[3] = GEN_INT (shift);
5850 +; If we're not dependent on the state of the condition codes we can construct
5851 +; some other constants by using an lsl.4 to shift 7 bits left by some
5855 + [(match_scratch:SI 2 "d")
5856 + (set (match_operand:SI 0 "nonimmediate_operand" "")
5857 + (match_operand:SI 1 "const_int_operand" ""))]
5858 + "(ubicom32_shiftable_const_int (INTVAL (operands[1]))
5859 + && peep2_regno_dead_p (0, CC_REGNO))"
5861 + [(set (match_dup 2)
5862 + (ashift:SI (match_dup 3)
5864 + (clobber (reg:CC CC_REGNO))])
5865 + (set (match_dup 0)
5868 + int shift = ubicom32_shiftable_const_int (INTVAL (operands[1]));
5869 + operands[3] = GEN_INT (INTVAL (operands[1]) >> shift);
5870 + operands[4] = GEN_INT (shift);
5873 +; For some 16-bit unsigned constants that have bit 15 set we can use
5876 +; Note that the movsi code emits the same sequence but by using a peephole2
5877 +; we split the pattern early enough to allow instruction scheduling to
5881 + [(set (match_operand:SI 0 "register_operand" "")
5882 + (match_operand:SI 1 "const_int_operand" ""))]
5884 + && (INTVAL (operands[1]) & 0xffff80ff) == 0x80ff)"
5885 + [(set (match_dup 0)
5886 + (zero_extend:SI (bswap:HI (match_dup 2))))]
5888 + HOST_WIDE_INT i = INTVAL (operands[1]) >> 8;
5891 + operands[2] = GEN_INT (i);
5894 +; In general for a 16-bit unsigned constant that has bit 15 set
5895 +; then we need a movei/move.2 pair unless we can represent it
5896 +; via just a move.2.
5899 + [(set (match_operand:SI 0 "register_operand" "")
5900 + (match_operand:SI 1 "const_int_operand" ""))]
5901 + "(INTVAL (operands[1]) & 0xffff8000) == 0x8000
5902 + && (INTVAL (operands[1]) & 0xffff) < 0xff80"
5903 + [(set (match_dup 2)
5905 + (set (match_dup 0)
5906 + (zero_extend:SI (match_dup 2)))]
5908 + operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
5911 +; If we're not dependent on the state of the condition codes we can construct
5912 +; 32-bit constants that have bits 16 through 31 set to arbitrary values
5913 +; and have bits 0 through 15 set to something representable as a default
5914 +; source-1 immediate - we use movei/shmrg.2
5917 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
5918 + (match_operand:SI 1 "const_int_operand" ""))]
5919 + "(((INTVAL (operands[1]) >= 0x8000
5920 + && INTVAL (operands[1]) < 0xff80)
5921 + || INTVAL (operands[1]) >= 0x10000
5922 + || INTVAL (operands[1]) < -0x8000)
5923 + && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5924 + || (INTVAL (operands[1]) & 0xffff) < 0x80)
5925 + && peep2_regno_dead_p (0, CC_REGNO))"
5926 + [(set (match_dup 0)
5929 + [(set (match_dup 0)
5931 + (ashift:SI (match_dup 0)
5935 + (clobber (reg:CC CC_REGNO))])]
5937 + operands[2] = gen_highpart_mode (HImode, SImode, operands[1]);
5938 + operands[3] = gen_lowpart (HImode, operands[1]);
5941 +; Exactly the same as the peephole2 preceding except that this targets a
5942 +; general register instead of D register. Hopefully the later optimization
5943 +; passes will notice that the value ended up in a D register first here
5944 +; and eliminate away the other register!
5947 + [(match_scratch:SI 2 "d")
5948 + (set (match_operand:SI 0 "register_operand" "")
5949 + (match_operand:SI 1 "const_int_operand" ""))]
5950 + "(((INTVAL (operands[1]) >= 0x8000
5951 + && INTVAL (operands[1]) < 0xff80)
5952 + || INTVAL (operands[1]) >= 0x10000
5953 + || INTVAL (operands[1]) < -0x8000)
5954 + && ((INTVAL (operands[1]) & 0xffff) >= 0xff80
5955 + || (INTVAL (operands[1]) & 0xffff) < 0x80)
5956 + && peep2_regno_dead_p (0, CC_REGNO))"
5957 + [(set (match_dup 2)
5960 + [(set (match_dup 2)
5962 + (ashift:SI (match_dup 2)
5966 + (clobber (reg:CC CC_REGNO))])
5967 + (set (match_dup 0)
5970 + operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
5971 + operands[4] = gen_lowpart (HImode, operands[1]);
5974 +; If we have a load of a large integer constant which does not have bit 31
5975 +; set and we have a spare A reg then construct it with a moveai/lea.1 pair
5976 +; instead. This avoids constructing it in 3 instructions on the stack.
5978 +; Note that we have to be careful not to match anything that matches
5979 +; something we can do in a single instruction! There aren't many such
5980 +; constants but there are some.
5983 + [(match_scratch:SI 2 "a")
5984 + (set (match_operand:SI 0 "register_operand" "")
5985 + (match_operand:SI 1 "const_int_operand" ""))]
5986 + "(! (INTVAL (operands[1]) & 0x80000000)
5987 + && ((INTVAL (operands[1]) >= 0x8000
5988 + && INTVAL (operands[1]) < 0xff80)
5989 + || INTVAL (operands[1]) >= 0x10000))"
5990 + [(set (match_dup 2)
5992 + (set (match_dup 0)
5993 + (plus:SI (match_dup 2)
5996 + HOST_WIDE_INT i = INTVAL (operands[1]);
5997 + operands[3] = GEN_INT (i & 0xffffff80);
5998 + operands[4] = GEN_INT (i & 0x7f);
6001 +; If we're not dependent on the state of the condition codes we can construct
6002 +; a 32-bit constant with a movei/movei/shmrg.2 sequence if possible.
6005 + [(match_scratch:HI 2 "d")
6006 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "")
6007 + (match_operand:SI 1 "const_int_operand" ""))
6009 + "(INTVAL (operands[1]) & 0x80000000
6010 + && INTVAL (operands[1]) < -0x8000
6011 + && peep2_regno_dead_p (0, CC_REGNO))"
6012 + [(set (match_dup 0)
6014 + (set (match_dup 2)
6017 + [(set (match_dup 0)
6019 + (ashift:SI (match_dup 0)
6023 + (clobber (reg:CC CC_REGNO))])]
6025 + operands[3] = gen_highpart_mode (HImode, SImode, operands[1]);
6026 + operands[4] = gen_lowpart (HImode, operands[1]);
6029 +; Exactly the same as the peephole2 preceding except that this targets a
6030 +; general register instead of D register. Hopefully the later optimization
6031 +; passes will notice that the value ended up in a D register first here
6032 +; and eliminate away the other register!
6035 + [(match_scratch:SI 2 "d")
6036 + (match_scratch:HI 3 "d")
6037 + (set (match_operand:SI 0 "register_operand" "")
6038 + (match_operand:SI 1 "const_int_operand" ""))
6040 + "(INTVAL (operands[1]) & 0x80000000
6041 + && INTVAL (operands[1]) < -0x8000
6042 + && peep2_regno_dead_p (0, CC_REGNO))"
6043 + [(set (match_dup 2)
6045 + (set (match_dup 3)
6048 + [(set (match_dup 2)
6050 + (ashift:SI (match_dup 2)
6054 + (clobber (reg:CC CC_REGNO))])
6055 + (set (match_dup 0)
6058 + operands[4] = gen_highpart_mode (HImode, SImode, operands[1]);
6059 + operands[5] = gen_lowpart (HImode, operands[1]);
6062 +(define_insn "movsi_fdpic_got_offset"
6063 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6064 + (match_operand:SI 1 "ubicom32_fdpic_got_offset_operand" "Y"))]
6068 +; The explicit MEM inside the UNSPEC prevents the compiler from moving
6069 +; the load before a branch after a NULL test, or before a store that
6070 +; initializes a function descriptor.
6072 +(define_insn_and_split "load_fdpic_funcdesc"
6073 + [(set (match_operand:SI 0 "ubicom32_address_register_operand" "=a")
6074 + (unspec_volatile:SI [(mem:SI (match_operand:SI 1 "address_operand" "p"))]
6075 + UNSPEC_VOLATILE_LOAD_FDPIC_FUNCDESC))]
6078 + "reload_completed"
6079 + [(set (match_dup 0)
6080 + (mem:SI (match_dup 1)))])
6082 +; Combiner-generated 32-bit move with the zero flag set accordingly.
6084 +(define_insn "movsi_ccwzn"
6085 + [(set (reg CC_REGNO)
6086 + (compare (match_operand:SI 0 "nonimmediate_operand" "rm, d")
6088 + (set (match_operand:SI 1 "nonimmediate_operand" "=d,rm")
6090 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
6092 + lsl.4\\t%1, %0, #0
6093 + add.4\\t%1, #0, %0")
6095 +; Combiner-generated 32-bit move with all flags set accordingly.
6097 +(define_insn "movsi_ccw"
6098 + [(set (reg CC_REGNO)
6099 + (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6101 + (set (match_operand:SI 1 "nonimmediate_operand" "=rm")
6103 + "ubicom32_match_cc_mode(insn, CCWmode)"
6104 + "add.4\\t%1, #0, %0")
6106 +; Combine isn't very good at merging some types of operations so we
6107 +; have to make do with a peephole. It's not as effective but it's better
6108 +; than doing nothing.
6111 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "")
6112 + (match_operand:SI 1 "nonimmediate_operand" ""))
6114 + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6115 + (match_operator 3 "ubicom32_compare_operator"
6118 + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6119 + "(GET_MODE (operands[2]) == CCWZNmode
6120 + || GET_MODE (operands[2]) == CCWZmode)"
6122 + [(set (match_dup 2)
6126 + (set (match_dup 0)
6130 +; Combine isn't very good at merging some types of operations so we
6131 +; have to make do with a peephole. It's not as effective but it's better
6132 +; than doing nothing.
6135 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
6136 + (match_operand:SI 1 "ubicom32_data_register_operand" ""))
6138 + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6139 + (match_operator 3 "ubicom32_compare_operator"
6142 + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6143 + "(GET_MODE (operands[2]) == CCWZNmode
6144 + || GET_MODE (operands[2]) == CCWZmode)"
6146 + [(set (match_dup 2)
6150 + (set (match_dup 0)
6154 +; Combine isn't very good at merging some types of operations so we
6155 +; have to make do with a peephole. It's not as effective but it's better
6156 +; than doing nothing.
6159 + [(set (match_operand:SI 0 "register_operand" "")
6160 + (match_operand:SI 1 "nonimmediate_operand" ""))
6162 + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6163 + (match_operator 3 "ubicom32_compare_operator"
6166 + (set (match_operand:SI 4 "ubicom32_data_register_operand" "")
6168 + "(peep2_reg_dead_p (2, operands[0])
6169 + && (GET_MODE (operands[2]) == CCWZNmode
6170 + || GET_MODE (operands[2]) == CCWZmode))"
6172 + [(set (match_dup 2)
6176 + (set (match_dup 4)
6180 +; Register renaming may make a general reg into a D reg in which case
6181 +; we may be able to simplify a compare.
6184 + [(set (match_operand:SI 0 "register_operand" "")
6185 + (match_operand:SI 1 "nonimmediate_operand" ""))
6187 + [(set (match_operand 2 "ubicom32_cc_register_operand" "")
6188 + (match_operator 3 "ubicom32_compare_operator"
6191 + (clobber (match_operand:SI 4 "ubicom32_data_register_operand" ""))])]
6192 + "(peep2_reg_dead_p (2, operands[0])
6193 + && (GET_MODE (operands[2]) == CCWZNmode
6194 + || GET_MODE (operands[2]) == CCWZmode))"
6196 + [(set (match_dup 2)
6200 + (clobber (match_dup 4))])]
6203 +(define_insn_and_split "movdi"
6204 + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6205 + (match_operand:DI 1 "general_operand" "rmi,ri"))]
6208 + "reload_completed"
6209 + [(set (match_dup 2) (match_dup 3))
6210 + (set (match_dup 4) (match_dup 5))]
6215 + dest_low = gen_lowpart (SImode, operands[0]);
6216 + src_low = gen_lowpart (SImode, operands[1]);
6218 + if (REG_P (operands[0])
6219 + && REG_P (operands[1])
6220 + && REGNO (operands[0]) < REGNO (operands[1]))
6222 + operands[2] = gen_highpart (SImode, operands[0]);
6223 + operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6224 + operands[4] = dest_low;
6225 + operands[5] = src_low;
6227 + else if (reg_mentioned_p (dest_low, src_low))
6229 + operands[2] = gen_highpart (SImode, operands[0]);
6230 + operands[3] = gen_highpart_mode (SImode, DImode, operands[1]);
6231 + operands[4] = dest_low;
6232 + operands[5] = src_low;
6236 + operands[2] = dest_low;
6237 + operands[3] = src_low;
6238 + operands[4] = gen_highpart (SImode, operands[0]);
6239 + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6242 + [(set_attr "length" "8")])
6244 +; Combiner-generated 64-bit move with all flags set accordingly.
6246 +(define_insn "movdi_ccwzn"
6247 + [(set (reg CC_REGNO)
6248 + (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6250 + (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6252 + (clobber (match_scratch:SI 2 "=X, d, d"))]
6253 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
6256 + operands[3] = gen_lowpart (SImode, operands[0]);
6257 + operands[4] = gen_lowpart (SImode, operands[1]);
6258 + operands[5] = gen_highpart (SImode, operands[0]);
6259 + operands[6] = gen_highpart (SImode, operands[1]);
6261 + if (ubicom32_data_register_operand (operands[0], VOIDmode))
6262 + return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6264 + return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6266 + [(set_attr "length" "8")])
6268 +(define_insn "movdi_ccw"
6269 + [(set (reg CC_REGNO)
6270 + (compare (match_operand:DI 0 "nonimmediate_operand" "d, m, r")
6272 + (set (match_operand:DI 1 "nonimmediate_operand" "=&rm,rm,!&rm")
6274 + (clobber (match_scratch:SI 2 "=X, d, d"))]
6275 + "ubicom32_match_cc_mode(insn, CCWmode)"
6278 + operands[3] = gen_lowpart (SImode, operands[0]);
6279 + operands[4] = gen_lowpart (SImode, operands[1]);
6280 + operands[5] = gen_highpart (SImode, operands[0]);
6281 + operands[6] = gen_highpart (SImode, operands[1]);
6283 + if (ubicom32_data_register_operand (operands[0], VOIDmode))
6284 + return \"add.4\\t%4, #0, %3\;addc\\t%6, #0, %5\";
6286 + return \"movei\\t%2, #0\;add.4\\t%4, %3, %2\;addc\\t%6, %5, %2\";
6288 + [(set_attr "length" "8")])
6290 +(define_insn "movsf"
6291 + [(set (match_operand:SF 0 "nonimmediate_operand" "=!d,*rm")
6292 + (match_operand:SF 1 "ubicom32_move_operand" "rmF,rmF"))]
6296 + if (GET_CODE (operands[1]) == CONST_DOUBLE)
6298 + HOST_WIDE_INT val;
6299 + REAL_VALUE_TYPE rv;
6301 + REAL_VALUE_FROM_CONST_DOUBLE (rv, operands[1]);
6302 + REAL_VALUE_TO_TARGET_SINGLE (rv, val);
6304 + ubicom32_emit_move_const_int (operands[0], GEN_INT (val));
6308 + return \"move.4\\t%0, %1\";
6311 +(define_insn "zero_extendqihi2"
6312 + [(set (match_operand:HI 0 "register_operand" "=r")
6313 + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6315 + "move.1\\t%0, %1")
6317 +(define_insn "zero_extendqisi2"
6318 + [(set (match_operand:SI 0 "register_operand" "=r")
6319 + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6321 + "move.1\\t%0, %1")
6323 +(define_insn "zero_extendqisi2_ccwz_1"
6324 + [(set (reg CC_REGNO)
6326 + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
6328 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6329 + (zero_extend:SI (match_dup 1)))]
6330 + "ubicom32_match_cc_mode(insn, CCWZmode)"
6331 + "shmrg.1\\t%0, %1, #0")
6333 +(define_insn "zero_extendhisi2"
6334 + [(set (match_operand:SI 0 "register_operand" "=r")
6335 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6337 + "move.2\\t%0, %1")
6339 +(define_insn "zero_extendhisi2_ccwz_1"
6340 + [(set (reg CC_REGNO)
6342 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
6344 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
6345 + (zero_extend:SI (match_dup 1)))]
6346 + "ubicom32_match_cc_mode(insn, CCWZmode)"
6347 + "shmrg.2\\t%0, %1, #0")
6349 +(define_insn_and_split "zero_extendqidi2"
6350 + [(set (match_operand:DI 0 "register_operand" "=r")
6351 + (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
6354 + "reload_completed"
6355 + [(set (match_dup 2)
6356 + (zero_extend:SI (match_dup 1)))
6357 + (set (match_dup 3)
6360 + operands[2] = gen_lowpart (SImode, operands[0]);
6361 + operands[3] = gen_highpart (SImode, operands[0]);
6363 + [(set_attr "length" "8")])
6365 +(define_insn_and_split "zero_extendhidi2"
6366 + [(set (match_operand:DI 0 "register_operand" "=r")
6367 + (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
6370 + "reload_completed"
6371 + [(set (match_dup 2)
6372 + (zero_extend:SI (match_dup 1)))
6373 + (set (match_dup 3)
6376 + operands[2] = gen_lowpart (SImode, operands[0]);
6377 + operands[3] = gen_highpart (SImode, operands[0]);
6379 + [(set_attr "length" "8")])
6381 +(define_insn_and_split "zero_extendsidi2"
6382 + [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
6383 + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6386 + "reload_completed"
6387 + [(set (match_dup 2)
6389 + (set (match_dup 3)
6392 + operands[2] = gen_lowpart (SImode, operands[0]);
6393 + operands[3] = gen_highpart (SImode, operands[0]);
6395 + [(set_attr "length" "8")])
6397 +(define_insn "extendqihi2"
6398 + [(set (match_operand:HI 0 "register_operand" "=r")
6399 + (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6400 + (clobber (reg:CC CC_REGNO))]
6404 +(define_insn "extendqisi2"
6405 + [(set (match_operand:SI 0 "register_operand" "=r")
6406 + (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))
6407 + (clobber (reg:CC CC_REGNO))]
6411 +(define_insn "extendhisi2"
6412 + [(set (match_operand:SI 0 "register_operand" "=r")
6413 + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))
6414 + (clobber (reg:CC CC_REGNO))]
6418 +(define_insn_and_split "extendsidi2"
6419 + [(set (match_operand:DI 0 "nonimmediate_operand" "=d")
6420 + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "rm")))
6421 + (clobber (reg:CC CC_REGNO))]
6424 + "reload_completed"
6425 + [(set (match_dup 2)
6428 + [(set (match_dup 3)
6429 + (ashiftrt:SI (match_dup 2)
6431 + (clobber (reg:CC CC_REGNO))])]
6433 + operands[2] = gen_lowpart (SImode, operands[0]);
6434 + operands[3] = gen_highpart (SImode, operands[0]);
6436 + [(set_attr "length" "8")])
6438 +(define_insn "bswaphi"
6439 + [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
6440 + (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6442 + "swapb.2\\t%0, %1");
6444 +(define_insn "bswaphisi"
6445 + [(set (match_operand:SI 0 "register_operand" "=r")
6447 + (bswap:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI"))))]
6449 + "swapb.2\\t%0, %1");
6451 +(define_insn "bswapsi"
6452 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
6453 + (bswap:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))]
6455 + "swapb.4\\t%0, %1");
6457 +(define_insn "tstqi_ext1"
6458 + [(set (reg CC_REGNO)
6459 + (compare (match_operand:QI 0 "nonimmediate_operand" "rm")
6461 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
6464 +(define_expand "cmpqi"
6465 + [(set (reg CC_REGNO)
6466 + (compare (match_operand:QI 0 "ubicom32_arith_operand" "")
6467 + (match_operand:QI 1 "ubicom32_data_register_operand" "")))]
6470 + ubicom32_compare_op0 = operands[0];
6471 + ubicom32_compare_op1 = operands[1];
6475 +(define_insn "sub1_ccs"
6476 + [(set (reg CC_REGNO)
6477 + (compare (match_operand:QI 0 "ubicom32_arith_operand" "rmI")
6478 + (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6480 + "sub.1\\t#0, %0, %1")
6482 +; If we're testing for equality we don't have to worry about reversing conditions.
6484 +(define_insn "sub1_ccsz_1"
6485 + [(set (reg:CCSZ CC_REGNO)
6486 + (compare:CCSZ (match_operand:QI 0 "nonimmediate_operand" "rm")
6487 + (match_operand:QI 1 "ubicom32_data_register_operand" "d")))]
6489 + "sub.1\\t#0, %0, %1")
6491 +(define_insn "sub1_ccsz_2"
6492 + [(set (reg:CCSZ CC_REGNO)
6493 + (compare:CCSZ (match_operand:QI 0 "ubicom32_data_register_operand" "d")
6494 + (match_operand:QI 1 "ubicom32_arith_operand" "rmI")))]
6496 + "sub.1\\t#0, %1, %0")
6498 +; When the combiner runs it doesn't have any insight into whether or not an argument
6499 +; to a compare is spilled to the stack and therefore can't swap the comparison in
6500 +; an attempt to use sub.1 more effectively. We peephole this case here.
6503 + [(set (match_operand:QI 0 "register_operand" "")
6504 + (match_operand:QI 1 "ubicom32_arith_operand" ""))
6505 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
6506 + (compare (match_operand:QI 3 "ubicom32_data_register_operand" "")
6509 + (if_then_else (match_operator 4 "comparison_operator"
6512 + (label_ref (match_operand 5 "" ""))
6514 + "(peep2_reg_dead_p (2, operands[0])
6515 + && peep2_regno_dead_p (3, CC_REGNO))"
6516 + [(set (match_dup 2)
6517 + (compare (match_dup 1)
6520 + (if_then_else (match_op_dup 6
6523 + (label_ref (match_dup 5))
6528 + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6529 + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6530 + GET_MODE (operands[4]),
6535 +(define_insn "tsthi_ext2"
6536 + [(set (reg CC_REGNO)
6537 + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6539 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
6542 +(define_expand "cmphi"
6543 + [(set (reg CC_REGNO)
6544 + (compare (match_operand:HI 0 "ubicom32_arith_operand" "")
6545 + (match_operand:HI 1 "ubicom32_compare_operand" "")))]
6550 + /* Is this a cmpi? */
6551 + if (CONST_INT_P (operands[1]))
6554 + /* Must be a sub.2 - if necessary copy an operand into a reg. */
6555 + if (! ubicom32_data_register_operand (operands[1], HImode))
6556 + operands[1] = copy_to_mode_reg (HImode, operands[1]);
6560 + ubicom32_compare_op0 = operands[0];
6561 + ubicom32_compare_op1 = operands[1];
6565 +(define_insn "cmpi"
6566 + [(set (reg CC_REGNO)
6567 + (compare (match_operand:HI 0 "nonimmediate_operand" "rm")
6568 + (match_operand 1 "const_int_operand" "N")))]
6572 +(define_insn "sub2_ccs"
6573 + [(set (reg CC_REGNO)
6574 + (compare (match_operand:HI 0 "ubicom32_arith_operand" "rmI")
6575 + (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6577 + "sub.2\\t#0, %0, %1")
6579 +; If we're testing for equality we don't have to worry about reversing conditions.
6581 +(define_insn "sub2_ccsz_1"
6582 + [(set (reg:CCSZ CC_REGNO)
6583 + (compare:CCSZ (match_operand:HI 0 "nonimmediate_operand" "rm")
6584 + (match_operand:HI 1 "ubicom32_data_register_operand" "d")))]
6586 + "sub.2\\t#0, %0, %1")
6588 +(define_insn "sub2_ccsz_2"
6589 + [(set (reg:CCSZ CC_REGNO)
6590 + (compare:CCSZ (match_operand:HI 0 "ubicom32_data_register_operand" "d")
6591 + (match_operand:HI 1 "ubicom32_arith_operand" "rmI")))]
6593 + "sub.2\\t#0, %1, %0")
6595 +; When the combiner runs it doesn't have any insight into whether or not an argument
6596 +; to a compare is spilled to the stack and therefore can't swap the comparison in
6597 +; an attempt to use sub.2 more effectively. We peephole this case here.
6600 + [(set (match_operand:HI 0 "register_operand" "")
6601 + (match_operand:HI 1 "ubicom32_arith_operand" ""))
6602 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
6603 + (compare (match_operand:HI 3 "ubicom32_data_register_operand" "")
6606 + (if_then_else (match_operator 4 "comparison_operator"
6609 + (label_ref (match_operand 5 "" ""))
6611 + "(peep2_reg_dead_p (2, operands[0])
6612 + && peep2_regno_dead_p (3, CC_REGNO))"
6613 + [(set (match_dup 2)
6614 + (compare (match_dup 1)
6617 + (if_then_else (match_op_dup 6
6620 + (label_ref (match_dup 5))
6625 + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6626 + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6627 + GET_MODE (operands[4]),
6632 +(define_insn_and_split "tstsi_lsl4"
6633 + [(set (match_operand 0 "ubicom32_cc_register_operand" "=r")
6634 + (match_operator 1 "ubicom32_compare_operator"
6635 + [(match_operand:SI 2 "nonimmediate_operand" "rm")
6637 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
6639 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
6641 + [(set (match_dup 0)
6645 + (clobber (match_dup 3))])]
6647 + operands[3] = gen_reg_rtx (SImode);
6650 +(define_insn "tstsi_lsl4_d"
6651 + [(set (reg CC_REGNO)
6652 + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6654 + (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6655 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
6656 + "lsl.4\\t%1, %0, #0")
6658 +; Comparison for equality with -1.
6660 +(define_insn "cmpsi_not4_ccwz"
6661 + [(set (reg CC_REGNO)
6662 + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6664 + "ubicom32_match_cc_mode(insn, CCWZmode)"
6667 +(define_expand "cmpsi"
6668 + [(set (reg CC_REGNO)
6669 + (compare (match_operand:SI 0 "ubicom32_arith_operand" "")
6670 + (match_operand:SI 1 "ubicom32_compare_operand" "")))]
6675 + /* Is this a cmpi? We can't take a memory address as cmpi takes
6676 + 16-bit operands. */
6677 + if (register_operand (operands[0], SImode)
6678 + && CONST_INT_P (operands[1])
6679 + && satisfies_constraint_N (operands[1]))
6682 + /* Must be a sub.4 - if necessary copy an operand into a reg. */
6683 + if (! ubicom32_data_register_operand (operands[1], SImode))
6684 + operands[1] = copy_to_mode_reg (SImode, operands[1]);
6688 + ubicom32_compare_op0 = operands[0];
6689 + ubicom32_compare_op1 = operands[1];
6693 +(define_insn "cmpsi_cmpi"
6694 + [(set (reg CC_REGNO)
6695 + (compare (match_operand:SI 0 "register_operand" "r")
6696 + (match_operand 1 "const_int_operand" "N")))]
6697 + "(satisfies_constraint_N (operands[1]))"
6700 +(define_insn "cmpsi_sub4"
6701 + [(set (reg CC_REGNO)
6702 + (compare (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
6703 + (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6705 + "sub.4\\t#0, %0, %1")
6707 +; If we're testing for equality we don't have to worry about reversing conditions.
6709 +(define_insn "cmpsi_sub4_ccwz_1"
6710 + [(set (reg CC_REGNO)
6711 + (compare (match_operand:SI 0 "nonimmediate_operand" "rm")
6712 + (match_operand:SI 1 "ubicom32_data_register_operand" "d")))]
6713 + "ubicom32_match_cc_mode(insn, CCWZmode)"
6714 + "sub.4\\t#0, %0, %1")
6716 +(define_insn "cmpsi_sub4_ccwz_2"
6717 + [(set (reg CC_REGNO)
6718 + (compare (match_operand:SI 0 "ubicom32_data_register_operand" "d")
6719 + (match_operand:SI 1 "nonimmediate_operand" "rm")))]
6720 + "ubicom32_match_cc_mode(insn, CCWZmode)"
6721 + "sub.4\\t#0, %1, %0")
6723 +; When the combiner runs it doesn't have any insight into whether or not an argument
6724 +; to a compare is spilled to the stack and therefore can't swap the comparison in
6725 +; an attempt to use sub.4 more effectively. We peephole this case here.
6728 + [(set (match_operand:SI 0 "register_operand" "")
6729 + (match_operand:SI 1 "ubicom32_arith_operand" ""))
6730 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
6731 + (compare (match_operand:SI 3 "ubicom32_data_register_operand" "")
6734 + (if_then_else (match_operator 4 "comparison_operator"
6737 + (label_ref (match_operand 5 "" ""))
6739 + "(peep2_reg_dead_p (2, operands[0])
6740 + && peep2_regno_dead_p (3, CC_REGNO))"
6741 + [(set (match_dup 2)
6742 + (compare (match_dup 1)
6745 + (if_then_else (match_op_dup 6
6748 + (label_ref (match_dup 5))
6753 + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6754 + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6755 + GET_MODE (operands[4]),
6760 +(define_insn_and_split "tstdi_or4"
6761 + [(set (reg:CCWZ CC_REGNO)
6762 + (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6768 + [(set (reg:CCWZ CC_REGNO)
6769 + (compare:CCWZ (match_dup 0)
6771 + (clobber (match_dup 1))])]
6773 + operands[1] = gen_reg_rtx (SImode);
6776 +(define_insn "tstdi_or4_d"
6777 + [(set (reg:CCWZ CC_REGNO)
6778 + (compare:CCWZ (match_operand:DI 0 "nonimmediate_operand" "rm")
6780 + (clobber (match_operand:SI 1 "ubicom32_data_register_operand" "=d"))]
6784 + operands[2] = gen_lowpart (SImode, operands[0]);
6785 + operands[3] = gen_highpart_mode (SImode, DImode, operands[0]);
6787 + if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
6788 + return \"or.4\\t#0, %2, %3\";
6790 + return \"move.4\\t%1, %2\;or.4\\t%1, %3, %1\";
6792 + [(set_attr "length" "8")])
6794 +(define_expand "cmpdi"
6795 + [(set (reg CC_REGNO)
6796 + (compare (match_operand:DI 0 "ubicom32_arith_operand" "")
6797 + (match_operand:DI 1 "ubicom32_data_register_operand" "")))]
6800 + ubicom32_compare_op0 = operands[0];
6801 + ubicom32_compare_op1 = operands[1];
6805 +(define_insn "cmpdi_sub4subc"
6806 + [(set (reg CC_REGNO)
6807 + (compare (match_operand:DI 0 "ubicom32_arith_operand" "rmI")
6808 + (match_operand:DI 1 "ubicom32_data_register_operand" "d")))]
6812 + operands[2] = gen_lowpart (SImode, operands[0]);
6813 + operands[3] = gen_lowpart (SImode, operands[1]);
6814 + operands[4] = gen_highpart_mode (SImode, DImode, operands[0]);
6815 + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
6817 + return \"sub.4\\t#0, %2, %3\;subc\\t#0, %4, %5\";
6819 + [(set_attr "length" "8")])
6821 +; When the combiner runs it doesn't have any insight into whether or not an argument
6822 +; to a compare is spilled to the stack and therefore can't swap the comparison in
6823 +; an attempt to use sub.4/subc more effectively. We peephole this case here.
6826 + [(set (match_operand:DI 0 "register_operand" "")
6827 + (match_operand:DI 1 "ubicom32_arith_operand" ""))
6828 + (set (match_operand 2 "ubicom32_cc_register_operand" "")
6829 + (compare (match_operand:DI 3 "ubicom32_data_register_operand" "")
6832 + (if_then_else (match_operator 4 "comparison_operator"
6835 + (label_ref (match_operand 5 "" ""))
6837 + "(peep2_reg_dead_p (2, operands[0])
6838 + && peep2_regno_dead_p (3, CC_REGNO))"
6839 + [(set (match_dup 2)
6840 + (compare (match_dup 1)
6843 + (if_then_else (match_op_dup 6
6846 + (label_ref (match_dup 5))
6851 + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
6852 + operands[6] = gen_rtx_fmt_ee (swap_condition (GET_CODE (operands[4])),
6853 + GET_MODE (operands[4]),
6858 +(define_insn "btst"
6859 + [(set (reg:CCWZ CC_REGNO)
6862 + (match_operand:SI 0 "nonimmediate_operand" "rm")
6864 + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
6869 +(define_insn "bfextu_ccwz_null"
6870 + [(set (reg:CCWZ CC_REGNO)
6873 + (match_operand:SI 0 "nonimmediate_operand" "rm")
6874 + (match_operand 1 "const_int_operand" "M")
6877 + (clobber (match_scratch:SI 2 "=d"))]
6879 + "bfextu\\t%2, %0, %1")
6881 +(define_expand "addqi3"
6883 + [(set (match_operand:QI 0 "memory_operand" "")
6884 + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6885 + (match_operand:QI 2 "ubicom32_arith_operand" "")))
6886 + (clobber (reg:CC CC_REGNO))])]
6889 + if (!memory_operand (operands[0], QImode))
6892 + /* If we have a non-data reg for operand 1 then prefer that over
6893 + a CONST_INT in operand 2. */
6894 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6895 + && CONST_INT_P (operands[2]))
6896 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
6898 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6899 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
6902 +(define_insn "addqi3_add1"
6903 + [(set (match_operand:QI 0 "memory_operand" "=m, m")
6904 + (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
6905 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
6906 + (clobber (reg:CC CC_REGNO))]
6909 + add.1\\t%0, %2, %1
6910 + add.1\\t%0, %1, %2")
6912 +(define_insn "addqi3_add1_ccszn_null"
6913 + [(set (reg CC_REGNO)
6915 + (neg:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm"))
6916 + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d")))]
6918 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
6920 + add.1\\t#0, %1, %0
6921 + add.1\\t#0, %0, %1")
6923 +(define_expand "addhi3"
6925 + [(set (match_operand:HI 0 "memory_operand" "")
6926 + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6927 + (match_operand:HI 2 "ubicom32_arith_operand" "")))
6928 + (clobber (reg:CC CC_REGNO))])]
6931 + if (!memory_operand (operands[0], HImode))
6934 + /* If we have a non-data reg for operand 1 then prefer that over
6935 + a CONST_INT in operand 2. */
6936 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
6937 + && CONST_INT_P (operands[2]))
6938 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
6940 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
6941 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
6944 +(define_insn "addhi3_add2"
6945 + [(set (match_operand:HI 0 "memory_operand" "=m, m")
6946 + (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
6947 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
6948 + (clobber (reg:CC CC_REGNO))]
6951 + add.2\\t%0, %2, %1
6952 + add.2\\t%0, %1, %2")
6954 +(define_insn "addhi3_add2_ccszn_null"
6955 + [(set (reg CC_REGNO)
6957 + (neg:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm"))
6958 + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d")))]
6959 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
6961 + add.2\\t#0, %1, %0
6962 + add.2\\t#0, %0, %1")
6964 +(define_expand "addsi3"
6965 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
6966 + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6967 + (match_operand:SI 2 "ubicom32_move_operand" "")))]
6970 + ubicom32_expand_addsi3 (operands);
6974 +; We start with an instruction pattern that can do all sorts of interesting
6975 +; things but we split out any uses of lea or pdec instructions because
6976 +; those instructions don't clobber the condition codes.
6978 +(define_insn_and_split "addsi3_1"
6979 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm, rm,rm")
6980 + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%a, a, a, a, a, d,rm")
6981 + (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d,rmI, d")))
6982 + (clobber (reg:CC CC_REGNO))]
6990 + add.4\\t%0, %2, %1
6991 + add.4\\t%0, %1, %2"
6992 + "(reload_completed
6993 + && ubicom32_address_register_operand (operands[1], GET_MODE (operands[1])))"
6994 + [(set (match_dup 0)
6995 + (plus:SI (match_dup 1)
7000 +(define_insn "addsi3_1_ccwzn"
7001 + [(set (reg CC_REGNO)
7003 + (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7004 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7006 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7007 + (plus:SI (match_dup 1)
7009 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7011 + add.4\\t%0, %2, %1
7012 + add.4\\t%0, %1, %2")
7014 +(define_insn "addsi3_1_ccwzn_null"
7015 + [(set (reg CC_REGNO)
7017 + (neg:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm"))
7018 + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d")))]
7019 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7021 + add.4\\t#0, %1, %0
7022 + add.4\\t#0, %0, %1")
7024 +(define_insn_and_split "addsi3_2"
7025 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,rm,rm,rm,rm")
7026 + (plus:SI (match_operand:SI 1 "ubicom32_address_register_operand" "%a, a, a, a, a, a")
7027 + (match_operand:SI 2 "ubicom32_move_operand" "L, K, J, P, d, n")))]
7030 + lea.4\\t%0, %E2(%1)
7031 + lea.2\\t%0, %E2(%1)
7032 + lea.1\\t%0, %E2(%1)
7033 + pdec\\t%0, %n2(%1)
7034 + lea.1\\t%0, (%1,%2)
7036 + "(reload_completed
7037 + && ! satisfies_constraint_L (operands[2])
7038 + && ! satisfies_constraint_K (operands[2])
7039 + && ! satisfies_constraint_J (operands[2])
7040 + && ! satisfies_constraint_P (operands[2])
7041 + && ! ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))"
7042 + [(set (reg:SI AUX_DATA_REGNO)
7044 + (set (match_dup 0)
7045 + (plus:SI (match_dup 1)
7046 + (reg:SI AUX_DATA_REGNO)))]
7050 +(define_insn "lea_2"
7051 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7052 + (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7054 + (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7056 + "lea.2\\t%0, (%2,%1)")
7058 +(define_insn "lea_4"
7059 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7060 + (plus:SI (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
7062 + (match_operand:SI 2 "ubicom32_address_register_operand" "a")))]
7064 + "lea.4\\t%0, (%2,%1)")
7066 +(define_expand "adddi3"
7068 + [(set (match_operand:DI 0 "nonimmediate_operand" "")
7069 + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7070 + (match_operand:DI 2 "ubicom32_arith_operand" "")))
7071 + (clobber (reg:CC CC_REGNO))])]
7074 + /* If we have a non-data reg for operand 1 then prefer that over
7075 + a CONST_INT in operand 2. */
7076 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7077 + && CONST_INT_P (operands[2]))
7078 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
7080 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7081 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
7084 +; We construct a 64-bit add from 32-bit operations. Note that we use the
7085 +; & constraint to prevent overlapping registers being allocated. We do
7086 +; allow identical registers though as that won't break anything.
7088 +(define_insn "adddi3_add4addc"
7089 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
7090 + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7091 + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d")))
7092 + (clobber (reg:CC CC_REGNO))]
7096 + operands[3] = gen_lowpart (SImode, operands[0]);
7097 + operands[4] = gen_lowpart (SImode, operands[1]);
7098 + operands[5] = gen_lowpart (SImode, operands[2]);
7099 + operands[6] = gen_highpart (SImode, operands[0]);
7100 + operands[7] = gen_highpart (SImode, operands[1]);
7101 + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7103 + if (ubicom32_data_register_operand (operands[2], GET_MODE (operands[2])))
7104 + return \"add.4\\t%3, %4, %5\;addc\\t%6, %7, %8\";
7106 + return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
7108 + [(set_attr "length" "8")])
7110 +(define_insn "adddi3_ccwz"
7111 + [(set (reg CC_REGNO)
7113 + (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7114 + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d, d,rmI,rmI, d"))
7116 + (set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r,rm, d, m, m")
7117 + (plus:DI (match_dup 1)
7119 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7122 + operands[3] = gen_lowpart (SImode, operands[0]);
7123 + operands[6] = gen_highpart (SImode, operands[0]);
7125 + if (ubicom32_data_register_operand (operands[1], GET_MODE (operands[1])))
7127 + operands[4] = gen_lowpart (SImode, operands[1]);
7128 + operands[5] = gen_lowpart (SImode, operands[2]);
7129 + operands[7] = gen_highpart (SImode, operands[1]);
7130 + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7134 + operands[4] = gen_lowpart (SImode, operands[2]);
7135 + operands[5] = gen_lowpart (SImode, operands[1]);
7136 + operands[7] = gen_highpart (SImode, operands[2]);
7137 + operands[8] = gen_highpart (SImode, operands[1]);
7140 + return \"add.4\\t%3, %5, %4\;addc\\t%6, %8, %7\";
7142 + [(set_attr "length" "8")])
7144 +(define_insn "adddi3_ccwz_null"
7145 + [(set (reg CC_REGNO)
7147 + (neg:DI (match_operand:DI 0 "nonimmediate_operand" "%d,rm"))
7148 + (match_operand:DI 1 "ubicom32_arith_operand" "rmI, d")))]
7149 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7152 + if (ubicom32_data_register_operand (operands[0], GET_MODE (operands[0])))
7154 + operands[2] = gen_lowpart (SImode, operands[0]);
7155 + operands[3] = gen_lowpart (SImode, operands[1]);
7156 + operands[4] = gen_highpart (SImode, operands[0]);
7157 + operands[5] = gen_highpart_mode (SImode, DImode, operands[1]);
7161 + operands[2] = gen_lowpart (SImode, operands[1]);
7162 + operands[3] = gen_lowpart (SImode, operands[0]);
7163 + operands[4] = gen_highpart (SImode, operands[1]);
7164 + operands[5] = gen_highpart (SImode, operands[0]);
7167 + return \"add.4\\t#0, %3, %2\;addc\\t#0, %5, %4\";
7169 + [(set_attr "length" "8")])
7171 +(define_expand "subqi3"
7173 + [(set (match_operand:QI 0 "memory_operand" "")
7174 + (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "")
7175 + (match_operand:QI 2 "ubicom32_data_register_operand" "")))
7176 + (clobber (reg:CC CC_REGNO))])]
7179 + if (!memory_operand (operands[0], QImode))
7183 +(define_insn "subqi3_sub1"
7184 + [(set (match_operand:QI 0 "memory_operand" "=m")
7185 + (minus:QI (match_operand:QI 1 "ubicom32_arith_operand" "rmI")
7186 + (match_operand:QI 2 "ubicom32_data_register_operand" "d")))
7187 + (clobber (reg:CC CC_REGNO))]
7189 + "sub.1\\t%0, %1, %2")
7191 +(define_expand "subhi3"
7193 + [(set (match_operand:HI 0 "memory_operand" "")
7194 + (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "")
7195 + (match_operand:HI 2 "ubicom32_data_register_operand" "")))
7196 + (clobber (reg:CC CC_REGNO))])]
7199 + if (!memory_operand (operands[0], HImode))
7203 +(define_insn "subhi3_sub2"
7204 + [(set (match_operand:HI 0 "memory_operand" "=m")
7205 + (minus:HI (match_operand:HI 1 "ubicom32_arith_operand" "rmI")
7206 + (match_operand:HI 2 "ubicom32_data_register_operand" "d")))
7207 + (clobber (reg:CC CC_REGNO))]
7209 + "sub.2\\t%0, %1, %2")
7211 +(define_insn "subsi3"
7212 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7213 + (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
7214 + (match_operand:SI 2 "ubicom32_data_register_operand" "d")))
7215 + (clobber (reg:CC CC_REGNO))]
7217 + "sub.4\\t%0, %1, %2")
7219 +(define_insn "subsi3_ccwz"
7220 + [(set (reg CC_REGNO)
7222 + (minus:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
7223 + (match_operand:SI 2 "ubicom32_data_register_operand" "d"))
7225 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7226 + (minus:SI (match_dup 1)
7228 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7229 + "sub.4\\t%0, %1, %2")
7231 +; We construct a 64-bit add from 32-bit operations. Note that we use the
7232 +; & constraint to prevent overlapping registers being allocated. We do
7233 +; allow identical registers though as that won't break anything.
7235 +(define_insn "subdi3"
7236 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,r, d, m")
7237 + (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,0,rmI,rmI")
7238 + (match_operand:DI 2 "ubicom32_data_register_operand" "d,d, 0, d")))
7239 + (clobber (reg:CC CC_REGNO))]
7243 + operands[3] = gen_lowpart (SImode, operands[0]);
7244 + operands[4] = gen_lowpart (SImode, operands[1]);
7245 + operands[5] = gen_lowpart (SImode, operands[2]);
7246 + operands[6] = gen_highpart (SImode, operands[0]);
7247 + operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
7248 + operands[8] = gen_highpart (SImode, operands[2]);
7250 + return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
7252 + [(set_attr "length" "8")])
7254 +(define_insn "subdi3_ccwz"
7255 + [(set (reg CC_REGNO)
7257 + (minus:DI (match_operand:DI 1 "ubicom32_arith_operand" "rmI,rmI")
7258 + (match_operand:DI 2 "ubicom32_data_register_operand" "d, d"))
7260 + (set (match_operand:DI 0 "nonimmediate_operand" "=&r, m")
7261 + (minus:DI (match_dup 1)
7263 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7266 + operands[3] = gen_lowpart (SImode, operands[0]);
7267 + operands[4] = gen_lowpart (SImode, operands[1]);
7268 + operands[5] = gen_lowpart (SImode, operands[2]);
7269 + operands[6] = gen_highpart (SImode, operands[0]);
7270 + operands[7] = gen_highpart_mode (SImode, DImode, operands[1]);
7271 + operands[8] = gen_highpart (SImode, operands[2]);
7273 + return \"sub.4\\t%3, %4, %5\;subc\\t%6, %7, %8\";
7275 + [(set_attr "length" "8")])
7277 +;(define_insn "negqi2"
7278 +; [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
7279 +; (neg:QI (match_operand:QI 1 "ubicom32_data_register_operand" "d")))
7280 +; (clobber (reg:CC CC_REGNO))]
7282 +; "sub.1\\t%0, #0, %1")
7284 +;(define_insn "neghi2"
7285 +; [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
7286 +; (neg:HI (match_operand:HI 1 "ubicom32_data_register_operand" "d")))
7287 +; (clobber (reg:CC CC_REGNO))]
7289 +; "sub.2\\t%0, #0, %1")
7291 +(define_insn "negsi2"
7292 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7293 + (neg:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")))
7294 + (clobber (reg:CC CC_REGNO))]
7296 + "sub.4\\t%0, #0, %1")
7298 +(define_insn_and_split "negdi2"
7299 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
7300 + (neg:DI (match_operand:DI 1 "ubicom32_data_register_operand" "d")))
7301 + (clobber (reg:CC CC_REGNO))]
7304 + "reload_completed"
7305 + [(parallel [(set (match_dup 0)
7306 + (minus:DI (const_int 0)
7308 + (clobber (reg:CC CC_REGNO))])]
7310 + [(set_attr "length" "8")])
7312 +(define_insn "umulhisi3"
7313 + [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
7315 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
7316 + (zero_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
7317 + (clobber (reg:HI ACC0_HI_REGNO))
7318 + (clobber (reg:HI ACC1_HI_REGNO))]
7321 + mulu\\t%A0, %2, %1
7322 + mulu\\t%A0, %1, %2"
7323 + [(set_attr "type" "mul,mul")])
7325 +(define_insn "mulhisi3"
7326 + [(set (match_operand:SI 0 "ubicom32_acc_lo_register_operand" "=l, l")
7328 + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "%d,rm"))
7329 + (sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rm, d"))))
7330 + (clobber (reg:HI ACC0_HI_REGNO))
7331 + (clobber (reg:HI ACC1_HI_REGNO))]
7334 + muls\\t%A0, %2, %1
7335 + muls\\t%A0, %1, %2"
7336 + [(set_attr "type" "mul,mul")])
7338 +(define_expand "mulsi3"
7339 + [(set (match_operand:SI 0 "ubicom32_acc_hi_register_operand" "")
7340 + (mult:SI (match_operand:SI 1 "ubicom32_arith_operand" "")
7341 + (match_operand:SI 2 "ubicom32_arith_operand" "")))]
7344 + if (ubicom32_emit_mult_sequence (operands))
7348 +(define_insn "umulsidi3"
7349 + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
7351 + (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
7352 + (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
7355 + mulu.4\\t%A0, %2, %1
7356 + mulu.4\\t%A0, %1, %2"
7357 + [(set_attr "type" "mul,mul")])
7360 + [(set (match_operand:SI 0 "register_operand" "")
7361 + (match_operand:SI 1 "nonimmediate_operand" ""))
7362 + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7364 + (zero_extend:DI (match_dup 0))
7365 + (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
7366 + "(peep2_reg_dead_p (2, operands[0])
7367 + || REGNO (operands[0]) == REGNO (operands[2])
7368 + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7369 + && ! rtx_equal_p (operands[0], operands[3])"
7370 + [(set (match_dup 2)
7372 + (zero_extend:DI (match_dup 1))
7373 + (zero_extend:DI (match_dup 3))))]
7377 + [(set (match_operand:SI 0 "register_operand" "")
7378 + (match_operand:SI 1 "nonimmediate_operand" ""))
7379 + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7381 + (zero_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
7382 + (zero_extend:DI (match_dup 0))))]
7383 + "(peep2_reg_dead_p (2, operands[0])
7384 + || REGNO (operands[0]) == REGNO (operands[2])
7385 + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7386 + && ! rtx_equal_p (operands[0], operands[3])"
7387 + [(set (match_dup 2)
7389 + (zero_extend:DI (match_dup 1))
7390 + (zero_extend:DI (match_dup 3))))]
7393 +(define_insn "umulsidi3_const"
7394 + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
7396 + (zero_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
7397 + (match_operand 2 "const_int_operand" "I")))]
7398 + "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
7399 + "mulu.4\\t%A0, %2, %1"
7400 + [(set_attr "type" "mul")])
7402 +(define_insn "mulsidi3"
7403 + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h, h")
7405 + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%d,rm"))
7406 + (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm, d"))))]
7409 + muls.4\\t%A0, %2, %1
7410 + muls.4\\t%A0, %1, %2"
7411 + [(set_attr "type" "mul,mul")])
7414 + [(set (match_operand:SI 0 "register_operand" "")
7415 + (match_operand:SI 1 "nonimmediate_operand" ""))
7416 + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7418 + (sign_extend:DI (match_dup 0))
7419 + (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))))]
7420 + "(peep2_reg_dead_p (2, operands[0])
7421 + || REGNO (operands[0]) == REGNO (operands[2])
7422 + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7423 + && ! rtx_equal_p (operands[0], operands[3])"
7424 + [(set (match_dup 2)
7426 + (sign_extend:DI (match_dup 1))
7427 + (sign_extend:DI (match_dup 3))))]
7431 + [(set (match_operand:SI 0 "register_operand" "")
7432 + (match_operand:SI 1 "nonimmediate_operand" ""))
7433 + (set (match_operand:DI 2 "ubicom32_acc_hi_register_operand" "")
7435 + (sign_extend:DI (match_operand:SI 3 "ubicom32_data_register_operand" ""))
7436 + (sign_extend:DI (match_dup 0))))]
7437 + "(peep2_reg_dead_p (2, operands[0])
7438 + || REGNO (operands[0]) == REGNO (operands[2])
7439 + || REGNO (operands[0]) == REGNO (operands[2]) + 1)
7440 + && ! rtx_equal_p (operands[0], operands[3])"
7441 + [(set (match_dup 2)
7443 + (sign_extend:DI (match_dup 1))
7444 + (sign_extend:DI (match_dup 3))))]
7447 +(define_insn "mulsidi3_const"
7448 + [(set (match_operand:DI 0 "ubicom32_acc_hi_register_operand" "=h")
7450 + (sign_extend:DI (match_operand:SI 1 "ubicom32_data_register_operand" "%d"))
7451 + (match_operand 2 "const_int_operand" "I")))]
7452 + "(ubicom32_v4 && satisfies_constraint_I (operands[2]))"
7453 + "muls.4\\t%A0, %2, %1"
7454 + [(set_attr "type" "mul")])
7456 +(define_expand "andqi3"
7458 + [(set (match_operand:QI 0 "memory_operand" "")
7459 + (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
7460 + (match_operand:QI 2 "ubicom32_arith_operand" "")))
7461 + (clobber (reg:CC CC_REGNO))])]
7464 + if (!memory_operand (operands[0], QImode))
7467 + /* If we have a non-data reg for operand 1 then prefer that over
7468 + a CONST_INT in operand 2. */
7469 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7470 + && CONST_INT_P (operands[2]))
7471 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
7473 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7474 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
7477 +(define_insn "andqi3_and1"
7478 + [(set (match_operand:QI 0 "memory_operand" "=m, m")
7479 + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7480 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
7481 + (clobber (reg:CC CC_REGNO))]
7484 + and.1\\t%0, %2, %1
7485 + and.1\\t%0, %1, %2")
7487 +(define_insn "andqi3_and1_ccszn"
7488 + [(set (reg CC_REGNO)
7490 + (and:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7491 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
7493 + (set (match_operand:QI 0 "memory_operand" "=m, m")
7494 + (and:QI (match_dup 1)
7497 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
7499 + and.1\\t%0, %2, %1
7500 + and.1\\t%0, %1, %2")
7502 +(define_insn "andqi3_and1_ccszn_null"
7503 + [(set (reg CC_REGNO)
7505 + (and:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
7506 + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
7509 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
7511 + and.1\\t#0, %1, %0
7512 + and.1\\t#0, %0, %1")
7514 +(define_insn "and1_ccszn_null_1"
7515 + [(set (reg CC_REGNO)
7518 + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
7519 + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
7523 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
7524 + "and.1\\t#0, %1, %0")
7526 +(define_insn "and1_ccszn_null_2"
7527 + [(set (reg CC_REGNO)
7530 + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
7532 + (match_operand:QI 1 "memory_operand" "m")
7537 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
7538 + "and.1\\t#0, %1, %0")
7540 +(define_insn "and1_ccszn_null_3"
7541 + [(set (reg CC_REGNO)
7544 + (and:SI (subreg:SI
7545 + (match_operand:QI 0 "memory_operand" "m")
7547 + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
7551 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
7552 + "and.1\\t#0, %0, %1")
7554 +(define_expand "andhi3"
7556 + [(set (match_operand:HI 0 "memory_operand" "")
7557 + (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
7558 + (match_operand:HI 2 "ubicom32_arith_operand" "")))
7559 + (clobber (reg:CC CC_REGNO))])]
7562 + if (!memory_operand (operands[0], HImode))
7565 + /* If we have a non-data reg for operand 1 then prefer that over
7566 + a CONST_INT in operand 2. */
7567 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7568 + && CONST_INT_P (operands[2]))
7569 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
7571 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7572 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
7575 +(define_insn "andhi3_and2"
7576 + [(set (match_operand:HI 0 "memory_operand" "=m, m")
7577 + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7578 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
7579 + (clobber (reg:CC CC_REGNO))]
7582 + and.2\\t%0, %2, %1
7583 + and.2\\t%0, %1, %2")
7585 +(define_insn "andhi3_and2_ccszn"
7586 + [(set (reg CC_REGNO)
7588 + (and:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7589 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
7591 + (set (match_operand:HI 0 "memory_operand" "=m, m")
7592 + (and:HI (match_dup 1)
7594 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
7596 + and.2\\t%0, %2, %1
7597 + and.2\\t%0, %1, %2")
7599 +(define_insn "andhi3_and2_ccszn_null"
7600 + [(set (reg CC_REGNO)
7602 + (and:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
7603 + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
7605 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
7607 + and.2\\t#0, %1, %0
7608 + and.2\\t#0, %0, %1")
7610 +(define_insn "and2_ccszn_null_1"
7611 + [(set (reg CC_REGNO)
7614 + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
7615 + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
7618 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
7619 + "and.2\\t#0, %1, %0")
7621 +(define_insn "and2_ccszn_null_2"
7622 + [(set (reg CC_REGNO)
7625 + (and:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
7627 + (match_operand:HI 1 "memory_operand" "m")
7631 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
7632 + "and.2\\t#0, %1, %0")
7634 +(define_insn "and2_ccszn_null_3"
7635 + [(set (reg CC_REGNO)
7638 + (and:SI (subreg:SI
7639 + (match_operand:HI 0 "memory_operand" "m")
7641 + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
7644 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
7645 + "and.2\\t#0, %0, %1")
7647 +(define_expand "andsi3"
7649 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
7650 + (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
7651 + (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
7652 + (clobber (reg:CC CC_REGNO))])]
7657 + /* Is this a bfextu? */
7658 + if (ubicom32_data_register_operand (operands[0], SImode)
7659 + && CONST_INT_P (operands[2])
7660 + && exact_log2 (INTVAL (operands[2]) + 1) != -1)
7663 + /* Is this a bclr? */
7664 + if (CONST_INT_P (operands[2])
7665 + && exact_log2 (~INTVAL (operands[2])) != -1)
7668 + /* Must be an and.4 */
7669 + if (!ubicom32_data_register_operand (operands[1], SImode))
7670 + operands[1] = copy_to_mode_reg (SImode, operands[1]);
7672 + if (!ubicom32_arith_operand (operands[2], SImode))
7673 + operands[2] = copy_to_mode_reg (SImode, operands[2]);
7678 +(define_insn "andsi3_bfextu"
7679 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
7680 + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
7681 + (match_operand:SI 2 "const_int_operand" "O")))
7682 + (clobber (reg:CC CC_REGNO))]
7683 + "(satisfies_constraint_O (operands[2]))"
7686 + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
7688 + return \"bfextu\\t%0, %1, %3\";
7691 +(define_insn "andsi3_bfextu_ccwz"
7692 + [(set (reg CC_REGNO)
7694 + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%rm")
7695 + (match_operand:SI 2 "const_int_operand" "O"))
7697 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
7698 + (and:SI (match_dup 1)
7700 + "(satisfies_constraint_O (operands[2])
7701 + && ubicom32_match_cc_mode(insn, CCWZmode))"
7704 + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[2]) + 1));
7706 + return \"bfextu\\t%0, %1, %3\";
7709 +(define_insn "andsi3_bfextu_ccwz_null"
7710 + [(set (reg CC_REGNO)
7712 + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
7713 + (match_operand:SI 1 "const_int_operand" "O"))
7715 + (clobber (match_scratch:SI 2 "=d"))]
7716 + "(satisfies_constraint_O (operands[1])
7717 + && ubicom32_match_cc_mode(insn, CCWZmode))"
7720 + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1]) + 1));
7722 + return \"bfextu\\t%2, %0, %3\";
7725 +(define_insn "andsi3_bclr"
7726 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7727 + (and:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
7728 + (match_operand:SI 2 "const_int_operand" "n")))
7729 + (clobber (reg:CC CC_REGNO))]
7730 + "(exact_log2 (~INTVAL (operands[2])) != -1)"
7731 + "bclr\\t%0, %1, #%D2")
7733 +(define_insn "andsi3_and4"
7734 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7735 + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7736 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
7737 + (clobber (reg:CC CC_REGNO))]
7740 + and.4\\t%0, %2, %1
7741 + and.4\\t%0, %1, %2")
7743 +(define_insn "andsi3_and4_ccwzn"
7744 + [(set (reg CC_REGNO)
7746 + (and:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7747 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7749 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7750 + (and:SI (match_dup 1)
7752 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7754 + and.4\\t%0, %2, %1
7755 + and.4\\t%0, %1, %2")
7757 +(define_insn "andsi3_and4_ccwzn_null"
7758 + [(set (reg CC_REGNO)
7760 + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
7761 + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
7763 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7765 + and.4\\t#0, %1, %0
7766 + and.4\\t#0, %0, %1")
7768 +(define_insn "andsi3_lsr4_ccwz_null"
7769 + [(set (reg CC_REGNO)
7771 + (and:SI (match_operand:SI 0 "nonimmediate_operand" "%rm")
7772 + (match_operand:SI 1 "const_int_operand" "n"))
7774 + (clobber (match_scratch:SI 2 "=d"))]
7775 + "(exact_log2 ((~(INTVAL (operands[1]))) + 1) != -1
7776 + && ubicom32_match_cc_mode(insn, CCWZmode))"
7779 + operands[3] = GEN_INT (exact_log2 ((~(INTVAL (operands[1]))) + 1));
7781 + return \"lsr.4\\t%2, %0, %3\";
7784 +; We really would like the combiner to recognize this scenario and deal with
7785 +; it but unfortunately it tries to canonicalize zero_extract ops on MEMs
7786 +; into QImode operations and we can't match them in any useful way.
7789 + [(set (match_operand:SI 0 "register_operand" "")
7790 + (match_operand:SI 1 "const_int_operand" ""))
7791 + (set (reg:CCWZ CC_REGNO)
7793 + (and:SI (match_operand:SI 2 "nonimmediate_operand" "")
7796 + "(exact_log2 (INTVAL (operands[1])) != -1
7797 + && peep2_reg_dead_p (2, operands[0]))"
7798 + [(set (reg:CCWZ CC_REGNO)
7806 + operands[3] = GEN_INT (exact_log2 (INTVAL (operands[1])));
7809 +(define_expand "anddi3"
7811 + [(set (match_operand:DI 0 "nonimmediate_operand" "")
7812 + (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
7813 + (match_operand:DI 2 "ubicom32_arith_operand" "")))
7814 + (clobber (reg:CC CC_REGNO))])]
7817 + /* If we have a non-data reg for operand 1 then prefer that over
7818 + a CONST_INT in operand 2. */
7819 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7820 + && CONST_INT_P (operands[2]))
7821 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
7823 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7824 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
7827 +(define_insn_and_split "anddi3_and4"
7828 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
7829 + (and:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
7830 + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
7831 + (clobber (reg:CC CC_REGNO))]
7834 + "reload_completed"
7835 + [(parallel [(set (match_dup 3)
7836 + (and:SI (match_dup 4)
7838 + (clobber (reg:CC CC_REGNO))])
7839 + (parallel [(set (match_dup 6)
7840 + (and:SI (match_dup 7)
7842 + (clobber (reg:CC CC_REGNO))])]
7844 + operands[3] = gen_lowpart (SImode, operands[0]);
7845 + operands[4] = gen_lowpart (SImode, operands[1]);
7846 + operands[5] = gen_lowpart (SImode, operands[2]);
7847 + operands[6] = gen_highpart (SImode, operands[0]);
7848 + operands[7] = gen_highpart (SImode, operands[1]);
7849 + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
7851 + [(set_attr "length" "8")])
7853 +(define_expand "iorqi3"
7855 + [(set (match_operand:QI 0 "memory_operand" "")
7856 + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
7857 + (match_operand:QI 2 "ubicom32_arith_operand" "")))
7858 + (clobber (reg:CC CC_REGNO))])]
7861 + if (!memory_operand (operands[0], QImode))
7864 + /* If we have a non-data reg for operand 1 then prefer that over
7865 + a CONST_INT in operand 2. */
7866 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7867 + && CONST_INT_P (operands[2]))
7868 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
7870 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7871 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
7874 +(define_insn "iorqi3_or1"
7875 + [(set (match_operand:QI 0 "memory_operand" "=m, m")
7876 + (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
7877 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
7878 + (clobber (reg:CC CC_REGNO))]
7882 + or.1\\t%0, %1, %2")
7884 +(define_expand "iorhi3"
7886 + [(set (match_operand:HI 0 "memory_operand" "")
7887 + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
7888 + (match_operand:HI 2 "ubicom32_arith_operand" "")))
7889 + (clobber (reg:CC CC_REGNO))])]
7892 + if (!memory_operand (operands[0], HImode))
7895 + /* If we have a non-data reg for operand 1 then prefer that over
7896 + a CONST_INT in operand 2. */
7897 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7898 + && CONST_INT_P (operands[2]))
7899 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
7901 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7902 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
7905 +(define_insn "iorhi3_or2"
7906 + [(set (match_operand:HI 0 "memory_operand" "=m, m")
7907 + (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
7908 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
7909 + (clobber (reg:CC CC_REGNO))]
7913 + or.2\\t%0, %1, %2")
7915 +(define_expand "iorsi3"
7917 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
7918 + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
7919 + (match_operand:SI 2 "ubicom32_and_or_si3_operand" "")))
7920 + (clobber (reg:CC CC_REGNO))])]
7925 + /* Is this a bset? */
7926 + if (CONST_INT_P (operands[2])
7927 + && exact_log2 (INTVAL (operands[2])) != -1)
7930 + /* Must be an or.4 */
7931 + if (!ubicom32_data_register_operand (operands[1], SImode))
7932 + operands[1] = copy_to_mode_reg (SImode, operands[1]);
7934 + if (!ubicom32_arith_operand (operands[2], SImode))
7935 + operands[2] = copy_to_mode_reg (SImode, operands[2]);
7940 +(define_insn "iorsi3_bset"
7941 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
7942 + (ior:SI (match_operand:SI 1 "ubicom32_arith_operand" "%rmI")
7943 + (match_operand 2 "const_int_operand" "n")))
7944 + (clobber (reg:CC CC_REGNO))]
7945 + "(exact_log2 (INTVAL (operands[2])) != -1)"
7946 + "bset\\t%0, %1, #%d2")
7948 +(define_insn "iorsi3_or4"
7949 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7950 + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7951 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
7952 + (clobber (reg:CC CC_REGNO))]
7956 + or.4\\t%0, %1, %2")
7958 +(define_insn "iorsi3_ccwzn"
7959 + [(set (reg CC_REGNO)
7961 + (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
7962 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
7964 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
7965 + (ior:SI (match_dup 1)
7967 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7970 + or.4\\t%0, %1, %2")
7972 +(define_insn "iorsi3_ccwzn_null"
7973 + [(set (reg CC_REGNO)
7975 + (ior:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
7976 + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
7978 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
7981 + or.4\\t#0, %0, %1")
7983 +(define_expand "iordi3"
7985 + [(set (match_operand:DI 0 "nonimmediate_operand" "")
7986 + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
7987 + (match_operand:DI 2 "ubicom32_arith_operand" "")))
7988 + (clobber (reg:CC CC_REGNO))])]
7991 + /* If we have a non-data reg for operand 1 then prefer that over
7992 + a CONST_INT in operand 2. */
7993 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
7994 + && CONST_INT_P (operands[2]))
7995 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
7997 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
7998 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
8001 +(define_insn_and_split "iordi3_or4"
8002 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
8003 + (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
8004 + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
8005 + (clobber (reg:CC CC_REGNO))]
8008 + "reload_completed"
8009 + [(parallel [(set (match_dup 3)
8010 + (ior:SI (match_dup 4)
8012 + (clobber (reg:CC CC_REGNO))])
8013 + (parallel [(set (match_dup 6)
8014 + (ior:SI (match_dup 7)
8016 + (clobber (reg:CC CC_REGNO))])]
8018 + operands[3] = gen_lowpart (SImode, operands[0]);
8019 + operands[4] = gen_lowpart (SImode, operands[1]);
8020 + operands[5] = gen_lowpart (SImode, operands[2]);
8021 + operands[6] = gen_highpart (SImode, operands[0]);
8022 + operands[7] = gen_highpart (SImode, operands[1]);
8023 + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
8025 + [(set_attr "length" "8")])
8027 +(define_expand "xorqi3"
8029 + [(set (match_operand:QI 0 "memory_operand" "")
8030 + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
8031 + (match_operand:QI 2 "ubicom32_arith_operand" "")))
8032 + (clobber (reg:CC CC_REGNO))])]
8035 + if (!memory_operand (operands[0], QImode))
8038 + /* If we have a non-data reg for operand 1 then prefer that over
8039 + a CONST_INT in operand 2. */
8040 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8041 + && CONST_INT_P (operands[2]))
8042 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
8044 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8045 + operands[2] = copy_to_mode_reg (QImode, operands[2]);
8048 +(define_insn "xorqi3_xor1"
8049 + [(set (match_operand:QI 0 "memory_operand" "=m, m")
8050 + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
8051 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d")))
8052 + (clobber (reg:CC CC_REGNO))]
8055 + xor.1\\t%0, %2, %1
8056 + xor.1\\t%0, %1, %2")
8058 +(define_insn "xorqi3_xor1_ccszn"
8059 + [(set (reg CC_REGNO)
8061 + (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%d,rm")
8062 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI, d"))
8064 + (set (match_operand:QI 0 "memory_operand" "=m, m")
8065 + (xor:QI (match_dup 1)
8068 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
8070 + xor.1\\t%0, %2, %1
8071 + xor.1\\t%0, %1, %2")
8073 +(define_insn "xorqi3_xor1_ccszn_null"
8074 + [(set (reg CC_REGNO)
8076 + (xor:QI (match_operand:QI 0 "nonimmediate_operand" "%d,rm")
8077 + (match_operand:QI 1 "ubicom32_arith_operand" "rmI, d"))
8080 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
8082 + xor.1\\t#0, %1, %0
8083 + xor.1\\t#0, %0, %1")
8085 +(define_insn "xor1_ccszn_null_1"
8086 + [(set (reg CC_REGNO)
8089 + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
8090 + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
8094 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
8095 + "xor.1\\t#0, %1, %0")
8097 +(define_insn "xor1_ccszn_null_2"
8098 + [(set (reg CC_REGNO)
8101 + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
8103 + (match_operand:QI 1 "memory_operand" "m")
8108 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
8109 + "xor.1\\t#0, %1, %0")
8111 +(define_insn "xor1_ccwzn_null_3"
8112 + [(set (reg CC_REGNO)
8115 + (xor:SI (subreg:SI
8116 + (match_operand:QI 0 "memory_operand" "m")
8118 + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
8122 + && ubicom32_match_cc_mode(insn, CCSZNmode))"
8123 + "xor.1\\t#0, %0, %1")
8125 +(define_expand "xorhi3"
8127 + [(set (match_operand:HI 0 "memory_operand" "")
8128 + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
8129 + (match_operand:HI 2 "ubicom32_arith_operand" "")))
8130 + (clobber (reg:CC CC_REGNO))])]
8133 + if (!memory_operand (operands[0], HImode))
8136 + /* If we have a non-data reg for operand 1 then prefer that over
8137 + a CONST_INT in operand 2. */
8138 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8139 + && CONST_INT_P (operands[2]))
8140 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
8142 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8143 + operands[2] = copy_to_mode_reg (HImode, operands[2]);
8146 +(define_insn "xorhi3_xor2"
8147 + [(set (match_operand:HI 0 "memory_operand" "=m, m")
8148 + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
8149 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d")))
8150 + (clobber (reg:CC CC_REGNO))]
8153 + xor.2\\t%0, %2, %1
8154 + xor.2\\t%0, %1, %2")
8156 +(define_insn "xorhi3_xor2_ccszn"
8157 + [(set (reg CC_REGNO)
8159 + (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%d,rm")
8160 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI, d"))
8162 + (set (match_operand:HI 0 "memory_operand" "=m, m")
8163 + (xor:HI (match_dup 1)
8165 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
8167 + xor.2\\t%0, %2, %1
8168 + xor.2\\t%0, %1, %2")
8170 +(define_insn "xorhi3_xor2_ccszn_null"
8171 + [(set (reg CC_REGNO)
8173 + (xor:HI (match_operand:HI 0 "nonimmediate_operand" "%d,rm")
8174 + (match_operand:HI 1 "ubicom32_arith_operand" "rmI, d"))
8176 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
8178 + xor.2\\t#0, %1, %0
8179 + xor.2\\t#0, %0, %1")
8181 +(define_insn "xor2_ccszn_null_1"
8182 + [(set (reg CC_REGNO)
8185 + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "%d")
8186 + (match_operand:SI 1 "ubicom32_arith_operand" "rI"))
8189 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
8190 + "xor.2\\t#0, %1, %0")
8192 +(define_insn "xor2_ccszn_null_2"
8193 + [(set (reg CC_REGNO)
8196 + (xor:SI (match_operand:SI 0 "ubicom32_data_register_operand" "d")
8198 + (match_operand:HI 1 "memory_operand" "m")
8202 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
8203 + "xor.2\\t#0, %1, %0")
8205 +(define_insn "xor2_ccszn_null_3"
8206 + [(set (reg CC_REGNO)
8209 + (xor:SI (subreg:SI
8210 + (match_operand:HI 0 "memory_operand" "m")
8212 + (match_operand:SI 1 "ubicom32_data_register_operand" "d"))
8215 + "ubicom32_match_cc_mode(insn, CCSZNmode)"
8216 + "xor.2\\t#0, %0, %1")
8218 +(define_insn "xorsi3"
8219 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8220 + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
8221 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d")))
8222 + (clobber (reg:CC CC_REGNO))]
8225 + xor.4\\t%0, %2, %1
8226 + xor.4\\t%0, %1, %2")
8228 +(define_insn "xorsi3_ccwzn"
8229 + [(set (reg CC_REGNO)
8231 + (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%d,rm")
8232 + (match_operand:SI 2 "ubicom32_arith_operand" "rmI, d"))
8234 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
8235 + (xor:SI (match_dup 1)
8237 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8239 + xor.4\\t%0, %2, %1
8240 + xor.4\\t%0, %1, %2")
8242 +(define_insn "xorsi3_ccwzn_null"
8243 + [(set (reg CC_REGNO)
8245 + (xor:SI (match_operand:SI 0 "nonimmediate_operand" "%d,rm")
8246 + (match_operand:SI 1 "ubicom32_arith_operand" "rmI, d"))
8248 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8250 + xor.4\\t#0, %1, %0
8251 + xor.4\\t#0, %0, %1")
8253 +(define_expand "xordi3"
8255 + [(set (match_operand:DI 0 "nonimmediate_operand" "")
8256 + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
8257 + (match_operand:DI 2 "ubicom32_arith_operand" "")))
8258 + (clobber (reg:CC CC_REGNO))])]
8261 + /* If we have a non-data reg for operand 1 then prefer that over
8262 + a CONST_INT in operand 2. */
8263 + if (! ubicom32_data_register_operand (operands[1], GET_MODE (operands[1]))
8264 + && CONST_INT_P (operands[2]))
8265 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
8267 + if (CONST_INT_P (operands[2]) && ! satisfies_constraint_I (operands[2]))
8268 + operands[2] = copy_to_mode_reg (DImode, operands[2]);
8271 +(define_insn_and_split "xordi3_xor4"
8272 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&r,&r, d,rm, m, m")
8273 + (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%d,rm, 0, 0, d,rm")
8274 + (match_operand:DI 2 "ubicom32_arith_operand" "rmI, d,rmI, d,rmI, d")))
8275 + (clobber (reg:CC CC_REGNO))]
8278 + "reload_completed"
8279 + [(parallel [(set (match_dup 3)
8280 + (xor:SI (match_dup 4)
8282 + (clobber (reg:CC CC_REGNO))])
8283 + (parallel [(set (match_dup 6)
8284 + (xor:SI (match_dup 7)
8286 + (clobber (reg:CC CC_REGNO))])]
8288 + operands[3] = gen_lowpart (SImode, operands[0]);
8289 + operands[4] = gen_lowpart (SImode, operands[1]);
8290 + operands[5] = gen_lowpart (SImode, operands[2]);
8291 + operands[6] = gen_highpart (SImode, operands[0]);
8292 + operands[7] = gen_highpart (SImode, operands[1]);
8293 + operands[8] = gen_highpart_mode (SImode, DImode, operands[2]);
8295 + [(set_attr "length" "8")])
8297 +(define_insn "not2_2"
8298 + [(set (match_operand:HI 0 "memory_operand" "=m")
8300 + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
8302 + (clobber (reg:CC CC_REGNO))]
8306 +(define_insn "one_cmplsi2"
8307 + [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8308 + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")))
8309 + (clobber (reg:CC CC_REGNO))]
8313 +(define_insn "one_cmplsi2_ccwzn"
8314 + [(set (reg CC_REGNO)
8316 + (not:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI"))
8318 + (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
8319 + (not:SI (match_dup 1)))]
8320 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8323 +(define_insn "one_cmplsi2_ccwzn_null"
8324 + [(set (reg CC_REGNO)
8326 + (not:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI"))
8328 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8331 +(define_insn_and_split "one_cmpldi2"
8332 + [(set (match_operand:DI 0 "nonimmediate_operand" "=&rm")
8333 + (not:DI (match_operand:DI 1 "nonimmediate_operand" "rmI0")))
8334 + (clobber (reg:CC CC_REGNO))]
8338 + [(parallel [(set (match_dup 2)
8339 + (not:SI (match_dup 3)))
8340 + (clobber (reg:CC CC_REGNO))])
8341 + (parallel [(set (match_dup 4)
8342 + (not:SI (match_dup 5)))
8343 + (clobber (reg:CC CC_REGNO))])]
8345 + operands[2] = gen_lowpart (SImode, operands[0]);
8346 + operands[3] = gen_lowpart (SImode, operands[1]);
8347 + operands[4] = gen_highpart (SImode, operands[0]);
8348 + operands[5] = gen_highpart (SImode, operands[1]);
8350 + [(set_attr "length" "8")])
8352 +; Conditional jump instructions
8354 +(define_expand "beq"
8356 + (if_then_else (eq (match_dup 1)
8358 + (label_ref (match_operand 0 "" ""))
8362 + operands[1] = ubicom32_gen_compare_reg (EQ, ubicom32_compare_op0,
8363 + ubicom32_compare_op1);
8366 +(define_expand "bne"
8368 + (if_then_else (ne (match_dup 1)
8370 + (label_ref (match_operand 0 "" ""))
8374 + operands[1] = ubicom32_gen_compare_reg (NE, ubicom32_compare_op0,
8375 + ubicom32_compare_op1);
8378 +(define_expand "bgt"
8380 + (if_then_else (gt (match_dup 1)
8382 + (label_ref (match_operand 0 "" ""))
8386 + operands[1] = ubicom32_gen_compare_reg (GT, ubicom32_compare_op0,
8387 + ubicom32_compare_op1);
8390 +(define_expand "ble"
8392 + (if_then_else (le (match_dup 1)
8394 + (label_ref (match_operand 0 "" ""))
8398 + operands[1] = ubicom32_gen_compare_reg (LE, ubicom32_compare_op0,
8399 + ubicom32_compare_op1);
8402 +(define_expand "bge"
8404 + (if_then_else (ge (match_dup 1)
8406 + (label_ref (match_operand 0 "" ""))
8410 + operands[1] = ubicom32_gen_compare_reg (GE, ubicom32_compare_op0,
8411 + ubicom32_compare_op1);
8414 +(define_expand "blt"
8416 + (if_then_else (lt (match_dup 1)
8418 + (label_ref (match_operand 0 "" ""))
8422 + operands[1] = ubicom32_gen_compare_reg (LT, ubicom32_compare_op0,
8423 + ubicom32_compare_op1);
8426 +(define_expand "bgtu"
8428 + (if_then_else (gtu (match_dup 1)
8430 + (label_ref (match_operand 0 "" ""))
8434 + operands[1] = ubicom32_gen_compare_reg (GTU, ubicom32_compare_op0,
8435 + ubicom32_compare_op1);
8438 +(define_expand "bleu"
8440 + (if_then_else (leu (match_dup 1)
8442 + (label_ref (match_operand 0 "" ""))
8446 + operands[1] = ubicom32_gen_compare_reg (LEU, ubicom32_compare_op0,
8447 + ubicom32_compare_op1);
8450 +(define_expand "bgeu"
8452 + (if_then_else (geu (match_dup 1)
8454 + (label_ref (match_operand 0 "" ""))
8458 + operands[1] = ubicom32_gen_compare_reg (GEU, ubicom32_compare_op0,
8459 + ubicom32_compare_op1);
8462 +(define_expand "bltu"
8464 + (if_then_else (ltu (match_dup 1)
8466 + (label_ref (match_operand 0 "" ""))
8470 + operands[1] = ubicom32_gen_compare_reg (LTU, ubicom32_compare_op0,
8471 + ubicom32_compare_op1);
8476 + (if_then_else (match_operator 1 "comparison_operator"
8477 + [(match_operand 2 "ubicom32_cc_register_operand" "")
8479 + (label_ref (match_operand 0 "" ""))
8484 + ubicom32_output_cond_jump (insn, operands[1], operands[0]);
8488 +; Reverse branch - reverse our comparison condition so that we can
8489 +; branch in the opposite sense.
8491 +(define_insn_and_split "jcc_reverse"
8493 + (if_then_else (match_operator 1 "comparison_operator"
8494 + [(match_operand 2 "ubicom32_cc_register_operand" "")
8497 + (label_ref (match_operand 0 "" ""))))]
8500 + "reload_completed"
8502 + (if_then_else (match_dup 3)
8503 + (label_ref (match_dup 0))
8508 + cc_reg = gen_rtx_REG (GET_MODE (operands[2]), CC_REGNO);
8509 + operands[3] = gen_rtx_fmt_ee (reverse_condition (GET_CODE (operands[1])),
8510 + GET_MODE (operands[1]),
8515 +(define_insn "jump"
8517 + (label_ref (match_operand 0 "" "")))]
8521 +(define_expand "indirect_jump"
8522 + [(parallel [(set (pc)
8523 + (match_operand:SI 0 "register_operand" ""))
8524 + (clobber (match_dup 0))])]
8528 +(define_insn "indirect_jump_internal"
8530 + (match_operand:SI 0 "register_operand" "a"))
8531 + (clobber (match_dup 0))]
8533 + "calli\\t%0,0(%0)")
8535 +; Program Space: The table contains instructions, typically jumps.
8536 +; CALL An,TABLE_SIZE(PC) ;An = Jump Table Base Address.
8537 +; <Jump Table is Here> ;An -> Here.
8538 +; LEA Ak, (An,Dn) ;Ak -> Table Entry
8541 +(define_expand "tablejump"
8542 + [(parallel [(set (pc)
8543 + (match_operand:SI 0 "nonimmediate_operand" ""))
8544 + (use (label_ref (match_operand 1 "" "")))])]
8548 +(define_insn "tablejump_internal"
8550 + (match_operand:SI 0 "nonimmediate_operand" "rm"))
8551 + (use (label_ref (match_operand 1 "" "")))]
8555 +; Call subroutine with no return value.
8557 +(define_expand "call"
8558 + [(call (match_operand:QI 0 "general_operand" "")
8559 + (match_operand:SI 1 "general_operand" ""))]
8564 + ubicom32_expand_call_fdpic (operands);
8568 + if (! ubicom32_call_address_operand (XEXP (operands[0], 0), VOIDmode))
8569 + XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
8572 +; We expand to a simple form that doesn't clobber the link register and
8573 +; then split to a form that does. This allows the RTL optimizers that
8574 +; run before the splitter to have the opportunity to eliminate the call
8575 +; without marking A5 as being clobbered and this in turn avoids saves
8576 +; and returns in a number of cases.
8578 +(define_insn_and_split "call_1"
8579 + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8580 + (match_operand:SI 1 "general_operand" "g,g"))]
8585 + [(call (mem:QI (match_dup 0))
8587 + (clobber (reg:SI LINK_REGNO))])]
8590 +(define_insn "call_slow"
8591 + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8592 + (match_operand:SI 1 "general_operand" "g,g"))
8593 + (clobber (reg:SI LINK_REGNO))]
8594 + "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
8597 + moveai\\ta5, #%%hi(%C0)\;calli\\ta5, %%lo(%C0)(a5)")
8599 +(define_insn "call_fast"
8600 + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8601 + (match_operand:SI 1 "general_operand" "g,g"))
8602 + (clobber (reg:SI LINK_REGNO))]
8603 + "(! TARGET_FDPIC && TARGET_FASTCALL)"
8608 +; We expand to a simple form that doesn't clobber the link register and
8609 +; then split to a form that does. This allows the RTL optimizers that
8610 +; run before the splitter to have the opportunity to eliminate the call
8611 +; without marking A5 as being clobbered and this in turn avoids saves
8612 +; and returns in a number of cases.
8614 +(define_insn_and_split "call_fdpic"
8615 + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8616 + (match_operand:SI 1 "general_operand" "g,g"))
8617 + (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))]
8622 + [(call (mem:QI (match_dup 0))
8624 + (use (match_dup 2))
8625 + (clobber (reg:SI LINK_REGNO))])]
8628 +(define_insn "call_fdpic_clobber"
8629 + [(call (mem:QI (match_operand:SI 0 "ubicom32_call_address_operand" "a,S"))
8630 + (match_operand:SI 1 "general_operand" "g,g"))
8631 + (use (match_operand:SI 2 "ubicom32_fdpic_operand" "Z,Z"))
8632 + (clobber (reg:SI LINK_REGNO))]
8635 + move.4\\ta5, 0(%0)\;move.4\\t%2, 4(%0)\;calli\\ta5, 0(a5)
8638 +; Call subroutine, returning value in operand 0
8639 +; (which must be a hard register).
8641 +(define_expand "call_value"
8642 + [(set (match_operand 0 "" "")
8643 + (call (match_operand:QI 1 "general_operand" "")
8644 + (match_operand:SI 2 "general_operand" "")))]
8649 + ubicom32_expand_call_value_fdpic (operands);
8653 + if (! ubicom32_call_address_operand (XEXP (operands[1], 0), VOIDmode))
8654 + XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
8657 +; We expand to a simple form that doesn't clobber the link register and
8658 +; then split to a form that does. This allows the RTL optimizers that
8659 +; run before the splitter to have the opportunity to eliminate the call
8660 +; without marking A5 as being clobbered and this in turn avoids saves
8661 +; and returns in a number of cases.
8663 +(define_insn_and_split "call_value_1"
8664 + [(set (match_operand 0 "register_operand" "=r,r")
8665 + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8666 + (match_operand:SI 2 "general_operand" "g,g")))]
8671 + [(set (match_dup 0)
8672 + (call (mem:QI (match_dup 1))
8674 + (clobber (reg:SI LINK_REGNO))])]
8677 +(define_insn "call_value_slow"
8678 + [(set (match_operand 0 "register_operand" "=r,r")
8679 + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8680 + (match_operand:SI 2 "general_operand" "g,g")))
8681 + (clobber (reg:SI LINK_REGNO))]
8682 + "(! TARGET_FDPIC && ! TARGET_FASTCALL)"
8685 + moveai\\ta5, #%%hi(%C1)\;calli\\ta5, %%lo(%C1)(a5)")
8687 +(define_insn "call_value_fast"
8688 + [(set (match_operand 0 "register_operand" "=r,r")
8689 + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8690 + (match_operand:SI 2 "general_operand" "g,g")))
8691 + (clobber (reg:SI LINK_REGNO))]
8692 + "(! TARGET_FDPIC && TARGET_FASTCALL)"
8697 +; We expand to a simple form that doesn't clobber the link register and
8698 +; then split to a form that does. This allows the RTL optimizers that
8699 +; run before the splitter to have the opportunity to eliminate the call
8700 +; without marking A5 as being clobbered and this in turn avoids saves
8701 +; and returns in a number of cases.
8703 +(define_insn_and_split "call_value_fdpic"
8704 + [(set (match_operand 0 "register_operand" "=r,r")
8705 + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8706 + (match_operand:SI 2 "general_operand" "g,g")))
8707 + (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))]
8712 + [(set (match_dup 0)
8713 + (call (mem:QI (match_dup 1))
8715 + (use (match_dup 3))
8716 + (clobber (reg:SI LINK_REGNO))])]
8719 +(define_insn "call_value_fdpic_clobber"
8720 + [(set (match_operand 0 "register_operand" "=r,r")
8721 + (call (mem:QI (match_operand:SI 1 "ubicom32_call_address_operand" "a,S"))
8722 + (match_operand:SI 2 "general_operand" "g,g")))
8723 + (use (match_operand:SI 3 "ubicom32_fdpic_operand" "Z,Z"))
8724 + (clobber (reg:SI LINK_REGNO))]
8727 + move.4\\ta5, 0(%1)\;move.4\\t%3, 4(%1)\;calli\\ta5, 0(a5)
8730 +(define_expand "untyped_call"
8731 + [(parallel [(call (match_operand 0 "" "")
8733 + (match_operand 1 "" "")
8734 + (match_operand 2 "" "")])]
8739 + emit_call_insn (gen_call (operands[0], const0_rtx));
8741 + for (i = 0; i < XVECLEN (operands[2], 0); i++)
8743 + rtx set = XVECEXP (operands[2], 0, i);
8744 + emit_move_insn (SET_DEST (set), SET_SRC (set));
8749 +(define_insn "lsl1_1"
8750 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8751 + (ashift:SI (subreg:SI
8752 + (match_operand:QI 1 "memory_operand" "m")
8754 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8755 + (clobber (reg:CC CC_REGNO))]
8757 + "lsl.1\\t%0, %1, %2")
8759 +; The combiner gets rather creative about left shifts of sub-word memory
8760 +; operands because it's uncertain about whether the memory is sign or
8761 +; zero extended. It only wants zero-extended behaviour and so throws
8762 +; in an extra and operation.
8764 +(define_insn "lsl1_2"
8765 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8767 + (ashift:SI (subreg:SI
8768 + (match_operand:QI 1 "memory_operand" "m")
8770 + (match_operand:SI 2 "const_int_operand" "M"))
8771 + (match_operand:SI 3 "const_int_operand" "n")))
8772 + (clobber (reg:CC CC_REGNO))]
8774 + && INTVAL (operands[3]) == (0xff << INTVAL (operands[2])))"
8775 + "lsl.1\\t%0, %1, %2")
8777 +(define_insn "lsl2_1"
8778 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8779 + (ashift:SI (subreg:SI
8780 + (match_operand:HI 1 "memory_operand" "m")
8782 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8783 + (clobber (reg:CC CC_REGNO))]
8785 + "lsl.2\\t%0, %1, %2")
8787 +; The combiner gets rather creative about left shifts of sub-word memory
8788 +; operands because it's uncertain about whether the memory is sign or
8789 +; zero extended. It only wants zero-extended behaviour and so throws
8790 +; in an extra and operation.
8792 +(define_insn "lsl2_2"
8793 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8795 + (ashift:SI (subreg:SI
8796 + (match_operand:HI 1 "memory_operand" "m")
8798 + (match_operand:SI 2 "const_int_operand" "M"))
8799 + (match_operand:SI 3 "const_int_operand" "n")))
8800 + (clobber (reg:CC CC_REGNO))]
8802 + && INTVAL (operands[3]) == (0xffff << INTVAL (operands[2])))"
8803 + "lsl.2\\t%0, %1, %2")
8805 +(define_insn "ashlsi3"
8806 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8807 + (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8808 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8809 + (clobber (reg:CC CC_REGNO))]
8811 + "lsl.4\\t%0, %1, %2")
8813 +(define_insn "lshlsi3_ccwz"
8814 + [(set (reg CC_REGNO)
8816 + (ashift:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8817 + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8819 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8820 + (ashift:SI (match_dup 1)
8822 + "ubicom32_match_cc_mode(insn, CCWZmode)"
8823 + "lsl.4\\t%0, %1, %2")
8825 +(define_insn "lshlsi3_ccwz_null"
8826 + [(set (reg CC_REGNO)
8828 + (ashift:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
8829 + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8831 + (clobber (match_scratch:SI 2 "=d"))]
8832 + "ubicom32_match_cc_mode(insn, CCWZmode)"
8833 + "lsl.4\\t%2, %0, %1")
8835 +; The combiner finds this canonical form for what is in essence a right
8838 +(define_insn "asr1_2"
8839 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8840 + (sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
8841 + (match_operand:SI 2 "const_int_operand" "M")
8842 + (match_operand:SI 3 "const_int_operand" "M")))
8843 + (clobber (reg:CC CC_REGNO))]
8845 + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
8846 + "asr.1\\t%0, %1, %3")
8848 +; The combiner finds this canonical form for what is in essence a right
8851 +(define_insn "asr2_2"
8852 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8853 + (sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
8854 + (match_operand:SI 2 "const_int_operand" "M")
8855 + (match_operand:SI 3 "const_int_operand" "M")))
8856 + (clobber (reg:CC CC_REGNO))]
8858 + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
8859 + "asr.2\\t%0, %1, %3")
8861 +(define_insn "ashrsi3"
8862 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8863 + (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
8864 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8865 + (clobber (reg:CC CC_REGNO))]
8867 + "asr.4\\t%0, %1, %2")
8869 +(define_insn "ashrsi3_ccwzn"
8870 + [(set (reg CC_REGNO)
8872 + (ashiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmJ")
8873 + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8875 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8876 + (ashiftrt:SI (match_dup 1)
8878 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8879 + "asr.4\\t%0, %1, %2")
8881 +(define_insn "ashrsi3_ccwzn_null"
8882 + [(set (reg CC_REGNO)
8884 + (ashiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmJ")
8885 + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8887 + (clobber (match_scratch:SI 2 "=d"))]
8888 + "ubicom32_match_cc_mode(insn, CCWZNmode)"
8889 + "asr.4\\t%2, %0, %1")
8891 +(define_insn "lsr1_1"
8892 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8893 + (lshiftrt:SI (subreg:SI
8894 + (match_operand:QI 1 "memory_operand" "m")
8896 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8897 + (clobber (reg:CC CC_REGNO))]
8899 + "lsr.1\\t%0, %1, %2")
8901 +; The combiner finds this canonical form for what is in essence a right
8904 +(define_insn "lsr1_2"
8905 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8906 + (zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
8907 + (match_operand:SI 2 "const_int_operand" "M")
8908 + (match_operand:SI 3 "const_int_operand" "M")))
8909 + (clobber (reg:CC CC_REGNO))]
8911 + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 8))"
8912 + "lsr.1\\t%0, %1, %3")
8914 +(define_insn "lsr2_1"
8915 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8916 + (lshiftrt:SI (subreg:SI
8917 + (match_operand:HI 1 "memory_operand" "m")
8919 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8920 + (clobber (reg:CC CC_REGNO))]
8922 + "lsr.2\\t%0, %1, %2")
8924 +; The combiner finds this canonical form for what is in essence a right
8927 +(define_insn "lsr2_2"
8928 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8929 + (zero_extract:SI (match_operand:HI 1 "memory_operand" "m")
8930 + (match_operand:SI 2 "const_int_operand" "M")
8931 + (match_operand:SI 3 "const_int_operand" "M")))
8932 + (clobber (reg:CC CC_REGNO))]
8934 + && (INTVAL (operands[2]) + INTVAL (operands[3]) == 16))"
8935 + "lsr.2\\t%0, %1, %3")
8937 +(define_insn "lshrsi3"
8938 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8939 + (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8940 + (match_operand:SI 2 "ubicom32_arith_operand" "dM")))
8941 + (clobber (reg:CC CC_REGNO))]
8943 + "lsr.4\\t%0, %1, %2")
8945 +(define_insn "lshrsi3_ccwz"
8946 + [(set (reg CC_REGNO)
8948 + (lshiftrt:SI (match_operand:SI 1 "ubicom32_arith_operand" "rmI")
8949 + (match_operand:SI 2 "ubicom32_arith_operand" "dM"))
8951 + (set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
8952 + (lshiftrt:SI (match_dup 1)
8954 + "ubicom32_match_cc_mode(insn, CCWZmode)"
8955 + "lsr.4\\t%0, %1, %2")
8957 +(define_insn "lshrsi3_ccwz_null"
8958 + [(set (reg CC_REGNO)
8960 + (lshiftrt:SI (match_operand:SI 0 "ubicom32_arith_operand" "rmI")
8961 + (match_operand:SI 1 "ubicom32_arith_operand" "dM"))
8963 + (clobber (match_scratch:SI 2 "=d"))]
8964 + "ubicom32_match_cc_mode(insn, CCWZmode)"
8965 + "lsr.4\\t%2, %0, %1")
8967 +(define_expand "prologue"
8971 + ubicom32_expand_prologue ();
8975 +(define_expand "epilogue"
8979 + ubicom32_expand_epilogue ();
8983 +(define_expand "return"
8987 + ubicom32_expand_epilogue ();
8991 +(define_expand "_eh_return"
8992 + [(use (match_operand:SI 0 "register_operand" "r"))
8993 + (use (match_operand:SI 1 "register_operand" "r"))]
8996 + ubicom32_expand_eh_return (operands);
9000 +; XXX - it looks almost certain that we could make return_internal use a Dn
9001 +; register too. In that instance we'd have to use a ret instruction
9002 +; rather than a calli but it might save cycles.
9004 +(define_insn "return_internal"
9007 + (use (match_operand:SI 0 "ubicom32_mem_or_address_register_operand" "rm"))]
9011 + if (REG_P (operands[0]) && REGNO (operands[0]) == LINK_REGNO
9012 + && ubicom32_can_use_calli_to_ret)
9013 + return \"calli\\t%0, 0(%0)\";
9015 + return \"ret\\t%0\";
9018 +(define_insn "return_from_post_modify_sp"
9022 + (use (mem:SI (post_modify:SI
9024 + (plus:SI (reg:SI SP_REGNO)
9025 + (match_operand:SI 0 "const_int_operand" "n")))))])]
9026 + "INTVAL (operands[0]) >= 4 && INTVAL (operands[0]) <= 7 * 4"
9027 + "ret\\t(sp)%E0++")
9029 +;(define_insn "eh_return_internal"
9032 +; (use (reg:SI 34))]
9036 +; No operation, needed in case the user uses -g but not -O.
9037 +(define_expand "nop"
9042 +(define_insn "nop_internal"
9047 +; The combiner will generate this pattern given shift and add operations.
9048 +; The canonical form that the combiner wants to use appears to be multiplies
9049 +; instead of shifts even if the compiled sources use shifts.
9051 +(define_insn "shmrg1_add"
9052 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9054 + (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9057 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
9058 + (clobber (reg:CC CC_REGNO))]
9060 + "shmrg.1\\t%0, %2, %1")
9062 +; The combiner will generate this pattern given shift and or operations.
9064 +(define_insn "shmrg1_ior"
9065 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9067 + (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9070 + (match_operand:QI 2 "ubicom32_arith_operand" "rmI"))))
9071 + (clobber (reg:CC CC_REGNO))]
9073 + "shmrg.1\\t%0, %2, %1")
9075 +; The combiner will generate this pattern given shift and add operations.
9076 +; The canonical form that the combiner wants to use appears to be multiplies
9077 +; instead of shifts even if the compiled sources use shifts.
9079 +(define_insn "shmrg2_add"
9080 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9082 + (mult:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9083 + (const_int 65536))
9085 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
9086 + (clobber (reg:CC CC_REGNO))]
9088 + "shmrg.2\\t%0, %2, %1")
9090 +; The combiner will generate this pattern given shift and or operations.
9092 +(define_insn "shmrg2_ior"
9093 + [(set (match_operand:SI 0 "ubicom32_data_register_operand" "=d")
9095 + (ashift:SI (match_operand:SI 1 "ubicom32_data_register_operand" "d")
9098 + (match_operand:HI 2 "ubicom32_arith_operand" "rmI"))))
9099 + (clobber (reg:CC CC_REGNO))]
9101 + "shmrg.2\\t%0, %2, %1")
9103 +; Match the case where we load a word from the stack but then discard the
9104 +; upper 16 bits. We turn this into a zero-extended load of that useful
9105 +; 16 bits direct from the stack where possible.
9108 +; XXX - do these peephole2 ops actually work after the CCmode conversion?
9110 + [(set (match_operand:SI 0 "register_operand" "")
9111 + (mem:SI (plus:SI (reg:SI SP_REGNO)
9112 + (match_operand:SI 1 "const_int_operand" ""))))
9113 + (set (match_operand:SI 2 "nonimmediate_operand" "")
9114 + (zero_extend:SI (match_operand:HI 3 "register_operand" "")))]
9115 + "(INTVAL (operands[1]) <= 252
9116 + && REGNO (operands[3]) == REGNO (operands[0])
9117 + && ((peep2_reg_dead_p (2, operands[0])
9118 + && ! reg_mentioned_p (operands[0], operands[2]))
9119 + || rtx_equal_p (operands[0], operands[2])))"
9120 + [(set (match_dup 2)
9121 + (zero_extend:SI (mem:HI (plus:SI (reg:SI SP_REGNO)
9122 + (match_dup 4)))))]
9124 + operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
9127 +; Match the case where we load a word from the stack but then discard the
9128 +; upper 16 bits. We turn this into a 16-bit load of that useful
9129 +; 16 bits direct from the stack where possible.
9132 + [(set (match_operand:SI 0 "register_operand" "")
9133 + (mem:SI (plus:SI (reg:SI SP_REGNO)
9134 + (match_operand:SI 1 "const_int_operand" ""))))
9135 + (set (match_operand:HI 2 "nonimmediate_operand" "")
9136 + (match_operand:HI 3 "register_operand" ""))]
9137 + "(INTVAL (operands[1]) <= 252
9138 + && REGNO (operands[3]) == REGNO (operands[0])
9139 + && ((peep2_reg_dead_p (2, operands[0])
9140 + && ! reg_mentioned_p (operands[0], operands[2]))
9141 + || rtx_equal_p (operands[0], operands[2])))"
9142 + [(set (match_dup 2)
9143 + (mem:HI (plus:SI (reg:SI SP_REGNO)
9146 + operands[4] = GEN_INT (INTVAL (operands[1]) + 2);
9149 +; Match the case where we load a word from the stack but then discard the
9150 +; upper 24 bits. We turn this into a zero-extended load of that useful
9151 +; 8 bits direct from the stack where possible.
9154 + [(set (match_operand:SI 0 "register_operand" "")
9155 + (mem:SI (plus:SI (reg:SI SP_REGNO)
9156 + (match_operand:SI 1 "const_int_operand" ""))))
9157 + (set (match_operand:SI 2 "nonimmediate_operand" "")
9158 + (zero_extend:SI (match_operand:QI 3 "register_operand" "")))]
9159 + "(INTVAL (operands[1]) <= 124
9160 + && REGNO (operands[3]) == REGNO (operands[0])
9161 + && ((peep2_reg_dead_p (2, operands[0])
9162 + && ! reg_mentioned_p (operands[0], operands[2]))
9163 + || rtx_equal_p (operands[0], operands[2])))"
9164 + [(set (match_dup 2)
9165 + (zero_extend:SI (mem:QI (plus:SI (reg:SI SP_REGNO)
9166 + (match_dup 4)))))]
9168 + operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
9171 +; Match the case where we load a word from the stack but then discard the
9172 +; upper 24 bits. We turn this into an 8-bit load of that useful
9173 +; 8 bits direct from the stack where possible.
9176 + [(set (match_operand:SI 0 "register_operand" "")
9177 + (mem:SI (plus:SI (reg:SI SP_REGNO)
9178 + (match_operand:SI 1 "const_int_operand" ""))))
9179 + (set (match_operand:QI 2 "nonimmediate_operand" "")
9180 + (match_operand:QI 3 "register_operand" ""))]
9181 + "(INTVAL (operands[1]) <= 124
9182 + && REGNO (operands[3]) == REGNO (operands[0])
9183 + && ((peep2_reg_dead_p (2, operands[0])
9184 + && ! reg_mentioned_p (operands[0], operands[2]))
9185 + || rtx_equal_p (operands[0], operands[2])))"
9186 + [(set (match_dup 2)
9187 + (mem:QI (plus:SI (reg:SI SP_REGNO)
9190 + operands[4] = GEN_INT (INTVAL (operands[1]) + 3);
9194 +++ b/gcc/config/ubicom32/ubicom32.opt
9197 +Target RejectNegative Report Undocumented Mask(DEBUG_ADDRESS)
9201 +Target RejectNegative Report Undocumented Mask(DEBUG_CONTEXT)
9205 +Target Report Var(ubicom32_arch_name) Init("ubicom32v4") Joined
9206 +Specify the name of the target architecture
9209 +Target Report Mask(FDPIC)
9210 +Enable Function Descriptor PIC mode
9213 +Target Report Mask(INLINE_PLT)
9214 +Enable inlining of PLT in function calls
9217 +Target Report Mask(FASTCALL)
9218 +Enable default fast (call) calling sequence for smaller applications
9221 +Target Report Mask(IPOS_ABI)
9222 +Enable the ipOS ABI in which D10-D13 are caller-clobbered
9224 +++ b/gcc/config/ubicom32/uclinux.h
9226 +/* Definitions of target machine for Ubicom32-uclinux
9228 + Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
9229 + 2009 Free Software Foundation, Inc.
9230 + Contributed by Ubicom, Inc.
9232 + This file is part of GCC.
9234 + GCC is free software; you can redistribute it and/or modify it
9235 + under the terms of the GNU General Public License as published
9236 + by the Free Software Foundation; either version 3, or (at your
9237 + option) any later version.
9239 + GCC is distributed in the hope that it will be useful, but WITHOUT
9240 + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9241 + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
9242 + License for more details.
9244 + You should have received a copy of the GNU General Public License
9245 + along with GCC; see the file COPYING3. If not see
9246 + <http://www.gnu.org/licenses/>. */
9248 +/* Don't assume anything about the header files. */
9249 +#define NO_IMPLICIT_EXTERN_C
9253 + "%{pthread:-lpthread} " \
9254 + "%{!shared:%{!symbolic: -lc}} "
9257 +#undef LINK_GCC_C_SEQUENCE_SPEC
9258 +#define LINK_GCC_C_SEQUENCE_SPEC \
9259 + "%{!shared:--start-group} %G %L %{!shared:--end-group}%{shared:%G} "
9261 +#undef STARTFILE_SPEC
9262 +#define STARTFILE_SPEC \
9263 + "%{!shared: crt1%O%s}" \
9264 + " crti%O%s crtbegin%O%s"
9266 +#undef ENDFILE_SPEC
9267 +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
9269 +/* This macro applies on top of OBJECT_FORMAT_ELF and indicates that
9270 + we want to support both flat and ELF output. */
9271 +#define OBJECT_FORMAT_FLAT
9273 +#undef DRIVER_SELF_SPECS
9274 +#define DRIVER_SELF_SPECS \
9275 + "%{!mno-fastcall:-mfastcall}"
9277 +/* taken from linux.h */
9278 +/* The GNU C++ standard library requires that these macros be defined. */
9279 +#undef CPLUSPLUS_CPP_SPEC
9280 +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
9282 +#define TARGET_OS_CPP_BUILTINS() \
9284 + builtin_define_std ("__UBICOM32__"); \
9285 + builtin_define_std ("__ubicom32__"); \
9286 + builtin_define ("__gnu_linux__"); \
9287 + builtin_define_std ("linux"); \
9288 + builtin_define_std ("unix"); \
9289 + builtin_assert ("system=linux"); \
9290 + builtin_assert ("system=unix"); \
9291 + builtin_assert ("system=posix"); \
9294 +++ b/gcc/config/ubicom32/xm-ubicom32.h
9296 +/* Configuration for Ubicom's Ubicom32 architecture.
9297 + Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Free Software
9299 + Contributed by Ubicom Inc.
9301 +This file is part of GNU CC.
9303 +GNU CC is free software; you can redistribute it and/or modify
9304 +it under the terms of the GNU General Public License as published by
9305 +the Free Software Foundation; either version 2, or (at your option)
9308 +GNU CC is distributed in the hope that it will be useful,
9309 +but WITHOUT ANY WARRANTY; without even the implied warranty of
9310 +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9311 +GNU General Public License for more details.
9313 +You should have received a copy of the GNU General Public License
9314 +along with GNU CC; see the file COPYING. If not, write to
9315 +the Free Software Foundation, 59 Temple Place - Suite 330,
9316 +Boston, MA 02111-1307, USA. */
9318 +/* #defines that need visibility everywhere. */
9322 +/* This describes the machine the compiler is hosted on. */
9323 +#define HOST_BITS_PER_CHAR 8
9324 +#define HOST_BITS_PER_SHORT 16
9325 +#define HOST_BITS_PER_INT 32
9326 +#define HOST_BITS_PER_LONG 32
9327 +#define HOST_BITS_PER_LONGLONG 64
9329 +/* Arguments to use with `exit'. */
9330 +#define SUCCESS_EXIT_CODE 0
9331 +#define FATAL_EXIT_CODE 33
9332 --- a/gcc/config.gcc
9333 +++ b/gcc/config.gcc
9334 @@ -2314,6 +2314,34 @@ spu-*-elf*)
9335 c_target_objs="${c_target_objs} spu-c.o"
9336 cxx_target_objs="${cxx_target_objs} spu-c.o"
9339 + xm_file=ubicom32/xm-ubicom32.h
9340 + tm_file="${tm_file} ubicom32/elf.h" # still need dbxelf.h elfos.h
9341 + tmake_file=ubicom32/t-ubicom32
9343 +ubicom32-*-uclinux*)
9344 + xm_file=ubicom32/xm-ubicom32.h
9345 + tm_file="${tm_file} ubicom32/elf.h ubicom32/uclinux.h" # still need dbxelf.h elfos.h linux.h
9346 + tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
9347 + extra_options="${extra_options} linux.opt"
9348 + tmake_file=ubicom32/t-ubicom32-uclinux
9351 +ubicom32-*-linux-uclibc)
9352 + xm_file=ubicom32/xm-ubicom32.h
9353 + tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
9354 + tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
9355 + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
9359 + xm_file=ubicom32/xm-ubicom32.h
9360 + tm_file="${tm_file} ubicom32/elf.h linux.h ubicom32/linux.h" # still need dbxelf.h elfos.h
9361 + tmake_file="t-slibgcc-elf-ver ubicom32/t-ubicom32-linux"
9362 + tm_defines="${tm_defines} UCLIBC_DEFAULT=1"
9363 + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
9367 target_cpu_default="TARGET_CPU_v850e1"
9368 tm_file="dbxelf.h elfos.h svr4.h v850/v850.h"
9369 --- a/libgcc/config.host
9370 +++ b/libgcc/config.host
9371 @@ -551,6 +551,15 @@ sparc64-*-netbsd*)
9377 +ubicom32*-*-uclinux*)
9379 +ubicom32*-*-linux*)
9380 + # No need to build crtbeginT.o on uClibc systems. Should probably
9381 + # be moved to the OS specific section above.
9382 + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"