067456da5b5be46243af44c71111fbd580c1fd76
[openwrt.git] / toolchain / gcc / patches / 4.2.3 / 900-avr32_support.patch
1 diff -Nrup gcc-4.2.1/configure.in gcc-4.2.1.atmel.1.3.2/configure.in
2 --- gcc-4.2.1/configure.in 2007-05-30 15:48:07.000000000 +0200
3 +++ gcc-4.2.1.atmel.1.3.2/configure.in 2007-09-28 10:34:36.000000000 +0200
4 @@ -503,6 +503,9 @@ case "${target}" in
5 arm-*-riscix*)
6 noconfigdirs="$noconfigdirs ld target-libgloss ${libgcj}"
7 ;;
8 + avr32-*-*)
9 + noconfigdirs="$noconfigdirs target-libiberty target-libmudflap target-libffi ${libgcj}"
10 + ;;
11 avr-*-*)
12 noconfigdirs="$noconfigdirs target-libiberty target-libstdc++-v3 ${libgcj}"
13 ;;
14 diff -Nrup gcc-4.2.1/gcc/builtins.c gcc-4.2.1.atmel.1.3.2/gcc/builtins.c
15 --- gcc-4.2.1/gcc/builtins.c 2007-03-29 18:19:32.000000000 +0200
16 +++ gcc-4.2.1.atmel.1.3.2/gcc/builtins.c 2007-09-28 10:33:08.000000000 +0200
17 @@ -9223,7 +9223,7 @@ validate_arglist (tree arglist, ...)
18
19 do
20 {
21 - code = va_arg (ap, enum tree_code);
22 + code = va_arg (ap, int);
23 switch (code)
24 {
25 case 0:
26 diff -Nrup gcc-4.2.1/gcc/calls.c gcc-4.2.1.atmel.1.3.2/gcc/calls.c
27 --- gcc-4.2.1/gcc/calls.c 2007-06-20 08:44:26.000000000 +0200
28 +++ gcc-4.2.1.atmel.1.3.2/gcc/calls.c 2007-09-28 10:33:09.000000000 +0200
29 @@ -3448,7 +3448,7 @@ emit_library_call_value_1 (int retval, r
30 for (; count < nargs; count++)
31 {
32 rtx val = va_arg (p, rtx);
33 - enum machine_mode mode = va_arg (p, enum machine_mode);
34 + enum machine_mode mode = va_arg (p, int);
35
36 /* We cannot convert the arg value to the mode the library wants here;
37 must do it earlier where we know the signedness of the arg. */
38 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32.c gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.c
39 --- gcc-4.2.1/gcc/config/avr32/avr32.c 1970-01-01 01:00:00.000000000 +0100
40 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.c 2007-09-28 10:33:00.000000000 +0200
41 @@ -0,0 +1,7060 @@
42 +/*
43 + Target hooks and helper functions for AVR32.
44 + Copyright 2003-2006 Atmel Corporation.
45 +
46 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
47 + Initial porting by Anders �dland.
48 +
49 + This file is part of GCC.
50 +
51 + This program is free software; you can redistribute it and/or modify
52 + it under the terms of the GNU General Public License as published by
53 + the Free Software Foundation; either version 2 of the License, or
54 + (at your option) any later version.
55 +
56 + This program is distributed in the hope that it will be useful,
57 + but WITHOUT ANY WARRANTY; without even the implied warranty of
58 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
59 + GNU General Public License for more details.
60 +
61 + You should have received a copy of the GNU General Public License
62 + along with this program; if not, write to the Free Software
63 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
64 +
65 +#include "config.h"
66 +#include "system.h"
67 +#include "coretypes.h"
68 +#include "tm.h"
69 +#include "rtl.h"
70 +#include "tree.h"
71 +#include "obstack.h"
72 +#include "regs.h"
73 +#include "hard-reg-set.h"
74 +#include "real.h"
75 +#include "insn-config.h"
76 +#include "conditions.h"
77 +#include "output.h"
78 +#include "insn-attr.h"
79 +#include "flags.h"
80 +#include "reload.h"
81 +#include "function.h"
82 +#include "expr.h"
83 +#include "optabs.h"
84 +#include "toplev.h"
85 +#include "recog.h"
86 +#include "ggc.h"
87 +#include "except.h"
88 +#include "c-pragma.h"
89 +#include "integrate.h"
90 +#include "tm_p.h"
91 +#include "langhooks.h"
92 +
93 +#include "target.h"
94 +#include "target-def.h"
95 +
96 +#include <ctype.h>
97 +
98 +/* Forward definitions of types. */
99 +typedef struct minipool_node Mnode;
100 +typedef struct minipool_fixup Mfix;
101 +
102 +/* Obstack for minipool constant handling. */
103 +static struct obstack minipool_obstack;
104 +static char *minipool_startobj;
105 +static rtx minipool_vector_label;
106 +
107 +/* True if we are currently building a constant table. */
108 +int making_const_table;
109 +
110 +/* Some forward function declarations */
111 +static unsigned long avr32_isr_value (tree);
112 +static unsigned long avr32_compute_func_type (void);
113 +static tree avr32_handle_isr_attribute (tree *, tree, tree, int, bool *);
114 +static tree avr32_handle_acall_attribute (tree *, tree, tree, int, bool *);
115 +static tree avr32_handle_fndecl_attribute (tree * node, tree name, tree args,
116 + int flags, bool * no_add_attrs);
117 +static void avr32_reorg (void);
118 +bool avr32_return_in_msb (tree type);
119 +bool avr32_vector_mode_supported (enum machine_mode mode);
120 +static void avr32_init_libfuncs (void);
121 +
122 +
123 +static void
124 +avr32_add_gc_roots (void)
125 + {
126 + gcc_obstack_init (&minipool_obstack);
127 + minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
128 + }
129 +
130 +
131 +/* List of all known AVR32 parts */
132 +static const struct part_type_s avr32_part_types[] = {
133 + /* name, part_type, architecture type, macro */
134 + {"none", PART_TYPE_AVR32_NONE, ARCH_TYPE_AVR32_AP, "__AVR32__"},
135 + {"ap7000", PART_TYPE_AVR32_AP7000, ARCH_TYPE_AVR32_AP, "__AVR32_AP7000__"},
136 + {"ap7010", PART_TYPE_AVR32_AP7010, ARCH_TYPE_AVR32_AP, "__AVR32_AP7010__"},
137 + {"ap7020", PART_TYPE_AVR32_AP7020, ARCH_TYPE_AVR32_AP, "__AVR32_AP7020__"},
138 + {"uc3a0256", PART_TYPE_AVR32_UC3A0256, ARCH_TYPE_AVR32_UC,
139 + "__AVR32_UC3A0256__"},
140 + {"uc3a0512", PART_TYPE_AVR32_UC3A0512, ARCH_TYPE_AVR32_UC,
141 + "__AVR32_UC3A0512__"},
142 + {"uc3a1128", PART_TYPE_AVR32_UC3A1128, ARCH_TYPE_AVR32_UC,
143 + "__AVR32_UC3A1128__"},
144 + {"uc3a1256", PART_TYPE_AVR32_UC3A1256, ARCH_TYPE_AVR32_UC,
145 + "__AVR32_UC3A1256__"},
146 + {"uc3a1512", PART_TYPE_AVR32_UC3A1512, ARCH_TYPE_AVR32_UC,
147 + "__AVR32_UC3A1512__"},
148 + {"uc3b064", PART_TYPE_AVR32_UC3B064, ARCH_TYPE_AVR32_UC,
149 + "__AVR32_UC3B064__"},
150 + {"uc3b0128", PART_TYPE_AVR32_UC3B0128, ARCH_TYPE_AVR32_UC,
151 + "__AVR32_UC3B0128__"},
152 + {"uc3b0256", PART_TYPE_AVR32_UC3B0256, ARCH_TYPE_AVR32_UC,
153 + "__AVR32_UC3B0256__"},
154 + {"uc3b164", PART_TYPE_AVR32_UC3B164, ARCH_TYPE_AVR32_UC,
155 + "__AVR32_UC3B164__"},
156 + {"uc3b1128", PART_TYPE_AVR32_UC3B1128, ARCH_TYPE_AVR32_UC,
157 + "__AVR32_UC3B1128__"},
158 + {"uc3b1256", PART_TYPE_AVR32_UC3B1256, ARCH_TYPE_AVR32_UC,
159 + "__AVR32_UC3B1256__"},
160 + {NULL, 0, 0, NULL}
161 +};
162 +
163 +/* List of all known AVR32 architectures */
164 +static const struct arch_type_s avr32_arch_types[] = {
165 + /* name, architecture type, microarchitecture type, feature flags, macro */
166 + {"ap", ARCH_TYPE_AVR32_AP, UARCH_TYPE_AVR32B,
167 + (FLAG_AVR32_HAS_DSP
168 + | FLAG_AVR32_HAS_SIMD
169 + | FLAG_AVR32_HAS_UNALIGNED_WORD
170 + | FLAG_AVR32_HAS_CACHES
171 + | FLAG_AVR32_HAS_BRANCH_PRED
172 + | FLAG_AVR32_HAS_RETURN_STACK),
173 + "__AVR32_AP__"},
174 + {"uc", ARCH_TYPE_AVR32_UC, UARCH_TYPE_AVR32A,
175 + (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW),
176 + "__AVR32_UC__"},
177 + {NULL, 0, 0, 0, NULL}
178 +};
179 +
180 +/* Default arch name */
181 +const char *avr32_arch_name = "ap";
182 +const char *avr32_part_name = "none";
183 +
184 +const struct part_type_s *avr32_part;
185 +const struct arch_type_s *avr32_arch;
186 +
187 +/* Set default target_flags. */
188 +#undef TARGET_DEFAULT_TARGET_FLAGS
189 +#define TARGET_DEFAULT_TARGET_FLAGS \
190 + (MASK_HAS_ASM_ADDR_PSEUDOS | MASK_MD_REORG_OPTIMIZATION)
191 +
192 +void
193 +avr32_optimization_options (int level,
194 + int size){
195 + if (AVR32_ALWAYS_PIC)
196 + flag_pic = 1;
197 +
198 + /* Enable section anchors if optimization is enabled. */
199 + if (level > 0 || size)
200 + flag_section_anchors = 1;
201 +}
202 +
203 +/* Override command line options */
204 +void
205 +avr32_override_options (void)
206 + {
207 + const struct part_type_s *part;
208 + const struct arch_type_s *arch;
209 +
210 + /* Check if part type is set. */
211 + for (part = avr32_part_types; part->name; part++)
212 + if (strcmp (part->name, avr32_part_name) == 0)
213 + break;
214 +
215 + avr32_part = part;
216 +
217 + if (!part->name)
218 + {
219 + fprintf (stderr, "Unknown part `%s' specified\nKnown part names:\n",
220 + avr32_part_name);
221 + for (part = avr32_part_types; part->name; part++)
222 + fprintf (stderr, "\t%s\n", part->name);
223 + avr32_part = &avr32_part_types[PART_TYPE_AVR32_NONE];
224 + }
225 +
226 + avr32_arch = &avr32_arch_types[avr32_part->arch_type];
227 +
228 + /* If part was set to "none" then check if arch was set. */
229 + if (strcmp (avr32_part->name, "none") == 0)
230 + {
231 + /* Check if arch type is set. */
232 + for (arch = avr32_arch_types; arch->name; arch++)
233 + if (strcmp (arch->name, avr32_arch_name) == 0)
234 + break;
235 +
236 + avr32_arch = arch;
237 +
238 + if (!arch->name)
239 + {
240 + fprintf (stderr, "Unknown arch `%s' specified\nKnown arch names:\n",
241 + avr32_arch_name);
242 + for (arch = avr32_arch_types; arch->name; arch++)
243 + fprintf (stderr, "\t%s\n", arch->name);
244 + avr32_arch = &avr32_arch_types[ARCH_TYPE_AVR32_AP];
245 + }
246 + }
247 +
248 + /* If optimization level is two or greater, then align start of loops to a
249 + word boundary since this will allow folding the first insn of the loop.
250 + Do this only for targets supporting branch prediction. */
251 + if (optimize >= 2 && TARGET_BRANCH_PRED)
252 + align_loops = 2;
253 +
254 +
255 + /* Enable section anchors if optimization is enabled. */
256 + if (optimize > 0 || optimize_size)
257 + flag_section_anchors = 1;
258 +
259 + /* Enable fast-float library if unsafe math optimizations
260 + are used. */
261 + if (flag_unsafe_math_optimizations)
262 + target_flags |= MASK_FAST_FLOAT;
263 +
264 + /* Check if we should set avr32_imm_in_const_pool
265 + based on if caches are present or not. */
266 + if ( avr32_imm_in_const_pool == -1 )
267 + {
268 + if ( TARGET_CACHES )
269 + avr32_imm_in_const_pool = 1;
270 + else
271 + avr32_imm_in_const_pool = 0;
272 + }
273 +
274 + avr32_add_gc_roots ();
275 + }
276 +
277 +
278 +/*
279 +If defined, a function that outputs the assembler code for entry to a
280 +function. The prologue is responsible for setting up the stack frame,
281 +initializing the frame pointer register, saving registers that must be
282 +saved, and allocating size additional bytes of storage for the
283 +local variables. size is an integer. file is a stdio
284 +stream to which the assembler code should be output.
285 +
286 +The label for the beginning of the function need not be output by this
287 +macro. That has already been done when the macro is run.
288 +
289 +To determine which registers to save, the macro can refer to the array
290 +regs_ever_live: element r is nonzero if hard register
291 +r is used anywhere within the function. This implies the function
292 +prologue should save register r, provided it is not one of the
293 +call-used registers. (TARGET_ASM_FUNCTION_EPILOGUE must likewise use
294 +regs_ever_live.)
295 +
296 +On machines that have ``register windows'', the function entry code does
297 +not save on the stack the registers that are in the windows, even if
298 +they are supposed to be preserved by function calls; instead it takes
299 +appropriate steps to ``push'' the register stack, if any non-call-used
300 +registers are used in the function.
301 +
302 +On machines where functions may or may not have frame-pointers, the
303 +function entry code must vary accordingly; it must set up the frame
304 +pointer if one is wanted, and not otherwise. To determine whether a
305 +frame pointer is in wanted, the macro can refer to the variable
306 +frame_pointer_needed. The variable's value will be 1 at run
307 +time in a function that needs a frame pointer. (see Elimination).
308 +
309 +The function entry code is responsible for allocating any stack space
310 +required for the function. This stack space consists of the regions
311 +listed below. In most cases, these regions are allocated in the
312 +order listed, with the last listed region closest to the top of the
313 +stack (the lowest address if STACK_GROWS_DOWNWARD is defined, and
314 +the highest address if it is not defined). You can use a different order
315 +for a machine if doing so is more convenient or required for
316 +compatibility reasons. Except in cases where required by standard
317 +or by a debugger, there is no reason why the stack layout used by GCC
318 +need agree with that used by other compilers for a machine.
319 + */
320 +
321 +#undef TARGET_ASM_FUNCTION_PROLOGUE
322 +#define TARGET_ASM_FUNCTION_PROLOGUE avr32_target_asm_function_prologue
323 +
324 +
325 +#undef TARGET_DEFAULT_SHORT_ENUMS
326 +#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false
327 +
328 +#undef TARGET_PROMOTE_FUNCTION_ARGS
329 +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
330 +
331 +#undef TARGET_PROMOTE_FUNCTION_RETURN
332 +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
333 +
334 +#undef TARGET_PROMOTE_PROTOTYPES
335 +#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
336 +
337 +#undef TARGET_MUST_PASS_IN_STACK
338 +#define TARGET_MUST_PASS_IN_STACK avr32_must_pass_in_stack
339 +
340 +#undef TARGET_PASS_BY_REFERENCE
341 +#define TARGET_PASS_BY_REFERENCE avr32_pass_by_reference
342 +
343 +#undef TARGET_STRICT_ARGUMENT_NAMING
344 +#define TARGET_STRICT_ARGUMENT_NAMING avr32_strict_argument_naming
345 +
346 +#undef TARGET_VECTOR_MODE_SUPPORTED_P
347 +#define TARGET_VECTOR_MODE_SUPPORTED_P avr32_vector_mode_supported
348 +
349 +#undef TARGET_RETURN_IN_MEMORY
350 +#define TARGET_RETURN_IN_MEMORY avr32_return_in_memory
351 +
352 +#undef TARGET_RETURN_IN_MSB
353 +#define TARGET_RETURN_IN_MSB avr32_return_in_msb
354 +
355 +#undef TARGET_ARG_PARTIAL_BYTES
356 +#define TARGET_ARG_PARTIAL_BYTES avr32_arg_partial_bytes
357 +
358 +#undef TARGET_STRIP_NAME_ENCODING
359 +#define TARGET_STRIP_NAME_ENCODING avr32_strip_name_encoding
360 +
361 +#define streq(string1, string2) (strcmp (string1, string2) == 0)
362 +
363 +#undef TARGET_NARROW_VOLATILE_BITFIELD
364 +#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
365 +
366 +#undef TARGET_ATTRIBUTE_TABLE
367 +#define TARGET_ATTRIBUTE_TABLE avr32_attribute_table
368 +
369 +#undef TARGET_COMP_TYPE_ATTRIBUTES
370 +#define TARGET_COMP_TYPE_ATTRIBUTES avr32_comp_type_attributes
371 +
372 +
373 +#undef TARGET_RTX_COSTS
374 +#define TARGET_RTX_COSTS avr32_rtx_costs
375 +
376 +#undef TARGET_CANNOT_FORCE_CONST_MEM
377 +#define TARGET_CANNOT_FORCE_CONST_MEM avr32_cannot_force_const_mem
378 +
379 +#undef TARGET_ASM_INTEGER
380 +#define TARGET_ASM_INTEGER avr32_assemble_integer
381 +
382 +#undef TARGET_FUNCTION_VALUE
383 +#define TARGET_FUNCTION_VALUE avr32_function_value
384 +
385 +#undef TARGET_MIN_ANCHOR_OFFSET
386 +#define TARGET_MIN_ANCHOR_OFFSET (0)
387 +
388 +#undef TARGET_MAX_ANCHOR_OFFSET
389 +#define TARGET_MAX_ANCHOR_OFFSET ((1 << 15) - 1)
390 +
391 +
392 +/*
393 + * Switches to the appropriate section for output of constant pool
394 + * entry x in mode. You can assume that x is some kind of constant in
395 + * RTL. The argument mode is redundant except in the case of a
396 + * const_int rtx. Select the section by calling readonly_data_ section
397 + * or one of the alternatives for other sections. align is the
398 + * constant alignment in bits.
399 + *
400 + * The default version of this function takes care of putting symbolic
401 + * constants in flag_ pic mode in data_section and everything else in
402 + * readonly_data_section.
403 + */
404 +//#undef TARGET_ASM_SELECT_RTX_SECTION
405 +//#define TARGET_ASM_SELECT_RTX_SECTION avr32_select_rtx_section
406 +
407 +
408 +/*
409 + * If non-null, this hook performs a target-specific pass over the
410 + * instruction stream. The compiler will run it at all optimization
411 + * levels, just before the point at which it normally does
412 + * delayed-branch scheduling.
413 + *
414 + * The exact purpose of the hook varies from target to target. Some
415 + * use it to do transformations that are necessary for correctness,
416 + * such as laying out in-function constant pools or avoiding hardware
417 + * hazards. Others use it as an opportunity to do some
418 + * machine-dependent optimizations.
419 + *
420 + * You need not implement the hook if it has nothing to do. The
421 + * default definition is null.
422 + */
423 +#undef TARGET_MACHINE_DEPENDENT_REORG
424 +#define TARGET_MACHINE_DEPENDENT_REORG avr32_reorg
425 +
426 +/* Target hook for assembling integer objects.
427 + Need to handle integer vectors */
428 +static bool
429 +avr32_assemble_integer (rtx x, unsigned int size, int aligned_p)
430 + {
431 + if (avr32_vector_mode_supported (GET_MODE (x)))
432 + {
433 + int i, units;
434 +
435 + if (GET_CODE (x) != CONST_VECTOR)
436 + abort ();
437 +
438 + units = CONST_VECTOR_NUNITS (x);
439 +
440 + switch (GET_MODE (x))
441 + {
442 + case V2HImode:
443 + size = 2;
444 + break;
445 + case V4QImode:
446 + size = 1;
447 + break;
448 + default:
449 + abort ();
450 + }
451 +
452 + for (i = 0; i < units; i++)
453 + {
454 + rtx elt;
455 +
456 + elt = CONST_VECTOR_ELT (x, i);
457 + assemble_integer (elt, size, i == 0 ? 32 : size * BITS_PER_UNIT, 1);
458 + }
459 +
460 + return true;
461 + }
462 +
463 + return default_assemble_integer (x, size, aligned_p);
464 + }
465 +
466 +/*
467 + * This target hook describes the relative costs of RTL expressions.
468 + *
469 + * The cost may depend on the precise form of the expression, which is
470 + * available for examination in x, and the rtx code of the expression
471 + * in which it is contained, found in outer_code. code is the
472 + * expression code--redundant, since it can be obtained with GET_CODE
473 + * (x).
474 + *
475 + * In implementing this hook, you can use the construct COSTS_N_INSNS
476 + * (n) to specify a cost equal to n fast instructions.
477 + *
478 + * On entry to the hook, *total contains a default estimate for the
479 + * cost of the expression. The hook should modify this value as
480 + * necessary. Traditionally, the default costs are COSTS_N_INSNS (5)
481 + * for multiplications, COSTS_N_INSNS (7) for division and modulus
482 + * operations, and COSTS_N_INSNS (1) for all other operations.
483 + *
484 + * When optimizing for code size, i.e. when optimize_size is non-zero,
485 + * this target hook should be used to estimate the relative size cost
486 + * of an expression, again relative to COSTS_N_INSNS.
487 + *
488 + * The hook returns true when all subexpressions of x have been
489 + * processed, and false when rtx_cost should recurse.
490 + */
491 +
492 +/* Worker routine for avr32_rtx_costs. */
493 +static inline int
494 +avr32_rtx_costs_1 (rtx x, enum rtx_code code ATTRIBUTE_UNUSED,
495 + enum rtx_code outer ATTRIBUTE_UNUSED)
496 + {
497 + enum machine_mode mode = GET_MODE (x);
498 +
499 + switch (GET_CODE (x))
500 + {
501 + case MEM:
502 + /* Using pre decrement / post increment memory operations on the
503 + avr32_uc architecture means that two writebacks must be performed
504 + and hence two cycles are needed. */
505 + if (!optimize_size
506 + && GET_MODE_SIZE (mode) <= 2 * UNITS_PER_WORD
507 + && avr32_arch->arch_type == ARCH_TYPE_AVR32_UC
508 + && (GET_CODE (XEXP (x, 0)) == PRE_DEC
509 + || GET_CODE (XEXP (x, 0)) == POST_INC))
510 + return COSTS_N_INSNS (5);
511 +
512 + /* Memory costs quite a lot for the first word, but subsequent words
513 + load at the equivalent of a single insn each. */
514 + if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
515 + return COSTS_N_INSNS (3 + (GET_MODE_SIZE (mode) / UNITS_PER_WORD));
516 +
517 + return COSTS_N_INSNS (4);
518 + case SYMBOL_REF:
519 + case CONST:
520 + /* These are valid for the pseudo insns: lda.w and call which operates
521 + on direct addresses. We assume that the cost of a lda.w is the same
522 + as the cost of a ld.w insn. */
523 + return (outer == SET) ? COSTS_N_INSNS (4) : COSTS_N_INSNS (1);
524 + case DIV:
525 + case MOD:
526 + case UDIV:
527 + case UMOD:
528 + return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16);
529 +
530 + case ROTATE:
531 + case ROTATERT:
532 + if (mode == TImode)
533 + return COSTS_N_INSNS (100);
534 +
535 + if (mode == DImode)
536 + return COSTS_N_INSNS (10);
537 + return COSTS_N_INSNS (4);
538 + case ASHIFT:
539 + case LSHIFTRT:
540 + case ASHIFTRT:
541 + case NOT:
542 + if (mode == TImode)
543 + return COSTS_N_INSNS (10);
544 +
545 + if (mode == DImode)
546 + return COSTS_N_INSNS (4);
547 + return COSTS_N_INSNS (1);
548 + case PLUS:
549 + case MINUS:
550 + case NEG:
551 + case COMPARE:
552 + case ABS:
553 + if (GET_MODE_CLASS (mode) == MODE_FLOAT)
554 + return COSTS_N_INSNS (100);
555 +
556 + if (mode == TImode)
557 + return COSTS_N_INSNS (50);
558 +
559 + if (mode == DImode)
560 + return COSTS_N_INSNS (2);
561 + return COSTS_N_INSNS (1);
562 +
563 + case MULT:
564 + {
565 + if (GET_MODE_CLASS (mode) == MODE_FLOAT)
566 + return COSTS_N_INSNS (300);
567 +
568 + if (mode == TImode)
569 + return COSTS_N_INSNS (16);
570 +
571 + if (mode == DImode)
572 + return COSTS_N_INSNS (4);
573 +
574 + if (mode == HImode)
575 + return COSTS_N_INSNS (2);
576 +
577 + return COSTS_N_INSNS (3);
578 + }
579 + case IF_THEN_ELSE:
580 + if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
581 + return COSTS_N_INSNS (4);
582 + return COSTS_N_INSNS (1);
583 + case SIGN_EXTEND:
584 + case ZERO_EXTEND:
585 + /* Sign/Zero extensions of registers cost quite much since these
586 + instrcutions only take one register operand which means that gcc
587 + often must insert some move instrcutions */
588 + if (mode == QImode || mode == HImode)
589 + return (COSTS_N_INSNS (GET_CODE (XEXP (x, 0)) == MEM ? 0 : 1));
590 + return COSTS_N_INSNS (4);
591 + case UNSPEC:
592 + /* divmod operations */
593 + if (XINT (x, 1) == UNSPEC_UDIVMODSI4_INTERNAL
594 + || XINT (x, 1) == UNSPEC_DIVMODSI4_INTERNAL)
595 + {
596 + return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16);
597 + }
598 + /* Fallthrough */
599 + default:
600 + return COSTS_N_INSNS (1);
601 + }
602 + }
603 +
604 +static bool
605 +avr32_rtx_costs (rtx x, int code, int outer_code, int *total)
606 + {
607 + *total = avr32_rtx_costs_1 (x, code, outer_code);
608 + return true;
609 + }
610 +
611 +
612 +bool
613 +avr32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
614 + {
615 + /* Do not want symbols in the constant pool when compiling pic or if using
616 + address pseudo instructions. */
617 + return ((flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS)
618 + && avr32_find_symbol (x) != NULL_RTX);
619 + }
620 +
621 +
622 +/* Table of machine attributes. */
623 +const struct attribute_spec avr32_attribute_table[] = {
624 + /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
625 + /* Interrupt Service Routines have special prologue and epilogue
626 + requirements. */
627 + {"isr", 0, 1, false, false, false, avr32_handle_isr_attribute},
628 + {"interrupt", 0, 1, false, false, false, avr32_handle_isr_attribute},
629 + {"acall", 0, 1, false, true, true, avr32_handle_acall_attribute},
630 + {"naked", 0, 0, true, false, false, avr32_handle_fndecl_attribute},
631 + {NULL, 0, 0, false, false, false, NULL}
632 +};
633 +
634 +
635 +typedef struct
636 +{
637 + const char *const arg;
638 + const unsigned long return_value;
639 +}
640 +isr_attribute_arg;
641 +
642 +static const isr_attribute_arg isr_attribute_args[] = {
643 + {"FULL", AVR32_FT_ISR_FULL},
644 + {"full", AVR32_FT_ISR_FULL},
645 + {"HALF", AVR32_FT_ISR_HALF},
646 + {"half", AVR32_FT_ISR_HALF},
647 + {"NONE", AVR32_FT_ISR_NONE},
648 + {"none", AVR32_FT_ISR_NONE},
649 + {"UNDEF", AVR32_FT_ISR_NONE},
650 + {"undef", AVR32_FT_ISR_NONE},
651 + {"SWI", AVR32_FT_ISR_NONE},
652 + {"swi", AVR32_FT_ISR_NONE},
653 + {NULL, AVR32_FT_ISR_NONE}
654 +};
655 +
656 +/* Returns the (interrupt) function type of the current
657 + function, or AVR32_FT_UNKNOWN if the type cannot be determined. */
658 +
659 +static unsigned long
660 +avr32_isr_value (tree argument)
661 + {
662 + const isr_attribute_arg *ptr;
663 + const char *arg;
664 +
665 + /* No argument - default to ISR_NONE. */
666 + if (argument == NULL_TREE)
667 + return AVR32_FT_ISR_NONE;
668 +
669 + /* Get the value of the argument. */
670 + if (TREE_VALUE (argument) == NULL_TREE
671 + || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
672 + return AVR32_FT_UNKNOWN;
673 +
674 + arg = TREE_STRING_POINTER (TREE_VALUE (argument));
675 +
676 + /* Check it against the list of known arguments. */
677 + for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
678 + if (streq (arg, ptr->arg))
679 + return ptr->return_value;
680 +
681 + /* An unrecognized interrupt type. */
682 + return AVR32_FT_UNKNOWN;
683 + }
684 +
685 +
686 +
687 +/*
688 +These hooks specify assembly directives for creating certain kinds
689 +of integer object. The TARGET_ASM_BYTE_OP directive creates a
690 +byte-sized object, the TARGET_ASM_ALIGNED_HI_OP one creates an
691 +aligned two-byte object, and so on. Any of the hooks may be
692 +NULL, indicating that no suitable directive is available.
693 +
694 +The compiler will print these strings at the start of a new line,
695 +followed immediately by the object's initial value. In most cases,
696 +the string should contain a tab, a pseudo-op, and then another tab.
697 + */
698 +#undef TARGET_ASM_BYTE_OP
699 +#define TARGET_ASM_BYTE_OP "\t.byte\t"
700 +#undef TARGET_ASM_ALIGNED_HI_OP
701 +#define TARGET_ASM_ALIGNED_HI_OP "\t.align 1\n\t.short\t"
702 +#undef TARGET_ASM_ALIGNED_SI_OP
703 +#define TARGET_ASM_ALIGNED_SI_OP "\t.align 2\n\t.int\t"
704 +#undef TARGET_ASM_ALIGNED_DI_OP
705 +#define TARGET_ASM_ALIGNED_DI_OP NULL
706 +#undef TARGET_ASM_ALIGNED_TI_OP
707 +#define TARGET_ASM_ALIGNED_TI_OP NULL
708 +#undef TARGET_ASM_UNALIGNED_HI_OP
709 +#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
710 +#undef TARGET_ASM_UNALIGNED_SI_OP
711 +#define TARGET_ASM_UNALIGNED_SI_OP "\t.int\t"
712 +#undef TARGET_ASM_UNALIGNED_DI_OP
713 +#define TARGET_ASM_UNALIGNED_DI_OP NULL
714 +#undef TARGET_ASM_UNALIGNED_TI_OP
715 +#define TARGET_ASM_UNALIGNED_TI_OP NULL
716 +
717 +#undef TARGET_ASM_OUTPUT_MI_THUNK
718 +#define TARGET_ASM_OUTPUT_MI_THUNK avr32_output_mi_thunk
719 +
720 +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
721 +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_tree_hwi_hwi_tree_true
722 +
723 +static void
724 +avr32_output_mi_thunk (FILE * file,
725 + tree thunk ATTRIBUTE_UNUSED,
726 + HOST_WIDE_INT delta,
727 + HOST_WIDE_INT vcall_offset, tree function)
728 + {
729 + int mi_delta = delta;
730 + int this_regno =
731 + (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ?
732 + INTERNAL_REGNUM (11) : INTERNAL_REGNUM (12));
733 +
734 +
735 + if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")
736 + || vcall_offset
737 + || flag_pic)
738 + {
739 + fputs ("\tpushm\tlr\n", file);
740 + }
741 +
742 +
743 + if (mi_delta != 0)
744 + {
745 + if (avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21"))
746 + {
747 + fprintf (file, "\tsub\t%s, -0x%x\n", reg_names[this_regno],
748 + mi_delta);
749 + }
750 + else
751 + {
752 + /* Immediate is larger than k21 we must make us a temp register by
753 + pushing a register to the stack. */
754 + fprintf (file, "\tmov\tlr, lo(%x)\n", mi_delta);
755 + fprintf (file, "\torh\tlr, hi(%x)\n", mi_delta);
756 + fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]);
757 + }
758 + }
759 +
760 +
761 + if (vcall_offset != 0)
762 + {
763 + fprintf (file, "\tld.w\tlr, %s[0]\n", reg_names[this_regno]);
764 + fprintf (file, "\tld.w\tlr, lr[%i]\n", (int) vcall_offset);
765 + fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]);
766 + }
767 +
768 +
769 + if ( (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")
770 + || vcall_offset)
771 + && !flag_pic )
772 + {
773 + fputs ("\tpopm\tlr\n", file);
774 + }
775 +
776 + if (flag_pic)
777 + {
778 + /* Load the got into lr and then load the pointer
779 + to the function from the got and put it on the stack.
780 + We can then call the function and restore lr by issuing
781 + a doubleword load from the stack. We do not use a popm/ldm
782 + since it will be treated as a return and might need a flushing
783 + of the return-stack if available. */
784 + rtx label = gen_label_rtx ();
785 + /* Load the got. */
786 + fputs ("\tlddpc\tlr, 0f\n", file);
787 + (*targetm.asm_out.internal_label) (file, "L",
788 + CODE_LABEL_NUMBER (label));
789 + fputs ("\trsub\tlr, pc\n", file);
790 + /* Load the function pointer. */
791 + fputs ("\tld.w\tlr, lr[", file);
792 + assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
793 + fputs ("@got]\n", file);
794 + /* Push the function pointer on the stack.*/
795 + fputs ("\tpushm\tlr\n", file);
796 + /* Restore the old lr value and load the function pointer into
797 + pc. */
798 + fputs ("\tld.d\tlr,sp++\n", file);
799 + fprintf (file, "\t.align 2\n");
800 + fprintf (file, "0:\t.long\t.L%d - _GLOBAL_OFFSET_TABLE_\n", CODE_LABEL_NUMBER (label));
801 + }
802 + else
803 + {
804 + fprintf (file, "\tlddpc\tpc, 0f\n");
805 + fprintf (file, "\t.align 2\n");
806 + fputs ("0:\t.long\t", file);
807 + assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
808 + fputc ('\n', file);
809 + }
810 + }
811 +
812 +/* Implements target hook vector_mode_supported. */
813 +bool
814 +avr32_vector_mode_supported (enum machine_mode mode)
815 + {
816 + if ((mode == V2HImode) || (mode == V4QImode))
817 + return true;
818 +
819 + return false;
820 + }
821 +
822 +
823 +#undef TARGET_INIT_LIBFUNCS
824 +#define TARGET_INIT_LIBFUNCS avr32_init_libfuncs
825 +
826 +#undef TARGET_INIT_BUILTINS
827 +#define TARGET_INIT_BUILTINS avr32_init_builtins
828 +
829 +#undef TARGET_EXPAND_BUILTIN
830 +#define TARGET_EXPAND_BUILTIN avr32_expand_builtin
831 +
832 +tree int_ftype_int, int_ftype_void, short_ftype_short, void_ftype_int_int,
833 +void_ftype_ptr_int;
834 +tree void_ftype_int, void_ftype_void, int_ftype_ptr_int;
835 +tree short_ftype_short, int_ftype_int_short, int_ftype_short_short,
836 +short_ftype_short_short;
837 +tree int_ftype_int_int, longlong_ftype_int_short, longlong_ftype_short_short;
838 +tree void_ftype_int_int_int_int_int, void_ftype_int_int_int;
839 +tree longlong_ftype_int_int, void_ftype_int_int_longlong;
840 +tree int_ftype_int_int_int, longlong_ftype_longlong_int_short;
841 +tree longlong_ftype_longlong_short_short, int_ftype_int_short_short;
842 +
843 +#define def_builtin(NAME, TYPE, CODE) \
844 + lang_hooks.builtin_function ((NAME), (TYPE), (CODE), \
845 + BUILT_IN_MD, NULL, NULL_TREE)
846 +
847 +#define def_mbuiltin(MASK, NAME, TYPE, CODE) \
848 + do \
849 + { \
850 + if ((MASK)) \
851 + lang_hooks.builtin_function ((NAME), (TYPE), (CODE), \
852 + BUILT_IN_MD, NULL, NULL_TREE); \
853 + } \
854 + while (0)
855 +
856 +struct builtin_description
857 +{
858 + const unsigned int mask;
859 + const enum insn_code icode;
860 + const char *const name;
861 + const int code;
862 + const enum rtx_code comparison;
863 + const unsigned int flag;
864 + const tree *ftype;
865 +};
866 +
867 +static const struct builtin_description bdesc_2arg[] = {
868 +#define DSP_BUILTIN(code, builtin, ftype) \
869 + { 1, CODE_FOR_##code, "__builtin_" #code , \
870 + AVR32_BUILTIN_##builtin, 0, 0, ftype }
871 +
872 + DSP_BUILTIN (mulsathh_h, MULSATHH_H, &short_ftype_short_short),
873 + DSP_BUILTIN (mulsathh_w, MULSATHH_W, &int_ftype_short_short),
874 + DSP_BUILTIN (mulsatrndhh_h, MULSATRNDHH_H, &short_ftype_short_short),
875 + DSP_BUILTIN (mulsatrndwh_w, MULSATRNDWH_W, &int_ftype_int_short),
876 + DSP_BUILTIN (mulsatwh_w, MULSATWH_W, &int_ftype_int_short),
877 + DSP_BUILTIN (satadd_h, SATADD_H, &short_ftype_short_short),
878 + DSP_BUILTIN (satsub_h, SATSUB_H, &short_ftype_short_short),
879 + DSP_BUILTIN (satadd_w, SATADD_W, &int_ftype_int_int),
880 + DSP_BUILTIN (satsub_w, SATSUB_W, &int_ftype_int_int),
881 + DSP_BUILTIN (mulwh_d, MULWH_D, &longlong_ftype_int_short),
882 + DSP_BUILTIN (mulnwh_d, MULNWH_D, &longlong_ftype_int_short)
883 +};
884 +
885 +
886 +void
887 +avr32_init_builtins (void)
888 + {
889 + unsigned int i;
890 + const struct builtin_description *d;
891 + tree endlink = void_list_node;
892 + tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
893 + tree longlong_endlink =
894 + tree_cons (NULL_TREE, long_long_integer_type_node, endlink);
895 + tree short_endlink =
896 + tree_cons (NULL_TREE, short_integer_type_node, endlink);
897 + tree void_endlink = tree_cons (NULL_TREE, void_type_node, endlink);
898 +
899 + /* int func (int) */
900 + int_ftype_int = build_function_type (integer_type_node, int_endlink);
901 +
902 + /* short func (short) */
903 + short_ftype_short
904 + = build_function_type (short_integer_type_node, short_endlink);
905 +
906 + /* short func (short, short) */
907 + short_ftype_short_short
908 + = build_function_type (short_integer_type_node,
909 + tree_cons (NULL_TREE, short_integer_type_node,
910 + short_endlink));
911 +
912 + /* long long func (long long, short, short) */
913 + longlong_ftype_longlong_short_short
914 + = build_function_type (long_long_integer_type_node,
915 + tree_cons (NULL_TREE, long_long_integer_type_node,
916 + tree_cons (NULL_TREE,
917 + short_integer_type_node,
918 + short_endlink)));
919 +
920 + /* long long func (short, short) */
921 + longlong_ftype_short_short
922 + = build_function_type (long_long_integer_type_node,
923 + tree_cons (NULL_TREE, short_integer_type_node,
924 + short_endlink));
925 +
926 + /* int func (int, int) */
927 + int_ftype_int_int
928 + = build_function_type (integer_type_node,
929 + tree_cons (NULL_TREE, integer_type_node,
930 + int_endlink));
931 +
932 + /* long long func (int, int) */
933 + longlong_ftype_int_int
934 + = build_function_type (long_long_integer_type_node,
935 + tree_cons (NULL_TREE, integer_type_node,
936 + int_endlink));
937 +
938 + /* long long int func (long long, int, short) */
939 + longlong_ftype_longlong_int_short
940 + = build_function_type (long_long_integer_type_node,
941 + tree_cons (NULL_TREE, long_long_integer_type_node,
942 + tree_cons (NULL_TREE, integer_type_node,
943 + short_endlink)));
944 +
945 + /* long long int func (int, short) */
946 + longlong_ftype_int_short
947 + = build_function_type (long_long_integer_type_node,
948 + tree_cons (NULL_TREE, integer_type_node,
949 + short_endlink));
950 +
951 + /* int func (int, short, short) */
952 + int_ftype_int_short_short
953 + = build_function_type (integer_type_node,
954 + tree_cons (NULL_TREE, integer_type_node,
955 + tree_cons (NULL_TREE,
956 + short_integer_type_node,
957 + short_endlink)));
958 +
959 + /* int func (short, short) */
960 + int_ftype_short_short
961 + = build_function_type (integer_type_node,
962 + tree_cons (NULL_TREE, short_integer_type_node,
963 + short_endlink));
964 +
965 + /* int func (int, short) */
966 + int_ftype_int_short
967 + = build_function_type (integer_type_node,
968 + tree_cons (NULL_TREE, integer_type_node,
969 + short_endlink));
970 +
971 + /* void func (int, int) */
972 + void_ftype_int_int
973 + = build_function_type (void_type_node,
974 + tree_cons (NULL_TREE, integer_type_node,
975 + int_endlink));
976 +
977 + /* void func (int, int, int) */
978 + void_ftype_int_int_int
979 + = build_function_type (void_type_node,
980 + tree_cons (NULL_TREE, integer_type_node,
981 + tree_cons (NULL_TREE, integer_type_node,
982 + int_endlink)));
983 +
984 + /* void func (int, int, long long) */
985 + void_ftype_int_int_longlong
986 + = build_function_type (void_type_node,
987 + tree_cons (NULL_TREE, integer_type_node,
988 + tree_cons (NULL_TREE, integer_type_node,
989 + longlong_endlink)));
990 +
991 + /* void func (int, int, int, int, int) */
992 + void_ftype_int_int_int_int_int
993 + = build_function_type (void_type_node,
994 + tree_cons (NULL_TREE, integer_type_node,
995 + tree_cons (NULL_TREE, integer_type_node,
996 + tree_cons (NULL_TREE,
997 + integer_type_node,
998 + tree_cons
999 + (NULL_TREE,
1000 + integer_type_node,
1001 + int_endlink)))));
1002 +
1003 + /* void func (void *, int) */
1004 + void_ftype_ptr_int
1005 + = build_function_type (void_type_node,
1006 + tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1007 +
1008 + /* void func (int) */
1009 + void_ftype_int = build_function_type (void_type_node, int_endlink);
1010 +
1011 + /* void func (void) */
1012 + void_ftype_void = build_function_type (void_type_node, void_endlink);
1013 +
1014 + /* int func (void) */
1015 + int_ftype_void = build_function_type (integer_type_node, void_endlink);
1016 +
1017 + /* int func (void *, int) */
1018 + int_ftype_ptr_int
1019 + = build_function_type (integer_type_node,
1020 + tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1021 +
1022 + /* int func (int, int, int) */
1023 + int_ftype_int_int_int
1024 + = build_function_type (integer_type_node,
1025 + tree_cons (NULL_TREE, integer_type_node,
1026 + tree_cons (NULL_TREE, integer_type_node,
1027 + int_endlink)));
1028 +
1029 + /* Initialize avr32 builtins. */
1030 + def_builtin ("__builtin_mfsr", int_ftype_int, AVR32_BUILTIN_MFSR);
1031 + def_builtin ("__builtin_mtsr", void_ftype_int_int, AVR32_BUILTIN_MTSR);
1032 + def_builtin ("__builtin_mfdr", int_ftype_int, AVR32_BUILTIN_MFDR);
1033 + def_builtin ("__builtin_mtdr", void_ftype_int_int, AVR32_BUILTIN_MTDR);
1034 + def_builtin ("__builtin_cache", void_ftype_ptr_int, AVR32_BUILTIN_CACHE);
1035 + def_builtin ("__builtin_sync", void_ftype_int, AVR32_BUILTIN_SYNC);
1036 + def_builtin ("__builtin_tlbr", void_ftype_void, AVR32_BUILTIN_TLBR);
1037 + def_builtin ("__builtin_tlbs", void_ftype_void, AVR32_BUILTIN_TLBS);
1038 + def_builtin ("__builtin_tlbw", void_ftype_void, AVR32_BUILTIN_TLBW);
1039 + def_builtin ("__builtin_breakpoint", void_ftype_void,
1040 + AVR32_BUILTIN_BREAKPOINT);
1041 + def_builtin ("__builtin_xchg", int_ftype_ptr_int, AVR32_BUILTIN_XCHG);
1042 + def_builtin ("__builtin_ldxi", int_ftype_ptr_int, AVR32_BUILTIN_LDXI);
1043 + def_builtin ("__builtin_bswap_16", short_ftype_short,
1044 + AVR32_BUILTIN_BSWAP16);
1045 + def_builtin ("__builtin_bswap_32", int_ftype_int, AVR32_BUILTIN_BSWAP32);
1046 + def_builtin ("__builtin_cop", void_ftype_int_int_int_int_int,
1047 + AVR32_BUILTIN_COP);
1048 + def_builtin ("__builtin_mvcr_w", int_ftype_int_int, AVR32_BUILTIN_MVCR_W);
1049 + def_builtin ("__builtin_mvrc_w", void_ftype_int_int_int,
1050 + AVR32_BUILTIN_MVRC_W);
1051 + def_builtin ("__builtin_mvcr_d", longlong_ftype_int_int,
1052 + AVR32_BUILTIN_MVCR_D);
1053 + def_builtin ("__builtin_mvrc_d", void_ftype_int_int_longlong,
1054 + AVR32_BUILTIN_MVRC_D);
1055 + def_builtin ("__builtin_sats", int_ftype_int_int_int, AVR32_BUILTIN_SATS);
1056 + def_builtin ("__builtin_satu", int_ftype_int_int_int, AVR32_BUILTIN_SATU);
1057 + def_builtin ("__builtin_satrnds", int_ftype_int_int_int,
1058 + AVR32_BUILTIN_SATRNDS);
1059 + def_builtin ("__builtin_satrndu", int_ftype_int_int_int,
1060 + AVR32_BUILTIN_SATRNDU);
1061 + def_builtin ("__builtin_musfr", void_ftype_int, AVR32_BUILTIN_MUSFR);
1062 + def_builtin ("__builtin_mustr", int_ftype_void, AVR32_BUILTIN_MUSTR);
1063 + def_builtin ("__builtin_macsathh_w", int_ftype_int_short_short,
1064 + AVR32_BUILTIN_MACSATHH_W);
1065 + def_builtin ("__builtin_macwh_d", longlong_ftype_longlong_int_short,
1066 + AVR32_BUILTIN_MACWH_D);
1067 + def_builtin ("__builtin_machh_d", longlong_ftype_longlong_short_short,
1068 + AVR32_BUILTIN_MACHH_D);
1069 +
1070 + /* Add all builtins that are more or less simple operations on two
1071 + operands. */
1072 + for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
1073 + {
1074 + /* Use one of the operands; the target can have a different mode for
1075 + mask-generating compares. */
1076 +
1077 + if (d->name == 0)
1078 + continue;
1079 +
1080 + def_mbuiltin (d->mask, d->name, *(d->ftype), d->code);
1081 + }
1082 + }
1083 +
1084 +
1085 +/* Subroutine of avr32_expand_builtin to take care of binop insns. */
1086 +
1087 +static rtx
1088 +avr32_expand_binop_builtin (enum insn_code icode, tree arglist, rtx target)
1089 + {
1090 + rtx pat;
1091 + tree arg0 = TREE_VALUE (arglist);
1092 + tree arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1093 + rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1094 + rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1095 + enum machine_mode tmode = insn_data[icode].operand[0].mode;
1096 + enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1097 + enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1098 +
1099 + if (!target
1100 + || GET_MODE (target) != tmode
1101 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1102 + target = gen_reg_rtx (tmode);
1103 +
1104 + /* In case the insn wants input operands in modes different from the
1105 + result, abort. */
1106 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1107 + {
1108 + /* If op0 is already a reg we must cast it to the correct mode. */
1109 + if (REG_P (op0))
1110 + op0 = convert_to_mode (mode0, op0, 1);
1111 + else
1112 + op0 = copy_to_mode_reg (mode0, op0);
1113 + }
1114 + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1115 + {
1116 + /* If op1 is already a reg we must cast it to the correct mode. */
1117 + if (REG_P (op1))
1118 + op1 = convert_to_mode (mode1, op1, 1);
1119 + else
1120 + op1 = copy_to_mode_reg (mode1, op1);
1121 + }
1122 + pat = GEN_FCN (icode) (target, op0, op1);
1123 + if (!pat)
1124 + return 0;
1125 + emit_insn (pat);
1126 + return target;
1127 + }
1128 +
1129 +/* Expand an expression EXP that calls a built-in function,
1130 + with result going to TARGET if that's convenient
1131 + (and in mode MODE if that's convenient).
1132 + SUBTARGET may be used as the target for computing one of EXP's operands.
1133 + IGNORE is nonzero if the value is to be ignored. */
1134 +
1135 +rtx
1136 +avr32_expand_builtin (tree exp,
1137 + rtx target,
1138 + rtx subtarget ATTRIBUTE_UNUSED,
1139 + enum machine_mode mode ATTRIBUTE_UNUSED,
1140 + int ignore ATTRIBUTE_UNUSED)
1141 + {
1142 + const struct builtin_description *d;
1143 + unsigned int i;
1144 + enum insn_code icode;
1145 + tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
1146 + tree arglist = TREE_OPERAND (exp, 1);
1147 + tree arg0, arg1, arg2;
1148 + rtx op0, op1, op2, pat;
1149 + enum machine_mode tmode, mode0, mode1;
1150 + enum machine_mode arg0_mode;
1151 + int fcode = DECL_FUNCTION_CODE (fndecl);
1152 +
1153 + switch (fcode)
1154 + {
1155 + default:
1156 + break;
1157 +
1158 + case AVR32_BUILTIN_SATS:
1159 + case AVR32_BUILTIN_SATU:
1160 + case AVR32_BUILTIN_SATRNDS:
1161 + case AVR32_BUILTIN_SATRNDU:
1162 + {
1163 + const char *fname;
1164 + switch (fcode)
1165 + {
1166 + default:
1167 + case AVR32_BUILTIN_SATS:
1168 + icode = CODE_FOR_sats;
1169 + fname = "sats";
1170 + break;
1171 + case AVR32_BUILTIN_SATU:
1172 + icode = CODE_FOR_satu;
1173 + fname = "satu";
1174 + break;
1175 + case AVR32_BUILTIN_SATRNDS:
1176 + icode = CODE_FOR_satrnds;
1177 + fname = "satrnds";
1178 + break;
1179 + case AVR32_BUILTIN_SATRNDU:
1180 + icode = CODE_FOR_satrndu;
1181 + fname = "satrndu";
1182 + break;
1183 + }
1184 +
1185 + arg0 = TREE_VALUE (arglist);
1186 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1187 + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1188 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1189 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1190 + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1191 +
1192 + tmode = insn_data[icode].operand[0].mode;
1193 +
1194 +
1195 + if (target == 0
1196 + || GET_MODE (target) != tmode
1197 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1198 + target = gen_reg_rtx (tmode);
1199 +
1200 +
1201 + if (!(*insn_data[icode].operand[0].predicate) (op0, GET_MODE (op0)))
1202 + {
1203 + op0 = copy_to_mode_reg (insn_data[icode].operand[0].mode, op0);
1204 + }
1205 +
1206 + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1207 + {
1208 + error ("Parameter 2 to __builtin_%s should be a constant number.",
1209 + fname);
1210 + return NULL_RTX;
1211 + }
1212 +
1213 + if (!(*insn_data[icode].operand[1].predicate) (op2, SImode))
1214 + {
1215 + error ("Parameter 3 to __builtin_%s should be a constant number.",
1216 + fname);
1217 + return NULL_RTX;
1218 + }
1219 +
1220 + emit_move_insn (target, op0);
1221 + pat = GEN_FCN (icode) (target, op1, op2);
1222 + if (!pat)
1223 + return 0;
1224 + emit_insn (pat);
1225 +
1226 + return target;
1227 + }
1228 + case AVR32_BUILTIN_MUSTR:
1229 + icode = CODE_FOR_mustr;
1230 + tmode = insn_data[icode].operand[0].mode;
1231 +
1232 + if (target == 0
1233 + || GET_MODE (target) != tmode
1234 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1235 + target = gen_reg_rtx (tmode);
1236 + pat = GEN_FCN (icode) (target);
1237 + if (!pat)
1238 + return 0;
1239 + emit_insn (pat);
1240 + return target;
1241 +
1242 + case AVR32_BUILTIN_MFSR:
1243 + icode = CODE_FOR_mfsr;
1244 + arg0 = TREE_VALUE (arglist);
1245 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1246 + tmode = insn_data[icode].operand[0].mode;
1247 + mode0 = insn_data[icode].operand[1].mode;
1248 +
1249 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1250 + {
1251 + error ("Parameter 1 to __builtin_mfsr must be a constant number");
1252 + }
1253 +
1254 + if (target == 0
1255 + || GET_MODE (target) != tmode
1256 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1257 + target = gen_reg_rtx (tmode);
1258 + pat = GEN_FCN (icode) (target, op0);
1259 + if (!pat)
1260 + return 0;
1261 + emit_insn (pat);
1262 + return target;
1263 + case AVR32_BUILTIN_MTSR:
1264 + icode = CODE_FOR_mtsr;
1265 + arg0 = TREE_VALUE (arglist);
1266 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1267 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1268 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1269 + mode0 = insn_data[icode].operand[0].mode;
1270 + mode1 = insn_data[icode].operand[1].mode;
1271 +
1272 + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1273 + {
1274 + error ("Parameter 1 to __builtin_mtsr must be a constant number");
1275 + return gen_reg_rtx (mode0);
1276 + }
1277 + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1278 + op1 = copy_to_mode_reg (mode1, op1);
1279 + pat = GEN_FCN (icode) (op0, op1);
1280 + if (!pat)
1281 + return 0;
1282 + emit_insn (pat);
1283 + return NULL_RTX;
1284 + case AVR32_BUILTIN_MFDR:
1285 + icode = CODE_FOR_mfdr;
1286 + arg0 = TREE_VALUE (arglist);
1287 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1288 + tmode = insn_data[icode].operand[0].mode;
1289 + mode0 = insn_data[icode].operand[1].mode;
1290 +
1291 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1292 + {
1293 + error ("Parameter 1 to __builtin_mfdr must be a constant number");
1294 + }
1295 +
1296 + if (target == 0
1297 + || GET_MODE (target) != tmode
1298 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1299 + target = gen_reg_rtx (tmode);
1300 + pat = GEN_FCN (icode) (target, op0);
1301 + if (!pat)
1302 + return 0;
1303 + emit_insn (pat);
1304 + return target;
1305 + case AVR32_BUILTIN_MTDR:
1306 + icode = CODE_FOR_mtdr;
1307 + arg0 = TREE_VALUE (arglist);
1308 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1309 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1310 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1311 + mode0 = insn_data[icode].operand[0].mode;
1312 + mode1 = insn_data[icode].operand[1].mode;
1313 +
1314 + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1315 + {
1316 + error ("Parameter 1 to __builtin_mtdr must be a constant number");
1317 + return gen_reg_rtx (mode0);
1318 + }
1319 + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1320 + op1 = copy_to_mode_reg (mode1, op1);
1321 + pat = GEN_FCN (icode) (op0, op1);
1322 + if (!pat)
1323 + return 0;
1324 + emit_insn (pat);
1325 + return NULL_RTX;
1326 + case AVR32_BUILTIN_CACHE:
1327 + icode = CODE_FOR_cache;
1328 + arg0 = TREE_VALUE (arglist);
1329 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1330 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1331 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1332 + mode0 = insn_data[icode].operand[0].mode;
1333 + mode1 = insn_data[icode].operand[1].mode;
1334 +
1335 + if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1336 + {
1337 + error ("Parameter 2 to __builtin_cache must be a constant number");
1338 + return gen_reg_rtx (mode1);
1339 + }
1340 +
1341 + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1342 + op0 = copy_to_mode_reg (mode0, op0);
1343 +
1344 + pat = GEN_FCN (icode) (op0, op1);
1345 + if (!pat)
1346 + return 0;
1347 + emit_insn (pat);
1348 + return NULL_RTX;
1349 + case AVR32_BUILTIN_SYNC:
1350 + case AVR32_BUILTIN_MUSFR:
1351 + {
1352 + const char *fname;
1353 + switch (fcode)
1354 + {
1355 + default:
1356 + case AVR32_BUILTIN_SYNC:
1357 + icode = CODE_FOR_sync;
1358 + fname = "sync";
1359 + break;
1360 + case AVR32_BUILTIN_MUSFR:
1361 + icode = CODE_FOR_musfr;
1362 + fname = "musfr";
1363 + break;
1364 + }
1365 +
1366 + arg0 = TREE_VALUE (arglist);
1367 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1368 + mode0 = insn_data[icode].operand[0].mode;
1369 +
1370 + if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1371 + {
1372 + if (icode == CODE_FOR_musfr)
1373 + op0 = copy_to_mode_reg (mode0, op0);
1374 + else
1375 + {
1376 + error ("Parameter to __builtin_%s is illegal.", fname);
1377 + return gen_reg_rtx (mode0);
1378 + }
1379 + }
1380 + pat = GEN_FCN (icode) (op0);
1381 + if (!pat)
1382 + return 0;
1383 + emit_insn (pat);
1384 + return NULL_RTX;
1385 + }
1386 + case AVR32_BUILTIN_TLBR:
1387 + icode = CODE_FOR_tlbr;
1388 + pat = GEN_FCN (icode) (NULL_RTX);
1389 + if (!pat)
1390 + return 0;
1391 + emit_insn (pat);
1392 + return NULL_RTX;
1393 + case AVR32_BUILTIN_TLBS:
1394 + icode = CODE_FOR_tlbs;
1395 + pat = GEN_FCN (icode) (NULL_RTX);
1396 + if (!pat)
1397 + return 0;
1398 + emit_insn (pat);
1399 + return NULL_RTX;
1400 + case AVR32_BUILTIN_TLBW:
1401 + icode = CODE_FOR_tlbw;
1402 + pat = GEN_FCN (icode) (NULL_RTX);
1403 + if (!pat)
1404 + return 0;
1405 + emit_insn (pat);
1406 + return NULL_RTX;
1407 + case AVR32_BUILTIN_BREAKPOINT:
1408 + icode = CODE_FOR_breakpoint;
1409 + pat = GEN_FCN (icode) (NULL_RTX);
1410 + if (!pat)
1411 + return 0;
1412 + emit_insn (pat);
1413 + return NULL_RTX;
1414 + case AVR32_BUILTIN_XCHG:
1415 + icode = CODE_FOR_sync_lock_test_and_setsi;
1416 + arg0 = TREE_VALUE (arglist);
1417 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1418 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1419 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1420 + tmode = insn_data[icode].operand[0].mode;
1421 + mode0 = insn_data[icode].operand[1].mode;
1422 + mode1 = insn_data[icode].operand[2].mode;
1423 +
1424 + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1425 + {
1426 + op1 = copy_to_mode_reg (mode1, op1);
1427 + }
1428 +
1429 + op0 = gen_rtx_MEM (SImode, op0);
1430 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1431 + {
1432 + error
1433 + ("Parameter 1 to __builtin_xchg must be a pointer to an integer.");
1434 + }
1435 +
1436 + if (target == 0
1437 + || GET_MODE (target) != tmode
1438 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1439 + target = gen_reg_rtx (tmode);
1440 + pat = GEN_FCN (icode) (target, op0, op1);
1441 + if (!pat)
1442 + return 0;
1443 + emit_insn (pat);
1444 + return target;
1445 + case AVR32_BUILTIN_LDXI:
1446 + icode = CODE_FOR_ldxi;
1447 + arg0 = TREE_VALUE (arglist);
1448 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1449 + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1450 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1451 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1452 + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1453 + tmode = insn_data[icode].operand[0].mode;
1454 + mode0 = insn_data[icode].operand[1].mode;
1455 + mode1 = insn_data[icode].operand[2].mode;
1456 +
1457 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1458 + {
1459 + op0 = copy_to_mode_reg (mode0, op0);
1460 + }
1461 +
1462 + if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1463 + {
1464 + op1 = copy_to_mode_reg (mode1, op1);
1465 + }
1466 +
1467 + if (!(*insn_data[icode].operand[3].predicate) (op2, SImode))
1468 + {
1469 + error
1470 + ("Parameter 3 to __builtin_ldxi must be a valid extract shift operand: (0|8|16|24)");
1471 + return gen_reg_rtx (mode0);
1472 + }
1473 +
1474 + if (target == 0
1475 + || GET_MODE (target) != tmode
1476 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1477 + target = gen_reg_rtx (tmode);
1478 + pat = GEN_FCN (icode) (target, op0, op1, op2);
1479 + if (!pat)
1480 + return 0;
1481 + emit_insn (pat);
1482 + return target;
1483 + case AVR32_BUILTIN_BSWAP16:
1484 + {
1485 + icode = CODE_FOR_bswap_16;
1486 + arg0 = TREE_VALUE (arglist);
1487 + arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1488 + mode0 = insn_data[icode].operand[1].mode;
1489 + if (arg0_mode != mode0)
1490 + arg0 = build1 (NOP_EXPR,
1491 + (*lang_hooks.types.type_for_mode) (mode0, 0), arg0);
1492 +
1493 + op0 = expand_expr (arg0, NULL_RTX, HImode, 0);
1494 + tmode = insn_data[icode].operand[0].mode;
1495 +
1496 +
1497 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1498 + {
1499 + op0 = copy_to_mode_reg (mode0, op0);
1500 + }
1501 +
1502 + if (target == 0
1503 + || GET_MODE (target) != tmode
1504 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1505 + {
1506 + target = gen_reg_rtx (tmode);
1507 + }
1508 +
1509 +
1510 + pat = GEN_FCN (icode) (target, op0);
1511 + if (!pat)
1512 + return 0;
1513 + emit_insn (pat);
1514 +
1515 + return target;
1516 + }
1517 + case AVR32_BUILTIN_BSWAP32:
1518 + {
1519 + icode = CODE_FOR_bswap_32;
1520 + arg0 = TREE_VALUE (arglist);
1521 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1522 + tmode = insn_data[icode].operand[0].mode;
1523 + mode0 = insn_data[icode].operand[1].mode;
1524 +
1525 + if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1526 + {
1527 + op0 = copy_to_mode_reg (mode0, op0);
1528 + }
1529 +
1530 + if (target == 0
1531 + || GET_MODE (target) != tmode
1532 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1533 + target = gen_reg_rtx (tmode);
1534 +
1535 +
1536 + pat = GEN_FCN (icode) (target, op0);
1537 + if (!pat)
1538 + return 0;
1539 + emit_insn (pat);
1540 +
1541 + return target;
1542 + }
1543 + case AVR32_BUILTIN_MVCR_W:
1544 + case AVR32_BUILTIN_MVCR_D:
1545 + {
1546 + arg0 = TREE_VALUE (arglist);
1547 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1548 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1549 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1550 +
1551 + if (fcode == AVR32_BUILTIN_MVCR_W)
1552 + icode = CODE_FOR_mvcrsi;
1553 + else
1554 + icode = CODE_FOR_mvcrdi;
1555 +
1556 + tmode = insn_data[icode].operand[0].mode;
1557 +
1558 + if (target == 0
1559 + || GET_MODE (target) != tmode
1560 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1561 + target = gen_reg_rtx (tmode);
1562 +
1563 + if (!(*insn_data[icode].operand[1].predicate) (op0, SImode))
1564 + {
1565 + error
1566 + ("Parameter 1 to __builtin_cop is not a valid coprocessor number.");
1567 + error ("Number should be between 0 and 7.");
1568 + return NULL_RTX;
1569 + }
1570 +
1571 + if (!(*insn_data[icode].operand[2].predicate) (op1, SImode))
1572 + {
1573 + error
1574 + ("Parameter 2 to __builtin_cop is not a valid coprocessor register number.");
1575 + error ("Number should be between 0 and 15.");
1576 + return NULL_RTX;
1577 + }
1578 +
1579 + pat = GEN_FCN (icode) (target, op0, op1);
1580 + if (!pat)
1581 + return 0;
1582 + emit_insn (pat);
1583 +
1584 + return target;
1585 + }
1586 + case AVR32_BUILTIN_MACSATHH_W:
1587 + case AVR32_BUILTIN_MACWH_D:
1588 + case AVR32_BUILTIN_MACHH_D:
1589 + {
1590 + arg0 = TREE_VALUE (arglist);
1591 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1592 + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1593 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1594 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1595 + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1596 +
1597 + icode = ((fcode == AVR32_BUILTIN_MACSATHH_W) ? CODE_FOR_macsathh_w :
1598 + (fcode == AVR32_BUILTIN_MACWH_D) ? CODE_FOR_macwh_d :
1599 + CODE_FOR_machh_d);
1600 +
1601 + tmode = insn_data[icode].operand[0].mode;
1602 + mode0 = insn_data[icode].operand[1].mode;
1603 + mode1 = insn_data[icode].operand[2].mode;
1604 +
1605 +
1606 + if (!target
1607 + || GET_MODE (target) != tmode
1608 + || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1609 + target = gen_reg_rtx (tmode);
1610 +
1611 + if (!(*insn_data[icode].operand[0].predicate) (op0, tmode))
1612 + {
1613 + /* If op0 is already a reg we must cast it to the correct mode. */
1614 + if (REG_P (op0))
1615 + op0 = convert_to_mode (tmode, op0, 1);
1616 + else
1617 + op0 = copy_to_mode_reg (tmode, op0);
1618 + }
1619 +
1620 + if (!(*insn_data[icode].operand[1].predicate) (op1, mode0))
1621 + {
1622 + /* If op1 is already a reg we must cast it to the correct mode. */
1623 + if (REG_P (op1))
1624 + op1 = convert_to_mode (mode0, op1, 1);
1625 + else
1626 + op1 = copy_to_mode_reg (mode0, op1);
1627 + }
1628 +
1629 + if (!(*insn_data[icode].operand[2].predicate) (op2, mode1))
1630 + {
1631 + /* If op1 is already a reg we must cast it to the correct mode. */
1632 + if (REG_P (op2))
1633 + op2 = convert_to_mode (mode1, op2, 1);
1634 + else
1635 + op2 = copy_to_mode_reg (mode1, op2);
1636 + }
1637 +
1638 + emit_move_insn (target, op0);
1639 +
1640 + pat = GEN_FCN (icode) (target, op1, op2);
1641 + if (!pat)
1642 + return 0;
1643 + emit_insn (pat);
1644 + return target;
1645 + }
1646 + case AVR32_BUILTIN_MVRC_W:
1647 + case AVR32_BUILTIN_MVRC_D:
1648 + {
1649 + arg0 = TREE_VALUE (arglist);
1650 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1651 + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1652 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1653 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1654 + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1655 +
1656 + if (fcode == AVR32_BUILTIN_MVRC_W)
1657 + icode = CODE_FOR_mvrcsi;
1658 + else
1659 + icode = CODE_FOR_mvrcdi;
1660 +
1661 + if (!(*insn_data[icode].operand[0].predicate) (op0, SImode))
1662 + {
1663 + error ("Parameter 1 is not a valid coprocessor number.");
1664 + error ("Number should be between 0 and 7.");
1665 + return NULL_RTX;
1666 + }
1667 +
1668 + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1669 + {
1670 + error ("Parameter 2 is not a valid coprocessor register number.");
1671 + error ("Number should be between 0 and 15.");
1672 + return NULL_RTX;
1673 + }
1674 +
1675 + if (GET_CODE (op2) == CONST_INT
1676 + || GET_CODE (op2) == CONST
1677 + || GET_CODE (op2) == SYMBOL_REF || GET_CODE (op2) == LABEL_REF)
1678 + {
1679 + op2 = force_const_mem (insn_data[icode].operand[2].mode, op2);
1680 + }
1681 +
1682 + if (!(*insn_data[icode].operand[2].predicate) (op2, GET_MODE (op2)))
1683 + op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
1684 +
1685 +
1686 + pat = GEN_FCN (icode) (op0, op1, op2);
1687 + if (!pat)
1688 + return 0;
1689 + emit_insn (pat);
1690 +
1691 + return NULL_RTX;
1692 + }
1693 + case AVR32_BUILTIN_COP:
1694 + {
1695 + rtx op3, op4;
1696 + tree arg3, arg4;
1697 + icode = CODE_FOR_cop;
1698 + arg0 = TREE_VALUE (arglist);
1699 + arg1 = TREE_VALUE (TREE_CHAIN (arglist));
1700 + arg2 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (arglist)));
1701 + arg3 = TREE_VALUE (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))));
1702 + arg4 =
1703 + TREE_VALUE (TREE_CHAIN
1704 + (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist)))));
1705 + op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1706 + op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1707 + op2 = expand_expr (arg2, NULL_RTX, VOIDmode, 0);
1708 + op3 = expand_expr (arg3, NULL_RTX, VOIDmode, 0);
1709 + op4 = expand_expr (arg4, NULL_RTX, VOIDmode, 0);
1710 +
1711 + if (!(*insn_data[icode].operand[0].predicate) (op0, SImode))
1712 + {
1713 + error
1714 + ("Parameter 1 to __builtin_cop is not a valid coprocessor number.");
1715 + error ("Number should be between 0 and 7.");
1716 + return NULL_RTX;
1717 + }
1718 +
1719 + if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1720 + {
1721 + error
1722 + ("Parameter 2 to __builtin_cop is not a valid coprocessor register number.");
1723 + error ("Number should be between 0 and 15.");
1724 + return NULL_RTX;
1725 + }
1726 +
1727 + if (!(*insn_data[icode].operand[2].predicate) (op2, SImode))
1728 + {
1729 + error
1730 + ("Parameter 3 to __builtin_cop is not a valid coprocessor register number.");
1731 + error ("Number should be between 0 and 15.");
1732 + return NULL_RTX;
1733 + }
1734 +
1735 + if (!(*insn_data[icode].operand[3].predicate) (op3, SImode))
1736 + {
1737 + error
1738 + ("Parameter 4 to __builtin_cop is not a valid coprocessor register number.");
1739 + error ("Number should be between 0 and 15.");
1740 + return NULL_RTX;
1741 + }
1742 +
1743 + if (!(*insn_data[icode].operand[4].predicate) (op4, SImode))
1744 + {
1745 + error
1746 + ("Parameter 5 to __builtin_cop is not a valid coprocessor operation.");
1747 + error ("Number should be between 0 and 127.");
1748 + return NULL_RTX;
1749 + }
1750 +
1751 + pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
1752 + if (!pat)
1753 + return 0;
1754 + emit_insn (pat);
1755 +
1756 + return target;
1757 + }
1758 + }
1759 +
1760 + for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
1761 + if (d->code == fcode)
1762 + return avr32_expand_binop_builtin (d->icode, arglist, target);
1763 +
1764 +
1765 + /* @@@ Should really do something sensible here. */
1766 + return NULL_RTX;
1767 + }
1768 +
1769 +
1770 +/* Handle an "interrupt" or "isr" attribute;
1771 + arguments as in struct attribute_spec.handler. */
1772 +
1773 +static tree
1774 +avr32_handle_isr_attribute (tree * node, tree name, tree args,
1775 + int flags, bool * no_add_attrs)
1776 + {
1777 + if (DECL_P (*node))
1778 + {
1779 + if (TREE_CODE (*node) != FUNCTION_DECL)
1780 + {
1781 + warning ("`%s' attribute only applies to functions",
1782 + IDENTIFIER_POINTER (name));
1783 + *no_add_attrs = true;
1784 + }
1785 + /* FIXME: the argument if any is checked for type attributes; should it
1786 + be checked for decl ones? */
1787 + }
1788 + else
1789 + {
1790 + if (TREE_CODE (*node) == FUNCTION_TYPE
1791 + || TREE_CODE (*node) == METHOD_TYPE)
1792 + {
1793 + if (avr32_isr_value (args) == AVR32_FT_UNKNOWN)
1794 + {
1795 + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1796 + *no_add_attrs = true;
1797 + }
1798 + }
1799 + else if (TREE_CODE (*node) == POINTER_TYPE
1800 + && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
1801 + || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
1802 + && avr32_isr_value (args) != AVR32_FT_UNKNOWN)
1803 + {
1804 + *node = build_variant_type_copy (*node);
1805 + TREE_TYPE (*node) = build_type_attribute_variant
1806 + (TREE_TYPE (*node),
1807 + tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
1808 + *no_add_attrs = true;
1809 + }
1810 + else
1811 + {
1812 + /* Possibly pass this attribute on from the type to a decl. */
1813 + if (flags & ((int) ATTR_FLAG_DECL_NEXT
1814 + | (int) ATTR_FLAG_FUNCTION_NEXT
1815 + | (int) ATTR_FLAG_ARRAY_NEXT))
1816 + {
1817 + *no_add_attrs = true;
1818 + return tree_cons (name, args, NULL_TREE);
1819 + }
1820 + else
1821 + {
1822 + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
1823 + }
1824 + }
1825 + }
1826 +
1827 + return NULL_TREE;
1828 + }
1829 +
1830 +/* Handle an attribute requiring a FUNCTION_DECL;
1831 + arguments as in struct attribute_spec.handler. */
1832 +static tree
1833 +avr32_handle_fndecl_attribute (tree * node, tree name,
1834 + tree args ATTRIBUTE_UNUSED,
1835 + int flags ATTRIBUTE_UNUSED,
1836 + bool * no_add_attrs)
1837 + {
1838 + if (TREE_CODE (*node) != FUNCTION_DECL)
1839 + {
1840 + warning ("%qs attribute only applies to functions",
1841 + IDENTIFIER_POINTER (name));
1842 + *no_add_attrs = true;
1843 + }
1844 +
1845 + return NULL_TREE;
1846 + }
1847 +
1848 +
1849 +/* Handle an acall attribute;
1850 + arguments as in struct attribute_spec.handler. */
1851 +
1852 +static tree
1853 +avr32_handle_acall_attribute (tree * node, tree name,
1854 + tree args ATTRIBUTE_UNUSED,
1855 + int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
1856 + {
1857 + if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE)
1858 + {
1859 + warning ("`%s' attribute not yet supported...",
1860 + IDENTIFIER_POINTER (name));
1861 + *no_add_attrs = true;
1862 + return NULL_TREE;
1863 + }
1864 +
1865 + warning ("`%s' attribute only applies to functions",
1866 + IDENTIFIER_POINTER (name));
1867 + *no_add_attrs = true;
1868 + return NULL_TREE;
1869 + }
1870 +
1871 +
1872 +/* Return 0 if the attributes for two types are incompatible, 1 if they
1873 + are compatible, and 2 if they are nearly compatible (which causes a
1874 + warning to be generated). */
1875 +
1876 +static int
1877 +avr32_comp_type_attributes (tree type1, tree type2)
1878 + {
1879 + int acall1, acall2, isr1, isr2, naked1, naked2;
1880 +
1881 + /* Check for mismatch of non-default calling convention. */
1882 + if (TREE_CODE (type1) != FUNCTION_TYPE)
1883 + return 1;
1884 +
1885 + /* Check for mismatched call attributes. */
1886 + acall1 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type1)) != NULL;
1887 + acall2 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type2)) != NULL;
1888 + naked1 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type1)) != NULL;
1889 + naked2 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type2)) != NULL;
1890 + isr1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL;
1891 + if (!isr1)
1892 + isr1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL;
1893 +
1894 + isr2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL;
1895 + if (!isr2)
1896 + isr2 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL;
1897 +
1898 + if ((acall1 && isr2)
1899 + || (acall2 && isr1) || (naked1 && isr2) || (naked2 && isr1))
1900 + return 0;
1901 +
1902 + return 1;
1903 + }
1904 +
1905 +
1906 +/* Computes the type of the current function. */
1907 +
1908 +static unsigned long
1909 +avr32_compute_func_type (void)
1910 + {
1911 + unsigned long type = AVR32_FT_UNKNOWN;
1912 + tree a;
1913 + tree attr;
1914 +
1915 + if (TREE_CODE (current_function_decl) != FUNCTION_DECL)
1916 + abort ();
1917 +
1918 + /* Decide if the current function is volatile. Such functions never
1919 + return, and many memory cycles can be saved by not storing register
1920 + values that will never be needed again. This optimization was added to
1921 + speed up context switching in a kernel application. */
1922 + if (optimize > 0
1923 + && TREE_NOTHROW (current_function_decl)
1924 + && TREE_THIS_VOLATILE (current_function_decl))
1925 + type |= AVR32_FT_VOLATILE;
1926 +
1927 + if (cfun->static_chain_decl != NULL)
1928 + type |= AVR32_FT_NESTED;
1929 +
1930 + attr = DECL_ATTRIBUTES (current_function_decl);
1931 +
1932 + a = lookup_attribute ("isr", attr);
1933 + if (a == NULL_TREE)
1934 + a = lookup_attribute ("interrupt", attr);
1935 +
1936 + if (a == NULL_TREE)
1937 + type |= AVR32_FT_NORMAL;
1938 + else
1939 + type |= avr32_isr_value (TREE_VALUE (a));
1940 +
1941 +
1942 + a = lookup_attribute ("acall", attr);
1943 + if (a != NULL_TREE)
1944 + type |= AVR32_FT_ACALL;
1945 +
1946 + a = lookup_attribute ("naked", attr);
1947 + if (a != NULL_TREE)
1948 + type |= AVR32_FT_NAKED;
1949 +
1950 + return type;
1951 + }
1952 +
1953 +/* Returns the type of the current function. */
1954 +
1955 +static unsigned long
1956 +avr32_current_func_type (void)
1957 + {
1958 + if (AVR32_FUNC_TYPE (cfun->machine->func_type) == AVR32_FT_UNKNOWN)
1959 + cfun->machine->func_type = avr32_compute_func_type ();
1960 +
1961 + return cfun->machine->func_type;
1962 + }
1963 +
1964 +/*
1965 + This target hook should return true if we should not pass type solely
1966 + in registers. The file expr.h defines a definition that is usually appropriate,
1967 + refer to expr.h for additional documentation.
1968 + */
1969 +bool
1970 +avr32_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type)
1971 + {
1972 + if (type && AGGREGATE_TYPE_P (type)
1973 + /* If the alignment is less than the size then pass in the struct on
1974 + the stack. */
1975 + && ((unsigned int) TYPE_ALIGN_UNIT (type) <
1976 + (unsigned int) int_size_in_bytes (type))
1977 + /* If we support unaligned word accesses then structs of size 4 and 8
1978 + can have any alignment and still be passed in registers. */
1979 + && !(TARGET_UNALIGNED_WORD
1980 + && (int_size_in_bytes (type) == 4
1981 + || int_size_in_bytes (type) == 8))
1982 + /* Double word structs need only a word alignment. */
1983 + && !(int_size_in_bytes (type) == 8 && TYPE_ALIGN_UNIT (type) >= 4))
1984 + return true;
1985 +
1986 + if (type && AGGREGATE_TYPE_P (type)
1987 + /* Structs of size 3,5,6,7 are always passed in registers. */
1988 + && (int_size_in_bytes (type) == 3
1989 + || int_size_in_bytes (type) == 5
1990 + || int_size_in_bytes (type) == 6 || int_size_in_bytes (type) == 7))
1991 + return true;
1992 +
1993 +
1994 + return (type && TREE_ADDRESSABLE (type));
1995 + }
1996 +
1997 +
1998 +bool
1999 +avr32_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED)
2000 + {
2001 + return true;
2002 + }
2003 +
2004 +/*
2005 + This target hook should return true if an argument at the position indicated
2006 + by cum should be passed by reference. This predicate is queried after target
2007 + independent reasons for being passed by reference, such as TREE_ADDRESSABLE (type).
2008 +
2009 + If the hook returns true, a copy of that argument is made in memory and a
2010 + pointer to the argument is passed instead of the argument itself. The pointer
2011 + is passed in whatever way is appropriate for passing a pointer to that type.
2012 + */
2013 +bool
2014 +avr32_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
2015 + enum machine_mode mode ATTRIBUTE_UNUSED,
2016 + tree type, bool named ATTRIBUTE_UNUSED)
2017 + {
2018 + return (type && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST));
2019 + }
2020 +
2021 +static int
2022 +avr32_arg_partial_bytes (CUMULATIVE_ARGS * pcum ATTRIBUTE_UNUSED,
2023 + enum machine_mode mode ATTRIBUTE_UNUSED,
2024 + tree type ATTRIBUTE_UNUSED,
2025 + bool named ATTRIBUTE_UNUSED)
2026 + {
2027 + return 0;
2028 + }
2029 +
2030 +
2031 +struct gcc_target targetm = TARGET_INITIALIZER;
2032 +
2033 +/*
2034 + Table used to convert from register number in the assembler instructions and
2035 + the register numbers used in gcc.
2036 + */
2037 +const int avr32_function_arg_reglist[] = {
2038 + INTERNAL_REGNUM (12),
2039 + INTERNAL_REGNUM (11),
2040 + INTERNAL_REGNUM (10),
2041 + INTERNAL_REGNUM (9),
2042 + INTERNAL_REGNUM (8)
2043 +};
2044 +
2045 +rtx avr32_compare_op0 = NULL_RTX;
2046 +rtx avr32_compare_op1 = NULL_RTX;
2047 +rtx avr32_compare_operator = NULL_RTX;
2048 +rtx avr32_acc_cache = NULL_RTX;
2049 +
2050 +/*
2051 + Returns nonzero if it is allowed to store a value of mode mode in hard
2052 + register number regno.
2053 + */
2054 +int
2055 +avr32_hard_regno_mode_ok (int regnr, enum machine_mode mode)
2056 + {
2057 + /* We allow only float modes in the fp-registers */
2058 + if (regnr >= FIRST_FP_REGNUM
2059 + && regnr <= LAST_FP_REGNUM && GET_MODE_CLASS (mode) != MODE_FLOAT)
2060 + {
2061 + return 0;
2062 + }
2063 +
2064 + switch (mode)
2065 + {
2066 + case DImode: /* long long */
2067 + case DFmode: /* double */
2068 + case SCmode: /* __complex__ float */
2069 + case CSImode: /* __complex__ int */
2070 + if (regnr < 4)
2071 + { /* long long int not supported in r12, sp, lr
2072 + or pc. */
2073 + return 0;
2074 + }
2075 + else
2076 + {
2077 + if (regnr % 2) /* long long int has to be refered in even
2078 + registers. */
2079 + return 0;
2080 + else
2081 + return 1;
2082 + }
2083 + case CDImode: /* __complex__ long long */
2084 + case DCmode: /* __complex__ double */
2085 + case TImode: /* 16 bytes */
2086 + if (regnr < 7)
2087 + return 0;
2088 + else if (regnr % 2)
2089 + return 0;
2090 + else
2091 + return 1;
2092 + default:
2093 + return 1;
2094 + }
2095 + }
2096 +
2097 +
2098 +int
2099 +avr32_rnd_operands (rtx add, rtx shift)
2100 + {
2101 + if (GET_CODE (shift) == CONST_INT &&
2102 + GET_CODE (add) == CONST_INT && INTVAL (shift) > 0)
2103 + {
2104 + if ((1 << (INTVAL (shift) - 1)) == INTVAL (add))
2105 + return TRUE;
2106 + }
2107 +
2108 + return FALSE;
2109 + }
2110 +
2111 +
2112 +
2113 +int
2114 +avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, const char *str)
2115 + {
2116 + switch (c)
2117 + {
2118 + case 'K':
2119 + case 'I':
2120 + {
2121 + HOST_WIDE_INT min_value = 0, max_value = 0;
2122 + char size_str[3];
2123 + int const_size;
2124 +
2125 + size_str[0] = str[2];
2126 + size_str[1] = str[3];
2127 + size_str[2] = '\0';
2128 + const_size = atoi (size_str);
2129 +
2130 + if (toupper (str[1]) == 'U')
2131 + {
2132 + min_value = 0;
2133 + max_value = (1 << const_size) - 1;
2134 + }
2135 + else if (toupper (str[1]) == 'S')
2136 + {
2137 + min_value = -(1 << (const_size - 1));
2138 + max_value = (1 << (const_size - 1)) - 1;
2139 + }
2140 +
2141 + if (c == 'I')
2142 + {
2143 + value = -value;
2144 + }
2145 +
2146 + if (value >= min_value && value <= max_value)
2147 + {
2148 + return 1;
2149 + }
2150 + break;
2151 + }
2152 + case 'M':
2153 + return avr32_mask_upper_bits_operand (GEN_INT (value), VOIDmode);
2154 + }
2155 +
2156 + return 0;
2157 + }
2158 +
2159 +
2160 +/*Compute mask of which floating-point registers needs saving upon
2161 + entry to this function*/
2162 +static unsigned long
2163 +avr32_compute_save_fp_reg_mask (void)
2164 + {
2165 + unsigned long func_type = avr32_current_func_type ();
2166 + unsigned int save_reg_mask = 0;
2167 + unsigned int reg;
2168 + unsigned int max_reg = 7;
2169 + int save_all_call_used_regs = FALSE;
2170 +
2171 + /* This only applies for hardware floating-point implementation. */
2172 + if (!TARGET_HARD_FLOAT)
2173 + return 0;
2174 +
2175 + if (IS_INTERRUPT (func_type))
2176 + {
2177 +
2178 + /* Interrupt functions must not corrupt any registers, even call
2179 + clobbered ones. If this is a leaf function we can just examine the
2180 + registers used by the RTL, but otherwise we have to assume that
2181 + whatever function is called might clobber anything, and so we have
2182 + to save all the call-clobbered registers as well. */
2183 + max_reg = 13;
2184 + save_all_call_used_regs = !current_function_is_leaf;
2185 + }
2186 +
2187 + /* All used registers used must be saved */
2188 + for (reg = 0; reg <= max_reg; reg++)
2189 + if (regs_ever_live[INTERNAL_FP_REGNUM (reg)]
2190 + || (save_all_call_used_regs
2191 + && call_used_regs[INTERNAL_FP_REGNUM (reg)]))
2192 + save_reg_mask |= (1 << reg);
2193 +
2194 + return save_reg_mask;
2195 + }
2196 +
2197 +/*Compute mask of registers which needs saving upon function entry */
2198 +static unsigned long
2199 +avr32_compute_save_reg_mask (int push)
2200 + {
2201 + unsigned long func_type;
2202 + unsigned int save_reg_mask = 0;
2203 + unsigned int reg;
2204 +
2205 + func_type = avr32_current_func_type ();
2206 +
2207 + if (IS_INTERRUPT (func_type))
2208 + {
2209 + unsigned int max_reg = 12;
2210 +
2211 +
2212 + /* Get the banking scheme for the interrupt */
2213 + switch (func_type)
2214 + {
2215 + case AVR32_FT_ISR_FULL:
2216 + max_reg = 0;
2217 + break;
2218 + case AVR32_FT_ISR_HALF:
2219 + max_reg = 7;
2220 + break;
2221 + case AVR32_FT_ISR_NONE:
2222 + max_reg = 12;
2223 + break;
2224 + }
2225 +
2226 + /* Interrupt functions must not corrupt any registers, even call
2227 + clobbered ones. If this is a leaf function we can just examine the
2228 + registers used by the RTL, but otherwise we have to assume that
2229 + whatever function is called might clobber anything, and so we have
2230 + to save all the call-clobbered registers as well. */
2231 +
2232 + /* Need not push the registers r8-r12 for AVR32A architectures, as this
2233 + is automatially done in hardware. We also do not have any shadow
2234 + registers. */
2235 + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A)
2236 + {
2237 + max_reg = 7;
2238 + func_type = AVR32_FT_ISR_NONE;
2239 + }
2240 +
2241 + /* All registers which are used and is not shadowed must be saved */
2242 + for (reg = 0; reg <= max_reg; reg++)
2243 + if (regs_ever_live[INTERNAL_REGNUM (reg)]
2244 + || (!current_function_is_leaf
2245 + && call_used_regs[INTERNAL_REGNUM (reg)]))
2246 + save_reg_mask |= (1 << reg);
2247 +
2248 + /* Check LR */
2249 + if ((regs_ever_live[LR_REGNUM]
2250 + || !current_function_is_leaf || frame_pointer_needed)
2251 + /* Only non-shadowed register models */
2252 + && (func_type == AVR32_FT_ISR_NONE))
2253 + save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM));
2254 +
2255 + /* Make sure that the GOT register is pushed. */
2256 + if (max_reg >= ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)
2257 + && current_function_uses_pic_offset_table)
2258 + save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM));
2259 +
2260 + }
2261 + else
2262 + {
2263 + int use_pushm = optimize_size;
2264 +
2265 + /* In the normal case we only need to save those registers which are
2266 + call saved and which are used by this function. */
2267 + for (reg = 0; reg <= 7; reg++)
2268 + if (regs_ever_live[INTERNAL_REGNUM (reg)]
2269 + && !call_used_regs[INTERNAL_REGNUM (reg)])
2270 + save_reg_mask |= (1 << reg);
2271 +
2272 + /* Make sure that the GOT register is pushed. */
2273 + if (current_function_uses_pic_offset_table)
2274 + save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM));
2275 +
2276 +
2277 + /* If we optimize for size and do not have anonymous arguments: use
2278 + popm/pushm always */
2279 + if (use_pushm)
2280 + {
2281 + if ((save_reg_mask & (1 << 0))
2282 + || (save_reg_mask & (1 << 1))
2283 + || (save_reg_mask & (1 << 2)) || (save_reg_mask & (1 << 3)))
2284 + save_reg_mask |= 0xf;
2285 +
2286 + if ((save_reg_mask & (1 << 4))
2287 + || (save_reg_mask & (1 << 5))
2288 + || (save_reg_mask & (1 << 6)) || (save_reg_mask & (1 << 7)))
2289 + save_reg_mask |= 0xf0;
2290 +
2291 + if ((save_reg_mask & (1 << 8)) || (save_reg_mask & (1 << 9)))
2292 + save_reg_mask |= 0x300;
2293 + }
2294 +
2295 +
2296 + /* Check LR */
2297 + if ((regs_ever_live[LR_REGNUM]
2298 + || !current_function_is_leaf
2299 + || (optimize_size
2300 + && save_reg_mask
2301 + && !current_function_calls_eh_return) || frame_pointer_needed))
2302 + {
2303 + if (push
2304 + /* Never pop LR into PC for functions which
2305 + calls __builtin_eh_return, since we need to
2306 + fix the SP after the restoring of the registers
2307 + and before returning. */
2308 + || current_function_calls_eh_return)
2309 + {
2310 + /* Push/Pop LR */
2311 + save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM));
2312 + }
2313 + else
2314 + {
2315 + /* Pop PC */
2316 + save_reg_mask |= (1 << ASM_REGNUM (PC_REGNUM));
2317 + }
2318 + }
2319 + }
2320 +
2321 +
2322 + /* Save registers so the exception handler can modify them. */
2323 + if (current_function_calls_eh_return)
2324 + {
2325 + unsigned int i;
2326 +
2327 + for (i = 0;; i++)
2328 + {
2329 + reg = EH_RETURN_DATA_REGNO (i);
2330 + if (reg == INVALID_REGNUM)
2331 + break;
2332 + save_reg_mask |= 1 << ASM_REGNUM (reg);
2333 + }
2334 + }
2335 +
2336 + return save_reg_mask;
2337 + }
2338 +
2339 +/*Compute total size in bytes of all saved registers */
2340 +static int
2341 +avr32_get_reg_mask_size (int reg_mask)
2342 + {
2343 + int reg, size;
2344 + size = 0;
2345 +
2346 + for (reg = 0; reg <= 15; reg++)
2347 + if (reg_mask & (1 << reg))
2348 + size += 4;
2349 +
2350 + return size;
2351 + }
2352 +
2353 +/*Get a register from one of the registers which are saved onto the stack
2354 + upon function entry */
2355 +
2356 +static int
2357 +avr32_get_saved_reg (int save_reg_mask)
2358 + {
2359 + unsigned int reg;
2360 +
2361 + /* Find the first register which is saved in the saved_reg_mask */
2362 + for (reg = 0; reg <= 15; reg++)
2363 + if (save_reg_mask & (1 << reg))
2364 + return reg;
2365 +
2366 + return -1;
2367 + }
2368 +
2369 +/* Return 1 if it is possible to return using a single instruction. */
2370 +int
2371 +avr32_use_return_insn (int iscond)
2372 + {
2373 + unsigned int func_type = avr32_current_func_type ();
2374 + unsigned long saved_int_regs;
2375 + unsigned long saved_fp_regs;
2376 +
2377 + /* Never use a return instruction before reload has run. */
2378 + if (!reload_completed)
2379 + return 0;
2380 +
2381 + /* Must adjust the stack for vararg functions. */
2382 + if (current_function_args_info.uses_anonymous_args)
2383 + return 0;
2384 +
2385 + /* If there a stack adjstment. */
2386 + if (get_frame_size ())
2387 + return 0;
2388 +
2389 + saved_int_regs = avr32_compute_save_reg_mask (TRUE);
2390 + saved_fp_regs = avr32_compute_save_fp_reg_mask ();
2391 +
2392 + /* Functions which have saved fp-regs on the stack can not be performed in
2393 + one instruction */
2394 + if (saved_fp_regs)
2395 + return 0;
2396 +
2397 + /* Conditional returns can not be performed in one instruction if we need
2398 + to restore registers from the stack */
2399 + if (iscond && saved_int_regs)
2400 + return 0;
2401 +
2402 + /* Conditional return can not be used for interrupt handlers. */
2403 + if (iscond && IS_INTERRUPT (func_type))
2404 + return 0;
2405 +
2406 + /* For interrupt handlers which needs to pop registers */
2407 + if (saved_int_regs && IS_INTERRUPT (func_type))
2408 + return 0;
2409 +
2410 +
2411 + /* If there are saved registers but the LR isn't saved, then we need two
2412 + instructions for the return. */
2413 + if (saved_int_regs && !(saved_int_regs & (1 << ASM_REGNUM (LR_REGNUM))))
2414 + return 0;
2415 +
2416 +
2417 + return 1;
2418 + }
2419 +
2420 +
2421 +/*Generate some function prologue info in the assembly file*/
2422 +
2423 +void
2424 +avr32_target_asm_function_prologue (FILE * f, HOST_WIDE_INT frame_size)
2425 + {
2426 + if (IS_NAKED (avr32_current_func_type ()))
2427 + fprintf (f,
2428 + "\t# Function is naked: Prologue and epilogue provided by programmer\n");
2429 +
2430 + if (IS_INTERRUPT (avr32_current_func_type ()))
2431 + {
2432 + switch (avr32_current_func_type ())
2433 + {
2434 + case AVR32_FT_ISR_FULL:
2435 + fprintf (f,
2436 + "\t# Interrupt Function: Fully shadowed register file\n");
2437 + break;
2438 + case AVR32_FT_ISR_HALF:
2439 + fprintf (f,
2440 + "\t# Interrupt Function: Half shadowed register file\n");
2441 + break;
2442 + default:
2443 + case AVR32_FT_ISR_NONE:
2444 + fprintf (f, "\t# Interrupt Function: No shadowed register file\n");
2445 + break;
2446 + }
2447 + }
2448 +
2449 +
2450 + fprintf (f, "\t# args = %i, frame = %li, pretend = %i\n",
2451 + current_function_args_size, frame_size,
2452 + current_function_pretend_args_size);
2453 +
2454 + fprintf (f, "\t# frame_needed = %i, leaf_function = %i\n",
2455 + frame_pointer_needed, current_function_is_leaf);
2456 +
2457 + fprintf (f, "\t# uses_anonymous_args = %i\n",
2458 + current_function_args_info.uses_anonymous_args);
2459 + if (current_function_calls_eh_return)
2460 + fprintf (f, "\t# Calls __builtin_eh_return.\n");
2461 +
2462 + }
2463 +
2464 +
2465 +/* Generate and emit an insn that we will recognize as a pushm or stm.
2466 + Unfortunately, since this insn does not reflect very well the actual
2467 + semantics of the operation, we need to annotate the insn for the benefit
2468 + of DWARF2 frame unwind information. */
2469 +
2470 +int avr32_convert_to_reglist16 (int reglist8_vect);
2471 +
2472 +static rtx
2473 +emit_multi_reg_push (int reglist, int usePUSHM)
2474 + {
2475 + rtx insn;
2476 + rtx dwarf;
2477 + rtx tmp;
2478 + rtx reg;
2479 + int i;
2480 + int nr_regs;
2481 + int index = 0;
2482 +
2483 + if (usePUSHM)
2484 + {
2485 + insn = emit_insn (gen_pushm (gen_rtx_CONST_INT (SImode, reglist)));
2486 + reglist = avr32_convert_to_reglist16 (reglist);
2487 + }
2488 + else
2489 + {
2490 + insn = emit_insn (gen_stm (stack_pointer_rtx,
2491 + gen_rtx_CONST_INT (SImode, reglist),
2492 + gen_rtx_CONST_INT (SImode, 1)));
2493 + }
2494 +
2495 + nr_regs = avr32_get_reg_mask_size (reglist) / 4;
2496 + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1));
2497 +
2498 + for (i = 15; i >= 0; i--)
2499 + {
2500 + if (reglist & (1 << i))
2501 + {
2502 + reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (i));
2503 + tmp = gen_rtx_SET (VOIDmode,
2504 + gen_rtx_MEM (SImode,
2505 + plus_constant (stack_pointer_rtx,
2506 + 4 * index)), reg);
2507 + RTX_FRAME_RELATED_P (tmp) = 1;
2508 + XVECEXP (dwarf, 0, 1 + index++) = tmp;
2509 + }
2510 + }
2511 +
2512 + tmp = gen_rtx_SET (SImode,
2513 + stack_pointer_rtx,
2514 + gen_rtx_PLUS (SImode,
2515 + stack_pointer_rtx,
2516 + GEN_INT (-4 * nr_regs)));
2517 + RTX_FRAME_RELATED_P (tmp) = 1;
2518 + XVECEXP (dwarf, 0, 0) = tmp;
2519 + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
2520 + REG_NOTES (insn));
2521 + return insn;
2522 + }
2523 +
2524 +
2525 +static rtx
2526 +emit_multi_fp_reg_push (int reglist)
2527 + {
2528 + rtx insn;
2529 + rtx dwarf;
2530 + rtx tmp;
2531 + rtx reg;
2532 + int i;
2533 + int nr_regs;
2534 + int index = 0;
2535 +
2536 + insn = emit_insn (gen_stm_fp (stack_pointer_rtx,
2537 + gen_rtx_CONST_INT (SImode, reglist),
2538 + gen_rtx_CONST_INT (SImode, 1)));
2539 +
2540 + nr_regs = avr32_get_reg_mask_size (reglist) / 4;
2541 + dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1));
2542 +
2543 + for (i = 15; i >= 0; i--)
2544 + {
2545 + if (reglist & (1 << i))
2546 + {
2547 + reg = gen_rtx_REG (SImode, INTERNAL_FP_REGNUM (i));
2548 + tmp = gen_rtx_SET (VOIDmode,
2549 + gen_rtx_MEM (SImode,
2550 + plus_constant (stack_pointer_rtx,
2551 + 4 * index)), reg);
2552 + RTX_FRAME_RELATED_P (tmp) = 1;
2553 + XVECEXP (dwarf, 0, 1 + index++) = tmp;
2554 + }
2555 + }
2556 +
2557 + tmp = gen_rtx_SET (SImode,
2558 + stack_pointer_rtx,
2559 + gen_rtx_PLUS (SImode,
2560 + stack_pointer_rtx,
2561 + GEN_INT (-4 * nr_regs)));
2562 + RTX_FRAME_RELATED_P (tmp) = 1;
2563 + XVECEXP (dwarf, 0, 0) = tmp;
2564 + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
2565 + REG_NOTES (insn));
2566 + return insn;
2567 + }
2568 +
2569 +rtx
2570 +avr32_gen_load_multiple (rtx * regs, int count, rtx from,
2571 + int write_back, int in_struct_p, int scalar_p)
2572 + {
2573 +
2574 + rtx result;
2575 + int i = 0, j;
2576 +
2577 + result =
2578 + gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + (write_back ? 1 : 0)));
2579 +
2580 + if (write_back)
2581 + {
2582 + XVECEXP (result, 0, 0)
2583 + = gen_rtx_SET (GET_MODE (from), from,
2584 + plus_constant (from, count * 4));
2585 + i = 1;
2586 + count++;
2587 + }
2588 +
2589 +
2590 + for (j = 0; i < count; i++, j++)
2591 + {
2592 + rtx unspec;
2593 + rtx mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4));
2594 + MEM_IN_STRUCT_P (mem) = in_struct_p;
2595 + MEM_SCALAR_P (mem) = scalar_p;
2596 + unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, mem), UNSPEC_LDM);
2597 + XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, regs[j], unspec);
2598 + }
2599 +
2600 + return result;
2601 + }
2602 +
2603 +
2604 +rtx
2605 +avr32_gen_store_multiple (rtx * regs, int count, rtx to,
2606 + int in_struct_p, int scalar_p)
2607 + {
2608 + rtx result;
2609 + int i = 0, j;
2610 +
2611 + result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2612 +
2613 + for (j = 0; i < count; i++, j++)
2614 + {
2615 + rtx mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4));
2616 + MEM_IN_STRUCT_P (mem) = in_struct_p;
2617 + MEM_SCALAR_P (mem) = scalar_p;
2618 + XVECEXP (result, 0, i)
2619 + = gen_rtx_SET (VOIDmode, mem,
2620 + gen_rtx_UNSPEC (VOIDmode,
2621 + gen_rtvec (1, regs[j]),
2622 + UNSPEC_STORE_MULTIPLE));
2623 + }
2624 +
2625 + return result;
2626 + }
2627 +
2628 +
2629 +/* Move a block of memory if it is word aligned or we support unaligned
2630 + word memory accesses. The size must be maximum 64 bytes. */
2631 +
2632 +int
2633 +avr32_gen_movmemsi (rtx * operands)
2634 + {
2635 + HOST_WIDE_INT bytes_to_go;
2636 + rtx src, dst;
2637 + rtx st_src, st_dst;
2638 + int ptr_offset = 0;
2639 + int block_size;
2640 + int dst_in_struct_p, src_in_struct_p;
2641 + int dst_scalar_p, src_scalar_p;
2642 + int unaligned;
2643 +
2644 + if (GET_CODE (operands[2]) != CONST_INT
2645 + || GET_CODE (operands[3]) != CONST_INT
2646 + || INTVAL (operands[2]) > 64
2647 + || ((INTVAL (operands[3]) & 3) && !TARGET_UNALIGNED_WORD))
2648 + return 0;
2649 +
2650 + unaligned = (INTVAL (operands[3]) & 3) != 0;
2651 +
2652 + block_size = 4;
2653 +
2654 + st_dst = XEXP (operands[0], 0);
2655 + st_src = XEXP (operands[1], 0);
2656 +
2657 + dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
2658 + dst_scalar_p = MEM_SCALAR_P (operands[0]);
2659 + src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
2660 + src_scalar_p = MEM_SCALAR_P (operands[1]);
2661 +
2662 + dst = copy_to_mode_reg (SImode, st_dst);
2663 + src = copy_to_mode_reg (SImode, st_src);
2664 +
2665 + bytes_to_go = INTVAL (operands[2]);
2666 +
2667 + while (bytes_to_go)
2668 + {
2669 + enum machine_mode move_mode;
2670 + /* (Seems to be a problem with reloads for the movti pattern so this is
2671 + disabled until that problem is resolved)
2672 + UPDATE: Problem seems to be solved now.... */
2673 + if (bytes_to_go >= GET_MODE_SIZE (TImode) && !unaligned
2674 + /* Do not emit ldm/stm for UC3 as ld.d/st.d is more optimal. */
2675 + && avr32_arch->arch_type != ARCH_TYPE_AVR32_UC)
2676 + move_mode = TImode;
2677 + else if ((bytes_to_go >= GET_MODE_SIZE (DImode)) && !unaligned)
2678 + move_mode = DImode;
2679 + else if (bytes_to_go >= GET_MODE_SIZE (SImode))
2680 + move_mode = SImode;
2681 + else
2682 + move_mode = QImode;
2683 +
2684 + {
2685 + rtx dst_mem = gen_rtx_MEM (move_mode,
2686 + gen_rtx_PLUS (SImode, dst,
2687 + GEN_INT (ptr_offset)));
2688 + rtx src_mem = gen_rtx_MEM (move_mode,
2689 + gen_rtx_PLUS (SImode, src,
2690 + GEN_INT (ptr_offset)));
2691 + ptr_offset += GET_MODE_SIZE (move_mode);
2692 + bytes_to_go -= GET_MODE_SIZE (move_mode);
2693 +
2694 + MEM_IN_STRUCT_P (dst_mem) = dst_in_struct_p;
2695 + MEM_SCALAR_P (dst_mem) = dst_scalar_p;
2696 +
2697 + MEM_IN_STRUCT_P (src_mem) = src_in_struct_p;
2698 + MEM_SCALAR_P (src_mem) = src_scalar_p;
2699 + emit_move_insn (dst_mem, src_mem);
2700 +
2701 + }
2702 + }
2703 +
2704 + return 1;
2705 + }
2706 +
2707 +
2708 +
2709 +/*Expand the prologue instruction*/
2710 +void
2711 +avr32_expand_prologue (void)
2712 + {
2713 + rtx insn, dwarf;
2714 + unsigned long saved_reg_mask, saved_fp_reg_mask;
2715 + int reglist8 = 0;
2716 +
2717 + /* Naked functions does not have a prologue */
2718 + if (IS_NAKED (avr32_current_func_type ()))
2719 + return;
2720 +
2721 + saved_reg_mask = avr32_compute_save_reg_mask (TRUE);
2722 +
2723 + if (saved_reg_mask)
2724 + {
2725 + /* Must push used registers */
2726 +
2727 + /* Should we use POPM or LDM? */
2728 + int usePUSHM = TRUE;
2729 + reglist8 = 0;
2730 + if (((saved_reg_mask & (1 << 0)) ||
2731 + (saved_reg_mask & (1 << 1)) ||
2732 + (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3))))
2733 + {
2734 + /* One of R0-R3 should at least be pushed */
2735 + if (((saved_reg_mask & (1 << 0)) &&
2736 + (saved_reg_mask & (1 << 1)) &&
2737 + (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3))))
2738 + {
2739 + /* All should be pushed */
2740 + reglist8 |= 0x01;
2741 + }
2742 + else
2743 + {
2744 + usePUSHM = FALSE;
2745 + }
2746 + }
2747 +
2748 + if (((saved_reg_mask & (1 << 4)) ||
2749 + (saved_reg_mask & (1 << 5)) ||
2750 + (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7))))
2751 + {
2752 + /* One of R4-R7 should at least be pushed */
2753 + if (((saved_reg_mask & (1 << 4)) &&
2754 + (saved_reg_mask & (1 << 5)) &&
2755 + (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7))))
2756 + {
2757 + if (usePUSHM)
2758 + /* All should be pushed */
2759 + reglist8 |= 0x02;
2760 + }
2761 + else
2762 + {
2763 + usePUSHM = FALSE;
2764 + }
2765 + }
2766 +
2767 + if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9))))
2768 + {
2769 + /* One of R8-R9 should at least be pushed */
2770 + if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9))))
2771 + {
2772 + if (usePUSHM)
2773 + /* All should be pushed */
2774 + reglist8 |= 0x04;
2775 + }
2776 + else
2777 + {
2778 + usePUSHM = FALSE;
2779 + }
2780 + }
2781 +
2782 + if (saved_reg_mask & (1 << 10))
2783 + reglist8 |= 0x08;
2784 +
2785 + if (saved_reg_mask & (1 << 11))
2786 + reglist8 |= 0x10;
2787 +
2788 + if (saved_reg_mask & (1 << 12))
2789 + reglist8 |= 0x20;
2790 +
2791 + if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM)))
2792 + {
2793 + /* Push LR */
2794 + reglist8 |= 0x40;
2795 + }
2796 +
2797 + if (usePUSHM)
2798 + {
2799 + insn = emit_multi_reg_push (reglist8, TRUE);
2800 + }
2801 + else
2802 + {
2803 + insn = emit_multi_reg_push (saved_reg_mask, FALSE);
2804 + }
2805 + RTX_FRAME_RELATED_P (insn) = 1;
2806 +
2807 + /* Prevent this instruction from being scheduled after any other
2808 + instructions. */
2809 + emit_insn (gen_blockage ());
2810 + }
2811 +
2812 + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask ();
2813 + if (saved_fp_reg_mask)
2814 + {
2815 + insn = emit_multi_fp_reg_push (saved_fp_reg_mask);
2816 + RTX_FRAME_RELATED_P (insn) = 1;
2817 +
2818 + /* Prevent this instruction from being scheduled after any other
2819 + instructions. */
2820 + emit_insn (gen_blockage ());
2821 + }
2822 +
2823 + /* Set frame pointer */
2824 + if (frame_pointer_needed)
2825 + {
2826 + insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
2827 + RTX_FRAME_RELATED_P (insn) = 1;
2828 + }
2829 +
2830 + if (get_frame_size () > 0)
2831 + {
2832 + if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks21"))
2833 + {
2834 + insn = emit_insn (gen_rtx_SET (SImode,
2835 + stack_pointer_rtx,
2836 + gen_rtx_PLUS (SImode,
2837 + stack_pointer_rtx,
2838 + gen_rtx_CONST_INT
2839 + (SImode,
2840 + -get_frame_size
2841 + ()))));
2842 + RTX_FRAME_RELATED_P (insn) = 1;
2843 + }
2844 + else
2845 + {
2846 + /* Immediate is larger than k21 We must either check if we can use
2847 + one of the pushed reegisters as temporary storage or we must
2848 + make us a temp register by pushing a register to the stack. */
2849 + rtx temp_reg, const_pool_entry, insn;
2850 + if (saved_reg_mask)
2851 + {
2852 + temp_reg =
2853 + gen_rtx_REG (SImode,
2854 + INTERNAL_REGNUM (avr32_get_saved_reg
2855 + (saved_reg_mask)));
2856 + }
2857 + else
2858 + {
2859 + temp_reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (7));
2860 + emit_move_insn (gen_rtx_MEM
2861 + (SImode,
2862 + gen_rtx_PRE_DEC (SImode, stack_pointer_rtx)),
2863 + temp_reg);
2864 + }
2865 +
2866 + const_pool_entry =
2867 + force_const_mem (SImode,
2868 + gen_rtx_CONST_INT (SImode, get_frame_size ()));
2869 + emit_move_insn (temp_reg, const_pool_entry);
2870 +
2871 + insn = emit_insn (gen_rtx_SET (SImode,
2872 + stack_pointer_rtx,
2873 + gen_rtx_MINUS (SImode,
2874 + stack_pointer_rtx,
2875 + temp_reg)));
2876 +
2877 + dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
2878 + gen_rtx_PLUS (SImode, stack_pointer_rtx,
2879 + GEN_INT (-get_frame_size ())));
2880 + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
2881 + dwarf, REG_NOTES (insn));
2882 + RTX_FRAME_RELATED_P (insn) = 1;
2883 +
2884 + if (!saved_reg_mask)
2885 + {
2886 + insn =
2887 + emit_move_insn (temp_reg,
2888 + gen_rtx_MEM (SImode,
2889 + gen_rtx_POST_INC (SImode,
2890 + gen_rtx_REG
2891 + (SImode,
2892 + 13))));
2893 + }
2894 +
2895 + /* Mark the temp register as dead */
2896 + REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, temp_reg,
2897 + REG_NOTES (insn));
2898 +
2899 +
2900 + }
2901 +
2902 + /* Prevent the the stack adjustment to be scheduled after any
2903 + instructions using the frame pointer. */
2904 + emit_insn (gen_blockage ());
2905 + }
2906 +
2907 + /* Load GOT */
2908 + if (flag_pic)
2909 + {
2910 + avr32_load_pic_register ();
2911 +
2912 + /* gcc does not know that load or call instructions might use the pic
2913 + register so it might schedule these instructions before the loading
2914 + of the pic register. To avoid this emit a barrier for now. TODO!
2915 + Find out a better way to let gcc know which instructions might use
2916 + the pic register. */
2917 + emit_insn (gen_blockage ());
2918 + }
2919 + return;
2920 + }
2921 +
2922 +void
2923 +avr32_set_return_address (rtx source, rtx scratch)
2924 + {
2925 + rtx addr;
2926 + unsigned long saved_regs;
2927 +
2928 + saved_regs = avr32_compute_save_reg_mask (TRUE);
2929 +
2930 + if (!(saved_regs & (1 << ASM_REGNUM (LR_REGNUM))))
2931 + emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source);
2932 + else
2933 + {
2934 + if (frame_pointer_needed)
2935 + addr = gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM);
2936 + else
2937 + if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks16"))
2938 + {
2939 + addr = plus_constant (stack_pointer_rtx, get_frame_size ());
2940 + }
2941 + else
2942 + {
2943 + emit_insn (gen_movsi (scratch, GEN_INT (get_frame_size ())));
2944 + addr = scratch;
2945 + }
2946 + emit_move_insn (gen_rtx_MEM (Pmode, addr), source);
2947 + }
2948 + }
2949 +
2950 +
2951 +
2952 +/* Return the length of INSN. LENGTH is the initial length computed by
2953 + attributes in the machine-description file. */
2954 +
2955 +int
2956 +avr32_adjust_insn_length (rtx insn ATTRIBUTE_UNUSED,
2957 + int length ATTRIBUTE_UNUSED)
2958 + {
2959 + return length;
2960 + }
2961 +
2962 +void
2963 +avr32_output_return_instruction (int single_ret_inst ATTRIBUTE_UNUSED,
2964 + int iscond ATTRIBUTE_UNUSED,
2965 + rtx cond ATTRIBUTE_UNUSED, rtx r12_imm)
2966 + {
2967 +
2968 + unsigned long saved_reg_mask, saved_fp_reg_mask;
2969 + int insert_ret = TRUE;
2970 + int reglist8 = 0;
2971 + int stack_adjustment = get_frame_size ();
2972 + unsigned int func_type = avr32_current_func_type ();
2973 + FILE *f = asm_out_file;
2974 +
2975 + /* Naked functions does not have an epilogue */
2976 + if (IS_NAKED (func_type))
2977 + return;
2978 +
2979 + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask ();
2980 +
2981 + saved_reg_mask = avr32_compute_save_reg_mask (FALSE);
2982 +
2983 + /* Reset frame pointer */
2984 + if (stack_adjustment > 0)
2985 + {
2986 + if (avr32_const_ok_for_constraint_p (stack_adjustment, 'I', "Is21"))
2987 + {
2988 + fprintf (f, "\tsub\tsp, %i # Reset Frame Pointer\n",
2989 + -stack_adjustment);
2990 + }
2991 + else
2992 + {
2993 + /* TODO! Is it safe to use r8 as scratch?? */
2994 + fprintf (f, "\tmov\tr8, lo(%i) # Reset Frame Pointer\n",
2995 + -stack_adjustment);
2996 + fprintf (f, "\torh\tr8, hi(%i) # Reset Frame Pointer\n",
2997 + -stack_adjustment);
2998 + fprintf (f, "\tadd\tsp, r8 # Reset Frame Pointer\n");
2999 + }
3000 + }
3001 +
3002 + if (saved_fp_reg_mask)
3003 + {
3004 + char reglist[64]; /* 64 bytes should be enough... */
3005 + avr32_make_fp_reglist_w (saved_fp_reg_mask, (char *) reglist);
3006 + fprintf (f, "\tldcm.w\tcp0, sp++, %s\n", reglist);
3007 + if (saved_fp_reg_mask & ~0xff)
3008 + {
3009 + saved_fp_reg_mask &= ~0xff;
3010 + avr32_make_fp_reglist_d (saved_fp_reg_mask, (char *) reglist);
3011 + fprintf (f, "\tldcm.d\tcp0, sp++, %s\n", reglist);
3012 + }
3013 + }
3014 +
3015 + if (saved_reg_mask)
3016 + {
3017 + /* Must pop used registers */
3018 +
3019 + /* Should we use POPM or LDM? */
3020 + int usePOPM = TRUE;
3021 + if (((saved_reg_mask & (1 << 0)) ||
3022 + (saved_reg_mask & (1 << 1)) ||
3023 + (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3))))
3024 + {
3025 + /* One of R0-R3 should at least be popped */
3026 + if (((saved_reg_mask & (1 << 0)) &&
3027 + (saved_reg_mask & (1 << 1)) &&
3028 + (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3))))
3029 + {
3030 + /* All should be popped */
3031 + reglist8 |= 0x01;
3032 + }
3033 + else
3034 + {
3035 + usePOPM = FALSE;
3036 + }
3037 + }
3038 +
3039 + if (((saved_reg_mask & (1 << 4)) ||
3040 + (saved_reg_mask & (1 << 5)) ||
3041 + (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7))))
3042 + {
3043 + /* One of R0-R3 should at least be popped */
3044 + if (((saved_reg_mask & (1 << 4)) &&
3045 + (saved_reg_mask & (1 << 5)) &&
3046 + (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7))))
3047 + {
3048 + if (usePOPM)
3049 + /* All should be popped */
3050 + reglist8 |= 0x02;
3051 + }
3052 + else
3053 + {
3054 + usePOPM = FALSE;
3055 + }
3056 + }
3057 +
3058 + if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9))))
3059 + {
3060 + /* One of R8-R9 should at least be pushed */
3061 + if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9))))
3062 + {
3063 + if (usePOPM)
3064 + /* All should be pushed */
3065 + reglist8 |= 0x04;
3066 + }
3067 + else
3068 + {
3069 + usePOPM = FALSE;
3070 + }
3071 + }
3072 +
3073 + if (saved_reg_mask & (1 << 10))
3074 + reglist8 |= 0x08;
3075 +
3076 + if (saved_reg_mask & (1 << 11))
3077 + reglist8 |= 0x10;
3078 +
3079 + if (saved_reg_mask & (1 << 12))
3080 + reglist8 |= 0x20;
3081 +
3082 + if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM)))
3083 + /* Pop LR */
3084 + reglist8 |= 0x40;
3085 +
3086 + if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM)))
3087 + /* Pop LR into PC. */
3088 + reglist8 |= 0x80;
3089 +
3090 + if (usePOPM)
3091 + {
3092 + char reglist[64]; /* 64 bytes should be enough... */
3093 + avr32_make_reglist8 (reglist8, (char *) reglist);
3094 +
3095 + if (reglist8 & 0x80)
3096 + /* This instruction is also a return */
3097 + insert_ret = FALSE;
3098 +
3099 + if (r12_imm && !insert_ret)
3100 + fprintf (f, "\tpopm\t%s, r12=%li\n", reglist, INTVAL (r12_imm));
3101 + else
3102 + fprintf (f, "\tpopm\t%s\n", reglist);
3103 +
3104 + }
3105 + else
3106 + {
3107 + char reglist[64]; /* 64 bytes should be enough... */
3108 + avr32_make_reglist16 (saved_reg_mask, (char *) reglist);
3109 + if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM)))
3110 + /* This instruction is also a return */
3111 + insert_ret = FALSE;
3112 +
3113 + if (r12_imm && !insert_ret)
3114 + fprintf (f, "\tldm\tsp++, %s, r12=%li\n", reglist,
3115 + INTVAL (r12_imm));
3116 + else
3117 + fprintf (f, "\tldm\tsp++, %s\n", reglist);
3118 +
3119 + }
3120 +
3121 + }
3122 +
3123 + /* Stack adjustment for exception handler. */
3124 + if (current_function_calls_eh_return)
3125 + fprintf (f, "\tadd\tsp, r%d\n", ASM_REGNUM (EH_RETURN_STACKADJ_REGNO));
3126 +
3127 +
3128 + if (IS_INTERRUPT (func_type))
3129 + {
3130 + fprintf (f, "\trete\n");
3131 + }
3132 + else if (insert_ret)
3133 + {
3134 + if (r12_imm)
3135 + fprintf (f, "\tretal\t%li\n", INTVAL (r12_imm));
3136 + else
3137 + fprintf (f, "\tretal\tr12\n");
3138 + }
3139 + }
3140 +
3141 +/* Function for converting a fp-register mask to a
3142 + reglistCPD8 register list string. */
3143 +void
3144 +avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string)
3145 + {
3146 + int i;
3147 +
3148 + /* Make sure reglist_string is empty */
3149 + reglist_string[0] = '\0';
3150 +
3151 + for (i = 0; i < NUM_FP_REGS; i += 2)
3152 + {
3153 + if (reglist_mask & (1 << i))
3154 + {
3155 + strlen (reglist_string) ?
3156 + sprintf (reglist_string, "%s, %s-%s", reglist_string,
3157 + reg_names[INTERNAL_FP_REGNUM (i)],
3158 + reg_names[INTERNAL_FP_REGNUM (i + 1)]) :
3159 + sprintf (reglist_string, "%s-%s",
3160 + reg_names[INTERNAL_FP_REGNUM (i)],
3161 + reg_names[INTERNAL_FP_REGNUM (i + 1)]);
3162 + }
3163 + }
3164 + }
3165 +
3166 +/* Function for converting a fp-register mask to a
3167 + reglistCP8 register list string. */
3168 +void
3169 +avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string)
3170 + {
3171 + int i;
3172 +
3173 + /* Make sure reglist_string is empty */
3174 + reglist_string[0] = '\0';
3175 +
3176 + for (i = 0; i < NUM_FP_REGS; ++i)
3177 + {
3178 + if (reglist_mask & (1 << i))
3179 + {
3180 + strlen (reglist_string) ?
3181 + sprintf (reglist_string, "%s, %s", reglist_string,
3182 + reg_names[INTERNAL_FP_REGNUM (i)]) :
3183 + sprintf (reglist_string, "%s", reg_names[INTERNAL_FP_REGNUM (i)]);
3184 + }
3185 + }
3186 + }
3187 +
3188 +void
3189 +avr32_make_reglist16 (int reglist16_vect, char *reglist16_string)
3190 + {
3191 + int i;
3192 +
3193 + /* Make sure reglist16_string is empty */
3194 + reglist16_string[0] = '\0';
3195 +
3196 + for (i = 0; i < 16; ++i)
3197 + {
3198 + if (reglist16_vect & (1 << i))
3199 + {
3200 + strlen (reglist16_string) ?
3201 + sprintf (reglist16_string, "%s, %s", reglist16_string,
3202 + reg_names[INTERNAL_REGNUM (i)]) :
3203 + sprintf (reglist16_string, "%s", reg_names[INTERNAL_REGNUM (i)]);
3204 + }
3205 + }
3206 + }
3207 +
3208 +int
3209 +avr32_convert_to_reglist16 (int reglist8_vect)
3210 + {
3211 + int reglist16_vect = 0;
3212 + if (reglist8_vect & 0x1)
3213 + reglist16_vect |= 0xF;
3214 + if (reglist8_vect & 0x2)
3215 + reglist16_vect |= 0xF0;
3216 + if (reglist8_vect & 0x4)
3217 + reglist16_vect |= 0x300;
3218 + if (reglist8_vect & 0x8)
3219 + reglist16_vect |= 0x400;
3220 + if (reglist8_vect & 0x10)
3221 + reglist16_vect |= 0x800;
3222 + if (reglist8_vect & 0x20)
3223 + reglist16_vect |= 0x1000;
3224 + if (reglist8_vect & 0x40)
3225 + reglist16_vect |= 0x4000;
3226 + if (reglist8_vect & 0x80)
3227 + reglist16_vect |= 0x8000;
3228 +
3229 + return reglist16_vect;
3230 + }
3231 +
3232 +void
3233 +avr32_make_reglist8 (int reglist8_vect, char *reglist8_string)
3234 + {
3235 + /* Make sure reglist8_string is empty */
3236 + reglist8_string[0] = '\0';
3237 +
3238 + if (reglist8_vect & 0x1)
3239 + sprintf (reglist8_string, "r0-r3");
3240 + if (reglist8_vect & 0x2)
3241 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r4-r7",
3242 + reglist8_string) :
3243 + sprintf (reglist8_string, "r4-r7");
3244 + if (reglist8_vect & 0x4)
3245 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r8-r9",
3246 + reglist8_string) :
3247 + sprintf (reglist8_string, "r8-r9");
3248 + if (reglist8_vect & 0x8)
3249 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r10",
3250 + reglist8_string) :
3251 + sprintf (reglist8_string, "r10");
3252 + if (reglist8_vect & 0x10)
3253 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r11",
3254 + reglist8_string) :
3255 + sprintf (reglist8_string, "r11");
3256 + if (reglist8_vect & 0x20)
3257 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, r12",
3258 + reglist8_string) :
3259 + sprintf (reglist8_string, "r12");
3260 + if (reglist8_vect & 0x40)
3261 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, lr",
3262 + reglist8_string) :
3263 + sprintf (reglist8_string, "lr");
3264 + if (reglist8_vect & 0x80)
3265 + strlen (reglist8_string) ? sprintf (reglist8_string, "%s, pc",
3266 + reglist8_string) :
3267 + sprintf (reglist8_string, "pc");
3268 + }
3269 +
3270 +int
3271 +avr32_eh_return_data_regno (int n)
3272 + {
3273 + if (n >= 0 && n <= 3)
3274 + return 8 + n;
3275 + else
3276 + return INVALID_REGNUM;
3277 + }
3278 +
3279 +/* Compute the distance from register FROM to register TO.
3280 + These can be the arg pointer, the frame pointer or
3281 + the stack pointer.
3282 + Typical stack layout looks like this:
3283 +
3284 + old stack pointer -> | |
3285 + ----
3286 + | | \
3287 + | | saved arguments for
3288 + | | vararg functions
3289 + arg_pointer -> | | /
3290 + --
3291 + | | \
3292 + | | call saved
3293 + | | registers
3294 + | | /
3295 + frame ptr -> --
3296 + | | \
3297 + | | local
3298 + | | variables
3299 + stack ptr --> | | /
3300 + --
3301 + | | \
3302 + | | outgoing
3303 + | | arguments
3304 + | | /
3305 + --
3306 +
3307 + For a given funciton some or all of these stack compomnents
3308 + may not be needed, giving rise to the possibility of
3309 + eliminating some of the registers.
3310 +
3311 + The values returned by this function must reflect the behaviour
3312 + of avr32_expand_prologue() and avr32_compute_save_reg_mask().
3313 +
3314 + The sign of the number returned reflects the direction of stack
3315 + growth, so the values are positive for all eliminations except
3316 + from the soft frame pointer to the hard frame pointer. */
3317 +
3318 +
3319 +int
3320 +avr32_initial_elimination_offset (int from, int to)
3321 + {
3322 + int i;
3323 + int call_saved_regs = 0;
3324 + unsigned long saved_reg_mask, saved_fp_reg_mask;
3325 + unsigned int local_vars = get_frame_size ();
3326 +
3327 + saved_reg_mask = avr32_compute_save_reg_mask (TRUE);
3328 + saved_fp_reg_mask = avr32_compute_save_fp_reg_mask ();
3329 +
3330 + for (i = 0; i < 16; ++i)
3331 + {
3332 + if (saved_reg_mask & (1 << i))
3333 + call_saved_regs += 4;
3334 + }
3335 +
3336 + for (i = 0; i < NUM_FP_REGS; ++i)
3337 + {
3338 + if (saved_fp_reg_mask & (1 << i))
3339 + call_saved_regs += 4;
3340 + }
3341 +
3342 + switch (from)
3343 + {
3344 + case ARG_POINTER_REGNUM:
3345 + switch (to)
3346 + {
3347 + case STACK_POINTER_REGNUM:
3348 + return call_saved_regs + local_vars;
3349 + case FRAME_POINTER_REGNUM:
3350 + return call_saved_regs;
3351 + default:
3352 + abort ();
3353 + }
3354 + case FRAME_POINTER_REGNUM:
3355 + switch (to)
3356 + {
3357 + case STACK_POINTER_REGNUM:
3358 + return local_vars;
3359 + default:
3360 + abort ();
3361 + }
3362 + default:
3363 + abort ();
3364 + }
3365 + }
3366 +
3367 +
3368 +/*
3369 + Returns a rtx used when passing the next argument to a function.
3370 + avr32_init_cumulative_args() and avr32_function_arg_advance() sets witch
3371 + register to use.
3372 + */
3373 +rtx
3374 +avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode,
3375 + tree type, int named)
3376 + {
3377 + int index = -1;
3378 +
3379 + HOST_WIDE_INT arg_size, arg_rsize;
3380 + if (type)
3381 + {
3382 + arg_size = int_size_in_bytes (type);
3383 + }
3384 + else
3385 + {
3386 + arg_size = GET_MODE_SIZE (mode);
3387 + }
3388 + arg_rsize = PUSH_ROUNDING (arg_size);
3389 +
3390 + /*
3391 + The last time this macro is called, it is called with mode == VOIDmode,
3392 + and its result is passed to the call or call_value pattern as operands 2
3393 + and 3 respectively. */
3394 + if (mode == VOIDmode)
3395 + {
3396 + return gen_rtx_CONST_INT (SImode, 22); /* ToDo: fixme. */
3397 + }
3398 +
3399 + if ((*targetm.calls.must_pass_in_stack) (mode, type) || !named)
3400 + {
3401 + return NULL_RTX;
3402 + }
3403 +
3404 + if (arg_rsize == 8)
3405 + {
3406 + /* use r11:r10 or r9:r8. */
3407 + if (!(GET_USED_INDEX (cum, 1) || GET_USED_INDEX (cum, 2)))
3408 + index = 1;
3409 + else if (!(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4)))
3410 + index = 3;
3411 + else
3412 + index = -1;
3413 + }
3414 + else if (arg_rsize == 4)
3415 + { /* Use first available register */
3416 + index = 0;
3417 + while (index <= LAST_CUM_REG_INDEX && GET_USED_INDEX (cum, index))
3418 + index++;
3419 + if (index > LAST_CUM_REG_INDEX)
3420 + index = -1;
3421 + }
3422 +
3423 + SET_REG_INDEX (cum, index);
3424 +
3425 + if (GET_REG_INDEX (cum) >= 0)
3426 + return gen_rtx_REG (mode,
3427 + avr32_function_arg_reglist[GET_REG_INDEX (cum)]);
3428 +
3429 + return NULL_RTX;
3430 + }
3431 +
3432 +/*
3433 + Set the register used for passing the first argument to a function.
3434 + */
3435 +void
3436 +avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
3437 + rtx libname ATTRIBUTE_UNUSED,
3438 + tree fndecl ATTRIBUTE_UNUSED)
3439 + {
3440 + /* Set all registers as unused. */
3441 + SET_INDEXES_UNUSED (cum);
3442 +
3443 + /* Reset uses_anonymous_args */
3444 + cum->uses_anonymous_args = 0;
3445 +
3446 + /* Reset size of stack pushed arguments */
3447 + cum->stack_pushed_args_size = 0;
3448 + }
3449 +
3450 +/*
3451 + Set register used for passing the next argument to a function. Only the
3452 + Scratch Registers are used.
3453 +
3454 + number name
3455 + 15 r15 PC
3456 + 14 r14 LR
3457 + 13 r13 _SP_________
3458 + FIRST_CUM_REG 12 r12 _||_
3459 + 10 r11 ||
3460 + 11 r10 _||_ Scratch Registers
3461 + 8 r9 ||
3462 + LAST_SCRATCH_REG 9 r8 _\/_________
3463 + 6 r7 /\
3464 + 7 r6 ||
3465 + 4 r5 ||
3466 + 5 r4 ||
3467 + 2 r3 ||
3468 + 3 r2 ||
3469 + 0 r1 ||
3470 + 1 r0 _||_________
3471 +
3472 + */
3473 +void
3474 +avr32_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode,
3475 + tree type, int named ATTRIBUTE_UNUSED)
3476 + {
3477 + HOST_WIDE_INT arg_size, arg_rsize;
3478 +
3479 + if (type)
3480 + {
3481 + arg_size = int_size_in_bytes (type);
3482 + }
3483 + else
3484 + {
3485 + arg_size = GET_MODE_SIZE (mode);
3486 + }
3487 + arg_rsize = PUSH_ROUNDING (arg_size);
3488 +
3489 + /* It the argument had to be passed in stack, no register is used. */
3490 + if ((*targetm.calls.must_pass_in_stack) (mode, type))
3491 + {
3492 + cum->stack_pushed_args_size += PUSH_ROUNDING (int_size_in_bytes (type));
3493 + return;
3494 + }
3495 +
3496 + /* Mark the used registers as "used". */
3497 + if (GET_REG_INDEX (cum) >= 0)
3498 + {
3499 + SET_USED_INDEX (cum, GET_REG_INDEX (cum));
3500 + if (arg_rsize == 8)
3501 + {
3502 + SET_USED_INDEX (cum, (GET_REG_INDEX (cum) + 1));
3503 + }
3504 + }
3505 + else
3506 + {
3507 + /* Had to use stack */
3508 + cum->stack_pushed_args_size += arg_rsize;
3509 + }
3510 + }
3511 +
3512 +/*
3513 + Defines witch direction to go to find the next register to use if the
3514 + argument is larger then one register or for arguments shorter than an
3515 + int which is not promoted, such as the last part of structures with
3516 + size not a multiple of 4. */
3517 +enum direction
3518 +avr32_function_arg_padding (enum machine_mode mode ATTRIBUTE_UNUSED,
3519 + tree type)
3520 + {
3521 + /* Pad upward for all aggregates except byte and halfword sized aggregates
3522 + which can be passed in registers. */
3523 + if (type
3524 + && AGGREGATE_TYPE_P (type)
3525 + && (int_size_in_bytes (type) != 1)
3526 + && !((int_size_in_bytes (type) == 2)
3527 + && TYPE_ALIGN_UNIT (type) >= 2)
3528 + && (int_size_in_bytes (type) & 0x3))
3529 + {
3530 + return upward;
3531 + }
3532 +
3533 + return downward;
3534 + }
3535 +
3536 +/*
3537 + Return a rtx used for the return value from a function call.
3538 + */
3539 +rtx
3540 +avr32_function_value (tree type, tree func, bool outgoing ATTRIBUTE_UNUSED)
3541 + {
3542 + if (avr32_return_in_memory (type, func))
3543 + return NULL_RTX;
3544 +
3545 + if (int_size_in_bytes (type) <= 4)
3546 + if (avr32_return_in_msb (type))
3547 + /* Aggregates of size less than a word which does align the data in the
3548 + MSB must use SImode for r12. */
3549 + return gen_rtx_REG (SImode, RET_REGISTER);
3550 + else
3551 + return gen_rtx_REG (TYPE_MODE (type), RET_REGISTER);
3552 + else if (int_size_in_bytes (type) <= 8)
3553 + return gen_rtx_REG (TYPE_MODE (type), INTERNAL_REGNUM (11));
3554 +
3555 + return NULL_RTX;
3556 + }
3557 +
3558 +/*
3559 + Return a rtx used for the return value from a library function call.
3560 + */
3561 +rtx
3562 +avr32_libcall_value (enum machine_mode mode)
3563 + {
3564 +
3565 + if (GET_MODE_SIZE (mode) <= 4)
3566 + return gen_rtx_REG (mode, RET_REGISTER);
3567 + else if (GET_MODE_SIZE (mode) <= 8)
3568 + return gen_rtx_REG (mode, INTERNAL_REGNUM (11));
3569 + else
3570 + return NULL_RTX;
3571 + }
3572 +
3573 +/* Return TRUE if X references a SYMBOL_REF. */
3574 +int
3575 +symbol_mentioned_p (rtx x)
3576 + {
3577 + const char *fmt;
3578 + int i;
3579 +
3580 + if (GET_CODE (x) == SYMBOL_REF)
3581 + return 1;
3582 +
3583 + fmt = GET_RTX_FORMAT (GET_CODE (x));
3584 +
3585 + for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3586 + {
3587 + if (fmt[i] == 'E')
3588 + {
3589 + int j;
3590 +
3591 + for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3592 + if (symbol_mentioned_p (XVECEXP (x, i, j)))
3593 + return 1;
3594 + }
3595 + else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
3596 + return 1;
3597 + }
3598 +
3599 + return 0;
3600 + }
3601 +
3602 +/* Return TRUE if X references a LABEL_REF. */
3603 +int
3604 +label_mentioned_p (rtx x)
3605 + {
3606 + const char *fmt;
3607 + int i;
3608 +
3609 + if (GET_CODE (x) == LABEL_REF)
3610 + return 1;
3611 +
3612 + fmt = GET_RTX_FORMAT (GET_CODE (x));
3613 + for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3614 + {
3615 + if (fmt[i] == 'E')
3616 + {
3617 + int j;
3618 +
3619 + for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3620 + if (label_mentioned_p (XVECEXP (x, i, j)))
3621 + return 1;
3622 + }
3623 + else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
3624 + return 1;
3625 + }
3626 +
3627 + return 0;
3628 + }
3629 +
3630 +
3631 +int
3632 +avr32_legitimate_pic_operand_p (rtx x)
3633 + {
3634 +
3635 + /* We can't have const, this must be broken down to a symbol. */
3636 + if (GET_CODE (x) == CONST)
3637 + return FALSE;
3638 +
3639 + /* Can't access symbols or labels via the constant pool either */
3640 + if ((GET_CODE (x) == SYMBOL_REF
3641 + && CONSTANT_POOL_ADDRESS_P (x)
3642 + && (symbol_mentioned_p (get_pool_constant (x))
3643 + || label_mentioned_p (get_pool_constant (x)))))
3644 + return FALSE;
3645 +
3646 + return TRUE;
3647 + }
3648 +
3649 +
3650 +rtx
3651 +legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
3652 + rtx reg)
3653 + {
3654 +
3655 + if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
3656 + {
3657 + int subregs = 0;
3658 +
3659 + if (reg == 0)
3660 + {
3661 + if (no_new_pseudos)
3662 + abort ();
3663 + else
3664 + reg = gen_reg_rtx (Pmode);
3665 +
3666 + subregs = 1;
3667 + }
3668 +
3669 + emit_move_insn (reg, orig);
3670 +
3671 + /* Only set current function as using pic offset table if flag_pic is
3672 + set. This is because this function is also used if
3673 + TARGET_HAS_ASM_ADDR_PSEUDOS is set. */
3674 + if (flag_pic)
3675 + current_function_uses_pic_offset_table = 1;
3676 +
3677 + /* Put a REG_EQUAL note on this insn, so that it can be optimized by
3678 + loop. */
3679 + return reg;
3680 + }
3681 + else if (GET_CODE (orig) == CONST)
3682 + {
3683 + rtx base, offset;
3684 +
3685 + if (flag_pic
3686 + && GET_CODE (XEXP (orig, 0)) == PLUS
3687 + && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
3688 + return orig;
3689 +
3690 + if (reg == 0)
3691 + {
3692 + if (no_new_pseudos)
3693 + abort ();
3694 + else
3695 + reg = gen_reg_rtx (Pmode);
3696 + }
3697 +
3698 + if (GET_CODE (XEXP (orig, 0)) == PLUS)
3699 + {
3700 + base =
3701 + legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
3702 + offset =
3703 + legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
3704 + base == reg ? 0 : reg);
3705 + }
3706 + else
3707 + abort ();
3708 +
3709 + if (GET_CODE (offset) == CONST_INT)
3710 + {
3711 + /* The base register doesn't really matter, we only want to test
3712 + the index for the appropriate mode. */
3713 + if (!avr32_const_ok_for_constraint_p (INTVAL (offset), 'I', "Is21"))
3714 + {
3715 + if (!no_new_pseudos)
3716 + offset = force_reg (Pmode, offset);
3717 + else
3718 + abort ();
3719 + }
3720 +
3721 + if (GET_CODE (offset) == CONST_INT)
3722 + return plus_constant (base, INTVAL (offset));
3723 + }
3724 +
3725 + return gen_rtx_PLUS (Pmode, base, offset);
3726 + }
3727 +
3728 + return orig;
3729 + }
3730 +
3731 +/* Generate code to load the PIC register. */
3732 +void
3733 +avr32_load_pic_register (void)
3734 + {
3735 + rtx l1, pic_tmp;
3736 + rtx global_offset_table;
3737 +
3738 + if ((current_function_uses_pic_offset_table == 0) || TARGET_NO_INIT_GOT)
3739 + return;
3740 +
3741 + if (!flag_pic)
3742 + abort ();
3743 +
3744 + l1 = gen_label_rtx ();
3745 +
3746 + global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
3747 + pic_tmp =
3748 + gen_rtx_CONST (Pmode,
3749 + gen_rtx_MINUS (SImode, gen_rtx_LABEL_REF (Pmode, l1),
3750 + global_offset_table));
3751 + emit_insn (gen_pic_load_addr
3752 + (pic_offset_table_rtx, force_const_mem (SImode, pic_tmp)));
3753 + emit_insn (gen_pic_compute_got_from_pc (pic_offset_table_rtx, l1));
3754 +
3755 + /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp
3756 + can cause life info to screw up. */
3757 + emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
3758 + }
3759 +
3760 +
3761 +
3762 +/* This hook should return true if values of type type are returned at the most
3763 + significant end of a register (in other words, if they are padded at the
3764 + least significant end). You can assume that type is returned in a register;
3765 + the caller is required to check this. Note that the register provided by
3766 + FUNCTION_VALUE must be able to hold the complete return value. For example,
3767 + if a 1-, 2- or 3-byte structure is returned at the most significant end of a
3768 + 4-byte register, FUNCTION_VALUE should provide an SImode rtx. */
3769 +bool
3770 +avr32_return_in_msb (tree type ATTRIBUTE_UNUSED)
3771 + {
3772 + /* if ( AGGREGATE_TYPE_P (type) ) if ((int_size_in_bytes(type) == 1) ||
3773 + ((int_size_in_bytes(type) == 2) && TYPE_ALIGN_UNIT(type) >= 2)) return
3774 + false; else return true; */
3775 +
3776 + return false;
3777 + }
3778 +
3779 +
3780 +/*
3781 + Returns one if a certain function value is going to be returned in memory
3782 + and zero if it is going to be returned in a register.
3783 +
3784 + BLKmode and all other modes that is larger than 64 bits are returned in
3785 + memory.
3786 + */
3787 +bool
3788 +avr32_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
3789 + {
3790 + if (TYPE_MODE (type) == VOIDmode)
3791 + return false;
3792 +
3793 + if (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
3794 + || int_size_in_bytes (type) == -1)
3795 + {
3796 + return true;
3797 + }
3798 +
3799 + /* If we have an aggregate then use the same mechanism as when checking if
3800 + it should be passed on the stack. */
3801 + if (type
3802 + && AGGREGATE_TYPE_P (type)
3803 + && (*targetm.calls.must_pass_in_stack) (TYPE_MODE (type), type))
3804 + return true;
3805 +
3806 + return false;
3807 + }
3808 +
3809 +
3810 +/* Output the constant part of the trampoline.
3811 + lddpc r0, pc[0x8:e] ; load static chain register
3812 + lddpc pc, pc[0x8:e] ; jump to subrutine
3813 + .long 0 ; Address to static chain,
3814 + ; filled in by avr32_initialize_trampoline()
3815 + .long 0 ; Address to subrutine,
3816 + ; filled in by avr32_initialize_trampoline()
3817 + */
3818 +void
3819 +avr32_trampoline_template (FILE * file)
3820 + {
3821 + fprintf (file, "\tlddpc r0, pc[8]\n");
3822 + fprintf (file, "\tlddpc pc, pc[8]\n");
3823 + /* make room for the address of the static chain. */
3824 + fprintf (file, "\t.long\t0\n");
3825 + /* make room for the address to the subrutine. */
3826 + fprintf (file, "\t.long\t0\n");
3827 + }
3828 +
3829 +
3830 +/*
3831 + Initialize the variable parts of a trampoline.
3832 + */
3833 +void
3834 +avr32_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
3835 + {
3836 + /* Store the address to the static chain. */
3837 + emit_move_insn (gen_rtx_MEM
3838 + (SImode, plus_constant (addr, TRAMPOLINE_SIZE - 4)),
3839 + static_chain);
3840 +
3841 + /* Store the address to the function. */
3842 + emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, TRAMPOLINE_SIZE)),
3843 + fnaddr);
3844 +
3845 + emit_insn (gen_cache (gen_rtx_REG (SImode, 13),
3846 + gen_rtx_CONST_INT (SImode,
3847 + AVR32_CACHE_INVALIDATE_ICACHE)));
3848 + }
3849 +
3850 +/* Return nonzero if X is valid as an addressing register. */
3851 +int
3852 +avr32_address_register_rtx_p (rtx x, int strict_p)
3853 + {
3854 + int regno;
3855 +
3856 + if (!register_operand(x, GET_MODE(x)))
3857 + return 0;
3858 +
3859 + /* If strict we require the register to be a hard register. */
3860 + if (strict_p
3861 + && !REG_P(x))
3862 + return 0;
3863 +
3864 + regno = REGNO (x);
3865 +
3866 + if (strict_p)
3867 + return REGNO_OK_FOR_BASE_P (regno);
3868 +
3869 + return (regno <= LAST_REGNUM || regno >= FIRST_PSEUDO_REGISTER);
3870 + }
3871 +
3872 +/* Return nonzero if INDEX is valid for an address index operand. */
3873 +int
3874 +avr32_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
3875 + {
3876 + enum rtx_code code = GET_CODE (index);
3877 +
3878 + if (GET_MODE_SIZE (mode) > 8)
3879 + return 0;
3880 +
3881 + /* Standard coprocessor addressing modes. */
3882 + if (code == CONST_INT)
3883 + {
3884 + if (TARGET_HARD_FLOAT && GET_MODE_CLASS (mode) == MODE_FLOAT)
3885 + /* Coprocessor mem insns has a smaller reach than ordinary mem insns */
3886 + return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ku14");
3887 + else
3888 + return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ks16");
3889 + }
3890 +
3891 + if (avr32_address_register_rtx_p (index, strict_p))
3892 + return 1;
3893 +
3894 + if (code == MULT)
3895 + {
3896 + rtx xiop0 = XEXP (index, 0);
3897 + rtx xiop1 = XEXP (index, 1);
3898 + return ((avr32_address_register_rtx_p (xiop0, strict_p)
3899 + && power_of_two_operand (xiop1, SImode)
3900 + && (INTVAL (xiop1) <= 8))
3901 + || (avr32_address_register_rtx_p (xiop1, strict_p)
3902 + && power_of_two_operand (xiop0, SImode)
3903 + && (INTVAL (xiop0) <= 8)));
3904 + }
3905 + else if (code == ASHIFT)
3906 + {
3907 + rtx op = XEXP (index, 1);
3908 +
3909 + return (avr32_address_register_rtx_p (XEXP (index, 0), strict_p)
3910 + && GET_CODE (op) == CONST_INT
3911 + && INTVAL (op) > 0 && INTVAL (op) <= 3);
3912 + }
3913 +
3914 + return 0;
3915 + }
3916 +
3917 +/*
3918 + Used in the GO_IF_LEGITIMATE_ADDRESS macro. Returns a nonzero value if
3919 + the RTX x is a legitimate memory address.
3920 +
3921 + Returns NO_REGS if the address is not legatime, GENERAL_REGS or ALL_REGS
3922 + if it is.
3923 + */
3924 +
3925 +/* Forward declaration*/
3926 +int is_minipool_label (rtx label);
3927 +
3928 +int
3929 +avr32_legitimate_address (enum machine_mode mode, rtx x, int strict)
3930 + {
3931 +
3932 + switch (GET_CODE (x))
3933 + {
3934 + case REG:
3935 + return avr32_address_register_rtx_p (x, strict);
3936 + case CONST:
3937 + {
3938 + rtx label = avr32_find_symbol (x);
3939 + if (label
3940 + &&
3941 + ((CONSTANT_POOL_ADDRESS_P (label)
3942 + && !(flag_pic
3943 + && (symbol_mentioned_p (get_pool_constant (label))
3944 + || label_mentioned_p (get_pool_constant (label)))))
3945 + /* TODO! Can this ever happen??? */
3946 + || ((GET_CODE (label) == LABEL_REF)
3947 + && GET_CODE (XEXP (label, 0)) == CODE_LABEL
3948 + && is_minipool_label (XEXP (label, 0)))))
3949 + {
3950 + return TRUE;
3951 + }
3952 + }
3953 + break;
3954 + case LABEL_REF:
3955 + if (GET_CODE (XEXP (x, 0)) == CODE_LABEL
3956 + && is_minipool_label (XEXP (x, 0)))
3957 + {
3958 + return TRUE;
3959 + }
3960 + break;
3961 + case SYMBOL_REF:
3962 + {
3963 + if (CONSTANT_POOL_ADDRESS_P (x)
3964 + && !(flag_pic
3965 + && (symbol_mentioned_p (get_pool_constant (x))
3966 + || label_mentioned_p (get_pool_constant (x)))))
3967 + return TRUE;
3968 + /*
3969 + A symbol_ref is only legal if it is a function. If all of them are
3970 + legal, a pseudo reg that is a constant will be replaced by a
3971 + symbol_ref and make illegale code. SYMBOL_REF_FLAG is set by
3972 + ENCODE_SECTION_INFO. */
3973 + else if (SYMBOL_REF_RCALL_FUNCTION_P (x))
3974 + return TRUE;
3975 + break;
3976 + }
3977 + case PRE_DEC: /* (pre_dec (...)) */
3978 + case POST_INC: /* (post_inc (...)) */
3979 + return avr32_address_register_rtx_p (XEXP (x, 0), strict);
3980 + case PLUS: /* (plus (...) (...)) */
3981 + {
3982 + rtx xop0 = XEXP (x, 0);
3983 + rtx xop1 = XEXP (x, 1);
3984 +
3985 + return ((avr32_address_register_rtx_p (xop0, strict)
3986 + && avr32_legitimate_index_p (mode, xop1, strict))
3987 + || (avr32_address_register_rtx_p (xop1, strict)
3988 + && avr32_legitimate_index_p (mode, xop0, strict)));
3989 + }
3990 + default:
3991 + break;
3992 + }
3993 +
3994 + return FALSE;
3995 + }
3996 +
3997 +
3998 +int
3999 +avr32_const_double_immediate (rtx value)
4000 + {
4001 + HOST_WIDE_INT hi, lo;
4002 +
4003 + if (GET_CODE (value) != CONST_DOUBLE)
4004 + return FALSE;
4005 +
4006 + if (SCALAR_FLOAT_MODE_P (GET_MODE (value)))
4007 + {
4008 + HOST_WIDE_INT target_float[2];
4009 + hi = lo = 0;
4010 + real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (value),
4011 + GET_MODE (value));
4012 + lo = target_float[0];
4013 + hi = target_float[1];
4014 + }
4015 + else
4016 + {
4017 + hi = CONST_DOUBLE_HIGH (value);
4018 + lo = CONST_DOUBLE_LOW (value);
4019 + }
4020 +
4021 + if (avr32_const_ok_for_constraint_p (lo, 'K', "Ks21")
4022 + && (GET_MODE (value) == SFmode
4023 + || avr32_const_ok_for_constraint_p (hi, 'K', "Ks21")))
4024 + {
4025 + return TRUE;
4026 + }
4027 +
4028 + return FALSE;
4029 + }
4030 +
4031 +
4032 +int
4033 +avr32_legitimate_constant_p (rtx x)
4034 + {
4035 + switch (GET_CODE (x))
4036 + {
4037 + case CONST_INT:
4038 + /* Check if we should put large immediate into constant pool
4039 + or load them directly with mov/orh.*/
4040 + if (!avr32_imm_in_const_pool)
4041 + return 1;
4042 +
4043 + return avr32_const_ok_for_constraint_p (INTVAL (x), 'K', "Ks21");
4044 + case CONST_DOUBLE:
4045 + /* Check if we should put large immediate into constant pool
4046 + or load them directly with mov/orh.*/
4047 + if (!avr32_imm_in_const_pool)
4048 + return 1;
4049 +
4050 + if (GET_MODE (x) == SFmode
4051 + || GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
4052 + return avr32_const_double_immediate (x);
4053 + else
4054 + return 0;
4055 + case LABEL_REF:
4056 + return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS;
4057 + case SYMBOL_REF:
4058 + return flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS;
4059 + case CONST:
4060 + case HIGH:
4061 + case CONST_VECTOR:
4062 + return 0;
4063 + default:
4064 + printf ("%s():\n", __FUNCTION__);
4065 + debug_rtx (x);
4066 + return 1;
4067 + }
4068 + }
4069 +
4070 +
4071 +/* Strip any special encoding from labels */
4072 +const char *
4073 +avr32_strip_name_encoding (const char *name)
4074 +{
4075 + const char *stripped = name;
4076 +
4077 + while (1)
4078 + {
4079 + switch (stripped[0])
4080 + {
4081 + case '#':
4082 + stripped = strchr (name + 1, '#') + 1;
4083 + break;
4084 + case '*':
4085 + stripped = &stripped[1];
4086 + break;
4087 + default:
4088 + return stripped;
4089 + }
4090 + }
4091 +}
4092 +
4093 +
4094 +
4095 +/* Do anything needed before RTL is emitted for each function. */
4096 +static struct machine_function *
4097 +avr32_init_machine_status (void)
4098 +{
4099 + struct machine_function *machine;
4100 + machine =
4101 + (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
4102 +
4103 +#if AVR32_FT_UNKNOWN != 0
4104 + machine->func_type = AVR32_FT_UNKNOWN;
4105 +#endif
4106 +
4107 + machine->minipool_label_head = 0;
4108 + machine->minipool_label_tail = 0;
4109 + return machine;
4110 +}
4111 +
4112 +void
4113 +avr32_init_expanders (void)
4114 + {
4115 + /* Arrange to initialize and mark the machine per-function status. */
4116 + init_machine_status = avr32_init_machine_status;
4117 + }
4118 +
4119 +
4120 +/* Return an RTX indicating where the return address to the
4121 + calling function can be found. */
4122 +
4123 +rtx
4124 +avr32_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4125 + {
4126 + if (count != 0)
4127 + return NULL_RTX;
4128 +
4129 + return get_hard_reg_initial_val (Pmode, LR_REGNUM);
4130 + }
4131 +
4132 +
4133 +void
4134 +avr32_encode_section_info (tree decl, rtx rtl, int first)
4135 + {
4136 +
4137 + if (first && DECL_P (decl))
4138 + {
4139 + /* Set SYMBOL_REG_FLAG for local functions */
4140 + if (!TREE_PUBLIC (decl) && TREE_CODE (decl) == FUNCTION_DECL)
4141 + {
4142 + if ((*targetm.binds_local_p) (decl))
4143 + {
4144 + SYMBOL_REF_FLAG (XEXP (rtl, 0)) = 1;
4145 + }
4146 + }
4147 + }
4148 + }
4149 +
4150 +
4151 +void
4152 +avr32_asm_output_ascii (FILE * stream, char *ptr, int len)
4153 + {
4154 + int i, i_new = 0;
4155 + char *new_ptr = xmalloc (4 * len);
4156 + if (new_ptr == NULL)
4157 + internal_error ("Out of memory.");
4158 +
4159 + for (i = 0; i < len; i++)
4160 + {
4161 + if (ptr[i] == '\n')
4162 + {
4163 + new_ptr[i_new++] = '\\';
4164 + new_ptr[i_new++] = '0';
4165 + new_ptr[i_new++] = '1';
4166 + new_ptr[i_new++] = '2';
4167 + }
4168 + else if (ptr[i] == '\"')
4169 + {
4170 + new_ptr[i_new++] = '\\';
4171 + new_ptr[i_new++] = '\"';
4172 + }
4173 + else if (ptr[i] == '\\')
4174 + {
4175 + new_ptr[i_new++] = '\\';
4176 + new_ptr[i_new++] = '\\';
4177 + }
4178 + else if (ptr[i] == '\0' && i + 1 < len)
4179 + {
4180 + new_ptr[i_new++] = '\\';
4181 + new_ptr[i_new++] = '0';
4182 + }
4183 + else
4184 + {
4185 + new_ptr[i_new++] = ptr[i];
4186 + }
4187 + }
4188 +
4189 + /* Terminate new_ptr. */
4190 + new_ptr[i_new] = '\0';
4191 + fprintf (stream, "\t.ascii\t\"%s\"\n", new_ptr);
4192 + free (new_ptr);
4193 + }
4194 +
4195 +
4196 +void
4197 +avr32_asm_output_label (FILE * stream, const char *name)
4198 + {
4199 + name = avr32_strip_name_encoding (name);
4200 +
4201 + /* Print the label. */
4202 + assemble_name (stream, name);
4203 + fprintf (stream, ":\n");
4204 + }
4205 +
4206 +
4207 +
4208 +void
4209 +avr32_asm_weaken_label (FILE * stream, const char *name)
4210 + {
4211 + fprintf (stream, "\t.weak ");
4212 + assemble_name (stream, name);
4213 + fprintf (stream, "\n");
4214 + }
4215 +
4216 +/*
4217 + Checks if a labelref is equal to a reserved word in the assembler. If it is,
4218 + insert a '_' before the label name.
4219 + */
4220 +void
4221 +avr32_asm_output_labelref (FILE * stream, const char *name)
4222 + {
4223 + int verbatim = FALSE;
4224 + const char *stripped = name;
4225 + int strip_finished = FALSE;
4226 +
4227 + while (!strip_finished)
4228 + {
4229 + switch (stripped[0])
4230 + {
4231 + case '#':
4232 + stripped = strchr (name + 1, '#') + 1;
4233 + break;
4234 + case '*':
4235 + stripped = &stripped[1];
4236 + verbatim = TRUE;
4237 + break;
4238 + default:
4239 + strip_finished = TRUE;
4240 + break;
4241 + }
4242 + }
4243 +
4244 + if (verbatim)
4245 + fputs (stripped, stream);
4246 + else
4247 + asm_fprintf (stream, "%U%s", stripped);
4248 + }
4249 +
4250 +
4251 +
4252 +/*
4253 + Check if the comparison in compare_exp is redundant
4254 + for the condition given in next_cond given that the
4255 + needed flags are already set by an earlier instruction.
4256 + Uses cc_prev_status to check this.
4257 +
4258 + Returns NULL_RTX if the compare is not redundant
4259 + or the new condition to use in the conditional
4260 + instruction if the compare is redundant.
4261 + */
4262 +static rtx
4263 +is_compare_redundant (rtx compare_exp, rtx next_cond)
4264 + {
4265 + int z_flag_valid = FALSE;
4266 + int n_flag_valid = FALSE;
4267 + rtx new_cond;
4268 +
4269 + if (GET_CODE (compare_exp) != COMPARE)
4270 + return NULL_RTX;
4271 +
4272 +
4273 + if (rtx_equal_p (cc_prev_status.mdep.value, compare_exp))
4274 + {
4275 + /* cc0 already contains the correct comparison -> delete cmp insn */
4276 + return next_cond;
4277 + }
4278 +
4279 + if (GET_MODE (compare_exp) != SImode)
4280 + return NULL_RTX;
4281 +
4282 + switch (cc_prev_status.mdep.flags)
4283 + {
4284 + case CC_SET_VNCZ:
4285 + case CC_SET_NCZ:
4286 + n_flag_valid = TRUE;
4287 + case CC_SET_CZ:
4288 + case CC_SET_Z:
4289 + z_flag_valid = TRUE;
4290 + }
4291 +
4292 + if (cc_prev_status.mdep.value
4293 + && REG_P (XEXP (compare_exp, 0))
4294 + && REGNO (XEXP (compare_exp, 0)) == REGNO (cc_prev_status.mdep.value)
4295 + && GET_CODE (XEXP (compare_exp, 1)) == CONST_INT
4296 + && next_cond != NULL_RTX)
4297 + {
4298 + if (INTVAL (XEXP (compare_exp, 1)) == 0
4299 + && z_flag_valid
4300 + && (GET_CODE (next_cond) == EQ || GET_CODE (next_cond) == NE))
4301 + /* We can skip comparison Z flag is already reflecting ops[0] */
4302 + return next_cond;
4303 + else if (n_flag_valid
4304 + && ((INTVAL (XEXP (compare_exp, 1)) == 0
4305 + && (GET_CODE (next_cond) == GE
4306 + || GET_CODE (next_cond) == LT))
4307 + || (INTVAL (XEXP (compare_exp, 1)) == -1
4308 + && (GET_CODE (next_cond) == GT
4309 + || GET_CODE (next_cond) == LE))))
4310 + {
4311 + /* We can skip comparison N flag is already reflecting ops[0],
4312 + which means that we can use the mi/pl conditions to check if
4313 + ops[0] is GE or LT 0. */
4314 + if ((GET_CODE (next_cond) == GE) || (GET_CODE (next_cond) == GT))
4315 + new_cond =
4316 + gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx),
4317 + UNSPEC_COND_PL);
4318 + else
4319 + new_cond =
4320 + gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx),
4321 + UNSPEC_COND_MI);
4322 + return new_cond;
4323 + }
4324 + }
4325 + return NULL_RTX;
4326 + }
4327 +
4328 +/* Updates cc_status. */
4329 +void
4330 +avr32_notice_update_cc (rtx exp, rtx insn)
4331 + {
4332 + switch (get_attr_cc (insn))
4333 + {
4334 + case CC_CALL_SET:
4335 + CC_STATUS_INIT;
4336 + FPCC_STATUS_INIT;
4337 + /* Check if the function call returns a value in r12 */
4338 + if (REG_P (recog_data.operand[0])
4339 + && REGNO (recog_data.operand[0]) == RETVAL_REGNUM)
4340 + {
4341 + cc_status.flags = 0;
4342 + cc_status.mdep.value =
4343 + gen_rtx_COMPARE (SImode, recog_data.operand[0], const0_rtx);
4344 + cc_status.mdep.flags = CC_SET_VNCZ;
4345 +
4346 + }
4347 + break;
4348 + case CC_COMPARE:
4349 + /* Check that compare will not be optimized away if so nothing should
4350 + be done */
4351 + if (is_compare_redundant (SET_SRC (exp), get_next_insn_cond (insn)) ==
4352 + NULL_RTX)
4353 + {
4354 +
4355 + /* Reset the nonstandard flag */
4356 + CC_STATUS_INIT;
4357 + cc_status.flags = 0;
4358 + cc_status.mdep.value = SET_SRC (exp);
4359 + cc_status.mdep.flags = CC_SET_VNCZ;
4360 + }
4361 + break;
4362 + case CC_CMP_COND_INSN:
4363 + {
4364 + /* Conditional insn that emit the compare itself. */
4365 + rtx cmp = gen_rtx_COMPARE (GET_MODE (recog_data.operand[4]),
4366 + recog_data.operand[4],
4367 + recog_data.operand[5]);
4368 +
4369 + if (is_compare_redundant (cmp, recog_data.operand[1]) == NULL_RTX)
4370 + {
4371 +
4372 + /* Reset the nonstandard flag */
4373 + CC_STATUS_INIT;
4374 + cc_status.flags = 0;
4375 + cc_status.mdep.value = cmp;
4376 + cc_status.mdep.flags = CC_SET_VNCZ;
4377 + }
4378 + }
4379 + break;
4380 + case CC_FPCOMPARE:
4381 + /* Check that floating-point compare will not be optimized away if so
4382 + nothing should be done */
4383 + if (!rtx_equal_p (cc_prev_status.mdep.fpvalue, SET_SRC (exp)))
4384 + {
4385 + /* cc0 already contains the correct comparison -> delete cmp insn */
4386 + /* Reset the nonstandard flag */
4387 + cc_status.mdep.fpvalue = SET_SRC (exp);
4388 + cc_status.mdep.fpflags = CC_SET_CZ;
4389 + }
4390 + break;
4391 + case CC_FROM_FPCC:
4392 + /* Flags are updated with flags from Floating-point coprocessor, set
4393 + CC_NOT_SIGNED flag since the flags are set so that unsigned
4394 + condidion codes can be used directly. */
4395 + CC_STATUS_INIT;
4396 + cc_status.flags = CC_NOT_SIGNED;
4397 + cc_status.mdep.value = cc_status.mdep.fpvalue;
4398 + cc_status.mdep.flags = cc_status.mdep.fpflags;
4399 + break;
4400 + case CC_BLD:
4401 + /* Bit load is kind of like an inverted testsi, because the Z flag is
4402 + inverted */
4403 + CC_STATUS_INIT;
4404 + cc_status.flags = CC_INVERTED;
4405 + cc_status.mdep.value = SET_SRC (exp);
4406 + cc_status.mdep.flags = CC_SET_Z;
4407 + break;
4408 + case CC_NONE:
4409 + /* Insn does not affect CC at all. Check if the instruction updates
4410 + some of the register currently reflected in cc0 */
4411 +
4412 + if ((GET_CODE (exp) == SET)
4413 + && (cc_status.value1 || cc_status.value2 || cc_status.mdep.value)
4414 + && (reg_mentioned_p (SET_DEST (exp), cc_status.value1)
4415 + || reg_mentioned_p (SET_DEST (exp), cc_status.value2)
4416 + || reg_mentioned_p (SET_DEST (exp), cc_status.mdep.value)))
4417 + {
4418 + CC_STATUS_INIT;
4419 + }
4420 +
4421 + /* If this is a parallel we must step through each of the parallel
4422 + expressions */
4423 + if (GET_CODE (exp) == PARALLEL)
4424 + {
4425 + int i;
4426 + for (i = 0; i < XVECLEN (exp, 0); ++i)
4427 + {
4428 + rtx vec_exp = XVECEXP (exp, 0, i);
4429 + if ((GET_CODE (vec_exp) == SET)
4430 + && (cc_status.value1 || cc_status.value2
4431 + || cc_status.mdep.value)
4432 + && (reg_mentioned_p (SET_DEST (vec_exp), cc_status.value1)
4433 + || reg_mentioned_p (SET_DEST (vec_exp),
4434 + cc_status.value2)
4435 + || reg_mentioned_p (SET_DEST (vec_exp),
4436 + cc_status.mdep.value)))
4437 + {
4438 + CC_STATUS_INIT;
4439 + }
4440 + }
4441 + }
4442 +
4443 + /* Check if we have memory opartions with post_inc or pre_dec on the
4444 + register currently reflected in cc0 */
4445 + if (GET_CODE (exp) == SET
4446 + && GET_CODE (SET_SRC (exp)) == MEM
4447 + && (GET_CODE (XEXP (SET_SRC (exp), 0)) == POST_INC
4448 + || GET_CODE (XEXP (SET_SRC (exp), 0)) == PRE_DEC)
4449 + &&
4450 + (reg_mentioned_p
4451 + (XEXP (XEXP (SET_SRC (exp), 0), 0), cc_status.value1)
4452 + || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0),
4453 + cc_status.value2)
4454 + || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0),
4455 + cc_status.mdep.value)))
4456 + CC_STATUS_INIT;
4457 +
4458 + if (GET_CODE (exp) == SET
4459 + && GET_CODE (SET_DEST (exp)) == MEM
4460 + && (GET_CODE (XEXP (SET_DEST (exp), 0)) == POST_INC
4461 + || GET_CODE (XEXP (SET_DEST (exp), 0)) == PRE_DEC)
4462 + &&
4463 + (reg_mentioned_p
4464 + (XEXP (XEXP (SET_DEST (exp), 0), 0), cc_status.value1)
4465 + || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0),
4466 + cc_status.value2)
4467 + || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0),
4468 + cc_status.mdep.value)))
4469 + CC_STATUS_INIT;
4470 + break;
4471 +
4472 + case CC_SET_VNCZ:
4473 + CC_STATUS_INIT;
4474 + cc_status.mdep.value = recog_data.operand[0];
4475 + cc_status.mdep.flags = CC_SET_VNCZ;
4476 + break;
4477 +
4478 + case CC_SET_NCZ:
4479 + CC_STATUS_INIT;
4480 + cc_status.mdep.value = recog_data.operand[0];
4481 + cc_status.mdep.flags = CC_SET_NCZ;
4482 + break;
4483 +
4484 + case CC_SET_CZ:
4485 + CC_STATUS_INIT;
4486 + cc_status.mdep.value = recog_data.operand[0];
4487 + cc_status.mdep.flags = CC_SET_CZ;
4488 + break;
4489 +
4490 + case CC_SET_Z:
4491 + CC_STATUS_INIT;
4492 + cc_status.mdep.value = recog_data.operand[0];
4493 + cc_status.mdep.flags = CC_SET_Z;
4494 + break;
4495 +
4496 + case CC_CLOBBER:
4497 + CC_STATUS_INIT;
4498 + break;
4499 +
4500 + default:
4501 + CC_STATUS_INIT;
4502 + }
4503 + }
4504 +
4505 +
4506 +/*
4507 + Outputs to stdio stream stream the assembler syntax for an instruction
4508 + operand x. x is an RTL expression.
4509 + */
4510 +void
4511 +avr32_print_operand (FILE * stream, rtx x, int code)
4512 + {
4513 + int error = 0;
4514 +
4515 + switch (GET_CODE (x))
4516 + {
4517 + case UNSPEC:
4518 + switch (XINT (x, 1))
4519 + {
4520 + case UNSPEC_COND_PL:
4521 + if (code == 'i')
4522 + fputs ("mi", stream);
4523 + else
4524 + fputs ("pl", stream);
4525 + break;
4526 + case UNSPEC_COND_MI:
4527 + if (code == 'i')
4528 + fputs ("pl", stream);
4529 + else
4530 + fputs ("mi", stream);
4531 + break;
4532 + default:
4533 + error = 1;
4534 + }
4535 + break;
4536 + case EQ:
4537 + if (code == 'i')
4538 + fputs ("ne", stream);
4539 + else
4540 + fputs ("eq", stream);
4541 + break;
4542 + case NE:
4543 + if (code == 'i')
4544 + fputs ("eq", stream);
4545 + else
4546 + fputs ("ne", stream);
4547 + break;
4548 + case GT:
4549 + if (code == 'i')
4550 + fputs ("le", stream);
4551 + else
4552 + fputs ("gt", stream);
4553 + break;
4554 + case GTU:
4555 + if (code == 'i')
4556 + fputs ("ls", stream);
4557 + else
4558 + fputs ("hi", stream);
4559 + break;
4560 + case LT:
4561 + if (code == 'i')
4562 + fputs ("ge", stream);
4563 + else
4564 + fputs ("lt", stream);
4565 + break;
4566 + case LTU:
4567 + if (code == 'i')
4568 + fputs ("hs", stream);
4569 + else
4570 + fputs ("lo", stream);
4571 + break;
4572 + case GE:
4573 + if (code == 'i')
4574 + fputs ("lt", stream);
4575 + else
4576 + fputs ("ge", stream);
4577 + break;
4578 + case GEU:
4579 + if (code == 'i')
4580 + fputs ("lo", stream);
4581 + else
4582 + fputs ("hs", stream);
4583 + break;
4584 + case LE:
4585 + if (code == 'i')
4586 + fputs ("gt", stream);
4587 + else
4588 + fputs ("le", stream);
4589 + break;
4590 + case LEU:
4591 + if (code == 'i')
4592 + fputs ("hi", stream);
4593 + else
4594 + fputs ("ls", stream);
4595 + break;
4596 + case CONST_INT:
4597 + {
4598 + HOST_WIDE_INT value = INTVAL (x);
4599 +
4600 + switch (code)
4601 + {
4602 + case 'm':
4603 + if ( HOST_BITS_PER_WIDE_INT > BITS_PER_WORD )
4604 + {
4605 + /* A const_int can be used to represent DImode constants. */
4606 + value >>= BITS_PER_WORD;
4607 + }
4608 + /* We might get a const_int immediate for setting a DI register,
4609 + we then must then return the correct sign extended DI. The most
4610 + significant word is just a sign extension. */
4611 + else if (value < 0)
4612 + value = -1;
4613 + else
4614 + value = 0;
4615 + break;
4616 + case 'i':
4617 + value++;
4618 + break;
4619 + case 'p':
4620 + {
4621 + /* Set to bit position of first bit set in immediate */
4622 + int i, bitpos = 32;
4623 + for (i = 0; i < 32; i++)
4624 + if (value & (1 << i))
4625 + {
4626 + bitpos = i;
4627 + break;
4628 + }
4629 + value = bitpos;
4630 + }
4631 + break;
4632 + case 'r':
4633 + {
4634 + /* Reglist 8 */
4635 + char op[50];
4636 + op[0] = '\0';
4637 +
4638 + if (value & 0x01)
4639 + sprintf (op, "r0-r3");
4640 + if (value & 0x02)
4641 + strlen (op) ? sprintf (op, "%s, r4-r7", op) : sprintf (op,
4642 + "r4-r7");
4643 + if (value & 0x04)
4644 + strlen (op) ? sprintf (op, "%s, r8-r9", op) : sprintf (op,
4645 + "r8-r9");
4646 + if (value & 0x08)
4647 + strlen (op) ? sprintf (op, "%s, r10", op) : sprintf (op,
4648 + "r10");
4649 + if (value & 0x10)
4650 + strlen (op) ? sprintf (op, "%s, r11", op) : sprintf (op,
4651 + "r11");
4652 + if (value & 0x20)
4653 + strlen (op) ? sprintf (op, "%s, r12", op) : sprintf (op,
4654 + "r12");
4655 + if (value & 0x40)
4656 + strlen (op) ? sprintf (op, "%s, lr", op) : sprintf (op, "lr");
4657 + if (value & 0x80)
4658 + strlen (op) ? sprintf (op, "%s, pc", op) : sprintf (op, "pc");
4659 +
4660 + fputs (op, stream);
4661 + return;
4662 + }
4663 + case 's':
4664 + {
4665 + /* Reglist 16 */
4666 + char reglist16_string[100];
4667 + int i;
4668 + reglist16_string[0] = '\0';
4669 +
4670 + for (i = 0; i < 16; ++i)
4671 + {
4672 + if (value & (1 << i))
4673 + {
4674 + strlen (reglist16_string) ? sprintf (reglist16_string,
4675 + "%s, %s",
4676 + reglist16_string,
4677 + reg_names
4678 + [INTERNAL_REGNUM
4679 + (i)]) :
4680 + sprintf (reglist16_string, "%s",
4681 + reg_names[INTERNAL_REGNUM (i)]);
4682 + }
4683 + }
4684 + fputs (reglist16_string, stream);
4685 + return;
4686 + }
4687 + case 'C':
4688 + {
4689 + /* RegListCP8 */
4690 + char reglist_string[100];
4691 + avr32_make_fp_reglist_w (value, (char *) reglist_string);
4692 + fputs (reglist_string, stream);
4693 + return;
4694 + }
4695 + case 'D':
4696 + {
4697 + /* RegListCPD8 */
4698 + char reglist_string[100];
4699 + avr32_make_fp_reglist_d (value, (char *) reglist_string);
4700 + fputs (reglist_string, stream);
4701 + return;
4702 + }
4703 + case 'h':
4704 + /* Print halfword part of word */
4705 + fputs (value ? "b" : "t", stream);
4706 + return;
4707 + }
4708 +
4709 + /* Print Value */
4710 + fprintf (stream, "%d", value);
4711 + break;
4712 + }
4713 + case CONST_DOUBLE:
4714 + {
4715 + HOST_WIDE_INT hi, lo;
4716 + if (SCALAR_FLOAT_MODE_P (GET_MODE (x)))
4717 + {
4718 + HOST_WIDE_INT target_float[2];
4719 + hi = lo = 0;
4720 + real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (x),
4721 + GET_MODE (x));
4722 + /* For doubles the most significant part starts at index 0. */
4723 + if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
4724 + {
4725 + hi = target_float[0];
4726 + lo = target_float[1];
4727 + }
4728 + else
4729 + {
4730 + lo = target_float[0];
4731 + }
4732 + }
4733 + else
4734 + {
4735 + hi = CONST_DOUBLE_HIGH (x);
4736 + lo = CONST_DOUBLE_LOW (x);
4737 + }
4738 +
4739 + if (code == 'm')
4740 + fprintf (stream, "%ld", hi);
4741 + else
4742 + fprintf (stream, "%ld", lo);
4743 +
4744 + break;
4745 + }
4746 + case CONST:
4747 + output_addr_const (stream, XEXP (XEXP (x, 0), 0));
4748 + fprintf (stream, "+%ld", INTVAL (XEXP (XEXP (x, 0), 1)));
4749 + break;
4750 + case REG:
4751 + /* Swap register name if the register is DImode or DFmode. */
4752 + if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
4753 + {
4754 + /* Double register must have an even numbered address */
4755 + gcc_assert (!(REGNO (x) % 2));
4756 + if (code == 'm')
4757 + fputs (reg_names[true_regnum (x)], stream);
4758 + else
4759 + fputs (reg_names[true_regnum (x) + 1], stream);
4760 + }
4761 + else if (GET_MODE (x) == TImode)
4762 + {
4763 + switch (code)
4764 + {
4765 + case 'T':
4766 + fputs (reg_names[true_regnum (x)], stream);
4767 + break;
4768 + case 'U':
4769 + fputs (reg_names[true_regnum (x) + 1], stream);
4770 + break;
4771 + case 'L':
4772 + fputs (reg_names[true_regnum (x) + 2], stream);
4773 + break;
4774 + case 'B':
4775 + fputs (reg_names[true_regnum (x) + 3], stream);
4776 + break;
4777 + default:
4778 + fprintf (stream, "%s, %s, %s, %s",
4779 + reg_names[true_regnum (x) + 3],
4780 + reg_names[true_regnum (x) + 2],
4781 + reg_names[true_regnum (x) + 1],
4782 + reg_names[true_regnum (x)]);
4783 + break;
4784 + }
4785 + }
4786 + else
4787 + {
4788 + fputs (reg_names[true_regnum (x)], stream);
4789 + }
4790 + break;
4791 + case CODE_LABEL:
4792 + case LABEL_REF:
4793 + case SYMBOL_REF:
4794 + output_addr_const (stream, x);
4795 + break;
4796 + case MEM:
4797 + switch (GET_CODE (XEXP (x, 0)))
4798 + {
4799 + case LABEL_REF:
4800 + case SYMBOL_REF:
4801 + output_addr_const (stream, XEXP (x, 0));
4802 + break;
4803 + case MEM:
4804 + switch (GET_CODE (XEXP (XEXP (x, 0), 0)))
4805 + {
4806 + case SYMBOL_REF:
4807 + output_addr_const (stream, XEXP (XEXP (x, 0), 0));
4808 + break;
4809 + default:
4810 + error = 1;
4811 + break;
4812 + }
4813 + break;
4814 + case REG:
4815 + avr32_print_operand (stream, XEXP (x, 0), 0);
4816 + if (code != 'p')
4817 + fputs ("[0]", stream);
4818 + break;
4819 + case PRE_DEC:
4820 + fputs ("--", stream);
4821 + avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0);
4822 + break;
4823 + case POST_INC:
4824 + avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0);
4825 + fputs ("++", stream);
4826 + break;
4827 + case PLUS:
4828 + {
4829 + rtx op0 = XEXP (XEXP (x, 0), 0);
4830 + rtx op1 = XEXP (XEXP (x, 0), 1);
4831 + rtx base = NULL_RTX, offset = NULL_RTX;
4832 +
4833 + if (avr32_address_register_rtx_p (op0, 1))
4834 + {
4835 + base = op0;
4836 + offset = op1;
4837 + }
4838 + else if (avr32_address_register_rtx_p (op1, 1))
4839 + {
4840 + /* Operands are switched. */
4841 + base = op1;
4842 + offset = op0;
4843 + }
4844 +
4845 + gcc_assert (base && offset
4846 + && avr32_address_register_rtx_p (base, 1)
4847 + && avr32_legitimate_index_p (GET_MODE (x), offset,
4848 + 1));
4849 +
4850 + avr32_print_operand (stream, base, 0);
4851 + fputs ("[", stream);
4852 + avr32_print_operand (stream, offset, 0);
4853 + fputs ("]", stream);
4854 + break;
4855 + }
4856 + case CONST:
4857 + output_addr_const (stream, XEXP (XEXP (XEXP (x, 0), 0), 0));
4858 + fprintf (stream, " + %ld",
4859 + INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)));
4860 + break;
4861 + default:
4862 + error = 1;
4863 + }
4864 + break;
4865 + case MULT:
4866 + {
4867 + int value = INTVAL (XEXP (x, 1));
4868 +
4869 + /* Convert immediate in multiplication into a shift immediate */
4870 + switch (value)
4871 + {
4872 + case 2:
4873 + value = 1;
4874 + break;
4875 + case 4:
4876 + value = 2;
4877 + break;
4878 + case 8:
4879 + value = 3;
4880 + break;
4881 + default:
4882 + value = 0;
4883 + }
4884 + fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))],
4885 + value);
4886 + break;
4887 + }
4888 + case ASHIFT:
4889 + if (GET_CODE (XEXP (x, 1)) == CONST_INT)
4890 + fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))],
4891 + (int) INTVAL (XEXP (x, 1)));
4892 + else if (REG_P (XEXP (x, 1)))
4893 + fprintf (stream, "%s << %s", reg_names[true_regnum (XEXP (x, 0))],
4894 + reg_names[true_regnum (XEXP (x, 1))]);
4895 + else
4896 + {
4897 + error = 1;
4898 + }
4899 + break;
4900 + case LSHIFTRT:
4901 + if (GET_CODE (XEXP (x, 1)) == CONST_INT)
4902 + fprintf (stream, "%s >> %i", reg_names[true_regnum (XEXP (x, 0))],
4903 + (int) INTVAL (XEXP (x, 1)));
4904 + else if (REG_P (XEXP (x, 1)))
4905 + fprintf (stream, "%s >> %s", reg_names[true_regnum (XEXP (x, 0))],
4906 + reg_names[true_regnum (XEXP (x, 1))]);
4907 + else
4908 + {
4909 + error = 1;
4910 + }
4911 + fprintf (stream, ">>");
4912 + break;
4913 + case PARALLEL:
4914 + {
4915 + /* Load store multiple */
4916 + int i;
4917 + int count = XVECLEN (x, 0);
4918 + int reglist16 = 0;
4919 + char reglist16_string[100];
4920 +
4921 + for (i = 0; i < count; ++i)
4922 + {
4923 + rtx vec_elm = XVECEXP (x, 0, i);
4924 + if (GET_MODE (vec_elm) != SET)
4925 + {
4926 + debug_rtx (vec_elm);
4927 + internal_error ("Unknown element in parallel expression!");
4928 + }
4929 + if (GET_MODE (XEXP (vec_elm, 0)) == REG)
4930 + {
4931 + /* Load multiple */
4932 + reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 0)));
4933 + }
4934 + else
4935 + {
4936 + /* Store multiple */
4937 + reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 1)));
4938 + }
4939 + }
4940 +
4941 + avr32_make_reglist16 (reglist16, reglist16_string);
4942 + fputs (reglist16_string, stream);
4943 +
4944 + break;
4945 + }
4946 +
4947 + default:
4948 + error = 1;
4949 + }
4950 +
4951 + if (error)
4952 + {
4953 + debug_rtx (x);
4954 + internal_error ("Illegal expression for avr32_print_operand");
4955 + }
4956 + }
4957 +
4958 +rtx
4959 +avr32_get_note_reg_equiv (rtx insn)
4960 + {
4961 + rtx note;
4962 +
4963 + note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
4964 +
4965 + if (note != NULL_RTX)
4966 + return XEXP (note, 0);
4967 + else
4968 + return NULL_RTX;
4969 + }
4970 +
4971 +/*
4972 + Outputs to stdio stream stream the assembler syntax for an instruction
4973 + operand that is a memory reference whose address is x. x is an RTL
4974 + expression.
4975 +
4976 + ToDo: fixme.
4977 + */
4978 +void
4979 +avr32_print_operand_address (FILE * stream, rtx x)
4980 + {
4981 + fprintf (stream, "(%d) /* address */", REGNO (x));
4982 + }
4983 +
4984 +/* Return true if _GLOBAL_OFFSET_TABLE_ symbol is mentioned. */
4985 +bool
4986 +avr32_got_mentioned_p (rtx addr)
4987 + {
4988 + if (GET_CODE (addr) == MEM)
4989 + addr = XEXP (addr, 0);
4990 + while (GET_CODE (addr) == CONST)
4991 + addr = XEXP (addr, 0);
4992 + if (GET_CODE (addr) == SYMBOL_REF)
4993 + {
4994 + return streq (XSTR (addr, 0), "_GLOBAL_OFFSET_TABLE_");
4995 + }
4996 + if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
4997 + {
4998 + bool l1, l2;
4999 +
5000 + l1 = avr32_got_mentioned_p (XEXP (addr, 0));
5001 + l2 = avr32_got_mentioned_p (XEXP (addr, 1));
5002 + return l1 || l2;
5003 + }
5004 + return false;
5005 + }
5006 +
5007 +
5008 +/* Find the symbol in an address expression. */
5009 +
5010 +rtx
5011 +avr32_find_symbol (rtx addr)
5012 + {
5013 + if (GET_CODE (addr) == MEM)
5014 + addr = XEXP (addr, 0);
5015 +
5016 + while (GET_CODE (addr) == CONST)
5017 + addr = XEXP (addr, 0);
5018 +
5019 + if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
5020 + return addr;
5021 + if (GET_CODE (addr) == PLUS)
5022 + {
5023 + rtx l1, l2;
5024 +
5025 + l1 = avr32_find_symbol (XEXP (addr, 0));
5026 + l2 = avr32_find_symbol (XEXP (addr, 1));
5027 + if (l1 != NULL_RTX && l2 == NULL_RTX)
5028 + return l1;
5029 + else if (l1 == NULL_RTX && l2 != NULL_RTX)
5030 + return l2;
5031 + }
5032 +
5033 + return NULL_RTX;
5034 + }
5035 +
5036 +
5037 +/* Routines for manipulation of the constant pool. */
5038 +
5039 +/* AVR32 instructions cannot load a large constant directly into a
5040 + register; they have to come from a pc relative load. The constant
5041 + must therefore be placed in the addressable range of the pc
5042 + relative load. Depending on the precise pc relative load
5043 + instruction the range is somewhere between 256 bytes and 4k. This
5044 + means that we often have to dump a constant inside a function, and
5045 + generate code to branch around it.
5046 +
5047 + It is important to minimize this, since the branches will slow
5048 + things down and make the code larger.
5049 +
5050 + Normally we can hide the table after an existing unconditional
5051 + branch so that there is no interruption of the flow, but in the
5052 + worst case the code looks like this:
5053 +
5054 + lddpc rn, L1
5055 + ...
5056 + rjmp L2
5057 + align
5058 + L1: .long value
5059 + L2:
5060 + ...
5061 +
5062 + lddpc rn, L3
5063 + ...
5064 + rjmp L4
5065 + align
5066 + L3: .long value
5067 + L4:
5068 + ...
5069 +
5070 + We fix this by performing a scan after scheduling, which notices
5071 + which instructions need to have their operands fetched from the
5072 + constant table and builds the table.
5073 +
5074 + The algorithm starts by building a table of all the constants that
5075 + need fixing up and all the natural barriers in the function (places
5076 + where a constant table can be dropped without breaking the flow).
5077 + For each fixup we note how far the pc-relative replacement will be
5078 + able to reach and the offset of the instruction into the function.
5079 +
5080 + Having built the table we then group the fixes together to form
5081 + tables that are as large as possible (subject to addressing
5082 + constraints) and emit each table of constants after the last
5083 + barrier that is within range of all the instructions in the group.
5084 + If a group does not contain a barrier, then we forcibly create one
5085 + by inserting a jump instruction into the flow. Once the table has
5086 + been inserted, the insns are then modified to reference the
5087 + relevant entry in the pool.
5088 +
5089 + Possible enhancements to the algorithm (not implemented) are:
5090 +
5091 + 1) For some processors and object formats, there may be benefit in
5092 + aligning the pools to the start of cache lines; this alignment
5093 + would need to be taken into account when calculating addressability
5094 + of a pool. */
5095 +
5096 +/* These typedefs are located at the start of this file, so that
5097 + they can be used in the prototypes there. This comment is to
5098 + remind readers of that fact so that the following structures
5099 + can be understood more easily.
5100 +
5101 + typedef struct minipool_node Mnode;
5102 + typedef struct minipool_fixup Mfix; */
5103 +
5104 +struct minipool_node
5105 +{
5106 + /* Doubly linked chain of entries. */
5107 + Mnode *next;
5108 + Mnode *prev;
5109 + /* The maximum offset into the code that this entry can be placed. While
5110 + pushing fixes for forward references, all entries are sorted in order of
5111 + increasing max_address. */
5112 + HOST_WIDE_INT max_address;
5113 + /* Similarly for an entry inserted for a backwards ref. */
5114 + HOST_WIDE_INT min_address;
5115 + /* The number of fixes referencing this entry. This can become zero if we
5116 + "unpush" an entry. In this case we ignore the entry when we come to
5117 + emit the code. */
5118 + int refcount;
5119 + /* The offset from the start of the minipool. */
5120 + HOST_WIDE_INT offset;
5121 + /* The value in table. */
5122 + rtx value;
5123 + /* The mode of value. */
5124 + enum machine_mode mode;
5125 + /* The size of the value. */
5126 + int fix_size;
5127 +};
5128 +
5129 +struct minipool_fixup
5130 +{
5131 + Mfix *next;
5132 + rtx insn;
5133 + HOST_WIDE_INT address;
5134 + rtx *loc;
5135 + enum machine_mode mode;
5136 + int fix_size;
5137 + rtx value;
5138 + Mnode *minipool;
5139 + HOST_WIDE_INT forwards;
5140 + HOST_WIDE_INT backwards;
5141 +};
5142 +
5143 +
5144 +/* Fixes less than a word need padding out to a word boundary. */
5145 +#define MINIPOOL_FIX_SIZE(mode, value) \
5146 + (IS_FORCE_MINIPOOL(value) ? 0 : \
5147 + (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4))
5148 +
5149 +#define IS_FORCE_MINIPOOL(x) \
5150 + (GET_CODE(x) == UNSPEC && \
5151 + XINT(x, 1) == UNSPEC_FORCE_MINIPOOL)
5152 +
5153 +static Mnode *minipool_vector_head;
5154 +static Mnode *minipool_vector_tail;
5155 +
5156 +/* The linked list of all minipool fixes required for this function. */
5157 +Mfix *minipool_fix_head;
5158 +Mfix *minipool_fix_tail;
5159 +/* The fix entry for the current minipool, once it has been placed. */
5160 +Mfix *minipool_barrier;
5161 +
5162 +/* Determines if INSN is the start of a jump table. Returns the end
5163 + of the TABLE or NULL_RTX. */
5164 +static rtx
5165 +is_jump_table (rtx insn)
5166 + {
5167 + rtx table;
5168 +
5169 + if (GET_CODE (insn) == JUMP_INSN
5170 + && JUMP_LABEL (insn) != NULL
5171 + && ((table = next_real_insn (JUMP_LABEL (insn)))
5172 + == next_real_insn (insn))
5173 + && table != NULL
5174 + && GET_CODE (table) == JUMP_INSN
5175 + && (GET_CODE (PATTERN (table)) == ADDR_VEC
5176 + || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
5177 + return table;
5178 +
5179 + return NULL_RTX;
5180 + }
5181 +
5182 +static HOST_WIDE_INT
5183 +get_jump_table_size (rtx insn)
5184 + {
5185 + /* ADDR_VECs only take room if read-only data does into the text section. */
5186 + if (JUMP_TABLES_IN_TEXT_SECTION
5187 +#if !defined(READONLY_DATA_SECTION_ASM_OP)
5188 + || 1
5189 +#endif
5190 + )
5191 + {
5192 + rtx body = PATTERN (insn);
5193 + int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
5194 +
5195 + return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
5196 + }
5197 +
5198 + return 0;
5199 + }
5200 +
5201 +/* Move a minipool fix MP from its current location to before MAX_MP.
5202 + If MAX_MP is NULL, then MP doesn't need moving, but the addressing
5203 + constraints may need updating. */
5204 +static Mnode *
5205 +move_minipool_fix_forward_ref (Mnode * mp, Mnode * max_mp,
5206 + HOST_WIDE_INT max_address)
5207 + {
5208 + /* This should never be true and the code below assumes these are
5209 + different. */
5210 + if (mp == max_mp)
5211 + abort ();
5212 +
5213 + if (max_mp == NULL)
5214 + {
5215 + if (max_address < mp->max_address)
5216 + mp->max_address = max_address;
5217 + }
5218 + else
5219 + {
5220 + if (max_address > max_mp->max_address - mp->fix_size)
5221 + mp->max_address = max_mp->max_address - mp->fix_size;
5222 + else
5223 + mp->max_address = max_address;
5224 +
5225 + /* Unlink MP from its current position. Since max_mp is non-null,
5226 + mp->prev must be non-null. */
5227 + mp->prev->next = mp->next;
5228 + if (mp->next != NULL)
5229 + mp->next->prev = mp->prev;
5230 + else
5231 + minipool_vector_tail = mp->prev;
5232 +
5233 + /* Re-insert it before MAX_MP. */
5234 + mp->next = max_mp;
5235 + mp->prev = max_mp->prev;
5236 + max_mp->prev = mp;
5237 +
5238 + if (mp->prev != NULL)
5239 + mp->prev->next = mp;
5240 + else
5241 + minipool_vector_head = mp;
5242 + }
5243 +
5244 + /* Save the new entry. */
5245 + max_mp = mp;
5246 +
5247 + /* Scan over the preceding entries and adjust their addresses as required.
5248 + */
5249 + while (mp->prev != NULL
5250 + && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5251 + {
5252 + mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5253 + mp = mp->prev;
5254 + }
5255 +
5256 + return max_mp;
5257 + }
5258 +
5259 +/* Add a constant to the minipool for a forward reference. Returns the
5260 + node added or NULL if the constant will not fit in this pool. */
5261 +static Mnode *
5262 +add_minipool_forward_ref (Mfix * fix)
5263 +{
5264 + /* If set, max_mp is the first pool_entry that has a lower constraint than
5265 + the one we are trying to add. */
5266 + Mnode *max_mp = NULL;
5267 + HOST_WIDE_INT max_address = fix->address + fix->forwards;
5268 + Mnode *mp;
5269 +
5270 + /* If this fix's address is greater than the address of the first entry,
5271 + then we can't put the fix in this pool. We subtract the size of the
5272 + current fix to ensure that if the table is fully packed we still have
5273 + enough room to insert this value by suffling the other fixes forwards. */
5274 + if (minipool_vector_head &&
5275 + fix->address >= minipool_vector_head->max_address - fix->fix_size)
5276 + return NULL;
5277 +
5278 + /* Scan the pool to see if a constant with the same value has already been
5279 + added. While we are doing this, also note the location where we must
5280 + insert the constant if it doesn't already exist. */
5281 + for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5282 + {
5283 + if (GET_CODE (fix->value) == GET_CODE (mp->value)
5284 + && fix->mode == mp->mode
5285 + && (GET_CODE (fix->value) != CODE_LABEL
5286 + || (CODE_LABEL_NUMBER (fix->value)
5287 + == CODE_LABEL_NUMBER (mp->value)))
5288 + && rtx_equal_p (fix->value, mp->value))
5289 + {
5290 + /* More than one fix references this entry. */
5291 + mp->refcount++;
5292 + return move_minipool_fix_forward_ref (mp, max_mp, max_address);
5293 + }
5294 +
5295 + /* Note the insertion point if necessary. */
5296 + if (max_mp == NULL && mp->max_address > max_address)
5297 + max_mp = mp;
5298 +
5299 + }
5300 +
5301 + /* The value is not currently in the minipool, so we need to create a new
5302 + entry for it. If MAX_MP is NULL, the entry will be put on the end of
5303 + the list since the placement is less constrained than any existing
5304 + entry. Otherwise, we insert the new fix before MAX_MP and, if
5305 + necessary, adjust the constraints on the other entries. */
5306 + mp = xmalloc (sizeof (*mp));
5307 + mp->fix_size = fix->fix_size;
5308 + mp->mode = fix->mode;
5309 + mp->value = fix->value;
5310 + mp->refcount = 1;
5311 + /* Not yet required for a backwards ref. */
5312 + mp->min_address = -65536;
5313 +
5314 + if (max_mp == NULL)
5315 + {
5316 + mp->max_address = max_address;
5317 + mp->next = NULL;
5318 + mp->prev = minipool_vector_tail;
5319 +
5320 + if (mp->prev == NULL)
5321 + {
5322 + minipool_vector_head = mp;
5323 + minipool_vector_label = gen_label_rtx ();
5324 + }
5325 + else
5326 + mp->prev->next = mp;
5327 +
5328 + minipool_vector_tail = mp;
5329 + }
5330 + else
5331 + {
5332 + if (max_address > max_mp->max_address - mp->fix_size)
5333 + mp->max_address = max_mp->max_address - mp->fix_size;
5334 + else
5335 + mp->max_address = max_address;
5336 +
5337 + mp->next = max_mp;
5338 + mp->prev = max_mp->prev;
5339 + max_mp->prev = mp;
5340 + if (mp->prev != NULL)
5341 + mp->prev->next = mp;
5342 + else
5343 + minipool_vector_head = mp;
5344 + }
5345 +
5346 + /* Save the new entry. */
5347 + max_mp = mp;
5348 +
5349 + /* Scan over the preceding entries and adjust their addresses as required.
5350 + */
5351 + while (mp->prev != NULL
5352 + && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5353 + {
5354 + mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5355 + mp = mp->prev;
5356 + }
5357 +
5358 + return max_mp;
5359 +}
5360 +
5361 +static Mnode *
5362 +move_minipool_fix_backward_ref (Mnode * mp, Mnode * min_mp,
5363 + HOST_WIDE_INT min_address)
5364 + {
5365 + HOST_WIDE_INT offset;
5366 +
5367 + /* This should never be true, and the code below assumes these are
5368 + different. */
5369 + if (mp == min_mp)
5370 + abort ();
5371 +
5372 + if (min_mp == NULL)
5373 + {
5374 + if (min_address > mp->min_address)
5375 + mp->min_address = min_address;
5376 + }
5377 + else
5378 + {
5379 + /* We will adjust this below if it is too loose. */
5380 + mp->min_address = min_address;
5381 +
5382 + /* Unlink MP from its current position. Since min_mp is non-null,
5383 + mp->next must be non-null. */
5384 + mp->next->prev = mp->prev;
5385 + if (mp->prev != NULL)
5386 + mp->prev->next = mp->next;
5387 + else
5388 + minipool_vector_head = mp->next;
5389 +
5390 + /* Reinsert it after MIN_MP. */
5391 + mp->prev = min_mp;
5392 + mp->next = min_mp->next;
5393 + min_mp->next = mp;
5394 + if (mp->next != NULL)
5395 + mp->next->prev = mp;
5396 + else
5397 + minipool_vector_tail = mp;
5398 + }
5399 +
5400 + min_mp = mp;
5401 +
5402 + offset = 0;
5403 + for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5404 + {
5405 + mp->offset = offset;
5406 + if (mp->refcount > 0)
5407 + offset += mp->fix_size;
5408 +
5409 + if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size)
5410 + mp->next->min_address = mp->min_address + mp->fix_size;
5411 + }
5412 +
5413 + return min_mp;
5414 + }
5415 +
5416 +/* Add a constant to the minipool for a backward reference. Returns the
5417 + node added or NULL if the constant will not fit in this pool.
5418 +
5419 + Note that the code for insertion for a backwards reference can be
5420 + somewhat confusing because the calculated offsets for each fix do
5421 + not take into account the size of the pool (which is still under
5422 + construction. */
5423 +static Mnode *
5424 +add_minipool_backward_ref (Mfix * fix)
5425 +{
5426 + /* If set, min_mp is the last pool_entry that has a lower constraint than
5427 + the one we are trying to add. */
5428 + Mnode *min_mp = NULL;
5429 + /* This can be negative, since it is only a constraint. */
5430 + HOST_WIDE_INT min_address = fix->address - fix->backwards;
5431 + Mnode *mp;
5432 +
5433 + /* If we can't reach the current pool from this insn, or if we can't insert
5434 + this entry at the end of the pool without pushing other fixes out of
5435 + range, then we don't try. This ensures that we can't fail later on. */
5436 + if (min_address >= minipool_barrier->address
5437 + || (minipool_vector_tail->min_address + fix->fix_size
5438 + >= minipool_barrier->address))
5439 + return NULL;
5440 +
5441 + /* Scan the pool to see if a constant with the same value has already been
5442 + added. While we are doing this, also note the location where we must
5443 + insert the constant if it doesn't already exist. */
5444 + for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev)
5445 + {
5446 + if (GET_CODE (fix->value) == GET_CODE (mp->value)
5447 + && fix->mode == mp->mode
5448 + && (GET_CODE (fix->value) != CODE_LABEL
5449 + || (CODE_LABEL_NUMBER (fix->value)
5450 + == CODE_LABEL_NUMBER (mp->value)))
5451 + && rtx_equal_p (fix->value, mp->value)
5452 + /* Check that there is enough slack to move this entry to the end
5453 + of the table (this is conservative). */
5454 + && (mp->max_address
5455 + > (minipool_barrier->address
5456 + + minipool_vector_tail->offset
5457 + + minipool_vector_tail->fix_size)))
5458 + {
5459 + mp->refcount++;
5460 + return move_minipool_fix_backward_ref (mp, min_mp, min_address);
5461 + }
5462 +
5463 + if (min_mp != NULL)
5464 + mp->min_address += fix->fix_size;
5465 + else
5466 + {
5467 + /* Note the insertion point if necessary. */
5468 + if (mp->min_address < min_address)
5469 + {
5470 + min_mp = mp;
5471 + }
5472 + else if (mp->max_address
5473 + < minipool_barrier->address + mp->offset + fix->fix_size)
5474 + {
5475 + /* Inserting before this entry would push the fix beyond its
5476 + maximum address (which can happen if we have re-located a
5477 + forwards fix); force the new fix to come after it. */
5478 + min_mp = mp;
5479 + min_address = mp->min_address + fix->fix_size;
5480 + }
5481 + }
5482 + }
5483 +
5484 + /* We need to create a new entry. */
5485 + mp = xmalloc (sizeof (*mp));
5486 + mp->fix_size = fix->fix_size;
5487 + mp->mode = fix->mode;
5488 + mp->value = fix->value;
5489 + mp->refcount = 1;
5490 + mp->max_address = minipool_barrier->address + 65536;
5491 +
5492 + mp->min_address = min_address;
5493 +
5494 + if (min_mp == NULL)
5495 + {
5496 + mp->prev = NULL;
5497 + mp->next = minipool_vector_head;
5498 +
5499 + if (mp->next == NULL)
5500 + {
5501 + minipool_vector_tail = mp;
5502 + minipool_vector_label = gen_label_rtx ();
5503 + }
5504 + else
5505 + mp->next->prev = mp;
5506 +
5507 + minipool_vector_head = mp;
5508 + }
5509 + else
5510 + {
5511 + mp->next = min_mp->next;
5512 + mp->prev = min_mp;
5513 + min_mp->next = mp;
5514 +
5515 + if (mp->next != NULL)
5516 + mp->next->prev = mp;
5517 + else
5518 + minipool_vector_tail = mp;
5519 + }
5520 +
5521 + /* Save the new entry. */
5522 + min_mp = mp;
5523 +
5524 + if (mp->prev)
5525 + mp = mp->prev;
5526 + else
5527 + mp->offset = 0;
5528 +
5529 + /* Scan over the following entries and adjust their offsets. */
5530 + while (mp->next != NULL)
5531 + {
5532 + if (mp->next->min_address < mp->min_address + mp->fix_size)
5533 + mp->next->min_address = mp->min_address + mp->fix_size;
5534 +
5535 + if (mp->refcount)
5536 + mp->next->offset = mp->offset + mp->fix_size;
5537 + else
5538 + mp->next->offset = mp->offset;
5539 +
5540 + mp = mp->next;
5541 + }
5542 +
5543 + return min_mp;
5544 +}
5545 +
5546 +static void
5547 +assign_minipool_offsets (Mfix * barrier)
5548 + {
5549 + HOST_WIDE_INT offset = 0;
5550 + Mnode *mp;
5551 +
5552 + minipool_barrier = barrier;
5553 +
5554 + for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5555 + {
5556 + mp->offset = offset;
5557 +
5558 + if (mp->refcount > 0)
5559 + offset += mp->fix_size;
5560 + }
5561 + }
5562 +
5563 +/* Print a symbolic form of X to the debug file, F. */
5564 +static void
5565 +avr32_print_value (FILE * f, rtx x)
5566 + {
5567 + switch (GET_CODE (x))
5568 + {
5569 + case CONST_INT:
5570 + fprintf (f, "0x%x", (int) INTVAL (x));
5571 + return;
5572 +
5573 + case CONST_DOUBLE:
5574 + fprintf (f, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
5575 + return;
5576 +
5577 + case CONST_VECTOR:
5578 + {
5579 + int i;
5580 +
5581 + fprintf (f, "<");
5582 + for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
5583 + {
5584 + fprintf (f, "0x%x", (int) INTVAL (CONST_VECTOR_ELT (x, i)));
5585 + if (i < (CONST_VECTOR_NUNITS (x) - 1))
5586 + fputc (',', f);
5587 + }
5588 + fprintf (f, ">");
5589 + }
5590 + return;
5591 +
5592 + case CONST_STRING:
5593 + fprintf (f, "\"%s\"", XSTR (x, 0));
5594 + return;
5595 +
5596 + case SYMBOL_REF:
5597 + fprintf (f, "`%s'", XSTR (x, 0));
5598 + return;
5599 +
5600 + case LABEL_REF:
5601 + fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
5602 + return;
5603 +
5604 + case CONST:
5605 + avr32_print_value (f, XEXP (x, 0));
5606 + return;
5607 +
5608 + case PLUS:
5609 + avr32_print_value (f, XEXP (x, 0));
5610 + fprintf (f, "+");
5611 + avr32_print_value (f, XEXP (x, 1));
5612 + return;
5613 +
5614 + case PC:
5615 + fprintf (f, "pc");
5616 + return;
5617 +
5618 + default:
5619 + fprintf (f, "????");
5620 + return;
5621 + }
5622 + }
5623 +
5624 +int
5625 +is_minipool_label (rtx label)
5626 + {
5627 + minipool_labels *cur_mp_label = cfun->machine->minipool_label_head;
5628 +
5629 + if (GET_CODE (label) != CODE_LABEL)
5630 + return FALSE;
5631 +
5632 + while (cur_mp_label)
5633 + {
5634 + if (CODE_LABEL_NUMBER (label)
5635 + == CODE_LABEL_NUMBER (cur_mp_label->label))
5636 + return TRUE;
5637 + cur_mp_label = cur_mp_label->next;
5638 + }
5639 + return FALSE;
5640 + }
5641 +
5642 +static void
5643 +new_minipool_label (rtx label)
5644 + {
5645 + if (!cfun->machine->minipool_label_head)
5646 + {
5647 + cfun->machine->minipool_label_head =
5648 + ggc_alloc (sizeof (minipool_labels));
5649 + cfun->machine->minipool_label_tail = cfun->machine->minipool_label_head;
5650 + cfun->machine->minipool_label_head->label = label;
5651 + cfun->machine->minipool_label_head->next = 0;
5652 + cfun->machine->minipool_label_head->prev = 0;
5653 + }
5654 + else
5655 + {
5656 + cfun->machine->minipool_label_tail->next =
5657 + ggc_alloc (sizeof (minipool_labels));
5658 + cfun->machine->minipool_label_tail->next->label = label;
5659 + cfun->machine->minipool_label_tail->next->next = 0;
5660 + cfun->machine->minipool_label_tail->next->prev =
5661 + cfun->machine->minipool_label_tail;
5662 + cfun->machine->minipool_label_tail =
5663 + cfun->machine->minipool_label_tail->next;
5664 + }
5665 + }
5666 +
5667 +/* Output the literal table */
5668 +static void
5669 +dump_minipool (rtx scan)
5670 + {
5671 + Mnode *mp;
5672 + Mnode *nmp;
5673 +
5674 + if (dump_file)
5675 + fprintf (dump_file,
5676 + ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
5677 + INSN_UID (scan), (unsigned long) minipool_barrier->address, 4);
5678 +
5679 + scan = emit_insn_after (gen_consttable_start (), scan);
5680 + scan = emit_insn_after (gen_align_4 (), scan);
5681 + scan = emit_label_after (minipool_vector_label, scan);
5682 + new_minipool_label (minipool_vector_label);
5683 +
5684 + for (mp = minipool_vector_head; mp != NULL; mp = nmp)
5685 + {
5686 + if (mp->refcount > 0)
5687 + {
5688 + if (dump_file)
5689 + {
5690 + fprintf (dump_file,
5691 + ";; Offset %u, min %ld, max %ld ",
5692 + (unsigned) mp->offset, (unsigned long) mp->min_address,
5693 + (unsigned long) mp->max_address);
5694 + avr32_print_value (dump_file, mp->value);
5695 + fputc ('\n', dump_file);
5696 + }
5697 +
5698 + switch (mp->fix_size)
5699 + {
5700 +#ifdef HAVE_consttable_4
5701 + case 4:
5702 + scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
5703 + break;
5704 +
5705 +#endif
5706 +#ifdef HAVE_consttable_8
5707 + case 8:
5708 + scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
5709 + break;
5710 +
5711 +#endif
5712 +#ifdef HAVE_consttable_16
5713 + case 16:
5714 + scan = emit_insn_after (gen_consttable_16 (mp->value), scan);
5715 + break;
5716 +
5717 +#endif
5718 + case 0:
5719 + /* This can happen for force-minipool entries which just are
5720 + there to force the minipool to be generate. */
5721 + break;
5722 + default:
5723 + abort ();
5724 + break;
5725 + }
5726 + }
5727 +
5728 + nmp = mp->next;
5729 + free (mp);
5730 + }
5731 +
5732 + minipool_vector_head = minipool_vector_tail = NULL;
5733 + scan = emit_insn_after (gen_consttable_end (), scan);
5734 + scan = emit_barrier_after (scan);
5735 + }
5736 +
5737 +/* Return the cost of forcibly inserting a barrier after INSN. */
5738 +static int
5739 +avr32_barrier_cost (rtx insn)
5740 + {
5741 + /* Basing the location of the pool on the loop depth is preferable, but at
5742 + the moment, the basic block information seems to be corrupt by this
5743 + stage of the compilation. */
5744 + int base_cost = 50;
5745 + rtx next = next_nonnote_insn (insn);
5746 +
5747 + if (next != NULL && GET_CODE (next) == CODE_LABEL)
5748 + base_cost -= 20;
5749 +
5750 + switch (GET_CODE (insn))
5751 + {
5752 + case CODE_LABEL:
5753 + /* It will always be better to place the table before the label, rather
5754 + than after it. */
5755 + return 50;
5756 +
5757 + case INSN:
5758 + case CALL_INSN:
5759 + return base_cost;
5760 +
5761 + case JUMP_INSN:
5762 + return base_cost - 10;
5763 +
5764 + default:
5765 + return base_cost + 10;
5766 + }
5767 + }
5768 +
5769 +/* Find the best place in the insn stream in the range
5770 + (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
5771 + Create the barrier by inserting a jump and add a new fix entry for
5772 + it. */
5773 +static Mfix *
5774 +create_fix_barrier (Mfix * fix, HOST_WIDE_INT max_address)
5775 +{
5776 + HOST_WIDE_INT count = 0;
5777 + rtx barrier;
5778 + rtx from = fix->insn;
5779 + rtx selected = from;
5780 + int selected_cost;
5781 + HOST_WIDE_INT selected_address;
5782 + Mfix *new_fix;
5783 + HOST_WIDE_INT max_count = max_address - fix->address;
5784 + rtx label = gen_label_rtx ();
5785 +
5786 + selected_cost = avr32_barrier_cost (from);
5787 + selected_address = fix->address;
5788 +
5789 + while (from && count < max_count)
5790 + {
5791 + rtx tmp;
5792 + int new_cost;
5793 +
5794 + /* This code shouldn't have been called if there was a natural barrier
5795 + within range. */
5796 + if (GET_CODE (from) == BARRIER)
5797 + abort ();
5798 +
5799 + /* Count the length of this insn. */
5800 + count += get_attr_length (from);
5801 +
5802 + /* If there is a jump table, add its length. */
5803 + tmp = is_jump_table (from);
5804 + if (tmp != NULL)
5805 + {
5806 + count += get_jump_table_size (tmp);
5807 +
5808 + /* Jump tables aren't in a basic block, so base the cost on the
5809 + dispatch insn. If we select this location, we will still put
5810 + the pool after the table. */
5811 + new_cost = avr32_barrier_cost (from);
5812 +
5813 + if (count < max_count && new_cost <= selected_cost)
5814 + {
5815 + selected = tmp;
5816 + selected_cost = new_cost;
5817 + selected_address = fix->address + count;
5818 + }
5819 +
5820 + /* Continue after the dispatch table. */
5821 + from = NEXT_INSN (tmp);
5822 + continue;
5823 + }
5824 +
5825 + new_cost = avr32_barrier_cost (from);
5826 +
5827 + if (count < max_count && new_cost <= selected_cost)
5828 + {
5829 + selected = from;
5830 + selected_cost = new_cost;
5831 + selected_address = fix->address + count;
5832 + }
5833 +
5834 + from = NEXT_INSN (from);
5835 + }
5836 +
5837 + /* Create a new JUMP_INSN that branches around a barrier. */
5838 + from = emit_jump_insn_after (gen_jump (label), selected);
5839 + JUMP_LABEL (from) = label;
5840 + barrier = emit_barrier_after (from);
5841 + emit_label_after (label, barrier);
5842 +
5843 + /* Create a minipool barrier entry for the new barrier. */
5844 + new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*new_fix));
5845 + new_fix->insn = barrier;
5846 + new_fix->address = selected_address;
5847 + new_fix->next = fix->next;
5848 + fix->next = new_fix;
5849 +
5850 + return new_fix;
5851 +}
5852 +
5853 +/* Record that there is a natural barrier in the insn stream at
5854 + ADDRESS. */
5855 +static void
5856 +push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
5857 + {
5858 + Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
5859 +
5860 + fix->insn = insn;
5861 + fix->address = address;
5862 +
5863 + fix->next = NULL;
5864 + if (minipool_fix_head != NULL)
5865 + minipool_fix_tail->next = fix;
5866 + else
5867 + minipool_fix_head = fix;
5868 +
5869 + minipool_fix_tail = fix;
5870 + }
5871 +
5872 +/* Record INSN, which will need fixing up to load a value from the
5873 + minipool. ADDRESS is the offset of the insn since the start of the
5874 + function; LOC is a pointer to the part of the insn which requires
5875 + fixing; VALUE is the constant that must be loaded, which is of type
5876 + MODE. */
5877 +static void
5878 +push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx * loc,
5879 + enum machine_mode mode, rtx value)
5880 + {
5881 + Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
5882 + rtx body = PATTERN (insn);
5883 +
5884 + fix->insn = insn;
5885 + fix->address = address;
5886 + fix->loc = loc;
5887 + fix->mode = mode;
5888 + fix->fix_size = MINIPOOL_FIX_SIZE (mode, value);
5889 + fix->value = value;
5890 +
5891 + if (GET_CODE (body) == PARALLEL)
5892 + {
5893 + /* Mcall : Ks16 << 2 */
5894 + fix->forwards = ((1 << 15) - 1) << 2;
5895 + fix->backwards = (1 << 15) << 2;
5896 + }
5897 + else if (GET_CODE (body) == SET
5898 + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 4)
5899 + {
5900 + /* Word Load */
5901 + if (TARGET_HARD_FLOAT
5902 + && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT)
5903 + {
5904 + /* Ldc0.w : Ku12 << 2 */
5905 + fix->forwards = ((1 << 12) - 1) << 2;
5906 + fix->backwards = 0;
5907 + }
5908 + else
5909 + {
5910 + if (optimize_size)
5911 + {
5912 + /* Lddpc : Ku7 << 2 */
5913 + fix->forwards = ((1 << 7) - 1) << 2;
5914 + fix->backwards = 0;
5915 + }
5916 + else
5917 + {
5918 + /* Ld.w : Ks16 */
5919 + fix->forwards = ((1 << 15) - 4);
5920 + fix->backwards = (1 << 15);
5921 + }
5922 + }
5923 + }
5924 + else if (GET_CODE (body) == SET
5925 + && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 8)
5926 + {
5927 + /* Double word load */
5928 + if (TARGET_HARD_FLOAT
5929 + && GET_MODE_CLASS (GET_MODE (SET_DEST (body))) == MODE_FLOAT)
5930 + {
5931 + /* Ldc0.d : Ku12 << 2 */
5932 + fix->forwards = ((1 << 12) - 1) << 2;
5933 + fix->backwards = 0;
5934 + }
5935 + else
5936 + {
5937 + /* Ld.d : Ks16 */
5938 + fix->forwards = ((1 << 15) - 4);
5939 + fix->backwards = (1 << 15);
5940 + }
5941 + }
5942 + else if (GET_CODE (body) == UNSPEC_VOLATILE
5943 + && XINT (body, 1) == VUNSPEC_MVRC)
5944 + {
5945 + /* Coprocessor load */
5946 + /* Ldc : Ku8 << 2 */
5947 + fix->forwards = ((1 << 8) - 1) << 2;
5948 + fix->backwards = 0;
5949 + }
5950 + else
5951 + {
5952 + /* Assume worst case which is lddpc insn. */
5953 + fix->forwards = ((1 << 7) - 1) << 2;
5954 + fix->backwards = 0;
5955 + }
5956 +
5957 + fix->minipool = NULL;
5958 +
5959 + /* If an insn doesn't have a range defined for it, then it isn't expecting
5960 + to be reworked by this code. Better to abort now than to generate duff
5961 + assembly code. */
5962 + if (fix->forwards == 0 && fix->backwards == 0)
5963 + abort ();
5964 +
5965 + if (dump_file)
5966 + {
5967 + fprintf (dump_file,
5968 + ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
5969 + GET_MODE_NAME (mode),
5970 + INSN_UID (insn), (unsigned long) address,
5971 + -1 * (long) fix->backwards, (long) fix->forwards);
5972 + avr32_print_value (dump_file, fix->value);
5973 + fprintf (dump_file, "\n");
5974 + }
5975 +
5976 + /* Add it to the chain of fixes. */
5977 + fix->next = NULL;
5978 +
5979 + if (minipool_fix_head != NULL)
5980 + minipool_fix_tail->next = fix;
5981 + else
5982 + minipool_fix_head = fix;
5983 +
5984 + minipool_fix_tail = fix;
5985 + }
5986 +
5987 +/* Scan INSN and note any of its operands that need fixing.
5988 + If DO_PUSHES is false we do not actually push any of the fixups
5989 + needed. The function returns TRUE is any fixups were needed/pushed.
5990 + This is used by avr32_memory_load_p() which needs to know about loads
5991 + of constants that will be converted into minipool loads. */
5992 +static bool
5993 +note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
5994 + {
5995 + bool result = false;
5996 + int opno;
5997 +
5998 + extract_insn (insn);
5999 +
6000 + if (!constrain_operands (1))
6001 + fatal_insn_not_found (insn);
6002 +
6003 + if (recog_data.n_alternatives == 0)
6004 + return false;
6005 +
6006 + /* Fill in recog_op_alt with information about the constraints of this
6007 + insn. */
6008 + preprocess_constraints ();
6009 +
6010 + for (opno = 0; opno < recog_data.n_operands; opno++)
6011 + {
6012 + rtx op;
6013 +
6014 + /* Things we need to fix can only occur in inputs. */
6015 + if (recog_data.operand_type[opno] != OP_IN)
6016 + continue;
6017 +
6018 + op = recog_data.operand[opno];
6019 +
6020 + if (avr32_const_pool_ref_operand (op, GET_MODE (op)))
6021 + {
6022 + if (do_pushes)
6023 + {
6024 + rtx cop = avoid_constant_pool_reference (op);
6025 +
6026 + /* Casting the address of something to a mode narrower than a
6027 + word can cause avoid_constant_pool_reference() to return the
6028 + pool reference itself. That's no good to us here. Lets
6029 + just hope that we can use the constant pool value directly.
6030 + */
6031 + if (op == cop)
6032 + cop = get_pool_constant (XEXP (op, 0));
6033 +
6034 + push_minipool_fix (insn, address,
6035 + recog_data.operand_loc[opno],
6036 + recog_data.operand_mode[opno], cop);
6037 + }
6038 +
6039 + result = true;
6040 + }
6041 + else if (TARGET_HAS_ASM_ADDR_PSEUDOS
6042 + && avr32_address_operand (op, GET_MODE (op)))
6043 + {
6044 + /* Handle pseudo instructions using a direct address. These pseudo
6045 + instructions might need entries in the constant pool and we must
6046 + therefor create a constant pool for them, in case the
6047 + assembler/linker needs to insert entries. */
6048 + if (do_pushes)
6049 + {
6050 + /* Push a dummy constant pool entry so that the .cpool
6051 + directive should be inserted on the appropriate place in the
6052 + code even if there are no real constant pool entries. This
6053 + is used by the assembler and linker to know where to put
6054 + generated constant pool entries. */
6055 + push_minipool_fix (insn, address,
6056 + recog_data.operand_loc[opno],
6057 + recog_data.operand_mode[opno],
6058 + gen_rtx_UNSPEC (VOIDmode,
6059 + gen_rtvec (1, const0_rtx),
6060 + UNSPEC_FORCE_MINIPOOL));
6061 + result = true;
6062 + }
6063 + }
6064 + }
6065 + return result;
6066 + }
6067 +
6068 +
6069 +static int
6070 +avr32_insn_is_cast (rtx insn)
6071 + {
6072 +
6073 + if (NONJUMP_INSN_P (insn)
6074 + && GET_CODE (PATTERN (insn)) == SET
6075 + && (GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTEND
6076 + || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND)
6077 + && REG_P (XEXP (SET_SRC (PATTERN (insn)), 0))
6078 + && REG_P (SET_DEST (PATTERN (insn))))
6079 + return true;
6080 + return false;
6081 + }
6082 +
6083 +/* FIXME: The level of nesting in this function is way too deep. It needs to be
6084 + torn apart. */
6085 +static void
6086 +avr32_reorg_optimization (void)
6087 + {
6088 + rtx first = get_insns ();
6089 + rtx insn;
6090 +
6091 + if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0)))
6092 + {
6093 +
6094 + /* Scan through all insns looking for cast operations. */
6095 + if (dump_file)
6096 + {
6097 + fprintf (dump_file, ";; Deleting redundant cast operations:\n");
6098 + }
6099 + for (insn = first; insn; insn = NEXT_INSN (insn))
6100 + {
6101 + rtx reg, src_reg, scan;
6102 + enum machine_mode mode;
6103 + int unused_cast;
6104 + rtx label_ref;
6105 +
6106 + if (avr32_insn_is_cast (insn)
6107 + && (GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == QImode
6108 + || GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode))
6109 + {
6110 + mode = GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0));
6111 + reg = SET_DEST (PATTERN (insn));
6112 + src_reg = XEXP (SET_SRC (PATTERN (insn)), 0);
6113 + }
6114 + else
6115 + {
6116 + continue;
6117 + }
6118 +
6119 + unused_cast = false;
6120 + label_ref = NULL_RTX;
6121 + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6122 + {
6123 + /* Check if we have reached the destination of a simple
6124 + conditional jump which we have already scanned past. If so,
6125 + we can safely continue scanning. */
6126 + if (LABEL_P (scan) && label_ref != NULL_RTX)
6127 + {
6128 + if (CODE_LABEL_NUMBER (scan) ==
6129 + CODE_LABEL_NUMBER (XEXP (label_ref, 0)))
6130 + label_ref = NULL_RTX;
6131 + else
6132 + break;
6133 + }
6134 +
6135 + if (!INSN_P (scan))
6136 + continue;
6137 +
6138 + /* For conditional jumps we can manage to keep on scanning if
6139 + we meet the destination label later on before any new jump
6140 + insns occure. */
6141 + if (GET_CODE (scan) == JUMP_INSN)
6142 + {
6143 + if (any_condjump_p (scan) && label_ref == NULL_RTX)
6144 + label_ref = condjump_label (scan);
6145 + else
6146 + break;
6147 + }
6148 +
6149 + if (!reg_mentioned_p (reg, PATTERN (scan)))
6150 + continue;
6151 +
6152 + /* Check if casted register is used in this insn */
6153 + if ((regno_use_in (REGNO (reg), PATTERN (scan)) != NULL_RTX)
6154 + && (GET_MODE (regno_use_in (REGNO (reg), PATTERN (scan))) ==
6155 + GET_MODE (reg)))
6156 + {
6157 + /* If not used in the source to the set or in a memory
6158 + expression in the destiantion then the register is used
6159 + as a destination and is really dead. */
6160 + if (single_set (scan)
6161 + && GET_CODE (PATTERN (scan)) == SET
6162 + && REG_P (SET_DEST (PATTERN (scan)))
6163 + && !regno_use_in (REGNO (reg), SET_SRC (PATTERN (scan)))
6164 + && label_ref == NULL_RTX)
6165 + {
6166 + unused_cast = true;
6167 + }
6168 + break;
6169 + }
6170 +
6171 + /* Check if register is dead or set in this insn */
6172 + if (dead_or_set_p (scan, reg))
6173 + {
6174 + unused_cast = true;
6175 + break;
6176 + }
6177 + }
6178 +
6179 + /* Check if we have unresolved conditional jumps */
6180 + if (label_ref != NULL_RTX)
6181 + continue;
6182 +
6183 + if (unused_cast)
6184 + {
6185 + if (REGNO (reg) == REGNO (XEXP (SET_SRC (PATTERN (insn)), 0)))
6186 + {
6187 + /* One operand cast, safe to delete */
6188 + if (dump_file)
6189 + {
6190 + fprintf (dump_file,
6191 + ";; INSN %i removed, casted register %i value not used.\n",
6192 + INSN_UID (insn), REGNO (reg));
6193 + }
6194 + SET_INSN_DELETED (insn);
6195 + /* Force the instruction to be recognized again */
6196 + INSN_CODE (insn) = -1;
6197 + }
6198 + else
6199 + {
6200 + /* Two operand cast, which really could be substituted with
6201 + a move, if the source register is dead after the cast
6202 + insn and then the insn which sets the source register
6203 + could instead directly set the destination register for
6204 + the cast. As long as there are no insns in between which
6205 + uses the register. */
6206 + rtx link = NULL_RTX;
6207 + rtx set;
6208 + rtx src_reg = XEXP (SET_SRC (PATTERN (insn)), 0);
6209 + unused_cast = false;
6210 +
6211 + if (!find_reg_note (insn, REG_DEAD, src_reg))
6212 + continue;
6213 +
6214 + /* Search for the insn which sets the source register */
6215 + for (link = LOG_LINKS (insn); link; link = XEXP (link, 1))
6216 + {
6217 + if (REG_NOTE_KIND (link) != 0)
6218 + continue;
6219 + set = single_set (XEXP (link, 0));
6220 + if (set && rtx_equal_p (src_reg, SET_DEST (set)))
6221 + {
6222 + link = XEXP (link, 0);
6223 + break;
6224 + }
6225 + }
6226 +
6227 + /* Found no link or link is a call insn where we can not
6228 + change the destination register */
6229 + if (link == NULL_RTX || CALL_P (link))
6230 + continue;
6231 +
6232 + /* Scan through all insn between link and insn */
6233 + for (scan = NEXT_INSN (link); scan; scan = NEXT_INSN (scan))
6234 + {
6235 + /* Don't try to trace forward past a CODE_LABEL if we
6236 + haven't seen INSN yet. Ordinarily, we will only
6237 + find the setting insn in LOG_LINKS if it is in the
6238 + same basic block. However, cross-jumping can insert
6239 + code labels in between the load and the call, and
6240 + can result in situations where a single call insn
6241 + may have two targets depending on where we came
6242 + from. */
6243 +
6244 + if (GET_CODE (scan) == CODE_LABEL)
6245 + break;
6246 +
6247 + if (!INSN_P (scan))
6248 + continue;
6249 +
6250 + /* Don't try to trace forward past a JUMP. To optimize
6251 + safely, we would have to check that all the
6252 + instructions at the jump destination did not use REG.
6253 + */
6254 +
6255 + if (GET_CODE (scan) == JUMP_INSN)
6256 + {
6257 + break;
6258 + }
6259 +
6260 + if (!reg_mentioned_p (src_reg, PATTERN (scan)))
6261 + continue;
6262 +
6263 + /* We have reached the cast insn */
6264 + if (scan == insn)
6265 + {
6266 + /* We can remove cast and replace the destination
6267 + register of the link insn with the destination
6268 + of the cast */
6269 + if (dump_file)
6270 + {
6271 + fprintf (dump_file,
6272 + ";; INSN %i removed, casted value unused. "
6273 + "Destination of removed cast operation: register %i, folded into INSN %i.\n",
6274 + INSN_UID (insn), REGNO (reg),
6275 + INSN_UID (link));
6276 + }
6277 + /* Update link insn */
6278 + SET_DEST (PATTERN (link)) =
6279 + gen_rtx_REG (mode, REGNO (reg));
6280 + /* Force the instruction to be recognized again */
6281 + INSN_CODE (link) = -1;
6282 +
6283 + /* Delete insn */
6284 + SET_INSN_DELETED (insn);
6285 + /* Force the instruction to be recognized again */
6286 + INSN_CODE (insn) = -1;
6287 + break;
6288 + }
6289 + }
6290 + }
6291 + }
6292 + }
6293 + }
6294 +
6295 + if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0)))
6296 + {
6297 +
6298 + /* Scan through all insns looking for shifted add operations */
6299 + if (dump_file)
6300 + {
6301 + fprintf (dump_file,
6302 + ";; Deleting redundant shifted add operations:\n");
6303 + }
6304 + for (insn = first; insn; insn = NEXT_INSN (insn))
6305 + {
6306 + rtx reg, mem_expr, scan, op0, op1;
6307 + int add_only_used_as_pointer;
6308 +
6309 + if (INSN_P (insn)
6310 + && GET_CODE (PATTERN (insn)) == SET
6311 + && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
6312 + && (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT
6313 + || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == ASHIFT)
6314 + && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) ==
6315 + CONST_INT && REG_P (SET_DEST (PATTERN (insn)))
6316 + && REG_P (XEXP (SET_SRC (PATTERN (insn)), 1))
6317 + && REG_P (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)))
6318 + {
6319 + reg = SET_DEST (PATTERN (insn));
6320 + mem_expr = SET_SRC (PATTERN (insn));
6321 + op0 = XEXP (XEXP (mem_expr, 0), 0);
6322 + op1 = XEXP (mem_expr, 1);
6323 + }
6324 + else
6325 + {
6326 + continue;
6327 + }
6328 +
6329 + /* Scan forward the check if the result of the shifted add
6330 + operation is only used as an address in memory operations and
6331 + that the operands to the shifted add are not clobbered. */
6332 + add_only_used_as_pointer = false;
6333 + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6334 + {
6335 + if (!INSN_P (scan))
6336 + continue;
6337 +
6338 + /* Don't try to trace forward past a JUMP or CALL. To optimize
6339 + safely, we would have to check that all the instructions at
6340 + the jump destination did not use REG. */
6341 +
6342 + if (GET_CODE (scan) == JUMP_INSN)
6343 + {
6344 + break;
6345 + }
6346 +
6347 + /* If used in a call insn then we cannot optimize it away */
6348 + if (CALL_P (scan) && find_regno_fusage (scan, USE, REGNO (reg)))
6349 + break;
6350 +
6351 + /* If any of the operands of the shifted add are clobbered we
6352 + cannot optimize the shifted adda away */
6353 + if ((reg_set_p (op0, scan) && (REGNO (op0) != REGNO (reg)))
6354 + || (reg_set_p (op1, scan) && (REGNO (op1) != REGNO (reg))))
6355 + break;
6356 +
6357 + if (!reg_mentioned_p (reg, PATTERN (scan)))
6358 + continue;
6359 +
6360 + /* If used any other place than as a pointer or as the
6361 + destination register we failed */
6362 + if (!(single_set (scan)
6363 + && GET_CODE (PATTERN (scan)) == SET
6364 + && ((MEM_P (SET_DEST (PATTERN (scan)))
6365 + && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0))
6366 + && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) ==
6367 + REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan)))
6368 + &&
6369 + REG_P (XEXP
6370 + (SET_SRC (PATTERN (scan)),
6371 + 0))
6372 + &&
6373 + REGNO (XEXP
6374 + (SET_SRC (PATTERN (scan)),
6375 + 0)) == REGNO (reg))))
6376 + && !(GET_CODE (PATTERN (scan)) == SET
6377 + && REG_P (SET_DEST (PATTERN (scan)))
6378 + && !regno_use_in (REGNO (reg),
6379 + SET_SRC (PATTERN (scan)))))
6380 + break;
6381 +
6382 + /* Check if register is dead or set in this insn */
6383 + if (dead_or_set_p (scan, reg))
6384 + {
6385 + add_only_used_as_pointer = true;
6386 + break;
6387 + }
6388 + }
6389 +
6390 + if (add_only_used_as_pointer)
6391 + {
6392 + /* Lets delete the add insn and replace all memory references
6393 + which uses the pointer with the full expression. */
6394 + if (dump_file)
6395 + {
6396 + fprintf (dump_file,
6397 + ";; Deleting INSN %i since address expression can be folded into all "
6398 + "memory references using this expression\n",
6399 + INSN_UID (insn));
6400 + }
6401 + SET_INSN_DELETED (insn);
6402 + /* Force the instruction to be recognized again */
6403 + INSN_CODE (insn) = -1;
6404 +
6405 + for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6406 + {
6407 + if (!INSN_P (scan))
6408 + continue;
6409 +
6410 + if (!reg_mentioned_p (reg, PATTERN (scan)))
6411 + continue;
6412 +
6413 + /* If used any other place than as a pointer or as the
6414 + destination register we failed */
6415 + if ((single_set (scan)
6416 + && GET_CODE (PATTERN (scan)) == SET
6417 + && ((MEM_P (SET_DEST (PATTERN (scan)))
6418 + && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0))
6419 + && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) ==
6420 + REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan)))
6421 + &&
6422 + REG_P (XEXP
6423 + (SET_SRC (PATTERN (scan)),
6424 + 0))
6425 + &&
6426 + REGNO (XEXP
6427 + (SET_SRC (PATTERN (scan)),
6428 + 0)) == REGNO (reg)))))
6429 + {
6430 + if (dump_file)
6431 + {
6432 + fprintf (dump_file,
6433 + ";; Register %i replaced by indexed address in INSN %i\n",
6434 + REGNO (reg), INSN_UID (scan));
6435 + }
6436 + if (MEM_P (SET_DEST (PATTERN (scan))))
6437 + XEXP (SET_DEST (PATTERN (scan)), 0) = mem_expr;
6438 + else
6439 + XEXP (SET_SRC (PATTERN (scan)), 0) = mem_expr;
6440 + }
6441 +
6442 + /* Check if register is dead or set in this insn */
6443 + if (dead_or_set_p (scan, reg))
6444 + {
6445 + break;
6446 + }
6447 +
6448 + }
6449 + }
6450 + }
6451 + }
6452 + }
6453 +
6454 +/* Exported to toplev.c.
6455 +
6456 + Do a final pass over the function, just before delayed branch
6457 + scheduling. */
6458 +
6459 +static void
6460 +avr32_reorg (void)
6461 + {
6462 + rtx insn;
6463 + HOST_WIDE_INT address = 0;
6464 + Mfix *fix;
6465 +
6466 + minipool_fix_head = minipool_fix_tail = NULL;
6467 +
6468 + /* The first insn must always be a note, or the code below won't scan it
6469 + properly. */
6470 + insn = get_insns ();
6471 + if (GET_CODE (insn) != NOTE)
6472 + abort ();
6473 +
6474 + /* Scan all the insns and record the operands that will need fixing. */
6475 + for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
6476 + {
6477 + if (GET_CODE (insn) == BARRIER)
6478 + push_minipool_barrier (insn, address);
6479 + else if (INSN_P (insn))
6480 + {
6481 + rtx table;
6482 +
6483 + note_invalid_constants (insn, address, true);
6484 + address += get_attr_length (insn);
6485 +
6486 + /* If the insn is a vector jump, add the size of the table and skip
6487 + the table. */
6488 + if ((table = is_jump_table (insn)) != NULL)
6489 + {
6490 + address += get_jump_table_size (table);
6491 + insn = table;
6492 + }
6493 + }
6494 + }
6495 +
6496 + fix = minipool_fix_head;
6497 +
6498 + /* Now scan the fixups and perform the required changes. */
6499 + while (fix)
6500 + {
6501 + Mfix *ftmp;
6502 + Mfix *fdel;
6503 + Mfix *last_added_fix;
6504 + Mfix *last_barrier = NULL;
6505 + Mfix *this_fix;
6506 +
6507 + /* Skip any further barriers before the next fix. */
6508 + while (fix && GET_CODE (fix->insn) == BARRIER)
6509 + fix = fix->next;
6510 +
6511 + /* No more fixes. */
6512 + if (fix == NULL)
6513 + break;
6514 +
6515 + last_added_fix = NULL;
6516 +
6517 + for (ftmp = fix; ftmp; ftmp = ftmp->next)
6518 + {
6519 + if (GET_CODE (ftmp->insn) == BARRIER)
6520 + {
6521 + if (ftmp->address >= minipool_vector_head->max_address)
6522 + break;
6523 +
6524 + last_barrier = ftmp;
6525 + }
6526 + else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL)
6527 + break;
6528 +
6529 + last_added_fix = ftmp; /* Keep track of the last fix added.
6530 + */
6531 + }
6532 +
6533 + /* If we found a barrier, drop back to that; any fixes that we could
6534 + have reached but come after the barrier will now go in the next
6535 + mini-pool. */
6536 + if (last_barrier != NULL)
6537 + {
6538 + /* Reduce the refcount for those fixes that won't go into this pool
6539 + after all. */
6540 + for (fdel = last_barrier->next;
6541 + fdel && fdel != ftmp; fdel = fdel->next)
6542 + {
6543 + fdel->minipool->refcount--;
6544 + fdel->minipool = NULL;
6545 + }
6546 +
6547 + ftmp = last_barrier;
6548 + }
6549 + else
6550 + {
6551 + /* ftmp is first fix that we can't fit into this pool and there no
6552 + natural barriers that we could use. Insert a new barrier in the
6553 + code somewhere between the previous fix and this one, and
6554 + arrange to jump around it. */
6555 + HOST_WIDE_INT max_address;
6556 +
6557 + /* The last item on the list of fixes must be a barrier, so we can
6558 + never run off the end of the list of fixes without last_barrier
6559 + being set. */
6560 + if (ftmp == NULL)
6561 + abort ();
6562 +
6563 + max_address = minipool_vector_head->max_address;
6564 + /* Check that there isn't another fix that is in range that we
6565 + couldn't fit into this pool because the pool was already too
6566 + large: we need to put the pool before such an instruction. */
6567 + if (ftmp->address < max_address)
6568 + max_address = ftmp->address;
6569 +
6570 + last_barrier = create_fix_barrier (last_added_fix, max_address);
6571 + }
6572 +
6573 + assign_minipool_offsets (last_barrier);
6574 +
6575 + while (ftmp)
6576 + {
6577 + if (GET_CODE (ftmp->insn) != BARRIER
6578 + && ((ftmp->minipool = add_minipool_backward_ref (ftmp))
6579 + == NULL))
6580 + break;
6581 +
6582 + ftmp = ftmp->next;
6583 + }
6584 +
6585 + /* Scan over the fixes we have identified for this pool, fixing them up
6586 + and adding the constants to the pool itself. */
6587 + for (this_fix = fix; this_fix && ftmp != this_fix;
6588 + this_fix = this_fix->next)
6589 + if (GET_CODE (this_fix->insn) != BARRIER
6590 + /* Do nothing for entries present just to force the insertion of
6591 + a minipool. */
6592 + && !IS_FORCE_MINIPOOL (this_fix->value))
6593 + {
6594 + rtx addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
6595 + minipool_vector_label),
6596 + this_fix->minipool->offset);
6597 + *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
6598 + }
6599 +
6600 + dump_minipool (last_barrier->insn);
6601 + fix = ftmp;
6602 + }
6603 +
6604 + /* Free the minipool memory. */
6605 + obstack_free (&minipool_obstack, minipool_startobj);
6606 +
6607 + avr32_reorg_optimization ();
6608 + }
6609 +
6610 +
6611 +/*
6612 + Hook for doing some final scanning of instructions. Does nothing yet...*/
6613 +void
6614 +avr32_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED,
6615 + rtx * opvec ATTRIBUTE_UNUSED,
6616 + int noperands ATTRIBUTE_UNUSED)
6617 + {
6618 + return;
6619 + }
6620 +
6621 +
6622 +/* Function for changing the condition on the next instruction,
6623 + should be used when emmiting compare instructions and
6624 + the condition of the next instruction needs to change.
6625 + */
6626 +int
6627 +set_next_insn_cond (rtx cur_insn, rtx new_cond)
6628 + {
6629 + rtx next_insn = next_nonnote_insn (cur_insn);
6630 + if ((next_insn != NULL_RTX)
6631 + && (INSN_P (next_insn))
6632 + && (GET_CODE (PATTERN (next_insn)) == SET)
6633 + && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE))
6634 + {
6635 + /* Branch instructions */
6636 + XEXP (SET_SRC (PATTERN (next_insn)), 0) = new_cond;
6637 + /* Force the instruction to be recognized again */
6638 + INSN_CODE (next_insn) = -1;
6639 + return TRUE;
6640 + }
6641 + else if ((next_insn != NULL_RTX)
6642 + && (INSN_P (next_insn))
6643 + && (GET_CODE (PATTERN (next_insn)) == SET)
6644 + && comparison_operator (SET_SRC (PATTERN (next_insn)),
6645 + GET_MODE (SET_SRC (PATTERN (next_insn)))))
6646 + {
6647 + /* scc with no compare */
6648 + SET_SRC (PATTERN (next_insn)) = new_cond;
6649 + /* Force the instruction to be recognized again */
6650 + INSN_CODE (next_insn) = -1;
6651 + return TRUE;
6652 + }
6653 +
6654 + return FALSE;
6655 + }
6656 +
6657 +/* Function for obtaining the condition for the next instruction
6658 + after cur_insn.
6659 + */
6660 +rtx
6661 +get_next_insn_cond (rtx cur_insn)
6662 + {
6663 + rtx next_insn = next_nonnote_insn (cur_insn);
6664 + rtx cond = NULL_RTX;
6665 + if ((next_insn != NULL_RTX)
6666 + && (INSN_P (next_insn))
6667 + && (GET_CODE (PATTERN (next_insn)) == SET)
6668 + && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE))
6669 + {
6670 + /* Branch instructions */
6671 + cond = XEXP (SET_SRC (PATTERN (next_insn)), 0);
6672 + }
6673 + else if ((next_insn != NULL_RTX)
6674 + && (INSN_P (next_insn))
6675 + && (GET_CODE (PATTERN (next_insn)) == SET)
6676 + && comparison_operator (SET_SRC (PATTERN (next_insn)),
6677 + GET_MODE (SET_SRC (PATTERN (next_insn)))))
6678 + {
6679 + /* scc with no compare */
6680 + cond = SET_SRC (PATTERN (next_insn));
6681 + }
6682 +
6683 + return cond;
6684 + }
6685 +
6686 +
6687 +rtx
6688 +avr32_output_cmp (rtx cond, enum machine_mode mode, rtx op0, rtx op1)
6689 + {
6690 +
6691 + rtx new_cond = NULL_RTX;
6692 + rtx ops[2];
6693 + rtx compare_pattern;
6694 + ops[0] = op0;
6695 + ops[1] = op1;
6696 +
6697 + compare_pattern = gen_rtx_COMPARE (mode, op0, op1);
6698 +
6699 + new_cond = is_compare_redundant (compare_pattern, cond);
6700 +
6701 + if (new_cond != NULL_RTX)
6702 + return new_cond;
6703 +
6704 + /* Insert compare */
6705 + switch (mode)
6706 + {
6707 + case QImode:
6708 + output_asm_insn ("cp.b\t%0, %1", ops);
6709 + break;
6710 + case HImode:
6711 + output_asm_insn ("cp.h\t%0, %1", ops);
6712 + break;
6713 + case SImode:
6714 + output_asm_insn ("cp.w\t%0, %1", ops);
6715 + break;
6716 + case DImode:
6717 + if (GET_CODE (op1) != REG)
6718 + output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0", ops);
6719 + else
6720 + output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0, %m1", ops);
6721 + break;
6722 + default:
6723 + internal_error ("Unknown comparison mode");
6724 + break;
6725 + }
6726 +
6727 + return cond;
6728 + }
6729 +
6730 +int
6731 +avr32_load_multiple_operation (rtx op,
6732 + enum machine_mode mode ATTRIBUTE_UNUSED)
6733 + {
6734 + int count = XVECLEN (op, 0);
6735 + unsigned int dest_regno;
6736 + rtx src_addr;
6737 + rtx elt;
6738 + int i = 1, base = 0;
6739 +
6740 + if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
6741 + return 0;
6742 +
6743 + /* Check to see if this might be a write-back. */
6744 + if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
6745 + {
6746 + i++;
6747 + base = 1;
6748 +
6749 + /* Now check it more carefully. */
6750 + if (GET_CODE (SET_DEST (elt)) != REG
6751 + || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
6752 + || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
6753 + || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
6754 + return 0;
6755 + }
6756 +
6757 + /* Perform a quick check so we don't blow up below. */
6758 + if (count <= 1
6759 + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
6760 + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
6761 + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC)
6762 + return 0;
6763 +
6764 + dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
6765 + src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
6766 +
6767 + for (; i < count; i++)
6768 + {
6769 + elt = XVECEXP (op, 0, i);
6770 +
6771 + if (GET_CODE (elt) != SET
6772 + || GET_CODE (SET_DEST (elt)) != REG
6773 + || GET_MODE (SET_DEST (elt)) != SImode
6774 + || GET_CODE (SET_SRC (elt)) != UNSPEC)
6775 + return 0;
6776 + }
6777 +
6778 + return 1;
6779 + }
6780 +
6781 +int
6782 +avr32_store_multiple_operation (rtx op,
6783 + enum machine_mode mode ATTRIBUTE_UNUSED)
6784 + {
6785 + int count = XVECLEN (op, 0);
6786 + int src_regno;
6787 + rtx dest_addr;
6788 + rtx elt;
6789 + int i = 1;
6790 +
6791 + if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
6792 + return 0;
6793 +
6794 + /* Perform a quick check so we don't blow up below. */
6795 + if (count <= i
6796 + || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
6797 + || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
6798 + || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC)
6799 + return 0;
6800 +
6801 + src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
6802 + dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
6803 +
6804 + for (; i < count; i++)
6805 + {
6806 + elt = XVECEXP (op, 0, i);
6807 +
6808 + if (GET_CODE (elt) != SET
6809 + || GET_CODE (SET_DEST (elt)) != MEM
6810 + || GET_MODE (SET_DEST (elt)) != SImode
6811 + || GET_CODE (SET_SRC (elt)) != UNSPEC)
6812 + return 0;
6813 + }
6814 +
6815 + return 1;
6816 + }
6817 +
6818 +int
6819 +avr32_valid_macmac_bypass (rtx insn_out, rtx insn_in)
6820 + {
6821 + /* Check if they use the same accumulator */
6822 + if (rtx_equal_p
6823 + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
6824 + {
6825 + return TRUE;
6826 + }
6827 +
6828 + return FALSE;
6829 + }
6830 +
6831 +int
6832 +avr32_valid_mulmac_bypass (rtx insn_out, rtx insn_in)
6833 + {
6834 + /*
6835 + Check if the mul instruction produces the accumulator for the mac
6836 + instruction. */
6837 + if (rtx_equal_p
6838 + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
6839 + {
6840 + return TRUE;
6841 + }
6842 + return FALSE;
6843 + }
6844 +
6845 +int
6846 +avr32_store_bypass (rtx insn_out, rtx insn_in)
6847 + {
6848 + /* Only valid bypass if the output result is used as an src in the store
6849 + instruction, NOT if used as a pointer or base. */
6850 + if (rtx_equal_p
6851 + (SET_DEST (PATTERN (insn_out)), SET_SRC (PATTERN (insn_in))))
6852 + {
6853 + return TRUE;
6854 + }
6855 +
6856 + return FALSE;
6857 + }
6858 +
6859 +int
6860 +avr32_mul_waw_bypass (rtx insn_out, rtx insn_in)
6861 + {
6862 + /* Check if the register holding the result from the mul instruction is
6863 + used as a result register in the input instruction. */
6864 + if (rtx_equal_p
6865 + (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
6866 + {
6867 + return TRUE;
6868 + }
6869 +
6870 + return FALSE;
6871 + }
6872 +
6873 +int
6874 +avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in)
6875 + {
6876 + /* Check if the first loaded word in insn_out is used in insn_in. */
6877 + rtx dst_reg;
6878 + rtx second_loaded_reg;
6879 +
6880 + /* If this is a double alu operation then the bypass is not valid */
6881 + if ((get_attr_type (insn_in) == TYPE_ALU
6882 + || get_attr_type (insn_in) == TYPE_ALU2)
6883 + && (GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn_out)))) > 4))
6884 + return FALSE;
6885 +
6886 + /* Get the destination register in the load */
6887 + if (!REG_P (SET_DEST (PATTERN (insn_out))))
6888 + return FALSE;
6889 +
6890 + dst_reg = SET_DEST (PATTERN (insn_out));
6891 + second_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 1);
6892 +
6893 + if (!reg_mentioned_p (second_loaded_reg, PATTERN (insn_in)))
6894 + return TRUE;
6895 +
6896 + return FALSE;
6897 + }
6898 +
6899 +
6900 +int
6901 +avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in)
6902 + {
6903 + /*
6904 + Check if the two first loaded word in insn_out are used in insn_in. */
6905 + rtx dst_reg;
6906 + rtx third_loaded_reg, fourth_loaded_reg;
6907 +
6908 + /* Get the destination register in the load */
6909 + if (!REG_P (SET_DEST (PATTERN (insn_out))))
6910 + return FALSE;
6911 +
6912 + dst_reg = SET_DEST (PATTERN (insn_out));
6913 + third_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 2);
6914 + fourth_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 3);
6915 +
6916 + if (!reg_mentioned_p (third_loaded_reg, PATTERN (insn_in))
6917 + && !reg_mentioned_p (fourth_loaded_reg, PATTERN (insn_in)))
6918 + {
6919 + return TRUE;
6920 + }
6921 +
6922 + return FALSE;
6923 + }
6924 +
6925 +
6926 +//section *
6927 +//avr32_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED,
6928 +// rtx x ATTRIBUTE_UNUSED,
6929 +// unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
6930 +// {
6931 +// /* Let ASM_OUTPUT_POOL_PROLOGUE take care of this */
6932 +// return 0;
6933 +// }
6934 +
6935 +
6936 +/* Function for getting an integer value from a const_int or const_double
6937 + expression regardless of the HOST_WIDE_INT size. Each target cpu word
6938 + will be put into the val array where the LSW will be stored at the lowest
6939 + address and so forth. Assumes that const_expr is either a const_int or
6940 + const_double. Only valid for modes which have sizes that are a multiple
6941 + of the word size.
6942 +*/
6943 +void
6944 +avr32_get_intval (enum machine_mode mode,
6945 + rtx const_expr,
6946 + HOST_WIDE_INT *val)
6947 +{
6948 + int words_in_mode = GET_MODE_SIZE (mode)/UNITS_PER_WORD;
6949 + const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD;
6950 +
6951 + if ( GET_CODE(const_expr) == CONST_DOUBLE ){
6952 + HOST_WIDE_INT hi = CONST_DOUBLE_HIGH(const_expr);
6953 + HOST_WIDE_INT lo = CONST_DOUBLE_LOW(const_expr);
6954 + /* Evaluate hi and lo values of const_double. */
6955 + avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0),
6956 + GEN_INT (lo),
6957 + &val[0]);
6958 + avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0),
6959 + GEN_INT (hi),
6960 + &val[words_in_const_int]);
6961 + } else if ( GET_CODE(const_expr) == CONST_INT ){
6962 + HOST_WIDE_INT value = INTVAL(const_expr);
6963 + int word;
6964 + for ( word = 0; (word < words_in_mode) && (word < words_in_const_int); word++ ){
6965 + /* Shift word up to the MSW and shift down again to extract the
6966 + word and sign-extend. */
6967 + int lshift = (words_in_const_int - word - 1) * BITS_PER_WORD;
6968 + int rshift = (words_in_const_int-1) * BITS_PER_WORD;
6969 + val[word] = (value << lshift) >> rshift;
6970 + }
6971 +
6972 + for ( ; word < words_in_mode; word++ ){
6973 + /* Just put the sign bits in the remaining words. */
6974 + val[word] = value < 0 ? -1 : 0;
6975 + }
6976 + }
6977 +}
6978 +
6979 +void
6980 +avr32_split_const_expr (enum machine_mode mode,
6981 + enum machine_mode new_mode,
6982 + rtx expr,
6983 + rtx *split_expr)
6984 +{
6985 + int i, word;
6986 + int words_in_intval = GET_MODE_SIZE (mode)/UNITS_PER_WORD;
6987 + int words_in_split_values = GET_MODE_SIZE (new_mode)/UNITS_PER_WORD;
6988 + const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD;
6989 + HOST_WIDE_INT *val = alloca (words_in_intval * UNITS_PER_WORD);
6990 +
6991 + avr32_get_intval (mode, expr, val);
6992 +
6993 + for ( i=0; i < (words_in_intval/words_in_split_values); i++ )
6994 + {
6995 + HOST_WIDE_INT value_lo = 0, value_hi = 0;
6996 + for ( word = 0; word < words_in_split_values; word++ )
6997 + {
6998 + if ( word >= words_in_const_int )
6999 + value_hi |= ((val[i * words_in_split_values + word] &
7000 + (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1))
7001 + << (BITS_PER_WORD * (word - words_in_const_int)));
7002 + else
7003 + value_lo |= ((val[i * words_in_split_values + word] &
7004 + (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1))
7005 + << (BITS_PER_WORD * word));
7006 + }
7007 + split_expr[i] = immed_double_const(value_lo, value_hi, new_mode);
7008 + }
7009 +}
7010 +
7011 +
7012 +
7013 +/* Set up library functions to comply to AVR32 ABI */
7014 +
7015 +
7016 +/* Set up library functions to comply to AVR32 ABI */
7017 +
7018 +static void
7019 +avr32_init_libfuncs (void)
7020 +{
7021 + /* Convert gcc run-time function names to AVR32 ABI names */
7022 +
7023 + /* Double-precision floating-point arithmetic. */
7024 + set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div");
7025 + set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul");
7026 + set_optab_libfunc (neg_optab, DFmode, NULL);
7027 +
7028 + /* Double-precision comparisons. */
7029 + set_optab_libfunc (eq_optab, DFmode, "__avr32_f64_cmp_eq");
7030 + set_optab_libfunc (ne_optab, DFmode, NULL);
7031 + set_optab_libfunc (lt_optab, DFmode, "__avr32_f64_cmp_lt");
7032 + set_optab_libfunc (le_optab, DFmode, NULL);
7033 + set_optab_libfunc (ge_optab, DFmode, "__avr32_f64_cmp_ge");
7034 + set_optab_libfunc (gt_optab, DFmode, NULL);
7035 +
7036 + /* Single-precision floating-point arithmetic. */
7037 + set_optab_libfunc (smul_optab, SFmode, "__avr32_f32_mul");
7038 + set_optab_libfunc (neg_optab, SFmode, NULL);
7039 +
7040 + /* Single-precision comparisons. */
7041 + set_optab_libfunc (eq_optab, SFmode, "__avr32_f32_cmp_eq");
7042 + set_optab_libfunc (ne_optab, SFmode, NULL);
7043 + set_optab_libfunc (lt_optab, SFmode, "__avr32_f32_cmp_lt");
7044 + set_optab_libfunc (le_optab, SFmode, NULL);
7045 + set_optab_libfunc (ge_optab, SFmode, "__avr32_f32_cmp_ge");
7046 + set_optab_libfunc (gt_optab, SFmode, NULL);
7047 +
7048 + /* Floating-point to integer conversions. */
7049 + set_conv_libfunc (sfix_optab, SImode, DFmode, "__avr32_f64_to_s32");
7050 + set_conv_libfunc (ufix_optab, SImode, DFmode, "__avr32_f64_to_u32");
7051 + set_conv_libfunc (sfix_optab, DImode, DFmode, "__avr32_f64_to_s64");
7052 + set_conv_libfunc (ufix_optab, DImode, DFmode, "__avr32_f64_to_u64");
7053 + set_conv_libfunc (sfix_optab, SImode, SFmode, "__avr32_f32_to_s32");
7054 + set_conv_libfunc (ufix_optab, SImode, SFmode, "__avr32_f32_to_u32");
7055 + set_conv_libfunc (sfix_optab, DImode, SFmode, "__avr32_f32_to_s64");
7056 + set_conv_libfunc (ufix_optab, DImode, SFmode, "__avr32_f32_to_u64");
7057 +
7058 + /* Conversions between floating types. */
7059 + set_conv_libfunc (trunc_optab, SFmode, DFmode, "__avr32_f64_to_f32");
7060 + set_conv_libfunc (sext_optab, DFmode, SFmode, "__avr32_f32_to_f64");
7061 +
7062 + /* Integer to floating-point conversions. Table 8. */
7063 + set_conv_libfunc (sfloat_optab, DFmode, SImode, "__avr32_s32_to_f64");
7064 + set_conv_libfunc (sfloat_optab, DFmode, DImode, "__avr32_s64_to_f64");
7065 + set_conv_libfunc (sfloat_optab, SFmode, SImode, "__avr32_s32_to_f32");
7066 + set_conv_libfunc (sfloat_optab, SFmode, DImode, "__avr32_s64_to_f32");
7067 + set_conv_libfunc (ufloat_optab, DFmode, SImode, "__avr32_u32_to_f64");
7068 + set_conv_libfunc (ufloat_optab, SFmode, SImode, "__avr32_u32_to_f32");
7069 + /* TODO: Add these to gcc library functions */
7070 + //set_conv_libfunc (ufloat_optab, DFmode, DImode, NULL);
7071 + //set_conv_libfunc (ufloat_optab, SFmode, DImode, NULL);
7072 +
7073 + /* Long long. Table 9. */
7074 + set_optab_libfunc (smul_optab, DImode, "__avr32_mul64");
7075 + set_optab_libfunc (sdiv_optab, DImode, "__avr32_sdiv64");
7076 + set_optab_libfunc (udiv_optab, DImode, "__avr32_udiv64");
7077 + set_optab_libfunc (smod_optab, DImode, "__avr32_smod64");
7078 + set_optab_libfunc (umod_optab, DImode, "__avr32_umod64");
7079 + set_optab_libfunc (ashl_optab, DImode, "__avr32_lsl64");
7080 + set_optab_libfunc (lshr_optab, DImode, "__avr32_lsr64");
7081 + set_optab_libfunc (ashr_optab, DImode, "__avr32_asr64");
7082 +
7083 + /* Floating point library functions which have fast versions. */
7084 + if ( TARGET_FAST_FLOAT )
7085 + {
7086 + set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add_fast");
7087 + set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub_fast");
7088 + set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add_fast");
7089 + set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub_fast");
7090 + set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div_fast");
7091 + }
7092 + else
7093 + {
7094 + set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add");
7095 + set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub");
7096 + set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add");
7097 + set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub");
7098 + set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div");
7099 + }
7100 +}
7101 +
7102 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32-elf.h gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-elf.h
7103 --- gcc-4.2.1/gcc/config/avr32/avr32-elf.h 1970-01-01 01:00:00.000000000 +0100
7104 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-elf.h 2007-09-28 10:33:00.000000000 +0200
7105 @@ -0,0 +1,84 @@
7106 +/*
7107 + Elf specific definitions.
7108 + Copyright 2003-2006 Atmel Corporation.
7109 +
7110 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
7111 +
7112 + This file is part of GCC.
7113 +
7114 + This program is free software; you can redistribute it and/or modify
7115 + it under the terms of the GNU General Public License as published by
7116 + the Free Software Foundation; either version 2 of the License, or
7117 + (at your option) any later version.
7118 +
7119 + This program is distributed in the hope that it will be useful,
7120 + but WITHOUT ANY WARRANTY; without even the implied warranty of
7121 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7122 + GNU General Public License for more details.
7123 +
7124 + You should have received a copy of the GNU General Public License
7125 + along with this program; if not, write to the Free Software
7126 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
7127 +
7128 +
7129 +/*****************************************************************************
7130 + * Controlling the Compilator Driver, 'gcc'
7131 + *****************************************************************************/
7132 +
7133 +/* Run-time Target Specification. */
7134 +#undef TARGET_VERSION
7135 +#define TARGET_VERSION fputs (" (AVR32 GNU with ELF)", stderr);
7136 +
7137 +/*
7138 +Another C string constant used much like LINK_SPEC. The
7139 +difference between the two is that STARTFILE_SPEC is used at
7140 +the very beginning of the command given to the linker.
7141 +
7142 +If this macro is not defined, a default is provided that loads the
7143 +standard C startup file from the usual place. See gcc.c.
7144 +*/
7145 +#undef STARTFILE_SPEC
7146 +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s"
7147 +
7148 +#undef LINK_SPEC
7149 +#define LINK_SPEC "%{muse-oscall:--defsym __do_not_use_oscall_coproc__=0} %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}} %{mpart=*:-mavr32elf_%*} %{mcpu=*:-mavr32elf_%*}"
7150 +
7151 +
7152 +/*
7153 +Another C string constant used much like LINK_SPEC. The
7154 +difference between the two is that ENDFILE_SPEC is used at
7155 +the very end of the command given to the linker.
7156 +
7157 +Do not define this macro if it does not need to do anything.
7158 +*/
7159 +#undef ENDFILE_SPEC
7160 +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
7161 +
7162 +
7163 +/* Target CPU builtins. */
7164 +#define TARGET_CPU_CPP_BUILTINS() \
7165 + do \
7166 + { \
7167 + builtin_define ("__avr32__"); \
7168 + builtin_define ("__AVR32__"); \
7169 + builtin_define ("__AVR32_ELF__"); \
7170 + builtin_define (avr32_part->macro); \
7171 + builtin_define (avr32_arch->macro); \
7172 + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \
7173 + builtin_define ("__AVR32_AVR32A__"); \
7174 + else \
7175 + builtin_define ("__AVR32_AVR32B__"); \
7176 + if (TARGET_UNALIGNED_WORD) \
7177 + builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \
7178 + if (TARGET_SIMD) \
7179 + builtin_define ("__AVR32_HAS_SIMD__"); \
7180 + if (TARGET_DSP) \
7181 + builtin_define ("__AVR32_HAS_DSP__"); \
7182 + if (TARGET_RMW) \
7183 + builtin_define ("__AVR32_HAS_RMW__"); \
7184 + if (TARGET_BRANCH_PRED) \
7185 + builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \
7186 + if (TARGET_FAST_FLOAT) \
7187 + builtin_define ("__AVR32_FAST_FLOAT__"); \
7188 + } \
7189 + while (0)
7190 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32.h gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.h
7191 --- gcc-4.2.1/gcc/config/avr32/avr32.h 1970-01-01 01:00:00.000000000 +0100
7192 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.h 2007-09-28 10:33:00.000000000 +0200
7193 @@ -0,0 +1,3281 @@
7194 +/*
7195 + Definitions of target machine for AVR32.
7196 + Copyright 2003-2006 Atmel Corporation.
7197 +
7198 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
7199 + Initial porting by Anders �dland.
7200 +
7201 + This file is part of GCC.
7202 +
7203 + This program is free software; you can redistribute it and/or modify
7204 + it under the terms of the GNU General Public License as published by
7205 + the Free Software Foundation; either version 2 of the License, or
7206 + (at your option) any later version.
7207 +
7208 + This program is distributed in the hope that it will be useful,
7209 + but WITHOUT ANY WARRANTY; without even the implied warranty of
7210 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7211 + GNU General Public License for more details.
7212 +
7213 + You should have received a copy of the GNU General Public License
7214 + along with this program; if not, write to the Free Software
7215 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
7216 +
7217 +#ifndef GCC_AVR32_H
7218 +#define GCC_AVR32_H
7219 +
7220 +
7221 +#ifndef OBJECT_FORMAT_ELF
7222 +#error avr32.h included before elfos.h
7223 +#endif
7224 +
7225 +#ifndef LOCAL_LABEL_PREFIX
7226 +#define LOCAL_LABEL_PREFIX "."
7227 +#endif
7228 +
7229 +#ifndef SUBTARGET_CPP_SPEC
7230 +#define SUBTARGET_CPP_SPEC "-D__ELF__"
7231 +#endif
7232 +
7233 +
7234 +extern struct rtx_def *avr32_compare_op0;
7235 +extern struct rtx_def *avr32_compare_op1;
7236 +
7237 +
7238 +extern struct rtx_def *avr32_acc_cache;
7239 +
7240 +/* cache instruction op5 codes */
7241 +#define AVR32_CACHE_INVALIDATE_ICACHE 1
7242 +
7243 +/* These bits describe the different types of function supported
7244 + by the AVR32 backend. They are exclusive. ie a function cannot be both a
7245 + normal function and an interworked function, for example. Knowing the
7246 + type of a function is important for determining its prologue and
7247 + epilogue sequences.
7248 + Note value 7 is currently unassigned. Also note that the interrupt
7249 + function types all have bit 2 set, so that they can be tested for easily.
7250 + Note that 0 is deliberately chosen for AVR32_FT_UNKNOWN so that when the
7251 + machine_function structure is initialized (to zero) func_type will
7252 + default to unknown. This will force the first use of avr32_current_func_type
7253 + to call avr32_compute_func_type. */
7254 +#define AVR32_FT_UNKNOWN 0 /* Type has not yet been determined.
7255 + */
7256 +#define AVR32_FT_NORMAL 1 /* Your normal, straightforward
7257 + function. */
7258 +#define AVR32_FT_ACALL 2 /* An acall function. */
7259 +#define AVR32_FT_EXCEPTION_HANDLER 3 /* A C++ exception handler. */
7260 +#define AVR32_FT_ISR_FULL 4 /* A fully shadowed interrupt mode. */
7261 +#define AVR32_FT_ISR_HALF 5 /* A half shadowed interrupt mode. */
7262 +#define AVR32_FT_ISR_NONE 6 /* No shadow registers. */
7263 +
7264 +#define AVR32_FT_TYPE_MASK ((1 << 3) - 1)
7265 +
7266 +/* In addition functions can have several type modifiers,
7267 + outlined by these bit masks: */
7268 +#define AVR32_FT_INTERRUPT (1 << 2) /* Note overlap with FT_ISR
7269 + and above. */
7270 +#define AVR32_FT_NAKED (1 << 3) /* No prologue or epilogue. */
7271 +#define AVR32_FT_VOLATILE (1 << 4) /* Does not return. */
7272 +#define AVR32_FT_NESTED (1 << 5) /* Embedded inside another
7273 + func. */
7274 +
7275 +/* Some macros to test these flags. */
7276 +#define AVR32_FUNC_TYPE(t) (t & AVR32_FT_TYPE_MASK)
7277 +#define IS_INTERRUPT(t) (t & AVR32_FT_INTERRUPT)
7278 +#define IS_VOLATILE(t) (t & AVR32_FT_VOLATILE)
7279 +#define IS_NAKED(t) (t & AVR32_FT_NAKED)
7280 +#define IS_NESTED(t) (t & AVR32_FT_NESTED)
7281 +
7282 +
7283 +typedef struct minipool_labels
7284 +GTY ((chain_next ("%h.next"), chain_prev ("%h.prev")))
7285 +{
7286 + rtx label;
7287 + struct minipool_labels *prev;
7288 + struct minipool_labels *next;
7289 +} minipool_labels;
7290 +
7291 +/* A C structure for machine-specific, per-function data.
7292 + This is added to the cfun structure. */
7293 +
7294 +typedef struct machine_function
7295 +GTY (())
7296 +{
7297 + /* Records the type of the current function. */
7298 + unsigned long func_type;
7299 + /* List of minipool labels, use for checking if code label is valid in a
7300 + memory expression */
7301 + minipool_labels *minipool_label_head;
7302 + minipool_labels *minipool_label_tail;
7303 +} machine_function;
7304 +
7305 +/* Initialize data used by insn expanders. This is called from insn_emit,
7306 + once for every function before code is generated. */
7307 +#define INIT_EXPANDERS avr32_init_expanders ()
7308 +
7309 +/******************************************************************************
7310 + * SPECS
7311 + *****************************************************************************/
7312 +
7313 +#ifndef ASM_SPEC
7314 +#define ASM_SPEC "%{fpic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{march=*:-march=%*} %{mpart=*:-mpart=%*}"
7315 +#endif
7316 +
7317 +#ifndef MULTILIB_DEFAULTS
7318 +#define MULTILIB_DEFAULTS { "march=ap", "" }
7319 +#endif
7320 +
7321 +/******************************************************************************
7322 + * Run-time Target Specification
7323 + *****************************************************************************/
7324 +#ifndef TARGET_VERSION
7325 +#define TARGET_VERSION fprintf(stderr, " (AVR32, GNU assembler syntax)");
7326 +#endif
7327 +
7328 +/* Part types. Keep this in sync with the order of avr32_part_types in avr32.c*/
7329 +enum part_type
7330 +{
7331 + PART_TYPE_AVR32_NONE,
7332 + PART_TYPE_AVR32_AP7000,
7333 + PART_TYPE_AVR32_AP7010,
7334 + PART_TYPE_AVR32_AP7020,
7335 + PART_TYPE_AVR32_UC3A0256,
7336 + PART_TYPE_AVR32_UC3A0512,
7337 + PART_TYPE_AVR32_UC3A1128,
7338 + PART_TYPE_AVR32_UC3A1256,
7339 + PART_TYPE_AVR32_UC3A1512,
7340 + PART_TYPE_AVR32_UC3B064,
7341 + PART_TYPE_AVR32_UC3B0128,
7342 + PART_TYPE_AVR32_UC3B0256,
7343 + PART_TYPE_AVR32_UC3B164,
7344 + PART_TYPE_AVR32_UC3B1128,
7345 + PART_TYPE_AVR32_UC3B1256
7346 +};
7347 +
7348 +/* Microarchitectures. */
7349 +enum microarchitecture_type
7350 +{
7351 + UARCH_TYPE_AVR32A,
7352 + UARCH_TYPE_AVR32B,
7353 + UARCH_TYPE_NONE
7354 +};
7355 +
7356 +/* Architectures types which specifies the pipeline.
7357 + Keep this in sync with avr32_arch_types in avr32.c
7358 + and the pipeline attribute in avr32.md */
7359 +enum architecture_type
7360 +{
7361 + ARCH_TYPE_AVR32_AP,
7362 + ARCH_TYPE_AVR32_UC,
7363 + ARCH_TYPE_AVR32_NONE
7364 +};
7365 +
7366 +/* Flag specifying if the cpu has support for DSP instructions.*/
7367 +#define FLAG_AVR32_HAS_DSP (1 << 0)
7368 +/* Flag specifying if the cpu has support for Read-Modify-Write
7369 + instructions.*/
7370 +#define FLAG_AVR32_HAS_RMW (1 << 1)
7371 +/* Flag specifying if the cpu has support for SIMD instructions. */
7372 +#define FLAG_AVR32_HAS_SIMD (1 << 2)
7373 +/* Flag specifying if the cpu has support for unaligned memory word access. */
7374 +#define FLAG_AVR32_HAS_UNALIGNED_WORD (1 << 3)
7375 +/* Flag specifying if the cpu has support for branch prediction. */
7376 +#define FLAG_AVR32_HAS_BRANCH_PRED (1 << 4)
7377 +/* Flag specifying if the cpu has support for a return stack. */
7378 +#define FLAG_AVR32_HAS_RETURN_STACK (1 << 5)
7379 +/* Flag specifying if the cpu has caches. */
7380 +#define FLAG_AVR32_HAS_CACHES (1 << 6)
7381 +
7382 +/* Structure for holding information about different avr32 CPUs/parts */
7383 +struct part_type_s
7384 +{
7385 + const char *const name;
7386 + enum part_type part_type;
7387 + enum architecture_type arch_type;
7388 + /* Must lie outside user's namespace. NULL == no macro. */
7389 + const char *const macro;
7390 +};
7391 +
7392 +/* Structure for holding information about different avr32 pipeline
7393 + architectures. */
7394 +struct arch_type_s
7395 +{
7396 + const char *const name;
7397 + enum architecture_type arch_type;
7398 + enum microarchitecture_type uarch_type;
7399 + const unsigned long feature_flags;
7400 + /* Must lie outside user's namespace. NULL == no macro. */
7401 + const char *const macro;
7402 +};
7403 +
7404 +extern const struct part_type_s *avr32_part;
7405 +extern const struct arch_type_s *avr32_arch;
7406 +
7407 +#define TARGET_SIMD (avr32_arch->feature_flags & FLAG_AVR32_HAS_SIMD)
7408 +#define TARGET_DSP (avr32_arch->feature_flags & FLAG_AVR32_HAS_DSP)
7409 +#define TARGET_RMW (avr32_arch->feature_flags & FLAG_AVR32_HAS_RMW)
7410 +#define TARGET_UNALIGNED_WORD (avr32_arch->feature_flags & FLAG_AVR32_HAS_UNALIGNED_WORD)
7411 +#define TARGET_BRANCH_PRED (avr32_arch->feature_flags & FLAG_AVR32_HAS_BRANCH_PRED)
7412 +#define TARGET_RETURN_STACK (avr32_arch->feature_flags & FLAG_AVR32_HAS_RETURN_STACK)
7413 +#define TARGET_CACHES (avr32_arch->feature_flags & FLAG_AVR32_HAS_CACHES)
7414 +
7415 +#define CAN_DEBUG_WITHOUT_FP
7416 +
7417 +/******************************************************************************
7418 + * Storage Layout
7419 + *****************************************************************************/
7420 +
7421 +/*
7422 +Define this macro to have the value 1 if the most significant bit in a
7423 +byte has the lowest number; otherwise define it to have the value zero.
7424 +This means that bit-field instructions count from the most significant
7425 +bit. If the machine has no bit-field instructions, then this must still
7426 +be defined, but it doesn't matter which value it is defined to. This
7427 +macro need not be a constant.
7428 +
7429 +This macro does not affect the way structure fields are packed into
7430 +bytes or words; that is controlled by BYTES_BIG_ENDIAN.
7431 +*/
7432 +#define BITS_BIG_ENDIAN 0
7433 +
7434 +/*
7435 +Define this macro to have the value 1 if the most significant byte in a
7436 +word has the lowest number. This macro need not be a constant.
7437 +*/
7438 +/*
7439 + Data is stored in an big-endian way.
7440 +*/
7441 +#define BYTES_BIG_ENDIAN 1
7442 +
7443 +/*
7444 +Define this macro to have the value 1 if, in a multiword object, the
7445 +most significant word has the lowest number. This applies to both
7446 +memory locations and registers; GCC fundamentally assumes that the
7447 +order of words in memory is the same as the order in registers. This
7448 +macro need not be a constant.
7449 +*/
7450 +/*
7451 + Data is stored in an bin-endian way.
7452 +*/
7453 +#define WORDS_BIG_ENDIAN 1
7454 +
7455 +/*
7456 +Define this macro if WORDS_BIG_ENDIAN is not constant. This must be a
7457 +constant value with the same meaning as WORDS_BIG_ENDIAN, which will be
7458 +used only when compiling libgcc2.c. Typically the value will be set
7459 +based on preprocessor defines.
7460 +*/
7461 +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
7462 +
7463 +/*
7464 +Define this macro to have the value 1 if DFmode, XFmode or
7465 +TFmode floating point numbers are stored in memory with the word
7466 +containing the sign bit at the lowest address; otherwise define it to
7467 +have the value 0. This macro need not be a constant.
7468 +
7469 +You need not define this macro if the ordering is the same as for
7470 +multi-word integers.
7471 +*/
7472 +/* #define FLOAT_WORDS_BIG_ENDIAN 1 */
7473 +
7474 +/*
7475 +Define this macro to be the number of bits in an addressable storage
7476 +unit (byte); normally 8.
7477 +*/
7478 +#define BITS_PER_UNIT 8
7479 +
7480 +/*
7481 +Number of bits in a word; normally 32.
7482 +*/
7483 +#define BITS_PER_WORD 32
7484 +
7485 +/*
7486 +Maximum number of bits in a word. If this is undefined, the default is
7487 +BITS_PER_WORD. Otherwise, it is the constant value that is the
7488 +largest value that BITS_PER_WORD can have at run-time.
7489 +*/
7490 +/* MAX_BITS_PER_WORD not defined*/
7491 +
7492 +/*
7493 +Number of storage units in a word; normally 4.
7494 +*/
7495 +#define UNITS_PER_WORD 4
7496 +
7497 +/*
7498 +Minimum number of units in a word. If this is undefined, the default is
7499 +UNITS_PER_WORD. Otherwise, it is the constant value that is the
7500 +smallest value that UNITS_PER_WORD can have at run-time.
7501 +*/
7502 +/* MIN_UNITS_PER_WORD not defined */
7503 +
7504 +/*
7505 +Width of a pointer, in bits. You must specify a value no wider than the
7506 +width of Pmode. If it is not equal to the width of Pmode,
7507 +you must define POINTERS_EXTEND_UNSIGNED.
7508 +*/
7509 +#define POINTER_SIZE 32
7510 +
7511 +/*
7512 +A C expression whose value is greater than zero if pointers that need to be
7513 +extended from being POINTER_SIZE bits wide to Pmode are to
7514 +be zero-extended and zero if they are to be sign-extended. If the value
7515 +is less then zero then there must be an "ptr_extend" instruction that
7516 +extends a pointer from POINTER_SIZE to Pmode.
7517 +
7518 +You need not define this macro if the POINTER_SIZE is equal
7519 +to the width of Pmode.
7520 +*/
7521 +/* #define POINTERS_EXTEND_UNSIGNED */
7522 +
7523 +/*
7524 +A Macro to update M and UNSIGNEDP when an object whose type
7525 +is TYPE and which has the specified mode and signedness is to be
7526 +stored in a register. This macro is only called when TYPE is a
7527 +scalar type.
7528 +
7529 +On most RISC machines, which only have operations that operate on a full
7530 +register, define this macro to set M to word_mode if
7531 +M is an integer mode narrower than BITS_PER_WORD. In most
7532 +cases, only integer modes should be widened because wider-precision
7533 +floating-point operations are usually more expensive than their narrower
7534 +counterparts.
7535 +
7536 +For most machines, the macro definition does not change UNSIGNEDP.
7537 +However, some machines, have instructions that preferentially handle
7538 +either signed or unsigned quantities of certain modes. For example, on
7539 +the DEC Alpha, 32-bit loads from memory and 32-bit add instructions
7540 +sign-extend the result to 64 bits. On such machines, set
7541 +UNSIGNEDP according to which kind of extension is more efficient.
7542 +
7543 +Do not define this macro if it would never modify M.
7544 +*/
7545 +#define PROMOTE_MODE(M, UNSIGNEDP, TYPE) \
7546 + { \
7547 + if (GET_MODE_CLASS (M) == MODE_INT \
7548 + && GET_MODE_SIZE (M) < 4) \
7549 + { \
7550 + if (M == QImode) \
7551 + UNSIGNEDP = 1; \
7552 + else if (M == SImode) \
7553 + UNSIGNEDP = 0; \
7554 + (M) = SImode; \
7555 + } \
7556 + }
7557 +
7558 +#define PROMOTE_FUNCTION_MODE(M, UNSIGNEDP, TYPE) \
7559 + { \
7560 + if (GET_MODE_CLASS (M) == MODE_INT \
7561 + && GET_MODE_SIZE (M) < 4) \
7562 + { \
7563 + (M) = SImode; \
7564 + } \
7565 + }
7566 +
7567 +/* Define if operations between registers always perform the operation
7568 + on the full register even if a narrower mode is specified. */
7569 +#define WORD_REGISTER_OPERATIONS
7570 +
7571 +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
7572 + will either zero-extend or sign-extend. The value of this macro should
7573 + be the code that says which one of the two operations is implicitly
7574 + done, UNKNOWN if not known. */
7575 +#define LOAD_EXTEND_OP(MODE) \
7576 + (((MODE) == QImode) ? ZERO_EXTEND \
7577 + : ((MODE) == HImode) ? SIGN_EXTEND : UNKNOWN)
7578 +
7579 +
7580 +/*
7581 +Define this macro if the promotion described by PROMOTE_MODE
7582 +should only be performed for outgoing function arguments or
7583 +function return values, as specified by PROMOTE_FUNCTION_ARGS
7584 +and PROMOTE_FUNCTION_RETURN, respectively.
7585 +*/
7586 +/* #define PROMOTE_FOR_CALL_ONLY */
7587 +
7588 +/*
7589 +Normal alignment required for function parameters on the stack, in
7590 +bits. All stack parameters receive at least this much alignment
7591 +regardless of data type. On most machines, this is the same as the
7592 +size of an integer.
7593 +*/
7594 +#define PARM_BOUNDARY 32
7595 +
7596 +/*
7597 +Define this macro to the minimum alignment enforced by hardware for the
7598 +stack pointer on this machine. The definition is a C expression for the
7599 +desired alignment (measured in bits). This value is used as a default
7600 +if PREFERRED_STACK_BOUNDARY is not defined. On most machines,
7601 +this should be the same as PARM_BOUNDARY.
7602 +*/
7603 +#define STACK_BOUNDARY 32
7604 +
7605 +/*
7606 +Define this macro if you wish to preserve a certain alignment for the
7607 +stack pointer, greater than what the hardware enforces. The definition
7608 +is a C expression for the desired alignment (measured in bits). This
7609 +macro must evaluate to a value equal to or larger than
7610 +STACK_BOUNDARY.
7611 +*/
7612 +#define PREFERRED_STACK_BOUNDARY (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 )
7613 +
7614 +/*
7615 +Alignment required for a function entry point, in bits.
7616 +*/
7617 +#define FUNCTION_BOUNDARY 16
7618 +
7619 +/*
7620 +Biggest alignment that any data type can require on this machine, in bits.
7621 +*/
7622 +#define BIGGEST_ALIGNMENT (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 )
7623 +
7624 +/*
7625 +If defined, the smallest alignment, in bits, that can be given to an
7626 +object that can be referenced in one operation, without disturbing any
7627 +nearby object. Normally, this is BITS_PER_UNIT, but may be larger
7628 +on machines that don't have byte or half-word store operations.
7629 +*/
7630 +#define MINIMUM_ATOMIC_ALIGNMENT BITS_PER_UNIT
7631 +
7632 +
7633 +/*
7634 +An integer expression for the size in bits of the largest integer machine mode that
7635 +should actually be used. All integer machine modes of this size or smaller can be
7636 +used for structures and unions with the appropriate sizes. If this macro is undefined,
7637 +GET_MODE_BITSIZE (DImode) is assumed.*/
7638 +#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode)
7639 +
7640 +
7641 +/*
7642 +If defined, a C expression to compute the alignment given to a constant
7643 +that is being placed in memory. CONSTANT is the constant and
7644 +BASIC_ALIGN is the alignment that the object would ordinarily
7645 +have. The value of this macro is used instead of that alignment to
7646 +align the object.
7647 +
7648 +If this macro is not defined, then BASIC_ALIGN is used.
7649 +
7650 +The typical use of this macro is to increase alignment for string
7651 +constants to be word aligned so that strcpy calls that copy
7652 +constants can be done inline.
7653 +*/
7654 +#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \
7655 + ((TREE_CODE(CONSTANT) == STRING_CST) ? BITS_PER_WORD : BASIC_ALIGN)
7656 +
7657 +/* Try to align string to a word. */
7658 +#define DATA_ALIGNMENT(TYPE, ALIGN) \
7659 + ({(TREE_CODE (TYPE) == ARRAY_TYPE \
7660 + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
7661 + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));})
7662 +
7663 +/* Try to align local store strings to a word. */
7664 +#define LOCAL_ALIGNMENT(TYPE, ALIGN) \
7665 + ({(TREE_CODE (TYPE) == ARRAY_TYPE \
7666 + && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
7667 + && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));})
7668 +
7669 +/*
7670 +Define this macro to be the value 1 if instructions will fail to work
7671 +if given data not on the nominal alignment. If instructions will merely
7672 +go slower in that case, define this macro as 0.
7673 +*/
7674 +#define STRICT_ALIGNMENT 1
7675 +
7676 +/*
7677 +Define this if you wish to imitate the way many other C compilers handle
7678 +alignment of bit-fields and the structures that contain them.
7679 +
7680 +The behavior is that the type written for a bit-field (int,
7681 +short, or other integer type) imposes an alignment for the
7682 +entire structure, as if the structure really did contain an ordinary
7683 +field of that type. In addition, the bit-field is placed within the
7684 +structure so that it would fit within such a field, not crossing a
7685 +boundary for it.
7686 +
7687 +Thus, on most machines, a bit-field whose type is written as int
7688 +would not cross a four-byte boundary, and would force four-byte
7689 +alignment for the whole structure. (The alignment used may not be four
7690 +bytes; it is controlled by the other alignment parameters.)
7691 +
7692 +If the macro is defined, its definition should be a C expression;
7693 +a nonzero value for the expression enables this behavior.
7694 +
7695 +Note that if this macro is not defined, or its value is zero, some
7696 +bit-fields may cross more than one alignment boundary. The compiler can
7697 +support such references if there are insv, extv, and
7698 +extzv insns that can directly reference memory.
7699 +
7700 +The other known way of making bit-fields work is to define
7701 +STRUCTURE_SIZE_BOUNDARY as large as BIGGEST_ALIGNMENT.
7702 +Then every structure can be accessed with fullwords.
7703 +
7704 +Unless the machine has bit-field instructions or you define
7705 +STRUCTURE_SIZE_BOUNDARY that way, you must define
7706 +PCC_BITFIELD_TYPE_MATTERS to have a nonzero value.
7707 +
7708 +If your aim is to make GCC use the same conventions for laying out
7709 +bit-fields as are used by another compiler, here is how to investigate
7710 +what the other compiler does. Compile and run this program:
7711 +
7712 +struct foo1
7713 +{
7714 + char x;
7715 + char :0;
7716 + char y;
7717 +};
7718 +
7719 +struct foo2
7720 +{
7721 + char x;
7722 + int :0;
7723 + char y;
7724 +};
7725 +
7726 +main ()
7727 +{
7728 + printf ("Size of foo1 is %d\n",
7729 + sizeof (struct foo1));
7730 + printf ("Size of foo2 is %d\n",
7731 + sizeof (struct foo2));
7732 + exit (0);
7733 +}
7734 +
7735 +If this prints 2 and 5, then the compiler's behavior is what you would
7736 +get from PCC_BITFIELD_TYPE_MATTERS.
7737 +*/
7738 +#define PCC_BITFIELD_TYPE_MATTERS 1
7739 +
7740 +
7741 +/******************************************************************************
7742 + * Layout of Source Language Data Types
7743 + *****************************************************************************/
7744 +
7745 +/*
7746 +A C expression for the size in bits of the type int on the
7747 +target machine. If you don't define this, the default is one word.
7748 +*/
7749 +#define INT_TYPE_SIZE 32
7750 +
7751 +/*
7752 +A C expression for the size in bits of the type short on the
7753 +target machine. If you don't define this, the default is half a word. (If
7754 +this would be less than one storage unit, it is rounded up to one unit.)
7755 +*/
7756 +#define SHORT_TYPE_SIZE 16
7757 +
7758 +/*
7759 +A C expression for the size in bits of the type long on the
7760 +target machine. If you don't define this, the default is one word.
7761 +*/
7762 +#define LONG_TYPE_SIZE 32
7763 +
7764 +
7765 +/*
7766 +A C expression for the size in bits of the type long long on the
7767 +target machine. If you don't define this, the default is two
7768 +words. If you want to support GNU Ada on your machine, the value of this
7769 +macro must be at least 64.
7770 +*/
7771 +#define LONG_LONG_TYPE_SIZE 64
7772 +
7773 +/*
7774 +A C expression for the size in bits of the type char on the
7775 +target machine. If you don't define this, the default is
7776 +BITS_PER_UNIT.
7777 +*/
7778 +#define CHAR_TYPE_SIZE 8
7779 +
7780 +
7781 +/*
7782 +A C expression for the size in bits of the C++ type bool and
7783 +C99 type _Bool on the target machine. If you don't define
7784 +this, and you probably shouldn't, the default is CHAR_TYPE_SIZE.
7785 +*/
7786 +#define BOOL_TYPE_SIZE 8
7787 +
7788 +
7789 +/*
7790 +An expression whose value is 1 or 0, according to whether the type
7791 +char should be signed or unsigned by default. The user can
7792 +always override this default with the options -fsigned-char
7793 +and -funsigned-char.
7794 +*/
7795 +/* We are using unsigned char */
7796 +#define DEFAULT_SIGNED_CHAR 0
7797 +
7798 +
7799 +/*
7800 +A C expression for a string describing the name of the data type to use
7801 +for size values. The typedef name size_t is defined using the
7802 +contents of the string.
7803 +
7804 +The string can contain more than one keyword. If so, separate them with
7805 +spaces, and write first any length keyword, then unsigned if
7806 +appropriate, and finally int. The string must exactly match one
7807 +of the data type names defined in the function
7808 +init_decl_processing in the file c-decl.c. You may not
7809 +omit int or change the order - that would cause the compiler to
7810 +crash on startup.
7811 +
7812 +If you don't define this macro, the default is "long unsigned int".
7813 +*/
7814 +#define SIZE_TYPE "long unsigned int"
7815 +
7816 +/*
7817 +A C expression for a string describing the name of the data type to use
7818 +for the result of subtracting two pointers. The typedef name
7819 +ptrdiff_t is defined using the contents of the string. See
7820 +SIZE_TYPE above for more information.
7821 +
7822 +If you don't define this macro, the default is "long int".
7823 +*/
7824 +#define PTRDIFF_TYPE "long int"
7825 +
7826 +
7827 +/*
7828 +A C expression for the size in bits of the data type for wide
7829 +characters. This is used in cpp, which cannot make use of
7830 +WCHAR_TYPE.
7831 +*/
7832 +#define WCHAR_TYPE_SIZE 32
7833 +
7834 +
7835 +/*
7836 +A C expression for a string describing the name of the data type to
7837 +use for wide characters passed to printf and returned from
7838 +getwc. The typedef name wint_t is defined using the
7839 +contents of the string. See SIZE_TYPE above for more
7840 +information.
7841 +
7842 +If you don't define this macro, the default is "unsigned int".
7843 +*/
7844 +#define WINT_TYPE "unsigned int"
7845 +
7846 +/*
7847 +A C expression for a string describing the name of the data type that
7848 +can represent any value of any standard or extended signed integer type.
7849 +The typedef name intmax_t is defined using the contents of the
7850 +string. See SIZE_TYPE above for more information.
7851 +
7852 +If you don't define this macro, the default is the first of
7853 +"int", "long int", or "long long int" that has as
7854 +much precision as long long int.
7855 +*/
7856 +#define INTMAX_TYPE "long long int"
7857 +
7858 +/*
7859 +A C expression for a string describing the name of the data type that
7860 +can represent any value of any standard or extended unsigned integer
7861 +type. The typedef name uintmax_t is defined using the contents
7862 +of the string. See SIZE_TYPE above for more information.
7863 +
7864 +If you don't define this macro, the default is the first of
7865 +"unsigned int", "long unsigned int", or "long long unsigned int"
7866 +that has as much precision as long long unsigned int.
7867 +*/
7868 +#define UINTMAX_TYPE "long long unsigned int"
7869 +
7870 +
7871 +/******************************************************************************
7872 + * Register Usage
7873 + *****************************************************************************/
7874 +
7875 +/* Convert from gcc internal register number to register number
7876 + used in assembly code */
7877 +#define ASM_REGNUM(reg) (LAST_REGNUM - (reg))
7878 +#define ASM_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg))
7879 +
7880 +/* Convert between register number used in assembly to gcc
7881 + internal register number */
7882 +#define INTERNAL_REGNUM(reg) (LAST_REGNUM - (reg))
7883 +#define INTERNAL_FP_REGNUM(reg) (LAST_FP_REGNUM - (reg))
7884 +
7885 +/** Basic Characteristics of Registers **/
7886 +
7887 +/*
7888 +Number of hardware registers known to the compiler. They receive
7889 +numbers 0 through FIRST_PSEUDO_REGISTER-1; thus, the first
7890 +pseudo register's number really is assigned the number
7891 +FIRST_PSEUDO_REGISTER.
7892 +*/
7893 +#define FIRST_PSEUDO_REGISTER (LAST_FP_REGNUM + 1)
7894 +
7895 +#define FIRST_REGNUM 0
7896 +#define LAST_REGNUM 15
7897 +#define NUM_FP_REGS 16
7898 +#define FIRST_FP_REGNUM 16
7899 +#define LAST_FP_REGNUM (16+NUM_FP_REGS-1)
7900 +
7901 +/*
7902 +An initializer that says which registers are used for fixed purposes
7903 +all throughout the compiled code and are therefore not available for
7904 +general allocation. These would include the stack pointer, the frame
7905 +pointer (except on machines where that can be used as a general
7906 +register when no frame pointer is needed), the program counter on
7907 +machines where that is considered one of the addressable registers,
7908 +and any other numbered register with a standard use.
7909 +
7910 +This information is expressed as a sequence of numbers, separated by
7911 +commas and surrounded by braces. The nth number is 1 if
7912 +register n is fixed, 0 otherwise.
7913 +
7914 +The table initialized from this macro, and the table initialized by
7915 +the following one, may be overridden at run time either automatically,
7916 +by the actions of the macro CONDITIONAL_REGISTER_USAGE, or by
7917 +the user with the command options -ffixed-[reg],
7918 +-fcall-used-[reg] and -fcall-saved-[reg].
7919 +*/
7920 +
7921 +/* The internal gcc register numbers are reversed
7922 + compared to the real register numbers since
7923 + gcc expects data types stored over multiple
7924 + registers in the register file to be big endian
7925 + if the memory layout is big endian. But this
7926 + is not the case for avr32 so we fake a big
7927 + endian register file. */
7928 +
7929 +#define FIXED_REGISTERS { \
7930 + 1, /* Program Counter */ \
7931 + 0, /* Link Register */ \
7932 + 1, /* Stack Pointer */ \
7933 + 0, /* r12 */ \
7934 + 0, /* r11 */ \
7935 + 0, /* r10 */ \
7936 + 0, /* r9 */ \
7937 + 0, /* r8 */ \
7938 + 0, /* r7 */ \
7939 + 0, /* r6 */ \
7940 + 0, /* r5 */ \
7941 + 0, /* r4 */ \
7942 + 0, /* r3 */ \
7943 + 0, /* r2 */ \
7944 + 0, /* r1 */ \
7945 + 0, /* r0 */ \
7946 + 0, /* f15 */ \
7947 + 0, /* f14 */ \
7948 + 0, /* f13 */ \
7949 + 0, /* f12 */ \
7950 + 0, /* f11 */ \
7951 + 0, /* f10 */ \
7952 + 0, /* f9 */ \
7953 + 0, /* f8 */ \
7954 + 0, /* f7 */ \
7955 + 0, /* f6 */ \
7956 + 0, /* f5 */ \
7957 + 0, /* f4 */ \
7958 + 0, /* f3 */ \
7959 + 0, /* f2*/ \
7960 + 0, /* f1 */ \
7961 + 0 /* f0 */ \
7962 +}
7963 +
7964 +/*
7965 +Like FIXED_REGISTERS but has 1 for each register that is
7966 +clobbered (in general) by function calls as well as for fixed
7967 +registers. This macro therefore identifies the registers that are not
7968 +available for general allocation of values that must live across
7969 +function calls.
7970 +
7971 +If a register has 0 in CALL_USED_REGISTERS, the compiler
7972 +automatically saves it on function entry and restores it on function
7973 +exit, if the register is used within the function.
7974 +*/
7975 +#define CALL_USED_REGISTERS { \
7976 + 1, /* Program Counter */ \
7977 + 0, /* Link Register */ \
7978 + 1, /* Stack Pointer */ \
7979 + 1, /* r12 */ \
7980 + 1, /* r11 */ \
7981 + 1, /* r10 */ \
7982 + 1, /* r9 */ \
7983 + 1, /* r8 */ \
7984 + 0, /* r7 */ \
7985 + 0, /* r6 */ \
7986 + 0, /* r5 */ \
7987 + 0, /* r4 */ \
7988 + 0, /* r3 */ \
7989 + 0, /* r2 */ \
7990 + 0, /* r1 */ \
7991 + 0, /* r0 */ \
7992 + 1, /* f15 */ \
7993 + 1, /* f14 */ \
7994 + 1, /* f13 */ \
7995 + 1, /* f12 */ \
7996 + 1, /* f11 */ \
7997 + 1, /* f10 */ \
7998 + 1, /* f9 */ \
7999 + 1, /* f8 */ \
8000 + 0, /* f7 */ \
8001 + 0, /* f6 */ \
8002 + 0, /* f5 */ \
8003 + 0, /* f4 */ \
8004 + 0, /* f3 */ \
8005 + 0, /* f2*/ \
8006 + 0, /* f1*/ \
8007 + 0, /* f0 */ \
8008 +}
8009 +
8010 +/* Interrupt functions can only use registers that have already been
8011 + saved by the prologue, even if they would normally be
8012 + call-clobbered. */
8013 +#define HARD_REGNO_RENAME_OK(SRC, DST) \
8014 + (! IS_INTERRUPT (cfun->machine->func_type) || \
8015 + regs_ever_live[DST])
8016 +
8017 +
8018 +/*
8019 +Zero or more C statements that may conditionally modify five variables
8020 +fixed_regs, call_used_regs, global_regs,
8021 +reg_names, and reg_class_contents, to take into account
8022 +any dependence of these register sets on target flags. The first three
8023 +of these are of type char [] (interpreted as Boolean vectors).
8024 +global_regs is a const char *[], and
8025 +reg_class_contents is a HARD_REG_SET. Before the macro is
8026 +called, fixed_regs, call_used_regs,
8027 +reg_class_contents, and reg_names have been initialized
8028 +from FIXED_REGISTERS, CALL_USED_REGISTERS,
8029 +REG_CLASS_CONTENTS, and REGISTER_NAMES, respectively.
8030 +global_regs has been cleared, and any -ffixed-[reg],
8031 +-fcall-used-[reg] and -fcall-saved-[reg]
8032 +command options have been applied.
8033 +
8034 +You need not define this macro if it has no work to do.
8035 +
8036 +If the usage of an entire class of registers depends on the target
8037 +flags, you may indicate this to GCC by using this macro to modify
8038 +fixed_regs and call_used_regs to 1 for each of the
8039 +registers in the classes which should not be used by GCC. Also define
8040 +the macro REG_CLASS_FROM_LETTER to return NO_REGS if it
8041 +is called with a letter for a class that shouldn't be used.
8042 +
8043 + (However, if this class is not included in GENERAL_REGS and all
8044 +of the insn patterns whose constraints permit this class are
8045 +controlled by target switches, then GCC will automatically avoid using
8046 +these registers when the target switches are opposed to them.)
8047 +*/
8048 +#define CONDITIONAL_REGISTER_USAGE \
8049 + do \
8050 + { \
8051 + int regno; \
8052 + \
8053 + if (TARGET_SOFT_FLOAT) \
8054 + { \
8055 + for (regno = FIRST_FP_REGNUM; \
8056 + regno <= LAST_FP_REGNUM; ++regno) \
8057 + fixed_regs[regno] = call_used_regs[regno] = 1; \
8058 + } \
8059 + if (flag_pic) \
8060 + { \
8061 + fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
8062 + call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
8063 + } \
8064 + } \
8065 + while (0)
8066 +
8067 +
8068 +/*
8069 +If the program counter has a register number, define this as that
8070 +register number. Otherwise, do not define it.
8071 +*/
8072 +
8073 +#define LAST_AVR32_REGNUM 16
8074 +
8075 +
8076 +/** Order of Allocation of Registers **/
8077 +
8078 +/*
8079 +If defined, an initializer for a vector of integers, containing the
8080 +numbers of hard registers in the order in which GCC should prefer
8081 +to use them (from most preferred to least).
8082 +
8083 +If this macro is not defined, registers are used lowest numbered first
8084 +(all else being equal).
8085 +
8086 +One use of this macro is on machines where the highest numbered
8087 +registers must always be saved and the save-multiple-registers
8088 +instruction supports only sequences of consecutive registers. On such
8089 +machines, define REG_ALLOC_ORDER to be an initializer that lists
8090 +the highest numbered allocable register first.
8091 +*/
8092 +#define REG_ALLOC_ORDER \
8093 +{ \
8094 + INTERNAL_REGNUM(8), \
8095 + INTERNAL_REGNUM(9), \
8096 + INTERNAL_REGNUM(10), \
8097 + INTERNAL_REGNUM(11), \
8098 + INTERNAL_REGNUM(12), \
8099 + LR_REGNUM, \
8100 + INTERNAL_REGNUM(7), \
8101 + INTERNAL_REGNUM(6), \
8102 + INTERNAL_REGNUM(5), \
8103 + INTERNAL_REGNUM(4), \
8104 + INTERNAL_REGNUM(3), \
8105 + INTERNAL_REGNUM(2), \
8106 + INTERNAL_REGNUM(1), \
8107 + INTERNAL_REGNUM(0), \
8108 + INTERNAL_FP_REGNUM(15), \
8109 + INTERNAL_FP_REGNUM(14), \
8110 + INTERNAL_FP_REGNUM(13), \
8111 + INTERNAL_FP_REGNUM(12), \
8112 + INTERNAL_FP_REGNUM(11), \
8113 + INTERNAL_FP_REGNUM(10), \
8114 + INTERNAL_FP_REGNUM(9), \
8115 + INTERNAL_FP_REGNUM(8), \
8116 + INTERNAL_FP_REGNUM(7), \
8117 + INTERNAL_FP_REGNUM(6), \
8118 + INTERNAL_FP_REGNUM(5), \
8119 + INTERNAL_FP_REGNUM(4), \
8120 + INTERNAL_FP_REGNUM(3), \
8121 + INTERNAL_FP_REGNUM(2), \
8122 + INTERNAL_FP_REGNUM(1), \
8123 + INTERNAL_FP_REGNUM(0), \
8124 + SP_REGNUM, \
8125 + PC_REGNUM \
8126 +}
8127 +
8128 +
8129 +/** How Values Fit in Registers **/
8130 +
8131 +/*
8132 +A C expression for the number of consecutive hard registers, starting
8133 +at register number REGNO, required to hold a value of mode
8134 +MODE.
8135 +
8136 +On a machine where all registers are exactly one word, a suitable
8137 +definition of this macro is
8138 +
8139 +#define HARD_REGNO_NREGS(REGNO, MODE) \
8140 + ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) \
8141 + / UNITS_PER_WORD)
8142 +*/
8143 +#define HARD_REGNO_NREGS(REGNO, MODE) \
8144 + ((unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD -1 ) / UNITS_PER_WORD))
8145 +
8146 +/*
8147 +A C expression that is nonzero if it is permissible to store a value
8148 +of mode MODE in hard register number REGNO (or in several
8149 +registers starting with that one). For a machine where all registers
8150 +are equivalent, a suitable definition is
8151 +
8152 + #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
8153 +
8154 +You need not include code to check for the numbers of fixed registers,
8155 +because the allocation mechanism considers them to be always occupied.
8156 +
8157 +On some machines, double-precision values must be kept in even/odd
8158 +register pairs. You can implement that by defining this macro to reject
8159 +odd register numbers for such modes.
8160 +
8161 +The minimum requirement for a mode to be OK in a register is that the
8162 +mov[mode] instruction pattern support moves between the
8163 +register and other hard register in the same class and that moving a
8164 +value into the register and back out not alter it.
8165 +
8166 +Since the same instruction used to move word_mode will work for
8167 +all narrower integer modes, it is not necessary on any machine for
8168 +HARD_REGNO_MODE_OK to distinguish between these modes, provided
8169 +you define patterns movhi, etc., to take advantage of this. This
8170 +is useful because of the interaction between HARD_REGNO_MODE_OK
8171 +and MODES_TIEABLE_P; it is very desirable for all integer modes
8172 +to be tieable.
8173 +
8174 +Many machines have special registers for floating point arithmetic.
8175 +Often people assume that floating point machine modes are allowed only
8176 +in floating point registers. This is not true. Any registers that
8177 +can hold integers can safely hold a floating point machine
8178 +mode, whether or not floating arithmetic can be done on it in those
8179 +registers. Integer move instructions can be used to move the values.
8180 +
8181 +On some machines, though, the converse is true: fixed-point machine
8182 +modes may not go in floating registers. This is true if the floating
8183 +registers normalize any value stored in them, because storing a
8184 +non-floating value there would garble it. In this case,
8185 +HARD_REGNO_MODE_OK should reject fixed-point machine modes in
8186 +floating registers. But if the floating registers do not automatically
8187 +normalize, if you can store any bit pattern in one and retrieve it
8188 +unchanged without a trap, then any machine mode may go in a floating
8189 +register, so you can define this macro to say so.
8190 +
8191 +The primary significance of special floating registers is rather that
8192 +they are the registers acceptable in floating point arithmetic
8193 +instructions. However, this is of no concern to
8194 +HARD_REGNO_MODE_OK. You handle it by writing the proper
8195 +constraints for those instructions.
8196 +
8197 +On some machines, the floating registers are especially slow to access,
8198 +so that it is better to store a value in a stack frame than in such a
8199 +register if floating point arithmetic is not being done. As long as the
8200 +floating registers are not in class GENERAL_REGS, they will not
8201 +be used unless some pattern's constraint asks for one.
8202 +*/
8203 +#define HARD_REGNO_MODE_OK(REGNO, MODE) avr32_hard_regno_mode_ok(REGNO, MODE)
8204 +
8205 +/*
8206 +A C expression that is nonzero if a value of mode
8207 +MODE1 is accessible in mode MODE2 without copying.
8208 +
8209 +If HARD_REGNO_MODE_OK(R, MODE1) and
8210 +HARD_REGNO_MODE_OK(R, MODE2) are always the same for
8211 +any R, then MODES_TIEABLE_P(MODE1, MODE2)
8212 +should be nonzero. If they differ for any R, you should define
8213 +this macro to return zero unless some other mechanism ensures the
8214 +accessibility of the value in a narrower mode.
8215 +
8216 +You should define this macro to return nonzero in as many cases as
8217 +possible since doing so will allow GCC to perform better register
8218 +allocation.
8219 +*/
8220 +#define MODES_TIEABLE_P(MODE1, MODE2) \
8221 + (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
8222 +
8223 +
8224 +
8225 +/******************************************************************************
8226 + * Register Classes
8227 + *****************************************************************************/
8228 +
8229 +/*
8230 +An enumeral type that must be defined with all the register class names
8231 +as enumeral values. NO_REGS must be first. ALL_REGS
8232 +must be the last register class, followed by one more enumeral value,
8233 +LIM_REG_CLASSES, which is not a register class but rather
8234 +tells how many classes there are.
8235 +
8236 +Each register class has a number, which is the value of casting
8237 +the class name to type int. The number serves as an index
8238 +in many of the tables described below.
8239 +*/
8240 +enum reg_class
8241 +{
8242 + NO_REGS,
8243 + GENERAL_REGS,
8244 + FP_REGS,
8245 + ALL_REGS,
8246 + LIM_REG_CLASSES
8247 +};
8248 +
8249 +/*
8250 +The number of distinct register classes, defined as follows:
8251 + #define N_REG_CLASSES (int) LIM_REG_CLASSES
8252 +*/
8253 +#define N_REG_CLASSES (int)LIM_REG_CLASSES
8254 +
8255 +/*
8256 +An initializer containing the names of the register classes as C string
8257 +constants. These names are used in writing some of the debugging dumps.
8258 +*/
8259 +#define REG_CLASS_NAMES \
8260 +{ \
8261 + "NO_REGS", \
8262 + "GENERAL_REGS", \
8263 + "FLOATING_POINT_REGS", \
8264 + "ALL_REGS" \
8265 +}
8266 +
8267 +/*
8268 +An initializer containing the contents of the register classes, as integers
8269 +which are bit masks. The nth integer specifies the contents of class
8270 +n. The way the integer mask is interpreted is that
8271 +register r is in the class if mask & (1 << r) is 1.
8272 +
8273 +When the machine has more than 32 registers, an integer does not suffice.
8274 +Then the integers are replaced by sub-initializers, braced groupings containing
8275 +several integers. Each sub-initializer must be suitable as an initializer
8276 +for the type HARD_REG_SET which is defined in hard-reg-set.h.
8277 +In this situation, the first integer in each sub-initializer corresponds to
8278 +registers 0 through 31, the second integer to registers 32 through 63, and
8279 +so on.
8280 +*/
8281 +#define REG_CLASS_CONTENTS { \
8282 + {0x00000000}, /* NO_REGS */ \
8283 + {0x0000FFFF}, /* GENERAL_REGS */ \
8284 + {0xFFFF0000}, /* FP_REGS */ \
8285 + {0x7FFFFFFF}, /* ALL_REGS */ \
8286 +}
8287 +
8288 +
8289 +/*
8290 +A C expression whose value is a register class containing hard register
8291 +REGNO. In general there is more than one such class; choose a class
8292 +which is minimal, meaning that no smaller class also contains the
8293 +register.
8294 +*/
8295 +#define REGNO_REG_CLASS(REGNO) ((REGNO < 16) ? GENERAL_REGS : FP_REGS)
8296 +
8297 +/*
8298 +A macro whose definition is the name of the class to which a valid
8299 +base register must belong. A base register is one used in an address
8300 +which is the register value plus a displacement.
8301 +*/
8302 +#define BASE_REG_CLASS GENERAL_REGS
8303 +
8304 +/*
8305 +This is a variation of the BASE_REG_CLASS macro which allows
8306 +the selection of a base register in a mode depenedent manner. If
8307 +mode is VOIDmode then it should return the same value as
8308 +BASE_REG_CLASS.
8309 +*/
8310 +#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
8311 +
8312 +/*
8313 +A macro whose definition is the name of the class to which a valid
8314 +index register must belong. An index register is one used in an
8315 +address where its value is either multiplied by a scale factor or
8316 +added to another register (as well as added to a displacement).
8317 +*/
8318 +#define INDEX_REG_CLASS BASE_REG_CLASS
8319 +
8320 +/*
8321 +A C expression which defines the machine-dependent operand constraint
8322 +letters for register classes. If CHAR is such a letter, the
8323 +value should be the register class corresponding to it. Otherwise,
8324 +the value should be NO_REGS. The register letter r,
8325 +corresponding to class GENERAL_REGS, will not be passed
8326 +to this macro; you do not need to handle it.
8327 +*/
8328 +#define REG_CLASS_FROM_LETTER(CHAR) ((CHAR) == 'f' ? FP_REGS : NO_REGS)
8329 +
8330 +
8331 +/* These assume that REGNO is a hard or pseudo reg number.
8332 + They give nonzero only if REGNO is a hard reg of the suitable class
8333 + or a pseudo reg currently allocated to a suitable hard reg.
8334 + Since they use reg_renumber, they are safe only once reg_renumber
8335 + has been allocated, which happens in local-alloc.c. */
8336 +#define TEST_REGNO(R, TEST, VALUE) \
8337 + ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
8338 +
8339 +/*
8340 +A C expression which is nonzero if register number num is suitable for use as a base
8341 +register in operand addresses. It may be either a suitable hard register or a pseudo
8342 +register that has been allocated such a hard register.
8343 +*/
8344 +#define REGNO_OK_FOR_BASE_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM)
8345 +
8346 +/*
8347 +A C expression which is nonzero if register number NUM is
8348 +suitable for use as an index register in operand addresses. It may be
8349 +either a suitable hard register or a pseudo register that has been
8350 +allocated such a hard register.
8351 +
8352 +The difference between an index register and a base register is that
8353 +the index register may be scaled. If an address involves the sum of
8354 +two registers, neither one of them scaled, then either one may be
8355 +labeled the ``base'' and the other the ``index''; but whichever
8356 +labeling is used must fit the machine's constraints of which registers
8357 +may serve in each capacity. The compiler will try both labelings,
8358 +looking for one that is valid, and will reload one or both registers
8359 +only if neither labeling works.
8360 +*/
8361 +#define REGNO_OK_FOR_INDEX_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM)
8362 +
8363 +/*
8364 +A C expression that places additional restrictions on the register class
8365 +to use when it is necessary to copy value X into a register in class
8366 +CLASS. The value is a register class; perhaps CLASS, or perhaps
8367 +another, smaller class. On many machines, the following definition is
8368 +safe: #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
8369 +
8370 +Sometimes returning a more restrictive class makes better code. For
8371 +example, on the 68000, when X is an integer constant that is in range
8372 +for a 'moveq' instruction, the value of this macro is always
8373 +DATA_REGS as long as CLASS includes the data registers.
8374 +Requiring a data register guarantees that a 'moveq' will be used.
8375 +
8376 +If X is a const_double, by returning NO_REGS
8377 +you can force X into a memory constant. This is useful on
8378 +certain machines where immediate floating values cannot be loaded into
8379 +certain kinds of registers.
8380 +*/
8381 +#define PREFERRED_RELOAD_CLASS(X, CLASS) CLASS
8382 +
8383 +
8384 +
8385 +/*
8386 +A C expression for the maximum number of consecutive registers
8387 +of class CLASS needed to hold a value of mode MODE.
8388 +
8389 +This is closely related to the macro HARD_REGNO_NREGS. In fact,
8390 +the value of the macro CLASS_MAX_NREGS(CLASS, MODE)
8391 +should be the maximum value of HARD_REGNO_NREGS(REGNO, MODE)
8392 +for all REGNO values in the class CLASS.
8393 +
8394 +This macro helps control the handling of multiple-word values
8395 +in the reload pass.
8396 +*/
8397 +#define CLASS_MAX_NREGS(CLASS, MODE) /* ToDo:fixme */ \
8398 + (unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
8399 +
8400 +
8401 +/*
8402 + Using CONST_OK_FOR_CONSTRAINT_P instead of CONS_OK_FOR_LETTER_P
8403 + in order to support constraints with more than one letter.
8404 + Only two letters are then used for constant constraints,
8405 + the letter 'K' and the letter 'I'. The constraint starting with
8406 + these letters must consist of four characters. The character following
8407 + 'K' or 'I' must be either 'u' (unsigned) or 's' (signed) to specify
8408 + if the constant is zero or sign extended. The last two characters specify
8409 + the length in bits of the constant. The base constraint letter 'I' means
8410 + that this is an negated constant, meaning that actually -VAL should be
8411 + checked to lie withing the valid range instead of VAL which is used when
8412 + 'K' is the base constraint letter.
8413 +
8414 +*/
8415 +
8416 +#define CONSTRAINT_LEN(C, STR) \
8417 + ( ((C) == 'K' || (C) == 'I') ? 4 : \
8418 + ((C) == 'R') ? 5 : \
8419 + ((C) == 'N' || (C) == 'O' || \
8420 + (C) == 'P' || (C) == 'L' || (C) == 'J') ? -1 : \
8421 + DEFAULT_CONSTRAINT_LEN((C), (STR)) )
8422 +
8423 +#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR) \
8424 + avr32_const_ok_for_constraint_p(VALUE, C, STR)
8425 +
8426 +/*
8427 +A C expression that defines the machine-dependent operand constraint
8428 +letters that specify particular ranges of const_double values ('G' or 'H').
8429 +
8430 +If C is one of those letters, the expression should check that
8431 +VALUE, an RTX of code const_double, is in the appropriate
8432 +range and return 1 if so, 0 otherwise. If C is not one of those
8433 +letters, the value should be 0 regardless of VALUE.
8434 +
8435 +const_double is used for all floating-point constants and for
8436 +DImode fixed-point constants. A given letter can accept either
8437 +or both kinds of values. It can use GET_MODE to distinguish
8438 +between these kinds.
8439 +*/
8440 +#define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \
8441 + ((C) == 'G' ? avr32_const_double_immediate(OP) : 0)
8442 +
8443 +/*
8444 +A C expression that defines the optional machine-dependent constraint
8445 +letters that can be used to segregate specific types of operands, usually
8446 +memory references, for the target machine. Any letter that is not
8447 +elsewhere defined and not matched by REG_CLASS_FROM_LETTER
8448 +may be used. Normally this macro will not be defined.
8449 +
8450 +If it is required for a particular target machine, it should return 1
8451 +if VALUE corresponds to the operand type represented by the
8452 +constraint letter C. If C is not defined as an extra
8453 +constraint, the value returned should be 0 regardless of VALUE.
8454 +
8455 +For example, on the ROMP, load instructions cannot have their output
8456 +in r0 if the memory reference contains a symbolic address. Constraint
8457 +letter 'Q' is defined as representing a memory address that does
8458 +not contain a symbolic address. An alternative is specified with
8459 +a 'Q' constraint on the input and 'r' on the output. The next
8460 +alternative specifies 'm' on the input and a register class that
8461 +does not include r0 on the output.
8462 +*/
8463 +#define EXTRA_CONSTRAINT_STR(OP, C, STR) \
8464 + ((C) == 'W' ? avr32_address_operand(OP, GET_MODE(OP)) : \
8465 + (C) == 'R' ? (avr32_indirect_register_operand(OP, GET_MODE(OP)) || \
8466 + (avr32_imm_disp_memory_operand(OP, GET_MODE(OP)) \
8467 + && avr32_const_ok_for_constraint_p( \
8468 + INTVAL(XEXP(XEXP(OP, 0), 1)), \
8469 + (STR)[1], &(STR)[1]))) : \
8470 + (C) == 'S' ? avr32_indexed_memory_operand(OP, GET_MODE(OP)) : \
8471 + (C) == 'T' ? avr32_const_pool_ref_operand(OP, GET_MODE(OP)) : \
8472 + (C) == 'U' ? SYMBOL_REF_RCALL_FUNCTION_P(OP) : \
8473 + (C) == 'Z' ? avr32_cop_memory_operand(OP, GET_MODE(OP)) : \
8474 + 0)
8475 +
8476 +
8477 +#define EXTRA_MEMORY_CONSTRAINT(C, STR) ( ((C) == 'R') || \
8478 + ((C) == 'S') || \
8479 + ((C) == 'Z') )
8480 +
8481 +
8482 +/* Returns nonzero if op is a function SYMBOL_REF which
8483 + can be called using an rcall instruction */
8484 +#define SYMBOL_REF_RCALL_FUNCTION_P(op) \
8485 + ( GET_CODE(op) == SYMBOL_REF \
8486 + && SYMBOL_REF_FUNCTION_P(op) \
8487 + && SYMBOL_REF_LOCAL_P(op) \
8488 + && !SYMBOL_REF_EXTERNAL_P(op) \
8489 + && !TARGET_HAS_ASM_ADDR_PSEUDOS )
8490 +
8491 +/******************************************************************************
8492 + * Stack Layout and Calling Conventions
8493 + *****************************************************************************/
8494 +
8495 +/** Basic Stack Layout **/
8496 +
8497 +/*
8498 +Define this macro if pushing a word onto the stack moves the stack
8499 +pointer to a smaller address.
8500 +
8501 +When we say, ``define this macro if ...,'' it means that the
8502 +compiler checks this macro only with #ifdef so the precise
8503 +definition used does not matter.
8504 +*/
8505 +/* pushm decrece SP: *(--SP) <-- Rx */
8506 +#define STACK_GROWS_DOWNWARD
8507 +
8508 +/*
8509 +This macro defines the operation used when something is pushed
8510 +on the stack. In RTL, a push operation will be
8511 +(set (mem (STACK_PUSH_CODE (reg sp))) ...)
8512 +
8513 +The choices are PRE_DEC, POST_DEC, PRE_INC,
8514 +and POST_INC. Which of these is correct depends on
8515 +the stack direction and on whether the stack pointer points
8516 +to the last item on the stack or whether it points to the
8517 +space for the next item on the stack.
8518 +
8519 +The default is PRE_DEC when STACK_GROWS_DOWNWARD is
8520 +defined, which is almost always right, and PRE_INC otherwise,
8521 +which is often wrong.
8522 +*/
8523 +/* pushm: *(--SP) <-- Rx */
8524 +#define STACK_PUSH_CODE PRE_DEC
8525 +
8526 +/* Define this to nonzero if the nominal address of the stack frame
8527 + is at the high-address end of the local variables;
8528 + that is, each additional local variable allocated
8529 + goes at a more negative offset in the frame. */
8530 +#define FRAME_GROWS_DOWNWARD 1
8531 +
8532 +
8533 +/*
8534 +Offset from the frame pointer to the first local variable slot to be allocated.
8535 +
8536 +If FRAME_GROWS_DOWNWARD, find the next slot's offset by
8537 +subtracting the first slot's length from STARTING_FRAME_OFFSET.
8538 +Otherwise, it is found by adding the length of the first slot to the
8539 +value STARTING_FRAME_OFFSET.
8540 + (i'm not sure if the above is still correct.. had to change it to get
8541 + rid of an overfull. --mew 2feb93 )
8542 +*/
8543 +#define STARTING_FRAME_OFFSET 0
8544 +
8545 +/*
8546 +Offset from the stack pointer register to the first location at which
8547 +outgoing arguments are placed. If not specified, the default value of
8548 +zero is used. This is the proper value for most machines.
8549 +
8550 +If ARGS_GROW_DOWNWARD, this is the offset to the location above
8551 +the first location at which outgoing arguments are placed.
8552 +*/
8553 +#define STACK_POINTER_OFFSET 0
8554 +
8555 +/*
8556 +Offset from the argument pointer register to the first argument's
8557 +address. On some machines it may depend on the data type of the
8558 +function.
8559 +
8560 +If ARGS_GROW_DOWNWARD, this is the offset to the location above
8561 +the first argument's address.
8562 +*/
8563 +#define FIRST_PARM_OFFSET(FUNDECL) 0
8564 +
8565 +
8566 +/*
8567 +A C expression whose value is RTL representing the address in a stack
8568 +frame where the pointer to the caller's frame is stored. Assume that
8569 +FRAMEADDR is an RTL expression for the address of the stack frame
8570 +itself.
8571 +
8572 +If you don't define this macro, the default is to return the value
8573 +of FRAMEADDR - that is, the stack frame address is also the
8574 +address of the stack word that points to the previous frame.
8575 +*/
8576 +#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) plus_constant ((FRAMEADDR), 4)
8577 +
8578 +
8579 +/*
8580 +A C expression whose value is RTL representing the value of the return
8581 +address for the frame COUNT steps up from the current frame, after
8582 +the prologue. FRAMEADDR is the frame pointer of the COUNT
8583 +frame, or the frame pointer of the COUNT - 1 frame if
8584 +RETURN_ADDR_IN_PREVIOUS_FRAME is defined.
8585 +
8586 +The value of the expression must always be the correct address when
8587 +COUNT is zero, but may be NULL_RTX if there is not way to
8588 +determine the return address of other frames.
8589 +*/
8590 +#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) avr32_return_addr(COUNT, FRAMEADDR)
8591 +
8592 +
8593 +/*
8594 +A C expression whose value is RTL representing the location of the
8595 +incoming return address at the beginning of any function, before the
8596 +prologue. This RTL is either a REG, indicating that the return
8597 +value is saved in 'REG', or a MEM representing a location in
8598 +the stack.
8599 +
8600 +You only need to define this macro if you want to support call frame
8601 +debugging information like that provided by DWARF 2.
8602 +
8603 +If this RTL is a REG, you should also define
8604 +DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM (REGNO).
8605 +*/
8606 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM)
8607 +
8608 +
8609 +
8610 +/*
8611 +A C expression whose value is an integer giving the offset, in bytes,
8612 +from the value of the stack pointer register to the top of the stack
8613 +frame at the beginning of any function, before the prologue. The top of
8614 +the frame is defined to be the value of the stack pointer in the
8615 +previous frame, just before the call instruction.
8616 +
8617 +You only need to define this macro if you want to support call frame
8618 +debugging information like that provided by DWARF 2.
8619 +*/
8620 +#define INCOMING_FRAME_SP_OFFSET 0
8621 +
8622 +
8623 +/** Exception Handling Support **/
8624 +
8625 +/* Use setjump/longjump for exception handling. */
8626 +#define DWARF2_UNWIND_INFO 0
8627 +#define MUST_USE_SJLJ_EXCEPTIONS 1
8628 +
8629 +/*
8630 +A C expression whose value is the Nth register number used for
8631 +data by exception handlers, or INVALID_REGNUM if fewer than
8632 +N registers are usable.
8633 +
8634 +The exception handling library routines communicate with the exception
8635 +handlers via a set of agreed upon registers. Ideally these registers
8636 +should be call-clobbered; it is possible to use call-saved registers,
8637 +but may negatively impact code size. The target must support at least
8638 +2 data registers, but should define 4 if there are enough free registers.
8639 +
8640 +You must define this macro if you want to support call frame exception
8641 +handling like that provided by DWARF 2.
8642 +*/
8643 +/*
8644 + Use r9-r11
8645 +*/
8646 +#define EH_RETURN_DATA_REGNO(N) \
8647 + ((N<3) ? INTERNAL_REGNUM(N+9) : INVALID_REGNUM)
8648 +
8649 +/*
8650 +A C expression whose value is RTL representing a location in which
8651 +to store a stack adjustment to be applied before function return.
8652 +This is used to unwind the stack to an exception handler's call frame.
8653 +It will be assigned zero on code paths that return normally.
8654 +
8655 +Typically this is a call-clobbered hard register that is otherwise
8656 +untouched by the epilogue, but could also be a stack slot.
8657 +
8658 +You must define this macro if you want to support call frame exception
8659 +handling like that provided by DWARF 2.
8660 +*/
8661 +/*
8662 + Use r8
8663 +*/
8664 +#define EH_RETURN_STACKADJ_REGNO INTERNAL_REGNUM(8)
8665 +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG(SImode, EH_RETURN_STACKADJ_REGNO)
8666 +
8667 +/*
8668 +A C expression whose value is RTL representing a location in which
8669 +to store the address of an exception handler to which we should
8670 +return. It will not be assigned on code paths that return normally.
8671 +
8672 +Typically this is the location in the call frame at which the normal
8673 +return address is stored. For targets that return by popping an
8674 +address off the stack, this might be a memory address just below
8675 +the target call frame rather than inside the current call
8676 +frame. EH_RETURN_STACKADJ_RTX will have already been assigned,
8677 +so it may be used to calculate the location of the target call frame.
8678 +
8679 +Some targets have more complex requirements than storing to an
8680 +address calculable during initial code generation. In that case
8681 +the eh_return instruction pattern should be used instead.
8682 +
8683 +If you want to support call frame exception handling, you must
8684 +define either this macro or the eh_return instruction pattern.
8685 +*/
8686 +/*
8687 + We define the eh_return instruction pattern, so this isn't needed.
8688 +*/
8689 +/* #define EH_RETURN_HANDLER_RTX gen_rtx_REG(Pmode, RET_REGISTER) */
8690 +
8691 +/*
8692 + This macro chooses the encoding of pointers embedded in the
8693 + exception handling sections. If at all possible, this should be
8694 + defined such that the exception handling section will not require
8695 + dynamic relocations, and so may be read-only.
8696 +
8697 + code is 0 for data, 1 for code labels, 2 for function
8698 + pointers. global is true if the symbol may be affected by dynamic
8699 + relocations. The macro should return a combination of the DW_EH_PE_*
8700 + defines as found in dwarf2.h.
8701 +
8702 + If this macro is not defined, pointers will not be encoded but
8703 + represented directly.
8704 +*/
8705 +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
8706 + ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0) \
8707 + | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr) \
8708 + | DW_EH_PE_sdata4)
8709 +
8710 +/* ToDo: The rest of this subsection */
8711 +
8712 +/** Specifying How Stack Checking is Done **/
8713 +/* ToDo: All in this subsection */
8714 +
8715 +/** Registers That Address the Stack Frame **/
8716 +
8717 +/*
8718 +The register number of the stack pointer register, which must also be a
8719 +fixed register according to FIXED_REGISTERS. On most machines,
8720 +the hardware determines which register this is.
8721 +*/
8722 +/* Using r13 as stack pointer. */
8723 +#define STACK_POINTER_REGNUM INTERNAL_REGNUM(13)
8724 +
8725 +/*
8726 +The register number of the frame pointer register, which is used to
8727 +access automatic variables in the stack frame. On some machines, the
8728 +hardware determines which register this is. On other machines, you can
8729 +choose any register you wish for this purpose.
8730 +*/
8731 +/* Use r7 */
8732 +#define FRAME_POINTER_REGNUM INTERNAL_REGNUM(7)
8733 +
8734 +
8735 +
8736 +/*
8737 +The register number of the arg pointer register, which is used to access
8738 +the function's argument list. On some machines, this is the same as the
8739 +frame pointer register. On some machines, the hardware determines which
8740 +register this is. On other machines, you can choose any register you
8741 +wish for this purpose. If this is not the same register as the frame
8742 +pointer register, then you must mark it as a fixed register according to
8743 +FIXED_REGISTERS, or arrange to be able to eliminate it (see Section
8744 +10.10.5 [Elimination], page 224).
8745 +*/
8746 +/* Using r5 */
8747 +#define ARG_POINTER_REGNUM INTERNAL_REGNUM(4)
8748 +
8749 +
8750 +/*
8751 +Register numbers used for passing a function's static chain pointer. If
8752 +register windows are used, the register number as seen by the called
8753 +function is STATIC_CHAIN_INCOMING_REGNUM, while the register
8754 +number as seen by the calling function is STATIC_CHAIN_REGNUM. If
8755 +these registers are the same, STATIC_CHAIN_INCOMING_REGNUM need
8756 +not be defined.
8757 +
8758 +The static chain register need not be a fixed register.
8759 +
8760 +If the static chain is passed in memory, these macros should not be
8761 +defined; instead, the next two macros should be defined.
8762 +*/
8763 +/* Using r0 */
8764 +#define STATIC_CHAIN_REGNUM INTERNAL_REGNUM(0)
8765 +
8766 +
8767 +/** Eliminating Frame Pointer and Arg Pointer **/
8768 +
8769 +/*
8770 +A C expression which is nonzero if a function must have and use a frame
8771 +pointer. This expression is evaluated in the reload pass. If its value is
8772 +nonzero the function will have a frame pointer.
8773 +
8774 +The expression can in principle examine the current function and decide
8775 +according to the facts, but on most machines the constant 0 or the
8776 +constant 1 suffices. Use 0 when the machine allows code to be generated
8777 +with no frame pointer, and doing so saves some time or space. Use 1
8778 +when there is no possible advantage to avoiding a frame pointer.
8779 +
8780 +In certain cases, the compiler does not know how to produce valid code
8781 +without a frame pointer. The compiler recognizes those cases and
8782 +automatically gives the function a frame pointer regardless of what
8783 +FRAME_POINTER_REQUIRED says. You don't need to worry about
8784 +them.
8785 +
8786 +In a function that does not require a frame pointer, the frame pointer
8787 +register can be allocated for ordinary usage, unless you mark it as a
8788 +fixed register. See FIXED_REGISTERS for more information.
8789 +*/
8790 +/* We need the frame pointer when compiling for profiling */
8791 +#define FRAME_POINTER_REQUIRED (current_function_profile)
8792 +
8793 +/*
8794 +A C statement to store in the variable DEPTH_VAR the difference
8795 +between the frame pointer and the stack pointer values immediately after
8796 +the function prologue. The value would be computed from information
8797 +such as the result of get_frame_size () and the tables of
8798 +registers regs_ever_live and call_used_regs.
8799 +
8800 +If ELIMINABLE_REGS is defined, this macro will be not be used and
8801 +need not be defined. Otherwise, it must be defined even if
8802 +FRAME_POINTER_REQUIRED is defined to always be true; in that
8803 +case, you may set DEPTH_VAR to anything.
8804 +*/
8805 +#define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) ((DEPTH_VAR) = get_frame_size())
8806 +
8807 +/*
8808 +If defined, this macro specifies a table of register pairs used to
8809 +eliminate unneeded registers that point into the stack frame. If it is not
8810 +defined, the only elimination attempted by the compiler is to replace
8811 +references to the frame pointer with references to the stack pointer.
8812 +
8813 +The definition of this macro is a list of structure initializations, each
8814 +of which specifies an original and replacement register.
8815 +
8816 +On some machines, the position of the argument pointer is not known until
8817 +the compilation is completed. In such a case, a separate hard register
8818 +must be used for the argument pointer. This register can be eliminated by
8819 +replacing it with either the frame pointer or the argument pointer,
8820 +depending on whether or not the frame pointer has been eliminated.
8821 +
8822 +In this case, you might specify:
8823 + #define ELIMINABLE_REGS \
8824 + {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
8825 + {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
8826 + {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
8827 +
8828 +Note that the elimination of the argument pointer with the stack pointer is
8829 +specified first since that is the preferred elimination.
8830 +*/
8831 +#define ELIMINABLE_REGS \
8832 +{ \
8833 + { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
8834 + { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM }, \
8835 + { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM } \
8836 +}
8837 +
8838 +/*
8839 +A C expression that returns nonzero if the compiler is allowed to try
8840 +to replace register number FROM with register number
8841 +TO. This macro need only be defined if ELIMINABLE_REGS
8842 +is defined, and will usually be the constant 1, since most of the cases
8843 +preventing register elimination are things that the compiler already
8844 +knows about.
8845 +*/
8846 +#define CAN_ELIMINATE(FROM, TO) 1
8847 +
8848 +/*
8849 +This macro is similar to INITIAL_FRAME_POINTER_OFFSET. It
8850 +specifies the initial difference between the specified pair of
8851 +registers. This macro must be defined if ELIMINABLE_REGS is
8852 +defined.
8853 +*/
8854 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
8855 + ((OFFSET) = avr32_initial_elimination_offset(FROM, TO))
8856 +
8857 +/** Passing Function Arguments on the Stack **/
8858 +
8859 +
8860 +/*
8861 +A C expression. If nonzero, push insns will be used to pass
8862 +outgoing arguments.
8863 +If the target machine does not have a push instruction, set it to zero.
8864 +That directs GCC to use an alternate strategy: to
8865 +allocate the entire argument block and then store the arguments into
8866 +it. When PUSH_ARGS is nonzero, PUSH_ROUNDING must be defined too.
8867 +*/
8868 +#define PUSH_ARGS 1
8869 +
8870 +
8871 +/*
8872 +A C expression that is the number of bytes actually pushed onto the
8873 +stack when an instruction attempts to push NPUSHED bytes.
8874 +
8875 +On some machines, the definition
8876 +
8877 + #define PUSH_ROUNDING(BYTES) (BYTES)
8878 +
8879 +will suffice. But on other machines, instructions that appear
8880 +to push one byte actually push two bytes in an attempt to maintain
8881 +alignment. Then the definition should be
8882 +
8883 + #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
8884 +*/
8885 +/* Push 4 bytes at the time. */
8886 +#define PUSH_ROUNDING(NPUSHED) (((NPUSHED) + 3) & ~3)
8887 +
8888 +/*
8889 +A C expression. If nonzero, the maximum amount of space required for
8890 +outgoing arguments will be computed and placed into the variable
8891 +current_function_outgoing_args_size. No space will be pushed
8892 +onto the stack for each call; instead, the function prologue should
8893 +increase the stack frame size by this amount.
8894 +
8895 +Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper.
8896 +*/
8897 +#define ACCUMULATE_OUTGOING_ARGS 0
8898 +
8899 +
8900 +
8901 +
8902 +/*
8903 +A C expression that should indicate the number of bytes of its own
8904 +arguments that a function pops on returning, or 0 if the
8905 +function pops no arguments and the caller must therefore pop them all
8906 +after the function returns.
8907 +
8908 +FUNDECL is a C variable whose value is a tree node that describes
8909 +the function in question. Normally it is a node of type
8910 +FUNCTION_DECL that describes the declaration of the function.
8911 +From this you can obtain the DECL_ATTRIBUTES of the function.
8912 +
8913 +FUNTYPE is a C variable whose value is a tree node that
8914 +describes the function in question. Normally it is a node of type
8915 +FUNCTION_TYPE that describes the data type of the function.
8916 +From this it is possible to obtain the data types of the value and
8917 +arguments (if known).
8918 +
8919 +When a call to a library function is being considered, FUNDECL
8920 +will contain an identifier node for the library function. Thus, if
8921 +you need to distinguish among various library functions, you can do so
8922 +by their names. Note that ``library function'' in this context means
8923 +a function used to perform arithmetic, whose name is known specially
8924 +in the compiler and was not mentioned in the C code being compiled.
8925 +
8926 +STACK_SIZE is the number of bytes of arguments passed on the
8927 +stack. If a variable number of bytes is passed, it is zero, and
8928 +argument popping will always be the responsibility of the calling function.
8929 +
8930 +On the VAX, all functions always pop their arguments, so the definition
8931 +of this macro is STACK_SIZE. On the 68000, using the standard
8932 +calling convention, no functions pop their arguments, so the value of
8933 +the macro is always 0 in this case. But an alternative calling
8934 +convention is available in which functions that take a fixed number of
8935 +arguments pop them but other functions (such as printf) pop
8936 +nothing (the caller pops all). When this convention is in use,
8937 +FUNTYPE is examined to determine whether a function takes a fixed
8938 +number of arguments.
8939 +*/
8940 +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
8941 +
8942 +
8943 +/*Return true if this function can we use a single return instruction*/
8944 +#define USE_RETURN_INSN(ISCOND) avr32_use_return_insn(ISCOND)
8945 +
8946 +/*
8947 +A C expression that should indicate the number of bytes a call sequence
8948 +pops off the stack. It is added to the value of RETURN_POPS_ARGS
8949 +when compiling a function call.
8950 +
8951 +CUM is the variable in which all arguments to the called function
8952 +have been accumulated.
8953 +
8954 +On certain architectures, such as the SH5, a call trampoline is used
8955 +that pops certain registers off the stack, depending on the arguments
8956 +that have been passed to the function. Since this is a property of the
8957 +call site, not of the called function, RETURN_POPS_ARGS is not
8958 +appropriate.
8959 +*/
8960 +#define CALL_POPS_ARGS(CUM) 0
8961 +
8962 +/* Passing Arguments in Registers */
8963 +
8964 +/*
8965 +A C expression that controls whether a function argument is passed
8966 +in a register, and which register.
8967 +
8968 +The arguments are CUM, which summarizes all the previous
8969 +arguments; MODE, the machine mode of the argument; TYPE,
8970 +the data type of the argument as a tree node or 0 if that is not known
8971 +(which happens for C support library functions); and NAMED,
8972 +which is 1 for an ordinary argument and 0 for nameless arguments that
8973 +correspond to '...' in the called function's prototype.
8974 +TYPE can be an incomplete type if a syntax error has previously
8975 +occurred.
8976 +
8977 +The value of the expression is usually either a reg RTX for the
8978 +hard register in which to pass the argument, or zero to pass the
8979 +argument on the stack.
8980 +
8981 +For machines like the VAX and 68000, where normally all arguments are
8982 +pushed, zero suffices as a definition.
8983 +
8984 +The value of the expression can also be a parallel RTX. This is
8985 +used when an argument is passed in multiple locations. The mode of the
8986 +of the parallel should be the mode of the entire argument. The
8987 +parallel holds any number of expr_list pairs; each one
8988 +describes where part of the argument is passed. In each
8989 +expr_list the first operand must be a reg RTX for the hard
8990 +register in which to pass this part of the argument, and the mode of the
8991 +register RTX indicates how large this part of the argument is. The
8992 +second operand of the expr_list is a const_int which gives
8993 +the offset in bytes into the entire argument of where this part starts.
8994 +As a special exception the first expr_list in the parallel
8995 +RTX may have a first operand of zero. This indicates that the entire
8996 +argument is also stored on the stack.
8997 +
8998 +The last time this macro is called, it is called with MODE == VOIDmode,
8999 +and its result is passed to the call or call_value
9000 +pattern as operands 2 and 3 respectively.
9001 +
9002 +The usual way to make the ISO library 'stdarg.h' work on a machine
9003 +where some arguments are usually passed in registers, is to cause
9004 +nameless arguments to be passed on the stack instead. This is done
9005 +by making FUNCTION_ARG return 0 whenever NAMED is 0.
9006 +
9007 +You may use the macro MUST_PASS_IN_STACK (MODE, TYPE)
9008 +in the definition of this macro to determine if this argument is of a
9009 +type that must be passed in the stack. If REG_PARM_STACK_SPACE
9010 +is not defined and FUNCTION_ARG returns nonzero for such an
9011 +argument, the compiler will abort. If REG_PARM_STACK_SPACE is
9012 +defined, the argument will be computed in the stack and then loaded into
9013 +a register. */
9014 +
9015 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
9016 + avr32_function_arg(&(CUM), MODE, TYPE, NAMED)
9017 +
9018 +
9019 +
9020 +
9021 +/*
9022 +A C type for declaring a variable that is used as the first argument of
9023 +FUNCTION_ARG and other related values. For some target machines,
9024 +the type int suffices and can hold the number of bytes of
9025 +argument so far.
9026 +
9027 +There is no need to record in CUMULATIVE_ARGS anything about the
9028 +arguments that have been passed on the stack. The compiler has other
9029 +variables to keep track of that. For target machines on which all
9030 +arguments are passed on the stack, there is no need to store anything in
9031 +CUMULATIVE_ARGS; however, the data structure must exist and
9032 +should not be empty, so use int.
9033 +*/
9034 +typedef struct avr32_args
9035 +{
9036 + /* Index representing the argument register the current function argument
9037 + will occupy */
9038 + int index;
9039 + /* A mask with bits representing the argument registers: if a bit is set
9040 + then this register is used for an arguemnt */
9041 + int used_index;
9042 + /* TRUE if this function has anonymous arguments */
9043 + int uses_anonymous_args;
9044 + /* The size in bytes of the named arguments pushed on the stack */
9045 + int stack_pushed_args_size;
9046 + /* Set to true if this function needs a Return Value Pointer */
9047 + int use_rvp;
9048 +
9049 +} CUMULATIVE_ARGS;
9050 +
9051 +
9052 +#define FIRST_CUM_REG_INDEX 0
9053 +#define LAST_CUM_REG_INDEX 4
9054 +#define GET_REG_INDEX(CUM) ((CUM)->index)
9055 +#define SET_REG_INDEX(CUM, INDEX) ((CUM)->index = (INDEX));
9056 +#define GET_USED_INDEX(CUM, INDEX) ((CUM)->used_index & (1 << (INDEX)))
9057 +#define SET_USED_INDEX(CUM, INDEX) \
9058 + do \
9059 + { \
9060 + if (INDEX >= 0) \
9061 + (CUM)->used_index |= (1 << (INDEX)); \
9062 + } \
9063 + while (0)
9064 +#define SET_INDEXES_UNUSED(CUM) ((CUM)->used_index = 0)
9065 +
9066 +
9067 +/*
9068 + A C statement (sans semicolon) for initializing the variable cum for the
9069 + state at the beginning of the argument list. The variable has type
9070 + CUMULATIVE_ARGS. The value of FNTYPE is the tree node for the data type of
9071 + the function which will receive the args, or 0 if the args are to a compiler
9072 + support library function. For direct calls that are not libcalls, FNDECL
9073 + contain the declaration node of the function. FNDECL is also set when
9074 + INIT_CUMULATIVE_ARGS is used to find arguments for the function being
9075 + compiled. N_NAMED_ARGS is set to the number of named arguments, including a
9076 + structure return address if it is passed as a parameter, when making a call.
9077 + When processing incoming arguments, N_NAMED_ARGS is set to -1.
9078 +
9079 + When processing a call to a compiler support library function, LIBNAME
9080 + identifies which one. It is a symbol_ref rtx which contains the name of the
9081 + function, as a string. LIBNAME is 0 when an ordinary C function call is
9082 + being processed. Thus, each time this macro is called, either LIBNAME or
9083 + FNTYPE is nonzero, but never both of them at once.
9084 +*/
9085 +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
9086 + avr32_init_cumulative_args(&(CUM), FNTYPE, LIBNAME, FNDECL)
9087 +
9088 +
9089 +/*
9090 +A C statement (sans semicolon) to update the summarizer variable
9091 +CUM to advance past an argument in the argument list. The
9092 +values MODE, TYPE and NAMED describe that argument.
9093 +Once this is done, the variable CUM is suitable for analyzing
9094 +the following argument with FUNCTION_ARG, etc.
9095 +
9096 +This macro need not do anything if the argument in question was passed
9097 +on the stack. The compiler knows how to track the amount of stack space
9098 +used for arguments without any special help.
9099 +*/
9100 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
9101 + avr32_function_arg_advance(&(CUM), MODE, TYPE, NAMED)
9102 +
9103 +/*
9104 +If defined, a C expression which determines whether, and in which direction,
9105 +to pad out an argument with extra space. The value should be of type
9106 +enum direction: either 'upward' to pad above the argument,
9107 +'downward' to pad below, or 'none' to inhibit padding.
9108 +
9109 +The amount of padding is always just enough to reach the next
9110 +multiple of FUNCTION_ARG_BOUNDARY; this macro does not control
9111 +it.
9112 +
9113 +This macro has a default definition which is right for most systems.
9114 +For little-endian machines, the default is to pad upward. For
9115 +big-endian machines, the default is to pad downward for an argument of
9116 +constant size shorter than an int, and upward otherwise.
9117 +*/
9118 +#define FUNCTION_ARG_PADDING(MODE, TYPE) \
9119 + avr32_function_arg_padding(MODE, TYPE)
9120 +
9121 +/*
9122 + Specify padding for the last element of a block move between registers
9123 + and memory. First is nonzero if this is the only element. Defining
9124 + this macro allows better control of register function parameters on
9125 + big-endian machines, without using PARALLEL rtl. In particular,
9126 + MUST_PASS_IN_STACK need not test padding and mode of types in registers,
9127 + as there is no longer a "wrong" part of a register; For example, a three
9128 + byte aggregate may be passed in the high part of a register if so required.
9129 +*/
9130 +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
9131 + avr32_function_arg_padding(MODE, TYPE)
9132 +
9133 +/*
9134 +If defined, a C expression which determines whether the default
9135 +implementation of va_arg will attempt to pad down before reading the
9136 +next argument, if that argument is smaller than its aligned space as
9137 +controlled by PARM_BOUNDARY. If this macro is not defined, all such
9138 +arguments are padded down if BYTES_BIG_ENDIAN is true.
9139 +*/
9140 +#define PAD_VARARGS_DOWN \
9141 + (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
9142 +
9143 +
9144 +/*
9145 +A C expression that is nonzero if REGNO is the number of a hard
9146 +register in which function arguments are sometimes passed. This does
9147 +not include implicit arguments such as the static chain and
9148 +the structure-value address. On many machines, no registers can be
9149 +used for this purpose since all function arguments are pushed on the
9150 +stack.
9151 +*/
9152 +/*
9153 + Use r8 - r12 for function arguments.
9154 +*/
9155 +#define FUNCTION_ARG_REGNO_P(REGNO) \
9156 + (REGNO >= 3 && REGNO <= 7)
9157 +
9158 +/* Number of registers used for passing function arguments */
9159 +#define NUM_ARG_REGS 5
9160 +
9161 +/*
9162 +If defined, the order in which arguments are loaded into their
9163 +respective argument registers is reversed so that the last
9164 +argument is loaded first. This macro only affects arguments
9165 +passed in registers.
9166 +*/
9167 +/* #define LOAD_ARGS_REVERSED */
9168 +
9169 +/** How Scalar Function Values Are Returned **/
9170 +
9171 +/* AVR32 is using r12 as return register. */
9172 +#define RET_REGISTER (15 - 12)
9173 +
9174 +
9175 +/*
9176 +A C expression to create an RTX representing the place where a library
9177 +function returns a value of mode MODE. If the precise function
9178 +being called is known, FUNC is a tree node
9179 +(FUNCTION_DECL) for it; otherwise, func is a null
9180 +pointer. This makes it possible to use a different value-returning
9181 +convention for specific functions when all their calls are
9182 +known.
9183 +
9184 +Note that "library function" in this context means a compiler
9185 +support routine, used to perform arithmetic, whose name is known
9186 +specially by the compiler and was not mentioned in the C code being
9187 +compiled.
9188 +
9189 +The definition of LIBRARY_VALUE need not be concerned aggregate
9190 +data types, because none of the library functions returns such types.
9191 +*/
9192 +#define LIBCALL_VALUE(MODE) avr32_libcall_value(MODE)
9193 +
9194 +/*
9195 +A C expression that is nonzero if REGNO is the number of a hard
9196 +register in which the values of called function may come back.
9197 +
9198 +A register whose use for returning values is limited to serving as the
9199 +second of a pair (for a value of type double, say) need not be
9200 +recognized by this macro. So for most machines, this definition
9201 +suffices:
9202 + #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
9203 +
9204 +If the machine has register windows, so that the caller and the called
9205 +function use different registers for the return value, this macro
9206 +should recognize only the caller's register numbers.
9207 +*/
9208 +/*
9209 + When returning a value of mode DImode, r11:r10 is used, else r12 is used.
9210 +*/
9211 +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RET_REGISTER \
9212 + || (REGNO) == INTERNAL_REGNUM(11))
9213 +
9214 +
9215 +/** How Large Values Are Returned **/
9216 +
9217 +
9218 +/*
9219 +Define this macro to be 1 if all structure and union return values must be
9220 +in memory. Since this results in slower code, this should be defined
9221 +only if needed for compatibility with other compilers or with an ABI.
9222 +If you define this macro to be 0, then the conventions used for structure
9223 +and union return values are decided by the RETURN_IN_MEMORY macro.
9224 +
9225 +If not defined, this defaults to the value 1.
9226 +*/
9227 +#define DEFAULT_PCC_STRUCT_RETURN 0
9228 +
9229 +
9230 +
9231 +
9232 +/** Generating Code for Profiling **/
9233 +
9234 +/*
9235 +A C statement or compound statement to output to FILE some
9236 +assembler code to call the profiling subroutine mcount.
9237 +
9238 +The details of how mcount expects to be called are determined by
9239 +your operating system environment, not by GCC. To figure them out,
9240 +compile a small program for profiling using the system's installed C
9241 +compiler and look at the assembler code that results.
9242 +
9243 +Older implementations of mcount expect the address of a counter
9244 +variable to be loaded into some register. The name of this variable is
9245 +'LP' followed by the number LABELNO, so you would generate
9246 +the name using 'LP%d' in a fprintf.
9247 +*/
9248 +/* ToDo: fixme */
9249 +#ifndef FUNCTION_PROFILER
9250 +#define FUNCTION_PROFILER(FILE, LABELNO) \
9251 + fprintf((FILE), "/* profiler %d */", (LABELNO))
9252 +#endif
9253 +
9254 +
9255 +/*****************************************************************************
9256 + * Trampolines for Nested Functions *
9257 + *****************************************************************************/
9258 +
9259 +/*
9260 +A C statement to output, on the stream FILE, assembler code for a
9261 +block of data that contains the constant parts of a trampoline. This
9262 +code should not include a label - the label is taken care of
9263 +automatically.
9264 +
9265 +If you do not define this macro, it means no template is needed
9266 +for the target. Do not define this macro on systems where the block move
9267 +code to copy the trampoline into place would be larger than the code
9268 +to generate it on the spot.
9269 +*/
9270 +/* ToDo: correct? */
9271 +#define TRAMPOLINE_TEMPLATE(FILE) avr32_trampoline_template(FILE);
9272 +
9273 +
9274 +/*
9275 +A C expression for the size in bytes of the trampoline, as an integer.
9276 +*/
9277 +/* ToDo: fixme */
9278 +#define TRAMPOLINE_SIZE 0x0C
9279 +
9280 +/*
9281 +Alignment required for trampolines, in bits.
9282 +
9283 +If you don't define this macro, the value of BIGGEST_ALIGNMENT
9284 +is used for aligning trampolines.
9285 +*/
9286 +#define TRAMPOLINE_ALIGNMENT 16
9287 +
9288 +/*
9289 +A C statement to initialize the variable parts of a trampoline.
9290 +ADDR is an RTX for the address of the trampoline; FNADDR is
9291 +an RTX for the address of the nested function; STATIC_CHAIN is an
9292 +RTX for the static chain value that should be passed to the function
9293 +when it is called.
9294 +*/
9295 +#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \
9296 + avr32_initialize_trampoline(ADDR, FNADDR, STATIC_CHAIN)
9297 +
9298 +
9299 +/******************************************************************************
9300 + * Implicit Calls to Library Routines
9301 + *****************************************************************************/
9302 +
9303 +/* Tail calling. */
9304 +
9305 +/* A C expression that evaluates to true if it is ok to perform a sibling
9306 + call to DECL. */
9307 +#define FUNCTION_OK_FOR_SIBCALL(DECL) 0
9308 +
9309 +#define OVERRIDE_OPTIONS avr32_override_options ()
9310 +
9311 +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) avr32_optimization_options (LEVEL, SIZE)
9312 +
9313 +
9314 +/******************************************************************************
9315 + * Addressing Modes
9316 + *****************************************************************************/
9317 +
9318 +/*
9319 +A C expression that is nonzero if the machine supports pre-increment,
9320 +pre-decrement, post-increment, or post-decrement addressing respectively.
9321 +*/
9322 +/*
9323 + AVR32 supports Rp++ and --Rp
9324 +*/
9325 +#define HAVE_PRE_INCREMENT 0
9326 +#define HAVE_PRE_DECREMENT 1
9327 +#define HAVE_POST_INCREMENT 1
9328 +#define HAVE_POST_DECREMENT 0
9329 +
9330 +/*
9331 +A C expression that is nonzero if the machine supports pre- or
9332 +post-address side-effect generation involving constants other than
9333 +the size of the memory operand.
9334 +*/
9335 +#define HAVE_PRE_MODIFY_DISP 0
9336 +#define HAVE_POST_MODIFY_DISP 0
9337 +
9338 +/*
9339 +A C expression that is nonzero if the machine supports pre- or
9340 +post-address side-effect generation involving a register displacement.
9341 +*/
9342 +#define HAVE_PRE_MODIFY_REG 0
9343 +#define HAVE_POST_MODIFY_REG 0
9344 +
9345 +/*
9346 +A C expression that is 1 if the RTX X is a constant which
9347 +is a valid address. On most machines, this can be defined as
9348 +CONSTANT_P (X), but a few machines are more restrictive
9349 +in which constant addresses are supported.
9350 +
9351 +CONSTANT_P accepts integer-values expressions whose values are
9352 +not explicitly known, such as symbol_ref, label_ref, and
9353 +high expressions and const arithmetic expressions, in
9354 +addition to const_int and const_double expressions.
9355 +*/
9356 +#define CONSTANT_ADDRESS_P(X) CONSTANT_P(X)
9357 +
9358 +/*
9359 +A number, the maximum number of registers that can appear in a valid
9360 +memory address. Note that it is up to you to specify a value equal to
9361 +the maximum number that GO_IF_LEGITIMATE_ADDRESS would ever
9362 +accept.
9363 +*/
9364 +#define MAX_REGS_PER_ADDRESS 2
9365 +
9366 +/*
9367 +A C compound statement with a conditional goto LABEL;
9368 +executed if X (an RTX) is a legitimate memory address on the
9369 +target machine for a memory operand of mode MODE.
9370 +
9371 +It usually pays to define several simpler macros to serve as
9372 +subroutines for this one. Otherwise it may be too complicated to
9373 +understand.
9374 +
9375 +This macro must exist in two variants: a strict variant and a
9376 +non-strict one. The strict variant is used in the reload pass. It
9377 +must be defined so that any pseudo-register that has not been
9378 +allocated a hard register is considered a memory reference. In
9379 +contexts where some kind of register is required, a pseudo-register
9380 +with no hard register must be rejected.
9381 +
9382 +The non-strict variant is used in other passes. It must be defined to
9383 +accept all pseudo-registers in every context where some kind of
9384 +register is required.
9385 +
9386 +Compiler source files that want to use the strict variant of this
9387 +macro define the macro REG_OK_STRICT. You should use an
9388 +#ifdef REG_OK_STRICT conditional to define the strict variant
9389 +in that case and the non-strict variant otherwise.
9390 +
9391 +Subroutines to check for acceptable registers for various purposes (one
9392 +for base registers, one for index registers, and so on) are typically
9393 +among the subroutines used to define GO_IF_LEGITIMATE_ADDRESS.
9394 +Then only these subroutine macros need have two variants; the higher
9395 +levels of macros may be the same whether strict or not.
9396 +
9397 +Normally, constant addresses which are the sum of a symbol_ref
9398 +and an integer are stored inside a const RTX to mark them as
9399 +constant. Therefore, there is no need to recognize such sums
9400 +specifically as legitimate addresses. Normally you would simply
9401 +recognize any const as legitimate.
9402 +
9403 +Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant
9404 +sums that are not marked with const. It assumes that a naked
9405 +plus indicates indexing. If so, then you must reject such
9406 +naked constant sums as illegitimate addresses, so that none of them will
9407 +be given to PRINT_OPERAND_ADDRESS.
9408 +
9409 +On some machines, whether a symbolic address is legitimate depends on
9410 +the section that the address refers to. On these machines, define the
9411 +macro ENCODE_SECTION_INFO to store the information into the
9412 +symbol_ref, and then check for it here. When you see a
9413 +const, you will have to look inside it to find the
9414 +symbol_ref in order to determine the section.
9415 +
9416 +The best way to modify the name string is by adding text to the
9417 +beginning, with suitable punctuation to prevent any ambiguity. Allocate
9418 +the new name in saveable_obstack. You will have to modify
9419 +ASM_OUTPUT_LABELREF to remove and decode the added text and
9420 +output the name accordingly, and define STRIP_NAME_ENCODING to
9421 +access the original name string.
9422 +
9423 +You can check the information stored here into the symbol_ref in
9424 +the definitions of the macros GO_IF_LEGITIMATE_ADDRESS and
9425 +PRINT_OPERAND_ADDRESS.
9426 +*/
9427 +#ifdef REG_OK_STRICT
9428 +# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
9429 + do \
9430 + { \
9431 + if (avr32_legitimate_address(MODE, X, 1)) \
9432 + goto LABEL; \
9433 + } \
9434 + while (0)
9435 +#else
9436 +# define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL) \
9437 + do \
9438 + { \
9439 + if (avr32_legitimate_address(MODE, X, 0)) \
9440 + goto LABEL; \
9441 + } \
9442 + while (0)
9443 +#endif
9444 +
9445 +
9446 +
9447 +/*
9448 +A C compound statement that attempts to replace X with a valid
9449 +memory address for an operand of mode MODE. win will be a
9450 +C statement label elsewhere in the code; the macro definition may use
9451 +
9452 + GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
9453 +
9454 +to avoid further processing if the address has become legitimate.
9455 +
9456 +X will always be the result of a call to break_out_memory_refs,
9457 +and OLDX will be the operand that was given to that function to produce
9458 +X.
9459 +
9460 +The code generated by this macro should not alter the substructure of
9461 +X. If it transforms X into a more legitimate form, it
9462 +should assign X (which will always be a C variable) a new value.
9463 +
9464 +It is not necessary for this macro to come up with a legitimate
9465 +address. The compiler has standard ways of doing so in all cases. In
9466 +fact, it is safe for this macro to do nothing. But often a
9467 +machine-dependent strategy can generate better code.
9468 +*/
9469 +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
9470 + do \
9471 + { \
9472 + if (GET_CODE(X) == PLUS \
9473 + && GET_CODE(XEXP(X, 0)) == REG \
9474 + && GET_CODE(XEXP(X, 1)) == CONST_INT \
9475 + && !CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(X, 1)), \
9476 + 'K', "Ks16")) \
9477 + { \
9478 + rtx index = force_reg(SImode, XEXP(X, 1)); \
9479 + X = gen_rtx_PLUS( SImode, XEXP(X, 0), index); \
9480 + } \
9481 + GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN); \
9482 + } \
9483 + while(0)
9484 +
9485 +
9486 +/*
9487 +A C statement or compound statement with a conditional
9488 +goto LABEL; executed if memory address X (an RTX) can have
9489 +different meanings depending on the machine mode of the memory
9490 +reference it is used for or if the address is valid for some modes
9491 +but not others.
9492 +
9493 +Autoincrement and autodecrement addresses typically have mode-dependent
9494 +effects because the amount of the increment or decrement is the size
9495 +of the operand being addressed. Some machines have other mode-dependent
9496 +addresses. Many RISC machines have no mode-dependent addresses.
9497 +
9498 +You may assume that ADDR is a valid address for the machine.
9499 +*/
9500 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL) \
9501 + do \
9502 + { \
9503 + if (GET_CODE (ADDR) == POST_INC \
9504 + || GET_CODE (ADDR) == PRE_DEC) \
9505 + goto LABEL; \
9506 + } \
9507 + while (0)
9508 +
9509 +/*
9510 +A C expression that is nonzero if X is a legitimate constant for
9511 +an immediate operand on the target machine. You can assume that
9512 +X satisfies CONSTANT_P, so you need not check this. In fact,
9513 +'1' is a suitable definition for this macro on machines where
9514 +anything CONSTANT_P is valid.
9515 +*/
9516 +#define LEGITIMATE_CONSTANT_P(X) avr32_legitimate_constant_p(X)
9517 +
9518 +
9519 +/******************************************************************************
9520 + * Condition Code Status
9521 + *****************************************************************************/
9522 +
9523 +#define HAVE_conditional_move 1
9524 +
9525 +/*
9526 +C code for a data type which is used for declaring the mdep
9527 +component of cc_status. It defaults to int.
9528 +
9529 +This macro is not used on machines that do not use cc0.
9530 +*/
9531 +
9532 +typedef struct
9533 +{
9534 + int flags;
9535 + rtx value;
9536 + int fpflags;
9537 + rtx fpvalue;
9538 +} avr32_status_reg;
9539 +
9540 +
9541 +#define CC_STATUS_MDEP avr32_status_reg
9542 +
9543 +/*
9544 +A C expression to initialize the mdep field to "empty".
9545 +The default definition does nothing, since most machines don't use
9546 +the field anyway. If you want to use the field, you should probably
9547 +define this macro to initialize it.
9548 +
9549 +This macro is not used on machines that do not use cc0.
9550 +*/
9551 +
9552 +#define CC_STATUS_MDEP_INIT \
9553 + (cc_status.mdep.flags = CC_NONE , cc_status.mdep.value = 0)
9554 +
9555 +#define FPCC_STATUS_INIT \
9556 + (cc_status.mdep.fpflags = CC_NONE , cc_status.mdep.fpvalue = 0)
9557 +
9558 +/*
9559 +A C compound statement to set the components of cc_status
9560 +appropriately for an insn INSN whose body is EXP. It is
9561 +this macro's responsibility to recognize insns that set the condition
9562 +code as a byproduct of other activity as well as those that explicitly
9563 +set (cc0).
9564 +
9565 +This macro is not used on machines that do not use cc0.
9566 +
9567 +If there are insns that do not set the condition code but do alter
9568 +other machine registers, this macro must check to see whether they
9569 +invalidate the expressions that the condition code is recorded as
9570 +reflecting. For example, on the 68000, insns that store in address
9571 +registers do not set the condition code, which means that usually
9572 +NOTICE_UPDATE_CC can leave cc_status unaltered for such
9573 +insns. But suppose that the previous insn set the condition code
9574 +based on location 'a4@@(102)' and the current insn stores a new
9575 +value in 'a4'. Although the condition code is not changed by
9576 +this, it will no longer be true that it reflects the contents of
9577 +'a4@@(102)'. Therefore, NOTICE_UPDATE_CC must alter
9578 +cc_status in this case to say that nothing is known about the
9579 +condition code value.
9580 +
9581 +The definition of NOTICE_UPDATE_CC must be prepared to deal
9582 +with the results of peephole optimization: insns whose patterns are
9583 +parallel RTXs containing various reg, mem or
9584 +constants which are just the operands. The RTL structure of these
9585 +insns is not sufficient to indicate what the insns actually do. What
9586 +NOTICE_UPDATE_CC should do when it sees one is just to run
9587 +CC_STATUS_INIT.
9588 +
9589 +A possible definition of NOTICE_UPDATE_CC is to call a function
9590 +that looks at an attribute (see Insn Attributes) named, for example,
9591 +'cc'. This avoids having detailed information about patterns in
9592 +two places, the 'md' file and in NOTICE_UPDATE_CC.
9593 +*/
9594 +
9595 +#define NOTICE_UPDATE_CC(EXP, INSN) avr32_notice_update_cc(EXP, INSN)
9596 +
9597 +
9598 +
9599 +
9600 +/******************************************************************************
9601 + * Describing Relative Costs of Operations
9602 + *****************************************************************************/
9603 +
9604 +
9605 +
9606 +/*
9607 +A C expression for the cost of moving data of mode MODE from a
9608 +register in class FROM to one in class TO. The classes are
9609 +expressed using the enumeration values such as GENERAL_REGS. A
9610 +value of 2 is the default; other values are interpreted relative to
9611 +that.
9612 +
9613 +It is not required that the cost always equal 2 when FROM is the
9614 +same as TO; on some machines it is expensive to move between
9615 +registers if they are not general registers.
9616 +
9617 +If reload sees an insn consisting of a single set between two
9618 +hard registers, and if REGISTER_MOVE_COST applied to their
9619 +classes returns a value of 2, reload does not check to ensure that the
9620 +constraints of the insn are met. Setting a cost of other than 2 will
9621 +allow reload to verify that the constraints are met. You should do this
9622 +if the movm pattern's constraints do not allow such copying.
9623 +*/
9624 +#define REGISTER_MOVE_COST(MODE, FROM, TO) \
9625 + ((GET_MODE_SIZE(MODE) <= 4) ? 2: \
9626 + (GET_MODE_SIZE(MODE) <= 8) ? 3: \
9627 + 4)
9628 +
9629 +/*
9630 +A C expression for the cost of moving data of mode MODE between a
9631 +register of class CLASS and memory; IN is zero if the value
9632 +is to be written to memory, nonzero if it is to be read in. This cost
9633 +is relative to those in REGISTER_MOVE_COST. If moving between
9634 +registers and memory is more expensive than between two registers, you
9635 +should define this macro to express the relative cost.
9636 +
9637 +If you do not define this macro, GCC uses a default cost of 4 plus
9638 +the cost of copying via a secondary reload register, if one is
9639 +needed. If your machine requires a secondary reload register to copy
9640 +between memory and a register of CLASS but the reload mechanism is
9641 +more complex than copying via an intermediate, define this macro to
9642 +reflect the actual cost of the move.
9643 +
9644 +GCC defines the function memory_move_secondary_cost if
9645 +secondary reloads are needed. It computes the costs due to copying via
9646 +a secondary register. If your machine copies from memory using a
9647 +secondary register in the conventional way but the default base value of
9648 +4 is not correct for your machine, define this macro to add some other
9649 +value to the result of that function. The arguments to that function
9650 +are the same as to this macro.
9651 +*/
9652 +/*
9653 + Memory moves are costly
9654 +*/
9655 +#define MEMORY_MOVE_COST(MODE, CLASS, IN) \
9656 + (((IN) ? ((GET_MODE_SIZE(MODE) < 4) ? 4 : \
9657 + (GET_MODE_SIZE(MODE) > 8) ? 6 : \
9658 + 3) \
9659 + : ((GET_MODE_SIZE(MODE) > 8) ? 6 : 3)))
9660 +
9661 +/*
9662 +A C expression for the cost of a branch instruction. A value of 1 is
9663 +the default; other values are interpreted relative to that.
9664 +*/
9665 + /* Try to use conditionals as much as possible */
9666 +#define BRANCH_COST (TARGET_BRANCH_PRED ? 3 : 4)
9667 +
9668 +/*A C expression for the maximum number of instructions to execute via conditional
9669 + execution instructions instead of a branch. A value of BRANCH_COST+1 is the default
9670 + if the machine does not use cc0, and 1 if it does use cc0.*/
9671 +#define MAX_CONDITIONAL_EXECUTE 4
9672 +
9673 +/*
9674 +Define this macro as a C expression which is nonzero if accessing less
9675 +than a word of memory (i.e.: a char or a short) is no
9676 +faster than accessing a word of memory, i.e., if such access
9677 +require more than one instruction or if there is no difference in cost
9678 +between byte and (aligned) word loads.
9679 +
9680 +When this macro is not defined, the compiler will access a field by
9681 +finding the smallest containing object; when it is defined, a fullword
9682 +load will be used if alignment permits. Unless bytes accesses are
9683 +faster than word accesses, using word accesses is preferable since it
9684 +may eliminate subsequent memory access if subsequent accesses occur to
9685 +other fields in the same word of the structure, but to different bytes.
9686 +*/
9687 +#define SLOW_BYTE_ACCESS 1
9688 +
9689 +
9690 +/*
9691 +Define this macro if it is as good or better to call a constant
9692 +function address than to call an address kept in a register.
9693 +*/
9694 +#define NO_FUNCTION_CSE
9695 +
9696 +
9697 +/******************************************************************************
9698 + * Adjusting the Instruction Scheduler
9699 + *****************************************************************************/
9700 +
9701 +/*****************************************************************************
9702 + * Dividing the Output into Sections (Texts, Data, ...) *
9703 + *****************************************************************************/
9704 +
9705 +/*
9706 +A C expression whose value is a string, including spacing, containing the
9707 +assembler operation that should precede instructions and read-only data.
9708 +Normally "\t.text" is right.
9709 +*/
9710 +#define TEXT_SECTION_ASM_OP "\t.text"
9711 +/*
9712 +A C statement that switches to the default section containing instructions.
9713 +Normally this is not needed, as simply defining TEXT_SECTION_ASM_OP
9714 +is enough. The MIPS port uses this to sort all functions after all data
9715 +declarations.
9716 +*/
9717 +/* #define TEXT_SECTION */
9718 +
9719 +/*
9720 +A C expression whose value is a string, including spacing, containing the
9721 +assembler operation to identify the following data as writable initialized
9722 +data. Normally "\t.data" is right.
9723 +*/
9724 +#define DATA_SECTION_ASM_OP "\t.data"
9725 +
9726 +/*
9727 +If defined, a C expression whose value is a string, including spacing,
9728 +containing the assembler operation to identify the following data as
9729 +shared data. If not defined, DATA_SECTION_ASM_OP will be used.
9730 +*/
9731 +
9732 +/*
9733 +A C expression whose value is a string, including spacing, containing
9734 +the assembler operation to identify the following data as read-only
9735 +initialized data.
9736 +*/
9737 +#undef READONLY_DATA_SECTION_ASM_OP
9738 +#define READONLY_DATA_SECTION_ASM_OP \
9739 + ((TARGET_USE_RODATA_SECTION) ? \
9740 + "\t.section\t.rodata" : \
9741 + TEXT_SECTION_ASM_OP )
9742 +
9743 +
9744 +/*
9745 +If defined, a C expression whose value is a string, including spacing,
9746 +containing the assembler operation to identify the following data as
9747 +uninitialized global data. If not defined, and neither
9748 +ASM_OUTPUT_BSS nor ASM_OUTPUT_ALIGNED_BSS are defined,
9749 +uninitialized global data will be output in the data section if
9750 +-fno-common is passed, otherwise ASM_OUTPUT_COMMON will be
9751 +used.
9752 +*/
9753 +#define BSS_SECTION_ASM_OP "\t.section\t.bss"
9754 +
9755 +/*
9756 +If defined, a C expression whose value is a string, including spacing,
9757 +containing the assembler operation to identify the following data as
9758 +uninitialized global shared data. If not defined, and
9759 +BSS_SECTION_ASM_OP is, the latter will be used.
9760 +*/
9761 +/*#define SHARED_BSS_SECTION_ASM_OP "\trseg\tshared_bbs_section:data:noroot(0)\n"*/
9762 +/*
9763 +If defined, a C expression whose value is a string, including spacing,
9764 +containing the assembler operation to identify the following data as
9765 +initialization code. If not defined, GCC will assume such a section does
9766 +not exist.
9767 +*/
9768 +#undef INIT_SECTION_ASM_OP
9769 +#define INIT_SECTION_ASM_OP "\t.section\t.init"
9770 +
9771 +/*
9772 +If defined, a C expression whose value is a string, including spacing,
9773 +containing the assembler operation to identify the following data as
9774 +finalization code. If not defined, GCC will assume such a section does
9775 +not exist.
9776 +*/
9777 +#undef FINI_SECTION_ASM_OP
9778 +#define FINI_SECTION_ASM_OP "\t.section\t.fini"
9779 +
9780 +/*
9781 +If defined, an ASM statement that switches to a different section
9782 +via SECTION_OP, calls FUNCTION, and switches back to
9783 +the text section. This is used in crtstuff.c if
9784 +INIT_SECTION_ASM_OP or FINI_SECTION_ASM_OP to calls
9785 +to initialization and finalization functions from the init and fini
9786 +sections. By default, this macro uses a simple function call. Some
9787 +ports need hand-crafted assembly code to avoid dependencies on
9788 +registers initialized in the function prologue or to ensure that
9789 +constant pools don't end up too far way in the text section.
9790 +*/
9791 +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC) \
9792 + asm ( SECTION_OP "\n" \
9793 + "mcall r6[" USER_LABEL_PREFIX #FUNC "@got]\n" \
9794 + TEXT_SECTION_ASM_OP);
9795 +
9796 +
9797 +/*
9798 +Define this macro to be an expression with a nonzero value if jump
9799 +tables (for tablejump insns) should be output in the text
9800 +section, along with the assembler instructions. Otherwise, the
9801 +readonly data section is used.
9802 +
9803 +This macro is irrelevant if there is no separate readonly data section.
9804 +*/
9805 +/* Put jump tables in text section if we have caches. Otherwise assume that
9806 + loading data from code memory is slow. */
9807 +#define JUMP_TABLES_IN_TEXT_SECTION \
9808 + (TARGET_CACHES ? 1 : 0)
9809 +
9810 +
9811 +/******************************************************************************
9812 + * Position Independent Code (PIC)
9813 + *****************************************************************************/
9814 +
9815 +#ifndef AVR32_ALWAYS_PIC
9816 +#define AVR32_ALWAYS_PIC 0
9817 +#endif
9818 +
9819 +/* GOT is set to r6 */
9820 +#define PIC_OFFSET_TABLE_REGNUM INTERNAL_REGNUM(6)
9821 +
9822 +/*
9823 +A C expression that is nonzero if X is a legitimate immediate
9824 +operand on the target machine when generating position independent code.
9825 +You can assume that X satisfies CONSTANT_P, so you need not
9826 +check this. You can also assume flag_pic is true, so you need not
9827 +check it either. You need not define this macro if all constants
9828 +(including SYMBOL_REF) can be immediate operands when generating
9829 +position independent code.
9830 +*/
9831 +/* We can't directly access anything that contains a symbol,
9832 + nor can we indirect via the constant pool. */
9833 +#define LEGITIMATE_PIC_OPERAND_P(X) avr32_legitimate_pic_operand_p(X)
9834 +
9835 +
9836 +/* We need to know when we are making a constant pool; this determines
9837 + whether data needs to be in the GOT or can be referenced via a GOT
9838 + offset. */
9839 +extern int making_const_table;
9840 +
9841 +/******************************************************************************
9842 + * Defining the Output Assembler Language
9843 + *****************************************************************************/
9844 +
9845 +
9846 +/*
9847 +A C string constant describing how to begin a comment in the target
9848 +assembler language. The compiler assumes that the comment will end at
9849 +the end of the line.
9850 +*/
9851 +#define ASM_COMMENT_START "# "
9852 +
9853 +/*
9854 +A C string constant for text to be output before each asm
9855 +statement or group of consecutive ones. Normally this is
9856 +"#APP", which is a comment that has no effect on most
9857 +assemblers but tells the GNU assembler that it must check the lines
9858 +that follow for all valid assembler constructs.
9859 +*/
9860 +#undef ASM_APP_ON
9861 +#define ASM_APP_ON "#APP\n"
9862 +
9863 +/*
9864 +A C string constant for text to be output after each asm
9865 +statement or group of consecutive ones. Normally this is
9866 +"#NO_APP", which tells the GNU assembler to resume making the
9867 +time-saving assumptions that are valid for ordinary compiler output.
9868 +*/
9869 +#undef ASM_APP_OFF
9870 +#define ASM_APP_OFF "#NO_APP\n"
9871 +
9872 +
9873 +
9874 +#define FILE_ASM_OP "\t.file\n"
9875 +#define IDENT_ASM_OP "\t.ident\t"
9876 +#define SET_ASM_OP "\t.set\t"
9877 +
9878 +
9879 +/*
9880 + * Output assembly directives to switch to section name. The section
9881 + * should have attributes as specified by flags, which is a bit mask
9882 + * of the SECTION_* flags defined in 'output.h'. If align is nonzero,
9883 + * it contains an alignment in bytes to be used for the section,
9884 + * otherwise some target default should be used. Only targets that
9885 + * must specify an alignment within the section directive need pay
9886 + * attention to align -- we will still use ASM_OUTPUT_ALIGN.
9887 + *
9888 + * NOTE: This one must not be moved to avr32.c
9889 + */
9890 +#undef TARGET_ASM_NAMED_SECTION
9891 +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
9892 +
9893 +
9894 +/*
9895 +You may define this macro as a C expression. You should define the
9896 +expression to have a nonzero value if GCC should output the constant
9897 +pool for a function before the code for the function, or a zero value if
9898 +GCC should output the constant pool after the function. If you do
9899 +not define this macro, the usual case, GCC will output the constant
9900 +pool before the function.
9901 +*/
9902 +#define CONSTANT_POOL_BEFORE_FUNCTION 0
9903 +
9904 +
9905 +/*
9906 +Define this macro as a C expression which is nonzero if the constant
9907 +EXP, of type tree, should be output after the code for a
9908 +function. The compiler will normally output all constants before the
9909 +function; you need not define this macro if this is OK.
9910 +*/
9911 +#define CONSTANT_AFTER_FUNCTION_P(EXP) 1
9912 +
9913 +
9914 +/*
9915 +Define this macro as a C expression which is nonzero if C is
9916 +used as a logical line separator by the assembler.
9917 +
9918 +If you do not define this macro, the default is that only
9919 +the character ';' is treated as a logical line separator.
9920 +*/
9921 +#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '\n')
9922 +
9923 +
9924 +/** Output of Uninitialized Variables **/
9925 +
9926 +/*
9927 +A C statement (sans semicolon) to output to the stdio stream
9928 +STREAM the assembler definition of a common-label named
9929 +NAME whose size is SIZE bytes. The variable ROUNDED
9930 +is the size rounded up to whatever alignment the caller wants.
9931 +
9932 +Use the expression assemble_name(STREAM, NAME) to
9933 +output the name itself; before and after that, output the additional
9934 +assembler syntax for defining the name, and a newline.
9935 +
9936 +This macro controls how the assembler definitions of uninitialized
9937 +common global variables are output.
9938 +*/
9939 +/*
9940 +#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
9941 + avr32_asm_output_common(STREAM, NAME, SIZE, ROUNDED)
9942 +*/
9943 +
9944 +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED) \
9945 + do \
9946 + { \
9947 + fputs ("\t.comm ", (FILE)); \
9948 + assemble_name ((FILE), (NAME)); \
9949 + fprintf ((FILE), ",%d\n", (SIZE)); \
9950 + } \
9951 + while (0)
9952 +
9953 +/*
9954 + * Like ASM_OUTPUT_BSS except takes the required alignment as a
9955 + * separate, explicit argument. If you define this macro, it is used
9956 + * in place of ASM_OUTPUT_BSS, and gives you more flexibility in
9957 + * handling the required alignment of the variable. The alignment is
9958 + * specified as the number of bits.
9959 + *
9960 + * Try to use function asm_output_aligned_bss defined in file varasm.c
9961 + * when defining this macro.
9962 + */
9963 +#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
9964 + asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGNMENT)
9965 +
9966 +/*
9967 +A C statement (sans semicolon) to output to the stdio stream
9968 +STREAM the assembler definition of a local-common-label named
9969 +NAME whose size is SIZE bytes. The variable ROUNDED
9970 +is the size rounded up to whatever alignment the caller wants.
9971 +
9972 +Use the expression assemble_name(STREAM, NAME) to
9973 +output the name itself; before and after that, output the additional
9974 +assembler syntax for defining the name, and a newline.
9975 +
9976 +This macro controls how the assembler definitions of uninitialized
9977 +static variables are output.
9978 +*/
9979 +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED) \
9980 + do \
9981 + { \
9982 + fputs ("\t.lcomm ", (FILE)); \
9983 + assemble_name ((FILE), (NAME)); \
9984 + fprintf ((FILE), ",%d, %d\n", (SIZE), 2); \
9985 + } \
9986 + while (0)
9987 +
9988 +
9989 +/*
9990 +A C statement (sans semicolon) to output to the stdio stream
9991 +STREAM the assembler definition of a label named NAME.
9992 +Use the expression assemble_name(STREAM, NAME) to
9993 +output the name itself; before and after that, output the additional
9994 +assembler syntax for defining the name, and a newline.
9995 +*/
9996 +#define ASM_OUTPUT_LABEL(STREAM, NAME) avr32_asm_output_label(STREAM, NAME)
9997 +
9998 +/* A C string containing the appropriate assembler directive to
9999 + * specify the size of a symbol, without any arguments. On systems
10000 + * that use ELF, the default (in 'config/elfos.h') is '"\t.size\t"';
10001 + * on other systems, the default is not to define this macro.
10002 + *
10003 + * Define this macro only if it is correct to use the default
10004 + * definitions of ASM_ OUTPUT_SIZE_DIRECTIVE and
10005 + * ASM_OUTPUT_MEASURED_SIZE for your system. If you need your own
10006 + * custom definitions of those macros, or if you do not need explicit
10007 + * symbol sizes at all, do not define this macro.
10008 + */
10009 +#define SIZE_ASM_OP "\t.size\t"
10010 +
10011 +
10012 +/*
10013 +A C statement (sans semicolon) to output to the stdio stream
10014 +STREAM some commands that will make the label NAME global;
10015 +that is, available for reference from other files. Use the expression
10016 +assemble_name(STREAM, NAME) to output the name
10017 +itself; before and after that, output the additional assembler syntax
10018 +for making that name global, and a newline.
10019 +*/
10020 +#define GLOBAL_ASM_OP "\t.globl\t"
10021 +
10022 +
10023 +
10024 +/*
10025 +A C expression which evaluates to true if the target supports weak symbols.
10026 +
10027 +If you don't define this macro, defaults.h provides a default
10028 +definition. If either ASM_WEAKEN_LABEL or ASM_WEAKEN_DECL
10029 +is defined, the default definition is '1'; otherwise, it is
10030 +'0'. Define this macro if you want to control weak symbol support
10031 +with a compiler flag such as -melf.
10032 +*/
10033 +#define SUPPORTS_WEAK 1
10034 +
10035 +/*
10036 +A C statement (sans semicolon) to output to the stdio stream
10037 +STREAM a reference in assembler syntax to a label named
10038 +NAME. This should add '_' to the front of the name, if that
10039 +is customary on your operating system, as it is in most Berkeley Unix
10040 +systems. This macro is used in assemble_name.
10041 +*/
10042 +#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
10043 + avr32_asm_output_labelref(STREAM, NAME)
10044 +
10045 +
10046 +
10047 +/*
10048 +A C expression to assign to OUTVAR (which is a variable of type
10049 +char *) a newly allocated string made from the string
10050 +NAME and the number NUMBER, with some suitable punctuation
10051 +added. Use alloca to get space for the string.
10052 +
10053 +The string will be used as an argument to ASM_OUTPUT_LABELREF to
10054 +produce an assembler label for an internal static variable whose name is
10055 +NAME. Therefore, the string must be such as to result in valid
10056 +assembler code. The argument NUMBER is different each time this
10057 +macro is executed; it prevents conflicts between similarly-named
10058 +internal static variables in different scopes.
10059 +
10060 +Ideally this string should not be a valid C identifier, to prevent any
10061 +conflict with the user's own symbols. Most assemblers allow periods
10062 +or percent signs in assembler symbols; putting at least one of these
10063 +between the name and the number will suffice.
10064 +*/
10065 +#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER) \
10066 + do \
10067 + { \
10068 + (OUTVAR) = (char *) alloca (strlen ((NAME)) + 10); \
10069 + sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER)); \
10070 + } \
10071 + while (0)
10072 +
10073 +
10074 +/** Macros Controlling Initialization Routines **/
10075 +
10076 +
10077 +/*
10078 +If defined, main will not call __main as described above.
10079 +This macro should be defined for systems that control start-up code
10080 +on a symbol-by-symbol basis, such as OSF/1, and should not
10081 +be defined explicitly for systems that support INIT_SECTION_ASM_OP.
10082 +*/
10083 +/*
10084 + __main is not defined when debugging.
10085 +*/
10086 +#define HAS_INIT_SECTION
10087 +
10088 +
10089 +/** Output of Assembler Instructions **/
10090 +
10091 +/*
10092 +A C initializer containing the assembler's names for the machine
10093 +registers, each one as a C string constant. This is what translates
10094 +register numbers in the compiler into assembler language.
10095 +*/
10096 +
10097 +#define REGISTER_NAMES \
10098 +{ \
10099 + "pc", "lr", \
10100 + "sp", "r12", \
10101 + "r11", "r10", \
10102 + "r9", "r8", \
10103 + "r7", "r6", \
10104 + "r5", "r4", \
10105 + "r3", "r2", \
10106 + "r1", "r0", \
10107 + "f15","f14", \
10108 + "f13","f12", \
10109 + "f11","f10", \
10110 + "f9", "f8", \
10111 + "f7", "f6", \
10112 + "f5", "f4", \
10113 + "f3", "f2", \
10114 + "f1", "f0" \
10115 +}
10116 +
10117 +/*
10118 +A C compound statement to output to stdio stream STREAM the
10119 +assembler syntax for an instruction operand X. X is an
10120 +RTL expression.
10121 +
10122 +CODE is a value that can be used to specify one of several ways
10123 +of printing the operand. It is used when identical operands must be
10124 +printed differently depending on the context. CODE comes from
10125 +the '%' specification that was used to request printing of the
10126 +operand. If the specification was just '%digit' then
10127 +CODE is 0; if the specification was '%ltr digit'
10128 +then CODE is the ASCII code for ltr.
10129 +
10130 +If X is a register, this macro should print the register's name.
10131 +The names can be found in an array reg_names whose type is
10132 +char *[]. reg_names is initialized from REGISTER_NAMES.
10133 +
10134 +When the machine description has a specification '%punct'
10135 +(a '%' followed by a punctuation character), this macro is called
10136 +with a null pointer for X and the punctuation character for
10137 +CODE.
10138 +*/
10139 +#define PRINT_OPERAND(STREAM, X, CODE) avr32_print_operand(STREAM, X, CODE)
10140 +
10141 +/* A C statement to be executed just prior to the output of
10142 + assembler code for INSN, to modify the extracted operands so
10143 + they will be output differently.
10144 +
10145 + Here the argument OPVEC is the vector containing the operands
10146 + extracted from INSN, and NOPERANDS is the number of elements of
10147 + the vector which contain meaningful data for this insn.
10148 + The contents of this vector are what will be used to convert the insn
10149 + template into assembler code, so you can change the assembler output
10150 + by changing the contents of the vector. */
10151 +#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
10152 + avr32_final_prescan_insn ((INSN), (OPVEC), (NOPERANDS))
10153 +
10154 +/*
10155 +A C expression which evaluates to true if CODE is a valid
10156 +punctuation character for use in the PRINT_OPERAND macro. If
10157 +PRINT_OPERAND_PUNCT_VALID_P is not defined, it means that no
10158 +punctuation characters (except for the standard one, '%') are used
10159 +in this way.
10160 +*/
10161 +/*
10162 + 'm' refers to the most significant word in a two-register mode.
10163 +*/
10164 +#define PRINT_OPERAND_PUNCT_VALID_P(CODE) ((CODE) == 'm' || (CODE) == 'e')
10165 +
10166 +/*
10167 +A C compound statement to output to stdio stream STREAM the
10168 +assembler syntax for an instruction operand that is a memory reference
10169 +whose address is X. X is an RTL expression.
10170 +
10171 +On some machines, the syntax for a symbolic address depends on the
10172 +section that the address refers to. On these machines, define the macro
10173 +ENCODE_SECTION_INFO to store the information into the
10174 +symbol_ref, and then check for it here. (see Assembler Format.)
10175 +*/
10176 +#define PRINT_OPERAND_ADDRESS(STREAM, X) avr32_print_operand_address(STREAM, X)
10177 +
10178 +
10179 +/** Output of Dispatch Tables **/
10180 +
10181 +/*
10182 + * A C statement to output to the stdio stream stream an assembler
10183 + * pseudo-instruction to generate a difference between two
10184 + * labels. value and rel are the numbers of two internal labels. The
10185 + * definitions of these labels are output using
10186 + * (*targetm.asm_out.internal_label), and they must be printed in the
10187 + * same way here. For example,
10188 + *
10189 + * fprintf (stream, "\t.word L%d-L%d\n",
10190 + * value, rel)
10191 + *
10192 + * You must provide this macro on machines where the addresses in a
10193 + * dispatch table are relative to the table's own address. If defined,
10194 + * GCC will also use this macro on all machines when producing
10195 + * PIC. body is the body of the ADDR_DIFF_VEC; it is provided so that
10196 + * the mode and flags can be read.
10197 + */
10198 +#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL) \
10199 + fprintf(STREAM, "\tbral\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
10200 +
10201 +/*
10202 +This macro should be provided on machines where the addresses
10203 +in a dispatch table are absolute.
10204 +
10205 +The definition should be a C statement to output to the stdio stream
10206 +STREAM an assembler pseudo-instruction to generate a reference to
10207 +a label. VALUE is the number of an internal label whose
10208 +definition is output using ASM_OUTPUT_INTERNAL_LABEL.
10209 +For example,
10210 +
10211 +fprintf(STREAM, "\t.word L%d\n", VALUE)
10212 +*/
10213 +
10214 +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE) \
10215 + fprintf(STREAM, "\t.long %sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
10216 +
10217 +/** Assembler Commands for Exception Regions */
10218 +
10219 +/* ToDo: All of this subsection */
10220 +
10221 +/** Assembler Commands for Alignment */
10222 +
10223 +
10224 +/*
10225 +A C statement to output to the stdio stream STREAM an assembler
10226 +command to advance the location counter to a multiple of 2 to the
10227 +POWER bytes. POWER will be a C expression of type int.
10228 +*/
10229 +#define ASM_OUTPUT_ALIGN(STREAM, POWER) \
10230 + do \
10231 + { \
10232 + if ((POWER) != 0) \
10233 + fprintf(STREAM, "\t.align\t%d\n", POWER); \
10234 + } \
10235 + while (0)
10236 +
10237 +/*
10238 +Like ASM_OUTPUT_ALIGN, except that the \nop" instruction is used for padding, if
10239 +necessary.
10240 +*/
10241 +#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \
10242 + fprintf(STREAM, "\t.balignw\t%d, 0xd703\n", (1 << POWER))
10243 +
10244 +
10245 +
10246 +/******************************************************************************
10247 + * Controlling Debugging Information Format
10248 + *****************************************************************************/
10249 +
10250 +/* How to renumber registers for dbx and gdb. */
10251 +#define DBX_REGISTER_NUMBER(REGNO) ASM_REGNUM (REGNO)
10252 +
10253 +/* The DWARF 2 CFA column which tracks the return address. */
10254 +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM(LR_REGNUM)
10255 +
10256 +/*
10257 +Define this macro if GCC should produce dwarf version 2 format
10258 +debugging output in response to the -g option.
10259 +
10260 +To support optional call frame debugging information, you must also
10261 +define INCOMING_RETURN_ADDR_RTX and either set
10262 +RTX_FRAME_RELATED_P on the prologue insns if you use RTL for the
10263 +prologue, or call dwarf2out_def_cfa and dwarf2out_reg_save
10264 +as appropriate from TARGET_ASM_FUNCTION_PROLOGUE if you don't.
10265 +*/
10266 +#define DWARF2_DEBUGGING_INFO 1
10267 +
10268 +
10269 +#define DWARF2_ASM_LINE_DEBUG_INFO 1
10270 +#define DWARF2_FRAME_INFO 1
10271 +
10272 +
10273 +/******************************************************************************
10274 + * Miscellaneous Parameters
10275 + *****************************************************************************/
10276 +
10277 +/* ToDo: a lot */
10278 +
10279 +/*
10280 +An alias for a machine mode name. This is the machine mode that
10281 +elements of a jump-table should have.
10282 +*/
10283 +#define CASE_VECTOR_MODE SImode
10284 +
10285 +/*
10286 +Define this macro to be a C expression to indicate when jump-tables
10287 +should contain relative addresses. If jump-tables never contain
10288 +relative addresses, then you need not define this macro.
10289 +*/
10290 +#define CASE_VECTOR_PC_RELATIVE 0
10291 +
10292 +/* Increase the threshold for using table jumps on the UC arch. */
10293 +#define CASE_VALUES_THRESHOLD ((avr32_arch->arch_type == ARCH_TYPE_AVR32_UC) ? 7 : 4)
10294 +
10295 +/*
10296 +The maximum number of bytes that a single instruction can move quickly
10297 +between memory and registers or between two memory locations.
10298 +*/
10299 +#define MOVE_MAX (2*UNITS_PER_WORD)
10300 +
10301 +
10302 +/* A C expression that is nonzero if on this machine the number of bits actually used
10303 + for the count of a shift operation is equal to the number of bits needed to represent
10304 + the size of the object being shifted. When this macro is nonzero, the compiler will
10305 + assume that it is safe to omit a sign-extend, zero-extend, and certain bitwise 'and'
10306 + instructions that truncates the count of a shift operation. On machines that have
10307 + instructions that act on bit-fields at variable positions, which may include 'bit test'
10308 + 378 GNU Compiler Collection (GCC) Internals
10309 + instructions, a nonzero SHIFT_COUNT_TRUNCATED also enables deletion of truncations
10310 + of the values that serve as arguments to bit-field instructions.
10311 + If both types of instructions truncate the count (for shifts) and position (for bit-field
10312 + operations), or if no variable-position bit-field instructions exist, you should define
10313 + this macro.
10314 + However, on some machines, such as the 80386 and the 680x0, truncation only applies
10315 + to shift operations and not the (real or pretended) bit-field operations. Define SHIFT_
10316 + COUNT_TRUNCATED to be zero on such machines. Instead, add patterns to the 'md' file
10317 + that include the implied truncation of the shift instructions.
10318 + You need not de\fne this macro if it would always have the value of zero. */
10319 +#define SHIFT_COUNT_TRUNCATED 1
10320 +
10321 +/*
10322 +A C expression which is nonzero if on this machine it is safe to
10323 +convert an integer of INPREC bits to one of OUTPREC
10324 +bits (where OUTPREC is smaller than INPREC) by merely
10325 +operating on it as if it had only OUTPREC bits.
10326 +
10327 +On many machines, this expression can be 1.
10328 +
10329 +When TRULY_NOOP_TRUNCATION returns 1 for a pair of sizes for
10330 +modes for which MODES_TIEABLE_P is 0, suboptimal code can result.
10331 +If this is the case, making TRULY_NOOP_TRUNCATION return 0 in
10332 +such cases may improve things.
10333 +*/
10334 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
10335 +
10336 +/*
10337 +An alias for the machine mode for pointers. On most machines, define
10338 +this to be the integer mode corresponding to the width of a hardware
10339 +pointer; SImode on 32-bit machine or DImode on 64-bit machines.
10340 +On some machines you must define this to be one of the partial integer
10341 +modes, such as PSImode.
10342 +
10343 +The width of Pmode must be at least as large as the value of
10344 +POINTER_SIZE. If it is not equal, you must define the macro
10345 +POINTERS_EXTEND_UNSIGNED to specify how pointers are extended
10346 +to Pmode.
10347 +*/
10348 +#define Pmode SImode
10349 +
10350 +/*
10351 +An alias for the machine mode used for memory references to functions
10352 +being called, in call RTL expressions. On most machines this
10353 +should be QImode.
10354 +*/
10355 +#define FUNCTION_MODE SImode
10356 +
10357 +
10358 +#define REG_S_P(x) \
10359 + (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (XEXP (x, 0))))
10360 +
10361 +
10362 +/* If defined, modifies the length assigned to instruction INSN as a
10363 + function of the context in which it is used. LENGTH is an lvalue
10364 + that contains the initially computed length of the insn and should
10365 + be updated with the correct length of the insn. */
10366 +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
10367 + ((LENGTH) = avr32_adjust_insn_length ((INSN), (LENGTH)))
10368 +
10369 +
10370 +#define CLZ_DEFINED_VALUE_AT_ZERO(mode, value) \
10371 + (value = 32, (mode == SImode))
10372 +
10373 +#define CTZ_DEFINED_VALUE_AT_ZERO(mode, value) \
10374 + (value = 32, (mode == SImode))
10375 +
10376 +#define UNITS_PER_SIMD_WORD UNITS_PER_WORD
10377 +
10378 +#define STORE_FLAG_VALUE 1
10379 +
10380 +enum avr32_builtins
10381 +{
10382 + AVR32_BUILTIN_MTSR,
10383 + AVR32_BUILTIN_MFSR,
10384 + AVR32_BUILTIN_MTDR,
10385 + AVR32_BUILTIN_MFDR,
10386 + AVR32_BUILTIN_CACHE,
10387 + AVR32_BUILTIN_SYNC,
10388 + AVR32_BUILTIN_TLBR,
10389 + AVR32_BUILTIN_TLBS,
10390 + AVR32_BUILTIN_TLBW,
10391 + AVR32_BUILTIN_BREAKPOINT,
10392 + AVR32_BUILTIN_XCHG,
10393 + AVR32_BUILTIN_LDXI,
10394 + AVR32_BUILTIN_BSWAP16,
10395 + AVR32_BUILTIN_BSWAP32,
10396 + AVR32_BUILTIN_COP,
10397 + AVR32_BUILTIN_MVCR_W,
10398 + AVR32_BUILTIN_MVRC_W,
10399 + AVR32_BUILTIN_MVCR_D,
10400 + AVR32_BUILTIN_MVRC_D,
10401 + AVR32_BUILTIN_MULSATHH_H,
10402 + AVR32_BUILTIN_MULSATHH_W,
10403 + AVR32_BUILTIN_MULSATRNDHH_H,
10404 + AVR32_BUILTIN_MULSATRNDWH_W,
10405 + AVR32_BUILTIN_MULSATWH_W,
10406 + AVR32_BUILTIN_MACSATHH_W,
10407 + AVR32_BUILTIN_SATADD_H,
10408 + AVR32_BUILTIN_SATSUB_H,
10409 + AVR32_BUILTIN_SATADD_W,
10410 + AVR32_BUILTIN_SATSUB_W,
10411 + AVR32_BUILTIN_MULWH_D,
10412 + AVR32_BUILTIN_MULNWH_D,
10413 + AVR32_BUILTIN_MACWH_D,
10414 + AVR32_BUILTIN_MACHH_D,
10415 + AVR32_BUILTIN_MUSFR,
10416 + AVR32_BUILTIN_MUSTR,
10417 + AVR32_BUILTIN_SATS,
10418 + AVR32_BUILTIN_SATU,
10419 + AVR32_BUILTIN_SATRNDS,
10420 + AVR32_BUILTIN_SATRNDU
10421 +};
10422 +
10423 +
10424 +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) \
10425 + ((MODE == SFmode) || (MODE == DFmode))
10426 +
10427 +#define RENAME_LIBRARY_SET ".set"
10428 +
10429 +/* Make ABI_NAME an alias for __GCC_NAME. */
10430 +#define RENAME_LIBRARY(GCC_NAME, ABI_NAME) \
10431 + __asm__ (".globl\t__avr32_" #ABI_NAME "\n" \
10432 + ".set\t__avr32_" #ABI_NAME \
10433 + ", __" #GCC_NAME "\n");
10434 +
10435 +/* Give libgcc functions avr32 ABI name. */
10436 +#ifdef L_muldi3
10437 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, mul64)
10438 +#endif
10439 +#ifdef L_divdi3
10440 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (divdi3, sdiv64)
10441 +#endif
10442 +#ifdef L_udivdi3
10443 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (udivdi3, udiv64)
10444 +#endif
10445 +#ifdef L_moddi3
10446 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (moddi3, smod64)
10447 +#endif
10448 +#ifdef L_umoddi3
10449 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (umoddi3, umod64)
10450 +#endif
10451 +#ifdef L_ashldi3
10452 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashldi3, lsl64)
10453 +#endif
10454 +#ifdef L_lshrdi3
10455 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (lshrdi3, lsr64)
10456 +#endif
10457 +#ifdef L_ashrdi3
10458 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashrdi3, asr64)
10459 +#endif
10460 +
10461 +#ifdef L_fixsfdi
10462 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f32_to_s64)
10463 +#endif
10464 +#ifdef L_fixunssfdi
10465 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f32_to_u64)
10466 +#endif
10467 +#ifdef L_floatdidf
10468 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, s64_to_f64)
10469 +#endif
10470 +#ifdef L_floatdisf
10471 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, s64_to_f32)
10472 +#endif
10473 +
10474 +#endif
10475 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32.md gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.md
10476 --- gcc-4.2.1/gcc/config/avr32/avr32.md 1970-01-01 01:00:00.000000000 +0100
10477 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.md 2007-09-28 10:33:00.000000000 +0200
10478 @@ -0,0 +1,4606 @@
10479 +;; AVR32 machine description file.
10480 +;; Copyright 2003-2006 Atmel Corporation.
10481 +;;
10482 +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
10483 +;;
10484 +;; This file is part of GCC.
10485 +;;
10486 +;; This program is free software; you can redistribute it and/or modify
10487 +;; it under the terms of the GNU General Public License as published by
10488 +;; the Free Software Foundation; either version 2 of the License, or
10489 +;; (at your option) any later version.
10490 +;;
10491 +;; This program is distributed in the hope that it will be useful,
10492 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
10493 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10494 +;; GNU General Public License for more details.
10495 +;;
10496 +;; You should have received a copy of the GNU General Public License
10497 +;; along with this program; if not, write to the Free Software
10498 +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
10499 +
10500 +;; -*- Mode: Scheme -*-
10501 +
10502 +(define_attr "type" "alu,alu2,alu_sat,mulhh,mulwh,mulww_w,mulww_d,div,machh_w,macww_w,macww_d,branch,call,load,load_rm,store,load2,load4,store2,store4,fmul,fcmps,fcmpd,fcast,fmv,fmvcpu,fldd,fstd,flds,fsts,fstm"
10503 + (const_string "alu"))
10504 +
10505 +
10506 +(define_attr "cc" "none,set_vncz,set_ncz,set_cz,set_z,bld,compare,cmp_cond_insn,clobber,call_set,fpcompare,from_fpcc"
10507 + (const_string "none"))
10508 +
10509 +
10510 +; NB! Keep this in sync with enum architecture_type in avr32.h
10511 +(define_attr "pipeline" "ap,uc"
10512 + (const (symbol_ref "avr32_arch->arch_type")))
10513 +
10514 +(define_attr "length" ""
10515 + (const_int 4))
10516 +
10517 +
10518 +;; Uses of UNSPEC in this file:
10519 +(define_constants
10520 + [(UNSPEC_PUSHM 0)
10521 + (UNSPEC_POPM 1)
10522 + (UNSPEC_UDIVMODSI4_INTERNAL 2)
10523 + (UNSPEC_DIVMODSI4_INTERNAL 3)
10524 + (UNSPEC_STM 4)
10525 + (UNSPEC_LDM 5)
10526 + (UNSPEC_MOVSICC 6)
10527 + (UNSPEC_ADDSICC 7)
10528 + (UNSPEC_COND_MI 8)
10529 + (UNSPEC_COND_PL 9)
10530 + (UNSPEC_PIC_SYM 10)
10531 + (UNSPEC_PIC_BASE 11)
10532 + (UNSPEC_STORE_MULTIPLE 12)
10533 + (UNSPEC_STMFP 13)
10534 + (UNSPEC_FPCC_TO_REG 14)
10535 + (UNSPEC_REG_TO_CC 15)
10536 + (UNSPEC_FORCE_MINIPOOL 16)
10537 + (UNSPEC_SATS 17)
10538 + (UNSPEC_SATU 18)
10539 + (UNSPEC_SATRNDS 19)
10540 + (UNSPEC_SATRNDU 20)
10541 + ])
10542 +
10543 +(define_constants
10544 + [(VUNSPEC_EPILOGUE 0)
10545 + (VUNSPEC_CACHE 1)
10546 + (VUNSPEC_MTSR 2)
10547 + (VUNSPEC_MFSR 3)
10548 + (VUNSPEC_BLOCKAGE 4)
10549 + (VUNSPEC_SYNC 5)
10550 + (VUNSPEC_TLBR 6)
10551 + (VUNSPEC_TLBW 7)
10552 + (VUNSPEC_TLBS 8)
10553 + (VUNSPEC_BREAKPOINT 9)
10554 + (VUNSPEC_MTDR 10)
10555 + (VUNSPEC_MFDR 11)
10556 + (VUNSPEC_MVCR 12)
10557 + (VUNSPEC_MVRC 13)
10558 + (VUNSPEC_COP 14)
10559 + (VUNSPEC_ALIGN 15)
10560 + (VUNSPEC_POOL_START 16)
10561 + (VUNSPEC_POOL_END 17)
10562 + (VUNSPEC_POOL_4 18)
10563 + (VUNSPEC_POOL_8 19)
10564 + (VUNSPEC_POOL_16 20)
10565 + (VUNSPEC_MUSFR 21)
10566 + (VUNSPEC_MUSTR 22)
10567 + (VUNSPEC_SYNC_CMPXCHG 23)
10568 + (VUNSPEC_SYNC_SET_LOCK_AND_LOAD 24)
10569 + (VUNSPEC_SYNC_STORE_IF_LOCK 25)
10570 + (VUNSPEC_EH_RETURN 26)
10571 + (VUNSPEC_FRS 27)
10572 + ])
10573 +
10574 +(define_constants
10575 + [
10576 + ;; R7 = 15-7 = 8
10577 + (FP_REGNUM 8)
10578 + ;; Return Register = R12 = 15 - 12 = 3
10579 + (RETVAL_REGNUM 3)
10580 + ;; SP = R13 = 15 - 13 = 2
10581 + (SP_REGNUM 2)
10582 + ;; LR = R14 = 15 - 14 = 1
10583 + (LR_REGNUM 1)
10584 + ;; PC = R15 = 15 - 15 = 0
10585 + (PC_REGNUM 0)
10586 + ;; FPSR = GENERAL_REGS + 1 = 17
10587 + (FPCC_REGNUM 17)
10588 + ])
10589 +
10590 +
10591 +
10592 +
10593 +;;******************************************************************************
10594 +;; Macros
10595 +;;******************************************************************************
10596 +
10597 +;; Integer Modes for basic alu insns
10598 +(define_mode_macro INTM [SI HI QI])
10599 +(define_mode_attr alu_cc_attr [(SI "set_vncz") (HI "clobber") (QI "clobber")])
10600 +
10601 +;; Move word modes
10602 +(define_mode_macro MOVM [SI V2HI V4QI])
10603 +
10604 +;; For mov/addcc insns
10605 +(define_mode_macro ADDCC [SI HI QI])
10606 +(define_mode_macro MOVCC [SI HI QI])
10607 +(define_mode_macro CMP [DI SI HI QI])
10608 +(define_mode_attr cmp_constraint [(DI "rKu20") (SI "rKs21") (HI "r") (QI "r")])
10609 +(define_mode_attr cmp_predicate [(DI "register_immediate_operand")
10610 + (SI "register_immediate_operand")
10611 + (HI "register_operand")
10612 + (QI "register_operand")])
10613 +
10614 +;; For all conditional insns
10615 +(define_code_macro any_cond [eq ne gt ge lt le gtu geu ltu leu])
10616 +(define_code_attr cond [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt") (le "le")
10617 + (gtu "hi") (geu "hs") (ltu "lo") (leu "ls")])
10618 +(define_code_attr invcond [(eq "ne") (ne "eq") (gt "le") (ge "lt") (lt "ge") (le "gt")
10619 + (gtu "ls") (geu "lo") (ltu "hs") (leu "hi")])
10620 +
10621 +;; For logical operations
10622 +(define_code_macro logical [and ior xor])
10623 +(define_code_attr logical_insn [(and "and") (ior "or") (xor "eor")])
10624 +
10625 +;; Load the predicates
10626 +(include "predicates.md")
10627 +
10628 +
10629 +;;******************************************************************************
10630 +;; Automaton pipeline description for avr32
10631 +;;******************************************************************************
10632 +
10633 +(define_automaton "avr32_ap")
10634 +
10635 +
10636 +(define_cpu_unit "is" "avr32_ap")
10637 +(define_cpu_unit "a1,m1,da" "avr32_ap")
10638 +(define_cpu_unit "a2,m2,d" "avr32_ap")
10639 +
10640 +;;Alu instructions
10641 +(define_insn_reservation "alu_op" 1
10642 + (and (eq_attr "pipeline" "ap")
10643 + (eq_attr "type" "alu"))
10644 + "is,a1,a2")
10645 +
10646 +(define_insn_reservation "alu2_op" 2
10647 + (and (eq_attr "pipeline" "ap")
10648 + (eq_attr "type" "alu2"))
10649 + "is,is+a1,a1+a2,a2")
10650 +
10651 +(define_insn_reservation "alu_sat_op" 2
10652 + (and (eq_attr "pipeline" "ap")
10653 + (eq_attr "type" "alu_sat"))
10654 + "is,a1,a2")
10655 +
10656 +
10657 +;;Mul instructions
10658 +(define_insn_reservation "mulhh_op" 2
10659 + (and (eq_attr "pipeline" "ap")
10660 + (eq_attr "type" "mulhh,mulwh"))
10661 + "is,m1,m2")
10662 +
10663 +(define_insn_reservation "mulww_w_op" 3
10664 + (and (eq_attr "pipeline" "ap")
10665 + (eq_attr "type" "mulww_w"))
10666 + "is,m1,m1+m2,m2")
10667 +
10668 +(define_insn_reservation "mulww_d_op" 5
10669 + (and (eq_attr "pipeline" "ap")
10670 + (eq_attr "type" "mulww_d"))
10671 + "is,m1,m1+m2,m1+m2,m2,m2")
10672 +
10673 +(define_insn_reservation "div_op" 33
10674 + (and (eq_attr "pipeline" "ap")
10675 + (eq_attr "type" "div"))
10676 + "is,m1,m1*31 + m2*31,m2")
10677 +
10678 +(define_insn_reservation "machh_w_op" 3
10679 + (and (eq_attr "pipeline" "ap")
10680 + (eq_attr "type" "machh_w"))
10681 + "is*2,m1,m2")
10682 +
10683 +
10684 +(define_insn_reservation "macww_w_op" 4
10685 + (and (eq_attr "pipeline" "ap")
10686 + (eq_attr "type" "macww_w"))
10687 + "is*2,m1,m1,m2")
10688 +
10689 +
10690 +(define_insn_reservation "macww_d_op" 6
10691 + (and (eq_attr "pipeline" "ap")
10692 + (eq_attr "type" "macww_d"))
10693 + "is*2,m1,m1+m2,m1+m2,m2")
10694 +
10695 +;;Bypasses for Mac instructions, because of accumulator cache.
10696 +;;Set latency as low as possible in order to let the compiler let
10697 +;;mul -> mac and mac -> mac combinations which use the same
10698 +;;accumulator cache be placed close together to avoid any
10699 +;;instructions which can ruin the accumulator cache come inbetween.
10700 +(define_bypass 4 "machh_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10701 +(define_bypass 5 "macww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10702 +(define_bypass 7 "macww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10703 +
10704 +(define_bypass 3 "mulhh_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10705 +(define_bypass 4 "mulww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10706 +(define_bypass 6 "mulww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
10707 +
10708 +
10709 +;;Bypasses for all mul/mac instructions followed by an instruction
10710 +;;which reads the output AND writes the result to the same register.
10711 +;;This will generate an Write After Write hazard which gives an
10712 +;;extra cycle before the result is ready.
10713 +(define_bypass 0 "machh_w_op" "machh_w_op" "avr32_valid_macmac_bypass")
10714 +(define_bypass 0 "macww_w_op" "macww_w_op" "avr32_valid_macmac_bypass")
10715 +(define_bypass 0 "macww_d_op" "macww_d_op" "avr32_valid_macmac_bypass")
10716 +
10717 +(define_bypass 0 "mulhh_op" "machh_w_op" "avr32_valid_mulmac_bypass")
10718 +(define_bypass 0 "mulww_w_op" "macww_w_op" "avr32_valid_mulmac_bypass")
10719 +(define_bypass 0 "mulww_d_op" "macww_d_op" "avr32_valid_mulmac_bypass")
10720 +
10721 +;;Branch and call instructions
10722 +;;We assume that all branches and rcalls are predicted correctly :-)
10723 +;;while calls use a lot of cycles.
10724 +(define_insn_reservation "branch_op" 0
10725 + (and (eq_attr "pipeline" "ap")
10726 + (eq_attr "type" "branch"))
10727 + "nothing")
10728 +
10729 +(define_insn_reservation "call_op" 10
10730 + (and (eq_attr "pipeline" "ap")
10731 + (eq_attr "type" "call"))
10732 + "nothing")
10733 +
10734 +
10735 +;;Load store instructions
10736 +(define_insn_reservation "load_op" 2
10737 + (and (eq_attr "pipeline" "ap")
10738 + (eq_attr "type" "load"))
10739 + "is,da,d")
10740 +
10741 +(define_insn_reservation "load_rm_op" 3
10742 + (and (eq_attr "pipeline" "ap")
10743 + (eq_attr "type" "load_rm"))
10744 + "is,da,d")
10745 +
10746 +
10747 +(define_insn_reservation "store_op" 0
10748 + (and (eq_attr "pipeline" "ap")
10749 + (eq_attr "type" "store"))
10750 + "is,da,d")
10751 +
10752 +
10753 +(define_insn_reservation "load_double_op" 3
10754 + (and (eq_attr "pipeline" "ap")
10755 + (eq_attr "type" "load2"))
10756 + "is,da,da+d,d")
10757 +
10758 +(define_insn_reservation "load_quad_op" 4
10759 + (and (eq_attr "pipeline" "ap")
10760 + (eq_attr "type" "load4"))
10761 + "is,da,da+d,da+d,d")
10762 +
10763 +(define_insn_reservation "store_double_op" 0
10764 + (and (eq_attr "pipeline" "ap")
10765 + (eq_attr "type" "store2"))
10766 + "is,da,da+d,d")
10767 +
10768 +
10769 +(define_insn_reservation "store_quad_op" 0
10770 + (and (eq_attr "pipeline" "ap")
10771 + (eq_attr "type" "store4"))
10772 + "is,da,da+d,da+d,d")
10773 +
10774 +;;For store the operand to write to memory is read in d and
10775 +;;the real latency between any instruction and a store is therefore
10776 +;;one less than for the instructions which reads the operands in the first
10777 +;;excecution stage
10778 +(define_bypass 2 "load_double_op" "store_double_op" "avr32_store_bypass")
10779 +(define_bypass 3 "load_quad_op" "store_quad_op" "avr32_store_bypass")
10780 +(define_bypass 1 "load_op" "store_op" "avr32_store_bypass")
10781 +(define_bypass 2 "load_rm_op" "store_op" "avr32_store_bypass")
10782 +(define_bypass 1 "alu_sat_op" "store_op" "avr32_store_bypass")
10783 +(define_bypass 1 "alu2_op" "store_op" "avr32_store_bypass")
10784 +(define_bypass 1 "mulhh_op" "store_op" "avr32_store_bypass")
10785 +(define_bypass 2 "mulww_w_op" "store_op" "avr32_store_bypass")
10786 +(define_bypass 4 "mulww_d_op" "store_op" "avr32_store_bypass" )
10787 +(define_bypass 2 "machh_w_op" "store_op" "avr32_store_bypass")
10788 +(define_bypass 3 "macww_w_op" "store_op" "avr32_store_bypass")
10789 +(define_bypass 5 "macww_d_op" "store_op" "avr32_store_bypass")
10790 +
10791 +
10792 +; Bypass for load double operation. If only the first loaded word is needed
10793 +; then the latency is 2
10794 +(define_bypass 2 "load_double_op"
10795 + "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op,
10796 + mulww_d_op, machh_w_op, macww_w_op, macww_d_op"
10797 + "avr32_valid_load_double_bypass")
10798 +
10799 +; Bypass for load quad operation. If only the first or second loaded word is needed
10800 +; we set the latency to 2
10801 +(define_bypass 2 "load_quad_op"
10802 + "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op,
10803 + mulww_d_op, machh_w_op, macww_w_op, macww_d_op"
10804 + "avr32_valid_load_quad_bypass")
10805 +
10806 +
10807 +;;******************************************************************************
10808 +;; End of Automaton pipeline description for avr32
10809 +;;******************************************************************************
10810 +
10811 +
10812 +
10813 +;;=============================================================================
10814 +;; move
10815 +;;-----------------------------------------------------------------------------
10816 +
10817 +;;== char - 8 bits ============================================================
10818 +(define_expand "movqi"
10819 + [(set (match_operand:QI 0 "nonimmediate_operand" "")
10820 + (match_operand:QI 1 "general_operand" ""))]
10821 + ""
10822 + {
10823 + if ( !no_new_pseudos ){
10824 + if (GET_CODE (operands[1]) == MEM && optimize){
10825 + rtx reg = gen_reg_rtx (SImode);
10826 +
10827 + emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
10828 + operands[1] = gen_lowpart (QImode, reg);
10829 + }
10830 +
10831 + /* One of the ops has to be in a register. */
10832 + if (GET_CODE (operands[0]) == MEM)
10833 + operands[1] = force_reg (QImode, operands[1]);
10834 + }
10835 +
10836 + })
10837 +
10838 +(define_insn "*movqi_internal"
10839 + [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
10840 + (match_operand:QI 1 "general_operand" "rKs08,m,r,i"))]
10841 + ""
10842 + "@
10843 + mov\t%0, %1
10844 + ld.ub\t%0, %1
10845 + st.b\t%0, %1
10846 + mov\t%0, %1"
10847 + [(set_attr "length" "2,4,4,4")
10848 + (set_attr "type" "alu,load_rm,store,alu")])
10849 +
10850 +
10851 +
10852 +;;== short - 16 bits ==========================================================
10853 +(define_expand "movhi"
10854 + [(set (match_operand:HI 0 "nonimmediate_operand" "")
10855 + (match_operand:HI 1 "general_operand" ""))]
10856 + ""
10857 + {
10858 + if ( !no_new_pseudos ){
10859 + if (GET_CODE (operands[1]) == MEM && optimize){
10860 + rtx reg = gen_reg_rtx (SImode);
10861 +
10862 + emit_insn (gen_extendhisi2 (reg, operands[1]));
10863 + operands[1] = gen_lowpart (HImode, reg);
10864 + }
10865 +
10866 + /* One of the ops has to be in a register. */
10867 + if (GET_CODE (operands[0]) == MEM)
10868 + operands[1] = force_reg (HImode, operands[1]);
10869 + }
10870 +
10871 + })
10872 +
10873 +(define_insn "*movhi_internal"
10874 + [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
10875 + (match_operand:HI 1 "general_operand" "rKs08,m,r,i"))]
10876 + ""
10877 + "@
10878 + mov\t%0, %1
10879 + ld.sh\t%0, %1
10880 + st.h\t%0, %1
10881 + mov\t%0, %1"
10882 + [(set_attr "length" "2,4,4,4")
10883 + (set_attr "type" "alu,load_rm,store,alu")])
10884 +
10885 +
10886 +;;== int - 32 bits ============================================================
10887 +
10888 +(define_expand "movmisalignsi"
10889 + [(set (match_operand:SI 0 "nonimmediate_operand" "")
10890 + (match_operand:SI 1 "nonimmediate_operand" ""))]
10891 + "TARGET_UNALIGNED_WORD"
10892 + {
10893 + }
10894 +)
10895 +
10896 +(define_expand "mov<mode>"
10897 + [(set (match_operand:MOVM 0 "register_operand" "")
10898 + (match_operand:MOVM 1 "general_operand" ""))]
10899 + ""
10900 + {
10901 +
10902 + /* One of the ops has to be in a register. */
10903 + if (GET_CODE (operands[0]) == MEM)
10904 + operands[1] = force_reg (<MODE>mode, operands[1]);
10905 +
10906 +
10907 + /* Check for out of range immediate constants as these may
10908 + occur during reloading, since it seems like reload does
10909 + not check if the immediate is legitimate. Don't know if
10910 + this is a bug? */
10911 + if ( reload_in_progress
10912 + && avr32_arch->arch_type != ARCH_TYPE_AVR32_UC
10913 + && GET_CODE(operands[1]) == CONST_INT
10914 + && !avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', "Ks21") ){
10915 + operands[1] = force_const_mem(SImode, operands[1]);
10916 + }
10917 +
10918 + if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS)
10919 + && !avr32_legitimate_pic_operand_p(operands[1]) )
10920 + operands[1] = legitimize_pic_address (operands[1], <MODE>mode,
10921 + (no_new_pseudos ? operands[0] : 0));
10922 + else if ( flag_pic && avr32_address_operand(operands[1], GET_MODE(operands[1])) )
10923 + /* If we have an address operand then this function uses the pic register. */
10924 + current_function_uses_pic_offset_table = 1;
10925 + })
10926 +
10927 +
10928 +(define_insn "mov<mode>_internal"
10929 + [(set (match_operand:MOVM 0 "nonimmediate_operand" "=r, r, r,r,m,r")
10930 + (match_operand:MOVM 1 "general_operand" "rKs08,Ks21,n,m,r,W"))]
10931 + ""
10932 + {
10933 + switch (which_alternative) {
10934 + case 0:
10935 + case 1: return "mov\t%0, %1";
10936 + case 2: return "mov\t%0, lo(%1)\;orh\t%0,hi(%1)";
10937 + case 3:
10938 + if ( (REG_P(XEXP(operands[1], 0))
10939 + && REGNO(XEXP(operands[1], 0)) == SP_REGNUM)
10940 + || (GET_CODE(XEXP(operands[1], 0)) == PLUS
10941 + && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM
10942 + && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT
10943 + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0
10944 + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) )
10945 + return "lddsp\t%0, %1";
10946 + else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) )
10947 + return "lddpc\t%0, %1";
10948 + else
10949 + return "ld.w\t%0, %1";
10950 + case 4:
10951 + if ( (REG_P(XEXP(operands[0], 0))
10952 + && REGNO(XEXP(operands[0], 0)) == SP_REGNUM)
10953 + || (GET_CODE(XEXP(operands[0], 0)) == PLUS
10954 + && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM
10955 + && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT
10956 + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0
10957 + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) )
10958 + return "stdsp\t%0, %1";
10959 + else
10960 + return "st.w\t%0, %1";
10961 + case 5:
10962 + if ( TARGET_HAS_ASM_ADDR_PSEUDOS )
10963 + return "lda.w\t%0, %1";
10964 + else
10965 + return "ld.w\t%0, r6[%1@got]";
10966 + default:
10967 + abort();
10968 + }
10969 + }
10970 +
10971 + [(set_attr "length" "2,4,8,4,4,8")
10972 + (set_attr "type" "alu,alu,alu2,load,store,load")
10973 + (set_attr "cc" "none,none,set_z,none,none,clobber")])
10974 +
10975 +
10976 +;; These instructions are for loading constants which cannot be loaded
10977 +;; directly from the constant pool because the offset is too large
10978 +;; high and lo_sum are used even tough for our case it should be
10979 +;; low and high sum :-)
10980 +(define_insn "mov_symbol_lo"
10981 + [(set (match_operand:SI 0 "register_operand" "=r")
10982 + (high:SI (match_operand:SI 1 "immediate_operand" "i" )))]
10983 + ""
10984 + "mov\t%0, lo(%1)"
10985 + [(set_attr "type" "alu")
10986 + (set_attr "length" "4")]
10987 +)
10988 +
10989 +(define_insn "add_symbol_hi"
10990 + [(set (match_operand:SI 0 "register_operand" "=r")
10991 + (lo_sum:SI (match_dup 0)
10992 + (match_operand:SI 1 "immediate_operand" "i" )))]
10993 + ""
10994 + "orh\t%0, hi(%1)"
10995 + [(set_attr "type" "alu")
10996 + (set_attr "length" "4")]
10997 +)
10998 +
10999 +
11000 +
11001 +;; When generating pic, we need to load the symbol offset into a register.
11002 +;; So that the optimizer does not confuse this with a normal symbol load
11003 +;; we use an unspec. The offset will be loaded from a constant pool entry,
11004 +;; since that is the only type of relocation we can use.
11005 +(define_insn "pic_load_addr"
11006 + [(set (match_operand:SI 0 "register_operand" "=r")
11007 + (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYM))]
11008 + "flag_pic && CONSTANT_POOL_ADDRESS_P(XEXP(operands[1], 0))"
11009 + "lddpc\t%0, %1"
11010 + [(set_attr "type" "load")
11011 + (set_attr "length" "4")]
11012 +)
11013 +
11014 +(define_insn "pic_compute_got_from_pc"
11015 + [(set (match_operand:SI 0 "register_operand" "+r")
11016 + (unspec:SI [(minus:SI (pc)
11017 + (match_dup 0))] UNSPEC_PIC_BASE))
11018 + (use (label_ref (match_operand 1 "" "")))]
11019 + "flag_pic"
11020 + {
11021 + (*targetm.asm_out.internal_label) (asm_out_file, "L",
11022 + CODE_LABEL_NUMBER (operands[1]));
11023 + return \"rsub\t%0, pc\";
11024 + }
11025 + [(set_attr "cc" "clobber")
11026 + (set_attr "length" "2")]
11027 +)
11028 +
11029 +;;== long long int - 64 bits ==================================================
11030 +
11031 +(define_expand "movdi"
11032 + [(set (match_operand:DI 0 "nonimmediate_operand" "")
11033 + (match_operand:DI 1 "general_operand" ""))]
11034 + ""
11035 + {
11036 +
11037 + /* One of the ops has to be in a register. */
11038 + if (GET_CODE (operands[0]) != REG)
11039 + operands[1] = force_reg (DImode, operands[1]);
11040 +
11041 + })
11042 +
11043 +
11044 +(define_insn_and_split "*movdi_internal"
11045 + [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r, r, r,r,r,m")
11046 + (match_operand:DI 1 "general_operand" "r, Ks08,Ks21,G,n,m,r"))]
11047 + ""
11048 + {
11049 + switch (which_alternative ){
11050 + case 0:
11051 + case 1:
11052 + case 2:
11053 + case 3:
11054 + case 4:
11055 + return "#";
11056 + case 5:
11057 + if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])))
11058 + return "ld.d\t%0, pc[%1 - .]";
11059 + else
11060 + return "ld.d\t%0, %1";
11061 + case 6:
11062 + return "st.d\t%0, %1";
11063 + default:
11064 + abort();
11065 + }
11066 + }
11067 +;; Lets split all reg->reg or imm->reg transfers into two SImode transfers
11068 + "reload_completed &&
11069 + (REG_P (operands[0]) &&
11070 + (REG_P (operands[1])
11071 + || GET_CODE (operands[1]) == CONST_INT
11072 + || GET_CODE (operands[1]) == CONST_DOUBLE))"
11073 + [(set (match_dup 0) (match_dup 1))
11074 + (set (match_dup 2) (match_dup 3))]
11075 + {
11076 + operands[2] = gen_highpart (SImode, operands[0]);
11077 + operands[0] = gen_lowpart (SImode, operands[0]);
11078 + if ( REG_P(operands[1]) ){
11079 + operands[3] = gen_highpart(SImode, operands[1]);
11080 + operands[1] = gen_lowpart(SImode, operands[1]);
11081 + } else if ( GET_CODE(operands[1]) == CONST_DOUBLE
11082 + || GET_CODE(operands[1]) == CONST_INT ){
11083 + rtx split_const[2];
11084 + avr32_split_const_expr (DImode, SImode, operands[1], split_const);
11085 + operands[3] = split_const[1];
11086 + operands[1] = split_const[0];
11087 + } else {
11088 + internal_error("Illegal operand[1] for movdi split!");
11089 + }
11090 + }
11091 +
11092 + [(set_attr "length" "*,*,*,*,*,4,4")
11093 + (set_attr "type" "*,*,*,*,*,load2,store2")
11094 + (set_attr "cc" "*,*,*,*,*,none,none")])
11095 +
11096 +
11097 +;;== 128 bits ==================================================
11098 +(define_expand "movti"
11099 + [(set (match_operand:TI 0 "nonimmediate_operand" "")
11100 + (match_operand:TI 1 "nonimmediate_operand" ""))]
11101 + ""
11102 + {
11103 +
11104 + /* One of the ops has to be in a register. */
11105 + if (GET_CODE (operands[0]) != REG)
11106 + operands[1] = force_reg (TImode, operands[1]);
11107 +
11108 + /* We must fix any pre_dec for loads and post_inc stores */
11109 + if ( GET_CODE (operands[0]) == MEM
11110 + && GET_CODE (XEXP(operands[0],0)) == POST_INC ){
11111 + emit_move_insn(gen_rtx_MEM(TImode, XEXP(XEXP(operands[0],0),0)), operands[1]);
11112 + emit_insn(gen_addsi3(XEXP(XEXP(operands[0],0),0), XEXP(XEXP(operands[0],0),0), GEN_INT(GET_MODE_SIZE(TImode))));
11113 + DONE;
11114 + }
11115 +
11116 + if ( GET_CODE (operands[1]) == MEM
11117 + && GET_CODE (XEXP(operands[1],0)) == PRE_DEC ){
11118 + emit_insn(gen_addsi3(XEXP(XEXP(operands[1],0),0), XEXP(XEXP(operands[1],0),0), GEN_INT(-GET_MODE_SIZE(TImode))));
11119 + emit_move_insn(operands[0], gen_rtx_MEM(TImode, XEXP(XEXP(operands[1],0),0)));
11120 + DONE;
11121 + }
11122 + })
11123 +
11124 +
11125 +(define_insn_and_split "*movti_internal"
11126 + [(set (match_operand:TI 0 "avr32_movti_dst_operand" "=r,r,<RKu00,r,r")
11127 + (match_operand:TI 1 "avr32_movti_src_operand" " r,RKu00>,r,n,m"))]
11128 + ""
11129 + {
11130 + switch (which_alternative ){
11131 + case 0:
11132 + case 3:
11133 + return "#";
11134 + case 1:
11135 + return "ldm\t%p1, %0";
11136 + case 2:
11137 + return "stm\t%p0, %1";
11138 + case 4:
11139 + return "ld.d\t%U0, pc[%1 - .]\;ld.d\t%B0, pc[%1 - . + 8]";
11140 + }
11141 + }
11142 +
11143 + "reload_completed &&
11144 + (REG_P (operands[0]) &&
11145 + (REG_P (operands[1])
11146 + || (GET_CODE (operands[1]) == MEM
11147 + && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
11148 + && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))
11149 + || GET_CODE (operands[1]) == CONST_INT
11150 + || GET_CODE (operands[1]) == CONST_DOUBLE))"
11151 + [(set (match_dup 0) (match_dup 1))
11152 + (set (match_dup 2) (match_dup 3))]
11153 + {
11154 + operands[2] = simplify_gen_subreg ( DImode, operands[0],
11155 + TImode, 0 );
11156 + operands[0] = simplify_gen_subreg ( DImode, operands[0],
11157 + TImode, 8 );
11158 + if ( REG_P(operands[1]) ){
11159 + operands[3] = simplify_gen_subreg ( DImode, operands[1],
11160 + TImode, 0 );
11161 + operands[1] = simplify_gen_subreg ( DImode, operands[1],
11162 + TImode, 8 );
11163 + } else if ( GET_CODE(operands[1]) == CONST_DOUBLE
11164 + || GET_CODE(operands[1]) == CONST_INT ){
11165 + rtx split_const[2];
11166 + avr32_split_const_expr (TImode, DImode, operands[1], split_const);
11167 + operands[3] = split_const[1];
11168 + operands[1] = split_const[0];
11169 + } else if (avr32_const_pool_ref_operand (operands[1], GET_MODE(operands[1]))){
11170 + rtx split_const[2];
11171 + rtx cop = avoid_constant_pool_reference (operands[1]);
11172 + if (operands[1] == cop)
11173 + cop = get_pool_constant (XEXP (operands[1], 0));
11174 + avr32_split_const_expr (TImode, DImode, cop, split_const);
11175 + operands[3] = force_const_mem (DImode, split_const[1]);
11176 + operands[1] = force_const_mem (DImode, split_const[0]);
11177 + } else {
11178 + internal_error("Illegal operand[1] for movdi split!");
11179 + }
11180 + }
11181 + [(set_attr "length" "*,4,4,*,8")
11182 + (set_attr "type" "*,load4,store4,*,load4")])
11183 +
11184 +
11185 +;;== float - 32 bits ==========================================================
11186 +(define_expand "movsf"
11187 + [(set (match_operand:SF 0 "nonimmediate_operand" "")
11188 + (match_operand:SF 1 "general_operand" ""))]
11189 + ""
11190 + {
11191 +
11192 +
11193 + /* One of the ops has to be in a register. */
11194 + if (GET_CODE (operands[0]) != REG)
11195 + operands[1] = force_reg (SFmode, operands[1]);
11196 +
11197 + })
11198 +
11199 +(define_insn "*movsf_internal"
11200 + [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,r,r,m")
11201 + (match_operand:SF 1 "general_operand" "r, G,F,m,r"))]
11202 + "TARGET_SOFT_FLOAT"
11203 + {
11204 + switch (which_alternative) {
11205 + case 0:
11206 + case 1: return "mov\t%0, %1";
11207 + case 2: return "mov\t%0, lo(%1)\;orh\t%0, hi(%1)";
11208 + case 3:
11209 + if ( (REG_P(XEXP(operands[1], 0))
11210 + && REGNO(XEXP(operands[1], 0)) == SP_REGNUM)
11211 + || (GET_CODE(XEXP(operands[1], 0)) == PLUS
11212 + && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM
11213 + && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT
11214 + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0
11215 + && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) )
11216 + return "lddsp\t%0, %1";
11217 + else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) )
11218 + return "lddpc\t%0, %1";
11219 + else
11220 + return "ld.w\t%0, %1";
11221 + case 4:
11222 + if ( (REG_P(XEXP(operands[0], 0))
11223 + && REGNO(XEXP(operands[0], 0)) == SP_REGNUM)
11224 + || (GET_CODE(XEXP(operands[0], 0)) == PLUS
11225 + && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM
11226 + && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT
11227 + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0
11228 + && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) )
11229 + return "stdsp\t%0, %1";
11230 + else
11231 + return "st.w\t%0, %1";
11232 + default:
11233 + abort();
11234 + }
11235 + }
11236 +
11237 + [(set_attr "length" "2,4,8,4,4")
11238 + (set_attr "type" "alu,alu,alu2,load,store")
11239 + (set_attr "cc" "none,none,clobber,none,none")])
11240 +
11241 +
11242 +
11243 +;;== double - 64 bits =========================================================
11244 +(define_expand "movdf"
11245 + [(set (match_operand:DF 0 "nonimmediate_operand" "")
11246 + (match_operand:DF 1 "general_operand" ""))]
11247 + ""
11248 + {
11249 + /* One of the ops has to be in a register. */
11250 + if (GET_CODE (operands[0]) != REG){
11251 + operands[1] = force_reg (DFmode, operands[1]);
11252 + }
11253 + })
11254 +
11255 +
11256 +(define_insn_and_split "*movdf_internal"
11257 + [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,r,r,m")
11258 + (match_operand:DF 1 "general_operand" " r,G,F,m,r"))]
11259 + "TARGET_SOFT_FLOAT"
11260 + {
11261 + switch (which_alternative ){
11262 + case 0:
11263 + case 1:
11264 + case 2:
11265 + return "#";
11266 + case 3:
11267 + if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])))
11268 + return "ld.d\t%0, pc[%1 - .]";
11269 + else
11270 + return "ld.d\t%0, %1";
11271 + case 4:
11272 + return "st.d\t%0, %1";
11273 + default:
11274 + abort();
11275 + }
11276 + }
11277 + "TARGET_SOFT_FLOAT
11278 + && reload_completed
11279 + && (REG_P (operands[0])
11280 + && (REG_P (operands[1])
11281 + || GET_CODE (operands[1]) == CONST_DOUBLE))"
11282 + [(set (match_dup 0) (match_dup 1))
11283 + (set (match_dup 2) (match_dup 3))]
11284 + "
11285 + {
11286 + operands[2] = gen_highpart (SImode, operands[0]);
11287 + operands[0] = gen_lowpart (SImode, operands[0]);
11288 + operands[3] = gen_highpart(SImode, operands[1]);
11289 + operands[1] = gen_lowpart(SImode, operands[1]);
11290 + }
11291 + "
11292 +
11293 + [(set_attr "length" "*,*,*,4,4")
11294 + (set_attr "type" "*,*,*,load2,store2")
11295 + (set_attr "cc" "*,*,*,none,none")])
11296 +
11297 +
11298 +
11299 +
11300 +;;=============================================================================
11301 +;; Move chunks of memory
11302 +;;=============================================================================
11303 +
11304 +(define_expand "movmemsi"
11305 + [(match_operand:BLK 0 "general_operand" "")
11306 + (match_operand:BLK 1 "general_operand" "")
11307 + (match_operand:SI 2 "const_int_operand" "")
11308 + (match_operand:SI 3 "const_int_operand" "")]
11309 + ""
11310 + "
11311 + if (avr32_gen_movmemsi (operands))
11312 + DONE;
11313 + FAIL;
11314 + "
11315 +
11316 + )
11317 +
11318 +
11319 +
11320 +;;=============================================================================
11321 +;; Bit field instructions
11322 +;;-----------------------------------------------------------------------------
11323 +;; Instructions to insert or extract bit-fields
11324 +;;=============================================================================
11325 +
11326 +(define_insn "insv"
11327 + [ (set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
11328 + (match_operand:SI 1 "immediate_operand" "Ku05")
11329 + (match_operand:SI 2 "immediate_operand" "Ku05"))
11330 + (match_operand 3 "register_operand" "r"))]
11331 + ""
11332 + "bfins\t%0, %3, %2, %1"
11333 + [(set_attr "type" "alu")
11334 + (set_attr "length" "4")
11335 + (set_attr "cc" "set_ncz")])
11336 +
11337 +
11338 +
11339 +(define_expand "extv"
11340 + [ (set (match_operand:SI 0 "register_operand" "")
11341 + (sign_extract:SI (match_operand:SI 1 "register_operand" "")
11342 + (match_operand:SI 2 "immediate_operand" "")
11343 + (match_operand:SI 3 "immediate_operand" "")))]
11344 + ""
11345 + {
11346 + if ( INTVAL(operands[2]) >= 32 )
11347 + FAIL;
11348 + }
11349 +)
11350 +
11351 +(define_expand "extzv"
11352 + [ (set (match_operand:SI 0 "register_operand" "")
11353 + (zero_extract:SI (match_operand:SI 1 "register_operand" "")
11354 + (match_operand:SI 2 "immediate_operand" "")
11355 + (match_operand:SI 3 "immediate_operand" "")))]
11356 + ""
11357 + {
11358 + if ( INTVAL(operands[2]) >= 32 )
11359 + FAIL;
11360 + }
11361 +)
11362 +
11363 +(define_insn "extv_internal"
11364 + [ (set (match_operand:SI 0 "register_operand" "=r")
11365 + (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
11366 + (match_operand:SI 2 "immediate_operand" "Ku05")
11367 + (match_operand:SI 3 "immediate_operand" "Ku05")))]
11368 + "INTVAL(operands[2]) < 32"
11369 + "bfexts\t%0, %1, %3, %2"
11370 + [(set_attr "type" "alu")
11371 + (set_attr "length" "4")
11372 + (set_attr "cc" "set_ncz")])
11373 +
11374 +
11375 +(define_insn "extzv_internal"
11376 + [ (set (match_operand:SI 0 "register_operand" "=r")
11377 + (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
11378 + (match_operand:SI 2 "immediate_operand" "Ku05")
11379 + (match_operand:SI 3 "immediate_operand" "Ku05")))]
11380 + "INTVAL(operands[2]) < 32"
11381 + "bfextu\t%0, %1, %3, %2"
11382 + [(set_attr "type" "alu")
11383 + (set_attr "length" "4")
11384 + (set_attr "cc" "set_ncz")])
11385 +
11386 +
11387 +
11388 +;;=============================================================================
11389 +;; Some peepholes for avoiding unnecessary cast instructions
11390 +;; followed by bfins.
11391 +;;-----------------------------------------------------------------------------
11392 +
11393 +(define_peephole2
11394 + [(set (match_operand:SI 0 "register_operand" "")
11395 + (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
11396 + (set (zero_extract:SI (match_operand 2 "register_operand" "")
11397 + (match_operand:SI 3 "immediate_operand" "")
11398 + (match_operand:SI 4 "immediate_operand" ""))
11399 + (match_dup 0))]
11400 + "((peep2_reg_dead_p(2, operands[0]) &&
11401 + (INTVAL(operands[3]) <= 8)))"
11402 + [(set (zero_extract:SI (match_dup 2)
11403 + (match_dup 3)
11404 + (match_dup 4))
11405 + (match_dup 1))]
11406 + )
11407 +
11408 +(define_peephole2
11409 + [(set (match_operand:SI 0 "register_operand" "")
11410 + (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
11411 + (set (zero_extract:SI (match_operand 2 "register_operand" "")
11412 + (match_operand:SI 3 "immediate_operand" "")
11413 + (match_operand:SI 4 "immediate_operand" ""))
11414 + (match_dup 0))]
11415 + "((peep2_reg_dead_p(2, operands[0]) &&
11416 + (INTVAL(operands[3]) <= 16)))"
11417 + [(set (zero_extract:SI (match_dup 2)
11418 + (match_dup 3)
11419 + (match_dup 4))
11420 + (match_dup 1))]
11421 + )
11422 +
11423 +;;=============================================================================
11424 +;; push bytes
11425 +;;-----------------------------------------------------------------------------
11426 +;; Implements the push instruction
11427 +;;=============================================================================
11428 +(define_insn "pushm"
11429 + [(set (mem:BLK (pre_dec:BLK (reg:SI SP_REGNUM)))
11430 + (unspec:BLK [(match_operand 0 "const_int_operand" "")]
11431 + UNSPEC_PUSHM))]
11432 + ""
11433 + {
11434 + if (INTVAL(operands[0])) {
11435 + return "pushm\t%r0";
11436 + } else {
11437 + return "";
11438 + }
11439 + }
11440 + [(set_attr "type" "store")
11441 + (set_attr "length" "2")
11442 + (set_attr "cc" "none")])
11443 +
11444 +(define_insn "stm"
11445 + [(unspec [(match_operand 0 "register_operand" "r")
11446 + (match_operand 1 "const_int_operand" "")
11447 + (match_operand 2 "const_int_operand" "")]
11448 + UNSPEC_STM)]
11449 + ""
11450 + {
11451 + if (INTVAL(operands[1])) {
11452 + if (INTVAL(operands[2]) != 0)
11453 + return "stm\t--%0, %s1";
11454 + else
11455 + return "stm\t%0, %s1";
11456 + } else {
11457 + return "";
11458 + }
11459 + }
11460 + [(set_attr "type" "store")
11461 + (set_attr "length" "4")
11462 + (set_attr "cc" "none")])
11463 +
11464 +
11465 +
11466 +(define_insn "popm"
11467 + [(unspec [(match_operand 0 "const_int_operand" "")]
11468 + UNSPEC_POPM)]
11469 + ""
11470 + {
11471 + if (INTVAL(operands[0])) {
11472 + return "popm %r0";
11473 + } else {
11474 + return "";
11475 + }
11476 + }
11477 + [(set_attr "type" "load")
11478 + (set_attr "length" "2")])
11479 +
11480 +
11481 +
11482 +;;=============================================================================
11483 +;; add
11484 +;;-----------------------------------------------------------------------------
11485 +;; Adds reg1 with reg2 and puts the result in reg0.
11486 +;;=============================================================================
11487 +(define_insn "add<mode>3"
11488 + [(set (match_operand:INTM 0 "register_operand" "=r,r,r,r,r")
11489 + (plus:INTM (match_operand:INTM 1 "register_operand" "%0,r,0,r,0")
11490 + (match_operand:INTM 2 "avr32_add_operand" "r,r,Is08,Is16,Is21")))]
11491 + ""
11492 + "@
11493 + add %0, %2
11494 + add %0, %1, %2
11495 + sub %0, %n2
11496 + sub %0, %1, %n2
11497 + sub %0, %n2"
11498 +
11499 + [(set_attr "length" "2,4,2,4,4")
11500 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11501 +
11502 +(define_insn "add<mode>3_lsl"
11503 + [(set (match_operand:INTM 0 "register_operand" "=r")
11504 + (plus:INTM (ashift:INTM (match_operand:INTM 1 "register_operand" "r")
11505 + (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02"))
11506 + (match_operand:INTM 2 "register_operand" "r")))]
11507 + ""
11508 + "add %0, %2, %1 << %3"
11509 + [(set_attr "length" "4")
11510 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11511 +
11512 +(define_insn "add<mode>3_lsl2"
11513 + [(set (match_operand:INTM 0 "register_operand" "=r")
11514 + (plus:INTM (match_operand:INTM 1 "register_operand" "r")
11515 + (ashift:INTM (match_operand:INTM 2 "register_operand" "r")
11516 + (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02"))))]
11517 + ""
11518 + "add %0, %1, %2 << %3"
11519 + [(set_attr "length" "4")
11520 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11521 +
11522 +
11523 +
11524 +(define_insn "add<mode>3_mul"
11525 + [(set (match_operand:INTM 0 "register_operand" "=r")
11526 + (plus:INTM (mult:INTM (match_operand:INTM 1 "register_operand" "r")
11527 + (match_operand:INTM 3 "immediate_operand" "Ku04" ))
11528 + (match_operand:INTM 2 "register_operand" "r")))]
11529 + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
11530 + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
11531 + "add %0, %2, %1 << %p3"
11532 + [(set_attr "length" "4")
11533 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11534 +
11535 +(define_insn "add<mode>3_mul2"
11536 + [(set (match_operand:INTM 0 "register_operand" "=r")
11537 + (plus:INTM (match_operand:INTM 1 "register_operand" "r")
11538 + (mult:INTM (match_operand:INTM 2 "register_operand" "r")
11539 + (match_operand:INTM 3 "immediate_operand" "Ku04" ))))]
11540 + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
11541 + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
11542 + "add %0, %1, %2 << %p3"
11543 + [(set_attr "length" "4")
11544 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11545 +
11546 +
11547 +(define_peephole2
11548 + [(set (match_operand:SI 0 "register_operand" "")
11549 + (ashift:SI (match_operand:SI 1 "register_operand" "")
11550 + (match_operand:SI 2 "immediate_operand" "")))
11551 + (set (match_operand:SI 3 "register_operand" "")
11552 + (plus:SI (match_dup 0)
11553 + (match_operand:SI 4 "register_operand" "")))]
11554 + "(peep2_reg_dead_p(2, operands[0]) &&
11555 + (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))"
11556 + [(set (match_dup 3)
11557 + (plus:SI (ashift:SI (match_dup 1)
11558 + (match_dup 2))
11559 + (match_dup 4)))]
11560 + )
11561 +
11562 +(define_peephole2
11563 + [(set (match_operand:SI 0 "register_operand" "")
11564 + (ashift:SI (match_operand:SI 1 "register_operand" "")
11565 + (match_operand:SI 2 "immediate_operand" "")))
11566 + (set (match_operand:SI 3 "register_operand" "")
11567 + (plus:SI (match_operand:SI 4 "register_operand" "")
11568 + (match_dup 0)))]
11569 + "(peep2_reg_dead_p(2, operands[0]) &&
11570 + (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))"
11571 + [(set (match_dup 3)
11572 + (plus:SI (ashift:SI (match_dup 1)
11573 + (match_dup 2))
11574 + (match_dup 4)))]
11575 + )
11576 +
11577 +(define_insn "adddi3"
11578 + [(set (match_operand:DI 0 "register_operand" "=r,r")
11579 + (plus:DI (match_operand:DI 1 "register_operand" "%r,0")
11580 + (match_operand:DI 2 "register_operand" "r,r")))]
11581 + ""
11582 + "@
11583 + add %0, %1, %2\;adc %m0, %m1, %m2
11584 + add %0, %2\;adc %m0, %m0, %m2"
11585 + [(set_attr "length" "8,6")
11586 + (set_attr "type" "alu2")
11587 + (set_attr "cc" "set_vncz")])
11588 +
11589 +
11590 +
11591 +;;=============================================================================
11592 +;; subtract
11593 +;;-----------------------------------------------------------------------------
11594 +;; Subtract reg2 or immediate value from reg0 and puts the result in reg0.
11595 +;;=============================================================================
11596 +
11597 +(define_insn "sub<mode>3"
11598 + [(set (match_operand:INTM 0 "general_operand" "=r,r,r,r,r,r,r")
11599 + (minus:INTM (match_operand:INTM 1 "nonmemory_operand" "0,r,0,r,0,r,Ks08")
11600 + (match_operand:INTM 2 "nonmemory_operand" "r,r,Ks08,Ks16,Ks21,0,r")))]
11601 + ""
11602 + "@
11603 + sub %0, %2
11604 + sub %0, %1, %2
11605 + sub %0, %2
11606 + sub %0, %1, %2
11607 + sub %0, %2
11608 + rsub %0, %1
11609 + rsub %0, %2, %1"
11610 + [(set_attr "length" "2,4,2,4,4,2,4")
11611 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11612 +
11613 +(define_insn "*sub<mode>3_mul"
11614 + [(set (match_operand:INTM 0 "register_operand" "=r,r,r")
11615 + (minus:INTM (match_operand:INTM 1 "register_operand" "r,0,r")
11616 + (mult:INTM (match_operand:INTM 2 "register_operand" "r,r,0")
11617 + (match_operand:SI 3 "immediate_operand" "Ku04,Ku04,Ku04" ))))]
11618 + "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
11619 + (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
11620 + "@
11621 + sub %0, %1, %2 << %p3
11622 + sub %0, %0, %2 << %p3
11623 + sub %0, %1, %0 << %p3"
11624 + [(set_attr "length" "4,4,4")
11625 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11626 +
11627 +(define_insn "*sub<mode>3_lsl"
11628 + [(set (match_operand:INTM 0 "register_operand" "=r")
11629 + (minus:INTM (match_operand:INTM 1 "register_operand" "r")
11630 + (ashift:INTM (match_operand:INTM 2 "register_operand" "r")
11631 + (match_operand:SI 3 "avr32_add_shift_immediate_operand" "Ku02"))))]
11632 + ""
11633 + "sub %0, %1, %2 << %3"
11634 + [(set_attr "length" "4")
11635 + (set_attr "cc" "<INTM:alu_cc_attr>")])
11636 +
11637 +
11638 +(define_insn "subdi3"
11639 + [(set (match_operand:DI 0 "register_operand" "=r,r")
11640 + (minus:DI (match_operand:DI 1 "register_operand" "%r,0")
11641 + (match_operand:DI 2 "register_operand" "r,r")))]
11642 + ""
11643 + "@
11644 + sub %0, %1, %2\;sbc %m0, %m1, %m2
11645 + sub %0, %2\;sbc %m0, %m0, %m2"
11646 + [(set_attr "length" "8,6")
11647 + (set_attr "type" "alu2")
11648 + (set_attr "cc" "set_vncz")])
11649 +
11650 +
11651 +
11652 +;;=============================================================================
11653 +;; multiply
11654 +;;-----------------------------------------------------------------------------
11655 +;; Multiply op1 and op2 and put the value in op0.
11656 +;;=============================================================================
11657 +
11658 +
11659 +(define_insn "mulqi3"
11660 + [(set (match_operand:QI 0 "register_operand" "=r,r,r")
11661 + (mult:QI (match_operand:QI 1 "register_operand" "%0,r,r")
11662 + (match_operand:QI 2 "avr32_mul_operand" "r,r,Ks08")))]
11663 + ""
11664 + {
11665 + switch (which_alternative){
11666 + case 0:
11667 + return "mul %0, %2";
11668 + case 1:
11669 + return "mul %0, %1, %2";
11670 + case 2:
11671 + return "mul %0, %1, %2";
11672 + default:
11673 + abort();
11674 + }
11675 + }
11676 + [(set_attr "type" "mulww_w,mulww_w,mulwh")
11677 + (set_attr "length" "2,4,4")
11678 + (set_attr "cc" "none")])
11679 +
11680 +(define_insn "mulsi3"
11681 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
11682 + (mult:SI (match_operand:SI 1 "register_operand" "%0,r,r")
11683 + (match_operand:SI 2 "avr32_mul_operand" "r,r,Ks08")))]
11684 + ""
11685 + {
11686 + switch (which_alternative){
11687 + case 0:
11688 + return "mul %0, %2";
11689 + case 1:
11690 + return "mul %0, %1, %2";
11691 + case 2:
11692 + return "mul %0, %1, %2";
11693 + default:
11694 + abort();
11695 + }
11696 + }
11697 + [(set_attr "type" "mulww_w,mulww_w,mulwh")
11698 + (set_attr "length" "2,4,4")
11699 + (set_attr "cc" "none")])
11700 +
11701 +
11702 +(define_insn "mulhisi3"
11703 + [(set (match_operand:SI 0 "register_operand" "=r")
11704 + (mult:SI
11705 + (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
11706 + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
11707 + "TARGET_DSP"
11708 + "mulhh.w %0, %1:b, %2:b"
11709 + [(set_attr "type" "mulhh")
11710 + (set_attr "length" "4")
11711 + (set_attr "cc" "none")])
11712 +
11713 +(define_peephole2
11714 + [(match_scratch:DI 6 "r")
11715 + (set (match_operand:SI 0 "register_operand" "")
11716 + (mult:SI
11717 + (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
11718 + (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
11719 + (set (match_operand:SI 3 "register_operand" "")
11720 + (ashiftrt:SI (match_dup 0)
11721 + (const_int 16)))]
11722 + "TARGET_DSP
11723 + && (peep2_reg_dead_p(1, operands[0]) || (REGNO(operands[0]) == REGNO(operands[3])))"
11724 + [(set (match_dup 4) (sign_extend:SI (match_dup 1)))
11725 + (set (match_dup 6)
11726 + (ashift:DI (mult:DI (sign_extend:DI (match_dup 4))
11727 + (sign_extend:DI (match_dup 2)))
11728 + (const_int 16)))
11729 + (set (match_dup 3) (match_dup 5))]
11730 +
11731 + "{
11732 + operands[4] = gen_rtx_REG(SImode, REGNO(operands[1]));
11733 + operands[5] = gen_highpart (SImode, operands[4]);
11734 + }"
11735 + )
11736 +
11737 +(define_insn "mulnhisi3"
11738 + [(set (match_operand:SI 0 "register_operand" "=r")
11739 + (mult:SI
11740 + (sign_extend:SI (neg:HI (match_operand:HI 1 "register_operand" "r")))
11741 + (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
11742 + "TARGET_DSP"
11743 + "mulnhh.w %0, %1:b, %2:b"
11744 + [(set_attr "type" "mulhh")
11745 + (set_attr "length" "4")
11746 + (set_attr "cc" "none")])
11747 +
11748 +(define_insn "machisi3"
11749 + [(set (match_operand:SI 0 "register_operand" "+r")
11750 + (plus:SI (mult:SI
11751 + (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
11752 + (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
11753 + (match_dup 0)))]
11754 + "TARGET_DSP"
11755 + "machh.w %0, %1:b, %2:b"
11756 + [(set_attr "type" "machh_w")
11757 + (set_attr "length" "4")
11758 + (set_attr "cc" "none")])
11759 +
11760 +
11761 +
11762 +(define_insn "mulsidi3"
11763 + [(set (match_operand:DI 0 "register_operand" "=r")
11764 + (mult:DI
11765 + (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
11766 + (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
11767 + ""
11768 + "muls.d %0, %1, %2"
11769 + [(set_attr "type" "mulww_d")
11770 + (set_attr "length" "4")
11771 + (set_attr "cc" "none")])
11772 +
11773 +(define_insn "umulsidi3"
11774 + [(set (match_operand:DI 0 "register_operand" "=r")
11775 + (mult:DI
11776 + (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
11777 + (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
11778 + ""
11779 + "mulu.d %0, %1, %2"
11780 + [(set_attr "type" "mulww_d")
11781 + (set_attr "length" "4")
11782 + (set_attr "cc" "none")])
11783 +
11784 +(define_insn "*mulaccsi3"
11785 + [(set (match_operand:SI 0 "register_operand" "+r")
11786 + (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
11787 + (match_operand:SI 2 "register_operand" "r"))
11788 + (match_dup 0)))]
11789 + ""
11790 + "mac %0, %1, %2"
11791 + [(set_attr "type" "macww_w")
11792 + (set_attr "length" "4")
11793 + (set_attr "cc" "none")])
11794 +
11795 +(define_insn "mulaccsidi3"
11796 + [(set (match_operand:DI 0 "register_operand" "+r")
11797 + (plus:DI (mult:DI
11798 + (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
11799 + (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
11800 + (match_dup 0)))]
11801 + ""
11802 + "macs.d %0, %1, %2"
11803 + [(set_attr "type" "macww_d")
11804 + (set_attr "length" "4")
11805 + (set_attr "cc" "none")])
11806 +
11807 +(define_insn "umulaccsidi3"
11808 + [(set (match_operand:DI 0 "register_operand" "+r")
11809 + (plus:DI (mult:DI
11810 + (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
11811 + (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
11812 + (match_dup 0)))]
11813 + ""
11814 + "macu.d %0, %1, %2"
11815 + [(set_attr "type" "macww_d")
11816 + (set_attr "length" "4")
11817 + (set_attr "cc" "none")])
11818 +
11819 +
11820 +
11821 +;; Try to avoid Write-After-Write hazards for mul operations
11822 +;; if it can be done
11823 +(define_peephole2
11824 + [(set (match_operand:SI 0 "register_operand" "")
11825 + (mult:SI
11826 + (sign_extend:SI (match_operand 1 "general_operand" ""))
11827 + (sign_extend:SI (match_operand 2 "general_operand" ""))))
11828 + (set (match_dup 0)
11829 + (match_operator:SI 3 "alu_operator" [(match_dup 0)
11830 + (match_operand 4 "general_operand" "")]))]
11831 + "peep2_reg_dead_p(1, operands[2])"
11832 + [(set (match_dup 5)
11833 + (mult:SI
11834 + (sign_extend:SI (match_dup 1))
11835 + (sign_extend:SI (match_dup 2))))
11836 + (set (match_dup 0)
11837 + (match_op_dup 3 [(match_dup 5)
11838 + (match_dup 4)]))]
11839 + "{operands[5] = gen_rtx_REG(SImode, REGNO(operands[2]));}"
11840 + )
11841 +
11842 +
11843 +
11844 +;;=============================================================================
11845 +;; DSP instructions
11846 +;;=============================================================================
11847 +(define_insn "mulsathh_h"
11848 + [(set (match_operand:HI 0 "register_operand" "=r")
11849 + (ss_truncate:HI (ashiftrt:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
11850 + (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
11851 + (const_int 15))))]
11852 + "TARGET_DSP"
11853 + "mulsathh.h\t%0, %1:b, %2:b"
11854 + [(set_attr "length" "4")
11855 + (set_attr "cc" "none")
11856 + (set_attr "type" "mulhh")])
11857 +
11858 +(define_insn "mulsatrndhh_h"
11859 + [(set (match_operand:HI 0 "register_operand" "=r")
11860 + (ss_truncate:HI (ashiftrt:SI
11861 + (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
11862 + (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
11863 + (const_int 1073741824))
11864 + (const_int 15))))]
11865 + "TARGET_DSP"
11866 + "mulsatrndhh.h\t%0, %1:b, %2:b"
11867 + [(set_attr "length" "4")
11868 + (set_attr "cc" "none")
11869 + (set_attr "type" "mulhh")])
11870 +
11871 +(define_insn "mulsathh_w"
11872 + [(set (match_operand:SI 0 "register_operand" "=r")
11873 + (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
11874 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11875 + (const_int 1))))]
11876 + "TARGET_DSP"
11877 + "mulsathh.w\t%0, %1:b, %2:b"
11878 + [(set_attr "length" "4")
11879 + (set_attr "cc" "none")
11880 + (set_attr "type" "mulhh")])
11881 +
11882 +(define_insn "mulsatwh_w"
11883 + [(set (match_operand:SI 0 "register_operand" "=r")
11884 + (ss_truncate:SI (ashiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
11885 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11886 + (const_int 15))))]
11887 + "TARGET_DSP"
11888 + "mulsatwh.w\t%0, %1, %2:b"
11889 + [(set_attr "length" "4")
11890 + (set_attr "cc" "none")
11891 + (set_attr "type" "mulwh")])
11892 +
11893 +(define_insn "mulsatrndwh_w"
11894 + [(set (match_operand:SI 0 "register_operand" "=r")
11895 + (ss_truncate:SI (ashiftrt:DI (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
11896 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11897 + (const_int 1073741824))
11898 + (const_int 15))))]
11899 + "TARGET_DSP"
11900 + "mulsatrndwh.w\t%0, %1, %2:b"
11901 + [(set_attr "length" "4")
11902 + (set_attr "cc" "none")
11903 + (set_attr "type" "mulwh")])
11904 +
11905 +(define_insn "macsathh_w"
11906 + [(set (match_operand:SI 0 "register_operand" "+r")
11907 + (plus:SI (match_dup 0)
11908 + (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
11909 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11910 + (const_int 1)))))]
11911 + "TARGET_DSP"
11912 + "macsathh.w\t%0, %1:b, %2:b"
11913 + [(set_attr "length" "4")
11914 + (set_attr "cc" "none")
11915 + (set_attr "type" "mulhh")])
11916 +
11917 +
11918 +(define_insn "mulwh_d"
11919 + [(set (match_operand:DI 0 "register_operand" "=r")
11920 + (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
11921 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11922 + (const_int 16)))]
11923 + "TARGET_DSP"
11924 + "mulwh.d\t%0, %1, %2:b"
11925 + [(set_attr "length" "4")
11926 + (set_attr "cc" "none")
11927 + (set_attr "type" "mulwh")])
11928 +
11929 +
11930 +(define_insn "mulnwh_d"
11931 + [(set (match_operand:DI 0 "register_operand" "=r")
11932 + (ashift:DI (mult:DI (not:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))
11933 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11934 + (const_int 16)))]
11935 + "TARGET_DSP"
11936 + "mulnwh.d\t%0, %1, %2:b"
11937 + [(set_attr "length" "4")
11938 + (set_attr "cc" "none")
11939 + (set_attr "type" "mulwh")])
11940 +
11941 +(define_insn "macwh_d"
11942 + [(set (match_operand:DI 0 "register_operand" "+r")
11943 + (plus:DI (match_dup 0)
11944 + (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
11945 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
11946 + (const_int 16))))]
11947 + "TARGET_DSP"
11948 + "macwh.d\t%0, %1, %2:b"
11949 + [(set_attr "length" "4")
11950 + (set_attr "cc" "none")
11951 + (set_attr "type" "mulwh")])
11952 +
11953 +(define_insn "machh_d"
11954 + [(set (match_operand:DI 0 "register_operand" "+r")
11955 + (plus:DI (match_dup 0)
11956 + (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
11957 + (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))))]
11958 + "TARGET_DSP"
11959 + "machh.d\t%0, %1:b, %2:b"
11960 + [(set_attr "length" "4")
11961 + (set_attr "cc" "none")
11962 + (set_attr "type" "mulwh")])
11963 +
11964 +(define_insn "satadd_w"
11965 + [(set (match_operand:SI 0 "register_operand" "=r")
11966 + (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
11967 + (match_operand:SI 2 "register_operand" "r")))]
11968 + "TARGET_DSP"
11969 + "satadd.w\t%0, %1, %2"
11970 + [(set_attr "length" "4")
11971 + (set_attr "cc" "none")
11972 + (set_attr "type" "alu_sat")])
11973 +
11974 +(define_insn "satsub_w"
11975 + [(set (match_operand:SI 0 "register_operand" "=r")
11976 + (ss_minus:SI (match_operand:SI 1 "register_operand" "r")
11977 + (match_operand:SI 2 "register_operand" "r")))]
11978 + "TARGET_DSP"
11979 + "satsub.w\t%0, %1, %2"
11980 + [(set_attr "length" "4")
11981 + (set_attr "cc" "none")
11982 + (set_attr "type" "alu_sat")])
11983 +
11984 +(define_insn "satadd_h"
11985 + [(set (match_operand:HI 0 "register_operand" "=r")
11986 + (ss_plus:HI (match_operand:HI 1 "register_operand" "r")
11987 + (match_operand:HI 2 "register_operand" "r")))]
11988 + "TARGET_DSP"
11989 + "satadd.h\t%0, %1, %2"
11990 + [(set_attr "length" "4")
11991 + (set_attr "cc" "none")
11992 + (set_attr "type" "alu_sat")])
11993 +
11994 +(define_insn "satsub_h"
11995 + [(set (match_operand:HI 0 "register_operand" "=r")
11996 + (ss_minus:HI (match_operand:HI 1 "register_operand" "r")
11997 + (match_operand:HI 2 "register_operand" "r")))]
11998 + "TARGET_DSP"
11999 + "satsub.h\t%0, %1, %2"
12000 + [(set_attr "length" "4")
12001 + (set_attr "cc" "none")
12002 + (set_attr "type" "alu_sat")])
12003 +
12004 +
12005 +;;=============================================================================
12006 +;; smin
12007 +;;-----------------------------------------------------------------------------
12008 +;; Set reg0 to the smallest value of reg1 and reg2. It is used for signed
12009 +;; values in the registers.
12010 +;;=============================================================================
12011 +(define_insn "sminsi3"
12012 + [(set (match_operand:SI 0 "register_operand" "=r")
12013 + (smin:SI (match_operand:SI 1 "register_operand" "r")
12014 + (match_operand:SI 2 "register_operand" "r")))]
12015 + ""
12016 + "min %0, %1, %2"
12017 + [(set_attr "length" "4")
12018 + (set_attr "cc" "none")])
12019 +
12020 +;;=============================================================================
12021 +;; smax
12022 +;;-----------------------------------------------------------------------------
12023 +;; Set reg0 to the largest value of reg1 and reg2. It is used for signed
12024 +;; values in the registers.
12025 +;;=============================================================================
12026 +(define_insn "smaxsi3"
12027 + [(set (match_operand:SI 0 "register_operand" "=r")
12028 + (smax:SI (match_operand:SI 1 "register_operand" "r")
12029 + (match_operand:SI 2 "register_operand" "r")))]
12030 + ""
12031 + "max %0, %1, %2"
12032 + [(set_attr "length" "4")
12033 + (set_attr "cc" "none")])
12034 +
12035 +
12036 +;;=============================================================================
12037 +;; Logical operations
12038 +;;-----------------------------------------------------------------------------
12039 +
12040 +;; Split up simple DImode logical operations. Simply perform the logical
12041 +;; operation on the upper and lower halves of the registers.
12042 +(define_split
12043 + [(set (match_operand:DI 0 "register_operand" "")
12044 + (match_operator:DI 6 "logical_binary_operator"
12045 + [(match_operand:DI 1 "register_operand" "")
12046 + (match_operand:DI 2 "register_operand" "")]))]
12047 + "reload_completed"
12048 + [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
12049 + (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
12050 + "
12051 + {
12052 + operands[3] = gen_highpart (SImode, operands[0]);
12053 + operands[0] = gen_lowpart (SImode, operands[0]);
12054 + operands[4] = gen_highpart (SImode, operands[1]);
12055 + operands[1] = gen_lowpart (SImode, operands[1]);
12056 + operands[5] = gen_highpart (SImode, operands[2]);
12057 + operands[2] = gen_lowpart (SImode, operands[2]);
12058 + }"
12059 +)
12060 +
12061 +;;=============================================================================
12062 +;; Logical operations with shifted operand
12063 +;;=============================================================================
12064 +(define_insn "<code>si_lshift"
12065 + [(set (match_operand:SI 0 "register_operand" "=r")
12066 + (logical:SI (match_operator:SI 4 "logical_shift_operator"
12067 + [(match_operand:SI 2 "register_operand" "r")
12068 + (match_operand:SI 3 "immediate_operand" "Ku05")])
12069 + (match_operand:SI 1 "register_operand" "r")))]
12070 + ""
12071 + {
12072 + if ( GET_CODE(operands[4]) == ASHIFT )
12073 + return "<logical_insn>\t%0, %1, %2 << %3";
12074 + else
12075 + return "<logical_insn>\t%0, %1, %2 >> %3";
12076 + }
12077 +
12078 + [(set_attr "cc" "set_z")]
12079 +)
12080 +
12081 +
12082 +;;************************************************
12083 +;; Peepholes for detecting logical operantions
12084 +;; with shifted operands
12085 +;;************************************************
12086 +
12087 +(define_peephole
12088 + [(set (match_operand:SI 3 "register_operand" "")
12089 + (match_operator:SI 5 "logical_shift_operator"
12090 + [(match_operand:SI 1 "register_operand" "")
12091 + (match_operand:SI 2 "immediate_operand" "")]))
12092 + (set (match_operand:SI 0 "register_operand" "")
12093 + (logical:SI (match_operand:SI 4 "register_operand" "")
12094 + (match_dup 3)))]
12095 + "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))"
12096 + {
12097 + if ( GET_CODE(operands[5]) == ASHIFT )
12098 + return "<logical_insn>\t%0, %4, %1 << %2";
12099 + else
12100 + return "<logical_insn>\t%0, %4, %1 >> %2";
12101 + }
12102 + [(set_attr "cc" "set_z")]
12103 + )
12104 +
12105 +(define_peephole
12106 + [(set (match_operand:SI 3 "register_operand" "")
12107 + (match_operator:SI 5 "logical_shift_operator"
12108 + [(match_operand:SI 1 "register_operand" "")
12109 + (match_operand:SI 2 "immediate_operand" "")]))
12110 + (set (match_operand:SI 0 "register_operand" "")
12111 + (logical:SI (match_dup 3)
12112 + (match_operand:SI 4 "register_operand" "")))]
12113 + "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))"
12114 + {
12115 + if ( GET_CODE(operands[5]) == ASHIFT )
12116 + return "<logical_insn>\t%0, %4, %1 << %2";
12117 + else
12118 + return "<logical_insn>\t%0, %4, %1 >> %2";
12119 + }
12120 + [(set_attr "cc" "set_z")]
12121 + )
12122 +
12123 +
12124 +(define_peephole2
12125 + [(set (match_operand:SI 0 "register_operand" "")
12126 + (match_operator:SI 5 "logical_shift_operator"
12127 + [(match_operand:SI 1 "register_operand" "")
12128 + (match_operand:SI 2 "immediate_operand" "")]))
12129 + (set (match_operand:SI 3 "register_operand" "")
12130 + (logical:SI (match_operand:SI 4 "register_operand" "")
12131 + (match_dup 0)))]
12132 + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))"
12133 +
12134 + [(set (match_dup 3)
12135 + (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)])
12136 + (match_dup 4)))]
12137 +
12138 + ""
12139 +)
12140 +
12141 +(define_peephole2
12142 + [(set (match_operand:SI 0 "register_operand" "")
12143 + (match_operator:SI 5 "logical_shift_operator"
12144 + [(match_operand:SI 1 "register_operand" "")
12145 + (match_operand:SI 2 "immediate_operand" "")]))
12146 + (set (match_operand:SI 3 "register_operand" "")
12147 + (logical:SI (match_dup 0)
12148 + (match_operand:SI 4 "register_operand" "")))]
12149 + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))"
12150 +
12151 + [(set (match_dup 3)
12152 + (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)])
12153 + (match_dup 4)))]
12154 +
12155 + ""
12156 +)
12157 +
12158 +
12159 +;;=============================================================================
12160 +;; and
12161 +;;-----------------------------------------------------------------------------
12162 +;; Store the result after a bitwise logical-and between reg0 and reg2 in reg0.
12163 +;;=============================================================================
12164 +
12165 +(define_insn "andnsi"
12166 + [(set (match_operand:SI 0 "register_operand" "=r")
12167 + (and:SI (match_operand:SI 1 "register_operand" "0")
12168 + (not:SI (match_operand:SI 2 "register_operand" "r"))))]
12169 + ""
12170 + "andn %0, %2"
12171 + [(set_attr "cc" "set_z")
12172 + (set_attr "length" "2")]
12173 +)
12174 +
12175 +
12176 +
12177 +
12178 +(define_insn "andsi3"
12179 + [(set (match_operand:SI 0 "register_operand" "=r, r, r, r")
12180 + (and:SI (match_operand:SI 1 "register_operand" "%0, r, 0, r")
12181 + (match_operand:SI 2 "nonmemory_operand" "r, M, i, r")))]
12182 + ""
12183 + {
12184 + switch (which_alternative){
12185 + case 0:
12186 + return "and\t%0, %2";
12187 + case 1:
12188 + {
12189 + int i, first_set = -1;
12190 + /* Search for first bit set in mask */
12191 + for ( i = 31; i >= 0; --i )
12192 + if ( INTVAL(operands[2]) & (1 << i) ){
12193 + first_set = i;
12194 + break;
12195 + }
12196 + operands[2] = gen_rtx_CONST_INT(SImode, first_set + 1);
12197 + return "bfextu\t%0, %1, 0, %2";
12198 + }
12199 + case 2:
12200 + if ( one_bit_cleared_operand(operands[2], VOIDmode) ){
12201 + int bitpos;
12202 + for ( bitpos = 0; bitpos < 32; bitpos++ )
12203 + if ( !(INTVAL(operands[2]) & (1 << bitpos)) )
12204 + break;
12205 + operands[2] = gen_rtx_CONST_INT(SImode, bitpos);
12206 + return "cbr\t%0, %2";
12207 + } else if ( (INTVAL(operands[2]) >= 0) &&
12208 + (INTVAL(operands[2]) <= 65535) )
12209 + return "andl\t%0, %2, COH";
12210 + else if ( (INTVAL(operands[2]) < 0) &&
12211 + (INTVAL(operands[2]) >= -65536 ) )
12212 + return "andl\t%0, lo(%2)";
12213 + else if ( ((INTVAL(operands[2]) & 0xffff) == 0xffff) )
12214 + return "andh\t%0, hi(%2)";
12215 + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) )
12216 + return "andh\t%0, hi(%2), COH";
12217 + else
12218 + return "andh\t%0, hi(%2)\;andl\t%0, lo(%2)";
12219 + case 3:
12220 + return "and\t%0, %1, %2";
12221 + default:
12222 + abort();
12223 + }
12224 + }
12225 +
12226 + [(set_attr "length" "2,4,8,4")
12227 + (set_attr "cc" "set_z")])
12228 +
12229 +
12230 +(define_insn "anddi3"
12231 + [(set (match_operand:DI 0 "register_operand" "=&r,&r")
12232 + (and:DI (match_operand:DI 1 "register_operand" "%0,r")
12233 + (match_operand:DI 2 "register_operand" "r,r")))]
12234 + ""
12235 + "#"
12236 + [(set_attr "length" "8")
12237 + (set_attr "cc" "clobber")]
12238 +)
12239 +
12240 +;;=============================================================================
12241 +;; or
12242 +;;-----------------------------------------------------------------------------
12243 +;; Store the result after a bitwise inclusive-or between reg0 and reg2 in reg0.
12244 +;;=============================================================================
12245 +
12246 +(define_insn "iorsi3"
12247 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
12248 + (ior:SI (match_operand:SI 1 "register_operand" "%0,0,r" )
12249 + (match_operand:SI 2 "nonmemory_operand" "r ,i,r")))]
12250 + ""
12251 + {
12252 + switch (which_alternative){
12253 + case 0:
12254 + return "or\t%0, %2";
12255 + case 1:
12256 + if ( one_bit_set_operand(operands[2], VOIDmode) ){
12257 + int bitpos;
12258 + for (bitpos = 0; bitpos < 32; bitpos++)
12259 + if (INTVAL(operands[2]) & (1 << bitpos))
12260 + break;
12261 + operands[2] = gen_rtx_CONST_INT( SImode, bitpos);
12262 + return "sbr\t%0, %2";
12263 + } else if ( (INTVAL(operands[2]) >= 0) &&
12264 + (INTVAL(operands[2]) <= 65535) )
12265 + return "orl\t%0, %2";
12266 + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) )
12267 + return "orh\t%0, hi(%2)";
12268 + else
12269 + return "orh\t%0, hi(%2)\;orl\t%0, lo(%2)";
12270 + case 2:
12271 + return "or\t%0, %1, %2";
12272 + default:
12273 + abort();
12274 + }
12275 + }
12276 + [(set_attr "length" "2,8,4")
12277 + (set_attr "cc" "set_z")])
12278 +
12279 +
12280 +;(define_insn "iorsi3"
12281 +; [(set (match_operand:SI 0 "register_operand" "=r, r, r")
12282 +; (ior:SI (match_operand:SI 1 "avr32_logical_insn_operand" "r, r, rA" )
12283 +; (match_operand:SI 2 "register_operand" "0, i, r")))]
12284 +; ""
12285 +; {
12286 +; switch (which_alternative){
12287 +; case 0:
12288 +; return "or %0, %2";
12289 +; case 1:
12290 +; if ( one_bit_set_operand(operands[2], VOIDmode) ){
12291 +; int i, bitpos;
12292 +; for ( i = 0; i < 32; i++ )
12293 +; if ( INTVAL(operands[2]) & (1 << i) ){
12294 +; bitpos = i;
12295 +; break;
12296 +; }
12297 +; operands[2] = gen_rtx_CONST_INT( SImode, bitpos);
12298 +; return "sbr %0, %2";
12299 +; } else if ( (INTVAL(operands[2]) >= 0) &&
12300 +; (INTVAL(operands[2]) <= 65535) )
12301 +; return "orl %0, %2";
12302 +; else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) )
12303 +; return "orh %0, hi(%2)";
12304 +; else
12305 +; return "orh %0, hi(%2)\;orl %0, lo(%2)";
12306 +; case 2:
12307 +; return "or %0, %2, %1";
12308 +; }
12309 +; }
12310 +; [(set_attr "length" "2,8,4")
12311 +; (set_attr "cc" "set_z")])
12312 +
12313 +(define_insn "iordi3"
12314 + [(set (match_operand:DI 0 "register_operand" "=&r,&r")
12315 + (ior:DI (match_operand:DI 1 "register_operand" "%0,r")
12316 + (match_operand:DI 2 "register_operand" "r,r")))]
12317 + ""
12318 + "#"
12319 + [(set_attr "length" "8")
12320 + (set_attr "cc" "clobber")]
12321 +)
12322 +
12323 +;;=============================================================================
12324 +;; xor bytes
12325 +;;-----------------------------------------------------------------------------
12326 +;; Store the result after a bitwise exclusive-or between reg0 and reg2 in reg0.
12327 +;;=============================================================================
12328 +
12329 +(define_insn "xorsi3"
12330 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
12331 + (xor:SI (match_operand:SI 1 "register_operand" "0,0,r")
12332 + (match_operand:SI 2 "nonmemory_operand" "r,i,r")))]
12333 + ""
12334 + {
12335 + switch (which_alternative){
12336 + case 0:
12337 + return "eor %0, %2";
12338 + case 1:
12339 + if ( (INTVAL(operands[2]) >= 0) &&
12340 + (INTVAL(operands[2]) <= 65535) )
12341 + return "eorl %0, %2";
12342 + else if ( ((INTVAL(operands[2]) & 0xffff) == 0x0) )
12343 + return "eorh %0, hi(%2)";
12344 + else
12345 + return "eorh %0, hi(%2)\;eorl %0, lo(%2)";
12346 + case 2:
12347 + return "eor %0, %1, %2";
12348 + default:
12349 + abort();
12350 + }
12351 + }
12352 +
12353 + [(set_attr "length" "2,8,4")
12354 + (set_attr "cc" "set_z")])
12355 +
12356 +(define_insn "xordi3"
12357 + [(set (match_operand:DI 0 "register_operand" "=&r,&r")
12358 + (xor:DI (match_operand:DI 1 "register_operand" "%0,r")
12359 + (match_operand:DI 2 "register_operand" "r,r")))]
12360 + ""
12361 + "#"
12362 + [(set_attr "length" "8")
12363 + (set_attr "cc" "clobber")]
12364 +)
12365 +
12366 +;;=============================================================================
12367 +;; divmod
12368 +;;-----------------------------------------------------------------------------
12369 +;; Signed division that produces both a quotient and a remainder.
12370 +;;=============================================================================
12371 +(define_expand "divmodsi4"
12372 + [(parallel [
12373 + (parallel [
12374 + (set (match_operand:SI 0 "register_operand" "=r")
12375 + (div:SI (match_operand:SI 1 "register_operand" "r")
12376 + (match_operand:SI 2 "register_operand" "r")))
12377 + (set (match_operand:SI 3 "register_operand" "=r")
12378 + (mod:SI (match_dup 1)
12379 + (match_dup 2)))])
12380 + (use (match_dup 4))])]
12381 + ""
12382 + {
12383 + if (! no_new_pseudos) {
12384 + operands[4] = gen_reg_rtx (DImode);
12385 +
12386 + emit_insn(gen_divmodsi4_internal(operands[4],operands[1],operands[2]));
12387 + emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4));
12388 + emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0));
12389 +
12390 + DONE;
12391 + } else {
12392 + FAIL;
12393 + }
12394 +
12395 + })
12396 +
12397 +
12398 +(define_insn "divmodsi4_internal"
12399 + [(set (match_operand:DI 0 "register_operand" "=r")
12400 + (unspec:DI [(match_operand:SI 1 "register_operand" "r")
12401 + (match_operand:SI 2 "register_operand" "r")]
12402 + UNSPEC_DIVMODSI4_INTERNAL))]
12403 + ""
12404 + "divs %0, %1, %2"
12405 + [(set_attr "type" "div")
12406 + (set_attr "cc" "none")])
12407 +
12408 +
12409 +;;=============================================================================
12410 +;; udivmod
12411 +;;-----------------------------------------------------------------------------
12412 +;; Unsigned division that produces both a quotient and a remainder.
12413 +;;=============================================================================
12414 +(define_expand "udivmodsi4"
12415 + [(parallel [
12416 + (parallel [
12417 + (set (match_operand:SI 0 "register_operand" "=r")
12418 + (udiv:SI (match_operand:SI 1 "register_operand" "r")
12419 + (match_operand:SI 2 "register_operand" "r")))
12420 + (set (match_operand:SI 3 "register_operand" "=r")
12421 + (umod:SI (match_dup 1)
12422 + (match_dup 2)))])
12423 + (use (match_dup 4))])]
12424 + ""
12425 + {
12426 + if (! no_new_pseudos) {
12427 + operands[4] = gen_reg_rtx (DImode);
12428 +
12429 + emit_insn(gen_udivmodsi4_internal(operands[4],operands[1],operands[2]));
12430 + emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4));
12431 + emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0));
12432 +
12433 + DONE;
12434 + } else {
12435 + FAIL;
12436 + }
12437 + })
12438 +
12439 +(define_insn "udivmodsi4_internal"
12440 + [(set (match_operand:DI 0 "register_operand" "=r")
12441 + (unspec:DI [(match_operand:SI 1 "register_operand" "r")
12442 + (match_operand:SI 2 "register_operand" "r")]
12443 + UNSPEC_UDIVMODSI4_INTERNAL))]
12444 + ""
12445 + "divu %0, %1, %2"
12446 + [(set_attr "type" "div")
12447 + (set_attr "cc" "none")])
12448 +
12449 +
12450 +;;=============================================================================
12451 +;; Arithmetic-shift left
12452 +;;-----------------------------------------------------------------------------
12453 +;; Arithmetic-shift reg0 left by reg2 or immediate value.
12454 +;;=============================================================================
12455 +
12456 +(define_insn "ashlsi3"
12457 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
12458 + (ashift:SI (match_operand:SI 1 "register_operand" "r,0,r")
12459 + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))]
12460 + ""
12461 + "@
12462 + lsl %0, %1, %2
12463 + lsl %0, %2
12464 + lsl %0, %1, %2"
12465 + [(set_attr "length" "4,2,4")
12466 + (set_attr "cc" "set_ncz")])
12467 +
12468 +;;=============================================================================
12469 +;; Arithmetic-shift right
12470 +;;-----------------------------------------------------------------------------
12471 +;; Arithmetic-shift reg0 right by an immediate value.
12472 +;;=============================================================================
12473 +
12474 +(define_insn "ashrsi3"
12475 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
12476 + (ashiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
12477 + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))]
12478 + ""
12479 + "@
12480 + asr %0, %1, %2
12481 + asr %0, %2
12482 + asr %0, %1, %2"
12483 + [(set_attr "length" "4,2,4")
12484 + (set_attr "cc" "set_ncz")])
12485 +
12486 +;;=============================================================================
12487 +;; Logical shift right
12488 +;;-----------------------------------------------------------------------------
12489 +;; Logical shift reg0 right by an immediate value.
12490 +;;=============================================================================
12491 +
12492 +(define_insn "lshrsi3"
12493 + [(set (match_operand:SI 0 "register_operand" "=r,r,r")
12494 + (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,0,r")
12495 + (match_operand:SI 2 "nonmemory_operand" "r,Ku05,Ku05")))]
12496 + ""
12497 + "@
12498 + lsr %0, %1, %2
12499 + lsr %0, %2
12500 + lsr %0, %1, %2"
12501 + [(set_attr "length" "4,2,4")
12502 + (set_attr "cc" "set_ncz")])
12503 +
12504 +
12505 +;;=============================================================================
12506 +;; neg
12507 +;;-----------------------------------------------------------------------------
12508 +;; Negate operand 1 and store the result in operand 0.
12509 +;;=============================================================================
12510 +(define_insn "negsi2"
12511 + [(set (match_operand:SI 0 "register_operand" "=r")
12512 + (neg:SI (match_operand:SI 1 "register_operand" "0")))]
12513 + ""
12514 + "neg %0"
12515 + [(set_attr "length" "2")
12516 + (set_attr "cc" "set_vncz")])
12517 +
12518 +;;=============================================================================
12519 +;; abs
12520 +;;-----------------------------------------------------------------------------
12521 +;; Store the absolute value of operand 1 into operand 0.
12522 +;;=============================================================================
12523 +(define_insn "abssi2"
12524 + [(set (match_operand:SI 0 "register_operand" "=r")
12525 + (abs:SI (match_operand:SI 1 "register_operand" "0")))]
12526 + ""
12527 + "abs %0"
12528 + [(set_attr "length" "2")
12529 + (set_attr "cc" "set_z")])
12530 +
12531 +
12532 +;;=============================================================================
12533 +;; one_cmpl
12534 +;;-----------------------------------------------------------------------------
12535 +;; Store the bitwise-complement of operand 1 into operand 0.
12536 +;;=============================================================================
12537 +
12538 +(define_insn "one_cmplsi2"
12539 + [(set (match_operand:SI 0 "register_operand" "=r,r")
12540 + (not:SI (match_operand:SI 1 "register_operand" "r,0")))]
12541 + ""
12542 + "@
12543 + rsub %0, %1, -1
12544 + com %0"
12545 + [(set_attr "length" "4,2")
12546 + (set_attr "cc" "set_z")])
12547 +
12548 +
12549 +;;=============================================================================
12550 +;; Bit load
12551 +;;-----------------------------------------------------------------------------
12552 +;; Load a bit into Z and C flags
12553 +;;=============================================================================
12554 +(define_insn "bldsi"
12555 + [(set (cc0)
12556 + (and:SI (match_operand:SI 0 "register_operand" "r")
12557 + (match_operand:SI 1 "one_bit_set_operand" "i")))]
12558 + ""
12559 + "bld\t%0, %p1"
12560 + [(set_attr "length" "4")
12561 + (set_attr "cc" "bld")]
12562 + )
12563 +
12564 +
12565 +;;=============================================================================
12566 +;; Compare
12567 +;;-----------------------------------------------------------------------------
12568 +;; Compare reg0 with reg1 or an immediate value.
12569 +;;=============================================================================
12570 +
12571 +(define_expand "cmpqi"
12572 + [(set (cc0)
12573 + (compare:QI
12574 + (match_operand:QI 0 "general_operand" "")
12575 + (match_operand:QI 1 "general_operand" "")))]
12576 + ""
12577 + "{
12578 +
12579 + if ( GET_CODE(operands[0]) != REG
12580 + && GET_CODE(operands[0]) != SUBREG)
12581 + operands[0] = force_reg(QImode, operands[0]);
12582 +
12583 +
12584 + if ( GET_CODE(operands[1]) != REG
12585 + && GET_CODE(operands[1]) != SUBREG )
12586 + operands[1] = force_reg(QImode, operands[1]);
12587 +
12588 + avr32_compare_op0 = operands[0];
12589 + avr32_compare_op1 = operands[1];
12590 + emit_insn(gen_cmpqi_internal(operands[0], operands[1]));
12591 + DONE;
12592 + }"
12593 +)
12594 +
12595 +
12596 +(define_insn "cmpqi_internal"
12597 + [(set (cc0)
12598 + (compare:QI
12599 + (match_operand:QI 0 "register_operand" "r")
12600 + (match_operand:QI 1 "register_operand" "r")))]
12601 + ""
12602 + {
12603 + set_next_insn_cond(insn,
12604 + avr32_output_cmp(get_next_insn_cond(insn), QImode, operands[0], operands[1]));
12605 + return "";
12606 + }
12607 + [(set_attr "length" "4")
12608 + (set_attr "cc" "compare")])
12609 +
12610 +(define_expand "cmphi"
12611 + [(set (cc0)
12612 + (compare:HI
12613 + (match_operand:HI 0 "register_operand" "")
12614 + (match_operand:HI 1 "register_operand" "")))]
12615 + ""
12616 + "{
12617 +
12618 + //if ( (GET_CODE(operands[0]) == REG
12619 + // || GET_CODE(operands[0]) == SUBREG)
12620 + // && (GET_CODE(operands[1]) == CONST_INT
12621 + // && avr32_const_ok_for_constraint_p (INTVAL(operands[1]), 'K', \"Ks21\")) ){
12622 + // operands[0] = convert_to_mode(SImode, operands[0], 0);
12623 + // avr32_compare_op0 = operands[0];
12624 + // avr32_compare_op1 = operands[1];
12625 + // emit_insn(gen_cmpsi_internal(operands[0], operands[1]));
12626 + // DONE;
12627 + //}
12628 +
12629 + if ( GET_CODE(operands[0]) != REG
12630 + && GET_CODE(operands[0]) != SUBREG )
12631 + operands[0] = force_reg(HImode, operands[0]);
12632 +
12633 +
12634 + if ( GET_CODE(operands[1]) != REG
12635 + && GET_CODE(operands[1]) != SUBREG)
12636 + operands[1] = force_reg(HImode, operands[1]);
12637 +
12638 + avr32_compare_op0 = operands[0];
12639 + avr32_compare_op1 = operands[1];
12640 + }"
12641 +)
12642 +
12643 +
12644 +(define_insn "cmphi_internal"
12645 + [(set (cc0)
12646 + (compare:HI
12647 + (match_operand:HI 0 "register_operand" "r")
12648 + (match_operand:HI 1 "register_operand" "r")))]
12649 + ""
12650 + {
12651 + set_next_insn_cond(insn,
12652 + avr32_output_cmp(get_next_insn_cond(insn), HImode, operands[0], operands[1]));
12653 + return "";
12654 + }
12655 + [(set_attr "length" "4")
12656 + (set_attr "cc" "compare")])
12657 +
12658 +
12659 +(define_expand "cmpsi"
12660 + [(set (cc0)
12661 + (compare:SI
12662 + (match_operand:SI 0 "register_operand" "")
12663 + (match_operand:SI 1 "register_immediate_operand" "")))]
12664 + ""
12665 + "{
12666 + if ( GET_CODE(operands[0]) != REG
12667 + && GET_CODE(operands[0]) != SUBREG )
12668 + operands[0] = force_reg(SImode, operands[0]);
12669 +
12670 + if ( GET_CODE(operands[1]) != REG
12671 + && GET_CODE(operands[1]) != SUBREG
12672 + && GET_CODE(operands[1]) != CONST_INT )
12673 + operands[1] = force_reg(SImode, operands[1]);
12674 +
12675 + avr32_compare_op0 = operands[0];
12676 + avr32_compare_op1 = operands[1];
12677 +
12678 + }"
12679 +)
12680 +
12681 +
12682 +(define_insn "cmpsi_internal"
12683 + [(set (cc0)
12684 + (compare:SI
12685 + (match_operand:SI 0 "register_operand" "r, r, r")
12686 + (match_operand:SI 1 "register_immediate_operand" "r, Ks06, Ks21")))]
12687 + ""
12688 + {
12689 + set_next_insn_cond(insn,
12690 + avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], operands[1]));
12691 + return "";
12692 + }
12693 +
12694 + [(set_attr "length" "2,2,4")
12695 + (set_attr "cc" "compare")])
12696 +
12697 +
12698 +(define_expand "cmpdi"
12699 + [(set (cc0)
12700 + (compare:DI
12701 + (match_operand:DI 0 "register_operand" "")
12702 + (match_operand:DI 1 "register_immediate_operand" "")))]
12703 + ""
12704 + {
12705 + avr32_compare_op0 = operands[0];
12706 + avr32_compare_op1 = operands[1];
12707 + }
12708 +)
12709 +
12710 +(define_insn "cmpdi_internal"
12711 + [(set (cc0)
12712 + (compare:DI
12713 + (match_operand:DI 0 "register_operand" "r")
12714 + (match_operand:DI 1 "register_immediate_operand" "rKu20")))]
12715 + ""
12716 + {
12717 + set_next_insn_cond(insn,
12718 + avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], operands[1]));
12719 + return "";
12720 + }
12721 +
12722 + [(set_attr "length" "6")
12723 + (set_attr "type" "alu2")
12724 + (set_attr "cc" "compare")])
12725 +
12726 +
12727 +
12728 +;;=============================================================================
12729 +;; Test if zero
12730 +;;-----------------------------------------------------------------------------
12731 +;; Compare reg against zero and set the condition codes.
12732 +;;=============================================================================
12733 +
12734 +
12735 +(define_expand "tstsi"
12736 + [(set (cc0)
12737 + (match_operand:SI 0 "register_operand" ""))]
12738 + ""
12739 + {
12740 + avr32_compare_op0 = operands[0];
12741 + avr32_compare_op1 = const0_rtx;
12742 + }
12743 +)
12744 +
12745 +(define_insn "tstsi_internal"
12746 + [(set (cc0)
12747 + (match_operand:SI 0 "register_operand" "r"))]
12748 + ""
12749 + {
12750 + set_next_insn_cond(insn,
12751 + avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], const0_rtx));
12752 +
12753 + return "";
12754 + }
12755 + [(set_attr "length" "2")
12756 + (set_attr "cc" "compare")])
12757 +
12758 +
12759 +(define_expand "tstdi"
12760 + [(set (cc0)
12761 + (match_operand:DI 0 "register_operand" ""))]
12762 + ""
12763 + {
12764 + avr32_compare_op0 = operands[0];
12765 + avr32_compare_op1 = const0_rtx;
12766 + }
12767 +)
12768 +
12769 +(define_insn "tstdi_internal"
12770 + [(set (cc0)
12771 + (match_operand:DI 0 "register_operand" "r"))]
12772 + ""
12773 + {
12774 + set_next_insn_cond(insn,
12775 + avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], const0_rtx));
12776 + return "";
12777 + }
12778 + [(set_attr "length" "4")
12779 + (set_attr "type" "alu2")
12780 + (set_attr "cc" "compare")])
12781 +
12782 +
12783 +
12784 +;;=============================================================================
12785 +;; Convert operands
12786 +;;-----------------------------------------------------------------------------
12787 +;;
12788 +;;=============================================================================
12789 +(define_insn "truncdisi2"
12790 + [(set (match_operand:SI 0 "general_operand" "")
12791 + (truncate:SI (match_operand:DI 1 "general_operand" "")))]
12792 + ""
12793 + "truncdisi2")
12794 +
12795 +;;=============================================================================
12796 +;; Extend
12797 +;;-----------------------------------------------------------------------------
12798 +;;
12799 +;;=============================================================================
12800 +
12801 +
12802 +(define_insn "extendhisi2"
12803 + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
12804 + (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
12805 + ""
12806 + {
12807 + switch ( which_alternative ){
12808 + case 0:
12809 + return "casts.h\t%0";
12810 + case 1:
12811 + return "bfexts\t%0, %1, 0, 16";
12812 + case 2:
12813 + case 3:
12814 + return "ld.sh\t%0, %1";
12815 + default:
12816 + abort();
12817 + }
12818 + }
12819 + [(set_attr "length" "2,4,2,4")
12820 + (set_attr "cc" "set_ncz,set_ncz,none,none")
12821 + (set_attr "type" "alu,alu,load_rm,load_rm")])
12822 +
12823 +(define_insn "extendqisi2"
12824 + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
12825 + (sign_extend:SI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))]
12826 + ""
12827 + {
12828 + switch ( which_alternative ){
12829 + case 0:
12830 + return "casts.b\t%0";
12831 + case 1:
12832 + return "bfexts\t%0, %1, 0, 8";
12833 + case 2:
12834 + case 3:
12835 + return "ld.sb\t%0, %1";
12836 + default:
12837 + abort();
12838 + }
12839 + }
12840 + [(set_attr "length" "2,4,2,4")
12841 + (set_attr "cc" "set_ncz,set_ncz,none,none")
12842 + (set_attr "type" "alu,alu,load_rm,load_rm")])
12843 +
12844 +(define_insn "extendqihi2"
12845 + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
12846 + (sign_extend:HI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))]
12847 + ""
12848 + {
12849 + switch ( which_alternative ){
12850 + case 0:
12851 + return "casts.b\t%0";
12852 + case 1:
12853 + return "bfexts\t%0, %1, 0, 8";
12854 + case 2:
12855 + case 3:
12856 + return "ld.sb\t%0, %1";
12857 + default:
12858 + abort();
12859 + }
12860 + }
12861 + [(set_attr "length" "2,4,2,4")
12862 + (set_attr "cc" "set_ncz,set_ncz,none,none")
12863 + (set_attr "type" "alu,alu,load_rm,load_rm")])
12864 +
12865 +
12866 +;;=============================================================================
12867 +;; Zero-extend
12868 +;;-----------------------------------------------------------------------------
12869 +;;
12870 +;;=============================================================================
12871 +
12872 +(define_insn "zero_extendhisi2"
12873 + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
12874 + (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
12875 + ""
12876 + {
12877 + switch ( which_alternative ){
12878 + case 0:
12879 + return "castu.h\t%0";
12880 + case 1:
12881 + return "bfextu\t%0, %1, 0, 16";
12882 + case 2:
12883 + case 3:
12884 + return "ld.uh\t%0, %1";
12885 + default:
12886 + abort();
12887 + }
12888 + }
12889 +
12890 + [(set_attr "length" "2,4,2,4")
12891 + (set_attr "cc" "set_ncz,set_ncz,none,none")
12892 + (set_attr "type" "alu,alu,load_rm,load_rm")])
12893 +
12894 +(define_insn "zero_extendqisi2"
12895 + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
12896 + (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
12897 + ""
12898 + {
12899 + switch ( which_alternative ){
12900 + case 0:
12901 + return "castu.b\t%0";
12902 + case 1:
12903 + return "bfextu\t%0, %1, 0, 8";
12904 + case 2:
12905 + case 3:
12906 + return "ld.ub\t%0, %1";
12907 + default:
12908 + abort();
12909 + }
12910 + }
12911 + [(set_attr "length" "2,4,2,4")
12912 + (set_attr "cc" "set_ncz, set_ncz, none, none")
12913 + (set_attr "type" "alu, alu, load_rm, load_rm")])
12914 +
12915 +(define_insn "zero_extendqihi2"
12916 + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
12917 + (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
12918 + ""
12919 + {
12920 + switch ( which_alternative ){
12921 + case 0:
12922 + return "castu.b\t%0";
12923 + case 1:
12924 + return "bfextu\t%0, %1, 0, 8";
12925 + case 2:
12926 + case 3:
12927 + return "ld.ub\t%0, %1";
12928 + default:
12929 + abort();
12930 + }
12931 + }
12932 + [(set_attr "length" "2,4,2,4")
12933 + (set_attr "cc" "set_ncz, set_ncz, none, none")
12934 + (set_attr "type" "alu, alu, load_rm, load_rm")])
12935 +
12936 +
12937 +
12938 +;;=============================================================================
12939 +;; Conditional set register
12940 +;; sr{cond4} rd
12941 +;;-----------------------------------------------------------------------------
12942 +
12943 +;;Because of the same issue as with conditional moves and adds we must
12944 +;;not separate the compare instrcution from the scc instruction as
12945 +;;they might be sheduled "badly".
12946 +
12947 +(define_insn "s<code>"
12948 + [(set (match_operand:SI 0 "register_operand" "=r")
12949 + (any_cond:SI (cc0)
12950 + (const_int 0)))]
12951 + ""
12952 + "sr<cond>\t%0"
12953 + [(set_attr "length" "2")
12954 + (set_attr "cc" "none")])
12955 +
12956 +(define_insn "smi"
12957 + [(set (match_operand:SI 0 "register_operand" "=r")
12958 + (unspec:SI [(cc0)
12959 + (const_int 0)] UNSPEC_COND_MI))]
12960 + ""
12961 + "srmi\t%0"
12962 + [(set_attr "length" "2")
12963 + (set_attr "cc" "none")])
12964 +
12965 +(define_insn "spl"
12966 + [(set (match_operand:SI 0 "register_operand" "=r")
12967 + (unspec:SI [(cc0)
12968 + (const_int 0)] UNSPEC_COND_PL))]
12969 + ""
12970 + "srpl\t%0"
12971 + [(set_attr "length" "2")
12972 + (set_attr "cc" "none")])
12973 +
12974 +
12975 +;;=============================================================================
12976 +;; Conditional branch
12977 +;;-----------------------------------------------------------------------------
12978 +;; Branch to label if the specified condition codes are set.
12979 +;;=============================================================================
12980 +; branch if negative
12981 +(define_insn "bmi"
12982 + [(set (pc)
12983 + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI)
12984 + (label_ref (match_operand 0 "" ""))
12985 + (pc)))]
12986 + ""
12987 + "brmi %0"
12988 + [(set_attr "type" "branch")
12989 + (set (attr "length")
12990 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
12991 + (le (minus (pc) (match_dup 0)) (const_int 256)))
12992 + (const_int 2)] ; use compact branch
12993 + (const_int 4))) ; use extended branch
12994 + (set_attr "cc" "none")])
12995 +
12996 +(define_insn "*bmi-reverse"
12997 + [(set (pc)
12998 + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI)
12999 + (pc)
13000 + (label_ref (match_operand 0 "" ""))))]
13001 + ""
13002 + "brpl %0"
13003 + [(set_attr "type" "branch")
13004 + (set (attr "length")
13005 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
13006 + (le (minus (pc) (match_dup 0)) (const_int 256)))
13007 + (const_int 2)] ; use compact branch
13008 + (const_int 4))) ; use extended branch
13009 + (set_attr "cc" "none")])
13010 +
13011 +; branch if positive
13012 +(define_insn "bpl"
13013 + [(set (pc)
13014 + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL)
13015 + (label_ref (match_operand 0 "" ""))
13016 + (pc)))]
13017 + ""
13018 + "brpl %0"
13019 + [(set_attr "type" "branch")
13020 + (set (attr "length")
13021 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
13022 + (le (minus (pc) (match_dup 0)) (const_int 256)))
13023 + (const_int 2)] ; use compact branch
13024 + (const_int 4))) ; use extended branch
13025 + (set_attr "cc" "none")])
13026 +
13027 +(define_insn "*bpl-reverse"
13028 + [(set (pc)
13029 + (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL)
13030 + (pc)
13031 + (label_ref (match_operand 0 "" ""))))]
13032 + ""
13033 + "brmi %0"
13034 + [(set_attr "type" "branch")
13035 + (set (attr "length")
13036 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
13037 + (le (minus (pc) (match_dup 0)) (const_int 256)))
13038 + (const_int 2)] ; use compact branch
13039 + (const_int 4))) ; use extended branch
13040 + (set_attr "cc" "none")])
13041 +
13042 +; branch if equal
13043 +(define_insn "b<code>"
13044 + [(set (pc)
13045 + (if_then_else (any_cond:CC (cc0)
13046 + (const_int 0))
13047 + (label_ref (match_operand 0 "" ""))
13048 + (pc)))]
13049 + ""
13050 + "br<cond> %0 "
13051 + [(set_attr "type" "branch")
13052 + (set (attr "length")
13053 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
13054 + (le (minus (pc) (match_dup 0)) (const_int 256)))
13055 + (const_int 2)] ; use compact branch
13056 + (const_int 4))) ; use extended branch
13057 + (set_attr "cc" "none")])
13058 +
13059 +
13060 +(define_insn "*b<code>-reverse"
13061 + [(set (pc)
13062 + (if_then_else (any_cond:CC (cc0)
13063 + (const_int 0))
13064 + (pc)
13065 + (label_ref (match_operand 0 "" ""))))]
13066 + ""
13067 + "br<invcond> %0 "
13068 + [(set_attr "type" "branch")
13069 + (set (attr "length")
13070 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
13071 + (le (minus (pc) (match_dup 0)) (const_int 256)))
13072 + (const_int 2)] ; use compact branch
13073 + (const_int 4))) ; use extended branch
13074 + (set_attr "cc" "none")])
13075 +
13076 +
13077 +
13078 +;=============================================================================
13079 +; Conditional Add/Subtract
13080 +;-----------------------------------------------------------------------------
13081 +; sub{cond4} Rd, imm
13082 +;=============================================================================
13083 +
13084 +
13085 +(define_expand "add<mode>cc"
13086 + [(set (match_operand:ADDCC 0 "register_operand" "")
13087 + (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator"
13088 + [(match_dup 4)
13089 + (match_dup 5)])
13090 + (match_operand:ADDCC 2 "register_operand" "")
13091 + (plus:ADDCC
13092 + (match_dup 2)
13093 + (match_operand:ADDCC 3 "avr32_cond_immediate_operand" ""))))]
13094 + ""
13095 + {
13096 + /* Delete compare instruction as it is merged into this instruction */
13097 + remove_insn (get_last_insn_anywhere ());
13098 +
13099 + operands[4] = avr32_compare_op0;
13100 + operands[5] = avr32_compare_op1;
13101 + }
13102 + )
13103 +
13104 +
13105 +(define_insn "add<ADDCC:mode>cc_cmp<CMP:mode>"
13106 + [(set (match_operand:ADDCC 0 "register_operand" "=r")
13107 + (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator"
13108 + [(match_operand:CMP 4 "register_operand" "r")
13109 + (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>")])
13110 + (match_operand:ADDCC 2 "register_operand" "0")
13111 + (plus:ADDCC
13112 + (match_dup 2)
13113 + (match_operand:ADDCC 3 "avr32_cond_immediate_operand" "Is08"))))]
13114 + ""
13115 + {
13116 + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
13117 +
13118 + return "sub%i1\t%0, -%3";
13119 + }
13120 + [(set_attr "length" "8")
13121 + (set_attr "cc" "cmp_cond_insn")])
13122 +
13123 +;=============================================================================
13124 +; Conditional Move
13125 +;-----------------------------------------------------------------------------
13126 +; mov{cond4} Rd, (Rs/imm)
13127 +;=============================================================================
13128 +(define_expand "mov<mode>cc"
13129 + [(set (match_operand:MOVCC 0 "register_operand" "")
13130 + (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator"
13131 + [(match_dup 4)
13132 + (match_dup 5)])
13133 + (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "")
13134 + (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "")))]
13135 + ""
13136 + {
13137 + /* Delete compare instruction as it is merged into this instruction */
13138 + remove_insn (get_last_insn_anywhere ());
13139 +
13140 + operands[4] = avr32_compare_op0;
13141 + operands[5] = avr32_compare_op1;
13142 + }
13143 + )
13144 +
13145 +
13146 +(define_insn "mov<MOVCC:mode>cc_cmp<CMP:mode>"
13147 + [(set (match_operand:MOVCC 0 "register_operand" "=r,r,r")
13148 + (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator"
13149 + [(match_operand:CMP 4 "register_operand" "r,r,r")
13150 + (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>,<CMP:cmp_constraint>,<CMP:cmp_constraint>")])
13151 + (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "0, rKs08,rKs08")
13152 + (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "rKs08,0,rKs08")))]
13153 + ""
13154 + {
13155 + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
13156 +
13157 + switch( which_alternative ){
13158 + case 0:
13159 + return "mov%i1 %0, %3";
13160 + case 1:
13161 + return "mov%1 %0, %2";
13162 + case 2:
13163 + return "mov%1 %0, %2\;mov%i1 %0, %3";
13164 + default:
13165 + abort();
13166 + }
13167 +
13168 +
13169 + }
13170 + [(set_attr "length" "8,8,12")
13171 + (set_attr "cc" "cmp_cond_insn")])
13172 +
13173 +
13174 +;;=============================================================================
13175 +;; jump
13176 +;;-----------------------------------------------------------------------------
13177 +;; Jump inside a function; an unconditional branch to a label.
13178 +;;=============================================================================
13179 +(define_insn "jump"
13180 + [(set (pc)
13181 + (label_ref (match_operand 0 "" "")))]
13182 + ""
13183 + {
13184 + if (get_attr_length(insn) > 4)
13185 + return "Can't jump this far";
13186 + return (get_attr_length(insn) == 2 ?
13187 + "rjmp %0" : "bral %0");
13188 + }
13189 + [(set_attr "type" "branch")
13190 + (set (attr "length")
13191 + (cond [(and (le (minus (match_dup 0) (pc)) (const_int 1022))
13192 + (le (minus (pc) (match_dup 0)) (const_int 1024)))
13193 + (const_int 2) ; use rjmp
13194 + (le (match_dup 0) (const_int 1048575))
13195 + (const_int 4)] ; use bral
13196 + (const_int 8))) ; do something else
13197 + (set_attr "cc" "none")])
13198 +
13199 +;;=============================================================================
13200 +;; call
13201 +;;-----------------------------------------------------------------------------
13202 +;; Subroutine call instruction returning no value.
13203 +;;=============================================================================
13204 +(define_insn "call_internal"
13205 + [(parallel [(call (mem:SI (match_operand:SI 0 "avr32_call_operand" "r,U,T,W"))
13206 + (match_operand 1 "" ""))
13207 + (clobber (reg:SI LR_REGNUM))])]
13208 + ""
13209 + {
13210 + switch (which_alternative){
13211 + case 0:
13212 + return "icall\t%0";
13213 + case 1:
13214 + return "rcall\t%0";
13215 + case 2:
13216 + return "mcall\t%0";
13217 + case 3:
13218 + if ( TARGET_HAS_ASM_ADDR_PSEUDOS )
13219 + return "call\t%0";
13220 + else
13221 + return "mcall\tr6[%0@got]";
13222 + default:
13223 + abort();
13224 + }
13225 + }
13226 + [(set_attr "type" "call")
13227 + (set_attr "length" "2,4,4,10")
13228 + (set_attr "cc" "clobber")])
13229 +
13230 +
13231 +(define_expand "call"
13232 + [(parallel [(call (match_operand:SI 0 "" "")
13233 + (match_operand 1 "" ""))
13234 + (clobber (reg:SI LR_REGNUM))])]
13235 + ""
13236 + {
13237 + rtx call_address;
13238 + if ( GET_CODE(operands[0]) != MEM )
13239 + FAIL;
13240 +
13241 + call_address = XEXP(operands[0], 0);
13242 +
13243 + /* If assembler supports call pseudo insn and the call
13244 + address is a symbol then nothing special needs to be done. */
13245 + if ( TARGET_HAS_ASM_ADDR_PSEUDOS
13246 + && (GET_CODE(call_address) == SYMBOL_REF) ){
13247 + /* We must however mark the function as using the GOT if
13248 + flag_pic is set, since the call insn might turn into
13249 + a mcall using the GOT ptr register. */
13250 + if ( flag_pic ){
13251 + current_function_uses_pic_offset_table = 1;
13252 + emit_call_insn(gen_call_internal(call_address, operands[1]));
13253 + DONE;
13254 + }
13255 + } else {
13256 + if ( flag_pic &&
13257 + GET_CODE(call_address) == SYMBOL_REF ){
13258 + current_function_uses_pic_offset_table = 1;
13259 + emit_call_insn(gen_call_internal(call_address, operands[1]));
13260 + DONE;
13261 + }
13262 +
13263 + if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) ){
13264 + if ( optimize_size &&
13265 + GET_CODE(call_address) == SYMBOL_REF ){
13266 + call_address = force_const_mem(SImode, call_address);
13267 + } else {
13268 + call_address = force_reg(SImode, call_address);
13269 + }
13270 + }
13271 + }
13272 + emit_call_insn(gen_call_internal(call_address, operands[1]));
13273 + DONE;
13274 + }
13275 +)
13276 +
13277 +;;=============================================================================
13278 +;; call_value
13279 +;;-----------------------------------------------------------------------------
13280 +;; Subrutine call instruction returning a value.
13281 +;;=============================================================================
13282 +(define_expand "call_value"
13283 + [(parallel [(set (match_operand:SI 0 "" "")
13284 + (call (match_operand:SI 1 "" "")
13285 + (match_operand 2 "" "")))
13286 + (clobber (reg:SI LR_REGNUM))])]
13287 + ""
13288 + {
13289 + rtx call_address;
13290 + if ( GET_CODE(operands[1]) != MEM )
13291 + FAIL;
13292 +
13293 + call_address = XEXP(operands[1], 0);
13294 +
13295 + /* If assembler supports call pseudo insn and the call
13296 + address is a symbol then nothing special needs to be done. */
13297 + if ( TARGET_HAS_ASM_ADDR_PSEUDOS
13298 + && (GET_CODE(call_address) == SYMBOL_REF) ){
13299 + /* We must however mark the function as using the GOT if
13300 + flag_pic is set, since the call insn might turn into
13301 + a mcall using the GOT ptr register. */
13302 + if ( flag_pic ) {
13303 + current_function_uses_pic_offset_table = 1;
13304 + emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2]));
13305 + DONE;
13306 + }
13307 + } else {
13308 + if ( flag_pic &&
13309 + GET_CODE(call_address) == SYMBOL_REF ){
13310 + current_function_uses_pic_offset_table = 1;
13311 + emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2]));
13312 + DONE;
13313 + }
13314 +
13315 + if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[1]) ){
13316 + if ( optimize_size &&
13317 + GET_CODE(call_address) == SYMBOL_REF){
13318 + call_address = force_const_mem(SImode, call_address);
13319 + } else {
13320 + call_address = force_reg(SImode, call_address);
13321 + }
13322 + }
13323 + }
13324 + emit_call_insn(gen_call_value_internal(operands[0], call_address,
13325 + operands[2]));
13326 + DONE;
13327 +
13328 + })
13329 +
13330 +(define_insn "call_value_internal"
13331 + [(parallel [(set (match_operand 0 "register_operand" "=r,r,r,r")
13332 + (call (mem:SI (match_operand:SI 1 "avr32_call_operand" "r,U,T,W"))
13333 + (match_operand 2 "" "")))
13334 + (clobber (reg:SI LR_REGNUM))])]
13335 + ;; Operand 2 not used on the AVR32.
13336 + ""
13337 + {
13338 + switch (which_alternative){
13339 + case 0:
13340 + return "icall\t%1";
13341 + case 1:
13342 + return "rcall\t%1";
13343 + case 2:
13344 + return "mcall\t%1";
13345 + case 3:
13346 + if ( TARGET_HAS_ASM_ADDR_PSEUDOS )
13347 + return "call\t%1";
13348 + else
13349 + return "mcall\tr6[%1@got]";
13350 + default:
13351 + abort();
13352 + }
13353 + }
13354 + [(set_attr "type" "call")
13355 + (set_attr "length" "2,4,4,10")
13356 + (set_attr "cc" "call_set")])
13357 +
13358 +
13359 +;;=============================================================================
13360 +;; untyped_call
13361 +;;-----------------------------------------------------------------------------
13362 +;; Subrutine call instruction returning a value of any type.
13363 +;; The code is copied from m68k.md (except gen_blockage is removed)
13364 +;; Fixme!
13365 +;;=============================================================================
13366 +(define_expand "untyped_call"
13367 + [(parallel [(call (match_operand 0 "avr32_call_operand" "")
13368 + (const_int 0))
13369 + (match_operand 1 "" "")
13370 + (match_operand 2 "" "")])]
13371 + ""
13372 + {
13373 + int i;
13374 +
13375 + emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
13376 +
13377 + for (i = 0; i < XVECLEN (operands[2], 0); i++) {
13378 + rtx set = XVECEXP (operands[2], 0, i);
13379 + emit_move_insn (SET_DEST (set), SET_SRC (set));
13380 + }
13381 +
13382 + /* The optimizer does not know that the call sets the function value
13383 + registers we stored in the result block. We avoid problems by
13384 + claiming that all hard registers are used and clobbered at this
13385 + point. */
13386 + emit_insn (gen_blockage ());
13387 +
13388 + DONE;
13389 + })
13390 +
13391 +
13392 +;;=============================================================================
13393 +;; return
13394 +;;=============================================================================
13395 +
13396 +(define_insn "return"
13397 + [(return)]
13398 + "USE_RETURN_INSN (FALSE)"
13399 + {
13400 + avr32_output_return_instruction(TRUE, FALSE, NULL, NULL);
13401 + return "";
13402 + }
13403 + [(set_attr "length" "4")
13404 + (set_attr "type" "call")]
13405 + )
13406 +
13407 +(define_insn "return_cond"
13408 + [(set (pc)
13409 + (if_then_else (match_operand 0 "avr32_comparison_operand" "")
13410 + (return)
13411 + (pc)))]
13412 + "USE_RETURN_INSN (TRUE)"
13413 + "ret%0\tr12";
13414 + [(set_attr "type" "call")])
13415 +
13416 +
13417 +(define_insn "return_imm"
13418 + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
13419 + (use (reg RETVAL_REGNUM))
13420 + (return)])]
13421 + "USE_RETURN_INSN (FALSE) &&
13422 + ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
13423 + {
13424 + avr32_output_return_instruction(TRUE, FALSE, NULL, operands[0]);
13425 + return "";
13426 + }
13427 + [(set_attr "length" "4")
13428 + (set_attr "type" "call")]
13429 + )
13430 +
13431 +(define_insn "return_imm_cond"
13432 + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
13433 + (use (reg RETVAL_REGNUM))
13434 + (set (pc)
13435 + (if_then_else (match_operand 1 "avr32_comparison_operand" "")
13436 + (return)
13437 + (pc)))])]
13438 + "USE_RETURN_INSN (TRUE) &&
13439 + ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
13440 + "ret%1\t%0";
13441 + [(set_attr "type" "call")]
13442 + )
13443 +
13444 +(define_insn "return_<mode>reg"
13445 + [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r"))
13446 + (use (reg RETVAL_REGNUM))
13447 + (return)]
13448 + "USE_RETURN_INSN (TRUE)"
13449 + "retal %0";
13450 + [(set_attr "type" "call")]
13451 + )
13452 +
13453 +(define_insn "return_<mode>reg_cond"
13454 + [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r"))
13455 + (use (reg RETVAL_REGNUM))
13456 + (set (pc)
13457 + (if_then_else (match_operator 1 "avr32_comparison_operator"
13458 + [(cc0) (const_int 0)])
13459 + (return)
13460 + (pc)))]
13461 + "USE_RETURN_INSN (TRUE)"
13462 + "ret%1\t%0";
13463 + [(set_attr "type" "call")])
13464 +
13465 +;;=============================================================================
13466 +;; nop
13467 +;;-----------------------------------------------------------------------------
13468 +;; No-op instruction.
13469 +;;=============================================================================
13470 +(define_insn "nop"
13471 + [(const_int 0)]
13472 + ""
13473 + "nop"
13474 + [(set_attr "length" "2")
13475 + (set_attr "type" "alu")
13476 + (set_attr "cc" "none")])
13477 +
13478 +;;=============================================================================
13479 +;; nonlocal_goto_receiver
13480 +;;-----------------------------------------------------------------------------
13481 +;; For targets with a return stack we must make sure to flush the return stack
13482 +;; since it will be corrupt after a nonlocal goto.
13483 +;;=============================================================================
13484 +(define_expand "nonlocal_goto_receiver"
13485 + [(const_int 0)]
13486 + "TARGET_RETURN_STACK"
13487 + "
13488 + {
13489 + emit_insn ( gen_frs() );
13490 + DONE;
13491 + }
13492 + "
13493 + )
13494 +
13495 +
13496 +;;=============================================================================
13497 +;; builtin_setjmp_receiver
13498 +;;-----------------------------------------------------------------------------
13499 +;; For pic code we need to reload the pic register.
13500 +;; For targets with a return stack we must make sure to flush the return stack
13501 +;; since it will probably be corrupted.
13502 +;;=============================================================================
13503 +(define_expand "builtin_setjmp_receiver"
13504 + [(label_ref (match_operand 0 "" ""))]
13505 + "flag_pic"
13506 + "
13507 + {
13508 + if ( TARGET_RETURN_STACK )
13509 + emit_insn ( gen_frs() );
13510 + avr32_load_pic_register ();
13511 + DONE;
13512 + }
13513 + "
13514 +)
13515 +
13516 +
13517 +;;=============================================================================
13518 +;; indirect_jump
13519 +;;-----------------------------------------------------------------------------
13520 +;; Jump to an address in reg or memory.
13521 +;;=============================================================================
13522 +(define_expand "indirect_jump"
13523 + [(set (pc)
13524 + (match_operand:SI 0 "general_operand" ""))]
13525 + ""
13526 + {
13527 + /* One of the ops has to be in a register. */
13528 + if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS )
13529 + && !avr32_legitimate_pic_operand_p(operands[0]) )
13530 + operands[0] = legitimize_pic_address (operands[0], SImode, 0);
13531 + else if ( flag_pic && avr32_address_operand(operands[0], GET_MODE(operands[0])) )
13532 + /* If we have an address operand then this function uses the pic register. */
13533 + current_function_uses_pic_offset_table = 1;
13534 + })
13535 +
13536 +
13537 +(define_insn "indirect_jump_internal"
13538 + [(set (pc)
13539 + (match_operand:SI 0 "general_operand" "r,m,W"))]
13540 + ""
13541 + {
13542 + switch( which_alternative ){
13543 + case 0:
13544 + return "mov\tpc, %0";
13545 + case 1:
13546 + if ( avr32_const_pool_ref_operand(operands[0], GET_MODE(operands[0])) )
13547 + return "lddpc\tpc, %0";
13548 + else
13549 + return "ld.w\tpc, %0";
13550 + case 2:
13551 + if ( flag_pic )
13552 + return "ld.w\tpc, r6[%0@got]";
13553 + else
13554 + return "lda.w\tpc, %0";
13555 + default:
13556 + abort();
13557 + }
13558 + }
13559 + [(set_attr "length" "2,4,8")
13560 + (set_attr "type" "call,call,call")
13561 + (set_attr "cc" "none,none,clobber")])
13562 +
13563 +
13564 +;;=============================================================================
13565 +;; casesi and tablejump
13566 +;;=============================================================================
13567 +(define_insn "tablejump_add"
13568 + [(set (pc)
13569 + (plus:SI (match_operand:SI 0 "register_operand" "r")
13570 + (mult:SI (match_operand:SI 1 "register_operand" "r")
13571 + (match_operand:SI 2 "immediate_operand" "Ku04" ))))
13572 + (use (label_ref (match_operand 3 "" "")))]
13573 + "flag_pic &&
13574 + ((INTVAL(operands[2]) == 0) || (INTVAL(operands[2]) == 2) ||
13575 + (INTVAL(operands[2]) == 4) || (INTVAL(operands[2]) == 8))"
13576 + "add\tpc, %0, %1 << %p2"
13577 + [(set_attr "length" "4")
13578 + (set_attr "cc" "clobber")])
13579 +
13580 +(define_insn "tablejump_insn"
13581 + [(set (pc) (match_operand:SI 0 "memory_operand" "m"))
13582 + (use (label_ref (match_operand 1 "" "")))]
13583 + "!flag_pic"
13584 + "ld.w\tpc, %0"
13585 + [(set_attr "length" "4")
13586 + (set_attr "type" "call")
13587 + (set_attr "cc" "none")])
13588 +
13589 +(define_expand "casesi"
13590 + [(match_operand:SI 0 "register_operand" "") ; index to jump on
13591 + (match_operand:SI 1 "const_int_operand" "") ; lower bound
13592 + (match_operand:SI 2 "const_int_operand" "") ; total range
13593 + (match_operand:SI 3 "" "") ; table label
13594 + (match_operand:SI 4 "" "")] ; Out of range label
13595 + ""
13596 + "
13597 + {
13598 + rtx reg;
13599 + rtx index = operands[0];
13600 + rtx low_bound = operands[1];
13601 + rtx range = operands[2];
13602 + rtx table_label = operands[3];
13603 + rtx oor_label = operands[4];
13604 +
13605 + if (low_bound != const0_rtx)
13606 + {
13607 + if (!avr32_const_ok_for_constraint_p(INTVAL (low_bound), 'I', \"Is21\")){
13608 + reg = force_reg(SImode, GEN_INT (INTVAL (low_bound)));
13609 + emit_insn (gen_subsi3 (reg, index,
13610 + reg));
13611 + } else {
13612 + reg = gen_reg_rtx (SImode);
13613 + emit_insn (gen_addsi3 (reg, index,
13614 + GEN_INT (-INTVAL (low_bound))));
13615 + }
13616 + index = reg;
13617 + }
13618 +
13619 + if (!avr32_const_ok_for_constraint_p (INTVAL (range), 'K', \"Ks21\"))
13620 + range = force_reg (SImode, range);
13621 +
13622 + emit_cmp_and_jump_insns ( index, range, GTU, NULL_RTX, SImode, 1, oor_label );
13623 + reg = gen_reg_rtx (SImode);
13624 + emit_move_insn ( reg, gen_rtx_LABEL_REF (VOIDmode, table_label));
13625 +
13626 + if ( flag_pic )
13627 + emit_jump_insn ( gen_tablejump_add ( reg, index, GEN_INT(4), table_label));
13628 + else
13629 + emit_jump_insn (
13630 + gen_tablejump_insn ( gen_rtx_MEM ( SImode,
13631 + gen_rtx_PLUS ( SImode,
13632 + reg,
13633 + gen_rtx_MULT ( SImode,
13634 + index,
13635 + GEN_INT(4)))),
13636 + table_label));
13637 + DONE;
13638 + }"
13639 +)
13640 +
13641 +
13642 +
13643 +(define_insn "prefetch"
13644 + [(prefetch (match_operand:SI 0 "register_operand" "r")
13645 + (match_operand 1 "const_int_operand" "")
13646 + (match_operand 2 "const_int_operand" ""))]
13647 + ""
13648 + {
13649 + return "pref\t%0[0]";
13650 + }
13651 +
13652 + [(set_attr "length" "4")
13653 + (set_attr "type" "load")
13654 + (set_attr "cc" "none")])
13655 +
13656 +
13657 +
13658 +;;=============================================================================
13659 +;; prologue
13660 +;;-----------------------------------------------------------------------------
13661 +;; This pattern, if defined, emits RTL for entry to a function. The function
13662 +;; entry i responsible for setting up the stack frame, initializing the frame
13663 +;; pointer register, saving callee saved registers, etc.
13664 +;;=============================================================================
13665 +(define_expand "prologue"
13666 + [(clobber (const_int 0))]
13667 + ""
13668 + "
13669 + avr32_expand_prologue();
13670 + DONE;
13671 + "
13672 + )
13673 +
13674 +;;=============================================================================
13675 +;; eh_return
13676 +;;-----------------------------------------------------------------------------
13677 +;; This pattern, if defined, affects the way __builtin_eh_return, and
13678 +;; thence the call frame exception handling library routines, are
13679 +;; built. It is intended to handle non-trivial actions needed along
13680 +;; the abnormal return path.
13681 +;;
13682 +;; The address of the exception handler to which the function should
13683 +;; return is passed as operand to this pattern. It will normally need
13684 +;; to copied by the pattern to some special register or memory
13685 +;; location. If the pattern needs to determine the location of the
13686 +;; target call frame in order to do so, it may use
13687 +;; EH_RETURN_STACKADJ_RTX, if defined; it will have already been
13688 +;; assigned.
13689 +;;
13690 +;; If this pattern is not defined, the default action will be to
13691 +;; simply copy the return address to EH_RETURN_HANDLER_RTX. Either
13692 +;; that macro or this pattern needs to be defined if call frame
13693 +;; exception handling is to be used.
13694 +
13695 +;; We can't expand this before we know where the link register is stored.
13696 +(define_insn_and_split "eh_return"
13697 + [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
13698 + VUNSPEC_EH_RETURN)
13699 + (clobber (match_scratch:SI 1 "=&r"))]
13700 + ""
13701 + "#"
13702 + "reload_completed"
13703 + [(const_int 0)]
13704 + "
13705 + {
13706 + avr32_set_return_address (operands[0], operands[1]);
13707 + DONE;
13708 + }"
13709 + )
13710 +
13711 +;;=============================================================================
13712 +;; ffssi2
13713 +;;-----------------------------------------------------------------------------
13714 +(define_insn "ffssi2"
13715 + [ (set (match_operand:SI 0 "register_operand" "=r")
13716 + (ffs:SI (match_operand:SI 1 "register_operand" "r"))) ]
13717 + ""
13718 + "mov %0, %1
13719 + brev %0
13720 + clz %0, %0
13721 + sub %0, -1
13722 + cp %0, 33
13723 + moveq %0, 0"
13724 + [(set_attr "length" "18")
13725 + (set_attr "cc" "clobber")]
13726 + )
13727 +
13728 +
13729 +
13730 +;;=============================================================================
13731 +;; swap_h
13732 +;;-----------------------------------------------------------------------------
13733 +(define_insn "*swap_h"
13734 + [ (set (match_operand:SI 0 "register_operand" "=r")
13735 + (ior:SI (ashift:SI (match_dup 0) (const_int 16))
13736 + (lshiftrt:SI (match_dup 0) (const_int 16))))]
13737 + ""
13738 + "swap.h %0"
13739 + [(set_attr "length" "2")]
13740 + )
13741 +
13742 +(define_insn_and_split "bswap_16"
13743 + [ (set (match_operand:HI 0 "avr32_bswap_operand" "=r,RKs13,r")
13744 + (ior:HI (and:HI (lshiftrt:HI (match_operand:HI 1 "avr32_bswap_operand" "r,r,RKs13")
13745 + (const_int 8))
13746 + (const_int 255))
13747 + (ashift:HI (and:HI (match_dup 1)
13748 + (const_int 255))
13749 + (const_int 8))))]
13750 + ""
13751 + {
13752 + switch ( which_alternative ){
13753 + case 0:
13754 + if ( REGNO(operands[0]) == REGNO(operands[1]))
13755 + return "swap.bh\t%0";
13756 + else
13757 + return "mov\t%0, %1\;swap.bh\t%0";
13758 + case 1:
13759 + return "stswp.h\t%0, %1";
13760 + case 2:
13761 + return "ldswp.sh\t%0, %1";
13762 + default:
13763 + abort();
13764 + }
13765 + }
13766 +
13767 + "(reload_completed &&
13768 + REG_P(operands[0]) && REG_P(operands[1])
13769 + && (REGNO(operands[0]) != REGNO(operands[1])))"
13770 + [(set (match_dup 0) (match_dup 1))
13771 + (set (match_dup 0)
13772 + (ior:HI (and:HI (lshiftrt:HI (match_dup 0)
13773 + (const_int 8))
13774 + (const_int 255))
13775 + (ashift:HI (and:HI (match_dup 0)
13776 + (const_int 255))
13777 + (const_int 8))))]
13778 + ""
13779 +
13780 + [(set_attr "length" "4,4,4")
13781 + (set_attr "type" "alu,store,load_rm")]
13782 + )
13783 +
13784 +(define_insn_and_split "bswap_32"
13785 + [ (set (match_operand:SI 0 "avr32_bswap_operand" "=r,RKs14,r")
13786 + (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_operand:SI 1 "avr32_bswap_operand" "=r,r,RKs14")
13787 + (const_int 4278190080))
13788 + (const_int 24))
13789 + (lshiftrt:SI (and:SI (match_dup 1)
13790 + (const_int 16711680))
13791 + (const_int 8)))
13792 + (ior:SI (ashift:SI (and:SI (match_dup 1)
13793 + (const_int 65280))
13794 + (const_int 8))
13795 + (ashift:SI (and:SI (match_dup 1)
13796 + (const_int 255))
13797 + (const_int 24)))))]
13798 + ""
13799 + {
13800 + switch ( which_alternative ){
13801 + case 0:
13802 + if ( REGNO(operands[0]) == REGNO(operands[1]))
13803 + return "swap.b\t%0";
13804 + else
13805 + return "mov\t%0, %1\;swap.b\t%0";
13806 + case 1:
13807 + return "stswp.w\t%0, %1";
13808 + case 2:
13809 + return "ldswp.w\t%0, %1";
13810 + default:
13811 + abort();
13812 + }
13813 + }
13814 + "(reload_completed &&
13815 + REG_P(operands[0]) && REG_P(operands[1])
13816 + && (REGNO(operands[0]) != REGNO(operands[1])))"
13817 + [(set (match_dup 0) (match_dup 1))
13818 + (set (match_dup 0)
13819 + (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_dup 0)
13820 + (const_int 4278190080))
13821 + (const_int 24))
13822 + (lshiftrt:SI (and:SI (match_dup 0)
13823 + (const_int 16711680))
13824 + (const_int 8)))
13825 + (ior:SI (ashift:SI (and:SI (match_dup 0)
13826 + (const_int 65280))
13827 + (const_int 8))
13828 + (ashift:SI (and:SI (match_dup 0)
13829 + (const_int 255))
13830 + (const_int 24)))))]
13831 + ""
13832 +
13833 + [(set_attr "length" "4,4,4")
13834 + (set_attr "type" "alu,store,load_rm")]
13835 + )
13836 +
13837 +
13838 +;;=============================================================================
13839 +;; blockage
13840 +;;-----------------------------------------------------------------------------
13841 +;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13842 +;; all of memory. This blocks insns from being moved across this point.
13843 +
13844 +(define_insn "blockage"
13845 + [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
13846 + ""
13847 + ""
13848 + [(set_attr "length" "0")]
13849 +)
13850 +
13851 +;;=============================================================================
13852 +;; clzsi2
13853 +;;-----------------------------------------------------------------------------
13854 +(define_insn "clzsi2"
13855 + [ (set (match_operand:SI 0 "register_operand" "=r")
13856 + (clz:SI (match_operand:SI 1 "register_operand" "r"))) ]
13857 + ""
13858 + "clz %0, %1"
13859 + [(set_attr "length" "4")
13860 + (set_attr "cc" "set_z")]
13861 + )
13862 +
13863 +;;=============================================================================
13864 +;; ctzsi2
13865 +;;-----------------------------------------------------------------------------
13866 +(define_insn "ctzsi2"
13867 + [ (set (match_operand:SI 0 "register_operand" "=r,r")
13868 + (ctz:SI (match_operand:SI 1 "register_operand" "0,r"))) ]
13869 + ""
13870 + "@
13871 + brev\t%0\;clz\t%0, %0
13872 + mov\t%0, %1\;brev\t%0\;clz\t%0, %0"
13873 + [(set_attr "length" "8")
13874 + (set_attr "cc" "set_z")]
13875 + )
13876 +
13877 +;;=============================================================================
13878 +;; cache instructions
13879 +;;-----------------------------------------------------------------------------
13880 +(define_insn "cache"
13881 + [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r")
13882 + (match_operand:SI 1 "immediate_operand" "Ku05")] VUNSPEC_CACHE)]
13883 + ""
13884 + "cache %0[0], %1"
13885 + [(set_attr "length" "4")]
13886 + )
13887 +
13888 +(define_insn "sync"
13889 + [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku08")] VUNSPEC_SYNC)]
13890 + ""
13891 + "sync %0"
13892 + [(set_attr "length" "4")]
13893 + )
13894 +
13895 +;;=============================================================================
13896 +;; TLB instructions
13897 +;;-----------------------------------------------------------------------------
13898 +(define_insn "tlbr"
13899 + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBR)]
13900 + ""
13901 + "tlbr"
13902 + [(set_attr "length" "2")]
13903 + )
13904 +
13905 +(define_insn "tlbw"
13906 + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBW)]
13907 + ""
13908 + "tlbw"
13909 + [(set_attr "length" "2")]
13910 + )
13911 +
13912 +(define_insn "tlbs"
13913 + [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBS)]
13914 + ""
13915 + "tlbs"
13916 + [(set_attr "length" "2")]
13917 + )
13918 +
13919 +;;=============================================================================
13920 +;; Breakpoint instruction
13921 +;;-----------------------------------------------------------------------------
13922 +(define_insn "breakpoint"
13923 + [ (unspec_volatile [(const_int 0)] VUNSPEC_BREAKPOINT)]
13924 + ""
13925 + "breakpoint"
13926 + [(set_attr "length" "2")]
13927 + )
13928 +
13929 +
13930 +;;=============================================================================
13931 +;; mtsr/mfsr instruction
13932 +;;-----------------------------------------------------------------------------
13933 +(define_insn "mtsr"
13934 + [ (unspec_volatile [(match_operand 0 "immediate_operand" "i")
13935 + (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTSR)]
13936 + ""
13937 + "mtsr\t%0, %1"
13938 + [(set_attr "length" "4")]
13939 + )
13940 +
13941 +(define_insn "mfsr"
13942 + [ (set (match_operand:SI 0 "register_operand" "=r")
13943 + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFSR)) ]
13944 + ""
13945 + "mfsr\t%0, %1"
13946 + [(set_attr "length" "4")]
13947 + )
13948 +
13949 +;;=============================================================================
13950 +;; mtdr/mfdr instruction
13951 +;;-----------------------------------------------------------------------------
13952 +(define_insn "mtdr"
13953 + [ (unspec_volatile [(match_operand 0 "immediate_operand" "i")
13954 + (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTDR)]
13955 + ""
13956 + "mtdr\t%0, %1"
13957 + [(set_attr "length" "4")]
13958 + )
13959 +
13960 +(define_insn "mfdr"
13961 + [ (set (match_operand:SI 0 "register_operand" "=r")
13962 + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFDR)) ]
13963 + ""
13964 + "mfdr\t%0, %1"
13965 + [(set_attr "length" "4")]
13966 + )
13967 +
13968 +;;=============================================================================
13969 +;; musfr
13970 +;;-----------------------------------------------------------------------------
13971 +(define_insn "musfr"
13972 + [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_MUSFR)]
13973 + ""
13974 + "musfr\t%0"
13975 + [(set_attr "length" "2")
13976 + (set_attr "cc" "clobber")]
13977 + )
13978 +
13979 +(define_insn "mustr"
13980 + [ (set (match_operand:SI 0 "register_operand" "=r")
13981 + (unspec_volatile:SI [(const_int 0)] VUNSPEC_MUSTR)) ]
13982 + ""
13983 + "mustr\t%0"
13984 + [(set_attr "length" "2")]
13985 + )
13986 +
13987 +;;=============================================================================
13988 +;; Flush Return Stack instruction
13989 +;;-----------------------------------------------------------------------------
13990 +(define_insn "frs"
13991 + [ (unspec_volatile [(const_int 0)] VUNSPEC_FRS)]
13992 + ""
13993 + "frs"
13994 + [(set_attr "length" "2")
13995 + (set_attr "cc" "none")]
13996 + )
13997 +
13998 +
13999 +;;=============================================================================
14000 +;; Saturation Round Scale instruction
14001 +;;-----------------------------------------------------------------------------
14002 +(define_insn "sats"
14003 + [ (set (match_operand:SI 0 "register_operand" "+r")
14004 + (unspec:SI [(match_dup 0)
14005 + (match_operand 1 "immediate_operand" "Ku05")
14006 + (match_operand 2 "immediate_operand" "Ku05")]
14007 + UNSPEC_SATS)) ]
14008 + "TARGET_DSP"
14009 + "sats\t%0 >> %1, %2"
14010 + [(set_attr "type" "alu_sat")
14011 + (set_attr "length" "4")]
14012 + )
14013 +
14014 +(define_insn "satu"
14015 + [ (set (match_operand:SI 0 "register_operand" "+r")
14016 + (unspec:SI [(match_dup 0)
14017 + (match_operand 1 "immediate_operand" "Ku05")
14018 + (match_operand 2 "immediate_operand" "Ku05")]
14019 + UNSPEC_SATU)) ]
14020 + "TARGET_DSP"
14021 + "satu\t%0 >> %1, %2"
14022 + [(set_attr "type" "alu_sat")
14023 + (set_attr "length" "4")]
14024 + )
14025 +
14026 +(define_insn "satrnds"
14027 + [ (set (match_operand:SI 0 "register_operand" "+r")
14028 + (unspec:SI [(match_dup 0)
14029 + (match_operand 1 "immediate_operand" "Ku05")
14030 + (match_operand 2 "immediate_operand" "Ku05")]
14031 + UNSPEC_SATRNDS)) ]
14032 + "TARGET_DSP"
14033 + "satrnds\t%0 >> %1, %2"
14034 + [(set_attr "type" "alu_sat")
14035 + (set_attr "length" "4")]
14036 + )
14037 +
14038 +(define_insn "satrndu"
14039 + [ (set (match_operand:SI 0 "register_operand" "+r")
14040 + (unspec:SI [(match_dup 0)
14041 + (match_operand 1 "immediate_operand" "Ku05")
14042 + (match_operand 2 "immediate_operand" "Ku05")]
14043 + UNSPEC_SATRNDU)) ]
14044 + "TARGET_DSP"
14045 + "sats\t%0 >> %1, %2"
14046 + [(set_attr "type" "alu_sat")
14047 + (set_attr "length" "4")]
14048 + )
14049 +
14050 +;; Special patterns for dealing with the constant pool
14051 +
14052 +(define_insn "align_4"
14053 + [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
14054 + ""
14055 + {
14056 + assemble_align (32);
14057 + return "";
14058 + }
14059 + [(set_attr "length" "2")]
14060 +)
14061 +
14062 +(define_insn "consttable_start"
14063 + [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_START)]
14064 + ""
14065 + {
14066 + return ".cpool";
14067 + }
14068 + [(set_attr "length" "0")]
14069 + )
14070 +
14071 +(define_insn "consttable_end"
14072 + [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
14073 + ""
14074 + {
14075 + making_const_table = FALSE;
14076 + return "";
14077 + }
14078 + [(set_attr "length" "0")]
14079 +)
14080 +
14081 +
14082 +(define_insn "consttable_4"
14083 + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
14084 + ""
14085 + {
14086 + making_const_table = TRUE;
14087 + switch (GET_MODE_CLASS (GET_MODE (operands[0])))
14088 + {
14089 + case MODE_FLOAT:
14090 + {
14091 + REAL_VALUE_TYPE r;
14092 + char real_string[1024];
14093 + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
14094 + real_to_decimal(real_string, &r, 1024, 0, 1);
14095 + asm_fprintf (asm_out_file, "\t.float\t%s\n", real_string);
14096 + break;
14097 + }
14098 + default:
14099 + assemble_integer (operands[0], 4, 0, 1);
14100 + break;
14101 + }
14102 + return "";
14103 + }
14104 + [(set_attr "length" "4")]
14105 +)
14106 +
14107 +(define_insn "consttable_8"
14108 + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
14109 + ""
14110 + {
14111 + making_const_table = TRUE;
14112 + switch (GET_MODE_CLASS (GET_MODE (operands[0])))
14113 + {
14114 + case MODE_FLOAT:
14115 + {
14116 + REAL_VALUE_TYPE r;
14117 + char real_string[1024];
14118 + REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
14119 + real_to_decimal(real_string, &r, 1024, 0, 1);
14120 + asm_fprintf (asm_out_file, "\t.double\t%s\n", real_string);
14121 + break;
14122 + }
14123 + default:
14124 + assemble_integer(operands[0], 8, 0, 1);
14125 + break;
14126 + }
14127 + return "";
14128 + }
14129 + [(set_attr "length" "8")]
14130 +)
14131 +
14132 +(define_insn "consttable_16"
14133 + [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
14134 + ""
14135 + {
14136 + making_const_table = TRUE;
14137 + assemble_integer(operands[0], 16, 0, 1);
14138 + return "";
14139 + }
14140 + [(set_attr "length" "16")]
14141 +)
14142 +
14143 +;;=============================================================================
14144 +;; coprocessor instructions
14145 +;;-----------------------------------------------------------------------------
14146 +(define_insn "cop"
14147 + [ (unspec_volatile [(match_operand 0 "immediate_operand" "Ku03")
14148 + (match_operand 1 "immediate_operand" "Ku04")
14149 + (match_operand 2 "immediate_operand" "Ku04")
14150 + (match_operand 3 "immediate_operand" "Ku04")
14151 + (match_operand 4 "immediate_operand" "Ku07")] VUNSPEC_COP)]
14152 + ""
14153 + "cop\tcp%0, cr%1, cr%2, cr%3, %4"
14154 + [(set_attr "length" "4")]
14155 + )
14156 +
14157 +(define_insn "mvcrsi"
14158 + [ (set (match_operand:SI 0 "avr32_cop_move_operand" "=r,<,Z")
14159 + (unspec_volatile:SI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03")
14160 + (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")]
14161 + VUNSPEC_MVCR)) ]
14162 + ""
14163 + "@
14164 + mvcr.w\tcp%1, %0, cr%2
14165 + stcm.w\tcp%1, %0, cr%2
14166 + stc.w\tcp%1, %0, cr%2"
14167 + [(set_attr "length" "4")]
14168 + )
14169 +
14170 +(define_insn "mvcrdi"
14171 + [ (set (match_operand:DI 0 "avr32_cop_move_operand" "=r,<,Z")
14172 + (unspec_volatile:DI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03")
14173 + (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")]
14174 + VUNSPEC_MVCR)) ]
14175 + ""
14176 + "@
14177 + mvcr.d\tcp%1, %0, cr%2
14178 + stcm.d\tcp%1, %0, cr%2-cr%i2
14179 + stc.d\tcp%1, %0, cr%2"
14180 + [(set_attr "length" "4")]
14181 + )
14182 +
14183 +(define_insn "mvrcsi"
14184 + [ (unspec_volatile:SI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03")
14185 + (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04")
14186 + (match_operand:SI 2 "avr32_cop_move_operand" "r,>,Z")]
14187 + VUNSPEC_MVRC)]
14188 + ""
14189 + {
14190 + switch (which_alternative){
14191 + case 0:
14192 + return "mvrc.w\tcp%0, cr%1, %2";
14193 + case 1:
14194 + return "ldcm.w\tcp%0, %2, cr%1";
14195 + case 2:
14196 + return "ldc.w\tcp%0, cr%1, %2";
14197 + default:
14198 + abort();
14199 + }
14200 + }
14201 + [(set_attr "length" "4")]
14202 + )
14203 +
14204 +(define_insn "mvrcdi"
14205 + [ (unspec_volatile:DI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03")
14206 + (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04")
14207 + (match_operand:DI 2 "avr32_cop_move_operand" "r,>,Z")]
14208 + VUNSPEC_MVRC)]
14209 + ""
14210 + {
14211 + switch (which_alternative){
14212 + case 0:
14213 + return "mvrc.d\tcp%0, cr%1, %2";
14214 + case 1:
14215 + return "ldcm.d\tcp%0, %2, cr%1-cr%i1";
14216 + case 2:
14217 + return "ldc.d\tcp%0, cr%1, %2";
14218 + default:
14219 + abort();
14220 + }
14221 + }
14222 + [(set_attr "length" "4")]
14223 + )
14224 +
14225 +;;=============================================================================
14226 +;; epilogue
14227 +;;-----------------------------------------------------------------------------
14228 +;; This pattern emits RTL for exit from a function. The function exit is
14229 +;; responsible for deallocating the stack frame, restoring callee saved
14230 +;; registers and emitting the return instruction.
14231 +;; ToDo: using TARGET_ASM_FUNCTION_PROLOGUE instead.
14232 +;;=============================================================================
14233 +(define_expand "epilogue"
14234 + [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
14235 + ""
14236 + "
14237 + if (USE_RETURN_INSN (FALSE)){
14238 + emit_jump_insn (gen_return ());
14239 + DONE;
14240 + }
14241 + emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
14242 + gen_rtvec (1,
14243 + gen_rtx_RETURN (VOIDmode)),
14244 + VUNSPEC_EPILOGUE));
14245 + DONE;
14246 + "
14247 + )
14248 +
14249 +(define_insn "*epilogue_insns"
14250 + [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
14251 + ""
14252 + {
14253 + avr32_output_return_instruction (FALSE, FALSE, NULL, NULL);
14254 + return "";
14255 + }
14256 + ; Length is absolute worst case
14257 + [(set_attr "type" "branch")
14258 + (set_attr "length" "12")]
14259 + )
14260 +
14261 +(define_insn "*epilogue_insns_ret_imm"
14262 + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
14263 + (use (reg RETVAL_REGNUM))
14264 + (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
14265 + "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
14266 + {
14267 + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]);
14268 + return "";
14269 + }
14270 + ; Length is absolute worst case
14271 + [(set_attr "type" "branch")
14272 + (set_attr "length" "12")]
14273 + )
14274 +
14275 +(define_insn "sibcall_epilogue"
14276 + [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)]
14277 + ""
14278 + {
14279 + avr32_output_return_instruction (FALSE, FALSE, NULL, NULL);
14280 + return "";
14281 + }
14282 +;; Length is absolute worst case
14283 + [(set_attr "type" "branch")
14284 + (set_attr "length" "12")]
14285 + )
14286 +
14287 +(define_insn "*sibcall_epilogue_insns_ret_imm"
14288 + [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
14289 + (use (reg RETVAL_REGNUM))
14290 + (unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)])]
14291 + "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
14292 + {
14293 + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]);
14294 + return "";
14295 + }
14296 + ; Length is absolute worst case
14297 + [(set_attr "type" "branch")
14298 + (set_attr "length" "12")]
14299 + )
14300 +
14301 +(define_insn "ldxi"
14302 + [(set (match_operand:SI 0 "register_operand" "=r")
14303 + (mem:SI (plus:SI
14304 + (match_operand:SI 1 "register_operand" "r")
14305 + (mult:SI (zero_extract:SI (match_operand:SI 2 "register_operand" "r")
14306 + (const_int 8)
14307 + (match_operand:SI 3 "immediate_operand" "Ku05"))
14308 + (const_int 4)))))]
14309 + "(INTVAL(operands[3]) == 24 || INTVAL(operands[3]) == 16 || INTVAL(operands[3]) == 8
14310 + || INTVAL(operands[3]) == 0)"
14311 + {
14312 + switch ( INTVAL(operands[3]) ){
14313 + case 0:
14314 + return "ld.w %0, %1[%2:b << 2]";
14315 + case 8:
14316 + return "ld.w %0, %1[%2:l << 2]";
14317 + case 16:
14318 + return "ld.w %0, %1[%2:u << 2]";
14319 + case 24:
14320 + return "ld.w %0, %1[%2:t << 2]";
14321 + default:
14322 + internal_error("illegal operand for ldxi");
14323 + }
14324 + }
14325 + [(set_attr "type" "load")
14326 + (set_attr "length" "4")
14327 + (set_attr "cc" "none")])
14328 +
14329 +
14330 +
14331 +
14332 +
14333 +
14334 +;;=============================================================================
14335 +;; Peephole optimizing
14336 +;;-----------------------------------------------------------------------------
14337 +;; Changing
14338 +;; sub r8, r7, 8
14339 +;; st.w r8[0x0], r12
14340 +;; to
14341 +;; sub r8, r7, 8
14342 +;; st.w r7[-0x8], r12
14343 +;;=============================================================================
14344 +; (set (reg:SI 9 r8)
14345 +; (plus:SI (reg/f:SI 6 r7)
14346 +; (const_int ...)))
14347 +; (set (mem:SI (reg:SI 9 r8))
14348 +; (reg:SI 12 r12))
14349 +(define_peephole2
14350 + [(set (match_operand:SI 0 "register_operand" "")
14351 + (plus:SI (match_operand:SI 1 "register_operand" "")
14352 + (match_operand:SI 2 "immediate_operand" "")))
14353 + (set (mem:SI (match_dup 0))
14354 + (match_operand:SI 3 "register_operand" ""))]
14355 + "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")"
14356 + [(set (match_dup 0)
14357 + (plus:SI (match_dup 1)
14358 + (match_dup 2)))
14359 + (set (mem:SI (plus:SI (match_dup 1)
14360 + (match_dup 2)))
14361 + (match_dup 3))]
14362 + "")
14363 +
14364 +;;=============================================================================
14365 +;; Peephole optimizing
14366 +;;-----------------------------------------------------------------------------
14367 +;; Changing
14368 +;; sub r6, r7, 4
14369 +;; ld.w r6, r6[0x0]
14370 +;; to
14371 +;; sub r6, r7, 4
14372 +;; ld.w r6, r7[-0x4]
14373 +;;=============================================================================
14374 +; (set (reg:SI 7 r6)
14375 +; (plus:SI (reg/f:SI 6 r7)
14376 +; (const_int -4 [0xfffffffc])))
14377 +; (set (reg:SI 7 r6)
14378 +; (mem:SI (reg:SI 7 r6)))
14379 +(define_peephole2
14380 + [(set (match_operand:SI 0 "register_operand" "")
14381 + (plus:SI (match_operand:SI 1 "register_operand" "")
14382 + (match_operand:SI 2 "immediate_operand" "")))
14383 + (set (match_operand:SI 3 "register_operand" "")
14384 + (mem:SI (match_dup 0)))]
14385 + "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")"
14386 + [(set (match_dup 0)
14387 + (plus:SI (match_dup 1)
14388 + (match_dup 2)))
14389 + (set (match_dup 3)
14390 + (mem:SI (plus:SI (match_dup 1)
14391 + (match_dup 2))))]
14392 + "")
14393 +
14394 +;;=============================================================================
14395 +;; Peephole optimizing
14396 +;;-----------------------------------------------------------------------------
14397 +;; Changing
14398 +;; ld.sb r0, r7[-0x6]
14399 +;; cashs.b r0
14400 +;; to
14401 +;; ld.sb r0, r7[-0x6]
14402 +;;=============================================================================
14403 +(define_peephole2
14404 + [(set (match_operand:QI 0 "register_operand" "")
14405 + (match_operand:QI 1 "load_sb_memory_operand" ""))
14406 + (set (match_operand:SI 2 "register_operand" "")
14407 + (sign_extend:SI (match_dup 0)))]
14408 + "(REGNO(operands[0]) == REGNO(operands[2]) || peep2_reg_dead_p(2, operands[0]))"
14409 + [(set (match_dup 2)
14410 + (sign_extend:SI (match_dup 1)))]
14411 + "")
14412 +
14413 +;;=============================================================================
14414 +;; Peephole optimizing
14415 +;;-----------------------------------------------------------------------------
14416 +;; Changing
14417 +;; ld.ub r0, r7[-0x6]
14418 +;; cashu.b r0
14419 +;; to
14420 +;; ld.ub r0, r7[-0x6]
14421 +;;=============================================================================
14422 +(define_peephole2
14423 + [(set (match_operand:QI 0 "register_operand" "")
14424 + (match_operand:QI 1 "memory_operand" ""))
14425 + (set (match_operand:SI 2 "register_operand" "")
14426 + (zero_extend:SI (match_dup 0)))]
14427 + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
14428 + [(set (match_dup 2)
14429 + (zero_extend:SI (match_dup 1)))]
14430 + "")
14431 +
14432 +;;=============================================================================
14433 +;; Peephole optimizing
14434 +;;-----------------------------------------------------------------------------
14435 +;; Changing
14436 +;; ld.sh r0, r7[-0x6]
14437 +;; casts.h r0
14438 +;; to
14439 +;; ld.sh r0, r7[-0x6]
14440 +;;=============================================================================
14441 +(define_peephole2
14442 + [(set (match_operand:HI 0 "register_operand" "")
14443 + (match_operand:HI 1 "memory_operand" ""))
14444 + (set (match_operand:SI 2 "register_operand" "")
14445 + (sign_extend:SI (match_dup 0)))]
14446 + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
14447 + [(set (match_dup 2)
14448 + (sign_extend:SI (match_dup 1)))]
14449 + "")
14450 +
14451 +;;=============================================================================
14452 +;; Peephole optimizing
14453 +;;-----------------------------------------------------------------------------
14454 +;; Changing
14455 +;; ld.uh r0, r7[-0x6]
14456 +;; castu.h r0
14457 +;; to
14458 +;; ld.uh r0, r7[-0x6]
14459 +;;=============================================================================
14460 +(define_peephole2
14461 + [(set (match_operand:HI 0 "register_operand" "")
14462 + (match_operand:HI 1 "memory_operand" ""))
14463 + (set (match_operand:SI 2 "register_operand" "")
14464 + (zero_extend:SI (match_dup 0)))]
14465 + "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
14466 + [(set (match_dup 2)
14467 + (zero_extend:SI (match_dup 1)))]
14468 + "")
14469 +
14470 +;;=============================================================================
14471 +;; Peephole optimizing
14472 +;;-----------------------------------------------------------------------------
14473 +;; Changing
14474 +;; mul rd, rx, ry
14475 +;; add rd2, rd
14476 +;; to
14477 +;; mac rd2, rx, ry
14478 +;;=============================================================================
14479 +(define_peephole2
14480 + [(set (match_operand:SI 0 "register_operand" "")
14481 + (mult:SI (match_operand:SI 1 "register_operand" "")
14482 + (match_operand:SI 2 "register_operand" "")))
14483 + (set (match_operand:SI 3 "register_operand" "")
14484 + (plus:SI (match_dup 3)
14485 + (match_dup 0)))]
14486 + "peep2_reg_dead_p(2, operands[0])"
14487 + [(set (match_dup 3)
14488 + (plus:SI (mult:SI (match_dup 1)
14489 + (match_dup 2))
14490 + (match_dup 3)))]
14491 + "")
14492 +
14493 +
14494 +
14495 +;;=============================================================================
14496 +;; Peephole optimizing
14497 +;;-----------------------------------------------------------------------------
14498 +;; Changing
14499 +;; bfextu rd, rs, k5, 1 or and(h/l) rd, one_bit_set_mask
14500 +;; to
14501 +;; bld rs, k5
14502 +;;
14503 +;; If rd is dead after the operation.
14504 +;;=============================================================================
14505 +(define_peephole2
14506 + [ (set (match_operand:SI 0 "register_operand" "")
14507 + (zero_extract:SI (match_operand:SI 1 "register_operand" "")
14508 + (const_int 1)
14509 + (match_operand:SI 2 "immediate_operand" "")))
14510 + (set (cc0)
14511 + (match_dup 0))]
14512 + "peep2_reg_dead_p(2, operands[0])"
14513 + [(set (cc0)
14514 + (and:SI (match_dup 1)
14515 + (match_dup 2)))]
14516 + "operands[2] = GEN_INT(1 << INTVAL(operands[2]));")
14517 +
14518 +(define_peephole2
14519 + [ (set (match_operand:SI 0 "register_operand" "")
14520 + (and:SI (match_operand:SI 1 "register_operand" "")
14521 + (match_operand:SI 2 "one_bit_set_operand" "")))
14522 + (set (cc0)
14523 + (match_dup 0))]
14524 + "peep2_reg_dead_p(2, operands[0])"
14525 + [(set (cc0)
14526 + (and:SI (match_dup 1)
14527 + (match_dup 2)))]
14528 + "")
14529 +
14530 +;;=============================================================================
14531 +;; Peephole optimizing
14532 +;;-----------------------------------------------------------------------------
14533 +;; Load with extracted index: ld.w Rd, Rb[Ri:{t/u/b/l} << 2]
14534 +;;
14535 +;;=============================================================================
14536 +
14537 +
14538 +(define_peephole
14539 + [(set (match_operand:SI 0 "register_operand" "")
14540 + (zero_extract:SI (match_operand:SI 1 "register_operand" "")
14541 + (const_int 8)
14542 + (match_operand:SI 2 "avr32_extract_shift_operand" "")))
14543 + (set (match_operand:SI 3 "register_operand" "")
14544 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14545 + (match_operand:SI 4 "register_operand" ""))))]
14546 +
14547 + "(dead_or_set_p(insn, operands[0]))"
14548 + {
14549 + switch ( INTVAL(operands[2]) ){
14550 + case 0:
14551 + return "ld.w %3, %4[%1:b << 2]";
14552 + case 8:
14553 + return "ld.w %3, %4[%1:l << 2]";
14554 + case 16:
14555 + return "ld.w %3, %4[%1:u << 2]";
14556 + case 24:
14557 + return "ld.w %3, %4[%1:t << 2]";
14558 + default:
14559 + internal_error("illegal operand for ldxi");
14560 + }
14561 + }
14562 + [(set_attr "type" "load")
14563 + (set_attr "length" "4")
14564 + (set_attr "cc" "clobber")]
14565 + )
14566 +
14567 +
14568 +
14569 +(define_peephole
14570 + [(set (match_operand:SI 0 "register_operand" "")
14571 + (and:SI (match_operand:SI 1 "register_operand" "") (const_int 255)))
14572 + (set (match_operand:SI 2 "register_operand" "")
14573 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14574 + (match_operand:SI 3 "register_operand" ""))))]
14575 +
14576 + "(dead_or_set_p(insn, operands[0]))"
14577 +
14578 + "ld.w %2, %3[%1:b << 2]"
14579 + [(set_attr "type" "load")
14580 + (set_attr "length" "4")
14581 + (set_attr "cc" "clobber")]
14582 + )
14583 +
14584 +
14585 +(define_peephole2
14586 + [(set (match_operand:SI 0 "register_operand" "")
14587 + (zero_extract:SI (match_operand:SI 1 "register_operand" "")
14588 + (const_int 8)
14589 + (match_operand:SI 2 "avr32_extract_shift_operand" "")))
14590 + (set (match_operand:SI 3 "register_operand" "")
14591 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14592 + (match_operand:SI 4 "register_operand" ""))))]
14593 +
14594 + "(peep2_reg_dead_p(2, operands[0]))
14595 + || (REGNO(operands[0]) == REGNO(operands[3]))"
14596 + [(set (match_dup 3)
14597 + (mem:SI (plus:SI
14598 + (match_dup 4)
14599 + (mult:SI (zero_extract:SI (match_dup 1)
14600 + (const_int 8)
14601 + (match_dup 2))
14602 + (const_int 4)))))]
14603 + )
14604 +
14605 +(define_peephole2
14606 + [(set (match_operand:SI 0 "register_operand" "")
14607 + (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
14608 + (set (match_operand:SI 2 "register_operand" "")
14609 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14610 + (match_operand:SI 3 "register_operand" ""))))]
14611 +
14612 + "(peep2_reg_dead_p(2, operands[0]))
14613 + || (REGNO(operands[0]) == REGNO(operands[2]))"
14614 + [(set (match_dup 2)
14615 + (mem:SI (plus:SI
14616 + (match_dup 3)
14617 + (mult:SI (zero_extract:SI (match_dup 1)
14618 + (const_int 8)
14619 + (const_int 0))
14620 + (const_int 4)))))]
14621 + "operands[1] = gen_rtx_REG(SImode, REGNO(operands[1]));"
14622 + )
14623 +
14624 +
14625 +(define_peephole2
14626 + [(set (match_operand:SI 0 "register_operand" "")
14627 + (and:SI (match_operand:SI 1 "register_operand" "")
14628 + (const_int 255)))
14629 + (set (match_operand:SI 2 "register_operand" "")
14630 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14631 + (match_operand:SI 3 "register_operand" ""))))]
14632 +
14633 + "(peep2_reg_dead_p(2, operands[0]))
14634 + || (REGNO(operands[0]) == REGNO(operands[2]))"
14635 + [(set (match_dup 2)
14636 + (mem:SI (plus:SI
14637 + (match_dup 3)
14638 + (mult:SI (zero_extract:SI (match_dup 1)
14639 + (const_int 8)
14640 + (const_int 0))
14641 + (const_int 4)))))]
14642 + ""
14643 + )
14644 +
14645 +
14646 +
14647 +(define_peephole2
14648 + [(set (match_operand:SI 0 "register_operand" "")
14649 + (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
14650 + (const_int 24)))
14651 + (set (match_operand:SI 2 "register_operand" "")
14652 + (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
14653 + (match_operand:SI 3 "register_operand" ""))))]
14654 +
14655 + "(peep2_reg_dead_p(2, operands[0]))
14656 + || (REGNO(operands[0]) == REGNO(operands[2]))"
14657 + [(set (match_dup 2)
14658 + (mem:SI (plus:SI
14659 + (match_dup 3)
14660 + (mult:SI (zero_extract:SI (match_dup 1)
14661 + (const_int 8)
14662 + (const_int 24))
14663 + (const_int 4)))))]
14664 + ""
14665 + )
14666 +
14667 +
14668 +;;************************************************
14669 +;; ANDN
14670 +;;
14671 +;;************************************************
14672 +
14673 +
14674 +(define_peephole2
14675 + [(set (match_operand:SI 0 "register_operand" "")
14676 + (not:SI (match_operand:SI 1 "register_operand" "")))
14677 + (set (match_operand:SI 2 "register_operand" "")
14678 + (and:SI (match_dup 2)
14679 + (match_dup 0)))]
14680 + "peep2_reg_dead_p(2, operands[0])"
14681 +
14682 + [(set (match_dup 2)
14683 + (and:SI (match_dup 2)
14684 + (not:SI (match_dup 1))
14685 + ))]
14686 + ""
14687 +)
14688 +
14689 +(define_peephole2
14690 + [(set (match_operand:SI 0 "register_operand" "")
14691 + (not:SI (match_operand:SI 1 "register_operand" "")))
14692 + (set (match_operand:SI 2 "register_operand" "")
14693 + (and:SI (match_dup 0)
14694 + (match_dup 2)
14695 + ))]
14696 + "peep2_reg_dead_p(2, operands[0])"
14697 +
14698 + [(set (match_dup 2)
14699 + (and:SI (match_dup 2)
14700 + (not:SI (match_dup 1))
14701 + ))]
14702 +
14703 + ""
14704 +)
14705 +
14706 +
14707 +;;=================================================================
14708 +;; Addabs peephole
14709 +;;=================================================================
14710 +
14711 +(define_peephole
14712 + [(set (match_operand:SI 2 "register_operand" "=r")
14713 + (abs:SI (match_operand:SI 1 "register_operand" "r")))
14714 + (set (match_operand:SI 0 "register_operand" "=r")
14715 + (plus:SI (match_operand:SI 3 "register_operand" "r")
14716 + (match_dup 2)))]
14717 + "dead_or_set_p(insn, operands[2])"
14718 + "addabs %0, %3, %1"
14719 + [(set_attr "length" "4")
14720 + (set_attr "cc" "set_z")])
14721 +
14722 +(define_peephole
14723 + [(set (match_operand:SI 2 "register_operand" "=r")
14724 + (abs:SI (match_operand:SI 1 "register_operand" "r")))
14725 + (set (match_operand:SI 0 "register_operand" "=r")
14726 + (plus:SI (match_dup 2)
14727 + (match_operand:SI 3 "register_operand" "r")))]
14728 + "dead_or_set_p(insn, operands[2])"
14729 + "addabs %0, %3, %1"
14730 + [(set_attr "length" "4")
14731 + (set_attr "cc" "set_z")])
14732 +
14733 +
14734 +;;=================================================================
14735 +;; Detect roundings
14736 +;;=================================================================
14737 +
14738 +(define_insn "*round"
14739 + [(set (match_operand:SI 0 "register_operand" "=r")
14740 + (ashiftrt:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
14741 + (match_operand:SI 2 "immediate_operand" "i"))
14742 + (match_operand:SI 3 "immediate_operand" "i")))]
14743 + "avr32_rnd_operands(operands[2], operands[3])"
14744 +
14745 + "satrnds %0 >> %3, 31"
14746 +
14747 + [(set_attr "type" "alu_sat")
14748 + (set_attr "length" "4")]
14749 +
14750 + )
14751 +
14752 +
14753 +(define_peephole2
14754 + [(set (match_operand:SI 0 "register_operand" "")
14755 + (plus:SI (match_dup 0)
14756 + (match_operand:SI 1 "immediate_operand" "")))
14757 + (set (match_dup 0)
14758 + (ashiftrt:SI (match_dup 0)
14759 + (match_operand:SI 2 "immediate_operand" "")))]
14760 + "avr32_rnd_operands(operands[1], operands[2])"
14761 +
14762 + [(set (match_dup 0)
14763 + (ashiftrt:SI (plus:SI (match_dup 0)
14764 + (match_dup 1))
14765 + (match_dup 2)))]
14766 + )
14767 +
14768 +(define_peephole
14769 + [(set (match_operand:SI 0 "register_operand" "r")
14770 + (plus:SI (match_dup 0)
14771 + (match_operand:SI 1 "immediate_operand" "i")))
14772 + (set (match_dup 0)
14773 + (ashiftrt:SI (match_dup 0)
14774 + (match_operand:SI 2 "immediate_operand" "i")))]
14775 + "avr32_rnd_operands(operands[1], operands[2])"
14776 +
14777 + "satrnds %0 >> %2, 31"
14778 +
14779 + [(set_attr "type" "alu_sat")
14780 + (set_attr "length" "4")
14781 + (set_attr "cc" "clobber")]
14782 +
14783 + )
14784 +
14785 +
14786 +;;=================================================================
14787 +;; mcall
14788 +;;=================================================================
14789 +(define_peephole
14790 + [(set (match_operand:SI 0 "register_operand" "")
14791 + (match_operand 1 "avr32_const_pool_ref_operand" ""))
14792 + (parallel [(call (mem:SI (match_dup 0))
14793 + (match_operand 2 "" ""))
14794 + (clobber (reg:SI LR_REGNUM))])]
14795 + "dead_or_set_p(insn, operands[0])"
14796 + "mcall %1"
14797 + [(set_attr "type" "call")
14798 + (set_attr "length" "4")
14799 + (set_attr "cc" "clobber")]
14800 +)
14801 +
14802 +(define_peephole
14803 + [(set (match_operand:SI 2 "register_operand" "")
14804 + (match_operand 1 "avr32_const_pool_ref_operand" ""))
14805 + (parallel [(set (match_operand 0 "register_operand" "")
14806 + (call (mem:SI (match_dup 2))
14807 + (match_operand 3 "" "")))
14808 + (clobber (reg:SI LR_REGNUM))])]
14809 + "dead_or_set_p(insn, operands[2])"
14810 + "mcall %1"
14811 + [(set_attr "type" "call")
14812 + (set_attr "length" "4")
14813 + (set_attr "cc" "call_set")]
14814 +)
14815 +
14816 +
14817 +(define_peephole2
14818 + [(set (match_operand:SI 0 "register_operand" "")
14819 + (match_operand 1 "avr32_const_pool_ref_operand" ""))
14820 + (parallel [(call (mem:SI (match_dup 0))
14821 + (match_operand 2 "" ""))
14822 + (clobber (reg:SI LR_REGNUM))])]
14823 + "peep2_reg_dead_p(2, operands[0])"
14824 + [(parallel [(call (mem:SI (match_dup 1))
14825 + (match_dup 2))
14826 + (clobber (reg:SI LR_REGNUM))])]
14827 + ""
14828 +)
14829 +
14830 +(define_peephole2
14831 + [(set (match_operand:SI 0 "register_operand" "")
14832 + (match_operand 1 "avr32_const_pool_ref_operand" ""))
14833 + (parallel [(set (match_operand 2 "register_operand" "")
14834 + (call (mem:SI (match_dup 0))
14835 + (match_operand 3 "" "")))
14836 + (clobber (reg:SI LR_REGNUM))])]
14837 + "(peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[2]) == REGNO(operands[0])))"
14838 + [(parallel [(set (match_dup 2)
14839 + (call (mem:SI (match_dup 1))
14840 + (match_dup 3)))
14841 + (clobber (reg:SI LR_REGNUM))])]
14842 + ""
14843 +)
14844 +
14845 +;;=================================================================
14846 +;; Returning a value
14847 +;;=================================================================
14848 +
14849 +
14850 +(define_peephole
14851 + [(set (match_operand 0 "register_operand" "")
14852 + (match_operand 1 "register_operand" ""))
14853 + (return)]
14854 + "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM)
14855 + && (REGNO(operands[1]) != LR_REGNUM)
14856 + && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS)"
14857 + "retal %1"
14858 + [(set_attr "type" "call")
14859 + (set_attr "length" "2")]
14860 + )
14861 +
14862 +
14863 +(define_peephole
14864 + [(set (match_operand 0 "register_operand" "r")
14865 + (match_operand 1 "immediate_operand" "i"))
14866 + (return)]
14867 + "(USE_RETURN_INSN (FALSE) && (REGNO(operands[0]) == RETVAL_REGNUM) &&
14868 + ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1)))"
14869 + {
14870 + avr32_output_return_instruction (TRUE, FALSE, NULL, operands[1]);
14871 + return "";
14872 + }
14873 + [(set_attr "type" "call")
14874 + (set_attr "length" "4")]
14875 + )
14876 +
14877 +(define_peephole
14878 + [(set (match_operand 0 "register_operand" "r")
14879 + (match_operand 1 "immediate_operand" "i"))
14880 + (unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
14881 + "(REGNO(operands[0]) == RETVAL_REGNUM) &&
14882 + ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1))"
14883 + {
14884 + avr32_output_return_instruction (FALSE, FALSE, NULL, operands[1]);
14885 + return "";
14886 + }
14887 + ; Length is absolute worst case
14888 + [(set_attr "type" "branch")
14889 + (set_attr "length" "12")]
14890 + )
14891 +
14892 +(define_peephole
14893 + [(set (match_operand 0 "register_operand" "=r")
14894 + (if_then_else (match_operator 1 "avr32_comparison_operator"
14895 + [(match_operand 4 "register_operand" "r")
14896 + (match_operand 5 "register_immediate_operand" "rKs21")])
14897 + (match_operand 2 "avr32_cond_register_immediate_operand" "rKs08")
14898 + (match_operand 3 "avr32_cond_register_immediate_operand" "rKs08")))
14899 + (return)]
14900 + "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM)"
14901 + {
14902 + operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
14903 +
14904 + if ( GET_CODE(operands[2]) == REG
14905 + && GET_CODE(operands[3]) == REG
14906 + && REGNO(operands[2]) != LR_REGNUM
14907 + && REGNO(operands[3]) != LR_REGNUM ){
14908 + return "ret%1 %2\;ret%i1 %3";
14909 + } else if ( GET_CODE(operands[2]) == REG
14910 + && GET_CODE(operands[3]) == CONST_INT ){
14911 + if ( INTVAL(operands[3]) == -1
14912 + || INTVAL(operands[3]) == 0
14913 + || INTVAL(operands[3]) == 1 ){
14914 + return "ret%1 %2\;ret%i1 %d3";
14915 + } else {
14916 + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12";
14917 + }
14918 + } else if ( GET_CODE(operands[2]) == CONST_INT
14919 + && GET_CODE(operands[3]) == REG ){
14920 + if ( INTVAL(operands[2]) == -1
14921 + || INTVAL(operands[2]) == 0
14922 + || INTVAL(operands[2]) == 1 ){
14923 + return "ret%1 %d2\;ret%i1 %3";
14924 + } else {
14925 + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12";
14926 + }
14927 + } else {
14928 + if ( (INTVAL(operands[2]) == -1
14929 + || INTVAL(operands[2]) == 0
14930 + || INTVAL(operands[2]) == 1 )
14931 + && (INTVAL(operands[3]) == -1
14932 + || INTVAL(operands[3]) == 0
14933 + || INTVAL(operands[3]) == 1 )){
14934 + return "ret%1 %d2\;ret%i1 %d3";
14935 + } else {
14936 + return "mov%1 r12, %2\;mov%i1 r12, %3\;retal r12";
14937 + }
14938 + }
14939 + }
14940 +
14941 + [(set_attr "length" "10")
14942 + (set_attr "cc" "none")
14943 + (set_attr "type" "call")])
14944 +
14945 +
14946 +;;=================================================================
14947 +;; mulnhh.w
14948 +;;=================================================================
14949 +
14950 +(define_peephole2
14951 + [(set (match_operand:HI 0 "register_operand" "")
14952 + (neg:HI (match_operand:HI 1 "register_operand" "")))
14953 + (set (match_operand:SI 2 "register_operand" "")
14954 + (mult:SI
14955 + (sign_extend:SI (match_dup 0))
14956 + (sign_extend:SI (match_operand:HI 3 "register_operand" ""))))]
14957 + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))"
14958 + [ (set (match_dup 2)
14959 + (mult:SI
14960 + (sign_extend:SI (neg:HI (match_dup 1)))
14961 + (sign_extend:SI (match_dup 3))))]
14962 + ""
14963 + )
14964 +
14965 +(define_peephole2
14966 + [(set (match_operand:HI 0 "register_operand" "")
14967 + (neg:HI (match_operand:HI 1 "register_operand" "")))
14968 + (set (match_operand:SI 2 "register_operand" "")
14969 + (mult:SI
14970 + (sign_extend:SI (match_operand:HI 3 "register_operand" ""))
14971 + (sign_extend:SI (match_dup 0))))]
14972 + "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))"
14973 + [ (set (match_dup 2)
14974 + (mult:SI
14975 + (sign_extend:SI (neg:HI (match_dup 1)))
14976 + (sign_extend:SI (match_dup 3))))]
14977 + ""
14978 + )
14979 +
14980 +
14981 +
14982 +;;=================================================================
14983 +;; Vector set and extract operations
14984 +;;=================================================================
14985 +(define_insn "vec_setv2hi_hi"
14986 + [(set (match_operand:V2HI 0 "register_operand" "=r")
14987 + (vec_merge:V2HI
14988 + (match_dup 0)
14989 + (vec_duplicate:V2HI
14990 + (match_operand:HI 1 "register_operand" "r"))
14991 + (const_int 1)))]
14992 + ""
14993 + "bfins\t%0, %1, 16, 16"
14994 + [(set_attr "type" "alu")
14995 + (set_attr "length" "4")
14996 + (set_attr "cc" "clobber")])
14997 +
14998 +(define_insn "vec_setv2hi_lo"
14999 + [(set (match_operand:V2HI 0 "register_operand" "+r")
15000 + (vec_merge:V2HI
15001 + (match_dup 0)
15002 + (vec_duplicate:V2HI
15003 + (match_operand:HI 1 "register_operand" "r"))
15004 + (const_int 2)))]
15005 + ""
15006 + "bfins\t%0, %1, 0, 16"
15007 + [(set_attr "type" "alu")
15008 + (set_attr "length" "4")
15009 + (set_attr "cc" "clobber")])
15010 +
15011 +(define_expand "vec_setv2hi"
15012 + [(set (match_operand:V2HI 0 "register_operand" "")
15013 + (vec_merge:V2HI
15014 + (match_dup 0)
15015 + (vec_duplicate:V2HI
15016 + (match_operand:HI 1 "register_operand" ""))
15017 + (match_operand 2 "immediate_operand" "")))]
15018 + ""
15019 + { operands[2] = GEN_INT(INTVAL(operands[2]) + 1); }
15020 + )
15021 +
15022 +(define_insn "vec_extractv2hi"
15023 + [(set (match_operand:HI 0 "register_operand" "=r")
15024 + (vec_select:HI
15025 + (match_operand:V2HI 1 "register_operand" "r")
15026 + (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
15027 + ""
15028 + {
15029 + if ( INTVAL(operands[2]) == 0 )
15030 + return "bfextu\t%0, %1, 16, 16";
15031 + else
15032 + return "bfextu\t%0, %1, 0, 16";
15033 + }
15034 + [(set_attr "type" "alu")
15035 + (set_attr "length" "4")
15036 + (set_attr "cc" "clobber")])
15037 +
15038 +(define_insn "vec_extractv4qi"
15039 + [(set (match_operand:QI 0 "register_operand" "=r")
15040 + (vec_select:QI
15041 + (match_operand:V4QI 1 "register_operand" "r")
15042 + (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
15043 + ""
15044 + {
15045 + switch ( INTVAL(operands[2]) ){
15046 + case 0:
15047 + return "bfextu\t%0, %1, 24, 8";
15048 + case 1:
15049 + return "bfextu\t%0, %1, 16, 8";
15050 + case 2:
15051 + return "bfextu\t%0, %1, 8, 8";
15052 + case 3:
15053 + return "bfextu\t%0, %1, 0, 8";
15054 + default:
15055 + abort();
15056 + }
15057 + }
15058 + [(set_attr "type" "alu")
15059 + (set_attr "length" "4")
15060 + (set_attr "cc" "clobber")])
15061 +
15062 +
15063 +(define_insn "concatv2hi"
15064 + [(set (match_operand:V2HI 0 "register_operand" "=r, r, r")
15065 + (vec_concat:V2HI
15066 + (match_operand:HI 1 "register_operand" "r, r, 0")
15067 + (match_operand:HI 2 "register_operand" "r, 0, r")))]
15068 + ""
15069 + "@
15070 + mov\t%0, %1\;bfins\t%0, %2, 0, 16
15071 + bfins\t%0, %2, 0, 16
15072 + bfins\t%0, %1, 16, 16"
15073 + [(set_attr "length" "6, 4, 4")
15074 + (set_attr "type" "alu")])
15075 +
15076 +
15077 +;; Load the atomic operation description
15078 +(include "sync.md")
15079 +
15080 +;; Load the SIMD description
15081 +(include "simd.md")
15082 +
15083 +;; Load the FP coprocessor patterns
15084 +(include "fpcp.md")
15085 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32-modes.def gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-modes.def
15086 --- gcc-4.2.1/gcc/config/avr32/avr32-modes.def 1970-01-01 01:00:00.000000000 +0100
15087 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-modes.def 2007-05-07 14:29:10.000000000 +0200
15088 @@ -0,0 +1 @@
15089 +VECTOR_MODES (INT, 4); /* V4QI V2HI */
15090 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32.opt gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.opt
15091 --- gcc-4.2.1/gcc/config/avr32/avr32.opt 1970-01-01 01:00:00.000000000 +0100
15092 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32.opt 2007-09-28 10:33:00.000000000 +0200
15093 @@ -0,0 +1,73 @@
15094 +; Options for the ATMEL AVR32 port of the compiler.
15095 +
15096 +; Copyright 2007 Atmel Corporation.
15097 +;
15098 +; This file is part of GCC.
15099 +;
15100 +; GCC is free software; you can redistribute it and/or modify it under
15101 +; the terms of the GNU General Public License as published by the Free
15102 +; Software Foundation; either version 2, or (at your option) any later
15103 +; version.
15104 +;
15105 +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15106 +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
15107 +; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15108 +; for more details.
15109 +;
15110 +; You should have received a copy of the GNU General Public License
15111 +; along with GCC; see the file COPYING. If not, write to the Free
15112 +; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
15113 +; 02110-1301, USA.
15114 +
15115 +muse-rodata-section
15116 +Target Report Mask(USE_RODATA_SECTION)
15117 +Do not put readonly-data in .text section, but in .rodata.
15118 +
15119 +mhard-float
15120 +Target Report Undocumented Mask(HARD_FLOAT)
15121 +Use floating point coprocessor instructions.
15122 +
15123 +msoft-float
15124 +Target Report Undocumented InverseMask(HARD_FLOAT, SOFT_FLOAT)
15125 +Use software floating-point library for floating-point operations.
15126 +
15127 +force-double-align
15128 +Target Report RejectNegative Mask(FORCE_DOUBLE_ALIGN)
15129 +Force double-word alignment for double-word memory accesses.
15130 +
15131 +mno-init-got
15132 +Target Report RejectNegative Mask(NO_INIT_GOT)
15133 +Do not initialize GOT register before using it when compiling PIC code.
15134 +
15135 +mrelax
15136 +Target Report Mask(RELAX)
15137 +Let invoked assembler and linker do relaxing (Enabled by default when optimization level is >1).
15138 +
15139 +mmd-reorg-opt
15140 +Target Report Undocumented Mask(MD_REORG_OPTIMIZATION)
15141 +Perform machine dependent optimizations in reorg stage.
15142 +
15143 +masm-addr-pseudos
15144 +Target Report Mask(HAS_ASM_ADDR_PSEUDOS)
15145 +Use assembler pseudo-instructions lda.w and call for handling direct addresses. (Enabled by default)
15146 +
15147 +mpart=
15148 +Target Report RejectNegative Joined Var(avr32_part_name)
15149 +Specify the AVR32 part name
15150 +
15151 +mcpu=
15152 +Target Report RejectNegative Joined Undocumented Var(avr32_part_name)
15153 +Specify the AVR32 part name (deprecated)
15154 +
15155 +march=
15156 +Target Report RejectNegative Joined Var(avr32_arch_name)
15157 +Specify the AVR32 architecture name
15158 +
15159 +mfast-float
15160 +Target Report Mask(FAST_FLOAT)
15161 +Enable fast floating-point library. Enabled by default if the -funsafe-math-optimizations switch is specified.
15162 +
15163 +mimm-in-const-pool
15164 +Target Report Var(avr32_imm_in_const_pool) Init(-1)
15165 +Put large immediates in constant pool. This is enabled by default for archs with insn-cache.
15166 +
15167 diff -Nrup gcc-4.2.1/gcc/config/avr32/avr32-protos.h gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-protos.h
15168 --- gcc-4.2.1/gcc/config/avr32/avr32-protos.h 1970-01-01 01:00:00.000000000 +0100
15169 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/avr32-protos.h 2007-09-28 10:33:00.000000000 +0200
15170 @@ -0,0 +1,185 @@
15171 +/*
15172 + Prototypes for exported functions defined in avr32.c
15173 + Copyright 2003-2006 Atmel Corporation.
15174 +
15175 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
15176 + Initial porting by Anders �dland.
15177 +
15178 + This file is part of GCC.
15179 +
15180 + This program is free software; you can redistribute it and/or modify
15181 + it under the terms of the GNU General Public License as published by
15182 + the Free Software Foundation; either version 2 of the License, or
15183 + (at your option) any later version.
15184 +
15185 + This program is distributed in the hope that it will be useful,
15186 + but WITHOUT ANY WARRANTY; without even the implied warranty of
15187 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15188 + GNU General Public License for more details.
15189 +
15190 + You should have received a copy of the GNU General Public License
15191 + along with this program; if not, write to the Free Software
15192 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15193 +
15194 +
15195 +#ifndef AVR32_PROTOS_H
15196 +#define AVR32_PROTOS_H
15197 +
15198 +extern const int swap_reg[];
15199 +
15200 +extern int avr32_valid_macmac_bypass (rtx, rtx);
15201 +extern int avr32_valid_mulmac_bypass (rtx, rtx);
15202 +
15203 +extern int avr32_decode_lcomm_symbol_offset (rtx, int *);
15204 +extern void avr32_encode_lcomm_symbol_offset (tree, char *, int);
15205 +
15206 +extern const char *avr32_strip_name_encoding (const char *);
15207 +
15208 +extern rtx avr32_get_note_reg_equiv (rtx insn);
15209 +
15210 +extern int avr32_use_return_insn (int iscond);
15211 +
15212 +extern void avr32_make_reglist16 (int reglist16_vect, char *reglist16_string);
15213 +
15214 +extern void avr32_make_reglist8 (int reglist8_vect, char *reglist8_string);
15215 +extern void avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string);
15216 +extern void avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string);
15217 +
15218 +extern void avr32_output_return_instruction (int single_ret_inst,
15219 + int iscond, rtx cond,
15220 + rtx r12_imm);
15221 +extern void avr32_expand_prologue (void);
15222 +extern void avr32_set_return_address (rtx source, rtx scratch);
15223 +
15224 +extern int avr32_hard_regno_mode_ok (int regno, enum machine_mode mode);
15225 +extern int avr32_extra_constraint_s (rtx value, const int strict);
15226 +extern int avr32_eh_return_data_regno (const int n);
15227 +extern int avr32_initial_elimination_offset (const int from, const int to);
15228 +extern rtx avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode,
15229 + tree type, int named);
15230 +extern void avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
15231 + rtx libname, tree fndecl);
15232 +extern void avr32_function_arg_advance (CUMULATIVE_ARGS * cum,
15233 + enum machine_mode mode,
15234 + tree type, int named);
15235 +#ifdef ARGS_SIZE_RTX
15236 +/* expr.h defines ARGS_SIZE_RTX and `enum direction'. */
15237 +extern enum direction avr32_function_arg_padding (enum machine_mode mode,
15238 + tree type);
15239 +#endif /* ARGS_SIZE_RTX */
15240 +extern rtx avr32_function_value (tree valtype, tree func, bool outgoing);
15241 +extern rtx avr32_libcall_value (enum machine_mode mode);
15242 +extern int avr32_sched_use_dfa_pipeline_interface (void);
15243 +extern bool avr32_return_in_memory (tree type, tree fntype);
15244 +extern void avr32_regs_to_save (char *operand);
15245 +extern void avr32_target_asm_function_prologue (FILE * file,
15246 + HOST_WIDE_INT size);
15247 +extern void avr32_target_asm_function_epilogue (FILE * file,
15248 + HOST_WIDE_INT size);
15249 +extern void avr32_trampoline_template (FILE * file);
15250 +extern void avr32_initialize_trampoline (rtx addr, rtx fnaddr,
15251 + rtx static_chain);
15252 +extern int avr32_legitimate_address (enum machine_mode mode, rtx x,
15253 + int strict);
15254 +extern int avr32_legitimate_constant_p (rtx x);
15255 +
15256 +extern int avr32_legitimate_pic_operand_p (rtx x);
15257 +
15258 +extern rtx avr32_find_symbol (rtx x);
15259 +extern void avr32_select_section (rtx exp, int reloc, int align);
15260 +extern void avr32_encode_section_info (tree decl, rtx rtl, int first);
15261 +extern void avr32_asm_file_end (FILE * stream);
15262 +extern void avr32_asm_output_ascii (FILE * stream, char *ptr, int len);
15263 +extern void avr32_asm_output_common (FILE * stream, const char *name,
15264 + int size, int rounded);
15265 +extern void avr32_asm_output_label (FILE * stream, const char *name);
15266 +extern void avr32_asm_declare_object_name (FILE * stream, char *name,
15267 + tree decl);
15268 +extern void avr32_asm_globalize_label (FILE * stream, const char *name);
15269 +extern void avr32_asm_weaken_label (FILE * stream, const char *name);
15270 +extern void avr32_asm_output_external (FILE * stream, tree decl,
15271 + const char *name);
15272 +extern void avr32_asm_output_external_libcall (FILE * stream, rtx symref);
15273 +extern void avr32_asm_output_labelref (FILE * stream, const char *name);
15274 +extern void avr32_notice_update_cc (rtx exp, rtx insn);
15275 +extern void avr32_print_operand (FILE * stream, rtx x, int code);
15276 +extern void avr32_print_operand_address (FILE * stream, rtx x);
15277 +
15278 +extern int avr32_symbol (rtx x);
15279 +
15280 +extern void avr32_select_rtx_section (enum machine_mode mode, rtx x,
15281 + unsigned HOST_WIDE_INT align);
15282 +
15283 +extern int avr32_load_multiple_operation (rtx op, enum machine_mode mode);
15284 +extern int avr32_store_multiple_operation (rtx op, enum machine_mode mode);
15285 +
15286 +extern int avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c,
15287 + const char *str);
15288 +
15289 +extern bool avr32_cannot_force_const_mem (rtx x);
15290 +
15291 +extern void avr32_init_builtins (void);
15292 +
15293 +extern rtx avr32_expand_builtin (tree exp, rtx target, rtx subtarget,
15294 + enum machine_mode mode, int ignore);
15295 +
15296 +extern bool avr32_must_pass_in_stack (enum machine_mode mode, tree type);
15297 +
15298 +extern bool avr32_strict_argument_naming (CUMULATIVE_ARGS * ca);
15299 +
15300 +extern bool avr32_pass_by_reference (CUMULATIVE_ARGS * cum,
15301 + enum machine_mode mode,
15302 + tree type, bool named);
15303 +
15304 +extern rtx avr32_gen_load_multiple (rtx * regs, int count, rtx from,
15305 + int write_back, int in_struct_p,
15306 + int scalar_p);
15307 +extern rtx avr32_gen_store_multiple (rtx * regs, int count, rtx to,
15308 + int in_struct_p, int scalar_p);
15309 +extern int avr32_gen_movmemsi (rtx * operands);
15310 +
15311 +extern int avr32_rnd_operands (rtx add, rtx shift);
15312 +extern int avr32_adjust_insn_length (rtx insn, int length);
15313 +
15314 +extern int symbol_mentioned_p (rtx x);
15315 +extern int label_mentioned_p (rtx x);
15316 +extern rtx legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg);
15317 +extern int avr32_address_register_rtx_p (rtx x, int strict_p);
15318 +extern int avr32_legitimate_index_p (enum machine_mode mode, rtx index,
15319 + int strict_p);
15320 +
15321 +extern int avr32_const_double_immediate (rtx value);
15322 +extern void avr32_init_expanders (void);
15323 +extern rtx avr32_return_addr (int count, rtx frame);
15324 +extern bool avr32_got_mentioned_p (rtx addr);
15325 +
15326 +extern void avr32_final_prescan_insn (rtx insn, rtx * opvec, int noperands);
15327 +
15328 +extern int avr32_expand_movcc (enum machine_mode mode, rtx operands[]);
15329 +extern int avr32_expand_addcc (enum machine_mode mode, rtx operands[]);
15330 +#ifdef RTX_CODE
15331 +extern int avr32_expand_scc (RTX_CODE cond, rtx * operands);
15332 +#endif
15333 +
15334 +extern int avr32_store_bypass (rtx insn_out, rtx insn_in);
15335 +extern int avr32_mul_waw_bypass (rtx insn_out, rtx insn_in);
15336 +extern int avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in);
15337 +extern int avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in);
15338 +extern rtx avr32_output_cmp (rtx cond, enum machine_mode mode,
15339 + rtx op0, rtx op1);
15340 +
15341 +rtx get_next_insn_cond (rtx cur_insn);
15342 +int set_next_insn_cond (rtx cur_insn, rtx cond);
15343 +void avr32_override_options (void);
15344 +void avr32_load_pic_register (void);
15345 +void avr32_optimization_options (int level, int size);
15346 +void avr32_split_const_expr (enum machine_mode mode,
15347 + enum machine_mode new_mode,
15348 + rtx expr,
15349 + rtx *split_expr);
15350 +void avr32_get_intval (enum machine_mode mode,
15351 + rtx const_expr,
15352 + HOST_WIDE_INT *val);
15353 +
15354 +
15355 +#endif /* AVR32_PROTOS_H */
15356 diff -Nrup gcc-4.2.1/gcc/config/avr32/crti.asm gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/crti.asm
15357 --- gcc-4.2.1/gcc/config/avr32/crti.asm 1970-01-01 01:00:00.000000000 +0100
15358 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/crti.asm 2007-05-07 14:29:10.000000000 +0200
15359 @@ -0,0 +1,64 @@
15360 +/*
15361 + Init/fini stuff for AVR32.
15362 + Copyright 2003-2006 Atmel Corporation.
15363 +
15364 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
15365 +
15366 + This file is part of GCC.
15367 +
15368 + This program is free software; you can redistribute it and/or modify
15369 + it under the terms of the GNU General Public License as published by
15370 + the Free Software Foundation; either version 2 of the License, or
15371 + (at your option) any later version.
15372 +
15373 + This program is distributed in the hope that it will be useful,
15374 + but WITHOUT ANY WARRANTY; without even the implied warranty of
15375 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15376 + GNU General Public License for more details.
15377 +
15378 + You should have received a copy of the GNU General Public License
15379 + along with this program; if not, write to the Free Software
15380 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
15381 +
15382 +
15383 +/* The code in sections .init and .fini is supposed to be a single
15384 + regular function. The function in .init is called directly from
15385 + start in crt1.asm. The function in .fini is atexit()ed in crt1.asm
15386 + too.
15387 +
15388 + crti.asm contributes the prologue of a function to these sections,
15389 + and crtn.asm comes up the epilogue. STARTFILE_SPEC should list
15390 + crti.o before any other object files that might add code to .init
15391 + or .fini sections, and ENDFILE_SPEC should list crtn.o after any
15392 + such object files. */
15393 +
15394 + .file "crti.asm"
15395 +
15396 + .section ".init"
15397 +/* Just load the GOT */
15398 + .align 2
15399 + .global _init
15400 +_init:
15401 + stm --sp, r6, lr
15402 + lddpc r6, 1f
15403 +0:
15404 + rsub r6, pc
15405 + rjmp 2f
15406 + .align 2
15407 +1: .long 0b - _GLOBAL_OFFSET_TABLE_
15408 +2:
15409 +
15410 + .section ".fini"
15411 +/* Just load the GOT */
15412 + .align 2
15413 + .global _fini
15414 +_fini:
15415 + stm --sp, r6, lr
15416 + lddpc r6, 1f
15417 +0:
15418 + rsub r6, pc
15419 + rjmp 2f
15420 + .align 2
15421 +1: .long 0b - _GLOBAL_OFFSET_TABLE_
15422 +2:
15423 +
15424 diff -Nrup gcc-4.2.1/gcc/config/avr32/crtn.asm gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/crtn.asm
15425 --- gcc-4.2.1/gcc/config/avr32/crtn.asm 1970-01-01 01:00:00.000000000 +0100
15426 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/crtn.asm 2007-05-07 14:29:10.000000000 +0200
15427 @@ -0,0 +1,44 @@
15428 +/* Copyright (C) 2001 Free Software Foundation, Inc.
15429 + Written By Nick Clifton
15430 +
15431 + This file is free software; you can redistribute it and/or modify it
15432 + under the terms of the GNU General Public License as published by the
15433 + Free Software Foundation; either version 2, or (at your option) any
15434 + later version.
15435 +
15436 + In addition to the permissions in the GNU General Public License, the
15437 + Free Software Foundation gives you unlimited permission to link the
15438 + compiled version of this file with other programs, and to distribute
15439 + those programs without any restriction coming from the use of this
15440 + file. (The General Public License restrictions do apply in other
15441 + respects; for example, they cover modification of the file, and
15442 + distribution when not linked into another program.)
15443 +
15444 + This file is distributed in the hope that it will be useful, but
15445 + WITHOUT ANY WARRANTY; without even the implied warranty of
15446 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15447 + General Public License for more details.
15448 +
15449 + You should have received a copy of the GNU General Public License
15450 + along with this program; see the file COPYING. If not, write to
15451 + the Free Software Foundation, 59 Temple Place - Suite 330,
15452 + Boston, MA 02111-1307, USA.
15453 +
15454 + As a special exception, if you link this library with files
15455 + compiled with GCC to produce an executable, this does not cause
15456 + the resulting executable to be covered by the GNU General Public License.
15457 + This exception does not however invalidate any other reasons why
15458 + the executable file might be covered by the GNU General Public License.
15459 +*/
15460 +
15461 +
15462 +
15463 +
15464 + .file "crtn.asm"
15465 +
15466 + .section ".init"
15467 + ldm sp++, r6, pc
15468 +
15469 + .section ".fini"
15470 + ldm sp++, r6, pc
15471 +
15472 diff -Nrup gcc-4.2.1/gcc/config/avr32/fpcp.md gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/fpcp.md
15473 --- gcc-4.2.1/gcc/config/avr32/fpcp.md 1970-01-01 01:00:00.000000000 +0100
15474 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/fpcp.md 2007-05-07 14:29:10.000000000 +0200
15475 @@ -0,0 +1,551 @@
15476 +;; AVR32 machine description file for Floating-Point instructions.
15477 +;; Copyright 2003-2006 Atmel Corporation.
15478 +;;
15479 +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
15480 +;;
15481 +;; This file is part of GCC.
15482 +;;
15483 +;; This program is free software; you can redistribute it and/or modify
15484 +;; it under the terms of the GNU General Public License as published by
15485 +;; the Free Software Foundation; either version 2 of the License, or
15486 +;; (at your option) any later version.
15487 +;;
15488 +;; This program is distributed in the hope that it will be useful,
15489 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15490 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15491 +;; GNU General Public License for more details.
15492 +;;
15493 +;; You should have received a copy of the GNU General Public License
15494 +;; along with this program; if not, write to the Free Software
15495 +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15496 +
15497 +;; -*- Mode: Scheme -*-
15498 +
15499 +;;******************************************************************************
15500 +;; Automaton pipeline description for floating-point coprocessor insns
15501 +;;******************************************************************************
15502 +(define_cpu_unit "fid,fm1,fm2,fm3,fm4,fwb,fcmp,fcast" "avr32_ap")
15503 +
15504 +(define_insn_reservation "fmv_op" 1
15505 + (and (eq_attr "pipeline" "ap")
15506 + (eq_attr "type" "fmv"))
15507 + "is,da,d,fid,fwb")
15508 +
15509 +(define_insn_reservation "fmul_op" 5
15510 + (and (eq_attr "pipeline" "ap")
15511 + (eq_attr "type" "fmul"))
15512 + "is,da,d,fid,fm1,fm2,fm3,fm4,fwb")
15513 +
15514 +(define_insn_reservation "fcmps_op" 1
15515 + (and (eq_attr "pipeline" "ap")
15516 + (eq_attr "type" "fcmps"))
15517 + "is,da,d,fid,fcmp")
15518 +
15519 +(define_insn_reservation "fcmpd_op" 2
15520 + (and (eq_attr "pipeline" "ap")
15521 + (eq_attr "type" "fcmpd"))
15522 + "is,da,d,fid*2,fcmp")
15523 +
15524 +(define_insn_reservation "fcast_op" 3
15525 + (and (eq_attr "pipeline" "ap")
15526 + (eq_attr "type" "fcast"))
15527 + "is,da,d,fid,fcmp,fcast,fwb")
15528 +
15529 +(define_insn_reservation "fmvcpu_op" 2
15530 + (and (eq_attr "pipeline" "ap")
15531 + (eq_attr "type" "fmvcpu"))
15532 + "is,da,d")
15533 +
15534 +(define_insn_reservation "fldd_op" 1
15535 + (and (eq_attr "pipeline" "ap")
15536 + (eq_attr "type" "fldd"))
15537 + "is,da,d,fwb")
15538 +
15539 +(define_insn_reservation "flds_op" 1
15540 + (and (eq_attr "pipeline" "ap")
15541 + (eq_attr "type" "flds"))
15542 + "is,da,d,fwb")
15543 +
15544 +(define_insn_reservation "fsts_op" 0
15545 + (and (eq_attr "pipeline" "ap")
15546 + (eq_attr "type" "fsts"))
15547 + "is,da*2,d")
15548 +
15549 +(define_insn_reservation "fstd_op" 0
15550 + (and (eq_attr "pipeline" "ap")
15551 + (eq_attr "type" "fstd"))
15552 + "is,da*2,d")
15553 +
15554 +
15555 +(define_insn "*movsf_fpcp"
15556 + [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,r,m")
15557 + (match_operand:SF 1 "general_operand" " f,r,f,m,f,r,G,m,r"))]
15558 + "TARGET_HARD_FLOAT"
15559 + "@
15560 + fmov.s\t%0, %1
15561 + fmov.s\t%0, %1
15562 + fmov.s\t%0, %1
15563 + fld.s\t%0, %1
15564 + fst.s\t%0, %1
15565 + mov\t%0, %1
15566 + mov\t%0, %1
15567 + ld.w\t%0, %1
15568 + st.w\t%0, %1"
15569 + [(set_attr "length" "4,4,4,4,4,2,4,4,4")
15570 + (set_attr "type" "fmv,flds,fmvcpu,flds,fsts,alu,alu,load,store")])
15571 +
15572 +(define_insn_and_split "*movdf_fpcp"
15573 + [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,r,f,m,r,r,m")
15574 + (match_operand:DF 1 "general_operand" " f,r,f,m,f,r,m,r"))]
15575 + "TARGET_HARD_FLOAT"
15576 + "@
15577 + fmov.d\t%0, %1
15578 + fmov.d\t%0, %1
15579 + fmov.d\t%0, %1
15580 + fld.d\t%0, %1
15581 + fst.d\t%0, %1
15582 + mov\t%0, %1\;mov\t%m0, %m1
15583 + ld.d\t%0, %1
15584 + st.d\t%0, %1"
15585 +
15586 + "TARGET_HARD_FLOAT
15587 + && reload_completed
15588 + && (REG_P(operands[0]) && (REGNO_REG_CLASS(REGNO(operands[0])) == GENERAL_REGS))
15589 + && (REG_P(operands[1]) && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS))"
15590 + [(set (match_dup 0) (match_dup 1))
15591 + (set (match_dup 2) (match_dup 3))]
15592 + "
15593 + {
15594 + operands[2] = gen_highpart (SImode, operands[0]);
15595 + operands[0] = gen_lowpart (SImode, operands[0]);
15596 + operands[3] = gen_highpart(SImode, operands[1]);
15597 + operands[1] = gen_lowpart(SImode, operands[1]);
15598 + }
15599 + "
15600 +
15601 + [(set_attr "length" "4,4,4,4,4,4,4,4")
15602 + (set_attr "type" "fmv,fldd,fmvcpu,fldd,fstd,alu2,load2,store2")])
15603 +
15604 +
15605 +(define_insn "mulsf3"
15606 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15607 + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15608 + (match_operand:SF 2 "avr32_fp_register_operand" "f")))]
15609 + "TARGET_HARD_FLOAT"
15610 + "fmul.s\t%0, %1, %2"
15611 + [(set_attr "length" "4")
15612 + (set_attr "type" "fmul")])
15613 +
15614 +(define_insn "nmulsf3"
15615 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15616 + (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15617 + (match_operand:SF 2 "avr32_fp_register_operand" "f"))))]
15618 + "TARGET_HARD_FLOAT"
15619 + "fnmul.s\t%0, %1, %2"
15620 + [(set_attr "length" "4")
15621 + (set_attr "type" "fmul")])
15622 +
15623 +(define_peephole2
15624 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "")
15625 + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "")
15626 + (match_operand:SF 2 "avr32_fp_register_operand" "")))
15627 + (set (match_operand:SF 3 "avr32_fp_register_operand" "")
15628 + (neg:SF (match_dup 0)))]
15629 + "TARGET_HARD_FLOAT &&
15630 + (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))"
15631 + [(set (match_dup 3)
15632 + (neg:SF (mult:SF (match_dup 1)
15633 + (match_dup 2))))]
15634 +)
15635 +
15636 +
15637 +(define_insn "macsf3"
15638 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15639 + (plus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15640 + (match_operand:SF 2 "avr32_fp_register_operand" "f"))
15641 + (match_operand:SF 3 "avr32_fp_register_operand" "0")))]
15642 + "TARGET_HARD_FLOAT"
15643 + "fmac.s\t%0, %1, %2"
15644 + [(set_attr "length" "4")
15645 + (set_attr "type" "fmul")])
15646 +
15647 +(define_insn "nmacsf3"
15648 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15649 + (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15650 + (match_operand:SF 2 "avr32_fp_register_operand" "f")))
15651 + (match_operand:SF 3 "avr32_fp_register_operand" "0")))]
15652 + "TARGET_HARD_FLOAT"
15653 + "fnmac.s\t%0, %1, %2"
15654 + [(set_attr "length" "4")
15655 + (set_attr "type" "fmul")])
15656 +
15657 +(define_peephole2
15658 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "")
15659 + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "")
15660 + (match_operand:SF 2 "avr32_fp_register_operand" "")))
15661 + (set (match_operand:SF 3 "avr32_fp_register_operand" "")
15662 + (minus:SF
15663 + (match_dup 3)
15664 + (match_dup 0)))]
15665 + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])"
15666 + [(set (match_dup 3)
15667 + (plus:SF (neg:SF (mult:SF (match_dup 1)
15668 + (match_dup 2)))
15669 + (match_dup 3)))]
15670 +)
15671 +
15672 +
15673 +(define_insn "msubacsf3"
15674 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15675 + (minus:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15676 + (match_operand:SF 2 "avr32_fp_register_operand" "f"))
15677 + (match_operand:SF 3 "avr32_fp_register_operand" "0")))]
15678 + "TARGET_HARD_FLOAT"
15679 + "fmsc.s\t%0, %1, %2"
15680 + [(set_attr "length" "4")
15681 + (set_attr "type" "fmul")])
15682 +
15683 +(define_peephole2
15684 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "")
15685 + (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "")
15686 + (match_operand:SF 2 "avr32_fp_register_operand" "")))
15687 + (set (match_operand:SF 3 "avr32_fp_register_operand" "")
15688 + (minus:SF
15689 + (match_dup 0)
15690 + (match_dup 3)))]
15691 + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])"
15692 + [(set (match_dup 3)
15693 + (minus:SF (mult:SF (match_dup 1)
15694 + (match_dup 2))
15695 + (match_dup 3)))]
15696 +)
15697 +
15698 +(define_insn "nmsubacsf3"
15699 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15700 + (minus:SF (neg:SF (mult:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15701 + (match_operand:SF 2 "avr32_fp_register_operand" "f")))
15702 + (match_operand:SF 3 "avr32_fp_register_operand" "0")))]
15703 + "TARGET_HARD_FLOAT"
15704 + "fnmsc.s\t%0, %1, %2"
15705 + [(set_attr "length" "4")
15706 + (set_attr "type" "fmul")])
15707 +
15708 +
15709 +
15710 +(define_insn "addsf3"
15711 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15712 + (plus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15713 + (match_operand:SF 2 "avr32_fp_register_operand" "f")))]
15714 + "TARGET_HARD_FLOAT"
15715 + "fadd.s\t%0, %1, %2"
15716 + [(set_attr "length" "4")
15717 + (set_attr "type" "fmul")])
15718 +
15719 +(define_insn "subsf3"
15720 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15721 + (minus:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")
15722 + (match_operand:SF 2 "avr32_fp_register_operand" "f")))]
15723 + "TARGET_HARD_FLOAT"
15724 + "fsub.s\t%0, %1, %2"
15725 + [(set_attr "length" "4")
15726 + (set_attr "type" "fmul")])
15727 +
15728 +
15729 +(define_insn "negsf2"
15730 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15731 + (neg:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))]
15732 + "TARGET_HARD_FLOAT"
15733 + "fneg.s\t%0, %1"
15734 + [(set_attr "length" "4")
15735 + (set_attr "type" "fmv")])
15736 +
15737 +(define_insn "abssf2"
15738 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15739 + (abs:SF (match_operand:SF 1 "avr32_fp_register_operand" "f")))]
15740 + "TARGET_HARD_FLOAT"
15741 + "fabs.s\t%0, %1"
15742 + [(set_attr "length" "4")
15743 + (set_attr "type" "fmv")])
15744 +
15745 +(define_insn "truncdfsf2"
15746 + [(set (match_operand:SF 0 "avr32_fp_register_operand" "=f")
15747 + (float_truncate:SF
15748 + (match_operand:DF 1 "avr32_fp_register_operand" "f")))]
15749 + "TARGET_HARD_FLOAT"
15750 + "fcastd.s\t%0, %1"
15751 + [(set_attr "length" "4")
15752 + (set_attr "type" "fcast")])
15753 +
15754 +(define_insn "extendsfdf2"
15755 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15756 + (float_extend:DF
15757 + (match_operand:SF 1 "avr32_fp_register_operand" "f")))]
15758 + "TARGET_HARD_FLOAT"
15759 + "fcasts.d\t%0, %1"
15760 + [(set_attr "length" "4")
15761 + (set_attr "type" "fcast")])
15762 +
15763 +(define_insn "muldf3"
15764 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15765 + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15766 + (match_operand:DF 2 "avr32_fp_register_operand" "f")))]
15767 + "TARGET_HARD_FLOAT"
15768 + "fmul.d\t%0, %1, %2"
15769 + [(set_attr "length" "4")
15770 + (set_attr "type" "fmul")])
15771 +
15772 +(define_insn "nmuldf3"
15773 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15774 + (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15775 + (match_operand:DF 2 "avr32_fp_register_operand" "f"))))]
15776 + "TARGET_HARD_FLOAT"
15777 + "fnmul.d\t%0, %1, %2"
15778 + [(set_attr "length" "4")
15779 + (set_attr "type" "fmul")])
15780 +
15781 +(define_peephole2
15782 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "")
15783 + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "")
15784 + (match_operand:DF 2 "avr32_fp_register_operand" "")))
15785 + (set (match_operand:DF 3 "avr32_fp_register_operand" "")
15786 + (neg:DF (match_dup 0)))]
15787 + "TARGET_HARD_FLOAT &&
15788 + (peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[3]) == REGNO(operands[0])))"
15789 + [(set (match_dup 3)
15790 + (neg:DF (mult:DF (match_dup 1)
15791 + (match_dup 2))))]
15792 +)
15793 +
15794 +(define_insn "macdf3"
15795 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15796 + (plus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15797 + (match_operand:DF 2 "avr32_fp_register_operand" "f"))
15798 + (match_operand:DF 3 "avr32_fp_register_operand" "0")))]
15799 + "TARGET_HARD_FLOAT"
15800 + "fmac.d\t%0, %1, %2"
15801 + [(set_attr "length" "4")
15802 + (set_attr "type" "fmul")])
15803 +
15804 +(define_insn "msubacdf3"
15805 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15806 + (minus:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15807 + (match_operand:DF 2 "avr32_fp_register_operand" "f"))
15808 + (match_operand:DF 3 "avr32_fp_register_operand" "0")))]
15809 + "TARGET_HARD_FLOAT"
15810 + "fmsc.d\t%0, %1, %2"
15811 + [(set_attr "length" "4")
15812 + (set_attr "type" "fmul")])
15813 +
15814 +(define_peephole2
15815 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "")
15816 + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "")
15817 + (match_operand:DF 2 "avr32_fp_register_operand" "")))
15818 + (set (match_operand:DF 3 "avr32_fp_register_operand" "")
15819 + (minus:DF
15820 + (match_dup 0)
15821 + (match_dup 3)))]
15822 + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])"
15823 + [(set (match_dup 3)
15824 + (minus:DF (mult:DF (match_dup 1)
15825 + (match_dup 2))
15826 + (match_dup 3)))]
15827 + )
15828 +
15829 +(define_insn "nmsubacdf3"
15830 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15831 + (minus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15832 + (match_operand:DF 2 "avr32_fp_register_operand" "f")))
15833 + (match_operand:DF 3 "avr32_fp_register_operand" "0")))]
15834 + "TARGET_HARD_FLOAT"
15835 + "fnmsc.d\t%0, %1, %2"
15836 + [(set_attr "length" "4")
15837 + (set_attr "type" "fmul")])
15838 +
15839 +(define_insn "nmacdf3"
15840 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15841 + (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15842 + (match_operand:DF 2 "avr32_fp_register_operand" "f")))
15843 + (match_operand:DF 3 "avr32_fp_register_operand" "0")))]
15844 + "TARGET_HARD_FLOAT"
15845 + "fnmac.d\t%0, %1, %2"
15846 + [(set_attr "length" "4")
15847 + (set_attr "type" "fmul")])
15848 +
15849 +(define_peephole2
15850 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "")
15851 + (mult:DF (match_operand:DF 1 "avr32_fp_register_operand" "")
15852 + (match_operand:DF 2 "avr32_fp_register_operand" "")))
15853 + (set (match_operand:DF 3 "avr32_fp_register_operand" "")
15854 + (minus:DF
15855 + (match_dup 3)
15856 + (match_dup 0)))]
15857 + "TARGET_HARD_FLOAT && peep2_reg_dead_p(2, operands[0])"
15858 + [(set (match_dup 3)
15859 + (plus:DF (neg:DF (mult:DF (match_dup 1)
15860 + (match_dup 2)))
15861 + (match_dup 3)))]
15862 +)
15863 +
15864 +(define_insn "adddf3"
15865 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15866 + (plus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15867 + (match_operand:DF 2 "avr32_fp_register_operand" "f")))]
15868 + "TARGET_HARD_FLOAT"
15869 + "fadd.d\t%0, %1, %2"
15870 + [(set_attr "length" "4")
15871 + (set_attr "type" "fmul")])
15872 +
15873 +(define_insn "subdf3"
15874 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15875 + (minus:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")
15876 + (match_operand:DF 2 "avr32_fp_register_operand" "f")))]
15877 + "TARGET_HARD_FLOAT"
15878 + "fsub.d\t%0, %1, %2"
15879 + [(set_attr "length" "4")
15880 + (set_attr "type" "fmul")])
15881 +
15882 +(define_insn "negdf2"
15883 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15884 + (neg:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))]
15885 + "TARGET_HARD_FLOAT"
15886 + "fneg.d\t%0, %1"
15887 + [(set_attr "length" "4")
15888 + (set_attr "type" "fmv")])
15889 +
15890 +(define_insn "absdf2"
15891 + [(set (match_operand:DF 0 "avr32_fp_register_operand" "=f")
15892 + (abs:DF (match_operand:DF 1 "avr32_fp_register_operand" "f")))]
15893 + "TARGET_HARD_FLOAT"
15894 + "fabs.d\t%0, %1"
15895 + [(set_attr "length" "4")
15896 + (set_attr "type" "fmv")])
15897 +
15898 +
15899 +(define_expand "cmpdf"
15900 + [(set (cc0)
15901 + (compare:DF
15902 + (match_operand:DF 0 "general_operand" "")
15903 + (match_operand:DF 1 "general_operand" "")))]
15904 + "TARGET_HARD_FLOAT"
15905 + "{
15906 + rtx tmpreg;
15907 + if ( !REG_P(operands[0]) )
15908 + operands[0] = force_reg(DFmode, operands[0]);
15909 +
15910 + if ( !REG_P(operands[1]) )
15911 + operands[1] = force_reg(DFmode, operands[1]);
15912 +
15913 + avr32_compare_op0 = operands[0];
15914 + avr32_compare_op1 = operands[1];
15915 +
15916 + emit_insn(gen_cmpdf_internal(operands[0], operands[1]));
15917 +
15918 + tmpreg = gen_reg_rtx(SImode);
15919 + emit_insn(gen_fpcc_to_reg(tmpreg));
15920 + emit_insn(gen_reg_to_cc(tmpreg));
15921 +
15922 + DONE;
15923 + }"
15924 +)
15925 +
15926 +(define_insn "cmpdf_internal"
15927 + [(set (reg:CC FPCC_REGNUM)
15928 + (compare:CC
15929 + (match_operand:DF 0 "avr32_fp_register_operand" "f")
15930 + (match_operand:DF 1 "avr32_fp_register_operand" "f")))]
15931 + "TARGET_HARD_FLOAT"
15932 + {
15933 + if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) )
15934 + return "fcmp.d\t%0, %1";
15935 + return "";
15936 + }
15937 + [(set_attr "length" "4")
15938 + (set_attr "type" "fcmpd")
15939 + (set_attr "cc" "fpcompare")])
15940 +
15941 +(define_expand "cmpsf"
15942 + [(set (cc0)
15943 + (compare:SF
15944 + (match_operand:SF 0 "general_operand" "")
15945 + (match_operand:SF 1 "general_operand" "")))]
15946 + "TARGET_HARD_FLOAT"
15947 + "{
15948 + rtx tmpreg;
15949 + if ( !REG_P(operands[0]) )
15950 + operands[0] = force_reg(SFmode, operands[0]);
15951 +
15952 + if ( !REG_P(operands[1]) )
15953 + operands[1] = force_reg(SFmode, operands[1]);
15954 +
15955 + avr32_compare_op0 = operands[0];
15956 + avr32_compare_op1 = operands[1];
15957 +
15958 + emit_insn(gen_cmpsf_internal(operands[0], operands[1]));
15959 +
15960 + tmpreg = gen_reg_rtx(SImode);
15961 + emit_insn(gen_fpcc_to_reg(tmpreg));
15962 + emit_insn(gen_reg_to_cc(tmpreg));
15963 +
15964 + DONE;
15965 + }"
15966 +)
15967 +
15968 +(define_insn "cmpsf_internal"
15969 + [(set (reg:CC FPCC_REGNUM)
15970 + (compare:CC
15971 + (match_operand:SF 0 "avr32_fp_register_operand" "f")
15972 + (match_operand:SF 1 "avr32_fp_register_operand" "f")))]
15973 + "TARGET_HARD_FLOAT"
15974 + {
15975 + if (!rtx_equal_p(cc_prev_status.mdep.fpvalue, SET_SRC(PATTERN (insn))) )
15976 + return "fcmp.s\t%0, %1";
15977 + return "";
15978 + }
15979 + [(set_attr "length" "4")
15980 + (set_attr "type" "fcmps")
15981 + (set_attr "cc" "fpcompare")])
15982 +
15983 +(define_insn "fpcc_to_reg"
15984 + [(set (match_operand:SI 0 "register_operand" "=r")
15985 + (unspec:SI [(reg:CC FPCC_REGNUM)]
15986 + UNSPEC_FPCC_TO_REG))]
15987 + "TARGET_HARD_FLOAT"
15988 + "fmov.s\t%0, fsr"
15989 + [(set_attr "length" "4")
15990 + (set_attr "type" "fmvcpu")])
15991 +
15992 +(define_insn "reg_to_cc"
15993 + [(set (cc0)
15994 + (unspec:SI [(match_operand:SI 0 "register_operand" "r")]
15995 + UNSPEC_REG_TO_CC))]
15996 + "TARGET_HARD_FLOAT"
15997 + "musfr\t%0"
15998 + [(set_attr "length" "2")
15999 + (set_attr "type" "alu")
16000 + (set_attr "cc" "from_fpcc")])
16001 +
16002 +(define_insn "stm_fp"
16003 + [(unspec [(match_operand 0 "register_operand" "r")
16004 + (match_operand 1 "const_int_operand" "")
16005 + (match_operand 2 "const_int_operand" "")]
16006 + UNSPEC_STMFP)]
16007 + "TARGET_HARD_FLOAT"
16008 + {
16009 + int cop_reglist = INTVAL(operands[1]);
16010 +
16011 + if (INTVAL(operands[2]) != 0)
16012 + return "stcm.w\tcp0, --%0, %C1";
16013 + else
16014 + return "stcm.w\tcp0, %0, %C1";
16015 +
16016 + if ( cop_reglist & ~0xff ){
16017 + operands[1] = GEN_INT(cop_reglist & ~0xff);
16018 + if (INTVAL(operands[2]) != 0)
16019 + return "stcm.d\tcp0, --%0, %D1";
16020 + else
16021 + return "stcm.d\tcp0, %0, %D1";
16022 + }
16023 + }
16024 + [(set_attr "type" "fstm")
16025 + (set_attr "length" "4")
16026 + (set_attr "cc" "none")])
16027 diff -Nrup gcc-4.2.1/gcc/config/avr32/lib1funcs.S gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/lib1funcs.S
16028 --- gcc-4.2.1/gcc/config/avr32/lib1funcs.S 1970-01-01 01:00:00.000000000 +0100
16029 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/lib1funcs.S 2007-09-28 10:33:00.000000000 +0200
16030 @@ -0,0 +1,2589 @@
16031 +
16032 +/* Adjust the unpacked double number if it is a subnormal number.
16033 + The exponent and mantissa pair are stored
16034 + in [mant_hi,mant_lo] and [exp]. A register with the correct sign bit in
16035 + the MSB is passed in [sign]. Needs two scratch
16036 + registers [scratch1] and [scratch2]. An adjusted and packed double float
16037 + is present in [mant_hi,mant_lo] after macro has executed */
16038 +.macro adjust_subnormal_df exp, mant_lo, mant_hi, sign, scratch1, scratch2
16039 + /* We have an exponent which is <=0 indicating a subnormal number
16040 + As it should be stored as if the exponent was 1 (although the
16041 + exponent field is all zeros to indicate a subnormal number)
16042 + we have to shift down the mantissa to its correct position. */
16043 + neg \exp
16044 + sub \exp,-1 /* amount to shift down */
16045 + cp.w \exp,54
16046 + brlo 50f /* if more than 53 shift steps, the
16047 + entire mantissa will disappear
16048 + without any rounding to occur */
16049 + mov \mant_hi, 0
16050 + mov \mant_lo, 0
16051 + rjmp 52f
16052 +50:
16053 + sub \exp,-10 /* do the shift to position the
16054 + mantissa at the same time
16055 + note! this does not include the
16056 + final 1 step shift to add the sign */
16057 +
16058 + /* when shifting, save all shifted out bits in [scratch2]. we may need to
16059 + look at them to make correct rounding. */
16060 +
16061 + rsub \scratch1,\exp,32 /* get inverted shift count */
16062 + cp.w \exp,32 /* handle shifts >= 32 separately */
16063 + brhs 51f
16064 +
16065 + /* small (<32) shift amount, both words are part of the shift */
16066 + lsl \scratch2,\mant_lo,\scratch1 /* save bits to shift out from lsw*/
16067 + lsl \scratch1,\mant_hi,\scratch1 /* get bits from msw destined for lsw*/
16068 + lsr \mant_lo,\mant_lo,\exp /* shift down lsw */
16069 + lsr \mant_hi,\mant_hi,\exp /* shift down msw */
16070 + or \mant_hi,\scratch1 /* add bits from msw with prepared lsw */
16071 + rjmp 50f
16072 +
16073 + /* large (>=32) shift amount, only lsw will have bits left after shift.
16074 + note that shift operations will use ((shift count) mod 32) so
16075 + we do not need to subtract 32 from shift count. */
16076 +51:
16077 + lsl \scratch2,\mant_hi,\scratch1 /* save bits to shift out from msw */
16078 + or \scratch2,\mant_lo /* also save all bits from lsw */
16079 + mov \mant_lo,\mant_hi /* msw -> lsw (i.e. "shift 32 first") */
16080 + mov \mant_hi,0 /* clear msw */
16081 + lsr \mant_lo,\mant_lo,\exp /* make rest of shift inside lsw */
16082 +
16083 +50:
16084 + /* result is almost ready to return, except that least significant bit
16085 + and the part we already shifted out may cause the result to be
16086 + rounded */
16087 + bld \mant_lo,0 /* get bit to be shifted out */
16088 + brcc 51f /* if bit was 0, no rounding */
16089 +
16090 + /* msb of part to remove is 1, so rounding depends on rest of bits */
16091 + tst \scratch2,\scratch2 /* get shifted out tail */
16092 + brne 50f /* if rest > 0, do round */
16093 + bld \mant_lo,1 /* we have to look at lsb in result */
16094 + brcc 51f /* if lsb is 0, don't round */
16095 +
16096 +50:
16097 + /* subnormal result requires rounding
16098 + rounding may cause subnormal to become smallest normal number
16099 + luckily, smallest normal number has exactly the representation
16100 + we got by rippling a one bit up from mantissa into exponent field. */
16101 + sub \mant_lo,-1
16102 + subcc \mant_hi,-1
16103 +
16104 +51:
16105 + /* shift and return packed double with correct sign */
16106 + rol \sign
16107 + ror \mant_hi
16108 + ror \mant_lo
16109 +52:
16110 +.endm
16111 +
16112 +
16113 +/* Adjust subnormal single float number with exponent [exp]
16114 + and mantissa [mant] and round. */
16115 +.macro adjust_subnormal_sf sf, exp, mant, sign, scratch
16116 + /* subnormal number */
16117 + rsub \exp,\exp, 1 /* shift amount */
16118 + cp.w \exp, 25
16119 + movhs \mant, 0
16120 + brhs 90f /* Return zero */
16121 + rsub \scratch, \exp, 32
16122 + lsl \scratch, \mant,\scratch/* Check if there are any bits set
16123 + in the bits discarded in the mantissa */
16124 + srne \scratch /* If so set the lsb of the shifted mantissa */
16125 + lsr \mant,\mant,\exp /* Shift the mantissa */
16126 + or \mant, \scratch /* Round lsb if any bits were shifted out */
16127 + /* Rounding : For explaination, see round_sf. */
16128 + mov \scratch, 0x7f /* Set rounding constant */
16129 + bld \mant, 8
16130 + subeq \scratch, -1 /* For odd numbers use rounding constant 0x80 */
16131 + add \mant, \scratch /* Add rounding constant to mantissa */
16132 + /* We can't overflow because mantissa is at least shifted one position
16133 + to the right so the implicit bit is zero. We can however get the implicit
16134 + bit set after rounding which means that we have the lowest normal number
16135 + but this is ok since this bit has the same position as the LSB of the
16136 + exponent */
16137 + lsr \sf, \mant, 7
16138 + /* Rotate in sign */
16139 + lsl \sign, 1
16140 + ror \sf
16141 +90:
16142 +.endm
16143 +
16144 +
16145 +/* Round the unpacked df number with exponent [exp] and
16146 + mantissa [mant_hi, mant_lo]. Uses scratch register
16147 + [scratch] */
16148 +.macro round_df exp, mant_lo, mant_hi, scratch
16149 + mov \scratch, 0x3ff /* Rounding constant */
16150 + bld \mant_lo,11 /* Check if lsb in the final result is
16151 + set */
16152 + subeq \scratch, -1 /* Adjust rounding constant to 0x400
16153 + if rounding 0.5 upwards */
16154 + add \mant_lo, \scratch /* Round */
16155 + acr \mant_hi /* If overflowing we know that
16156 + we have all zeros in the bits not
16157 + scaled out so we can leave them
16158 + but we must increase the exponent with
16159 + two since we had an implicit bit
16160 + which is lost + the extra overflow bit */
16161 + subcs \exp, -2 /* Update exponent */
16162 +.endm
16163 +
16164 +/* Round single float number stored in [mant] and [exp] */
16165 +.macro round_sf exp, mant, scratch
16166 + /* Round:
16167 + For 0.5 we round to nearest even integer
16168 + for all other cases we round to nearest integer.
16169 + This means that if the digit left of the "point" (.)
16170 + is 1 we can add 0x80 to the mantissa since the
16171 + corner case 0x180 will round up to 0x200. If the
16172 + digit left of the "point" is 0 we will have to
16173 + add 0x7f since this will give 0xff and hence a
16174 + truncation/rounding downwards for the corner
16175 + case when the 9 lowest bits are 0x080 */
16176 + mov \scratch, 0x7f /* Set rounding constant */
16177 + /* Check if the mantissa is even or odd */
16178 + bld \mant, 8
16179 + subeq \scratch, -1 /* Rounding constant should be 0x80 */
16180 + add \mant, \scratch
16181 + subcs \exp, -2 /* Adjust exponent if we overflowed */
16182 +.endm
16183 +
16184 +/* Scale mantissa [mant_hi, mant_lo] with amount [shift_count].
16185 + Uses scratch registers [scratch1] and [scratch2] */
16186 +.macro scale_df shift_count, mant_lo, mant_hi, scratch1, scratch2
16187 + /* Scale [mant_hi, mant_lo] with shift_amount.
16188 + Must not forget the sticky bits we intend to shift out. */
16189 +
16190 + rsub \scratch1,\shift_count,32/* get (32 - shift count)
16191 + (if shift count > 32 we get a
16192 + negative value, but that will
16193 + work as well in the code below.) */
16194 +
16195 + cp.w \shift_count,32 /* handle shifts >= 32 separately */
16196 + brhs 70f
16197 +
16198 + /* small (<32) shift amount, both words are part of the shift
16199 + first remember whether part that is lost contains any 1 bits ... */
16200 + lsl \scratch2,\mant_lo,\scratch1 /*shift away bits that are part of
16201 + final mantissa. only part that goes
16202 + to scratch2 are bits that will be lost */
16203 +
16204 + /* ... and now to the actual shift */
16205 + lsl \scratch1,\mant_hi,\scratch1 /* get bits from msw destined for lsw*/
16206 + lsr \mant_lo,\mant_lo,\shift_count /* shift down lsw of mantissa */
16207 + lsr \mant_hi,\mant_hi,\shift_count /* shift down msw of mantissa */
16208 + or \mant_lo,\scratch1 /* combine these bits with prepared lsw*/
16209 + rjmp 71f
16210 +
16211 + /* large (>=32) shift amount, only lsw will have bits left after shift.
16212 + note that shift operations will use ((shift count) mod 32) so
16213 + we do not need to subtract 32 from shift count. */
16214 +70:
16215 + /* first remember whether part that is lost contains any 1 bits ... */
16216 + lsl \scratch2,\mant_hi,\scratch1 /* save all lost bits from msw */
16217 + or \scratch2,\mant_lo /* also save lost bits (all) from lsw
16218 + now scratch2<>0 if we lose any bits */
16219 +
16220 + /* ... and now to the actual shift */
16221 + mov \mant_lo,\mant_hi /* msw -> lsw (i.e. "shift 32 first")*/
16222 + mov \mant_hi,0 /* clear msw */
16223 + lsr \mant_lo,\mant_lo,\shift_count /* make rest of shift inside lsw*/
16224 +
16225 +71:
16226 + cp.w \scratch2,0 /* if any '1' bit in part we lost ...*/
16227 + breq 70f
16228 +
16229 + sbr \mant_lo,0 /* ... we need to set sticky bit*/
16230 +70:
16231 +.endm
16232 +
16233 +/* Unpack exponent and mantissa from the double number
16234 + stored in [df_hi,df_lo]. The exponent is stored in [exp]
16235 + while the mantissa is stored in [df_hi,df_lo]. */
16236 +
16237 +.macro unpack_df exp, df_lo, df_hi
16238 + lsr \exp, \df_hi,21 /* Extract exponent */
16239 + lsl \df_hi,10 /* Get mantissa */
16240 + or \df_hi,\df_hi,\df_lo>>21
16241 + lsl \df_lo,11
16242 +
16243 + neg \exp /* Fix implicit bit */
16244 + bst \df_hi,31
16245 + subeq \exp,1
16246 + neg \exp /* negate back exponent */
16247 + .endm
16248 +
16249 +/* Unpack exponent and mantissa from the single float number
16250 + stored in [sf]. The exponent is stored in [exp]
16251 + while the mantissa is stored in [sf]. */
16252 +.macro unpack_sf exp, sf
16253 + lsr \exp, \sf, 24
16254 + brne 80f
16255 + /* Fix subnormal number */
16256 + lsl \sf,7
16257 + clz \exp,\sf
16258 + lsl \sf,\sf,\exp
16259 + rsub \exp,\exp,1
16260 + rjmp 81f
16261 +80:
16262 + lsl \sf,7
16263 + sbr \sf, 31 /*Implicit bit*/
16264 +81:
16265 +.endm
16266 +
16267 +
16268 +
16269 +/* Pack a single float number stored in [mant] and [exp]
16270 + into a single float number in [sf] */
16271 +.macro pack_sf sf, exp, mant
16272 + bld \mant,31 /* implicit bit to z */
16273 + subne \exp,1 /* if subnormal (implicit bit 0)
16274 + adjust exponent to storage format */
16275 +
16276 + lsr \sf, \mant, 7
16277 + bfins \sf, \exp, 24, 8
16278 +.endm
16279 +
16280 +/* Pack exponent [exp] and mantissa [mant_hi, mant_lo]
16281 + into [df_hi, df_lo]. [df_hi] is shifted
16282 + one bit up so the sign bit can be shifted into it */
16283 +
16284 +.macro pack_df exp, mant_lo, mant_hi, df_lo, df_hi
16285 + bld \mant_hi,31 /* implicit bit to z */
16286 + subne \exp,1 /* if subnormal (implicit bit 0)
16287 + adjust exponent to storage format */
16288 +
16289 + lsr \mant_lo,11 /* shift back lsw */
16290 + or \df_lo,\mant_lo,\mant_hi<<21 /* combine with low bits from msw */
16291 + lsl \mant_hi,1 /* get rid of implicit bit */
16292 + lsr \mant_hi,11 /* shift back msw except for one step*/
16293 + or \df_hi,\mant_hi,\exp<<21 /* combine msw with exponent */
16294 +.endm
16295 +
16296 +/* Normalize single float number stored in [mant] and [exp]
16297 + using scratch register [scratch] */
16298 +.macro normalize_sf exp, mant, scratch
16299 + /* Adjust exponent and mantissa */
16300 + clz \scratch, \mant
16301 + sub \exp, \scratch
16302 + lsl \mant, \mant, \scratch
16303 +.endm
16304 +
16305 +/* Normalize the exponent and mantissa pair stored
16306 + in [mant_hi,mant_lo] and [exp]. Needs two scratch
16307 + registers [scratch1] and [scratch2]. */
16308 +.macro normalize_df exp, mant_lo, mant_hi, scratch1, scratch2
16309 + clz \scratch1,\mant_hi /* Check if we have zeros in high bits */
16310 + breq 80f /* No need for scaling if no zeros in high bits */
16311 + brcs 81f /* Check for all zeros */
16312 +
16313 + /* shift amount is smaller than 32, and involves both msw and lsw*/
16314 + rsub \scratch2,\scratch1,32 /* shift mantissa */
16315 + lsl \mant_hi,\mant_hi,\scratch1
16316 + lsr \scratch2,\mant_lo,\scratch2
16317 + or \mant_hi,\scratch2
16318 + lsl \mant_lo,\mant_lo,\scratch1
16319 + sub \exp,\scratch1 /* adjust exponent */
16320 + rjmp 80f /* Finished */
16321 +81:
16322 + /* shift amount is greater than 32 */
16323 + clz \scratch1,\mant_lo /* shift mantissa */
16324 + movcs \scratch1, 0
16325 + subcc \scratch1,-32
16326 + mov \mant_hi,\mant_lo
16327 + lsl \mant_hi,\mant_hi,\scratch1
16328 + mov \mant_lo,0
16329 + sub \exp,\scratch1 /* adjust exponent */
16330 +80:
16331 +.endm
16332 +
16333 +
16334 +/* Fast but approximate multiply of two 64-bit numbers to give a 64 bit result.
16335 + The multiplication of [al]x[bl] is discarded.
16336 + Operands in [ah], [al], [bh], [bl].
16337 + Scratch registers in [sh], [sl].
16338 + Returns results in registers [rh], [rl].*/
16339 +.macro mul_approx_df ah, al, bh, bl, rh, rl, sh, sl
16340 + mulu.d \sl, \ah, \bl
16341 + macu.d \sl, \al, \bh
16342 + mulu.d \rl, \ah, \bh
16343 + add \rl, \sh
16344 + acr \rh
16345 +.endm
16346 +
16347 +
16348 +
16349 +
16350 +#ifdef L_avr32_f64_mul
16351 + .align 2
16352 + .global __avr32_f64_mul
16353 + .type __avr32_f64_mul,@function
16354 +
16355 +
16356 +__avr32_f64_mul:
16357 + or r12, r10, r11 << 1
16358 + breq __avr32_f64_mul_op1_zero
16359 +
16360 + stm --sp, r5,r6,r7,lr
16361 + /* op1 in {r11,r10}*/
16362 + /* op2 in {r9,r8}*/
16363 + eor lr, r11, r9 /* MSB(lr) = Sign(op1) ^ Sign(op2) */
16364 +
16365 + /* Unpack op1 */
16366 + /* exp: r7 */
16367 + /* sf: r11, r10 */
16368 + lsr r7, r11, 20 /* Extract exponent */
16369 +
16370 + lsl r11, 11 /* Extract mantissa, leave room for implicit bit */
16371 + or r11, r11, r10>>21
16372 + lsl r10, 11
16373 + sbr r11, 31 /* Insert implicit bit */
16374 +
16375 + cbr r7, 11 /* Clear sign bit */
16376 + /* Check if normalization is needed */
16377 + breq __avr32_f64_mul_op1_subnormal /*If number is subnormal, normalize it */
16378 +
16379 +22:
16380 + /* Unpack op2 */
16381 + /* exp: r6 */
16382 + /* sf: r9, r8 */
16383 + lsr r6, r9, 20 /* Extract exponent */
16384 +
16385 + lsl r9, 11 /* Extract mantissa, leave room for implicit bit */
16386 + or r9, r9, r8>>21
16387 + lsl r8, 11
16388 + sbr r9, 31 /* Insert implicit bit */
16389 +
16390 + cbr r6, 11 /* Clear sign bit */
16391 + /* Check if normalization is needed */
16392 + breq __avr32_f64_mul_op2_subnormal /*If number is subnormal, normalize it */
16393 +23:
16394 +
16395 + /* Check if any operands are NaN or INF */
16396 + cp r7, 0x7ff
16397 + breq __avr32_f64_mul_op_nan_or_inf /* Check op1 for NaN or Inf */
16398 + cp r6, 0x7ff
16399 + breq __avr32_f64_mul_op_nan_or_inf /* Check op2 for NaN or Inf */
16400 +
16401 +
16402 + /* Calculate new exponent in r12*/
16403 + add r12, r7, r6
16404 + sub r12, (1023-1)
16405 +
16406 + /* Do the multiplication using approximate calculation.
16407 + Place result in r11, r10. Use r7, r6 as scratch registers */
16408 + mul_approx_df r11 /*ah*/, r10 /*al*/, r9 /*bh*/, r8 /*bl*/, r11 /*rh*/, r10 /*rl*/, r7 /*sh*/, r6 /*sl*/
16409 +
16410 + /* Check if result is zero */
16411 + breq __avr32_f64_mul_res_subnormal
16412 +
16413 + /* Adjust exponent and mantissa */
16414 + /* [r12]:exp, [r11, r10]:mant, [r9,r8,r7]:scratch*/
16415 + /* Mantissa may be of the format 0.xxxx or 1.xxxx. */
16416 + /* In the first case, shift one pos to left.*/
16417 + sub r9, r12, 1
16418 + mov r8, r11
16419 + lsl r7, r10, 1
16420 + rol r8
16421 + bld r11, 31
16422 + movne r12, r9
16423 + movne r11, r8
16424 + movne r10, r7
16425 + cp r12, 0
16426 + breq __avr32_f64_mul_res_subnormal /*Result was subnormal. Flush-to-zero and return zero*/
16427 +
16428 + /* Check for Inf. */
16429 + cp.w r12, 0x7ff
16430 + brge __avr32_f64_mul_res_inf
16431 +
16432 + /* Result was not subnormal. Perform rounding. */
16433 + /* Because of performance optimization, we have no sticky bit, */
16434 + /* so round-to-even won't work as specified in the IEEE standard.*/
16435 + /* [r12]:exp, [r11, r10]:mant */
16436 + /* Mantissa is in 0.64 format. Round by adding 1<<(64-(52+2))=1<<10*/
16437 + /* That is, 1 in the MSB of the part that will be discarded in final packing.*/
16438 + mov r9, (1<<10)
16439 + add r10, r9
16440 + acr r11
16441 + /* Adjust exponent if we overflowed.*/
16442 + subcs r12, -1
16443 +
16444 +
16445 + /* Pack final result*/
16446 + /* Input: [r12]:exp, [r11, r10]:mant */
16447 + /* Result in [r11,r10] */
16448 + /* Insert mantissa */
16449 + cbr r11, 31 /*Clear implicit bit*/
16450 + lsr r10, 11
16451 + or r10, r10, r11<<21
16452 + lsr r11, 11
16453 + /* Insert exponent and sign bit*/
16454 + or r11, r11, r12<<20
16455 + bld lr, 31
16456 + bst r11, 31
16457 +
16458 + /* Return result in [r11,r10] */
16459 + ldm sp++, r5, r6, r7,pc
16460 +
16461 +
16462 +__avr32_f64_mul_op1_subnormal:
16463 + cbr r11, 31 /* Clear implicit bit. */
16464 + normalize_df r7 /*exp*/, r10, r11 /*Mantissa*/, r5, r12 /*scratch*/
16465 + rjmp 22b
16466 +
16467 +__avr32_f64_mul_op2_subnormal:
16468 + cbr r9, 31 /* Clear implicit bit. */
16469 + normalize_df r6 /*exp*/, r8, r9 /*Mantissa*/, r5, r12 /*scratch*/
16470 + rjmp 23b
16471 +
16472 +
16473 +__avr32_f64_mul_op_nan_or_inf:
16474 + /* Same code for OP1 and OP2*/
16475 + /* Since we are here, at least one of the OPs were NaN or INF*/
16476 + /* Shift out implicit bit of both operands' mantissa */
16477 + lsl r11, 1
16478 + lsl r9, 1
16479 + /* Merge the regs in each operand to check for zero*/
16480 + or r11, r10 /* op1 */
16481 + or r9, r8 /* op2 */
16482 + /* Check if op1 is NaN or INF */
16483 + cp r7, 0x7ff
16484 + brne __avr32_f64_mul_op1_not_naninf
16485 + /* op1 was NaN or INF.*/
16486 + cp r11, 0
16487 + brne __avr32_f64_mul_res_nan /* op1 was NaN. Result will be NaN*/
16488 + /*op1 was INF. check if op2 is NaN or INF*/
16489 + cp r6, 0x7ff
16490 + brne __avr32_f64_mul_res_inf /*op1 was INF, op2 was neither NaN nor INF*/
16491 + /* op1 is INF, op2 is either NaN or INF*/
16492 + cp r9, 0
16493 + breq __avr32_f64_mul_res_inf /*op2 was also INF*/
16494 + rjmp __avr32_f64_mul_res_nan /*op2 was NaN*/
16495 +
16496 +__avr32_f64_mul_op1_not_naninf:
16497 + /* op1 was not NaN nor INF. Then op2 must be NaN or INF*/
16498 + cp r9, 0
16499 + breq __avr32_f64_mul_res_inf /*op2 was INF, return INF*/
16500 + rjmp __avr32_f64_mul_res_nan /*else return NaN*/
16501 +
16502 +__avr32_f64_mul_res_subnormal:/* Multiply result was subnormal. Return zero. */
16503 + mov r11, lr /*Get correct sign*/
16504 + andh r11, 0x8000, COH
16505 + mov r10, 0
16506 + ldm sp++, r5, r6, r7,pc
16507 +
16508 +__avr32_f64_mul_res_nan: /* Return NaN. */
16509 + mov r11, -1
16510 + mov r10, -1
16511 + ldm sp++, r5, r6, r7,pc
16512 +
16513 +__avr32_f64_mul_res_inf: /* Return INF. */
16514 + mov r11, 0
16515 + orh r11, 0x7ff0
16516 + bld lr, 31
16517 + bst r11, 31
16518 + mov r10, 0
16519 + ldm sp++, r5, r6, r7,pc
16520 +
16521 +__avr32_f64_mul_op1_zero:
16522 + /* Get sign */
16523 + eor r11, r11, r9
16524 + andh r11, 0x8000, COH
16525 + /* Check if op2 is Inf or NaN. */
16526 + bfextu r12, r9, 20, 11
16527 + cp.w r12, 0x7ff
16528 + retne r12 /* Return 0.0 */
16529 + /* Return NaN */
16530 + mov r10, -1
16531 + mov r11, -1
16532 + ret r12
16533 +
16534 +
16535 +
16536 +#endif
16537 +
16538 +
16539 +#if defined(L_avr32_f64_addsub) || defined(L_avr32_f64_addsub_fast)
16540 + .align 2
16541 +
16542 +__avr32_f64_sub_from_add:
16543 + /* Switch sign on op2 */
16544 + eorh r9, 0x8000
16545 +
16546 +#if defined(L_avr32_f64_addsub_fast)
16547 + .global __avr32_f64_sub_fast
16548 + .type __avr32_f64_sub_fast,@function
16549 +__avr32_f64_sub_fast:
16550 +#else
16551 + .global __avr32_f64_sub
16552 + .type __avr32_f64_sub,@function
16553 +__avr32_f64_sub:
16554 +#endif
16555 +
16556 + /* op1 in {r11,r10}*/
16557 + /* op2 in {r9,r8}*/
16558 +
16559 +#if defined(L_avr32_f64_addsub_fast)
16560 + /* If op2 is zero just return op1 */
16561 + or r12, r8, r9 << 1
16562 + reteq r12
16563 +#endif
16564 +
16565 + /* Check signs */
16566 + eor r12, r11, r9
16567 + /* Different signs, use addition. */
16568 + brmi __avr32_f64_add_from_sub
16569 +
16570 + stm --sp, r5, r6, r7, lr
16571 +
16572 + /* Get sign of op1 into r12 */
16573 + mov r12, r11
16574 + andh r12, 0x8000, COH
16575 +
16576 + /* Remove sign from operands */
16577 + cbr r11, 31
16578 + cbr r9, 31
16579 +
16580 + /* Put the number with the largest exponent in [r11, r10]
16581 + and the number with the smallest exponent in [r9, r8] */
16582 + cp r11, r9
16583 + brhs 1f /* Skip swap if operands already correctly ordered*/
16584 + /* Operands were not correctly ordered, swap them*/
16585 + mov r7, r11
16586 + mov r11, r9
16587 + mov r9, r7
16588 + mov r7, r10
16589 + mov r10, r8
16590 + mov r8, r7
16591 + eorh r12, 0x8000 /* Invert sign in r12*/
16592 +1:
16593 + /* Unpack largest operand - opH */
16594 + /* exp: r7 */
16595 + /* sf: r11, r10 */
16596 + lsr r7, r11, 20 /* Extract exponent */
16597 + cbr r7, 11 /* Clear sign bit */
16598 + lsl r11, 11 /* Extract mantissa, leave room for implicit bit */
16599 + or r11, r11, r10>>21
16600 + lsl r10, 11
16601 + sbr r11, 31 /* Insert implicit bit */
16602 +
16603 +
16604 + /* Unpack smallest operand - opL */
16605 + /* exp: r6 */
16606 + /* sf: r9, r8 */
16607 + lsr r6, r9, 20 /* Extract exponent */
16608 + cbr r6, 11 /* Clear sign bit */
16609 + breq __avr32_f64_sub_opL_subnormal /* If either zero or subnormal */
16610 + lsl r9, 11 /* Extract mantissa, leave room for implicit bit */
16611 + or r9, r9, r8>>21
16612 + lsl r8, 11
16613 + sbr r9, 31 /* Insert implicit bit */
16614 +
16615 +
16616 +__avr32_f64_sub_opL_subnormal_done:
16617 + /* opH is NaN or Inf. */
16618 + cp.w r7, 0x7ff
16619 + breq __avr32_f64_sub_opH_nan_or_inf
16620 +
16621 + /* Get shift amount to scale mantissa of op2. */
16622 + rsub r6, r7
16623 + breq __avr32_f64_sub_shift_done /* No need to shift, exponents are equal*/
16624 +
16625 + /* Scale mantissa [r9, r8] with amount [r6].
16626 + Uses scratch registers [r5] and [lr].
16627 + In IEEE mode:Must not forget the sticky bits we intend to shift out. */
16628 +
16629 + rsub r5,r6,32 /* get (32 - shift count)
16630 + (if shift count > 32 we get a
16631 + negative value, but that will
16632 + work as well in the code below.) */
16633 +
16634 + cp.w r6,32 /* handle shifts >= 32 separately */
16635 + brhs __avr32_f64_sub_longshift
16636 +
16637 + /* small (<32) shift amount, both words are part of the shift
16638 + first remember whether part that is lost contains any 1 bits ... */
16639 + lsl lr,r8,r5 /* shift away bits that are part of
16640 + final mantissa. only part that goes
16641 + to lr are bits that will be lost */
16642 +
16643 + /* ... and now to the actual shift */
16644 + lsl r5,r9,r5 /* get bits from msw destined for lsw*/
16645 + lsr r8,r8,r6 /* shift down lsw of mantissa */
16646 + lsr r9,r9,r6 /* shift down msw of mantissa */
16647 + or r8,r5 /* combine these bits with prepared lsw*/
16648 +#if defined(L_avr32_f64_addsub)
16649 + cp.w lr,0 /* if any '1' bit in part we lost ...*/
16650 + srne lr
16651 + or r8, lr /* ... we need to set sticky bit*/
16652 +#endif
16653 +
16654 +__avr32_f64_sub_shift_done:
16655 + /* Now subtract the mantissas. */
16656 + sub r10, r8
16657 + sbc r11, r11, r9
16658 +
16659 + /* Normalize the exponent and mantissa pair stored in
16660 + [r11,r10] and exponent in [r7]. Needs two scratch registers [r6] and [lr]. */
16661 + clz r6,r11 /* Check if we have zeros in high bits */
16662 + breq __avr32_f64_sub_longnormalize_done /* No need for scaling if no zeros in high bits */
16663 + brcs __avr32_f64_sub_longnormalize
16664 +
16665 + /* shift amount is smaller than 32, and involves both msw and lsw*/
16666 + rsub lr,r6,32 /* shift mantissa */
16667 + lsl r11,r11,r6
16668 + lsr lr,r10,lr
16669 + or r11,lr
16670 + lsl r10,r10,r6
16671 + sub r7,r6 /* adjust exponent */
16672 + brle __avr32_f64_sub_subnormal_result
16673 +
16674 +__avr32_f64_sub_longnormalize_done:
16675 +
16676 +#if defined(L_avr32_f64_addsub)
16677 + /* Insert the bits we will remove from the mantissa r9[31:21] */
16678 + lsl r9, r10, (32 - 11)
16679 +#else
16680 + /* Keep the last bit shifted out. */
16681 + bfextu r9, r10, 10, 1
16682 +#endif
16683 +
16684 + /* Pack final result*/
16685 + /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */
16686 + /* Result in [r11,r10] */
16687 + /* Insert mantissa */
16688 + cbr r11, 31 /*Clear implicit bit*/
16689 + lsr r10, 11
16690 + or r10, r10, r11<<21
16691 + lsr r11, 11
16692 + /* Insert exponent and sign bit*/
16693 + or r11, r11, r7<<20
16694 + bld r12, 31
16695 + bst r11, 31
16696 +
16697 + /* Round */
16698 +__avr32_f64_sub_round:
16699 +#if defined(L_avr32_f64_addsub)
16700 + mov r7, 0
16701 + sbr r7, 31
16702 + bld r10, 0
16703 + subne r7, -1
16704 +
16705 + cp.w r9, r7
16706 + srhs r9
16707 +#endif
16708 + add r10, r9
16709 + acr r11
16710 +
16711 + /* Return result in [r11,r10] */
16712 + ldm sp++, r5, r6, r7,pc
16713 +
16714 +
16715 +
16716 +__avr32_f64_sub_opL_subnormal:
16717 + /* Extract the of mantissa */
16718 + lsl r9, 11 /* Extract mantissa, leave room for implicit bit */
16719 + or r9, r9, r8>>21
16720 + lsl r8, 11
16721 +
16722 + /* Set exponent to 1 if we do not have a zero. */
16723 + or lr, r9, r8
16724 + movne r6,1
16725 +
16726 + /* Check if opH is also subnormal. If so, clear implicit bit in r11*/
16727 + rsub lr, r7, 0
16728 + moveq r7,1
16729 + bst r11, 31
16730 +
16731 + /* Check if op1 is zero, if so set exponent to 0. */
16732 + or lr, r11, r10
16733 + moveq r7,0
16734 +
16735 + rjmp __avr32_f64_sub_opL_subnormal_done
16736 +
16737 +__avr32_f64_sub_opH_nan_or_inf:
16738 + /* Check if opH is NaN, if so return NaN */
16739 + cbr r11, 31
16740 + or lr, r11, r10
16741 + brne __avr32_f64_sub_return_nan
16742 +
16743 + /* opH is Inf. */
16744 + /* Check if opL is Inf. or NaN */
16745 + cp.w r6, 0x7ff
16746 + breq __avr32_f64_sub_opL_nan_or_inf
16747 + ldm sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */
16748 +__avr32_f64_sub_opL_nan_or_inf:
16749 + cbr r9, 31
16750 + or lr, r9, r8
16751 + brne __avr32_f64_sub_return_nan
16752 + mov r10, 0 /* Generate Inf in r11, r10 */
16753 + mov r11, 0
16754 + orh r11, 0x7ff0
16755 + ldm sp++, r5, r6, r7, pc/* opL Inf, return Inf */
16756 +__avr32_f64_sub_return_nan:
16757 + mov r10, -1 /* Generate NaN in r11, r10 */
16758 + mov r11, -1
16759 + ldm sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */
16760 +
16761 +
16762 +__avr32_f64_sub_subnormal_result:
16763 + /* Just flush subnormals to zero. */
16764 + mov r10, 0
16765 + mov r11, 0
16766 + ldm sp++, r5, r6, r7, pc
16767 +
16768 +
16769 +__avr32_f64_sub_longshift:
16770 + /* large (>=32) shift amount, only lsw will have bits left after shift.
16771 + note that shift operations will use ((shift count=r6) mod 32) so
16772 + we do not need to subtract 32 from shift count. */
16773 + /* Saturate the shift amount to 63. If the amount
16774 + is any larger op2 is insignificant. */
16775 + satu r6 >> 0, 6
16776 +#if defined(L_avr32_f64_addsub)
16777 + /* first remember whether part that is lost contains any 1 bits ... */
16778 + lsl lr,r9,r5 /* save all lost bits from msw */
16779 + or lr,r8 /* also save lost bits (all) from lsw
16780 + now lr != 0 if we lose any bits */
16781 +#endif
16782 + /* ... and now to the actual shift */
16783 + mov r8,r9 /* msw -> lsw (i.e. "shift 32 first")*/
16784 + mov r9,0 /* clear msw */
16785 + lsr r8,r8,r6 /* make rest of shift inside lsw*/
16786 +#if defined(L_avr32_f64_addsub)
16787 + cp.w lr,0 /* if any '1' bit in part we lost ...*/
16788 + sreq lr
16789 + or r8, lr /* ... we need to set sticky bit*/
16790 +#endif
16791 + rjmp __avr32_f64_sub_shift_done
16792 +
16793 +__avr32_f64_sub_longnormalize:
16794 + /* shift amount is greater than 32 */
16795 + clz r6,r10 /* shift mantissa */
16796 + /* If the resulting mantissa is zero the result is
16797 + zero so force exponent to zero. */
16798 + movcs r7, 0
16799 + movcs r6, 0
16800 + subcc r6,-32
16801 + mov r11,r10
16802 + lsl r11,r11,r6
16803 + mov r10,0
16804 + sub r7,r6 /* adjust exponent */
16805 + brle __avr32_f64_sub_subnormal_result
16806 + rjmp __avr32_f64_sub_longnormalize_done
16807 +
16808 +
16809 +
16810 + .align 2
16811 +__avr32_f64_add_from_sub:
16812 + /* Switch sign on op2 */
16813 + eorh r9, 0x8000
16814 +
16815 +#if defined(L_avr32_f64_addsub_fast)
16816 + .global __avr32_f64_add_fast
16817 + .type __avr32_f64_add_fast,@function
16818 +__avr32_f64_add_fast:
16819 +#else
16820 + .global __avr32_f64_add
16821 + .type __avr32_f64_add,@function
16822 +__avr32_f64_add:
16823 +#endif
16824 +
16825 + /* op1 in {r11,r10}*/
16826 + /* op2 in {r9,r8}*/
16827 +
16828 +#if defined(L_avr32_f64_addsub_fast)
16829 + /* If op2 is zero just return op1 */
16830 + or r12, r8, r9 << 1
16831 + reteq r12
16832 +#endif
16833 +
16834 + /* Check signs */
16835 + eor r12, r11, r9
16836 + /* Different signs, use subtraction. */
16837 + brmi __avr32_f64_sub_from_add
16838 +
16839 + stm --sp, r5, r6, r7, lr
16840 +
16841 + /* Get sign of op1 into r12 */
16842 + mov r12, r11
16843 + andh r12, 0x8000, COH
16844 +
16845 + /* Remove sign from operands */
16846 + cbr r11, 31
16847 + cbr r9, 31
16848 +
16849 + /* Put the number with the largest exponent in [r11, r10]
16850 + and the number with the smallest exponent in [r9, r8] */
16851 + cp r11, r9
16852 + brhs 1f /* Skip swap if operands already correctly ordered*/
16853 + /* Operands were not correctly ordered, swap them*/
16854 + mov r7, r11
16855 + mov r11, r9
16856 + mov r9, r7
16857 + mov r7, r10
16858 + mov r10, r8
16859 + mov r8, r7
16860 +1:
16861 + /* Unpack largest operand - opH */
16862 + /* exp: r7 */
16863 + /* sf: r11, r10 */
16864 + lsr r7, r11, 20 /* Extract exponent */
16865 + cbr r7, 11 /* Clear sign bit */
16866 + lsl r11, 11 /* Extract mantissa, leave room for implicit bit */
16867 + or r11, r11, r10>>21
16868 + lsl r10, 11
16869 + sbr r11, 31 /* Insert implicit bit */
16870 +
16871 +
16872 + /* Unpack smallest operand - opL */
16873 + /* exp: r6 */
16874 + /* sf: r9, r8 */
16875 + lsr r6, r9, 20 /* Extract exponent */
16876 + cbr r6, 11 /* Clear sign bit */
16877 + breq __avr32_f64_add_opL_subnormal /* If either zero or subnormal */
16878 + lsl r9, 11 /* Extract mantissa, leave room for implicit bit */
16879 + or r9, r9, r8>>21
16880 + lsl r8, 11
16881 + sbr r9, 31 /* Insert implicit bit */
16882 +
16883 +
16884 +__avr32_f64_add_opL_subnormal_done:
16885 + /* opH is NaN or Inf. */
16886 + cp.w r7, 0x7ff
16887 + breq __avr32_f64_add_opH_nan_or_inf
16888 +
16889 + /* Get shift amount to scale mantissa of op2. */
16890 + rsub r6, r7
16891 + breq __avr32_f64_add_shift_done /* No need to shift, exponents are equal*/
16892 +
16893 + /* Scale mantissa [r9, r8] with amount [r6].
16894 + Uses scratch registers [r5] and [lr].
16895 + In IEEE mode:Must not forget the sticky bits we intend to shift out. */
16896 + rsub r5,r6,32 /* get (32 - shift count)
16897 + (if shift count > 32 we get a
16898 + negative value, but that will
16899 + work as well in the code below.) */
16900 +
16901 + cp.w r6,32 /* handle shifts >= 32 separately */
16902 + brhs __avr32_f64_add_longshift
16903 +
16904 + /* small (<32) shift amount, both words are part of the shift
16905 + first remember whether part that is lost contains any 1 bits ... */
16906 + lsl lr,r8,r5 /* shift away bits that are part of
16907 + final mantissa. only part that goes
16908 + to lr are bits that will be lost */
16909 +
16910 + /* ... and now to the actual shift */
16911 + lsl r5,r9,r5 /* get bits from msw destined for lsw*/
16912 + lsr r8,r8,r6 /* shift down lsw of mantissa */
16913 + lsr r9,r9,r6 /* shift down msw of mantissa */
16914 + or r8,r5 /* combine these bits with prepared lsw*/
16915 +#if defined(L_avr32_f64_addsub)
16916 + cp.w lr,0 /* if any '1' bit in part we lost ...*/
16917 + srne lr
16918 + or r8, lr /* ... we need to set sticky bit*/
16919 +#endif
16920 +
16921 +__avr32_f64_add_shift_done:
16922 + /* Now add the mantissas. */
16923 + add r10, r8
16924 + adc r11, r11, r9
16925 +
16926 + /* Check if we overflowed. */
16927 + brcs __avr32_f64_add_res_of
16928 +
16929 +__avr32_f64_add_res_of_done:
16930 +
16931 +#if defined(L_avr32_f64_addsub)
16932 + /* Insert the bits we will remove from the mantissa r9[31:21] */
16933 + lsl r9, r10, (32 - 11)
16934 +#else
16935 + /* Keep the last bit shifted out. */
16936 + bfextu r9, r10, 10, 1
16937 +#endif
16938 +
16939 + /* Pack final result*/
16940 + /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */
16941 + /* Result in [r11,r10] */
16942 + /* Insert mantissa */
16943 + cbr r11, 31 /*Clear implicit bit*/
16944 + lsr r10, 11
16945 + or r10, r10, r11<<21
16946 + lsr r11, 11
16947 + /* Insert exponent and sign bit*/
16948 + or r11, r11, r7<<20
16949 + bld r12, 31
16950 + bst r11, 31
16951 +
16952 + /* Round */
16953 +__avr32_f64_add_round:
16954 +#if defined(L_avr32_f64_addsub)
16955 + mov r7, 0
16956 + sbr r7, 31
16957 + bld r10, 0
16958 + subne r7, -1
16959 +
16960 + cp.w r9, r7
16961 + srhs r9
16962 +#endif
16963 + add r10, r9
16964 + acr r11
16965 +
16966 + /* Return result in [r11,r10] */
16967 + ldm sp++, r5, r6, r7,pc
16968 +
16969 +
16970 +
16971 +__avr32_f64_add_opL_subnormal:
16972 + /* Extract the of mantissa */
16973 + lsl r9, 11 /* Extract mantissa, leave room for implicit bit */
16974 + or r9, r9, r8>>21
16975 + lsl r8, 11
16976 +
16977 + /* Set exponent to 1 if we do not have a zero. */
16978 + or lr, r9, r8
16979 + movne r6,1
16980 +
16981 + /* Check if opH is also subnormal. If so, clear implicit bit in r11*/
16982 + rsub lr, r7, 0
16983 + moveq r7,1
16984 + bst r11, 31
16985 +
16986 + /* Check if op1 is zero, if so set exponent to 0. */
16987 + or lr, r11, r10
16988 + moveq r7,0
16989 +
16990 + rjmp __avr32_f64_add_opL_subnormal_done
16991 +
16992 +__avr32_f64_add_opH_nan_or_inf:
16993 + /* Check if opH is NaN, if so return NaN */
16994 + cbr r11, 31
16995 + or lr, r11, r10
16996 + brne __avr32_f64_add_return_nan
16997 +
16998 + /* opH is Inf. */
16999 + /* Check if opL is Inf. or NaN */
17000 + cp.w r6, 0x7ff
17001 + breq __avr32_f64_add_opL_nan_or_inf
17002 + ldm sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */
17003 +__avr32_f64_add_opL_nan_or_inf:
17004 + cbr r9, 31
17005 + or lr, r9, r8
17006 + brne __avr32_f64_add_return_nan
17007 + mov r10, 0 /* Generate Inf in r11, r10 */
17008 + mov r11, 0
17009 + orh r11, 0x7ff0
17010 + ldm sp++, r5, r6, r7, pc/* opL Inf, return Inf */
17011 +__avr32_f64_add_return_nan:
17012 + mov r10, -1 /* Generate NaN in r11, r10 */
17013 + mov r11, -1
17014 + ldm sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */
17015 +
17016 +
17017 +__avr32_f64_add_longshift:
17018 + /* large (>=32) shift amount, only lsw will have bits left after shift.
17019 + note that shift operations will use ((shift count=r6) mod 32) so
17020 + we do not need to subtract 32 from shift count. */
17021 + /* Saturate the shift amount to 63. If the amount
17022 + is any larger op2 is insignificant. */
17023 + satu r6 >> 0, 6
17024 +#if defined(L_avr32_f64_addsub)
17025 + /* first remember whether part that is lost contains any 1 bits ... */
17026 + lsl lr,r9,r5 /* save all lost bits from msw */
17027 + or lr,r8 /* also save lost bits (all) from lsw
17028 + now lr != 0 if we lose any bits */
17029 +#endif
17030 + /* ... and now to the actual shift */
17031 + mov r8,r9 /* msw -> lsw (i.e. "shift 32 first")*/
17032 + mov r9,0 /* clear msw */
17033 + lsr r8,r8,r6 /* make rest of shift inside lsw*/
17034 +#if defined(L_avr32_f64_addsub)
17035 + cp.w lr,0 /* if any '1' bit in part we lost ...*/
17036 + sreq lr
17037 + or r8, lr /* ... we need to set sticky bit*/
17038 +#endif
17039 + rjmp __avr32_f64_add_shift_done
17040 +
17041 +__avr32_f64_add_res_of:
17042 + /* We overflowed. Increase exponent and shift mantissa.*/
17043 + /* [r7]:exp, [r11, r10]:mant */
17044 + ror r11
17045 + lsr r10, 1
17046 + sub r7, -1
17047 +
17048 + /* Clear mantissa to set result to Inf if the exponent is 255. */
17049 + cp.w r7, 0x7ff
17050 + moveq r10, 0
17051 + moveq r11, 0
17052 + rjmp __avr32_f64_add_res_of_done
17053 +
17054 +
17055 +#endif
17056 +
17057 +#ifdef L_avr32_f64_to_u32
17058 + /* This goes into L_fixdfsi */
17059 +#endif
17060 +
17061 +
17062 +#ifdef L_avr32_f64_to_s32
17063 + .global __avr32_f64_to_u32
17064 + .type __avr32_f64_to_u32,@function
17065 +__avr32_f64_to_u32:
17066 + cp.w r11, 0
17067 + retmi 0 /* Negative returns 0 */
17068 +
17069 + /* Fallthrough to df to signed si conversion */
17070 + .global __avr32_f64_to_s32
17071 + .type __avr32_f64_to_s32,@function
17072 +__avr32_f64_to_s32:
17073 + lsl r12,r11,1
17074 + lsr r12,21 /* extract exponent*/
17075 + sub r12,1023 /* convert to unbiased exponent.*/
17076 + retlo 0 /* too small exponent implies zero. */
17077 +
17078 +1:
17079 + rsub r12,r12,31 /* shift count = 31 - exponent */
17080 + mov r9,r11 /* save sign for later...*/
17081 + lsl r11,11 /* remove exponent and sign*/
17082 + sbr r11,31 /* add implicit bit*/
17083 + or r11,r11,r10>>21 /* get rest of bits from lsw of double */
17084 + lsr r11,r11,r12 /* shift down mantissa to final place */
17085 + lsl r9,1 /* sign -> carry */
17086 + retcc r11 /* if positive, we are done */
17087 + neg r11 /* if negative float, negate result */
17088 + ret r11
17089 +
17090 +#endif /* L_fixdfsi*/
17091 +
17092 +#ifdef L_avr32_f64_to_u64
17093 + /* Actual function is in L_fixdfdi */
17094 +#endif
17095 +
17096 +#ifdef L_avr32_f64_to_s64
17097 + .global __avr32_f64_to_u64
17098 + .type __avr32_f64_to_u64,@function
17099 +__avr32_f64_to_u64:
17100 + cp.w r11,0
17101 + /* Negative numbers return zero */
17102 + movmi r10, 0
17103 + movmi r11, 0
17104 + retmi r11
17105 +
17106 +
17107 +
17108 + /* Fallthrough */
17109 + .global __avr32_f64_to_s64
17110 + .type __avr32_f64_to_s64,@function
17111 +__avr32_f64_to_s64:
17112 + lsl r9,r11,1
17113 + lsr r9,21 /* get exponent*/
17114 + sub r9,1023 /* convert to correct range*/
17115 + /* Return zero if exponent to small */
17116 + movlo r10, 0
17117 + movlo r11, 0
17118 + retlo r11
17119 +
17120 + mov r8,r11 /* save sign for later...*/
17121 +1:
17122 + lsl r11,11 /* remove exponent */
17123 + sbr r11,31 /* add implicit bit*/
17124 + or r11,r11,r10>>21 /* get rest of bits from lsw of double*/
17125 + lsl r10,11 /* align lsw correctly as well */
17126 + rsub r9,r9,63 /* shift count = 63 - exponent */
17127 + breq 1f
17128 +
17129 + cp.w r9,32 /* is shift count more than one reg? */
17130 + brhs 0f
17131 +
17132 + mov r12,r11 /* save msw */
17133 + lsr r10,r10,r9 /* small shift count, shift down lsw */
17134 + lsr r11,r11,r9 /* small shift count, shift down msw */
17135 + rsub r9,r9,32 /* get 32-size of shifted out tail */
17136 + lsl r12,r12,r9 /* align part to move from msw to lsw */
17137 + or r10,r12 /* combine to get new lsw */
17138 + rjmp 1f
17139 +
17140 +0:
17141 + lsr r10,r11,r9 /* large shift count,only lsw get bits
17142 + note that shift count is modulo 32*/
17143 + mov r11,0 /* msw will be 0 */
17144 +
17145 +1:
17146 + lsl r8,1 /* sign -> carry */
17147 + retcc r11 /* if positive, we are done */
17148 +
17149 + neg r11 /* if negative float, negate result */
17150 + neg r10
17151 + scr r11
17152 + ret r11
17153 +
17154 +#endif
17155 +
17156 +#ifdef L_avr32_u32_to_f64
17157 + /* Code located in L_floatsidf */
17158 +#endif
17159 +
17160 +#ifdef L_avr32_s32_to_f64
17161 + .global __avr32_u32_to_f64
17162 + .type __avr32_u32_to_f64,@function
17163 +__avr32_u32_to_f64:
17164 + sub r11, r12, 0 /* Move to r11 and force Z flag to be updated */
17165 + mov r12, 0 /* always positive */
17166 + rjmp 0f /* Jump to common code for floatsidf */
17167 +
17168 + .global __avr32_s32_to_f64
17169 + .type __avr32_s32_to_f64,@function
17170 +__avr32_s32_to_f64:
17171 + mov r11, r12 /* Keep original value in r12 for sign */
17172 + abs r11 /* Absolute value if r12 */
17173 +0:
17174 + mov r10,0 /* let remaining bits be zero */
17175 + reteq r11 /* zero long will return zero float */
17176 +
17177 + pushm lr
17178 + mov r9,31+1023 /* set exponent */
17179 +
17180 + normalize_df r9 /*exp*/, r10, r11 /* mantissa */, r8, lr /* scratch */
17181 +
17182 + /* Check if a subnormal result was created */
17183 + cp.w r9, 0
17184 + brgt 0f
17185 +
17186 + adjust_subnormal_df r9 /* exp */, r10, r11 /* Mantissa */, r12 /*sign*/, r8, lr /* scratch */
17187 + popm pc
17188 +0:
17189 +
17190 + /* Round result */
17191 + round_df r9 /*exp*/, r10, r11 /* Mantissa */, r8 /*scratch*/
17192 + cp.w r9,0x7ff
17193 + brlt 0f
17194 + /*Return infinity */
17195 + mov r10, 0
17196 + mov r11, 0
17197 + orh r11, 0xffe0
17198 + rjmp __floatsidf_return_op1
17199 +
17200 +0:
17201 +
17202 + /* Pack */
17203 + pack_df r9 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/
17204 +__floatsidf_return_op1:
17205 + lsl r12,1 /* shift in sign bit */
17206 + ror r11
17207 +
17208 + popm pc
17209 +#endif
17210 +
17211 +
17212 +#ifdef L_avr32_f32_cmp_eq
17213 + .global __avr32_f32_cmp_eq
17214 + .type __avr32_f32_cmp_eq,@function
17215 +__avr32_f32_cmp_eq:
17216 + cp.w r12, r11
17217 + breq 0f
17218 + /* If not equal check for +/-0 */
17219 + /* Or together the two values and shift out the sign bit.
17220 + If the result is zero, then the two values are both zero. */
17221 + or r12, r11
17222 + lsl r12, 1
17223 + sreq r12
17224 + ret r12
17225 +0:
17226 + /* Numbers were equal. Check for NaN or Inf */
17227 + mov r11, 0
17228 + orh r11, 0xff00
17229 + lsl r12, 1
17230 + cp.w r12, r11
17231 + srls r12 /* 0 if NaN, 1 otherwise */
17232 + ret r12
17233 +#endif
17234 +
17235 +#if defined(L_avr32_f32_cmp_ge) || defined(L_avr32_f32_cmp_lt)
17236 +#ifdef L_avr32_f32_cmp_ge
17237 + .global __avr32_f32_cmp_ge
17238 + .type __avr32_f32_cmp_ge,@function
17239 +__avr32_f32_cmp_ge:
17240 +#endif
17241 +#ifdef L_avr32_f32_cmp_lt
17242 + .global __avr32_f32_cmp_lt
17243 + .type __avr32_f32_cmp_lt,@function
17244 +__avr32_f32_cmp_lt:
17245 +#endif
17246 + lsl r10, r12, 1 /* Remove sign bits */
17247 + lsl r9, r11, 1
17248 + mov r8, 0
17249 + orh r8, 0xff00
17250 + cp.w r10, r8
17251 + rethi 0 /* Op0 is NaN */
17252 + cp.w r9, r8
17253 + rethi 0 /* Op1 is Nan */
17254 +
17255 + eor r8, r11, r12
17256 + bld r12, 31
17257 +#ifdef L_avr32_f32_cmp_ge
17258 + srcc r8 /* Set result to true if op0 is positive*/
17259 +#endif
17260 +#ifdef L_avr32_f32_cmp_lt
17261 + srcs r8 /* Set result to true if op0 is negative*/
17262 +#endif
17263 + retmi r8 /* Return if signs are different */
17264 + brcs 0f /* Both signs negative? */
17265 +
17266 + /* Both signs positive */
17267 + cp.w r12, r11
17268 +#ifdef L_avr32_f32_cmp_ge
17269 + srhs r12
17270 +#endif
17271 +#ifdef L_avr32_f32_cmp_lt
17272 + srlo r12
17273 +#endif
17274 + retal r12
17275 +0:
17276 + /* Both signs negative */
17277 + cp.w r11, r12
17278 +#ifdef L_avr32_f32_cmp_ge
17279 + srhs r12
17280 +#endif
17281 +#ifdef L_avr32_f32_cmp_lt
17282 + srlo r12
17283 +#endif
17284 + retal r12
17285 +#endif
17286 +
17287 +
17288 +#ifdef L_avr32_f64_cmp_eq
17289 + .global __avr32_f64_cmp_eq
17290 + .type __avr32_f64_cmp_eq,@function
17291 +__avr32_f64_cmp_eq:
17292 + cp.w r10,r8
17293 + cpc r11,r9
17294 + breq 0f
17295 +
17296 + /* Args were not equal*/
17297 + /* Both args could be zero with different sign bits */
17298 + lsl r11,1 /* get rid of sign bits */
17299 + lsl r9,1
17300 + or r11,r10 /* Check if all bits are zero */
17301 + or r11,r9
17302 + or r11,r8
17303 + sreq r12 /* If all zeros the arguments are equal
17304 + so return 1 else return 0 */
17305 + ret r12
17306 +0:
17307 + /* check for NaN */
17308 + lsl r11,1
17309 + mov r12, 0
17310 + orh r12, 0xffe0
17311 + cp.w r10,0
17312 + cpc r11,r12 /* check if nan or inf */
17313 + srls r12 /* If Arg is NaN return 0 else 1*/
17314 + ret r12 /* Return */
17315 +
17316 +#endif
17317 +
17318 +
17319 +#if defined(L_avr32_f64_cmp_ge) || defined(L_avr32_f64_cmp_lt)
17320 +
17321 +#ifdef L_avr32_f64_cmp_ge
17322 + .global __avr32_f64_cmp_ge
17323 + .type __avr32_f64_cmp_ge,@function
17324 +__avr32_f64_cmp_ge:
17325 +#endif
17326 +#ifdef L_avr32_f64_cmp_lt
17327 + .global __avr32_f64_cmp_lt
17328 + .type __avr32_f64_cmp_lt,@function
17329 +__avr32_f64_cmp_lt:
17330 +#endif
17331 +
17332 + /* compare magnitude of op1 and op2 */
17333 + pushm lr
17334 +
17335 + lsl r11,1 /* Remove sign bit of op1 */
17336 + srcs lr /* Sign op1 to lsb of lr*/
17337 + lsl r9,1 /* Remove sign bit of op2 */
17338 + rol lr /* Sign op2 to lsb of lr, sign bit op1 bit 1 of lr*/
17339 +
17340 + /* Check for Nan */
17341 + mov r12, 0
17342 + orh r12, 0xffe0
17343 + cp.w r10,0
17344 + cpc r11,r12
17345 + movhi r12, 0 /* Return false for NaN */
17346 + brhi 0f /* We have NaN */
17347 + cp.w r8,0
17348 + cpc r9,r12
17349 + movhi r12, 0 /* Return false for NaN */
17350 + brhi 0f /* We have NaN */
17351 +
17352 + cp.w lr,3 /* both operands negative ?*/
17353 + breq 1f
17354 +
17355 + cp.w lr,1 /* both operands positive? */
17356 + brlo 2f
17357 +
17358 + /* Different signs. If sign of op1 is negative the difference
17359 + between op1 and op2 will always be negative, and if op1 is
17360 + positive the difference will always be positive */
17361 +#ifdef L_avr32_f64_cmp_ge
17362 + sreq r12
17363 +#endif
17364 +#ifdef L_avr32_f64_cmp_lt
17365 + srne r12
17366 +#endif
17367 + popm pc
17368 +
17369 +
17370 +2:
17371 + /* Both operands positive. Just compute the difference */
17372 + cp.w r10,r8
17373 + cpc r11,r9
17374 +#ifdef L_avr32_f64_cmp_ge
17375 + srhs r12
17376 +#endif
17377 +#ifdef L_avr32_f64_cmp_lt
17378 + srlo r12
17379 +#endif
17380 + popm pc
17381 +
17382 +1:
17383 + /* Both operands negative. Compute the difference with operands switched */
17384 + cp r8,r10
17385 + cpc r9,r11
17386 +#ifdef L_avr32_f64_cmp_ge
17387 + srhs r12
17388 +#endif
17389 +#ifdef L_avr32_f64_cmp_lt
17390 + srlo r12
17391 +#endif
17392 +0:
17393 + popm pc
17394 +#endif
17395 +
17396 +
17397 +
17398 +#ifdef L_avr32_f64_div
17399 + .align 2
17400 + .global __avr32_f64_div
17401 + .type __avr32_f64_div,@function
17402 +
17403 +__avr32_f64_div:
17404 + stm --sp, r0, r1, r2, r3, r4, r5, r6, r7,lr
17405 + /* op1 in {r11,r10}*/
17406 + /* op2 in {r9,r8}*/
17407 + eor lr, r11, r9 /* MSB(lr) = Sign(op1) ^ Sign(op2) */
17408 +
17409 +
17410 + /* Unpack op1 to 2.62 format*/
17411 + /* exp: r7 */
17412 + /* sf: r11, r10 */
17413 + lsr r7, r11, 20 /* Extract exponent */
17414 +
17415 + lsl r11, 9 /* Extract mantissa, leave room for implicit bit */
17416 + or r11, r11, r10>>23
17417 + lsl r10, 9
17418 + sbr r11, 29 /* Insert implicit bit */
17419 + andh r11, 0x3fff /*Mask last part of exponent since we use 2.62 format*/
17420 +
17421 + cbr r7, 11 /* Clear sign bit */
17422 + /* Check if normalization is needed */
17423 + breq 11f /*If number is subnormal, normalize it */
17424 +22:
17425 + cp r7, 0x7ff
17426 + brhs 2f /* Check op1 for NaN or Inf */
17427 +
17428 + /* Unpack op2 to 2.62 format*/
17429 + /* exp: r6 */
17430 + /* sf: r9, r8 */
17431 + lsr r6, r9, 20 /* Extract exponent */
17432 +
17433 + lsl r9, 9 /* Extract mantissa, leave room for implicit bit */
17434 + or r9, r9, r8>>23
17435 + lsl r8, 9
17436 + sbr r9, 29 /* Insert implicit bit */
17437 + andh r9, 0x3fff /*Mask last part of exponent since we use 2.62 format*/
17438 +
17439 + cbr r6, 11 /* Clear sign bit */
17440 + /* Check if normalization is needed */
17441 + breq 13f /*If number is subnormal, normalize it */
17442 +23:
17443 + cp r6, 0x7ff
17444 + brhs 3f /* Check op2 for NaN or Inf */
17445 +
17446 + /* Calculate new exponent */
17447 + sub r7, r6
17448 + sub r7,-1023
17449 +
17450 + /* Divide */
17451 + /* Approximating 1/d with the following recurrence: */
17452 + /* R[j+1] = R[j]*(2-R[j]*d) */
17453 + /* Using 2.62 format */
17454 + /* TWO: r12 */
17455 + /* d = op2 = divisor (2.62 format): r9,r8 */
17456 + /* Multiply result : r5, r4 */
17457 + /* Initial guess : r3, r2 */
17458 + /* New approximations : r3, r2 */
17459 + /* op1 = Dividend (2.62 format) : r11, r10 */
17460 +
17461 + mov r12, 1 /* Load TWO */
17462 + brev r12
17463 +
17464 + /* Load initial guess, using look-up table */
17465 + /* Initial guess is of format 01.XY, where XY is constructed as follows: */
17466 + /* Let d be of following format: 00.1xy....., then XY=~xy */
17467 + /* For d=00.100 = 0,5 -> initial guess=01.11 = 1,75 */
17468 + /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5 */
17469 + /* For d=00.110 = 0,75 -> initial guess=01.11 = 1,25 */
17470 + /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0 */
17471 + /* r2 is also part of the reg pair forming initial guess, but it*/
17472 + /* is kept uninitialized to save one cycle since it has so low significance*/
17473 +
17474 + lsr r3, r12, 1
17475 + bfextu r4, r9, 27, 2
17476 + com r4
17477 + bfins r3, r4, 28, 2
17478 +
17479 + /* First approximation */
17480 + /* Approximating to 32 bits */
17481 + /* r5 = R[j]*d */
17482 + mulu.d r4, r3, r9
17483 + /* r5 = 2-R[j]*d */
17484 + sub r5, r12, r5<<2
17485 + /* r3 = R[j]*(2-R[j]*d) */
17486 + mulu.d r4, r3, r5
17487 + lsl r3, r5, 2
17488 +
17489 + /* Second approximation */
17490 + /* Approximating to 32 bits */
17491 + /* r5 = R[j]*d */
17492 + mulu.d r4, r3, r9
17493 + /* r5 = 2-R[j]*d */
17494 + sub r5, r12, r5<<2
17495 + /* r3 = R[j]*(2-R[j]*d) */
17496 + mulu.d r4, r3, r5
17497 + lsl r3, r5, 2
17498 +
17499 + /* Third approximation */
17500 + /* Approximating to 32 bits */
17501 + /* r5 = R[j]*d */
17502 + mulu.d r4, r3, r9
17503 + /* r5 = 2-R[j]*d */
17504 + sub r5, r12, r5<<2
17505 + /* r3 = R[j]*(2-R[j]*d) */
17506 + mulu.d r4, r3, r5
17507 + lsl r3, r5, 2
17508 +
17509 + /* Fourth approximation */
17510 + /* Approximating to 64 bits */
17511 + /* r5,r4 = R[j]*d */
17512 + mul_approx_df r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
17513 + lsl r5, 2
17514 + or r5, r5, r4>>30
17515 + lsl r4, 2
17516 + /* r5,r4 = 2-R[j]*d */
17517 + neg r4
17518 + sbc r5, r12, r5
17519 + /* r3,r2 = R[j]*(2-R[j]*d) */
17520 + mul_approx_df r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
17521 + lsl r3, r5, 2
17522 + or r3, r3, r4>>30
17523 + lsl r2, r4, 2
17524 +
17525 +
17526 + /* Fifth approximation */
17527 + /* Approximating to 64 bits */
17528 + /* r5,r4 = R[j]*d */
17529 + mul_approx_df r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
17530 + lsl r5, 2
17531 + or r5, r5, r4>>30
17532 + lsl r4, 2
17533 + /* r5,r4 = 2-R[j]*d */
17534 + neg r4
17535 + sbc r5, r12, r5
17536 + /* r3,r2 = R[j]*(2-R[j]*d) */
17537 + mul_approx_df r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
17538 + lsl r3, r5, 2
17539 + or r3, r3, r4>>30
17540 + lsl r2, r4, 2
17541 +
17542 +
17543 + /* Multiply with dividend to get quotient */
17544 + mul_approx_df r3 /*ah*/, r2 /*al*/, r11 /*bh*/, r10 /*bl*/, r3 /*rh*/, r2 /*rl*/, r1 /*sh*/, r0 /*sl*/
17545 +
17546 + /* Shift by 3 to get result in 1.63 format, as required by the exponent. */
17547 + /* Note that 1.63 format is already used by the exponent in r7, since */
17548 + /* a bias of 1023 was added to the result exponent, even though the implicit */
17549 + /* bit was inserted. This gives the exponent an additional bias of 1, which */
17550 + /* supports 1.63 format. */
17551 + lsl r3, r3, 3
17552 + or r3, r3, r2>>29
17553 + lsl r2, r2, 3
17554 +
17555 + /* To increase speed, this result is not corrected before final rounding.*/
17556 + /* This may give a difference to IEEE compliant code of 1 ULP.*/
17557 +
17558 + /* Adjust exponent and mantissa */
17559 + /* r7:exp, [r3, r2]:mant, [r12,r11,r10]:scratch*/
17560 + /* Mantissa may be of the format 0.xxxx or 1.xxxx. */
17561 + /* In the first case, shift one pos to left.*/
17562 + sub r10, r7, 1
17563 + mov r12, r3
17564 + lsl r11, r2, 1
17565 + rol r12
17566 + bld r3, 31
17567 + movne r7, r10
17568 + movne r3, r12
17569 + movne r2, r11
17570 + cp r7, 0
17571 + breq 15f /*Result was subnormal. Flush-to-zero and return zero*/
17572 +
17573 + /* Result was not subnormal. Perform rounding. */
17574 + /* Note that the tie case (for round-to-even) can not occur in division. */
17575 + /* [r7]:exp, [r3, r2]:mant */
17576 + /* Mantissa is in 0.64 format. Round by adding 1<<(64-(52+2))=1<<10*/
17577 + mov r12, (1<<10)
17578 + add r2, r12
17579 + acr r3
17580 + /* Adjust exponent if we overflowed.*/
17581 + subcs r7, -1
17582 +
17583 +
17584 +
17585 + /* Pack final result*/
17586 + /* Input: [r7]:exp, [r3, r2]:mant */
17587 + /* Result in [r11,r10] */
17588 + /* Insert exponent and sign bit*/
17589 + lsl r11, r7, 20
17590 + bld lr, 31
17591 + bst r11, 31
17592 + /* Insert mantissa */
17593 + cbr r3, 31 /*Clear implicit bit*/
17594 + or r11, r11, r3>>11
17595 + lsr r10, r2, 11
17596 + or r10, r10, r3<<21
17597 + /* Return result in [r11,r10] */
17598 + ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
17599 +
17600 +
17601 +2:
17602 + /* Op1 is NaN or inf */
17603 + andh r11, 0x000f /* Extract mantissa */
17604 + or r11, r10
17605 + brne 16f /* Return NaN if op1 is NaN */
17606 + /* Op1 is inf check op2 */
17607 + lsr r6, r9, 20 /* Extract exponent */
17608 + cbr r6, 8 /* Clear sign bit */
17609 + cp r6, 0x7ff
17610 + brne 17f /* Inf/number gives inf, return inf */
17611 + rjmp 16f /* The rest gives NaN*/
17612 +
17613 +3:
17614 + /* Op1 is a valid number. Op 2 is NaN or inf */
17615 + andh r9, 0x000f /* Extract mantissa */
17616 + or r9, r8
17617 + brne 16f /* Return NaN if op2 is NaN */
17618 + rjmp 15f /* Op2 was inf, return zero*/
17619 +
17620 +11: /* Op1 was denormal. Fix it. */
17621 + lsl r11, 2
17622 + or r11, r11, r10 >> 30
17623 + lsl r10, 2
17624 + cbr r11, 31
17625 + /* Check if op1 is zero. */
17626 + or r4, r10, r11
17627 + breq __avr32_f64_div_op1_zero
17628 + normalize_df r7 /*exp*/, r10, r11 /*Mantissa*/, r4, r5 /*scratch*/
17629 + lsr r10, 2
17630 + or r10, r10, r11 << 30
17631 + lsr r11, 2
17632 + rjmp 22b
17633 +
17634 +
17635 +13: /* Op2 was denormal. Fix it */
17636 + lsl r9, 2
17637 + or r9, r9, r8 >> 30
17638 + lsl r8, 2
17639 + cbr r9, 31
17640 + /* Check if op2 is zero. */
17641 + or r4, r9, r8
17642 + breq 17f /* Divisor is zero -> return Inf */
17643 + normalize_df r6 /*exp*/, r8, r9 /*Mantissa*/, r4, r5 /*scratch*/
17644 + lsr r8, 2
17645 + or r8, r8, r9 << 30
17646 + lsr r9, 2
17647 + rjmp 23b
17648 +
17649 +
17650 +15: /* Divide result was subnormal. Return zero. */
17651 + mov r11, lr /*Get correct sign*/
17652 + andh r11, 0x8000, COH
17653 + mov r10, 0
17654 + ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
17655 +
17656 +16: /* Return NaN. */
17657 + mov r11, -1
17658 + mov r10, -1
17659 + ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
17660 +
17661 +17: /* Return INF. */
17662 + mov r11, lr /*Get correct sign*/
17663 + andh r11, 0x8000, COH
17664 + orh r11, 0x7ff0
17665 + mov r10, 0
17666 + ldm sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
17667 +
17668 +__avr32_f64_div_op1_zero:
17669 + or r5, r8, r9 << 1
17670 + breq 16b /* 0.0/0.0 -> NaN */
17671 + bfextu r4, r9, 20, 11
17672 + cp r4, 0x7ff
17673 + brne 15b /* Return zero */
17674 + /* Check if divisor is Inf or NaN */
17675 + or r5, r8, r9 << 12
17676 + breq 15b /* Divisor is inf -> return zero */
17677 + rjmp 16b /* Return NaN */
17678 +
17679 +
17680 +
17681 +
17682 +#endif
17683 +
17684 +#if defined(L_avr32_f32_addsub) || defined(L_avr32_f32_addsub_fast)
17685 +
17686 + .align 2
17687 +__avr32_f32_sub_from_add:
17688 + /* Switch sign on op2 */
17689 + eorh r11, 0x8000
17690 +
17691 +#if defined(L_avr32_f32_addsub_fast)
17692 + .global __avr32_f32_sub_fast
17693 + .type __avr32_f32_sub_fast,@function
17694 +__avr32_f32_sub_fast:
17695 +#else
17696 + .global __avr32_f32_sub
17697 + .type __avr32_f32_sub,@function
17698 +__avr32_f32_sub:
17699 +#endif
17700 +
17701 + /* Check signs */
17702 + eor r8, r11, r12
17703 + /* Different signs, use subtraction. */
17704 + brmi __avr32_f32_add_from_sub
17705 +
17706 + /* Get sign of op1 */
17707 + mov r8, r12
17708 + andh r12, 0x8000, COH
17709 +
17710 + /* Remove sign from operands */
17711 + cbr r11, 31
17712 +#if defined(L_avr32_f32_addsub_fast)
17713 + reteq r8 /* If op2 is zero return op1 */
17714 +#endif
17715 + cbr r8, 31
17716 +
17717 + /* Put the number with the largest exponent in r10
17718 + and the number with the smallest exponent in r9 */
17719 + max r10, r8, r11
17720 + min r9, r8, r11
17721 + cp r10, r8 /*If largest operand (in R10) is not equal to op1*/
17722 + subne r12, 1 /* Subtract 1 from sign, which will invert MSB of r12*/
17723 + andh r12, 0x8000, COH /*Mask all but MSB*/
17724 +
17725 + /* Unpack exponent and mantissa of op1 */
17726 + lsl r8, r10, 8
17727 + sbr r8, 31 /* Set implicit bit. */
17728 + lsr r10, 23
17729 +
17730 + /* op1 is NaN or Inf. */
17731 + cp.w r10, 0xff
17732 + breq __avr32_f32_sub_op1_nan_or_inf
17733 +
17734 + /* Unpack exponent and mantissa of op2 */
17735 + lsl r11, r9, 8
17736 + sbr r11, 31 /* Set implicit bit. */
17737 + lsr r9, 23
17738 +
17739 +#if defined(L_avr32_f32_addsub)
17740 + /* Keep sticky bit for correct IEEE rounding */
17741 + st.w --sp, r12
17742 +
17743 + /* op2 is either zero or subnormal. */
17744 + breq __avr32_f32_sub_op2_subnormal
17745 +0:
17746 + /* Get shift amount to scale mantissa of op2. */
17747 + rsub r9, r10
17748 +
17749 + /* Saturate the shift amount to 31. If the amount
17750 + is any larger op2 is insignificant. */
17751 + satu r9 >> 0, 5
17752 +
17753 + /* Shift mantissa of op2 to same decimal point as the mantissa
17754 + of op1. */
17755 + lsr r12, r11, r9
17756 +
17757 + /* Put the remainding bits into r11[23:..].*/
17758 + rsub r9, r9, (32-8)
17759 + lsl r11, r11, r9
17760 +
17761 + /* Now subtract the mantissas. */
17762 + sub r8, r12
17763 +
17764 + ld.w r12, sp++
17765 +
17766 + /* Normalize resulting mantissa. */
17767 + clz r9, r8
17768 + lsl r8, r8, r9
17769 + sub r10, r9
17770 + brle __avr32_f32_sub_subnormal_result
17771 +
17772 + /* Insert the bits we will remove from the mantissa into r11[31:24] */
17773 + bfins r11, r8, 24, 8
17774 +#else
17775 + /* Ignore sticky bit to simplify and speed up rounding */
17776 + /* op2 is either zero or subnormal. */
17777 + breq __avr32_f32_sub_op2_subnormal
17778 +0:
17779 + /* Get shift amount to scale mantissa of op2. */
17780 + rsub r9, r10
17781 +
17782 + /* Saturate the shift amount to 31. If the amount
17783 + is any larger op2 is insignificant. */
17784 + satu r9 >> 0, 5
17785 +
17786 + /* Shift mantissa of op2 to same decimal point as the mantissa
17787 + of op1. */
17788 + lsr r11, r11, r9
17789 +
17790 + /* Now subtract the mantissas. */
17791 + sub r8, r11
17792 +
17793 + /* Normalize resulting mantissa. */
17794 + clz r9, r8
17795 + lsl r8, r8, r9
17796 + sub r10, r9
17797 + brle __avr32_f32_sub_subnormal_result
17798 +#endif
17799 +
17800 + /* Pack result. */
17801 + or r12, r12, r8 >> 8
17802 + bfins r12, r10, 23, 8
17803 +
17804 + /* Round */
17805 +__avr32_f32_sub_round:
17806 +#if defined(L_avr32_f32_addsub)
17807 + mov r10, 0
17808 + sbr r10, 31
17809 + bld r12, 0
17810 + subne r10, -1
17811 + cp.w r11, r10
17812 + subhs r12, -1
17813 +#else
17814 + bld r8, 7
17815 + acr r12
17816 +#endif
17817 +
17818 + ret r12
17819 +
17820 +
17821 +__avr32_f32_sub_op2_subnormal:
17822 + /* Fix implicit bit and adjust exponent of subnormals. */
17823 + cbr r11, 31
17824 + /* Set exponent to 1 if we do not have a zero. */
17825 + movne r9,1
17826 +
17827 + /* Check if op1 is also subnormal. */
17828 + cp.w r10, 0
17829 + brne 0b
17830 +
17831 + cbr r8, 31
17832 + /* If op1 is not zero set exponent to 1. */
17833 + movne r10,1
17834 +
17835 + rjmp 0b
17836 +
17837 +__avr32_f32_sub_op1_nan_or_inf:
17838 + /* Check if op1 is NaN, if so return NaN */
17839 + lsl r11, r8, 1
17840 + retne -1
17841 +
17842 + /* op1 is Inf. */
17843 + bfins r12, r10, 23, 8 /* Generate Inf in r12 */
17844 +
17845 + /* Check if op2 is Inf. or NaN */
17846 + lsr r11, r9, 23
17847 + cp.w r11, 0xff
17848 + retne r12 /* op2 not Inf or NaN, return op1 */
17849 +
17850 + ret -1 /* op2 Inf or NaN, return NaN */
17851 +
17852 +__avr32_f32_sub_subnormal_result:
17853 + /* Check if the number is so small that
17854 + it will be represented with zero. */
17855 + rsub r10, r10, 9
17856 + rsub r9, r10, 32
17857 + retcs 0
17858 +
17859 + /* Shift the mantissa into the correct position.*/
17860 + lsr r10, r8, r10
17861 + /* Add sign bit. */
17862 + or r10, r12
17863 +
17864 + /* Put the shifted out bits in the most significant part
17865 + of r8. */
17866 + lsl r8, r8, r9
17867 +
17868 +#if defined(L_avr32_f32_addsub)
17869 + /* Add all the remainder bits used for rounding into r11 */
17870 + andh r11, 0x00FF
17871 + or r11, r8
17872 +#else
17873 + lsr r8, 24
17874 +#endif
17875 + rjmp __avr32_f32_sub_round
17876 +
17877 +
17878 + .align 2
17879 +
17880 +__avr32_f32_add_from_sub:
17881 + /* Switch sign on op2 */
17882 + eorh r11, 0x8000
17883 +
17884 +#if defined(L_avr32_f32_addsub_fast)
17885 + .global __avr32_f32_add_fast
17886 + .type __avr32_f32_add_fast,@function
17887 +__avr32_f32_add_fast:
17888 +#else
17889 + .global __avr32_f32_add
17890 + .type __avr32_f32_add,@function
17891 +__avr32_f32_add:
17892 +#endif
17893 +
17894 + /* Check signs */
17895 + eor r8, r11, r12
17896 + /* Different signs, use subtraction. */
17897 + brmi __avr32_f32_sub_from_add
17898 +
17899 + /* Get sign of op1 */
17900 + mov r8, r12
17901 + andh r12, 0x8000, COH
17902 +
17903 + /* Remove sign from operands */
17904 + cbr r11, 31
17905 +#if defined(L_avr32_f32_addsub_fast)
17906 + reteq r8 /* If op2 is zero return op1 */
17907 +#endif
17908 + cbr r8, 31
17909 +
17910 + /* Put the number with the largest exponent in r10
17911 + and the number with the smallest exponent in r9 */
17912 + max r10, r8, r11
17913 + min r9, r8, r11
17914 +
17915 + /* Unpack exponent and mantissa of op1 */
17916 + lsl r8, r10, 8
17917 + sbr r8, 31 /* Set implicit bit. */
17918 + lsr r10, 23
17919 +
17920 + /* op1 is NaN or Inf. */
17921 + cp.w r10, 0xff
17922 + breq __avr32_f32_add_op1_nan_or_inf
17923 +
17924 + /* Unpack exponent and mantissa of op2 */
17925 + lsl r11, r9, 8
17926 + sbr r11, 31 /* Set implicit bit. */
17927 + lsr r9, 23
17928 +
17929 +#if defined(L_avr32_f32_addsub)
17930 + /* Keep sticky bit for correct IEEE rounding */
17931 + st.w --sp, r12
17932 +
17933 + /* op2 is either zero or subnormal. */
17934 + breq __avr32_f32_add_op2_subnormal
17935 +0:
17936 + /* Get shift amount to scale mantissa of op2. */
17937 + rsub r9, r10
17938 +
17939 + /* Saturate the shift amount to 31. If the amount
17940 + is any larger op2 is insignificant. */
17941 + satu r9 >> 0, 5
17942 +
17943 + /* Shift mantissa of op2 to same decimal point as the mantissa
17944 + of op1. */
17945 + lsr r12, r11, r9
17946 +
17947 + /* Put the remainding bits into r11[23:..].*/
17948 + rsub r9, r9, (32-8)
17949 + lsl r11, r11, r9
17950 + /* Insert the bits we will remove from the mantissa into r11[31:24] */
17951 + bfins r11, r12, 24, 8
17952 +
17953 + /* Now add the mantissas. */
17954 + add r8, r12
17955 +
17956 + ld.w r12, sp++
17957 +#else
17958 + /* Ignore sticky bit to simplify and speed up rounding */
17959 + /* op2 is either zero or subnormal. */
17960 + breq __avr32_f32_add_op2_subnormal
17961 +0:
17962 + /* Get shift amount to scale mantissa of op2. */
17963 + rsub r9, r10
17964 +
17965 + /* Saturate the shift amount to 31. If the amount
17966 + is any larger op2 is insignificant. */
17967 + satu r9 >> 0, 5
17968 +
17969 + /* Shift mantissa of op2 to same decimal point as the mantissa
17970 + of op1. */
17971 + lsr r11, r11, r9
17972 +
17973 + /* Now add the mantissas. */
17974 + add r8, r11
17975 +
17976 +#endif
17977 + /* Check if we overflowed. */
17978 + brcs __avr32_f32_add_res_of
17979 +1:
17980 + /* Pack result. */
17981 + or r12, r12, r8 >> 8
17982 + bfins r12, r10, 23, 8
17983 +
17984 + /* Round */
17985 +#if defined(L_avr32_f32_addsub)
17986 + mov r10, 0
17987 + sbr r10, 31
17988 + bld r12, 0
17989 + subne r10, -1
17990 + cp.w r11, r10
17991 + subhs r12, -1
17992 +#else
17993 + bld r8, 7
17994 + acr r12
17995 +#endif
17996 +
17997 + ret r12
17998 +
17999 +__avr32_f32_add_op2_subnormal:
18000 + /* Fix implicit bit and adjust exponent of subnormals. */
18001 + cbr r11, 31
18002 + /* Set exponent to 1 if we do not have a zero. */
18003 + movne r9,1
18004 +
18005 + /* Check if op1 is also subnormal. */
18006 + cp.w r10, 0
18007 + brne 0b
18008 +
18009 + cbr r8, 31
18010 + /* If op1 is not zero set exponent to 1. */
18011 + movne r10,1
18012 +
18013 + rjmp 0b
18014 +
18015 +__avr32_f32_add_op1_nan_or_inf:
18016 + /* Check if op1 is NaN, if so return NaN */
18017 + lsl r11, r8, 1
18018 + retne -1
18019 +
18020 + /* op1 is Inf. */
18021 + bfins r12, r10, 23, 8 /* Generate Inf in r12 */
18022 +
18023 + /* Check if op2 is Inf. or NaN */
18024 + lsr r11, r9, 23
18025 + cp.w r11, 0xff
18026 + retne r12 /* op2 not Inf or NaN, return op1 */
18027 +
18028 + lsl r9, 9
18029 + reteq r12 /* op2 Inf return op1 */
18030 + ret -1 /* op2 is NaN, return NaN */
18031 +
18032 +__avr32_f32_add_res_of:
18033 + /* We overflowed. Increase exponent and shift mantissa.*/
18034 + lsr r8, 1
18035 + sub r10, -1
18036 +
18037 + /* Clear mantissa to set result to Inf if the exponent is 255. */
18038 + cp.w r10, 255
18039 + moveq r8, 0
18040 + moveq r11, 0
18041 + rjmp 1b
18042 +
18043 +
18044 +#endif
18045 +
18046 +
18047 +#if defined(L_avr32_f32_div) || defined(L_avr32_f32_div_fast)
18048 + .align 2
18049 +
18050 +#if defined(L_avr32_f32_div_fast)
18051 + .global __avr32_f32_div_fast
18052 + .type __avr32_f32_div_fast,@function
18053 +__avr32_f32_div_fast:
18054 +#else
18055 + .global __avr32_f32_div
18056 + .type __avr32_f32_div,@function
18057 +__avr32_f32_div:
18058 +#endif
18059 +
18060 + eor r8, r11, r12 /* MSB(r8) = Sign(op1) ^ Sign(op2) */
18061 +
18062 + /* Unpack */
18063 + lsl r12,1
18064 + reteq 0 /* Return zero if op1 is zero */
18065 + lsl r11,1
18066 + breq 4f /* Check op2 for zero */
18067 +
18068 + /* Unpack op1*/
18069 + /* exp: r9 */
18070 + /* sf: r12 */
18071 + lsr r9, r12, 24
18072 + breq 11f /*If number is subnormal*/
18073 + cp r9, 0xff
18074 + brhs 2f /* Check op1 for NaN or Inf */
18075 + lsl r12, 7
18076 + sbr r12, 31 /*Implicit bit*/
18077 +12:
18078 +
18079 + /* Unpack op2*/
18080 + /* exp: r10 */
18081 + /* sf: r11 */
18082 + lsr r10, r11, 24
18083 + breq 13f /*If number is subnormal*/
18084 + cp r10, 0xff
18085 + brhs 3f /* Check op2 for NaN or Inf */
18086 +
18087 + lsl r11,7
18088 + sbr r11, 31 /*Implicit bit*/
18089 +14:
18090 +
18091 + /* For UC3, store with predecrement is faster than stm */
18092 + st.w --sp, r5
18093 + st.d --sp, r6
18094 +
18095 + /* Calculate new exponent */
18096 + sub r9, r10
18097 + sub r9,-127
18098 +
18099 + /* Divide */
18100 + /* Approximating 1/d with the following recurrence: */
18101 + /* R[j+1] = R[j]*(2-R[j]*d) */
18102 + /* Using 2.30 format */
18103 + /* TWO: r10 */
18104 + /* d: r5 */
18105 + /* Multiply result : r6, r7 */
18106 + /* Initial guess : r11 */
18107 + /* New approximations : r11 */
18108 + /* Dividend : r12 */
18109 +
18110 + mov r10, 1 /* Load TWO */
18111 + brev r10
18112 +
18113 + lsr r12, 2 /* Get significand of Op1 in 2.30 format */
18114 + lsr r5, r11, 2 /* Get significand of Op2 (=d) in 2.30 format */
18115 +
18116 + /* Load initial guess, using look-up table */
18117 + /* Initial guess is of format 01.XY, where XY is constructed as follows: */
18118 + /* Let d be of following format: 00.1xy....., then XY=~xy */
18119 + /* For d=00.100 = 0,5 -> initial guess=01.11 = 1,75 */
18120 + /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5 */
18121 + /* For d=00.110 = 0,75 -> initial guess=01.11 = 1,25 */
18122 + /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0 */
18123 +
18124 + lsr r11, r10, 1
18125 + bfextu r6, r5, 27, 2
18126 + com r6
18127 + bfins r11, r6, 28, 2
18128 +
18129 + /* First approximation */
18130 + /* r7 = R[j]*d */
18131 + mulu.d r6, r11, r5
18132 + /* r7 = 2-R[j]*d */
18133 + sub r7, r10, r7<<2
18134 + /* r11 = R[j]*(2-R[j]*d) */
18135 + mulu.d r6, r11, r7
18136 + lsl r11, r7, 2
18137 +
18138 + /* Second approximation */
18139 + /* r7 = R[j]*d */
18140 + mulu.d r6, r11, r5
18141 + /* r7 = 2-R[j]*d */
18142 + sub r7, r10, r7<<2
18143 + /* r11 = R[j]*(2-R[j]*d) */
18144 + mulu.d r6, r11, r7
18145 + lsl r11, r7, 2
18146 +
18147 + /* Third approximation */
18148 + /* r7 = R[j]*d */
18149 + mulu.d r6, r11, r5
18150 + /* r7 = 2-R[j]*d */
18151 + sub r7, r10, r7<<2
18152 + /* r11 = R[j]*(2-R[j]*d) */
18153 + mulu.d r6, r11, r7
18154 + lsl r11, r7, 2
18155 +
18156 + /* Fourth approximation */
18157 + /* r7 = R[j]*d */
18158 + mulu.d r6, r11, r5
18159 + /* r7 = 2-R[j]*d */
18160 + sub r7, r10, r7<<2
18161 + /* r11 = R[j]*(2-R[j]*d) */
18162 + mulu.d r6, r11, r7
18163 + lsl r11, r7, 2
18164 +
18165 +
18166 + /* Multiply with dividend to get quotient, r7 = sf(op1)/sf(op2) */
18167 + mulu.d r6, r11, r12
18168 +
18169 + /* Shift by 3 to get result in 1.31 format, as required by the exponent. */
18170 + /* Note that 1.31 format is already used by the exponent in r9, since */
18171 + /* a bias of 127 was added to the result exponent, even though the implicit */
18172 + /* bit was inserted. This gives the exponent an additional bias of 1, which */
18173 + /* supports 1.31 format. */
18174 + lsl r10, r7, 3
18175 +
18176 +#if defined(L_avr32_f32_div)
18177 + /* To perform correct rounding, check for nonzero remainder, */
18178 + /* and set LSB in quot if remainder != 0 */
18179 + /* Remainder = dividend(r12) - divisor(r5)*quotient(r10) */
18180 +
18181 + lsl r5, 1 /* Transform divisor from 2.30 to 1.31 format */
18182 + /* Mask all bits lower than guard in quotient. */
18183 + /* These bits are inexact due to approximative algorithm */
18184 + andl r10, 0xffc0
18185 + /* Add 1 in least significant bit pos to make sure approximation is from above */
18186 + sub r10, -64
18187 + mulu.d r6, r5, r10
18188 + /* If remainder < 0, truncated quotient is too large, so the */
18189 + /* delta added must be subtracted to get the correct truncated quotient. */
18190 + sub r12, r7 /* Calculate remainder and implicitly set flags */
18191 + sublt r10, 64
18192 +#endif
18193 +
18194 + /* For UC3, load with postincrement is faster than ldm */
18195 + ld.d r6, sp++
18196 + ld.w r5, sp++
18197 +
18198 + /* Adjust exponent and mantissa */
18199 + /* r9:exp, r10:mant, r11:scratch*/
18200 + clz r11, r10
18201 + sub r9, r11
18202 + breq 16f /*Result was subnormal*/
18203 + lsl r10, r10, r11
18204 +
18205 + /* Result was not subnormal. Perform rounding. */
18206 + /* Note that the tie case (for round-to-even) can not occur in division. */
18207 + /* r9:exp, r10:mant*/
18208 + sub r10, -1*(0x80)
18209 + /* Adjust exponent if we overflowed. Note that we must use {cc}
18210 + since we perform the add using a sub insn. */
18211 + subcc r9, -1
18212 +
18213 + /* Pack final result*/
18214 + lsr r12, r10, 7
18215 + bfins r12, r9, 24, 8
18216 +__divsf_return_op1:
18217 + lsl r8, 1
18218 + ror r12
18219 + ret r12
18220 +
18221 +
18222 +2:
18223 + /* Op1 is NaN or inf */
18224 + retne -1 /* Return NaN if op1 is NaN */
18225 + /* Op1 is inf check op2 */
18226 + mov r9, 0xff
18227 + brev r9
18228 + cp r11, r9
18229 + brlo __divsf_return_op1 /* inf/number gives inf */
18230 + ret -1 /* The rest gives NaN*/
18231 +3:
18232 + /* Op1 is NaN or inf */
18233 + reteq 0 /* Return zero if number/inf*/
18234 + ret -1 /* Return NaN*/
18235 +4:
18236 + /* Op2 is zero ? */
18237 + tst r12,r12
18238 + reteq -1 /* 0.0/0.0 is NaN */
18239 + /* Nonzero/0.0 is Inf. Sign bit will be shifted in before returning*/
18240 + mov r12, 0x7ff
18241 + brev r12
18242 + rjmp __divsf_return_op1
18243 +
18244 +11: /* Op1 was denormal. Fix it. */
18245 + lsl r12,7
18246 + clz r9,r12
18247 + lsl r12,r12,r9
18248 + rsub r9,r9,1
18249 + rjmp 12b
18250 +
18251 +13: /* Op2 was denormal. Fix it. */
18252 + lsl r11,7
18253 + clz r10,r11
18254 + lsl r11,r11,r10
18255 + rsub r10,r10,1
18256 + rjmp 14b
18257 +
18258 +
18259 +16: /* Divide result was subnormal. Fix it and return. */
18260 +#if defined(L_avr32_f32_div)
18261 + lsl r10, r10, r11 /*Perform shift required by adjustment of exponent and mantissa*/
18262 + adjust_subnormal_sf r12 /*sf*/, r9 /*exp*/, r10 /*mant*/, r8 /*sign*/,r11 /*scratch*/
18263 +#else
18264 + /*Flush to zero*/
18265 + mov r12, 0
18266 +#endif
18267 + ret r12
18268 +
18269 +#endif
18270 +
18271 +#ifdef L_avr32_f32_mul
18272 + .global __avr32_f32_mul
18273 + .type __avr32_f32_mul,@function
18274 +
18275 +
18276 +__avr32_f32_mul:
18277 + mov r8, r12
18278 + eor r12, r11 /* MSB(r8) = Sign(op1) ^ Sign(op2) */
18279 + andh r12, 0x8000, COH
18280 +
18281 + /* arrange operands so that that op1 >= op2 */
18282 + cbr r8, 31
18283 + breq __avr32_f32_mul_op1_zero
18284 + cbr r11, 31
18285 +
18286 + /* Put the number with the largest exponent in r10
18287 + and the number with the smallest exponent in r9 */
18288 + max r10, r8, r11
18289 + min r9, r8, r11
18290 +
18291 + /* Unpack exponent and mantissa of op1 */
18292 + lsl r8, r10, 8
18293 + sbr r8, 31 /* Set implicit bit. */
18294 + lsr r10, 23
18295 +
18296 + /* op1 is NaN or Inf. */
18297 + cp.w r10, 0xff
18298 + breq __avr32_f32_mul_op1_nan_or_inf
18299 +
18300 + /* Unpack exponent and mantissa of op2 */
18301 + lsl r11, r9, 8
18302 + sbr r11, 31 /* Set implicit bit. */
18303 + lsr r9, 23
18304 +
18305 + /* op2 is either zero or subnormal. */
18306 + breq __avr32_f32_mul_op2_subnormal
18307 +0:
18308 + /* Calculate new exponent */
18309 + add r9,r10
18310 +
18311 + /* Do the multiplication */
18312 + mulu.d r10,r8,r11
18313 +
18314 + /* We might need to scale up by two if the MSB of the result is
18315 + zero. */
18316 + lsl r8, r11, 1
18317 + movcc r11, r8
18318 + subcc r9, 1
18319 +
18320 + /* Put the shifted out bits of the mantissa into r10 */
18321 + lsr r10, 8
18322 + bfins r10, r11, 24, 8
18323 +
18324 + sub r9,(127-1) /* remove extra exponent bias */
18325 + brle __avr32_f32_mul_res_subnormal
18326 +
18327 + /* Check for Inf. */
18328 + cp.w r9, 0xff
18329 + brge 1f
18330 +
18331 + /* Pack result. */
18332 + or r12, r12, r11 >> 8
18333 + bfins r12, r9, 23, 8
18334 +
18335 + /* Round */
18336 +__avr32_f32_mul_round:
18337 + mov r8, 0
18338 + sbr r8, 31
18339 + bld r12, 0
18340 + subne r8, -1
18341 +
18342 + cp.w r10, r8
18343 + subhs r12, -1
18344 +
18345 + ret r12
18346 +
18347 +1:
18348 + /* Return Inf */
18349 + orh r12, 0x7f80
18350 + ret r12
18351 +
18352 +__avr32_f32_mul_op2_subnormal:
18353 + cbr r11, 31
18354 + clz r9, r11
18355 + retcs 0 /* op2 is zero. Return 0 */
18356 + lsl r11, r11, r9
18357 + rsub r9, r9, 1
18358 +
18359 + /* Check if op2 is subnormal. */
18360 + tst r10, r10
18361 + brne 0b
18362 +
18363 + /* op2 is subnormal */
18364 + cbr r8, 31
18365 + clz r10, r11
18366 + retcs 0 /* op1 is zero. Return 0 */
18367 + lsl r8, r8, r10
18368 + rsub r10, r10, 1
18369 +
18370 + rjmp 0b
18371 +
18372 +
18373 +__avr32_f32_mul_op1_nan_or_inf:
18374 + /* Check if op1 is NaN, if so return NaN */
18375 + lsl r11, r8, 1
18376 + retne -1
18377 +
18378 + /* op1 is Inf. */
18379 + tst r9, r9
18380 + reteq -1 /* Inf * 0 -> NaN */
18381 +
18382 + bfins r12, r10, 23, 8 /* Generate Inf in r12 */
18383 +
18384 + /* Check if op2 is Inf. or NaN */
18385 + lsr r11, r9, 23
18386 + cp.w r11, 0xff
18387 + retne r12 /* op2 not Inf or NaN, return Info */
18388 +
18389 + lsl r9, 9
18390 + reteq r12 /* op2 Inf return Inf */
18391 + ret -1 /* op2 is NaN, return NaN */
18392 +
18393 +__avr32_f32_mul_res_subnormal:
18394 + /* Check if the number is so small that
18395 + it will be represented with zero. */
18396 + rsub r9, r9, 9
18397 + rsub r8, r9, 32
18398 + retcs 0
18399 +
18400 + /* Shift the mantissa into the correct position.*/
18401 + lsr r9, r11, r9
18402 + /* Add sign bit. */
18403 + or r12, r9
18404 + /* Put the shifted out bits in the most significant part
18405 + of r8. */
18406 + lsl r11, r11, r8
18407 +
18408 + /* Add all the remainder bits used for rounding into r11 */
18409 + andh r10, 0x00FF
18410 + or r10, r11
18411 + rjmp __avr32_f32_mul_round
18412 +
18413 +__avr32_f32_mul_op1_zero:
18414 + bfextu r10, r11, 23, 8
18415 + cp.w r10, 0xff
18416 + retne r12
18417 + reteq -1
18418 +
18419 +#endif
18420 +
18421 +
18422 +#ifdef L_avr32_s32_to_f32
18423 + .global __avr32_s32_to_f32
18424 + .type __avr32_s32_to_f32,@function
18425 +__avr32_s32_to_f32:
18426 + cp r12, 0
18427 + reteq r12 /* If zero then return zero float */
18428 + mov r11, r12 /* Keep the sign */
18429 + abs r12 /* Compute the absolute value */
18430 + mov r10, 31 + 127 /* Set the correct exponent */
18431 +
18432 + /* Normalize */
18433 + normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/
18434 +
18435 + /* Check for subnormal result */
18436 + cp.w r10, 0
18437 + brle __avr32_s32_to_f32_subnormal
18438 +
18439 + round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/
18440 + pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/
18441 + lsl r11, 1
18442 + ror r12
18443 + ret r12
18444 +
18445 +__avr32_s32_to_f32_subnormal:
18446 + /* Adjust a subnormal result */
18447 + adjust_subnormal_sf r12/*sf*/, r10 /*exp*/, r12 /*mant*/, r11/*sign*/, r9 /*scratch*/
18448 + ret r12
18449 +
18450 +#endif
18451 +
18452 +#ifdef L_avr32_u32_to_f32
18453 + .global __avr32_u32_to_f32
18454 + .type __avr32_u32_to_f32,@function
18455 +__avr32_u32_to_f32:
18456 + cp r12, 0
18457 + reteq r12 /* If zero then return zero float */
18458 + mov r10, 31 + 127 /* Set the correct exponent */
18459 +
18460 + /* Normalize */
18461 + normalize_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/
18462 +
18463 + /* Check for subnormal result */
18464 + cp.w r10, 0
18465 + brle __avr32_u32_to_f32_subnormal
18466 +
18467 + round_sf r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/
18468 + pack_sf r12 /*sf*/, r10 /*exp*/, r12 /*mant*/
18469 + lsr r12,1 /* Sign bit is 0 for unsigned int */
18470 + ret r12
18471 +
18472 +__avr32_u32_to_f32_subnormal:
18473 + /* Adjust a subnormal result */
18474 + mov r8, 0
18475 + adjust_subnormal_sf r12/*sf*/,r10 /*exp*/, r12 /*mant*/,r8/*sign*/, r9 /*scratch*/
18476 + ret r12
18477 +
18478 +
18479 +#endif
18480 +
18481 +
18482 +#ifdef L_avr32_f32_to_s32
18483 + .global __avr32_f32_to_s32
18484 + .type __avr32_f32_to_s32,@function
18485 +__avr32_f32_to_s32:
18486 + bfextu r11, r12, 23, 8
18487 + sub r11,127 /* Fix bias */
18488 + retlo 0 /* Negative exponent yields zero integer */
18489 +
18490 + /* Shift mantissa into correct position */
18491 + rsub r11,r11,31 /* Shift amount */
18492 + lsl r10,r12,8 /* Get mantissa */
18493 + sbr r10,31 /* Add implicit bit */
18494 + lsr r10,r10,r11 /* Perform shift */
18495 + lsl r12,1 /* Check sign */
18496 + retcc r10 /* if positive, we are done */
18497 + neg r10 /* if negative float, negate result */
18498 + ret r10
18499 +
18500 +#endif
18501 +
18502 +#ifdef L_avr32_f32_to_u32
18503 + .global __avr32_f32_to_u32
18504 + .type __avr32_f32_to_u32,@function
18505 +__avr32_f32_to_u32:
18506 + cp r12,0
18507 + retmi 0 /* Negative numbers gives 0 */
18508 + bfextu r11, r12, 23, 8 /* Extract exponent */
18509 + sub r11,127 /* Fix bias */
18510 + retlo 0 /* Negative exponent yields zero integer */
18511 +
18512 + /* Shift mantissa into correct position */
18513 + rsub r11,r11,31 /* Shift amount */
18514 + lsl r12,8 /* Get mantissa */
18515 + sbr r12,31 /* Add implicit bit */
18516 + lsr r12,r12,r11 /* Perform shift */
18517 + ret r12
18518 +
18519 +#endif
18520 +
18521 +#ifdef L_avr32_f32_to_f64
18522 + .global __avr32_f32_to_f64
18523 + .type __avr32_f32_to_f64,@function
18524 +
18525 +__avr32_f32_to_f64:
18526 + lsl r11,r12,1 /* Remove sign bit, keep original value in r12*/
18527 + moveq r10, 0
18528 + reteq r11 /* Return zero if input is zero */
18529 +
18530 + bfextu r9,r11,24,8 /* Get exponent */
18531 + cp.w r9,0xff /* check for NaN or inf */
18532 + breq 0f
18533 +
18534 + lsl r11,7 /* Convert sf mantissa to df format */
18535 + mov r10,0
18536 +
18537 + /* Check if implicit bit should be set */
18538 + cp.w r9, 0
18539 + subeq r9,-1 /* Adjust exponent if it was 0 */
18540 + srne r8
18541 + or r11, r11, r8 << 31 /* Set implicit bit if needed */
18542 + sub r9,(127-0x3ff) /* Convert exponent to df format exponent */
18543 +
18544 + /*We know that low register of mantissa is 0, and will be unaffected by normalization.*/
18545 + /*We can therefore use the faster normalize_sf function instead of normalize_df.*/
18546 + normalize_sf r9 /*exp*/, r11 /*mantissa*/, r8 /*scratch*/
18547 + pack_df r9 /*exp*/, r10, r11 /*mantissa*/, r10, r11 /*df*/
18548 +
18549 +__extendsfdf_return_op1:
18550 + /* Rotate in sign bit */
18551 + lsl r12, 1
18552 + ror r11
18553 + ret r11
18554 +
18555 +0:
18556 + /* Inf or NaN*/
18557 + mov r10, 0
18558 + orh r10, 0xffe0
18559 + lsl r11,8 /* check mantissa */
18560 + movne r11, -1 /* Return NaN */
18561 + moveq r11, r10 /* Return inf */
18562 + rjmp __extendsfdf_return_op1
18563 +#endif
18564 +
18565 +
18566 +#ifdef L_avr32_f64_to_f32
18567 + .global __avr32_f64_to_f32
18568 + .type __avr32_f64_to_f32,@function
18569 +
18570 +__avr32_f64_to_f32:
18571 + /* Unpack */
18572 + lsl r9,r11,1 /* Unpack exponent */
18573 + lsr r9,21
18574 +
18575 + reteq 0 /* If exponent is 0 the number is so small
18576 + that the conversion to single float gives
18577 + zero */
18578 +
18579 + lsl r8,r11,10 /* Adjust mantissa */
18580 + or r12,r8,r10>>22
18581 +
18582 + lsl r10,10 /* Check if there are any remaining bits
18583 + in the low part of the mantissa.*/
18584 + neg r10
18585 + rol r12 /* If there were remaining bits then set lsb
18586 + of mantissa to 1 */
18587 +
18588 + cp r9,0x7ff
18589 + breq 2f /* Check for NaN or inf */
18590 +
18591 + sub r9,(0x3ff-127) /* Adjust bias of exponent */
18592 + sbr r12,31 /* set the implicit bit.*/
18593 +
18594 + cp.w r9, 0 /* Check for subnormal number */
18595 + brle 3f
18596 +
18597 + round_sf r9 /*exp*/, r12 /*mant*/, r10 /*scratch*/
18598 + pack_sf r12 /*sf*/, r9 /*exp*/, r12 /*mant*/
18599 +__truncdfsf_return_op1:
18600 + /* Rotate in sign bit */
18601 + lsl r11, 1
18602 + ror r12
18603 + ret r12
18604 +
18605 +2:
18606 + /* NaN or inf */
18607 + cbr r12,31 /* clear implicit bit */
18608 + retne -1 /* Return NaN if mantissa not zero */
18609 + mov r12, 0
18610 + orh r12, 0xff00
18611 + ret r12 /* Return inf */
18612 +
18613 +3: /* Result is subnormal. Adjust it.*/
18614 + adjust_subnormal_sf r12/*sf*/,r9 /*exp*/, r12 /*mant*/, r11/*sign*/, r10 /*scratch*/
18615 + ret r12
18616 +
18617 +
18618 +#endif
18619 +
18620 \ No newline at end of file
18621 diff -Nrup gcc-4.2.1/gcc/config/avr32/lib2funcs.S gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/lib2funcs.S
18622 --- gcc-4.2.1/gcc/config/avr32/lib2funcs.S 1970-01-01 01:00:00.000000000 +0100
18623 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/lib2funcs.S 2007-05-07 14:29:10.000000000 +0200
18624 @@ -0,0 +1,21 @@
18625 + .align 4
18626 + .global __nonlocal_goto
18627 + .type __nonlocal_goto,@function
18628 +
18629 +/* __nonlocal_goto: This function handles nonlocal_goto's in gcc.
18630 +
18631 + parameter 0 (r12) = New Frame Pointer
18632 + parameter 1 (r11) = Address to goto
18633 + parameter 2 (r10) = New Stack Pointer
18634 +
18635 + This function invalidates the return stack, since it returns from a
18636 + function without using a return instruction.
18637 +*/
18638 +__nonlocal_goto:
18639 + mov r7, r12
18640 + mov sp, r10
18641 + frs # Flush return stack
18642 + mov pc, r11
18643 +
18644 +
18645 +
18646 diff -Nrup gcc-4.2.1/gcc/config/avr32/linux-elf.h gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/linux-elf.h
18647 --- gcc-4.2.1/gcc/config/avr32/linux-elf.h 1970-01-01 01:00:00.000000000 +0100
18648 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/linux-elf.h 2007-09-28 10:33:00.000000000 +0200
18649 @@ -0,0 +1,156 @@
18650 +/*
18651 + Linux/Elf specific definitions.
18652 + Copyright 2003-2006 Atmel Corporation.
18653 +
18654 + Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
18655 + and H�vard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
18656 +
18657 + This file is part of GCC.
18658 +
18659 + This program is free software; you can redistribute it and/or modify
18660 + it under the terms of the GNU General Public License as published by
18661 + the Free Software Foundation; either version 2 of the License, or
18662 + (at your option) any later version.
18663 +
18664 + This program is distributed in the hope that it will be useful,
18665 + but WITHOUT ANY WARRANTY; without even the implied warranty of
18666 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18667 + GNU General Public License for more details.
18668 +
18669 + You should have received a copy of the GNU General Public License
18670 + along with this program; if not, write to the Free Software
18671 + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18672 +
18673 +
18674 +
18675 +/* elfos.h should have already been included. Now just override
18676 + any conflicting definitions and add any extras. */
18677 +
18678 +/* Run-time Target Specification. */
18679 +#undef TARGET_VERSION
18680 +#define TARGET_VERSION fputs (" (AVR32 GNU/Linux with ELF)", stderr);
18681 +
18682 +/* Do not assume anything about header files. */
18683 +#define NO_IMPLICIT_EXTERN_C
18684 +
18685 +/* The GNU C++ standard library requires that these macros be defined. */
18686 +#undef CPLUSPLUS_CPP_SPEC
18687 +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
18688 +
18689 +/* Now we define the strings used to build the spec file. */
18690 +#undef LIB_SPEC
18691 +#define LIB_SPEC \
18692 + "%{pthread:-lpthread} \
18693 + %{shared:-lc} \
18694 + %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
18695 +
18696 +/* Provide a STARTFILE_SPEC appropriate for GNU/Linux. Here we add
18697 + the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
18698 + provides part of the support for getting C++ file-scope static
18699 + object constructed before entering `main'. */
18700 +
18701 +#undef STARTFILE_SPEC
18702 +#define STARTFILE_SPEC \
18703 + "%{!shared: \
18704 + %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
18705 + %{!p:%{profile:gcrt1.o%s} \
18706 + %{!profile:crt1.o%s}}}} \
18707 + crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
18708 +
18709 +/* Provide a ENDFILE_SPEC appropriate for GNU/Linux. Here we tack on
18710 + the GNU/Linux magical crtend.o file (see crtstuff.c) which
18711 + provides part of the support for getting C++ file-scope static
18712 + object constructed before entering `main', followed by a normal
18713 + GNU/Linux "finalizer" file, `crtn.o'. */
18714 +
18715 +#undef ENDFILE_SPEC
18716 +#define ENDFILE_SPEC \
18717 + "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
18718 +
18719 +#undef ASM_SPEC
18720 +#define ASM_SPEC "%{!mno-pic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{mcpu=*:-mcpu=%*}"
18721 +
18722 +#undef LINK_SPEC
18723 +#define LINK_SPEC "%{version:-v} \
18724 + %{static:-Bstatic} \
18725 + %{shared:-shared} \
18726 + %{symbolic:-Bsymbolic} \
18727 + %{rdynamic:-export-dynamic} \
18728 + %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0} \
18729 + %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}}"
18730 +
18731 +#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
18732 +
18733 +/* This is how we tell the assembler that two symbols have the same value. */
18734 +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
18735 + do \
18736 + { \
18737 + assemble_name (FILE, NAME1); \
18738 + fputs (" = ", FILE); \
18739 + assemble_name (FILE, NAME2); \
18740 + fputc ('\n', FILE); \
18741 + } \
18742 + while (0)
18743 +
18744 +
18745 +
18746 +#undef CC1_SPEC
18747 +#define CC1_SPEC "%{profile:-p}"
18748 +
18749 +/* Target CPU builtins. */
18750 +#define TARGET_CPU_CPP_BUILTINS() \
18751 + do \
18752 + { \
18753 + builtin_define ("__avr32__"); \
18754 + builtin_define ("__AVR32__"); \
18755 + builtin_define ("__AVR32_LINUX__"); \
18756 + builtin_define (avr32_part->macro); \
18757 + builtin_define (avr32_arch->macro); \
18758 + if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A) \
18759 + builtin_define ("__AVR32_AVR32A__"); \
18760 + else \
18761 + builtin_define ("__AVR32_AVR32B__"); \
18762 + if (TARGET_UNALIGNED_WORD) \
18763 + builtin_define ("__AVR32_HAS_UNALIGNED_WORD__"); \
18764 + if (TARGET_SIMD) \
18765 + builtin_define ("__AVR32_HAS_SIMD__"); \
18766 + if (TARGET_DSP) \
18767 + builtin_define ("__AVR32_HAS_DSP__"); \
18768 + if (TARGET_RMW) \
18769 + builtin_define ("__AVR32_HAS_RMW__"); \
18770 + if (TARGET_BRANCH_PRED) \
18771 + builtin_define ("__AVR32_HAS_BRANCH_PRED__"); \
18772 + if (TARGET_FAST_FLOAT) \
18773 + builtin_define ("__AVR32_FAST_FLOAT__"); \
18774 + if (flag_pic) \
18775 + { \
18776 + builtin_define ("__PIC__"); \
18777 + builtin_define ("__pic__"); \
18778 + } \
18779 + } \
18780 + while (0)
18781 +
18782 +
18783 +
18784 +/* Call the function profiler with a given profile label. */
18785 +#undef FUNCTION_PROFILER
18786 +#define FUNCTION_PROFILER(STREAM, LABELNO) \
18787 + do \
18788 + { \
18789 + fprintf (STREAM, "\tmov\tlr, lo(mcount)\n\torh\tlr, hi(mcount)\n"); \
18790 + fprintf (STREAM, "\ticall lr\n"); \
18791 + } \
18792 + while (0)
18793 +
18794 +#define NO_PROFILE_COUNTERS 1
18795 +
18796 +/* For dynamic libraries to work */
18797 +/* #define PLT_REG_CALL_CLOBBERED 1 */
18798 +#define AVR32_ALWAYS_PIC 1
18799 +
18800 +/* uclibc does not implement sinf, cosf etc. */
18801 +#undef TARGET_C99_FUNCTIONS
18802 +#define TARGET_C99_FUNCTIONS 0
18803 +
18804 +#define LINK_GCC_C_SEQUENCE_SPEC \
18805 + "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
18806 diff -Nrup gcc-4.2.1/gcc/config/avr32/predicates.md gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/predicates.md
18807 --- gcc-4.2.1/gcc/config/avr32/predicates.md 1970-01-01 01:00:00.000000000 +0100
18808 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/predicates.md 2007-09-28 10:33:00.000000000 +0200
18809 @@ -0,0 +1,331 @@
18810 +;; AVR32 predicates file.
18811 +;; Copyright 2003-2006 Atmel Corporation.
18812 +;;
18813 +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
18814 +;;
18815 +;; This file is part of GCC.
18816 +;;
18817 +;; This program is free software; you can redistribute it and/or modify
18818 +;; it under the terms of the GNU General Public License as published by
18819 +;; the Free Software Foundation; either version 2 of the License, or
18820 +;; (at your option) any later version.
18821 +;;
18822 +;; This program is distributed in the hope that it will be useful,
18823 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18824 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18825 +;; GNU General Public License for more details.
18826 +;;
18827 +;; You should have received a copy of the GNU General Public License
18828 +;; along with this program; if not, write to the Free Software
18829 +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18830 +
18831 +
18832 +;; True if the operand is a memory reference which contains an
18833 +;; Address consisting of a single pointer register
18834 +(define_predicate "avr32_indirect_register_operand"
18835 + (and (match_code "mem")
18836 + (match_test "register_operand(XEXP(op, 0), SImode)")))
18837 +
18838 +
18839 +
18840 +;; Address expression with a base pointer offset with
18841 +;; a register displacement
18842 +(define_predicate "avr32_indexed_memory_operand"
18843 + (and (match_code "mem")
18844 + (match_test "GET_CODE(XEXP(op, 0)) == PLUS"))
18845 + {
18846 +
18847 + rtx op0 = XEXP(XEXP(op, 0), 0);
18848 + rtx op1 = XEXP(XEXP(op, 0), 1);
18849 +
18850 + return ((avr32_address_register_rtx_p (op0, 0)
18851 + && avr32_legitimate_index_p (GET_MODE(op), op1, 0))
18852 + || (avr32_address_register_rtx_p (op1, 0)
18853 + && avr32_legitimate_index_p (GET_MODE(op), op0, 0)));
18854 +
18855 + })
18856 +
18857 +;; Operand suitable for the ld.sb instruction
18858 +(define_predicate "load_sb_memory_operand"
18859 + (ior (match_operand 0 "avr32_indirect_register_operand")
18860 + (match_operand 0 "avr32_indexed_memory_operand")))
18861 +
18862 +
18863 +;; Operand suitable as operand to insns sign extending QI values
18864 +(define_predicate "extendqi_operand"
18865 + (ior (match_operand 0 "load_sb_memory_operand")
18866 + (match_operand 0 "register_operand")))
18867 +
18868 +(define_predicate "post_inc_memory_operand"
18869 + (and (match_code "mem")
18870 + (match_test "(GET_CODE(XEXP(op, 0)) == POST_INC)
18871 + && REG_P(XEXP(XEXP(op, 0), 0))")))
18872 +
18873 +(define_predicate "pre_dec_memory_operand"
18874 + (and (match_code "mem")
18875 + (match_test "(GET_CODE(XEXP(op, 0)) == PRE_DEC)
18876 + && REG_P(XEXP(XEXP(op, 0), 0))")))
18877 +
18878 +;; Operand suitable for add instructions
18879 +(define_predicate "avr32_add_operand"
18880 + (ior (match_operand 0 "register_operand")
18881 + (and (match_operand 0 "immediate_operand")
18882 + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is21\")"))))
18883 +
18884 +;; Operand is a power of two immediate
18885 +(define_predicate "power_of_two_operand"
18886 + (match_code "const_int")
18887 +{
18888 + HOST_WIDE_INT value = INTVAL (op);
18889 +
18890 + return value != 0 && (value & (value - 1)) == 0;
18891 +})
18892 +
18893 +;; Operand is a multiple of 8 immediate
18894 +(define_predicate "multiple_of_8_operand"
18895 + (match_code "const_int")
18896 +{
18897 + HOST_WIDE_INT value = INTVAL (op);
18898 +
18899 + return (value & 0x7) == 0 ;
18900 +})
18901 +
18902 +;; Operand is a multiple of 16 immediate
18903 +(define_predicate "multiple_of_16_operand"
18904 + (match_code "const_int")
18905 +{
18906 + HOST_WIDE_INT value = INTVAL (op);
18907 +
18908 + return (value & 0xf) == 0 ;
18909 +})
18910 +
18911 +;; Operand is a mask used for masking away upper bits of a reg
18912 +(define_predicate "avr32_mask_upper_bits_operand"
18913 + (match_code "const_int")
18914 +{
18915 + HOST_WIDE_INT value = INTVAL (op) + 1;
18916 +
18917 + return value != 1 && value != 0 && (value & (value - 1)) == 0;
18918 +})
18919 +
18920 +
18921 +;; Operand suitable for mul instructions
18922 +(define_predicate "avr32_mul_operand"
18923 + (ior (match_operand 0 "register_operand")
18924 + (and (match_operand 0 "immediate_operand")
18925 + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")"))))
18926 +
18927 +;; True for logical binary operators.
18928 +(define_predicate "logical_binary_operator"
18929 + (match_code "ior,xor,and"))
18930 +
18931 +;; True for logical shift operators
18932 +(define_predicate "logical_shift_operator"
18933 + (match_code "ashift,lshiftrt"))
18934 +
18935 +;; True for shift operand for logical and, or and eor insns
18936 +(define_predicate "avr32_logical_shift_operand"
18937 + (and (match_code "ashift,lshiftrt")
18938 + (ior (and (match_test "GET_CODE(XEXP(op, 1)) == CONST_INT")
18939 + (match_test "register_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))"))
18940 + (and (match_test "GET_CODE(XEXP(op, 0)) == CONST_INT")
18941 + (match_test "register_operand(XEXP(op, 1), GET_MODE(XEXP(op, 1)))"))))
18942 + {
18943 + return 1;
18944 + }
18945 + )
18946 +
18947 +
18948 +;; Predicate for second operand to and, ior and xor insn patterns
18949 +(define_predicate "avr32_logical_insn_operand"
18950 + (ior (match_operand 0 "register_operand")
18951 + (match_operand 0 "avr32_logical_shift_operand"))
18952 + {
18953 + return 1;
18954 + }
18955 +)
18956 +
18957 +
18958 +;; True for avr32 comparison operators
18959 +(define_predicate "avr32_comparison_operator"
18960 + (ior (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu")
18961 + (and (match_code "unspec")
18962 + (match_test "(XINT(op, 1) == UNSPEC_COND_MI)
18963 + || (XINT(op, 1) == UNSPEC_COND_PL)"))))
18964 +
18965 +;; True for avr32 comparison operand
18966 +(define_predicate "avr32_comparison_operand"
18967 + (ior (and (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu")
18968 + (match_test "(rtx_equal_p (XEXP(op,0), cc0_rtx) && rtx_equal_p (XEXP(op,1), const0_rtx))"))
18969 + (and (match_code "unspec")
18970 + (match_test "(XINT(op, 1) == UNSPEC_COND_MI)
18971 + || (XINT(op, 1) == UNSPEC_COND_PL)"))))
18972 +
18973 +;; True if this is a const_int with one bit set
18974 +(define_predicate "one_bit_set_operand"
18975 + (match_code "const_int")
18976 + {
18977 + int i;
18978 + int value;
18979 + int ones = 0;
18980 +
18981 + value = INTVAL(op);
18982 + for ( i = 0 ; i < 32; i++ ){
18983 + if ( value & ( 1 << i ) ){
18984 + ones++;
18985 + }
18986 + }
18987 +
18988 + return ( ones == 1 );
18989 + })
18990 +
18991 +
18992 +;; True if this is a const_int with one bit cleared
18993 +(define_predicate "one_bit_cleared_operand"
18994 + (match_code "const_int")
18995 + {
18996 + int i;
18997 + int value;
18998 + int zeroes = 0;
18999 +
19000 + value = INTVAL(op);
19001 + for ( i = 0 ; i < 32; i++ ){
19002 + if ( !(value & ( 1 << i )) ){
19003 + zeroes++;
19004 + }
19005 + }
19006 +
19007 + return ( zeroes == 1 );
19008 + })
19009 +
19010 +
19011 +;; True if this is a register or immediate operand
19012 +(define_predicate "register_immediate_operand"
19013 + (ior (match_operand 0 "register_operand")
19014 + (match_operand 0 "immediate_operand")))
19015 +
19016 +
19017 +;; True is this is an operand containing a label_ref
19018 +(define_predicate "avr32_label_ref_operand"
19019 + (and (match_code "mem")
19020 + (match_test "avr32_find_symbol(op)
19021 + && (GET_CODE(avr32_find_symbol(op)) == LABEL_REF)")))
19022 +
19023 +;; True is this is a valid symbol pointing to the constant pool
19024 +(define_predicate "avr32_const_pool_operand"
19025 + (and (match_code "symbol_ref")
19026 + (match_test "CONSTANT_POOL_ADDRESS_P(op)"))
19027 + {
19028 + return (flag_pic ? (!(symbol_mentioned_p (get_pool_constant (op))
19029 + || label_mentioned_p (get_pool_constant (op)))
19030 + || avr32_got_mentioned_p(get_pool_constant (op)))
19031 + : true);
19032 + }
19033 +)
19034 +
19035 +;; True is this is a memory reference to the constant or mini pool
19036 +(define_predicate "avr32_const_pool_ref_operand"
19037 + (ior (match_operand 0 "avr32_label_ref_operand")
19038 + (and (match_code "mem")
19039 + (match_test "avr32_const_pool_operand(XEXP(op,0), GET_MODE(XEXP(op,0)))"))))
19040 +
19041 +
19042 +;; Legal source operand for movti insns
19043 +(define_predicate "avr32_movti_src_operand"
19044 + (ior (match_operand 0 "avr32_const_pool_ref_operand")
19045 + (ior (ior (match_operand 0 "register_immediate_operand")
19046 + (match_operand 0 "avr32_indirect_register_operand"))
19047 + (match_operand 0 "post_inc_memory_operand"))))
19048 +
19049 +;; Legal destination operand for movti insns
19050 +(define_predicate "avr32_movti_dst_operand"
19051 + (ior (ior (match_operand 0 "register_operand")
19052 + (match_operand 0 "avr32_indirect_register_operand"))
19053 + (match_operand 0 "pre_dec_memory_operand")))
19054 +
19055 +
19056 +;; True is this is a k12 offseted memory operand
19057 +(define_predicate "avr32_k12_memory_operand"
19058 + (and (match_code "mem")
19059 + (ior (match_test "REG_P(XEXP(op, 0))")
19060 + (match_test "GET_CODE(XEXP(op, 0)) == PLUS
19061 + && REG_P(XEXP(XEXP(op, 0), 0))
19062 + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)
19063 + && (CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)),
19064 + 'K', (mode == SImode) ? \"Ks14\" : ((mode == HImode) ? \"Ks13\" : \"Ks12\")))"))))
19065 +
19066 +;; True is this is a memory operand with an immediate displacement
19067 +(define_predicate "avr32_imm_disp_memory_operand"
19068 + (and (match_code "mem")
19069 + (match_test "GET_CODE(XEXP(op, 0)) == PLUS
19070 + && REG_P(XEXP(XEXP(op, 0), 0))
19071 + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)")))
19072 +
19073 +;; True is this is a bswap operand
19074 +(define_predicate "avr32_bswap_operand"
19075 + (ior (match_operand 0 "avr32_k12_memory_operand")
19076 + (match_operand 0 "register_operand")))
19077 +
19078 +;; True is this is a valid coprocessor insn memory operand
19079 +(define_predicate "avr32_cop_memory_operand"
19080 + (and (match_operand 0 "memory_operand")
19081 + (not (match_test "GET_CODE(XEXP(op, 0)) == PLUS
19082 + && REG_P(XEXP(XEXP(op, 0), 0))
19083 + && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)
19084 + && !(CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), 'K', \"Ku10\"))"))))
19085 +
19086 +;; True is this is a valid source/destination operand
19087 +;; for moving values to/from a coprocessor
19088 +(define_predicate "avr32_cop_move_operand"
19089 + (ior (match_operand 0 "register_operand")
19090 + (match_operand 0 "avr32_cop_memory_operand")))
19091 +
19092 +
19093 +;; True is this is a valid extract byte offset for use in
19094 +;; load extracted index insns
19095 +(define_predicate "avr32_extract_shift_operand"
19096 + (and (match_operand 0 "const_int_operand")
19097 + (match_test "(INTVAL(op) == 0) || (INTVAL(op) == 8)
19098 + || (INTVAL(op) == 16) || (INTVAL(op) == 24)")))
19099 +
19100 +;; True is this is a floating-point register
19101 +(define_predicate "avr32_fp_register_operand"
19102 + (and (match_operand 0 "register_operand")
19103 + (match_test "REGNO_REG_CLASS(REGNO(op)) == FP_REGS")))
19104 +
19105 +;; True is this is valid avr32 symbol operand
19106 +(define_predicate "avr32_symbol_operand"
19107 + (ior (match_code "label_ref, symbol_ref")
19108 + (and (match_code "const")
19109 + (match_test "avr32_find_symbol(op)"))))
19110 +
19111 +;; True is this is valid operand for the lda.w and call pseudo insns
19112 +(define_predicate "avr32_address_operand"
19113 + (and (match_code "label_ref, symbol_ref")
19114 + (ior (match_test "TARGET_HAS_ASM_ADDR_PSEUDOS")
19115 + (match_test "flag_pic")) ))
19116 +
19117 +;; True if this is a avr32 call operand
19118 +(define_predicate "avr32_call_operand"
19119 + (ior (ior (match_operand 0 "register_operand")
19120 + (ior (match_operand 0 "avr32_const_pool_ref_operand")
19121 + (match_operand 0 "avr32_address_operand")))
19122 + (match_test "SYMBOL_REF_RCALL_FUNCTION_P(op)")))
19123 +
19124 +;; Return true for operators performing ALU operations
19125 +
19126 +(define_predicate "alu_operator"
19127 + (match_code "ior, xor, and, plus, minus, ashift, lshiftrt, ashiftrt"))
19128 +
19129 +(define_predicate "avr32_add_shift_immediate_operand"
19130 + (and (match_operand 0 "immediate_operand")
19131 + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ku02\")")))
19132 +
19133 +(define_predicate "avr32_cond_register_immediate_operand"
19134 + (ior (match_operand 0 "register_operand")
19135 + (and (match_operand 0 "immediate_operand")
19136 + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")"))))
19137 +
19138 +(define_predicate "avr32_cond_immediate_operand"
19139 + (and (match_operand 0 "immediate_operand")
19140 + (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is08\")")))
19141 diff -Nrup gcc-4.2.1/gcc/config/avr32/simd.md gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/simd.md
19142 --- gcc-4.2.1/gcc/config/avr32/simd.md 1970-01-01 01:00:00.000000000 +0100
19143 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/simd.md 2007-05-07 14:29:10.000000000 +0200
19144 @@ -0,0 +1,145 @@
19145 +;; AVR32 machine description file for SIMD instructions.
19146 +;; Copyright 2003-2006 Atmel Corporation.
19147 +;;
19148 +;; Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
19149 +;;
19150 +;; This file is part of GCC.
19151 +;;
19152 +;; This program is free software; you can redistribute it and/or modify
19153 +;; it under the terms of the GNU General Public License as published by
19154 +;; the Free Software Foundation; either version 2 of the License, or
19155 +;; (at your option) any later version.
19156 +;;
19157 +;; This program is distributed in the hope that it will be useful,
19158 +;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19159 +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19160 +;; GNU General Public License for more details.
19161 +;;
19162 +;; You should have received a copy of the GNU General Public License
19163 +;; along with this program; if not, write to the Free Software
19164 +;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19165 +
19166 +;; -*- Mode: Scheme -*-
19167 +
19168 +
19169 +;; Vector modes
19170 +(define_mode_macro VECM [V2HI V4QI])
19171 +(define_mode_attr size [(V2HI "h") (V4QI "b")])
19172 +
19173 +(define_insn "add<mode>3"
19174 + [(set (match_operand:VECM 0 "register_operand" "=r")
19175 + (plus:VECM (match_operand:VECM 1 "register_operand" "r")
19176 + (match_operand:VECM 2 "register_operand" "r")))]
19177 + "TARGET_SIMD"
19178 + "padd.<size>\t%0, %1, %2"
19179 + [(set_attr "length" "4")
19180 + (set_attr "type" "alu")])
19181 +
19182 +
19183 +(define_insn "sub<mode>3"
19184 + [(set (match_operand:VECM 0 "register_operand" "=r")
19185 + (minus:VECM (match_operand:VECM 1 "register_operand" "r")
19186 + (match_operand:VECM 2 "register_operand" "r")))]
19187 + "TARGET_SIMD"
19188 + "psub.<size>\t%0, %1, %2"
19189 + [(set_attr "length" "4")
19190 + (set_attr "type" "alu")])
19191 +
19192 +
19193 +(define_insn "abs<mode>2"
19194 + [(set (match_operand:VECM 0 "register_operand" "=r")
19195 + (abs:VECM (match_operand:VECM 1 "register_operand" "r")))]
19196 + "TARGET_SIMD"
19197 + "pabs.s<size>\t%0, %1"
19198 + [(set_attr "length" "4")
19199 + (set_attr "type" "alu")])
19200 +
19201 +(define_insn "ashl<mode>3"
19202 + [(set (match_operand:VECM 0 "register_operand" "=r")
19203 + (ashift:VECM (match_operand:VECM 1 "register_operand" "r")
19204 + (match_operand:SI 2 "immediate_operand" "Ku04")))]
19205 + "TARGET_SIMD"
19206 + "plsl.<size>\t%0, %1, %2"
19207 + [(set_attr "length" "4")
19208 + (set_attr "type" "alu")])
19209 +
19210 +(define_insn "ashr<mode>3"
19211 + [(set (match_operand:VECM 0 "register_operand" "=r")
19212 + (ashiftrt:VECM (match_operand:VECM 1 "register_operand" "r")
19213 + (match_operand:SI 2 "immediate_operand" "Ku04")))]
19214 + "TARGET_SIMD"
19215 + "pasr.<size>\t%0, %1, %2"
19216 + [(set_attr "length" "4")
19217 + (set_attr "type" "alu")])
19218 +
19219 +(define_insn "lshr<mode>3"
19220 + [(set (match_operand:VECM 0 "register_operand" "=r")
19221 + (lshiftrt:VECM (match_operand:VECM 1 "register_operand" "r")
19222 + (match_operand:SI 2 "immediate_operand" "Ku04")))]
19223 + "TARGET_SIMD"
19224 + "plsr.<size>\t%0, %1, %2"
19225 + [(set_attr "length" "4")
19226 + (set_attr "type" "alu")])
19227 +
19228 +(define_insn "smaxv2hi3"
19229 + [(set (match_operand:V2HI 0 "register_operand" "=r")
19230 + (smax:V2HI (match_operand:V2HI 1 "register_operand" "r")
19231 + (match_operand:V2HI 2 "register_operand" "r")))]
19232 +
19233 + "TARGET_SIMD"
19234 + "pmax.sh\t%0, %1, %2"
19235 + [(set_attr "length" "4")
19236 + (set_attr "type" "alu")])
19237 +
19238 +(define_insn "sminv2hi3"
19239 + [(set (match_operand:V2HI 0 "register_operand" "=r")
19240 + (smin:V2HI (match_operand:V2HI 1 "register_operand" "r")
19241 + (match_operand:V2HI 2 "register_operand" "r")))]
19242 +
19243 + "TARGET_SIMD"
19244 + "pmin.sh\t%0, %1, %2"
19245 + [(set_attr "length" "4")
19246 + (set_attr "type" "alu")])
19247 +
19248 +(define_insn "umaxv4qi3"
19249 + [(set (match_operand:V4QI 0 "register_operand" "=r")
19250 + (umax:V4QI (match_operand:V4QI 1 "register_operand" "r")
19251 + (match_operand:V4QI 2 "register_operand" "r")))]
19252 +
19253 + "TARGET_SIMD"
19254 + "pmax.ub\t%0, %1, %2"
19255 + [(set_attr "length" "4")
19256 + (set_attr "type" "alu")])
19257 +
19258 +(define_insn "uminv4qi3"
19259 + [(set (match_operand:V4QI 0 "register_operand" "=r")
19260 + (umin:V4QI (match_operand:V4QI 1 "register_operand" "r")
19261 + (match_operand:V4QI 2 "register_operand" "r")))]
19262 +
19263 + "TARGET_SIMD"
19264 + "pmin.ub\t%0, %1, %2"
19265 + [(set_attr "length" "4")
19266 + (set_attr "type" "alu")])
19267 +
19268 +
19269 +(define_insn "addsubv2hi"
19270 + [(set (match_operand:V2HI 0 "register_operand" "=r")
19271 + (vec_concat:V2HI
19272 + (plus:HI (match_operand:HI 1 "register_operand" "r")
19273 + (match_operand:HI 2 "register_operand" "r"))
19274 + (minus:HI (match_dup 1) (match_dup 2))))]
19275 + "TARGET_SIMD"
19276 + "paddsub.h\t%0, %1:b, %2:b"
19277 + [(set_attr "length" "4")
19278 + (set_attr "type" "alu")])
19279 +
19280 +(define_insn "subaddv2hi"
19281 + [(set (match_operand:V2HI 0 "register_operand" "=r")
19282 + (vec_concat:V2HI
19283 + (minus:HI (match_operand:HI 1 "register_operand" "r")
19284 + (match_operand:HI 2 "register_operand" "r"))
19285 + (plus:HI (match_dup 1) (match_dup 2))))]
19286 + "TARGET_SIMD"
19287 + "psubadd.h\t%0, %1:b, %2:b"
19288 + [(set_attr "length" "4")
19289 + (set_attr "type" "alu")])
19290 diff -Nrup gcc-4.2.1/gcc/config/avr32/sync.md gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/sync.md
19291 --- gcc-4.2.1/gcc/config/avr32/sync.md 1970-01-01 01:00:00.000000000 +0100
19292 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/sync.md 2007-09-28 10:33:00.000000000 +0200
19293 @@ -0,0 +1,175 @@
19294 +;;=================================================================
19295 +;; Atomic operations
19296 +;;=================================================================
19297 +
19298 +
19299 +(define_insn "sync_compare_and_swapsi"
19300 + [(set (match_operand:SI 0 "register_operand" "=&r,&r")
19301 + (match_operand:SI 1 "memory_operand" "+RKs16,+RKs16"))
19302 + (set (match_dup 1)
19303 + (unspec_volatile:SI
19304 + [(match_dup 1)
19305 + (match_operand:SI 2 "register_immediate_operand" "r,Ks21")
19306 + (match_operand:SI 3 "register_operand" "r,r")]
19307 + VUNSPEC_SYNC_CMPXCHG)) ]
19308 + ""
19309 + "0:
19310 + ssrf\t5
19311 + ld.w\t%0,%1
19312 + cp.w\t%0,%2
19313 + brne\t0f
19314 + stcond\t%1, %3
19315 + brne\t0b
19316 + 0:
19317 + "
19318 + [(set_attr "length" "16,18")
19319 + (set_attr "cc" "clobber")]
19320 + )
19321 +
19322 +
19323 +(define_code_macro atomic_op [plus minus and ior xor])
19324 +(define_code_attr atomic_asm_insn [(plus "add") (minus "sub") (and "and") (ior "or") (xor "eor")])
19325 +(define_code_attr atomic_insn [(plus "add") (minus "sub") (and "and") (ior "ior") (xor "xor")])
19326 +
19327 +(define_insn "sync_loadsi"
19328 + [(set (match_operand:SI 0 "register_operand" "=r")
19329 + (unspec_volatile:SI
19330 + [(match_operand:SI 1 "memory_operand" "RKs16")
19331 + (label_ref (match_operand 2 "" ""))]
19332 + VUNSPEC_SYNC_SET_LOCK_AND_LOAD) )]
19333 + ""
19334 + "%2:
19335 + ssrf\t5
19336 + ld.w\t%0,%1"
19337 + [(set_attr "length" "6")
19338 + (set_attr "cc" "clobber")]
19339 + )
19340 +
19341 +(define_insn "sync_store_if_lock"
19342 + [(set (match_operand:SI 0 "memory_operand" "=RKs16")
19343 + (unspec_volatile:SI
19344 + [(match_operand:SI 1 "register_operand" "r")
19345 + (label_ref (match_operand 2 "" ""))]
19346 + VUNSPEC_SYNC_STORE_IF_LOCK) )]
19347 + ""
19348 + "stcond\t%0, %1
19349 + brne\t%2"
19350 + [(set_attr "length" "6")
19351 + (set_attr "cc" "clobber")]
19352 + )
19353 +
19354 +
19355 +(define_expand "sync_<atomic_insn>si"
19356 + [(set (match_dup 2)
19357 + (unspec_volatile:SI
19358 + [(match_operand:SI 0 "memory_operand" "")
19359 + (match_dup 3)]
19360 + VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
19361 + (set (match_dup 2)
19362 + (atomic_op:SI (match_dup 2)
19363 + (match_operand:SI 1 "register_immediate_operand" "")))
19364 + (set (match_dup 0)
19365 + (unspec_volatile:SI
19366 + [(match_dup 2)
19367 + (match_dup 3)]
19368 + VUNSPEC_SYNC_STORE_IF_LOCK) )]
19369 + ""
19370 + {
19371 + operands[2] = gen_reg_rtx (SImode);
19372 + operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
19373 + }
19374 + )
19375 +
19376 +
19377 +
19378 +(define_expand "sync_old_<atomic_insn>si"
19379 + [(set (match_operand:SI 0 "register_operand" "")
19380 + (unspec_volatile:SI
19381 + [(match_operand:SI 1 "memory_operand" "")
19382 + (match_dup 4)]
19383 + VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
19384 + (set (match_dup 3)
19385 + (atomic_op:SI (match_dup 0)
19386 + (match_operand:SI 2 "register_immediate_operand" "")))
19387 + (set (match_dup 1)
19388 + (unspec_volatile:SI
19389 + [(match_dup 3)
19390 + (match_dup 4)]
19391 + VUNSPEC_SYNC_STORE_IF_LOCK) )]
19392 + ""
19393 + {
19394 + operands[3] = gen_reg_rtx (SImode);
19395 + operands[4] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
19396 + }
19397 + )
19398 +
19399 +(define_expand "sync_new_<atomic_insn>si"
19400 + [(set (match_operand:SI 0 "register_operand" "")
19401 + (unspec_volatile:SI
19402 + [(match_operand:SI 1 "memory_operand" "")
19403 + (match_dup 3)]
19404 + VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
19405 + (set (match_dup 0)
19406 + (atomic_op:SI (match_dup 0)
19407 + (match_operand:SI 2 "register_immediate_operand" "")))
19408 + (set (match_dup 1)
19409 + (unspec_volatile:SI
19410 + [(match_dup 0)
19411 + (match_dup 3)]
19412 + VUNSPEC_SYNC_STORE_IF_LOCK) )]
19413 + ""
19414 + {
19415 + operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
19416 + }
19417 + )
19418 +
19419 +
19420 +;(define_insn "sync_<atomic_insn>si"
19421 +; [(set (match_operand:SI 0 "memory_operand" "+RKs16")
19422 +; (unspec_volatile:SI
19423 +; [(atomic_op:SI (match_dup 0)
19424 +; (match_operand:SI 1 "register_operand" "r"))]
19425 +; VUNSPEC_SYNC_CMPXCHG))
19426 +; (clobber (match_scratch:SI 2 "=&r"))]
19427 +; ""
19428 +; "0:
19429 +; ssrf\t5
19430 +; ld.w\t%2,%0
19431 +; <atomic_asm_insn>\t%2,%1
19432 +; stcond\t%0, %2
19433 +; brne\t0b
19434 +; "
19435 +; [(set_attr "length" "14")
19436 +; (set_attr "cc" "clobber")]
19437 +; )
19438 +;
19439 +;(define_insn "sync_new_<atomic_insn>si"
19440 +; [(set (match_operand:SI 1 "memory_operand" "+RKs16")
19441 +; (unspec_volatile:SI
19442 +; [(atomic_op:SI (match_dup 1)
19443 +; (match_operand:SI 2 "register_operand" "r"))]
19444 +; VUNSPEC_SYNC_CMPXCHG))
19445 +; (set (match_operand:SI 0 "register_operand" "=&r")
19446 +; (atomic_op:SI (match_dup 1)
19447 +; (match_dup 2)))]
19448 +; ""
19449 +; "0:
19450 +; ssrf\t5
19451 +; ld.w\t%0,%1
19452 +; <atomic_asm_insn>\t%0,%2
19453 +; stcond\t%1, %0
19454 +; brne\t0b
19455 +; "
19456 +; [(set_attr "length" "14")
19457 +; (set_attr "cc" "clobber")]
19458 +; )
19459 +
19460 +(define_insn "sync_lock_test_and_setsi"
19461 + [ (set (match_operand:SI 0 "register_operand" "=&r")
19462 + (match_operand:SI 1 "memory_operand" "+RKu00"))
19463 + (set (match_dup 1)
19464 + (match_operand:SI 2 "register_operand" "r")) ]
19465 + ""
19466 + "xchg\t%0, %p1, %2"
19467 + [(set_attr "length" "4")]
19468 + )
19469 diff -Nrup gcc-4.2.1/gcc/config/avr32/t-avr32 gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/t-avr32
19470 --- gcc-4.2.1/gcc/config/avr32/t-avr32 1970-01-01 01:00:00.000000000 +0100
19471 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/t-avr32 2007-09-28 10:33:00.000000000 +0200
19472 @@ -0,0 +1,76 @@
19473 +
19474 +MD_INCLUDES= $(srcdir)/config/avr32/avr32.md \
19475 + $(srcdir)/config/avr32/sync.md \
19476 + $(srcdir)/config/avr32/fpcp.md \
19477 + $(srcdir)/config/avr32/simd.md \
19478 + $(srcdir)/config/avr32/predicates.md
19479 +
19480 +s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
19481 + s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
19482 +
19483 +# We want fine grained libraries, so use the new code
19484 +# to build the floating point emulation libraries.
19485 +FPBIT = fp-bit.c
19486 +DPBIT = dp-bit.c
19487 +
19488 +LIB1ASMSRC = avr32/lib1funcs.S
19489 +LIB1ASMFUNCS = _avr32_f64_mul _avr32_f64_addsub _avr32_f64_addsub_fast _avr32_f64_to_u32 \
19490 + _avr32_f64_to_s32 _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 \
19491 + _avr32_s32_to_f64 _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \
19492 + _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt _avr32_f64_div \
19493 + _avr32_f32_div _avr32_f32_div_fast _avr32_f32_addsub _avr32_f32_addsub_fast \
19494 + _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \
19495 + _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32
19496 +
19497 +#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S
19498 +
19499 +MULTILIB_OPTIONS = march=ap/march=uc
19500 +MULTILIB_DIRNAMES = ap uc
19501 +MULTILIB_EXCEPTIONS =
19502 +MULTILIB_MATCHES = march?ap=mcpu?ap7000
19503 +MULTILIB_MATCHES += march?ap=mcpu?ap7010
19504 +MULTILIB_MATCHES += march?ap=mcpu?ap7020
19505 +MULTILIB_MATCHES += march?uc=mcpu?uc3a0256
19506 +MULTILIB_MATCHES += march?uc=mcpu?uc3a0512
19507 +MULTILIB_MATCHES += march?uc=mcpu?uc3a1128
19508 +MULTILIB_MATCHES += march?uc=mcpu?uc3a1256
19509 +MULTILIB_MATCHES += march?uc=mcpu?uc3a1512
19510 +MULTILIB_MATCHES += march?uc=mcpu?uc3b064
19511 +MULTILIB_MATCHES += march?uc=mcpu?uc3b0128
19512 +MULTILIB_MATCHES += march?uc=mcpu?uc3b0256
19513 +MULTILIB_MATCHES += march?uc=mcpu?uc3b164
19514 +MULTILIB_MATCHES += march?uc=mcpu?uc3b1128
19515 +MULTILIB_MATCHES += march?uc=mcpu?uc3b1256
19516 +MULTILIB_MATCHES += march?ap=mpart?ap7000
19517 +MULTILIB_MATCHES += march?ap=mpart?ap7010
19518 +MULTILIB_MATCHES += march?ap=mpart?ap7020
19519 +MULTILIB_MATCHES += march?uc=mpart?uc3a0256
19520 +MULTILIB_MATCHES += march?uc=mpart?uc3a0512
19521 +MULTILIB_MATCHES += march?uc=mpart?uc3a1128
19522 +MULTILIB_MATCHES += march?uc=mpart?uc3a1256
19523 +MULTILIB_MATCHES += march?uc=mpart?uc3a1512
19524 +MULTILIB_MATCHES += march?uc=mpart?uc3b064
19525 +MULTILIB_MATCHES += march?uc=mpart?uc3b0128
19526 +MULTILIB_MATCHES += march?uc=mpart?uc3b0256
19527 +MULTILIB_MATCHES += march?uc=mpart?uc3b164
19528 +MULTILIB_MATCHES += march?uc=mpart?uc3b1128
19529 +MULTILIB_MATCHES += march?uc=mpart?uc3b1256
19530 +
19531 +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o
19532 +
19533 +CRTSTUFF_T_CFLAGS = -mrelax
19534 +CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC
19535 +TARGET_LIBGCC2_CFLAGS += -mrelax
19536 +
19537 +LIBGCC = stmp-multilib
19538 +INSTALL_LIBGCC = install-multilib
19539 +
19540 +fp-bit.c: $(srcdir)/config/fp-bit.c
19541 + echo '#define FLOAT' > fp-bit.c
19542 + cat $(srcdir)/config/fp-bit.c >> fp-bit.c
19543 +
19544 +dp-bit.c: $(srcdir)/config/fp-bit.c
19545 + cat $(srcdir)/config/fp-bit.c > dp-bit.c
19546 +
19547 +
19548 +
19549 diff -Nrup gcc-4.2.1/gcc/config/avr32/t-elf gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/t-elf
19550 --- gcc-4.2.1/gcc/config/avr32/t-elf 1970-01-01 01:00:00.000000000 +0100
19551 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/t-elf 2007-05-07 14:29:10.000000000 +0200
19552 @@ -0,0 +1,16 @@
19553 +
19554 +# Assemble startup files.
19555 +$(T)crti.o: $(srcdir)/config/avr32/crti.asm $(GCC_PASSES)
19556 + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \
19557 + -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/avr32/crti.asm
19558 +
19559 +$(T)crtn.o: $(srcdir)/config/avr32/crtn.asm $(GCC_PASSES)
19560 + $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \
19561 + -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/avr32/crtn.asm
19562 +
19563 +
19564 +# Build the libraries for both hard and soft floating point
19565 +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o
19566 +
19567 +LIBGCC = stmp-multilib
19568 +INSTALL_LIBGCC = install-multilib
19569 diff -Nrup gcc-4.2.1/gcc/config/avr32/uclinux-elf.h gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/uclinux-elf.h
19570 --- gcc-4.2.1/gcc/config/avr32/uclinux-elf.h 1970-01-01 01:00:00.000000000 +0100
19571 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/avr32/uclinux-elf.h 2007-05-07 14:29:10.000000000 +0200
19572 @@ -0,0 +1,20 @@
19573 +
19574 +/* Run-time Target Specification. */
19575 +#undef TARGET_VERSION
19576 +#define TARGET_VERSION fputs (" (AVR32 uClinux with ELF)", stderr)
19577 +
19578 +/* We don't want a .jcr section on uClinux. As if this makes a difference... */
19579 +#define TARGET_USE_JCR_SECTION 0
19580 +
19581 +/* Here we go. Drop the crtbegin/crtend stuff completely. */
19582 +#undef STARTFILE_SPEC
19583 +#define STARTFILE_SPEC \
19584 + "%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s}" \
19585 + " %{!p:%{profile:gcrt1.o%s}" \
19586 + " %{!profile:crt1.o%s}}}} crti.o%s"
19587 +
19588 +#undef ENDFILE_SPEC
19589 +#define ENDFILE_SPEC "crtn.o%s"
19590 +
19591 +#undef TARGET_DEFAULT
19592 +#define TARGET_DEFAULT (AVR32_FLAG_NO_INIT_GOT)
19593 diff -Nrup gcc-4.2.1/gcc/config/host-linux.c gcc-4.2.1.atmel.1.3.2/gcc/config/host-linux.c
19594 --- gcc-4.2.1/gcc/config/host-linux.c 2005-08-01 19:43:33.000000000 +0200
19595 +++ gcc-4.2.1.atmel.1.3.2/gcc/config/host-linux.c 2007-05-07 14:29:15.000000000 +0200
19596 @@ -26,6 +26,9 @@
19597 #include "hosthooks.h"
19598 #include "hosthooks-def.h"
19599
19600 +#ifndef SSIZE_MAX
19601 +#define SSIZE_MAX LONG_MAX
19602 +#endif
19603
19604 /* Linux has a feature called exec-shield-randomize that perturbs the
19605 address of non-fixed mapped segments by a (relatively) small amount.
19606 diff -Nrup gcc-4.2.1/gcc/config.gcc gcc-4.2.1.atmel.1.3.2/gcc/config.gcc
19607 --- gcc-4.2.1/gcc/config.gcc 2007-02-03 06:25:20.000000000 +0100
19608 +++ gcc-4.2.1.atmel.1.3.2/gcc/config.gcc 2007-09-28 10:33:09.000000000 +0200
19609 @@ -782,6 +782,24 @@ avr-*-*)
19610 tm_file="avr/avr.h dbxelf.h"
19611 use_fixproto=yes
19612 ;;
19613 +avr32*-*-linux*)
19614 + tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h "
19615 + tmake_file="t-linux avr32/t-avr32 avr32/t-elf"
19616 + extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
19617 + extra_modes=avr32/avr32-modes.def
19618 + gnu_ld=yes
19619 + ;;
19620 +avr32*-*-uclinux*)
19621 + tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/uclinux-elf.h avr32/avr32.h"
19622 + tmake_file="t-linux avr32/t-avr32 avr32/t-elf"
19623 + extra_modes=avr32/avr32-modes.def
19624 + gnu_ld=yes
19625 + ;;
19626 +avr32-*-*)
19627 + tm_file="dbxelf.h elfos.h avr32/avr32.h avr32/avr32-elf.h"
19628 + tmake_file="avr32/t-avr32 avr32/t-elf"
19629 + extra_modes=avr32/avr32-modes.def
19630 + ;;
19631 bfin*-elf*)
19632 tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h"
19633 tmake_file=bfin/t-bfin-elf
19634 @@ -1682,6 +1700,9 @@ pdp11-*-bsd)
19635 pdp11-*-*)
19636 use_fixproto=yes
19637 ;;
19638 +avr-*-*)
19639 + use_fixproto=yes
19640 + ;;
19641 # port not yet contributed
19642 #powerpc-*-openbsd*)
19643 # tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-fprules-fpbit "
19644 @@ -2718,6 +2739,32 @@ case "${target}" in
19645 fi
19646 ;;
19647
19648 + avr32*-*-*)
19649 + supported_defaults="part arch"
19650 +
19651 + case "$with_part" in
19652 + "" \
19653 + | "ap7000" | "ap7010" | "ap7020" | "uc3a0256" | "uc3a0512" | "uc3a1128" | "uc3a1256" | "uc3a1512" )
19654 + # OK
19655 + ;;
19656 + *)
19657 + echo "Unknown part used in --with-part=$with_part" 1>&2
19658 + exit 1
19659 + ;;
19660 + esac
19661 +
19662 + case "$with_arch" in
19663 + "" \
19664 + | "ap" | "uc")
19665 + # OK
19666 + ;;
19667 + *)
19668 + echo "Unknown arch used in --with-arch=$with_arch" 1>&2
19669 + exit 1
19670 + ;;
19671 + esac
19672 + ;;
19673 +
19674 fr*-*-*linux*)
19675 supported_defaults=cpu
19676 case "$with_cpu" in
19677 diff -Nrup gcc-4.2.1/gcc/doc/extend.texi gcc-4.2.1.atmel.1.3.2/gcc/doc/extend.texi
19678 --- gcc-4.2.1/gcc/doc/extend.texi 2007-03-12 23:10:12.000000000 +0100
19679 +++ gcc-4.2.1.atmel.1.3.2/gcc/doc/extend.texi 2007-09-28 10:32:30.000000000 +0200
19680 @@ -1981,7 +1981,7 @@ this attribute to work correctly.
19681
19682 @item interrupt
19683 @cindex interrupt handler functions
19684 -Use this attribute on the ARM, AVR, C4x, CRX, M32C, M32R/D, MS1, and Xstormy16
19685 +Use this attribute on the ARM, AVR, AVR32, C4x, CRX, M32C, M32R/D, MS1, and Xstormy16
19686 ports to indicate that the specified function is an interrupt handler.
19687 The compiler will generate function entry and exit sequences suitable
19688 for use in an interrupt handler when this attribute is present.
19689 @@ -2000,6 +2000,15 @@ void f () __attribute__ ((interrupt ("IR
19690
19691 Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@.
19692
19693 +Note, for the AVR32, you can specify which banking scheme is used for
19694 +the interrupt mode this interrupt handler is used in like this:
19695 +
19696 +@smallexample
19697 +void f () __attribute__ ((interrupt ("FULL")));
19698 +@end smallexample
19699 +
19700 +Permissible values for this parameter are: FULL, HALF, NONE and UNDEF.
19701 +
19702 @item interrupt_handler
19703 @cindex interrupt handler functions on the Blackfin, m68k, H8/300 and SH processors
19704 Use this attribute on the Blackfin, m68k, H8/300, H8/300H, H8S, and SH to
19705 @@ -6167,6 +6176,7 @@ instructions, but allow the compiler to
19706 @menu
19707 * Alpha Built-in Functions::
19708 * ARM Built-in Functions::
19709 +* AVR32 Built-in Functions::
19710 * Blackfin Built-in Functions::
19711 * FR-V Built-in Functions::
19712 * X86 Built-in Functions::
19713 @@ -6405,6 +6415,54 @@ long long __builtin_arm_wxor (long long,
19714 long long __builtin_arm_wzero ()
19715 @end smallexample
19716
19717 +@node AVR32 Built-in Functions
19718 +@subsection AVR32 Built-in Functions
19719 +
19720 +
19721 +@smallexample
19722 +
19723 +int __builtin_sats (int /*Rd*/,int /*sa*/, int /*bn*/)
19724 +int __builtin_satu (int /*Rd*/,int /*sa*/, int /*bn*/)
19725 +int __builtin_satrnds (int /*Rd*/,int /*sa*/, int /*bn*/)
19726 +int __builtin_satrndu (int /*Rd*/,int /*sa*/, int /*bn*/)
19727 +short __builtin_mulsathh_h (short, short)
19728 +int __builtin_mulsathh_w (short, short)
19729 +short __builtin_mulsatrndhh_h (short, short)
19730 +int __builtin_mulsatrndwh_w (int, short)
19731 +int __builtin_mulsatwh_w (int, short)
19732 +int __builtin_macsathh_w (int, short, short)
19733 +short __builtin_satadd_h (short, short)
19734 +short __builtin_satsub_h (short, short)
19735 +int __builtin_satadd_w (int, int)
19736 +int __builtin_satsub_w (int, int)
19737 +long long __builtin_mulwh_d(int, short)
19738 +long long __builtin_mulnwh_d(int, short)
19739 +long long __builtin_macwh_d(long long, int, short)
19740 +long long __builtin_machh_d(long long, short, short)
19741 +
19742 +void __builtin_musfr(int);
19743 +int __builtin_mustr(void);
19744 +int __builtin_mfsr(int /*Status Register Address*/)
19745 +void __builtin_mtsr(int /*Status Register Address*/, int /*Value*/)
19746 +int __builtin_mfdr(int /*Debug Register Address*/)
19747 +void __builtin_mtdr(int /*Debug Register Address*/, int /*Value*/)
19748 +void __builtin_cache(void * /*Address*/, int /*Cache Operation*/)
19749 +void __builtin_sync(int /*Sync Operation*/)
19750 +void __builtin_tlbr(void)
19751 +void __builtin_tlbs(void)
19752 +void __builtin_tlbw(void)
19753 +void __builtin_breakpoint(void)
19754 +int __builtin_xchg(void * /*Address*/, int /*Value*/ )
19755 +short __builtin_bswap_16(short)
19756 +int __builtin_bswap_32(int)
19757 +void __builtin_cop(int/*cpnr*/, int/*crd*/, int/*crx*/, int/*cry*/, int/*op*/)
19758 +int __builtin_mvcr_w(int/*cpnr*/, int/*crs*/)
19759 +void __builtin_mvrc_w(int/*cpnr*/, int/*crd*/, int/*value*/)
19760 +long long __builtin_mvcr_d(int/*cpnr*/, int/*crs*/)
19761 +void __builtin_mvrc_d(int/*cpnr*/, int/*crd*/, long long/*value*/)
19762 +
19763 +@end smallexample
19764 +
19765 @node Blackfin Built-in Functions
19766 @subsection Blackfin Built-in Functions
19767
19768 diff -Nrup gcc-4.2.1/gcc/doc/invoke.texi gcc-4.2.1.atmel.1.3.2/gcc/doc/invoke.texi
19769 --- gcc-4.2.1/gcc/doc/invoke.texi 2007-04-24 23:54:22.000000000 +0200
19770 +++ gcc-4.2.1.atmel.1.3.2/gcc/doc/invoke.texi 2007-09-28 10:32:30.000000000 +0200
19771 @@ -190,7 +190,7 @@ in the following sections.
19772 -fno-default-inline -fvisibility-inlines-hidden @gol
19773 -Wabi -Wctor-dtor-privacy @gol
19774 -Wnon-virtual-dtor -Wreorder @gol
19775 --Weffc++ -Wno-deprecated -Wstrict-null-sentinel @gol
19776 +-Weffc++ -Wno-deprecated @gol
19777 -Wno-non-template-friend -Wold-style-cast @gol
19778 -Woverloaded-virtual -Wno-pmf-conversions @gol
19779 -Wsign-promo}
19780 @@ -588,6 +588,12 @@ Objective-C and Objective-C++ Dialects}.
19781 -mauto-incdec -minmax -mlong-calls -mshort @gol
19782 -msoft-reg-count=@var{count}}
19783
19784 +@emph{AVR32 Options}
19785 +@gccoptlist{-muse-rodata-section -mhard-float -msoft-float -mrelax @gol
19786 +-mforce-double-align -mno-init-got -mpart=@var{part} -mcpu=@var{cpu} @gol
19787 +-march=@var{arch} -mfast-float -masm-addr-pseudos -mno-asm-addr-pseudos -mno-pic
19788 +}
19789 +
19790 @emph{MCore Options}
19791 @gccoptlist{-mhardlit -mno-hardlit -mdiv -mno-div -mrelax-immediates @gol
19792 -mno-relax-immediates -mwide-bitfields -mno-wide-bitfields @gol
19793 @@ -1868,14 +1874,6 @@ to filter out those warnings.
19794 @opindex Wno-deprecated
19795 Do not warn about usage of deprecated features. @xref{Deprecated Features}.
19796
19797 -@item -Wstrict-null-sentinel @r{(C++ only)}
19798 -@opindex Wstrict-null-sentinel
19799 -Warn also about the use of an uncasted @code{NULL} as sentinel. When
19800 -compiling only with GCC this is a valid sentinel, as @code{NULL} is defined
19801 -to @code{__null}. Although it is a null pointer constant not a null pointer,
19802 -it is guaranteed to of the same size as a pointer. But this use is
19803 -not portable across different compilers.
19804 -
19805 @item -Wno-non-template-friend @r{(C++ only)}
19806 @opindex Wno-non-template-friend
19807 Disable warnings when non-templatized friend functions are declared
19808 @@ -2732,13 +2730,11 @@ requiring @option{-O}.
19809 If you want to warn about code which uses the uninitialized value of the
19810 variable in its own initializer, use the @option{-Winit-self} option.
19811
19812 -These warnings occur for individual uninitialized or clobbered
19813 -elements of structure, union or array variables as well as for
19814 -variables which are uninitialized or clobbered as a whole. They do
19815 -not occur for variables or elements declared @code{volatile}. Because
19816 -these warnings depend on optimization, the exact variables or elements
19817 -for which there are warnings will depend on the precise optimization
19818 -options and version of GCC used.
19819 +These warnings occur only for variables that are candidates for
19820 +register allocation. Therefore, they do not occur for a variable that
19821 +is declared @code{volatile}, or whose address is taken, or whose size
19822 +is other than 1, 2, 4 or 8 bytes. Also, they do not occur for
19823 +structures, unions or arrays, even when they are in registers.
19824
19825 Note that there may be no warning about a variable that is used only
19826 to compute a value that itself is never used, because such
19827 @@ -6201,10 +6197,6 @@ If number of candidates in the set is sm
19828 we always try to remove unnecessary ivs from the set during its
19829 optimization when a new iv is added to the set.
19830
19831 -@item scev-max-expr-size
19832 -Bound on size of expressions used in the scalar evolutions analyzer.
19833 -Large expressions slow the analyzer.
19834 -
19835 @item vect-max-version-checks
19836 The maximum number of runtime checks that can be performed when doing
19837 loop versioning in the vectorizer. See option ftree-vect-loop-version
19838 @@ -7402,7 +7394,7 @@ platform.
19839 * ARC Options::
19840 * ARM Options::
19841 * AVR Options::
19842 -* Blackfin Options::
19843 +* AVR32 Options::
19844 * CRIS Options::
19845 * CRX Options::
19846 * Darwin Options::
19847 @@ -7867,81 +7859,68 @@ comply to the C standards, but it will p
19848 size.
19849 @end table
19850
19851 -@node Blackfin Options
19852 -@subsection Blackfin Options
19853 -@cindex Blackfin Options
19854 +@node AVR32 Options
19855 +@subsection AVR32 Options
19856 +@cindex AVR32 Options
19857 +
19858 +These options are defined for AVR32 implementations:
19859
19860 @table @gcctabopt
19861 -@item -momit-leaf-frame-pointer
19862 -@opindex momit-leaf-frame-pointer
19863 -Don't keep the frame pointer in a register for leaf functions. This
19864 -avoids the instructions to save, set up and restore frame pointers and
19865 -makes an extra register available in leaf functions. The option
19866 -@option{-fomit-frame-pointer} removes the frame pointer for all functions
19867 -which might make debugging harder.
19868 +@item -muse-rodata-section
19869 +@opindex muse-rodata-section
19870 +Use section @samp{.rodata} for read-only data instead of @samp{.text}.
19871
19872 -@item -mspecld-anomaly
19873 -@opindex mspecld-anomaly
19874 -When enabled, the compiler will ensure that the generated code does not
19875 -contain speculative loads after jump instructions. This option is enabled
19876 -by default.
19877 -
19878 -@item -mno-specld-anomaly
19879 -@opindex mno-specld-anomaly
19880 -Don't generate extra code to prevent speculative loads from occurring.
19881 -
19882 -@item -mcsync-anomaly
19883 -@opindex mcsync-anomaly
19884 -When enabled, the compiler will ensure that the generated code does not
19885 -contain CSYNC or SSYNC instructions too soon after conditional branches.
19886 -This option is enabled by default.
19887 -
19888 -@item -mno-csync-anomaly
19889 -@opindex mno-csync-anomaly
19890 -Don't generate extra code to prevent CSYNC or SSYNC instructions from
19891 -occurring too soon after a conditional branch.
19892 -
19893 -@item -mlow-64k
19894 -@opindex mlow-64k
19895 -When enabled, the compiler is free to take advantage of the knowledge that
19896 -the entire program fits into the low 64k of memory.
19897 -
19898 -@item -mno-low-64k
19899 -@opindex mno-low-64k
19900 -Assume that the program is arbitrarily large. This is the default.
19901 +@item -mrelax
19902 +@opindex mrelax
19903 +Enable relaxing in linker. This means that when the address of symbols
19904 +are known at link time, the linker can optimize @samp{icall} and @samp{mcall}
19905 +instructions into a @samp{rcall} instruction if possible. Loading the address
19906 +of a symbol can also be optimized.
19907 +
19908 +@item -mforce-double-align
19909 +@opindex mforce-double-align
19910 +Force double-word alignment for double-word memory accesses.
19911 +
19912 +@item -mno-init-got
19913 +@opindex mno-init-got
19914 +Do not initialize the GOT register before using it when compiling PIC
19915 +code.
19916
19917 -@item -mid-shared-library
19918 -@opindex mid-shared-library
19919 -Generate code that supports shared libraries via the library ID method.
19920 -This allows for execute in place and shared libraries in an environment
19921 -without virtual memory management. This option implies @option{-fPIC}.
19922 +@item -mno-pic
19923 +@opindex mno-pic
19924 +Do not emit position-independent code (will break dynamic linking.)
19925
19926 -@item -mno-id-shared-library
19927 -@opindex mno-id-shared-library
19928 -Generate code that doesn't assume ID based shared libraries are being used.
19929 -This is the default.
19930 +@item -masm-addr-pseudos
19931 +@opindex masm-addr-pseudos
19932 +Use assembler pseudo-instructions lda.w and call for handling direct
19933 +addresses. (Enabled by default)
19934 +
19935 +@item -mno-asm-addr-pseudos
19936 +@opindex mno-asm-addr-pseudos
19937 +Do not use assembler pseudo-instructions lda.w and call for handling direct addresses.
19938 +
19939 +@item -mpart=@var{part}
19940 +@opindex mpart
19941 +Generate code for the specified part. Permissible parts are: @samp{ap7000},
19942 +@samp{ap7010},@samp{ap7020},@samp{uc3a0256}, @samp{uc3a0512},
19943 +@samp{uc3a1128}, @samp{uc3a1256}, @samp{uc3a1512}.
19944
19945 -@item -mshared-library-id=n
19946 -@opindex mshared-library-id
19947 -Specified the identification number of the ID based shared library being
19948 -compiled. Specifying a value of 0 will generate more compact code, specifying
19949 -other values will force the allocation of that number to the current
19950 -library but is no more space or time efficient than omitting this option.
19951 +@item -mcpu=@var{cpu-type}
19952 +@opindex mcpu
19953 +Same as -mpart. Obsolete.
19954 +
19955 +@item -march=@var{arch}
19956 +@opindex march
19957 +Generate code for the specified architecture. Permissible architectures are:
19958 +@samp{ap} and @samp{uc}.
19959 +
19960 +@item -mfast-float
19961 +@opindex mfast-float
19962 +Enable fast floating-point library that does not conform to ieee but is still good enough
19963 +for most applications. The fast floating-point library does not round to the nearest even
19964 +but away from zero. Enabled by default if the -funsafe-math-optimizations switch is specified.
19965
19966 -@item -mlong-calls
19967 -@itemx -mno-long-calls
19968 -@opindex mlong-calls
19969 -@opindex mno-long-calls
19970 -Tells the compiler to perform function calls by first loading the
19971 -address of the function into a register and then performing a subroutine
19972 -call on this register. This switch is needed if the target function
19973 -will lie outside of the 24 bit addressing range of the offset based
19974 -version of subroutine call instruction.
19975
19976 -This feature is not enabled by default. Specifying
19977 -@option{-mno-long-calls} will restore the default behavior. Note these
19978 -switches have no effect on how the compiler generates code to handle
19979 -function calls via function pointers.
19980 @end table
19981
19982 @node CRIS Options
19983 @@ -11852,6 +11831,7 @@ conventions that adheres to the March 19
19984 Application Binary Interface, PowerPC processor supplement. This is the
19985 default unless you configured GCC using @samp{powerpc-*-eabiaix}.
19986
19987 +
19988 @item -mcall-sysv-eabi
19989 @opindex mcall-sysv-eabi
19990 Specify both @option{-mcall-sysv} and @option{-meabi} options.
19991 @@ -14153,4 +14133,4 @@ You need to include the special files al
19992 exist, because otherwise they won't get converted.
19993
19994 @xref{Protoize Caveats}, for more information on how to use
19995 -@code{protoize} successfully.
19996 +@code{protoize} successfully.
19997 \ No newline at end of file
19998 diff -Nrup gcc-4.2.1/gcc/doc/md.texi gcc-4.2.1.atmel.1.3.2/gcc/doc/md.texi
19999 --- gcc-4.2.1/gcc/doc/md.texi 2007-04-04 03:24:10.000000000 +0200
20000 +++ gcc-4.2.1.atmel.1.3.2/gcc/doc/md.texi 2007-09-28 10:32:30.000000000 +0200
20001 @@ -3,6 +3,7 @@
20002 @c This is part of the GCC manual.
20003 @c For copying conditions, see the file gcc.texi.
20004
20005 +
20006 @ifset INTERNALS
20007 @node Machine Desc
20008 @chapter Machine Descriptions
20009 @@ -1681,6 +1682,58 @@ A memory reference suitable for iWMMXt l
20010 A memory reference suitable for the ARMv4 ldrsb instruction.
20011 @end table
20012
20013 +@item AVR32 family---@file{avr32.h}
20014 +@table @code
20015 +@item f
20016 +Floating-point registers (f0 to f15)
20017 +
20018 +@item Ku@var{bits}
20019 +Unsigned constant representable with @var{bits} number of bits (Must be
20020 +two digits). I.e: An unsigned 8-bit constant is written as @samp{Ku08}
20021 +
20022 +@item Ks@var{bits}
20023 +Signed constant representable with @var{bits} number of bits (Must be
20024 +two digits). I.e: A signed 12-bit constant is written as @samp{Ks12}
20025 +
20026 +@item Is@var{bits}
20027 +The negated range of a signed constant representable with @var{bits}
20028 +number of bits. The same as @samp{Ks@var{bits}} with a negated range.
20029 +This means that the constant must be in the range @math{-2^{bits-1}-1} to @math{2^{bits-1}}
20030 +
20031 +@item G
20032 +A single/double precision floating-point immediate or 64-bit integer
20033 +immediate where the least and most significant words both can be
20034 +loaded with a move instruction. That is the the integer form of the
20035 +values in the least and most significant words both are in the range
20036 +@math{-2^{20}} to @math{2^{20}-1}.
20037 +
20038 +@item RKs@var{bits}
20039 +A memory reference where the address consists of a base register
20040 +plus a signed immediate displacement with range given by @samp{Ks@var{bits}}
20041 +which has the same format as for the signed immediate integer constraint
20042 +given above.
20043 +
20044 +@item RKu@var{bits}
20045 +A memory reference where the address consists of a base register
20046 +plus an unsigned immediate displacement with range given by @samp{Ku@var{bits}}
20047 +which has the same format as for the unsigned immediate integer constraint
20048 +given above.
20049 +
20050 +@item S
20051 +A memory reference with an immediate or register offset
20052 +
20053 +@item T
20054 +A memory reference to a constant pool entry
20055 +
20056 +@item W
20057 +A valid operand for use in the @samp{lda.w} instruction macro when
20058 +relaxing is enabled
20059 +
20060 +@item Z
20061 +A memory reference valid for coprocessor memory instructions
20062 +
20063 +@end table
20064 +
20065 @item AVR family---@file{config/avr/constraints.md}
20066 @table @code
20067 @item l
20068 diff -Nrup gcc-4.2.1/gcc/expmed.c gcc-4.2.1.atmel.1.3.2/gcc/expmed.c
20069 --- gcc-4.2.1/gcc/expmed.c 2007-04-25 07:43:32.000000000 +0200
20070 +++ gcc-4.2.1.atmel.1.3.2/gcc/expmed.c 2007-09-28 10:33:09.000000000 +0200
20071 @@ -37,6 +37,7 @@ Software Foundation, 51 Franklin Street,
20072 #include "real.h"
20073 #include "recog.h"
20074 #include "langhooks.h"
20075 +#include "target.h"
20076
20077 static void store_fixed_bit_field (rtx, unsigned HOST_WIDE_INT,
20078 unsigned HOST_WIDE_INT,
20079 @@ -455,9 +456,18 @@ store_bit_field (rtx str_rtx, unsigned H
20080 ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
20081 || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
20082 && byte_offset % GET_MODE_SIZE (fieldmode) == 0)
20083 - : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
20084 - || (offset * BITS_PER_UNIT % bitsize == 0
20085 - && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
20086 + : (
20087 +
20088 + /* NB! Added for AVR32, and I think this should be true for
20089 + all targets not using narrow volatile bitfields. If the
20090 + bitfield is volatile then we need to perform an access
20091 + consistent with the container type. */
20092 + !(MEM_VOLATILE_P (op0)
20093 + && GET_MODE_BITSIZE (GET_MODE (op0)) != bitsize
20094 + && !targetm.narrow_volatile_bitfield ())
20095 + && (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
20096 + || (offset * BITS_PER_UNIT % bitsize == 0
20097 + && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0)))))
20098 {
20099 if (MEM_P (op0))
20100 op0 = adjust_address (op0, fieldmode, offset);
20101 @@ -1257,6 +1267,13 @@ extract_bit_field (rtx str_rtx, unsigned
20102 && GET_MODE_SIZE (mode1) != 0
20103 && byte_offset % GET_MODE_SIZE (mode1) == 0)
20104 || (MEM_P (op0)
20105 + /* NB! Added for AVR32, and I think this should be true for
20106 + all targets not using narrow volatile bitfields. If the
20107 + bitfield is volatile then we need to perform an access
20108 + consistent with the container type. */
20109 + && !(MEM_VOLATILE_P (op0)
20110 + && GET_MODE_BITSIZE (GET_MODE (op0)) != bitsize
20111 + && !targetm.narrow_volatile_bitfield ())
20112 && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
20113 || (offset * BITS_PER_UNIT % bitsize == 0
20114 && MEM_ALIGN (op0) % bitsize == 0)))))
20115 diff -Nrup gcc-4.2.1/gcc/expr.c gcc-4.2.1.atmel.1.3.2/gcc/expr.c
20116 --- gcc-4.2.1/gcc/expr.c 2007-04-23 03:57:48.000000000 +0200
20117 +++ gcc-4.2.1.atmel.1.3.2/gcc/expr.c 2007-09-28 10:33:08.000000000 +0200
20118 @@ -3520,18 +3520,19 @@ emit_single_push_insn (enum machine_mode
20119 }
20120 else
20121 {
20122 + emit_move_insn (stack_pointer_rtx,
20123 + expand_binop (Pmode,
20124 #ifdef STACK_GROWS_DOWNWARD
20125 - /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC. */
20126 - dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
20127 - GEN_INT (-(HOST_WIDE_INT) rounded_size));
20128 + sub_optab,
20129 #else
20130 - /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC. */
20131 - dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
20132 - GEN_INT (rounded_size));
20133 + add_optab,
20134 #endif
20135 - dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
20136 + stack_pointer_rtx,
20137 + GEN_INT (rounded_size),
20138 + NULL_RTX, 0, OPTAB_LIB_WIDEN));
20139 + dest_addr = stack_pointer_rtx;
20140 }
20141 -
20142 +
20143 dest = gen_rtx_MEM (mode, dest_addr);
20144
20145 if (type != 0)
20146 @@ -5510,7 +5511,16 @@ store_field (rtx target, HOST_WIDE_INT b
20147 is a bit field, we cannot use addressing to access it.
20148 Use bit-field techniques or SUBREG to store in it. */
20149
20150 - if (mode == VOIDmode
20151 + if (
20152 + /* NB! Added for AVR32, and I think this should be true for
20153 + all targets not using narrow volatile bitfields. If the
20154 + bitfield is volatile then we need to perform an access
20155 + consistent with the container type. */
20156 + (MEM_P (target)
20157 + && MEM_VOLATILE_P (target)
20158 + && GET_MODE_BITSIZE (GET_MODE (target)) > bitsize
20159 + && !targetm.narrow_volatile_bitfield ())
20160 + || mode == VOIDmode
20161 || (mode != BLKmode && ! direct_store[(int) mode]
20162 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
20163 && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
20164 @@ -7512,7 +7522,16 @@ expand_expr_real_1 (tree exp, rtx target
20165 by doing the extract into an object as wide as the field
20166 (which we know to be the width of a basic mode), then
20167 storing into memory, and changing the mode to BLKmode. */
20168 - if (mode1 == VOIDmode
20169 + if (
20170 + /* NB! Added for AVR32, and I think this should be true for
20171 + all targets not using narrow volatile bitfields. If the
20172 + bitfield is volatile then we need to perform an access
20173 + consistent with the container type. */
20174 + (MEM_P (op0)
20175 + && MEM_VOLATILE_P (op0)
20176 + && GET_MODE_BITSIZE (GET_MODE (op0)) > bitsize
20177 + && !targetm.narrow_volatile_bitfield ())
20178 + || mode1 == VOIDmode
20179 || REG_P (op0) || GET_CODE (op0) == SUBREG
20180 || (mode1 != BLKmode && ! direct_load[(int) mode1]
20181 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
20182 diff -Nrup gcc-4.2.1/gcc/function.c gcc-4.2.1.atmel.1.3.2/gcc/function.c
20183 --- gcc-4.2.1/gcc/function.c 2007-07-19 05:25:32.000000000 +0200
20184 +++ gcc-4.2.1.atmel.1.3.2/gcc/function.c 2007-09-28 10:33:09.000000000 +0200
20185 @@ -2677,8 +2677,12 @@ assign_parm_setup_reg (struct assign_par
20186 SET_DECL_RTL (parm, parmreg);
20187
20188 /* Copy the value into the register. */
20189 - if (data->nominal_mode != data->passed_mode
20190 - || promoted_nominal_mode != data->promoted_mode)
20191 + if ( (data->nominal_mode != data->passed_mode
20192 + /* Added for AVR32: If passed_mode is equal
20193 + to promoted nominal mode why should be convert?
20194 + The conversion should make no difference. */
20195 + && data->passed_mode != promoted_nominal_mode)
20196 + || promoted_nominal_mode != data->promoted_mode)
20197 {
20198 int save_tree_used;
20199
20200 diff -Nrup gcc-4.2.1/gcc/genemit.c gcc-4.2.1.atmel.1.3.2/gcc/genemit.c
20201 --- gcc-4.2.1/gcc/genemit.c 2006-03-29 23:07:12.000000000 +0200
20202 +++ gcc-4.2.1.atmel.1.3.2/gcc/genemit.c 2007-09-28 10:33:08.000000000 +0200
20203 @@ -122,6 +122,24 @@ max_operand_vec (rtx insn, int arg)
20204 }
20205 \f
20206 static void
20207 +gen_vararg_prologue(int operands)
20208 +{
20209 + int i;
20210 +
20211 + if (operands > 1)
20212 + {
20213 + for (i = 1; i < operands; i++)
20214 + printf(" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
20215 +
20216 + printf(" va_list args;\n\n");
20217 + printf(" va_start(args, operand0);\n");
20218 + for (i = 1; i < operands; i++)
20219 + printf(" operand%d = va_arg(args, rtx);\n", i);
20220 + printf(" va_end(args);\n\n");
20221 + }
20222 +}
20223 +
20224 +static void
20225 print_code (RTX_CODE code)
20226 {
20227 const char *p1;
20228 @@ -406,18 +424,16 @@ gen_insn (rtx insn, int lineno)
20229 fatal ("match_dup operand number has no match_operand");
20230
20231 /* Output the function name and argument declarations. */
20232 - printf ("rtx\ngen_%s (", XSTR (insn, 0));
20233 + printf ("rtx\ngen_%s ", XSTR (insn, 0));
20234 +
20235 if (operands)
20236 - for (i = 0; i < operands; i++)
20237 - if (i)
20238 - printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
20239 - else
20240 - printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
20241 + printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
20242 else
20243 - printf ("void");
20244 - printf (")\n");
20245 + printf("(void)\n");
20246 printf ("{\n");
20247
20248 + gen_vararg_prologue(operands);
20249 +
20250 /* Output code to construct and return the rtl for the instruction body. */
20251
20252 if (XVECLEN (insn, 1) == 1)
20253 @@ -457,16 +473,12 @@ gen_expand (rtx expand)
20254 operands = max_operand_vec (expand, 1);
20255
20256 /* Output the function name and argument declarations. */
20257 - printf ("rtx\ngen_%s (", XSTR (expand, 0));
20258 + printf ("rtx\ngen_%s ", XSTR (expand, 0));
20259 if (operands)
20260 - for (i = 0; i < operands; i++)
20261 - if (i)
20262 - printf (",\n\trtx operand%d", i);
20263 - else
20264 - printf ("rtx operand%d", i);
20265 + printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
20266 else
20267 - printf ("void");
20268 - printf (")\n");
20269 + printf("(void)\n");
20270 +
20271 printf ("{\n");
20272
20273 /* If we don't have any C code to write, only one insn is being written,
20274 @@ -476,6 +488,8 @@ gen_expand (rtx expand)
20275 && operands > max_dup_opno
20276 && XVECLEN (expand, 1) == 1)
20277 {
20278 + gen_vararg_prologue(operands);
20279 +
20280 printf (" return ");
20281 gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL);
20282 printf (";\n}\n\n");
20283 @@ -489,6 +503,7 @@ gen_expand (rtx expand)
20284 for (; i <= max_scratch_opno; i++)
20285 printf (" rtx operand%d ATTRIBUTE_UNUSED;\n", i);
20286 printf (" rtx _val = 0;\n");
20287 + gen_vararg_prologue(operands);
20288 printf (" start_sequence ();\n");
20289
20290 /* The fourth operand of DEFINE_EXPAND is some code to be executed
20291 diff -Nrup gcc-4.2.1/gcc/genflags.c gcc-4.2.1.atmel.1.3.2/gcc/genflags.c
20292 --- gcc-4.2.1/gcc/genflags.c 2006-01-23 16:15:12.000000000 +0100
20293 +++ gcc-4.2.1.atmel.1.3.2/gcc/genflags.c 2007-09-28 10:33:09.000000000 +0200
20294 @@ -128,7 +128,6 @@ static void
20295 gen_proto (rtx insn)
20296 {
20297 int num = num_operands (insn);
20298 - int i;
20299 const char *name = XSTR (insn, 0);
20300 int truth = maybe_eval_c_test (XSTR (insn, 2));
20301
20302 @@ -159,12 +158,7 @@ gen_proto (rtx insn)
20303 if (num == 0)
20304 fputs ("void", stdout);
20305 else
20306 - {
20307 - for (i = 1; i < num; i++)
20308 - fputs ("rtx, ", stdout);
20309 -
20310 - fputs ("rtx", stdout);
20311 - }
20312 + fputs("rtx, ...", stdout);
20313
20314 puts (");");
20315
20316 @@ -174,12 +168,7 @@ gen_proto (rtx insn)
20317 {
20318 printf ("static inline rtx\ngen_%s", name);
20319 if (num > 0)
20320 - {
20321 - putchar ('(');
20322 - for (i = 0; i < num-1; i++)
20323 - printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
20324 - printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
20325 - }
20326 + puts("(rtx ARG_UNUSED(a), ...)");
20327 else
20328 puts ("(void)");
20329 puts ("{\n return 0;\n}");
20330 diff -Nrup gcc-4.2.1/gcc/genoutput.c gcc-4.2.1.atmel.1.3.2/gcc/genoutput.c
20331 --- gcc-4.2.1/gcc/genoutput.c 2006-03-29 23:07:12.000000000 +0200
20332 +++ gcc-4.2.1.atmel.1.3.2/gcc/genoutput.c 2007-09-28 10:33:08.000000000 +0200
20333 @@ -387,7 +387,7 @@ output_insn_data (void)
20334 }
20335
20336 if (d->name && d->name[0] != '*')
20337 - printf (" (insn_gen_fn) gen_%s,\n", d->name);
20338 + printf (" gen_%s,\n", d->name);
20339 else
20340 printf (" 0,\n");
20341
20342 diff -Nrup gcc-4.2.1/gcc/ifcvt.c gcc-4.2.1.atmel.1.3.2/gcc/ifcvt.c
20343 --- gcc-4.2.1/gcc/ifcvt.c 2006-11-15 09:37:38.000000000 +0100
20344 +++ gcc-4.2.1.atmel.1.3.2/gcc/ifcvt.c 2007-09-28 10:33:08.000000000 +0200
20345 @@ -1051,7 +1051,11 @@ noce_try_addcc (struct noce_if_info *if_
20346 != UNKNOWN))
20347 {
20348 rtx cond = if_info->cond;
20349 - enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
20350 + /* This generates wrong code for AVR32. The cond code need not be reversed
20351 + since the addmodecc patterns add if the condition is NOT met. */
20352 + /* enum rtx_code code = reversed_comparison_code (cond, if_info->jump);*/
20353 + enum rtx_code code = GET_CODE(cond);
20354 +
20355
20356 /* First try to use addcc pattern. */
20357 if (general_operand (XEXP (cond, 0), VOIDmode)
20358 diff -Nrup gcc-4.2.1/gcc/longlong.h gcc-4.2.1.atmel.1.3.2/gcc/longlong.h
20359 --- gcc-4.2.1/gcc/longlong.h 2006-06-13 19:44:56.000000000 +0200
20360 +++ gcc-4.2.1.atmel.1.3.2/gcc/longlong.h 2007-09-28 10:33:08.000000000 +0200
20361 @@ -227,6 +227,39 @@ UDItype __umulsidi3 (USItype, USItype);
20362 #define UDIV_TIME 100
20363 #endif /* __arm__ */
20364
20365 +#if defined (__avr32__) && W_TYPE_SIZE == 32
20366 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
20367 + __asm__ ("add\t%1, %4, %5\n\tadc\t%0, %2, %3" \
20368 + : "=r" ((USItype) (sh)), \
20369 + "=&r" ((USItype) (sl)) \
20370 + : "r" ((USItype) (ah)), \
20371 + "r" ((USItype) (bh)), \
20372 + "r" ((USItype) (al)), \
20373 + "r" ((USItype) (bl)) __CLOBBER_CC)
20374 +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
20375 + __asm__ ("sub\t%1, %4, %5\n\tsbc\t%0, %2, %3" \
20376 + : "=r" ((USItype) (sh)), \
20377 + "=&r" ((USItype) (sl)) \
20378 + : "r" ((USItype) (ah)), \
20379 + "r" ((USItype) (bh)), \
20380 + "r" ((USItype) (al)), \
20381 + "r" ((USItype) (bl)) __CLOBBER_CC)
20382 +
20383 +#define __umulsidi3(a,b) ((UDItype)(a) * (UDItype)(b))
20384 +
20385 +#define umul_ppmm(w1, w0, u, v) \
20386 +{ \
20387 + DWunion __w; \
20388 + __w.ll = __umulsidi3 (u, v); \
20389 + w1 = __w.s.high; \
20390 + w0 = __w.s.low; \
20391 +}
20392 +
20393 +#define count_leading_zeros(COUNT,X) ((COUNT) = __builtin_clz (X))
20394 +#define count_trailing_zeros(COUNT,X) ((COUNT) = __builtin_ctz (X))
20395 +#define COUNT_LEADING_ZEROS_0 32
20396 +#endif
20397 +
20398 #if defined (__hppa) && W_TYPE_SIZE == 32
20399 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
20400 __asm__ ("add %4,%5,%1\n\taddc %2,%3,%0" \
20401 diff -Nrup gcc-4.2.1/gcc/optabs.h gcc-4.2.1.atmel.1.3.2/gcc/optabs.h
20402 --- gcc-4.2.1/gcc/optabs.h 2006-01-19 11:24:00.000000000 +0100
20403 +++ gcc-4.2.1.atmel.1.3.2/gcc/optabs.h 2007-09-28 10:33:07.000000000 +0200
20404 @@ -432,7 +432,7 @@ extern enum insn_code reload_out_optab[N
20405 extern GTY(()) optab code_to_optab[NUM_RTX_CODE + 1];
20406
20407 \f
20408 -typedef rtx (*rtxfun) (rtx);
20409 +typedef rtx (*rtxfun) (rtx, ...);
20410
20411 /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
20412 gives the gen_function to make a branch to test that condition. */
20413 diff -Nrup gcc-4.2.1/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c
20414 --- gcc-4.2.1/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c 2005-02-19 20:48:02.000000000 +0100
20415 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/cpp/mac-eol-at-eof.c 2007-05-07 14:24:46.000000000 +0200
20416 @@ -1 +1,3 @@
20417 -/* Test no newline at eof warning when Mac line ending is used*/ /* { dg-do compile } */ int main() { return 0; }
20418 \ No newline at end of file
20419 +/* Test no newline at eof warning when Mac line ending is used*/
20420 +/* { dg-do compile } */
20421 +int main() { return 0; }
20422 diff -Nrup gcc-4.2.1/gcc/testsuite/gcc.dg/sibcall-3.c gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/sibcall-3.c
20423 --- gcc-4.2.1/gcc/testsuite/gcc.dg/sibcall-3.c 2005-07-20 08:39:38.000000000 +0200
20424 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/sibcall-3.c 2007-09-28 10:31:43.000000000 +0200
20425 @@ -5,7 +5,7 @@
20426 Copyright (C) 2002 Free Software Foundation Inc.
20427 Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
20428
20429 -/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
20430 +/* { dg-do run { xfail arc-*-* avr-*-* avr32-*-* c4x-*-* cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
20431 /* { dg-options "-O2 -foptimize-sibling-calls" } */
20432
20433 /* The option -foptimize-sibling-calls is the default, but serves as
20434 diff -Nrup gcc-4.2.1/gcc/testsuite/gcc.dg/sibcall-4.c gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/sibcall-4.c
20435 --- gcc-4.2.1/gcc/testsuite/gcc.dg/sibcall-4.c 2005-07-20 08:39:38.000000000 +0200
20436 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/sibcall-4.c 2007-09-28 10:31:43.000000000 +0200
20437 @@ -5,7 +5,7 @@
20438 Copyright (C) 2002 Free Software Foundation Inc.
20439 Contributed by Hans-Peter Nilsson <hp@bitrange.com> */
20440
20441 -/* { dg-do run { xfail arc-*-* avr-*-* c4x-*-* cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
20442 +/* { dg-do run { xfail arc-*-* avr-*-* avr32-*-* c4x-*-* cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* m681?-*-* m680*-*-* m68k-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa-*-* } } */
20443 /* { dg-options "-O2 -foptimize-sibling-calls" } */
20444
20445 /* The option -foptimize-sibling-calls is the default, but serves as
20446 diff -Nrup gcc-4.2.1/gcc/testsuite/gcc.dg/trampoline-1.c gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/trampoline-1.c
20447 --- gcc-4.2.1/gcc/testsuite/gcc.dg/trampoline-1.c 2004-08-03 10:22:26.000000000 +0200
20448 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gcc.dg/trampoline-1.c 2007-09-28 10:31:43.000000000 +0200
20449 @@ -46,6 +46,8 @@ void foo (void)
20450
20451 int main (void)
20452 {
20453 +#ifndef NO_TRAMPOLINES
20454 foo ();
20455 +#endif
20456 return 0;
20457 }
20458 diff -Nrup gcc-4.2.1/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gfortran.dg/char_pointer_assign.f90
20459 --- gcc-4.2.1/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 2005-05-29 18:03:43.000000000 +0200
20460 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/gfortran.dg/char_pointer_assign.f90 2007-05-07 16:38:14.000000000 +0200
20461 @@ -1,4 +1,4 @@
20462 -! { dg-do run }
20463 +! { dg-do run }
20464 program char_pointer_assign
20465 ! Test character pointer assignments, required
20466 ! to fix PR18890 and PR21297
20467 @@ -8,7 +8,7 @@ program char_pointer_assign
20468 character*4, target :: t2(4) =(/"lmno","lmno","lmno","lmno"/)
20469 character*4 :: const
20470 character*4, pointer :: c1, c3
20471 - character*4, pointer :: c2(:), c4(:)
20472 + character*4, pointer :: c2(:), c4(:)
20473 allocate (c3, c4(4))
20474 ! Scalars first.
20475 c3 = "lmno" ! pointer = constant
20476 @@ -24,13 +24,13 @@ program char_pointer_assign
20477
20478 ! Now arrays.
20479 c4 = "lmno" ! pointer = constant
20480 - t2 = c4 ! target = pointer
20481 - c2 => t2 ! pointer =>target
20482 - const = c2(1)
20483 + t2 = c4 ! target = pointer
20484 + c2 => t2 ! pointer =>target
20485 + const = c2(1)
20486 const(2:3) ="nm" ! c2(:)(2:3) = "nm" is still broken
20487 c2 = const
20488 c4 = c2 ! pointer = pointer
20489 - const = c4(1)
20490 + const = c4(1)
20491 const(1:1) ="o" ! c4(:)(1:1) = "o" is still broken
20492 const(4:4) ="l" ! c4(:)(4:4) = "l" is still broken
20493 c4 = const
20494 diff -Nrup gcc-4.2.1/gcc/testsuite/g++.old-deja/g++.pt/static11.C gcc-4.2.1.atmel.1.3.2/gcc/testsuite/g++.old-deja/g++.pt/static11.C
20495 --- gcc-4.2.1/gcc/testsuite/g++.old-deja/g++.pt/static11.C 2006-02-22 10:05:07.000000000 +0100
20496 +++ gcc-4.2.1.atmel.1.3.2/gcc/testsuite/g++.old-deja/g++.pt/static11.C 2007-09-28 10:31:46.000000000 +0200
20497 @@ -2,7 +2,7 @@
20498 // in their dejagnu baseboard description) require that the status is
20499 // final when exit is entered (or main returns), and not "overruled" by a
20500 // destructor calling _exit. It's not really worth it to handle that.
20501 -// { dg-do run { xfail mmix-knuth-mmixware xtensa-*-elf* arm*-*-elf arm*-*-eabi m68k-*-elf } }
20502 +// { dg-do run { xfail mmix-knuth-mmixware xtensa-*-elf* avr32-*-elf arm*-*-elf arm*-*-eabi m68k-*-elf } }
20503
20504 // Bug: g++ was failing to destroy C<int>::a because it was using two
20505 // different sentry variables for construction and destruction.
20506 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/copying.txt gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/copying.txt
20507 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/copying.txt 2006-03-10 14:25:35.000000000 +0100
20508 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/copying.txt 2007-09-28 10:34:16.000000000 +0200
20509 @@ -1,30 +1,30 @@
20510 -Copyright (c) 2001, Thai Open Source Software Center Ltd, Sun Microsystems.
20511 -All rights reserved.
20512 -
20513 -Redistribution and use in source and binary forms, with or without
20514 -modification, are permitted provided that the following conditions are
20515 -met:
20516 -
20517 - Redistributions of source code must retain the above copyright
20518 - notice, this list of conditions and the following disclaimer.
20519 -
20520 - Redistributions in binary form must reproduce the above copyright
20521 - notice, this list of conditions and the following disclaimer in
20522 - the documentation and/or other materials provided with the
20523 - distribution.
20524 -
20525 - Neither the names of the copyright holders nor the names of its
20526 - contributors may be used to endorse or promote products derived
20527 - from this software without specific prior written permission.
20528 -
20529 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20530 -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20531 -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20532 -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
20533 -CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20534 -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20535 -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20536 -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20537 -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20538 -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20539 -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20540 +Copyright (c) 2001, Thai Open Source Software Center Ltd, Sun Microsystems.
20541 +All rights reserved.
20542 +
20543 +Redistribution and use in source and binary forms, with or without
20544 +modification, are permitted provided that the following conditions are
20545 +met:
20546 +
20547 + Redistributions of source code must retain the above copyright
20548 + notice, this list of conditions and the following disclaimer.
20549 +
20550 + Redistributions in binary form must reproduce the above copyright
20551 + notice, this list of conditions and the following disclaimer in
20552 + the documentation and/or other materials provided with the
20553 + distribution.
20554 +
20555 + Neither the names of the copyright holders nor the names of its
20556 + contributors may be used to endorse or promote products derived
20557 + from this software without specific prior written permission.
20558 +
20559 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20560 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20561 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20562 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
20563 +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20564 +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20565 +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20566 +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20567 +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20568 +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
20569 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20570 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java
20571 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java 2006-03-10 14:25:35.000000000 +0100
20572 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeBuilder.java 2007-09-28 10:34:16.000000000 +0200
20573 @@ -1,45 +1,45 @@
20574 -package org.relaxng.datatype;
20575 -
20576 -/**
20577 - * Creates a user-defined type by adding parameters to
20578 - * the pre-defined type.
20579 - *
20580 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
20581 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
20582 - */
20583 -public interface DatatypeBuilder {
20584 -
20585 - /**
20586 - * Adds a new parameter.
20587 - *
20588 - * @param name
20589 - * The name of the parameter to be added.
20590 - * @param strValue
20591 - * The raw value of the parameter. Caller may not normalize
20592 - * this value because any white space is potentially significant.
20593 - * @param context
20594 - * The context information which can be used by the callee to
20595 - * acquire additional information. This context object is
20596 - * valid only during this method call. The callee may not
20597 - * keep a reference to this object.
20598 - * @exception DatatypeException
20599 - * When the given parameter is inappropriate for some reason.
20600 - * The callee is responsible to recover from this error.
20601 - * That is, the object should behave as if no such error
20602 - * was occured.
20603 - */
20604 - void addParameter( String name, String strValue, ValidationContext context )
20605 - throws DatatypeException;
20606 -
20607 - /**
20608 - * Derives a new Datatype from a Datatype by parameters that
20609 - * were already set through the addParameter method.
20610 - *
20611 - * @exception DatatypeException
20612 - * DatatypeException must be thrown if the derivation is
20613 - * somehow invalid. For example, a required parameter is missing,
20614 - * etc. The exception should contain a diagnosis message
20615 - * if possible.
20616 - */
20617 - Datatype createDatatype() throws DatatypeException;
20618 -}
20619 +package org.relaxng.datatype;
20620 +
20621 +/**
20622 + * Creates a user-defined type by adding parameters to
20623 + * the pre-defined type.
20624 + *
20625 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
20626 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
20627 + */
20628 +public interface DatatypeBuilder {
20629 +
20630 + /**
20631 + * Adds a new parameter.
20632 + *
20633 + * @param name
20634 + * The name of the parameter to be added.
20635 + * @param strValue
20636 + * The raw value of the parameter. Caller may not normalize
20637 + * this value because any white space is potentially significant.
20638 + * @param context
20639 + * The context information which can be used by the callee to
20640 + * acquire additional information. This context object is
20641 + * valid only during this method call. The callee may not
20642 + * keep a reference to this object.
20643 + * @exception DatatypeException
20644 + * When the given parameter is inappropriate for some reason.
20645 + * The callee is responsible to recover from this error.
20646 + * That is, the object should behave as if no such error
20647 + * was occured.
20648 + */
20649 + void addParameter( String name, String strValue, ValidationContext context )
20650 + throws DatatypeException;
20651 +
20652 + /**
20653 + * Derives a new Datatype from a Datatype by parameters that
20654 + * were already set through the addParameter method.
20655 + *
20656 + * @exception DatatypeException
20657 + * DatatypeException must be thrown if the derivation is
20658 + * somehow invalid. For example, a required parameter is missing,
20659 + * etc. The exception should contain a diagnosis message
20660 + * if possible.
20661 + */
20662 + Datatype createDatatype() throws DatatypeException;
20663 +}
20664 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java
20665 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java 2006-03-10 14:25:35.000000000 +0100
20666 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeException.java 2007-09-28 10:34:16.000000000 +0200
20667 @@ -1,39 +1,39 @@
20668 -package org.relaxng.datatype;
20669 -
20670 -/**
20671 - * Signals Datatype related exceptions.
20672 - *
20673 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
20674 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
20675 - */
20676 -public class DatatypeException extends Exception {
20677 -
20678 - public DatatypeException( int index, String msg ) {
20679 - super(msg);
20680 - this.index = index;
20681 - }
20682 - public DatatypeException( String msg ) {
20683 - this(UNKNOWN,msg);
20684 - }
20685 - /**
20686 - * A constructor for those datatype libraries which don't support any
20687 - * diagnostic information at all.
20688 - */
20689 - public DatatypeException() {
20690 - this(UNKNOWN,null);
20691 - }
20692 -
20693 -
20694 - private final int index;
20695 -
20696 - public static final int UNKNOWN = -1;
20697 -
20698 - /**
20699 - * Gets the index of the content where the error occured.
20700 - * UNKNOWN can be returned to indicate that no index information
20701 - * is available.
20702 - */
20703 - public int getIndex() {
20704 - return index;
20705 - }
20706 -}
20707 +package org.relaxng.datatype;
20708 +
20709 +/**
20710 + * Signals Datatype related exceptions.
20711 + *
20712 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
20713 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
20714 + */
20715 +public class DatatypeException extends Exception {
20716 +
20717 + public DatatypeException( int index, String msg ) {
20718 + super(msg);
20719 + this.index = index;
20720 + }
20721 + public DatatypeException( String msg ) {
20722 + this(UNKNOWN,msg);
20723 + }
20724 + /**
20725 + * A constructor for those datatype libraries which don't support any
20726 + * diagnostic information at all.
20727 + */
20728 + public DatatypeException() {
20729 + this(UNKNOWN,null);
20730 + }
20731 +
20732 +
20733 + private final int index;
20734 +
20735 + public static final int UNKNOWN = -1;
20736 +
20737 + /**
20738 + * Gets the index of the content where the error occured.
20739 + * UNKNOWN can be returned to indicate that no index information
20740 + * is available.
20741 + */
20742 + public int getIndex() {
20743 + return index;
20744 + }
20745 +}
20746 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java
20747 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java 2006-03-10 14:25:35.000000000 +0100
20748 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/Datatype.java 2007-09-28 10:34:16.000000000 +0200
20749 @@ -1,237 +1,237 @@
20750 -package org.relaxng.datatype;
20751 -
20752 -/**
20753 - * Datatype object.
20754 - *
20755 - * This object has the following functionality:
20756 - *
20757 - * <ol>
20758 - * <li> functionality to identify a class of character sequences. This is
20759 - * done through the isValid method.
20760 - *
20761 - * <li> functionality to produce a "value object" from a character sequence and
20762 - * context information.
20763 - *
20764 - * <li> functionality to test the equality of two value objects.
20765 - * </ol>
20766 - *
20767 - * This interface also defines the createStreamingValidator method,
20768 - * which is intended to efficiently support the validation of
20769 - * large character sequences.
20770 - *
20771 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
20772 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
20773 - */
20774 -public interface Datatype {
20775 -
20776 - /**
20777 - * Checks if the specified 'literal' matches this Datatype
20778 - * with respect to the current context.
20779 - *
20780 - * @param literal
20781 - * the lexical representation to be checked.
20782 - * @param context
20783 - * If this datatype is context-dependent
20784 - * (i.e. the {@link #isContextDependent} method returns true),
20785 - * then the caller must provide a non-null valid context object.
20786 - * Otherwise, the caller can pass null.
20787 - *
20788 - * @return
20789 - * true if the 'literal' is a member of this Datatype;
20790 - * false if it's not a member of this Datatype.
20791 - */
20792 - boolean isValid( String literal, ValidationContext context );
20793 -
20794 - /**
20795 - * Similar to the isValid method but throws an exception with diagnosis
20796 - * in case of errors.
20797 - *
20798 - * <p>
20799 - * If the specified 'literal' is a valid lexical representation for this
20800 - * datatype, then this method must return without throwing any exception.
20801 - * If not, the callee must throw an exception (with diagnosis message,
20802 - * if possible.)
20803 - *
20804 - * <p>
20805 - * The application can use this method to provide detailed error message
20806 - * to users. This method is kept separate from the isValid method to
20807 - * achieve higher performance during normal validation.
20808 - *
20809 - * @exception DatatypeException
20810 - * If the given literal is invalid, then this exception is thrown.
20811 - * If the callee supports error diagnosis, then the exception should
20812 - * contain a diagnosis message.
20813 - */
20814 - void checkValid( String literal, ValidationContext context )
20815 - throws DatatypeException;
20816 -
20817 - /**
20818 - * Creates an instance of a streaming validator for this type.
20819 - *
20820 - * <p>
20821 - * By using streaming validators instead of the isValid method,
20822 - * the caller can avoid keeping the entire string, which is
20823 - * sometimes quite big, in memory.
20824 - *
20825 - * @param context
20826 - * If this datatype is context-dependent
20827 - * (i.e. the {@link #isContextDependent} method returns true),
20828 - * then the caller must provide a non-null valid context object.
20829 - * Otherwise, the caller can pass null.
20830 - * The callee may keep a reference to this context object
20831 - * only while the returned streaming validator is being used.
20832 - */
20833 - DatatypeStreamingValidator createStreamingValidator( ValidationContext context );
20834 -
20835 - /**
20836 - * Converts lexcial value and the current context to the corresponding
20837 - * value object.
20838 - *
20839 - * <p>
20840 - * The caller cannot generally assume that the value object is
20841 - * a meaningful Java object. For example, the caller cannot expect
20842 - * this method to return <code>java.lang.Number</code> type for
20843 - * the "integer" type of XML Schema Part 2.
20844 - *
20845 - * <p>
20846 - * Also, the caller cannot assume that the equals method and
20847 - * the hashCode method of the value object are consistent with
20848 - * the semantics of the datatype. For that purpose, the sameValue
20849 - * method and the valueHashCode method have to be used. Note that
20850 - * this means you cannot use classes like
20851 - * <code>java.util.Hashtable</code> to store the value objects.
20852 - *
20853 - * <p>
20854 - * The returned value object should be used solely for the sameValue
20855 - * and valueHashCode methods.
20856 - *
20857 - * @param context
20858 - * If this datatype is context-dependent
20859 - * (when the {@link #isContextDependent} method returns true),
20860 - * then the caller must provide a non-null valid context object.
20861 - * Otherwise, the caller can pass null.
20862 - *
20863 - * @return null
20864 - * when the given lexical value is not a valid lexical
20865 - * value for this type.
20866 - */
20867 - Object createValue( String literal, ValidationContext context );
20868 -
20869 - /**
20870 - * Tests the equality of two value objects which were originally
20871 - * created by the createValue method of this object.
20872 - *
20873 - * The behavior is undefined if objects not created by this type
20874 - * are passed. It is the caller's responsibility to ensure that
20875 - * value objects belong to this type.
20876 - *
20877 - * @return
20878 - * true if two value objects are considered equal according to
20879 - * the definition of this datatype; false if otherwise.
20880 - */
20881 - boolean sameValue( Object value1, Object value2 );
20882 -
20883 -
20884 - /**
20885 - * Computes the hash code for a value object,
20886 - * which is consistent with the sameValue method.
20887 - *
20888 - * @return
20889 - * hash code for the specified value object.
20890 - */
20891 - int valueHashCode( Object value );
20892 -
20893 -
20894 -
20895 -
20896 - /**
20897 - * Indicates that the datatype doesn't have ID/IDREF semantics.
20898 - *
20899 - * This value is one of the possible return values of the
20900 - * {@link #getIdType} method.
20901 - */
20902 - public static final int ID_TYPE_NULL = 0;
20903 -
20904 - /**
20905 - * Indicates that RELAX NG compatibility processors should
20906 - * treat this datatype as having ID semantics.
20907 - *
20908 - * This value is one of the possible return values of the
20909 - * {@link #getIdType} method.
20910 - */
20911 - public static final int ID_TYPE_ID = 1;
20912 -
20913 - /**
20914 - * Indicates that RELAX NG compatibility processors should
20915 - * treat this datatype as having IDREF semantics.
20916 - *
20917 - * This value is one of the possible return values of the
20918 - * {@link #getIdType} method.
20919 - */
20920 - public static final int ID_TYPE_IDREF = 2;
20921 -
20922 - /**
20923 - * Indicates that RELAX NG compatibility processors should
20924 - * treat this datatype as having IDREFS semantics.
20925 - *
20926 - * This value is one of the possible return values of the
20927 - * {@link #getIdType} method.
20928 - */
20929 - public static final int ID_TYPE_IDREFS = 3;
20930 -
20931 - /**
20932 - * Checks if the ID/IDREF semantics is associated with this
20933 - * datatype.
20934 - *
20935 - * <p>
20936 - * This method is introduced to support the RELAX NG DTD
20937 - * compatibility spec. (Of course it's always free to use
20938 - * this method for other purposes.)
20939 - *
20940 - * <p>
20941 - * If you are implementing a datatype library and have no idea about
20942 - * the "RELAX NG DTD compatibility" thing, just return
20943 - * <code>ID_TYPE_NULL</code> is fine.
20944 - *
20945 - * @return
20946 - * If this datatype doesn't have any ID/IDREF semantics,
20947 - * it returns {@link #ID_TYPE_NULL}. If it has such a semantics
20948 - * (for example, XSD:ID, XSD:IDREF and comp:ID type), then
20949 - * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or
20950 - * {@link #ID_TYPE_IDREFS}.
20951 - */
20952 - public int getIdType();
20953 -
20954 -
20955 - /**
20956 - * Checks if this datatype may need a context object for
20957 - * the validation.
20958 - *
20959 - * <p>
20960 - * The callee must return true even when the context
20961 - * is not always necessary. (For example, the "QName" type
20962 - * doesn't need a context object when validating unprefixed
20963 - * string. But nonetheless QName must return true.)
20964 - *
20965 - * <p>
20966 - * XSD's <code>string</code> and <code>short</code> types
20967 - * are examples of context-independent datatypes.
20968 - * Its <code>QName</code> and <code>ENTITY</code> types
20969 - * are examples of context-dependent datatypes.
20970 - *
20971 - * <p>
20972 - * When a datatype is context-independent, then
20973 - * the {@link #isValid} method, the {@link #checkValid} method,
20974 - * the {@link #createStreamingValidator} method and
20975 - * the {@link #createValue} method can be called without
20976 - * providing a context object.
20977 - *
20978 - * @return
20979 - * <b>true</b> if this datatype is context-dependent
20980 - * (it needs a context object sometimes);
20981 - *
20982 - * <b>false</b> if this datatype is context-<b>in</b>dependent
20983 - * (it never needs a context object).
20984 - */
20985 - public boolean isContextDependent();
20986 -}
20987 +package org.relaxng.datatype;
20988 +
20989 +/**
20990 + * Datatype object.
20991 + *
20992 + * This object has the following functionality:
20993 + *
20994 + * <ol>
20995 + * <li> functionality to identify a class of character sequences. This is
20996 + * done through the isValid method.
20997 + *
20998 + * <li> functionality to produce a "value object" from a character sequence and
20999 + * context information.
21000 + *
21001 + * <li> functionality to test the equality of two value objects.
21002 + * </ol>
21003 + *
21004 + * This interface also defines the createStreamingValidator method,
21005 + * which is intended to efficiently support the validation of
21006 + * large character sequences.
21007 + *
21008 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21009 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21010 + */
21011 +public interface Datatype {
21012 +
21013 + /**
21014 + * Checks if the specified 'literal' matches this Datatype
21015 + * with respect to the current context.
21016 + *
21017 + * @param literal
21018 + * the lexical representation to be checked.
21019 + * @param context
21020 + * If this datatype is context-dependent
21021 + * (i.e. the {@link #isContextDependent} method returns true),
21022 + * then the caller must provide a non-null valid context object.
21023 + * Otherwise, the caller can pass null.
21024 + *
21025 + * @return
21026 + * true if the 'literal' is a member of this Datatype;
21027 + * false if it's not a member of this Datatype.
21028 + */
21029 + boolean isValid( String literal, ValidationContext context );
21030 +
21031 + /**
21032 + * Similar to the isValid method but throws an exception with diagnosis
21033 + * in case of errors.
21034 + *
21035 + * <p>
21036 + * If the specified 'literal' is a valid lexical representation for this
21037 + * datatype, then this method must return without throwing any exception.
21038 + * If not, the callee must throw an exception (with diagnosis message,
21039 + * if possible.)
21040 + *
21041 + * <p>
21042 + * The application can use this method to provide detailed error message
21043 + * to users. This method is kept separate from the isValid method to
21044 + * achieve higher performance during normal validation.
21045 + *
21046 + * @exception DatatypeException
21047 + * If the given literal is invalid, then this exception is thrown.
21048 + * If the callee supports error diagnosis, then the exception should
21049 + * contain a diagnosis message.
21050 + */
21051 + void checkValid( String literal, ValidationContext context )
21052 + throws DatatypeException;
21053 +
21054 + /**
21055 + * Creates an instance of a streaming validator for this type.
21056 + *
21057 + * <p>
21058 + * By using streaming validators instead of the isValid method,
21059 + * the caller can avoid keeping the entire string, which is
21060 + * sometimes quite big, in memory.
21061 + *
21062 + * @param context
21063 + * If this datatype is context-dependent
21064 + * (i.e. the {@link #isContextDependent} method returns true),
21065 + * then the caller must provide a non-null valid context object.
21066 + * Otherwise, the caller can pass null.
21067 + * The callee may keep a reference to this context object
21068 + * only while the returned streaming validator is being used.
21069 + */
21070 + DatatypeStreamingValidator createStreamingValidator( ValidationContext context );
21071 +
21072 + /**
21073 + * Converts lexcial value and the current context to the corresponding
21074 + * value object.
21075 + *
21076 + * <p>
21077 + * The caller cannot generally assume that the value object is
21078 + * a meaningful Java object. For example, the caller cannot expect
21079 + * this method to return <code>java.lang.Number</code> type for
21080 + * the "integer" type of XML Schema Part 2.
21081 + *
21082 + * <p>
21083 + * Also, the caller cannot assume that the equals method and
21084 + * the hashCode method of the value object are consistent with
21085 + * the semantics of the datatype. For that purpose, the sameValue
21086 + * method and the valueHashCode method have to be used. Note that
21087 + * this means you cannot use classes like
21088 + * <code>java.util.Hashtable</code> to store the value objects.
21089 + *
21090 + * <p>
21091 + * The returned value object should be used solely for the sameValue
21092 + * and valueHashCode methods.
21093 + *
21094 + * @param context
21095 + * If this datatype is context-dependent
21096 + * (when the {@link #isContextDependent} method returns true),
21097 + * then the caller must provide a non-null valid context object.
21098 + * Otherwise, the caller can pass null.
21099 + *
21100 + * @return null
21101 + * when the given lexical value is not a valid lexical
21102 + * value for this type.
21103 + */
21104 + Object createValue( String literal, ValidationContext context );
21105 +
21106 + /**
21107 + * Tests the equality of two value objects which were originally
21108 + * created by the createValue method of this object.
21109 + *
21110 + * The behavior is undefined if objects not created by this type
21111 + * are passed. It is the caller's responsibility to ensure that
21112 + * value objects belong to this type.
21113 + *
21114 + * @return
21115 + * true if two value objects are considered equal according to
21116 + * the definition of this datatype; false if otherwise.
21117 + */
21118 + boolean sameValue( Object value1, Object value2 );
21119 +
21120 +
21121 + /**
21122 + * Computes the hash code for a value object,
21123 + * which is consistent with the sameValue method.
21124 + *
21125 + * @return
21126 + * hash code for the specified value object.
21127 + */
21128 + int valueHashCode( Object value );
21129 +
21130 +
21131 +
21132 +
21133 + /**
21134 + * Indicates that the datatype doesn't have ID/IDREF semantics.
21135 + *
21136 + * This value is one of the possible return values of the
21137 + * {@link #getIdType} method.
21138 + */
21139 + public static final int ID_TYPE_NULL = 0;
21140 +
21141 + /**
21142 + * Indicates that RELAX NG compatibility processors should
21143 + * treat this datatype as having ID semantics.
21144 + *
21145 + * This value is one of the possible return values of the
21146 + * {@link #getIdType} method.
21147 + */
21148 + public static final int ID_TYPE_ID = 1;
21149 +
21150 + /**
21151 + * Indicates that RELAX NG compatibility processors should
21152 + * treat this datatype as having IDREF semantics.
21153 + *
21154 + * This value is one of the possible return values of the
21155 + * {@link #getIdType} method.
21156 + */
21157 + public static final int ID_TYPE_IDREF = 2;
21158 +
21159 + /**
21160 + * Indicates that RELAX NG compatibility processors should
21161 + * treat this datatype as having IDREFS semantics.
21162 + *
21163 + * This value is one of the possible return values of the
21164 + * {@link #getIdType} method.
21165 + */
21166 + public static final int ID_TYPE_IDREFS = 3;
21167 +
21168 + /**
21169 + * Checks if the ID/IDREF semantics is associated with this
21170 + * datatype.
21171 + *
21172 + * <p>
21173 + * This method is introduced to support the RELAX NG DTD
21174 + * compatibility spec. (Of course it's always free to use
21175 + * this method for other purposes.)
21176 + *
21177 + * <p>
21178 + * If you are implementing a datatype library and have no idea about
21179 + * the "RELAX NG DTD compatibility" thing, just return
21180 + * <code>ID_TYPE_NULL</code> is fine.
21181 + *
21182 + * @return
21183 + * If this datatype doesn't have any ID/IDREF semantics,
21184 + * it returns {@link #ID_TYPE_NULL}. If it has such a semantics
21185 + * (for example, XSD:ID, XSD:IDREF and comp:ID type), then
21186 + * it returns {@link #ID_TYPE_ID}, {@link #ID_TYPE_IDREF} or
21187 + * {@link #ID_TYPE_IDREFS}.
21188 + */
21189 + public int getIdType();
21190 +
21191 +
21192 + /**
21193 + * Checks if this datatype may need a context object for
21194 + * the validation.
21195 + *
21196 + * <p>
21197 + * The callee must return true even when the context
21198 + * is not always necessary. (For example, the "QName" type
21199 + * doesn't need a context object when validating unprefixed
21200 + * string. But nonetheless QName must return true.)
21201 + *
21202 + * <p>
21203 + * XSD's <code>string</code> and <code>short</code> types
21204 + * are examples of context-independent datatypes.
21205 + * Its <code>QName</code> and <code>ENTITY</code> types
21206 + * are examples of context-dependent datatypes.
21207 + *
21208 + * <p>
21209 + * When a datatype is context-independent, then
21210 + * the {@link #isValid} method, the {@link #checkValid} method,
21211 + * the {@link #createStreamingValidator} method and
21212 + * the {@link #createValue} method can be called without
21213 + * providing a context object.
21214 + *
21215 + * @return
21216 + * <b>true</b> if this datatype is context-dependent
21217 + * (it needs a context object sometimes);
21218 + *
21219 + * <b>false</b> if this datatype is context-<b>in</b>dependent
21220 + * (it never needs a context object).
21221 + */
21222 + public boolean isContextDependent();
21223 +}
21224 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java
21225 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java 2006-03-10 14:25:35.000000000 +0100
21226 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibraryFactory.java 2007-09-28 10:34:16.000000000 +0200
21227 @@ -1,26 +1,26 @@
21228 -package org.relaxng.datatype;
21229 -
21230 -/**
21231 - * Factory class for the DatatypeLibrary class.
21232 - *
21233 - * <p>
21234 - * The datatype library should provide the implementation of
21235 - * this interface if it wants to be found by the schema processors.
21236 - * The implementor also have to place a file in your jar file.
21237 - * See the reference datatype library implementation for detail.
21238 - *
21239 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21240 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21241 - */
21242 -public interface DatatypeLibraryFactory
21243 -{
21244 - /**
21245 - * Creates a new instance of a DatatypeLibrary that supports
21246 - * the specified namespace URI.
21247 - *
21248 - * @return
21249 - * <code>null</code> if the specified namespace URI is not
21250 - * supported.
21251 - */
21252 - DatatypeLibrary createDatatypeLibrary( String namespaceURI );
21253 -}
21254 +package org.relaxng.datatype;
21255 +
21256 +/**
21257 + * Factory class for the DatatypeLibrary class.
21258 + *
21259 + * <p>
21260 + * The datatype library should provide the implementation of
21261 + * this interface if it wants to be found by the schema processors.
21262 + * The implementor also have to place a file in your jar file.
21263 + * See the reference datatype library implementation for detail.
21264 + *
21265 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21266 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21267 + */
21268 +public interface DatatypeLibraryFactory
21269 +{
21270 + /**
21271 + * Creates a new instance of a DatatypeLibrary that supports
21272 + * the specified namespace URI.
21273 + *
21274 + * @return
21275 + * <code>null</code> if the specified namespace URI is not
21276 + * supported.
21277 + */
21278 + DatatypeLibrary createDatatypeLibrary( String namespaceURI );
21279 +}
21280 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java
21281 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java 2006-03-10 14:25:35.000000000 +0100
21282 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeLibrary.java 2007-09-28 10:34:16.000000000 +0200
21283 @@ -1,37 +1,37 @@
21284 -package org.relaxng.datatype;
21285 -
21286 -/**
21287 - * A Datatype library
21288 - *
21289 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21290 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21291 - */
21292 -public interface DatatypeLibrary {
21293 -
21294 - /**
21295 - * Creates a new instance of DatatypeBuilder.
21296 - *
21297 - * The callee should throw a DatatypeException in case of an error.
21298 - *
21299 - * @param baseTypeLocalName
21300 - * The local name of the base type.
21301 - *
21302 - * @return
21303 - * A non-null valid datatype object.
21304 - */
21305 - DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName )
21306 - throws DatatypeException;
21307 -
21308 - /**
21309 - * Gets or creates a pre-defined type.
21310 - *
21311 - * This is just a short-cut of
21312 - * <code>createDatatypeBuilder(typeLocalName).createDatatype();</code>
21313 - *
21314 - * The callee should throw a DatatypeException in case of an error.
21315 - *
21316 - * @return
21317 - * A non-null valid datatype object.
21318 - */
21319 - Datatype createDatatype( String typeLocalName ) throws DatatypeException;
21320 -}
21321 +package org.relaxng.datatype;
21322 +
21323 +/**
21324 + * A Datatype library
21325 + *
21326 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21327 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21328 + */
21329 +public interface DatatypeLibrary {
21330 +
21331 + /**
21332 + * Creates a new instance of DatatypeBuilder.
21333 + *
21334 + * The callee should throw a DatatypeException in case of an error.
21335 + *
21336 + * @param baseTypeLocalName
21337 + * The local name of the base type.
21338 + *
21339 + * @return
21340 + * A non-null valid datatype object.
21341 + */
21342 + DatatypeBuilder createDatatypeBuilder( String baseTypeLocalName )
21343 + throws DatatypeException;
21344 +
21345 + /**
21346 + * Gets or creates a pre-defined type.
21347 + *
21348 + * This is just a short-cut of
21349 + * <code>createDatatypeBuilder(typeLocalName).createDatatype();</code>
21350 + *
21351 + * The callee should throw a DatatypeException in case of an error.
21352 + *
21353 + * @return
21354 + * A non-null valid datatype object.
21355 + */
21356 + Datatype createDatatype( String typeLocalName ) throws DatatypeException;
21357 +}
21358 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java
21359 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java 2006-03-10 14:25:35.000000000 +0100
21360 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/DatatypeStreamingValidator.java 2007-09-28 10:34:16.000000000 +0200
21361 @@ -1,46 +1,46 @@
21362 -package org.relaxng.datatype;
21363 -
21364 -/**
21365 - * Datatype streaming validator.
21366 - *
21367 - * <p>
21368 - * The streaming validator is an optional feature that is useful for
21369 - * certain Datatypes. It allows the caller to incrementally provide
21370 - * the literal.
21371 - *
21372 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21373 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21374 - */
21375 -public interface DatatypeStreamingValidator {
21376 -
21377 - /**
21378 - * Passes an additional fragment of the literal.
21379 - *
21380 - * <p>
21381 - * The application can call this method several times, then call
21382 - * the isValid method (or the checkValid method) to check the validity
21383 - * of the accumulated characters.
21384 - */
21385 - void addCharacters( char[] buf, int start, int len );
21386 -
21387 - /**
21388 - * Tells if the accumulated literal is valid with respect to
21389 - * the underlying Datatype.
21390 - *
21391 - * @return
21392 - * True if it is valid. False if otherwise.
21393 - */
21394 - boolean isValid();
21395 -
21396 - /**
21397 - * Similar to the isValid method, but this method throws
21398 - * Exception (with possibly diagnostic information), instead of
21399 - * returning false.
21400 - *
21401 - * @exception DatatypeException
21402 - * If the callee supports the diagnosis and the accumulated
21403 - * literal is invalid, then this exception that possibly
21404 - * contains diagnosis information is thrown.
21405 - */
21406 - void checkValid() throws DatatypeException;
21407 -}
21408 +package org.relaxng.datatype;
21409 +
21410 +/**
21411 + * Datatype streaming validator.
21412 + *
21413 + * <p>
21414 + * The streaming validator is an optional feature that is useful for
21415 + * certain Datatypes. It allows the caller to incrementally provide
21416 + * the literal.
21417 + *
21418 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
21419 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
21420 + */
21421 +public interface DatatypeStreamingValidator {
21422 +
21423 + /**
21424 + * Passes an additional fragment of the literal.
21425 + *
21426 + * <p>
21427 + * The application can call this method several times, then call
21428 + * the isValid method (or the checkValid method) to check the validity
21429 + * of the accumulated characters.
21430 + */
21431 + void addCharacters( char[] buf, int start, int len );
21432 +
21433 + /**
21434 + * Tells if the accumulated literal is valid with respect to
21435 + * the underlying Datatype.
21436 + *
21437 + * @return
21438 + * True if it is valid. False if otherwise.
21439 + */
21440 + boolean isValid();
21441 +
21442 + /**
21443 + * Similar to the isValid method, but this method throws
21444 + * Exception (with possibly diagnostic information), instead of
21445 + * returning false.
21446 + *
21447 + * @exception DatatypeException
21448 + * If the callee supports the diagnosis and the accumulated
21449 + * literal is invalid, then this exception that possibly
21450 + * contains diagnosis information is thrown.
21451 + */
21452 + void checkValid() throws DatatypeException;
21453 +}
21454 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java
21455 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java 2006-03-10 14:25:35.000000000 +0100
21456 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/DatatypeLibraryLoader.java 2007-09-28 10:34:16.000000000 +0200
21457 @@ -1,262 +1,262 @@
21458 -/**
21459 - * Copyright (c) 2001, Thai Open Source Software Center Ltd
21460 - * All rights reserved.
21461 - *
21462 - * Redistribution and use in source and binary forms, with or without
21463 - * modification, are permitted provided that the following conditions are
21464 - * met:
21465 - *
21466 - * Redistributions of source code must retain the above copyright
21467 - * notice, this list of conditions and the following disclaimer.
21468 - *
21469 - * Redistributions in binary form must reproduce the above copyright
21470 - * notice, this list of conditions and the following disclaimer in
21471 - * the documentation and/or other materials provided with the
21472 - * distribution.
21473 - *
21474 - * Neither the name of the Thai Open Source Software Center Ltd nor
21475 - * the names of its contributors may be used to endorse or promote
21476 - * products derived from this software without specific prior written
21477 - * permission.
21478 - *
21479 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21480 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21481 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21482 - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21483 - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21484 - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21485 - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21486 - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21487 - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21488 - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21489 - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21490 - */
21491 -package org.relaxng.datatype.helpers;
21492 -
21493 -import org.relaxng.datatype.DatatypeLibraryFactory;
21494 -import org.relaxng.datatype.DatatypeLibrary;
21495 -import java.util.Enumeration;
21496 -import java.util.NoSuchElementException;
21497 -import java.util.Vector;
21498 -import java.io.Reader;
21499 -import java.io.InputStream;
21500 -import java.io.InputStreamReader;
21501 -import java.io.BufferedReader;
21502 -import java.io.IOException;
21503 -import java.io.UnsupportedEncodingException;
21504 -import java.net.URL;
21505 -
21506 -/**
21507 - * Discovers the datatype library implementation from the classpath.
21508 - *
21509 - * <p>
21510 - * The call of the createDatatypeLibrary method finds an implementation
21511 - * from a given datatype library URI at run-time.
21512 - */
21513 -public class DatatypeLibraryLoader implements DatatypeLibraryFactory {
21514 - private final Service service = new Service(DatatypeLibraryFactory.class);
21515 -
21516 - public DatatypeLibrary createDatatypeLibrary(String uri) {
21517 - for (Enumeration e = service.getProviders();
21518 - e.hasMoreElements();) {
21519 - DatatypeLibraryFactory factory
21520 - = (DatatypeLibraryFactory)e.nextElement();
21521 - DatatypeLibrary library = factory.createDatatypeLibrary(uri);
21522 - if (library != null)
21523 - return library;
21524 - }
21525 - return null;
21526 - }
21527 -
21528 - private static class Service {
21529 - private final Class serviceClass;
21530 - private final Enumeration configFiles;
21531 - private Enumeration classNames = null;
21532 - private final Vector providers = new Vector();
21533 - private Loader loader;
21534 -
21535 - private class ProviderEnumeration implements Enumeration {
21536 - private int nextIndex = 0;
21537 -
21538 - public boolean hasMoreElements() {
21539 - return nextIndex < providers.size() || moreProviders();
21540 - }
21541 -
21542 - public Object nextElement() {
21543 - try {
21544 - return providers.elementAt(nextIndex++);
21545 - }
21546 - catch (ArrayIndexOutOfBoundsException e) {
21547 - throw new NoSuchElementException();
21548 - }
21549 - }
21550 - }
21551 -
21552 - private static class Singleton implements Enumeration {
21553 - private Object obj;
21554 - private Singleton(Object obj) {
21555 - this.obj = obj;
21556 - }
21557 -
21558 - public boolean hasMoreElements() {
21559 - return obj != null;
21560 - }
21561 -
21562 - public Object nextElement() {
21563 - if (obj == null)
21564 - throw new NoSuchElementException();
21565 - Object tem = obj;
21566 - obj = null;
21567 - return tem;
21568 - }
21569 - }
21570 -
21571 - // JDK 1.1
21572 - private static class Loader {
21573 - Enumeration getResources(String resName) {
21574 - ClassLoader cl = Loader.class.getClassLoader();
21575 - URL url;
21576 - if (cl == null)
21577 - url = ClassLoader.getSystemResource(resName);
21578 - else
21579 - url = cl.getResource(resName);
21580 - return new Singleton(url);
21581 - }
21582 -
21583 - Class loadClass(String name) throws ClassNotFoundException {
21584 - return Class.forName(name);
21585 - }
21586 - }
21587 -
21588 - // JDK 1.2+
21589 - private static class Loader2 extends Loader {
21590 - private ClassLoader cl;
21591 -
21592 - Loader2() {
21593 - cl = Loader2.class.getClassLoader();
21594 - // If the thread context class loader has the class loader
21595 - // of this class as an ancestor, use the thread context class
21596 - // loader. Otherwise, the thread context class loader
21597 - // probably hasn't been set up properly, so don't use it.
21598 - ClassLoader clt = Thread.currentThread().getContextClassLoader();
21599 - for (ClassLoader tem = clt; tem != null; tem = tem.getParent())
21600 - if (tem == cl) {
21601 - cl = clt;
21602 - break;
21603 - }
21604 - }
21605 -
21606 - Enumeration getResources(String resName) {
21607 - try {
21608 - return cl.getResources(resName);
21609 - }
21610 - catch (IOException e) {
21611 - return new Singleton(null);
21612 - }
21613 - }
21614 -
21615 - Class loadClass(String name) throws ClassNotFoundException {
21616 - return Class.forName(name, true, cl);
21617 - }
21618 - }
21619 -
21620 - public Service(Class cls) {
21621 - try {
21622 - loader = new Loader2();
21623 - }
21624 - catch (NoSuchMethodError e) {
21625 - loader = new Loader();
21626 - }
21627 - serviceClass = cls;
21628 - String resName = "META-INF/services/" + serviceClass.getName();
21629 - configFiles = loader.getResources(resName);
21630 - }
21631 -
21632 - public Enumeration getProviders() {
21633 - return new ProviderEnumeration();
21634 - }
21635 -
21636 - synchronized private boolean moreProviders() {
21637 - for (;;) {
21638 - while (classNames == null) {
21639 - if (!configFiles.hasMoreElements())
21640 - return false;
21641 - classNames = parseConfigFile((URL)configFiles.nextElement());
21642 - }
21643 - while (classNames.hasMoreElements()) {
21644 - String className = (String)classNames.nextElement();
21645 - try {
21646 - Class cls = loader.loadClass(className);
21647 - Object obj = cls.newInstance();
21648 - if (serviceClass.isInstance(obj)) {
21649 - providers.addElement(obj);
21650 - return true;
21651 - }
21652 - }
21653 - catch (ClassNotFoundException e) { }
21654 - catch (InstantiationException e) { }
21655 - catch (IllegalAccessException e) { }
21656 - catch (LinkageError e) { }
21657 - }
21658 - classNames = null;
21659 - }
21660 - }
21661 -
21662 - private static final int START = 0;
21663 - private static final int IN_NAME = 1;
21664 - private static final int IN_COMMENT = 2;
21665 -
21666 - private static Enumeration parseConfigFile(URL url) {
21667 - try {
21668 - InputStream in = url.openStream();
21669 - Reader r;
21670 - try {
21671 - r = new InputStreamReader(in, "UTF-8");
21672 - }
21673 - catch (UnsupportedEncodingException e) {
21674 - r = new InputStreamReader(in, "UTF8");
21675 - }
21676 - r = new BufferedReader(r);
21677 - Vector tokens = new Vector();
21678 - StringBuffer tokenBuf = new StringBuffer();
21679 - int state = START;
21680 - for (;;) {
21681 - int n = r.read();
21682 - if (n < 0)
21683 - break;
21684 - char c = (char)n;
21685 - switch (c) {
21686 - case '\r':
21687 - case '\n':
21688 - state = START;
21689 - break;
21690 - case ' ':
21691 - case '\t':
21692 - break;
21693 - case '#':
21694 - state = IN_COMMENT;
21695 - break;
21696 - default:
21697 - if (state != IN_COMMENT) {
21698 - state = IN_NAME;
21699 - tokenBuf.append(c);
21700 - }
21701 - break;
21702 - }
21703 - if (tokenBuf.length() != 0 && state != IN_NAME) {
21704 - tokens.addElement(tokenBuf.toString());
21705 - tokenBuf.setLength(0);
21706 - }
21707 - }
21708 - if (tokenBuf.length() != 0)
21709 - tokens.addElement(tokenBuf.toString());
21710 - return tokens.elements();
21711 - }
21712 - catch (IOException e) {
21713 - return null;
21714 - }
21715 - }
21716 - }
21717 -
21718 -}
21719 -
21720 +/**
21721 + * Copyright (c) 2001, Thai Open Source Software Center Ltd
21722 + * All rights reserved.
21723 + *
21724 + * Redistribution and use in source and binary forms, with or without
21725 + * modification, are permitted provided that the following conditions are
21726 + * met:
21727 + *
21728 + * Redistributions of source code must retain the above copyright
21729 + * notice, this list of conditions and the following disclaimer.
21730 + *
21731 + * Redistributions in binary form must reproduce the above copyright
21732 + * notice, this list of conditions and the following disclaimer in
21733 + * the documentation and/or other materials provided with the
21734 + * distribution.
21735 + *
21736 + * Neither the name of the Thai Open Source Software Center Ltd nor
21737 + * the names of its contributors may be used to endorse or promote
21738 + * products derived from this software without specific prior written
21739 + * permission.
21740 + *
21741 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21742 + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21743 + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21744 + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21745 + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21746 + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21747 + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21748 + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21749 + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
21750 + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21751 + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21752 + */
21753 +package org.relaxng.datatype.helpers;
21754 +
21755 +import org.relaxng.datatype.DatatypeLibraryFactory;
21756 +import org.relaxng.datatype.DatatypeLibrary;
21757 +import java.util.Enumeration;
21758 +import java.util.NoSuchElementException;
21759 +import java.util.Vector;
21760 +import java.io.Reader;
21761 +import java.io.InputStream;
21762 +import java.io.InputStreamReader;
21763 +import java.io.BufferedReader;
21764 +import java.io.IOException;
21765 +import java.io.UnsupportedEncodingException;
21766 +import java.net.URL;
21767 +
21768 +/**
21769 + * Discovers the datatype library implementation from the classpath.
21770 + *
21771 + * <p>
21772 + * The call of the createDatatypeLibrary method finds an implementation
21773 + * from a given datatype library URI at run-time.
21774 + */
21775 +public class DatatypeLibraryLoader implements DatatypeLibraryFactory {
21776 + private final Service service = new Service(DatatypeLibraryFactory.class);
21777 +
21778 + public DatatypeLibrary createDatatypeLibrary(String uri) {
21779 + for (Enumeration e = service.getProviders();
21780 + e.hasMoreElements();) {
21781 + DatatypeLibraryFactory factory
21782 + = (DatatypeLibraryFactory)e.nextElement();
21783 + DatatypeLibrary library = factory.createDatatypeLibrary(uri);
21784 + if (library != null)
21785 + return library;
21786 + }
21787 + return null;
21788 + }
21789 +
21790 + private static class Service {
21791 + private final Class serviceClass;
21792 + private final Enumeration configFiles;
21793 + private Enumeration classNames = null;
21794 + private final Vector providers = new Vector();
21795 + private Loader loader;
21796 +
21797 + private class ProviderEnumeration implements Enumeration {
21798 + private int nextIndex = 0;
21799 +
21800 + public boolean hasMoreElements() {
21801 + return nextIndex < providers.size() || moreProviders();
21802 + }
21803 +
21804 + public Object nextElement() {
21805 + try {
21806 + return providers.elementAt(nextIndex++);
21807 + }
21808 + catch (ArrayIndexOutOfBoundsException e) {
21809 + throw new NoSuchElementException();
21810 + }
21811 + }
21812 + }
21813 +
21814 + private static class Singleton implements Enumeration {
21815 + private Object obj;
21816 + private Singleton(Object obj) {
21817 + this.obj = obj;
21818 + }
21819 +
21820 + public boolean hasMoreElements() {
21821 + return obj != null;
21822 + }
21823 +
21824 + public Object nextElement() {
21825 + if (obj == null)
21826 + throw new NoSuchElementException();
21827 + Object tem = obj;
21828 + obj = null;
21829 + return tem;
21830 + }
21831 + }
21832 +
21833 + // JDK 1.1
21834 + private static class Loader {
21835 + Enumeration getResources(String resName) {
21836 + ClassLoader cl = Loader.class.getClassLoader();
21837 + URL url;
21838 + if (cl == null)
21839 + url = ClassLoader.getSystemResource(resName);
21840 + else
21841 + url = cl.getResource(resName);
21842 + return new Singleton(url);
21843 + }
21844 +
21845 + Class loadClass(String name) throws ClassNotFoundException {
21846 + return Class.forName(name);
21847 + }
21848 + }
21849 +
21850 + // JDK 1.2+
21851 + private static class Loader2 extends Loader {
21852 + private ClassLoader cl;
21853 +
21854 + Loader2() {
21855 + cl = Loader2.class.getClassLoader();
21856 + // If the thread context class loader has the class loader
21857 + // of this class as an ancestor, use the thread context class
21858 + // loader. Otherwise, the thread context class loader
21859 + // probably hasn't been set up properly, so don't use it.
21860 + ClassLoader clt = Thread.currentThread().getContextClassLoader();
21861 + for (ClassLoader tem = clt; tem != null; tem = tem.getParent())
21862 + if (tem == cl) {
21863 + cl = clt;
21864 + break;
21865 + }
21866 + }
21867 +
21868 + Enumeration getResources(String resName) {
21869 + try {
21870 + return cl.getResources(resName);
21871 + }
21872 + catch (IOException e) {
21873 + return new Singleton(null);
21874 + }
21875 + }
21876 +
21877 + Class loadClass(String name) throws ClassNotFoundException {
21878 + return Class.forName(name, true, cl);
21879 + }
21880 + }
21881 +
21882 + public Service(Class cls) {
21883 + try {
21884 + loader = new Loader2();
21885 + }
21886 + catch (NoSuchMethodError e) {
21887 + loader = new Loader();
21888 + }
21889 + serviceClass = cls;
21890 + String resName = "META-INF/services/" + serviceClass.getName();
21891 + configFiles = loader.getResources(resName);
21892 + }
21893 +
21894 + public Enumeration getProviders() {
21895 + return new ProviderEnumeration();
21896 + }
21897 +
21898 + synchronized private boolean moreProviders() {
21899 + for (;;) {
21900 + while (classNames == null) {
21901 + if (!configFiles.hasMoreElements())
21902 + return false;
21903 + classNames = parseConfigFile((URL)configFiles.nextElement());
21904 + }
21905 + while (classNames.hasMoreElements()) {
21906 + String className = (String)classNames.nextElement();
21907 + try {
21908 + Class cls = loader.loadClass(className);
21909 + Object obj = cls.newInstance();
21910 + if (serviceClass.isInstance(obj)) {
21911 + providers.addElement(obj);
21912 + return true;
21913 + }
21914 + }
21915 + catch (ClassNotFoundException e) { }
21916 + catch (InstantiationException e) { }
21917 + catch (IllegalAccessException e) { }
21918 + catch (LinkageError e) { }
21919 + }
21920 + classNames = null;
21921 + }
21922 + }
21923 +
21924 + private static final int START = 0;
21925 + private static final int IN_NAME = 1;
21926 + private static final int IN_COMMENT = 2;
21927 +
21928 + private static Enumeration parseConfigFile(URL url) {
21929 + try {
21930 + InputStream in = url.openStream();
21931 + Reader r;
21932 + try {
21933 + r = new InputStreamReader(in, "UTF-8");
21934 + }
21935 + catch (UnsupportedEncodingException e) {
21936 + r = new InputStreamReader(in, "UTF8");
21937 + }
21938 + r = new BufferedReader(r);
21939 + Vector tokens = new Vector();
21940 + StringBuffer tokenBuf = new StringBuffer();
21941 + int state = START;
21942 + for (;;) {
21943 + int n = r.read();
21944 + if (n < 0)
21945 + break;
21946 + char c = (char)n;
21947 + switch (c) {
21948 + case '\r':
21949 + case '\n':
21950 + state = START;
21951 + break;
21952 + case ' ':
21953 + case '\t':
21954 + break;
21955 + case '#':
21956 + state = IN_COMMENT;
21957 + break;
21958 + default:
21959 + if (state != IN_COMMENT) {
21960 + state = IN_NAME;
21961 + tokenBuf.append(c);
21962 + }
21963 + break;
21964 + }
21965 + if (tokenBuf.length() != 0 && state != IN_NAME) {
21966 + tokens.addElement(tokenBuf.toString());
21967 + tokenBuf.setLength(0);
21968 + }
21969 + }
21970 + if (tokenBuf.length() != 0)
21971 + tokens.addElement(tokenBuf.toString());
21972 + return tokens.elements();
21973 + }
21974 + catch (IOException e) {
21975 + return null;
21976 + }
21977 + }
21978 + }
21979 +
21980 +}
21981 +
21982 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java
21983 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java 2006-03-10 14:25:35.000000000 +0100
21984 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/ParameterlessDatatypeBuilder.java 2007-09-28 10:34:16.000000000 +0200
21985 @@ -1,42 +1,42 @@
21986 -package org.relaxng.datatype.helpers;
21987 -
21988 -import org.relaxng.datatype.*;
21989 -
21990 -/**
21991 - * Dummy implementation of {@link DatatypeBuilder}.
21992 - *
21993 - * This implementation can be used for Datatypes which have no parameters.
21994 - * Any attempt to add parameters will be rejected.
21995 - *
21996 - * <p>
21997 - * Typical usage would be:
21998 - * <PRE><XMP>
21999 - * class MyDatatypeLibrary implements DatatypeLibrary {
22000 - * ....
22001 - * DatatypeBuilder createDatatypeBuilder( String typeName ) {
22002 - * return new ParameterleessDatatypeBuilder(createDatatype(typeName));
22003 - * }
22004 - * ....
22005 - * }
22006 - * </XMP></PRE>
22007 - *
22008 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22009 - */
22010 -public final class ParameterlessDatatypeBuilder implements DatatypeBuilder {
22011 -
22012 - /** This type object is returned for the derive method. */
22013 - private final Datatype baseType;
22014 -
22015 - public ParameterlessDatatypeBuilder( Datatype baseType ) {
22016 - this.baseType = baseType;
22017 - }
22018 -
22019 - public void addParameter( String name, String strValue, ValidationContext context )
22020 - throws DatatypeException {
22021 - throw new DatatypeException();
22022 - }
22023 -
22024 - public Datatype createDatatype() throws DatatypeException {
22025 - return baseType;
22026 - }
22027 -}
22028 +package org.relaxng.datatype.helpers;
22029 +
22030 +import org.relaxng.datatype.*;
22031 +
22032 +/**
22033 + * Dummy implementation of {@link DatatypeBuilder}.
22034 + *
22035 + * This implementation can be used for Datatypes which have no parameters.
22036 + * Any attempt to add parameters will be rejected.
22037 + *
22038 + * <p>
22039 + * Typical usage would be:
22040 + * <PRE><XMP>
22041 + * class MyDatatypeLibrary implements DatatypeLibrary {
22042 + * ....
22043 + * DatatypeBuilder createDatatypeBuilder( String typeName ) {
22044 + * return new ParameterleessDatatypeBuilder(createDatatype(typeName));
22045 + * }
22046 + * ....
22047 + * }
22048 + * </XMP></PRE>
22049 + *
22050 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22051 + */
22052 +public final class ParameterlessDatatypeBuilder implements DatatypeBuilder {
22053 +
22054 + /** This type object is returned for the derive method. */
22055 + private final Datatype baseType;
22056 +
22057 + public ParameterlessDatatypeBuilder( Datatype baseType ) {
22058 + this.baseType = baseType;
22059 + }
22060 +
22061 + public void addParameter( String name, String strValue, ValidationContext context )
22062 + throws DatatypeException {
22063 + throw new DatatypeException();
22064 + }
22065 +
22066 + public Datatype createDatatype() throws DatatypeException {
22067 + return baseType;
22068 + }
22069 +}
22070 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java
22071 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java 2006-03-10 14:25:35.000000000 +0100
22072 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/helpers/StreamingValidatorImpl.java 2007-09-28 10:34:16.000000000 +0200
22073 @@ -1,55 +1,55 @@
22074 -package org.relaxng.datatype.helpers;
22075 -
22076 -import org.relaxng.datatype.*;
22077 -
22078 -/**
22079 - * Dummy implementation of {@link DatatypeStreamingValidator}.
22080 - *
22081 - * <p>
22082 - * This implementation can be used as a quick hack when the performance
22083 - * of streaming validation is not important. And this implementation
22084 - * also shows you how to implement the DatatypeStreamingValidator interface.
22085 - *
22086 - * <p>
22087 - * Typical usage would be:
22088 - * <PRE><XMP>
22089 - * class MyDatatype implements Datatype {
22090 - * ....
22091 - * public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) {
22092 - * return new StreamingValidatorImpl(this,context);
22093 - * }
22094 - * ....
22095 - * }
22096 - * </XMP></PRE>
22097 - *
22098 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22099 - */
22100 -public final class StreamingValidatorImpl implements DatatypeStreamingValidator {
22101 -
22102 - /** This buffer accumulates characters. */
22103 - private final StringBuffer buffer = new StringBuffer();
22104 -
22105 - /** Datatype obejct that creates this streaming validator. */
22106 - private final Datatype baseType;
22107 -
22108 - /** The current context. */
22109 - private final ValidationContext context;
22110 -
22111 - public void addCharacters( char[] buf, int start, int len ) {
22112 - // append characters to the current buffer.
22113 - buffer.append(buf,start,len);
22114 - }
22115 -
22116 - public boolean isValid() {
22117 - return baseType.isValid(buffer.toString(),context);
22118 - }
22119 -
22120 - public void checkValid() throws DatatypeException {
22121 - baseType.checkValid(buffer.toString(),context);
22122 - }
22123 -
22124 - public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) {
22125 - this.baseType = baseType;
22126 - this.context = context;
22127 - }
22128 -}
22129 +package org.relaxng.datatype.helpers;
22130 +
22131 +import org.relaxng.datatype.*;
22132 +
22133 +/**
22134 + * Dummy implementation of {@link DatatypeStreamingValidator}.
22135 + *
22136 + * <p>
22137 + * This implementation can be used as a quick hack when the performance
22138 + * of streaming validation is not important. And this implementation
22139 + * also shows you how to implement the DatatypeStreamingValidator interface.
22140 + *
22141 + * <p>
22142 + * Typical usage would be:
22143 + * <PRE><XMP>
22144 + * class MyDatatype implements Datatype {
22145 + * ....
22146 + * public DatatypeStreamingValidator createStreamingValidator( ValidationContext context ) {
22147 + * return new StreamingValidatorImpl(this,context);
22148 + * }
22149 + * ....
22150 + * }
22151 + * </XMP></PRE>
22152 + *
22153 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22154 + */
22155 +public final class StreamingValidatorImpl implements DatatypeStreamingValidator {
22156 +
22157 + /** This buffer accumulates characters. */
22158 + private final StringBuffer buffer = new StringBuffer();
22159 +
22160 + /** Datatype obejct that creates this streaming validator. */
22161 + private final Datatype baseType;
22162 +
22163 + /** The current context. */
22164 + private final ValidationContext context;
22165 +
22166 + public void addCharacters( char[] buf, int start, int len ) {
22167 + // append characters to the current buffer.
22168 + buffer.append(buf,start,len);
22169 + }
22170 +
22171 + public boolean isValid() {
22172 + return baseType.isValid(buffer.toString(),context);
22173 + }
22174 +
22175 + public void checkValid() throws DatatypeException {
22176 + baseType.checkValid(buffer.toString(),context);
22177 + }
22178 +
22179 + public StreamingValidatorImpl( Datatype baseType, ValidationContext context ) {
22180 + this.baseType = baseType;
22181 + this.context = context;
22182 + }
22183 +}
22184 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java
22185 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java 2006-03-10 14:25:35.000000000 +0100
22186 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/org/relaxng/datatype/ValidationContext.java 2007-09-28 10:34:16.000000000 +0200
22187 @@ -1,66 +1,66 @@
22188 -package org.relaxng.datatype;
22189 -
22190 -/**
22191 - * An interface that must be implemented by caller to
22192 - * provide context information that is necessary to
22193 - * perform validation of some Datatypes.
22194 - *
22195 - * @author <a href="mailto:jjc@jclark.com">James Clark</a>
22196 - * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22197 - */
22198 -public interface ValidationContext {
22199 -
22200 - /**
22201 - * Resolves a namespace prefix to the corresponding namespace URI.
22202 - *
22203 - * This method is used for validating the QName type, for example.
22204 - *
22205 - * <p>
22206 - * If the prefix is "" (empty string), it indicates
22207 - * an unprefixed value. The callee
22208 - * should resolve it as for an unprefixed
22209 - * element, rather than for an unprefixed attribute.
22210 - *
22211 - * <p>
22212 - * If the prefix is "xml", then the callee must resolve
22213 - * this prefix into "http://www.w3.org/XML/1998/namespace",
22214 - * as defined in the XML Namespaces Recommendation.
22215 - *
22216 - * @return
22217 - * namespace URI of this prefix.
22218 - * If the specified prefix is not declared,
22219 - * the implementation must return null.
22220 - */
22221 - String resolveNamespacePrefix( String prefix );
22222 -
22223 - /**
22224 - * Returns the base URI of the context. The null string may be returned
22225 - * if no base URI is known.
22226 - */
22227 - String getBaseUri();
22228 -
22229 - /**
22230 - * Checks if an unparsed entity is declared with the
22231 - * specified name.
22232 - *
22233 - * @return
22234 - * true
22235 - * if the DTD has an unparsed entity declaration for
22236 - * the specified name.
22237 - * false
22238 - * otherwise.
22239 - */
22240 - boolean isUnparsedEntity( String entityName );
22241 -
22242 - /**
22243 - * Checks if a notation is declared with the
22244 - * specified name.
22245 - *
22246 - * @return
22247 - * true
22248 - * if the DTD has a notation declaration for the specified name.
22249 - * false
22250 - * otherwise.
22251 - */
22252 - boolean isNotation( String notationName );
22253 -}
22254 +package org.relaxng.datatype;
22255 +
22256 +/**
22257 + * An interface that must be implemented by caller to
22258 + * provide context information that is necessary to
22259 + * perform validation of some Datatypes.
22260 + *
22261 + * @author <a href="mailto:jjc@jclark.com">James Clark</a>
22262 + * @author <a href="mailto:kohsuke.kawaguchi@sun.com">Kohsuke KAWAGUCHI</a>
22263 + */
22264 +public interface ValidationContext {
22265 +
22266 + /**
22267 + * Resolves a namespace prefix to the corresponding namespace URI.
22268 + *
22269 + * This method is used for validating the QName type, for example.
22270 + *
22271 + * <p>
22272 + * If the prefix is "" (empty string), it indicates
22273 + * an unprefixed value. The callee
22274 + * should resolve it as for an unprefixed
22275 + * element, rather than for an unprefixed attribute.
22276 + *
22277 + * <p>
22278 + * If the prefix is "xml", then the callee must resolve
22279 + * this prefix into "http://www.w3.org/XML/1998/namespace",
22280 + * as defined in the XML Namespaces Recommendation.
22281 + *
22282 + * @return
22283 + * namespace URI of this prefix.
22284 + * If the specified prefix is not declared,
22285 + * the implementation must return null.
22286 + */
22287 + String resolveNamespacePrefix( String prefix );
22288 +
22289 + /**
22290 + * Returns the base URI of the context. The null string may be returned
22291 + * if no base URI is known.
22292 + */
22293 + String getBaseUri();
22294 +
22295 + /**
22296 + * Checks if an unparsed entity is declared with the
22297 + * specified name.
22298 + *
22299 + * @return
22300 + * true
22301 + * if the DTD has an unparsed entity declaration for
22302 + * the specified name.
22303 + * false
22304 + * otherwise.
22305 + */
22306 + boolean isUnparsedEntity( String entityName );
22307 +
22308 + /**
22309 + * Checks if a notation is declared with the
22310 + * specified name.
22311 + *
22312 + * @return
22313 + * true
22314 + * if the DTD has a notation declaration for the specified name.
22315 + * false
22316 + * otherwise.
22317 + */
22318 + boolean isNotation( String notationName );
22319 +}
22320 diff -Nrup gcc-4.2.1/libjava/classpath/external/relaxngDatatype/README.txt gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/README.txt
22321 --- gcc-4.2.1/libjava/classpath/external/relaxngDatatype/README.txt 2006-03-10 14:25:35.000000000 +0100
22322 +++ gcc-4.2.1.atmel.1.3.2/libjava/classpath/external/relaxngDatatype/README.txt 2007-09-28 10:34:16.000000000 +0200
22323 @@ -1,54 +1,54 @@
22324 -======================================================================
22325 - README FILE FOR DATATYPE INTERFACES FOR RELAX NG
22326 -======================================================================
22327 -
22328 -
22329 -
22330 -RELAX NG supports multiple datatype vocabularies. To achive this, an
22331 -interface between datatype vocabularies and schema processors is
22332 -necessary. This interface is intended to be a standard Java interface
22333 -for this purpose.
22334 -
22335 -
22336 -----------------------------------------------------------------------
22337 -LICENSE
22338 -----------------------------------------------------------------------
22339 -
22340 -See copying.txt.
22341 -
22342 -Note: this license is the BSD license.
22343 -
22344 -
22345 -
22346 -----------------------------------------------------------------------
22347 -FOR DEVELOPER
22348 -----------------------------------------------------------------------
22349 -
22350 -If you are planning to implement a datatype library, A sample datatype
22351 -library implementation by James Clark is available at [1], which
22352 -comes with documentation and source code.
22353 -
22354 -If you are planning to implement a schema processor, then don't forget
22355 -to check out org.relaxng.datatype.helpers.DatatypeLibraryLoader, as
22356 -this allows you to dynamically locate datatype implementations.
22357 -
22358 -
22359 -----------------------------------------------------------------------
22360 -LINKS
22361 -----------------------------------------------------------------------
22362 -
22363 -* OASIS RELAX NG TC
22364 - http://www.oasis-open.org/committees/relax-ng/
22365 -* RELAX home page
22366 - http://www.xml.gr.jp/relax/
22367 -
22368 -
22369 -----------------------------------------------------------------------
22370 -REFERENCES
22371 -----------------------------------------------------------------------
22372 -[1] Sample datatype library implementation by James Clark
22373 - http://www.thaiopensource.com/relaxng/datatype-sample.zip
22374 -
22375 -Document written by Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
22376 -======================================================================
22377 -END OF README
22378 +======================================================================
22379 + README FILE FOR DATATYPE INTERFACES FOR RELAX NG
22380 +======================================================================
22381 +
22382 +
22383 +
22384 +RELAX NG supports multiple datatype vocabularies. To achive this, an
22385 +interface between datatype vocabularies and schema processors is
22386 +necessary. This interface is intended to be a standard Java interface
22387 +for this purpose.
22388 +
22389 +
22390 +----------------------------------------------------------------------
22391 +LICENSE
22392 +----------------------------------------------------------------------
22393 +
22394 +See copying.txt.
22395 +
22396 +Note: this license is the BSD license.
22397 +
22398 +
22399 +
22400 +----------------------------------------------------------------------
22401 +FOR DEVELOPER
22402 +----------------------------------------------------------------------
22403 +
22404 +If you are planning to implement a datatype library, A sample datatype
22405 +library implementation by James Clark is available at [1], which
22406 +comes with documentation and source code.
22407 +
22408 +If you are planning to implement a schema processor, then don't forget
22409 +to check out org.relaxng.datatype.helpers.DatatypeLibraryLoader, as
22410 +this allows you to dynamically locate datatype implementations.
22411 +
22412 +
22413 +----------------------------------------------------------------------
22414 +LINKS
22415 +----------------------------------------------------------------------
22416 +
22417 +* OASIS RELAX NG TC
22418 + http://www.oasis-open.org/committees/relax-ng/
22419 +* RELAX home page
22420 + http://www.xml.gr.jp/relax/
22421 +
22422 +
22423 +----------------------------------------------------------------------
22424 +REFERENCES
22425 +----------------------------------------------------------------------
22426 +[1] Sample datatype library implementation by James Clark
22427 + http://www.thaiopensource.com/relaxng/datatype-sample.zip
22428 +
22429 +Document written by Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
22430 +======================================================================
22431 +END OF README
22432 diff -Nrup gcc-4.2.1/libstdc++-v3/config/os/gnu-linux/ctype_base.h gcc-4.2.1.atmel.1.3.2/libstdc++-v3/config/os/gnu-linux/ctype_base.h
22433 --- gcc-4.2.1/libstdc++-v3/config/os/gnu-linux/ctype_base.h 2006-12-01 13:56:23.000000000 +0100
22434 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/config/os/gnu-linux/ctype_base.h 2007-09-28 10:33:32.000000000 +0200
22435 @@ -31,6 +31,8 @@
22436 //
22437 // ISO C++ 14882: 22.1 Locales
22438 //
22439 +#include <features.h>
22440 +#include <ctype.h>
22441
22442 /** @file ctype_base.h
22443 * This is an internal header file, included by other library headers.
22444 @@ -45,8 +47,12 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
22445 struct ctype_base
22446 {
22447 // Non-standard typedefs.
22448 - typedef const int* __to_type;
22449 -
22450 +#ifdef __UCLIBC__
22451 + typedef const __ctype_touplow_t* __to_type;
22452 +#else
22453 + typedef const int* __to_type;
22454 +#endif
22455 +
22456 // NB: Offsets into ctype<char>::_M_table force a particular size
22457 // on the mask type. Because of this, we don't use an enum.
22458 typedef unsigned short mask;
22459 diff -Nrup gcc-4.2.1/libstdc++-v3/include/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/include/Makefile.in
22460 --- gcc-4.2.1/libstdc++-v3/include/Makefile.in 2007-07-05 13:46:00.000000000 +0200
22461 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/include/Makefile.in 2007-09-28 10:33:21.000000000 +0200
22462 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22463 build_triplet = @build@
22464 host_triplet = @host@
22465 target_triplet = @target@
22466 +LIBOBJDIR =
22467 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22468 $(top_srcdir)/fragment.am
22469 subdir = include
22470 diff -Nrup gcc-4.2.1/libstdc++-v3/libmath/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/libmath/Makefile.in
22471 --- gcc-4.2.1/libstdc++-v3/libmath/Makefile.in 2006-10-16 21:08:22.000000000 +0200
22472 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/libmath/Makefile.in 2007-09-28 10:33:16.000000000 +0200
22473 @@ -37,6 +37,7 @@ POST_UNINSTALL = :
22474 build_triplet = @build@
22475 host_triplet = @host@
22476 target_triplet = @target@
22477 +LIBOBJDIR =
22478 subdir = libmath
22479 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
22480 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
22481 diff -Nrup gcc-4.2.1/libstdc++-v3/libsupc++/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/libsupc++/Makefile.in
22482 --- gcc-4.2.1/libstdc++-v3/libsupc++/Makefile.in 2006-10-16 21:08:22.000000000 +0200
22483 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/libsupc++/Makefile.in 2007-09-28 10:33:21.000000000 +0200
22484 @@ -38,6 +38,7 @@ POST_UNINSTALL = :
22485 build_triplet = @build@
22486 host_triplet = @host@
22487 target_triplet = @target@
22488 +LIBOBJDIR =
22489 DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \
22490 $(srcdir)/Makefile.in $(top_srcdir)/fragment.am
22491 subdir = libsupc++
22492 diff -Nrup gcc-4.2.1/libstdc++-v3/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/Makefile.in
22493 --- gcc-4.2.1/libstdc++-v3/Makefile.in 2006-10-16 21:08:22.000000000 +0200
22494 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/Makefile.in 2007-09-28 10:33:34.000000000 +0200
22495 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22496 build_triplet = @build@
22497 host_triplet = @host@
22498 target_triplet = @target@
22499 +LIBOBJDIR =
22500 DIST_COMMON = README $(am__configure_deps) $(srcdir)/../config.guess \
22501 $(srcdir)/../config.sub $(srcdir)/../install-sh \
22502 $(srcdir)/../ltmain.sh $(srcdir)/../missing \
22503 diff -Nrup gcc-4.2.1/libstdc++-v3/po/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/po/Makefile.in
22504 --- gcc-4.2.1/libstdc++-v3/po/Makefile.in 2006-10-16 21:08:22.000000000 +0200
22505 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/po/Makefile.in 2007-09-28 10:33:34.000000000 +0200
22506 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22507 build_triplet = @build@
22508 host_triplet = @host@
22509 target_triplet = @target@
22510 +LIBOBJDIR =
22511 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22512 $(top_srcdir)/fragment.am
22513 subdir = po
22514 diff -Nrup gcc-4.2.1/libstdc++-v3/src/Makefile.in gcc-4.2.1.atmel.1.3.2/libstdc++-v3/src/Makefile.in
22515 --- gcc-4.2.1/libstdc++-v3/src/Makefile.in 2006-10-16 21:08:22.000000000 +0200
22516 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/src/Makefile.in 2007-09-28 10:33:21.000000000 +0200
22517 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22518 build_triplet = @build@
22519 host_triplet = @host@
22520 target_triplet = @target@
22521 +LIBOBJDIR =
22522 DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22523 $(top_srcdir)/fragment.am
22524 subdir = src
22525 diff -Nrup gcc-4.2.1/libstdc++-v3/acinclude.m4 gcc-4.2.1.atmel.1.3.2/libstdc++-v3/acinclude.m4
22526 --- gcc-4.2.1/libstdc++-v3/acinclude.m4 2007-06-29 01:02:05.000000000 +0200
22527 +++ gcc-4.2.1.atmel.1.3.2/libstdc++-v3/acinclude.m4 2007-09-28 10:33:34.000000000 +0200
22528 @@ -1389,8 +1380,8 @@ AC_DEFUN([GLIBCXX_ENABLE_CLOCALE], [
22529 #endif
22530 int main()
22531 {
22532 - const char __one[] = "Äuglein Augmen";
22533 - const char __two[] = "Äuglein";
22534 + const char __one[] = "Äuglein Augmen";
22535 + const char __two[] = "Äuglein";
22536 int i;
22537 int j;
22538 __locale_t loc;
This page took 1.027146 seconds and 3 git commands to generate.