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