avr32: remove target
[openwrt.git] / toolchain / gcc / patches / 4.4.7 / 930-avr32_support.patch
1 --- a/gcc/builtins.c
2 +++ b/gcc/builtins.c
3 @@ -11108,7 +11108,7 @@ validate_gimple_arglist (const_gimple ca
4  
5    do
6      {
7 -      code = va_arg (ap, enum tree_code);
8 +      code = va_arg (ap, int);
9        switch (code)
10         {
11         case 0:
12 --- a/gcc/calls.c
13 +++ b/gcc/calls.c
14 @@ -3447,7 +3447,7 @@ emit_library_call_value_1 (int retval, r
15    for (; count < nargs; count++)
16      {
17        rtx val = va_arg (p, rtx);
18 -      enum machine_mode mode = va_arg (p, enum machine_mode);
19 +      enum machine_mode mode = va_arg (p, int);
20  
21        /* We cannot convert the arg value to the mode the library wants here;
22          must do it earlier where we know the signedness of the arg.  */
23 --- /dev/null
24 +++ b/gcc/config/avr32/avr32.c
25 @@ -0,0 +1,8060 @@
26 +/*
27 +   Target hooks and helper functions for AVR32.
28 +   Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation.
29 +
30 +   This file is part of GCC.
31 +
32 +   This program is free software; you can redistribute it and/or modify
33 +   it under the terms of the GNU General Public License as published by
34 +   the Free Software Foundation; either version 2 of the License, or
35 +   (at your option) any later version.
36 +
37 +   This program is distributed in the hope that it will be useful,
38 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
39 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40 +   GNU General Public License for more details.
41 +
42 +   You should have received a copy of the GNU General Public License
43 +   along with this program; if not, write to the Free Software
44 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
45 +
46 +#include "config.h"
47 +#include "system.h"
48 +#include "coretypes.h"
49 +#include "tm.h"
50 +#include "rtl.h"
51 +#include "tree.h"
52 +#include "obstack.h"
53 +#include "regs.h"
54 +#include "hard-reg-set.h"
55 +#include "real.h"
56 +#include "insn-config.h"
57 +#include "conditions.h"
58 +#include "output.h"
59 +#include "insn-attr.h"
60 +#include "flags.h"
61 +#include "reload.h"
62 +#include "function.h"
63 +#include "expr.h"
64 +#include "optabs.h"
65 +#include "toplev.h"
66 +#include "recog.h"
67 +#include "ggc.h"
68 +#include "except.h"
69 +#include "c-pragma.h"
70 +#include "integrate.h"
71 +#include "tm_p.h"
72 +#include "langhooks.h"
73 +#include "hooks.h"
74 +#include "df.h"
75 +
76 +#include "target.h"
77 +#include "target-def.h"
78 +
79 +#include <ctype.h>
80 +
81 +
82 +
83 +/* Global variables.  */
84 +typedef struct minipool_node Mnode;
85 +typedef struct minipool_fixup Mfix;
86 +
87 +/* Obstack for minipool constant handling.  */
88 +static struct obstack minipool_obstack;
89 +static char *minipool_startobj;
90 +static rtx minipool_vector_label;
91 +
92 +/* True if we are currently building a constant table.  */
93 +int making_const_table;
94 +
95 +tree fndecl_attribute_args = NULL_TREE;
96 +
97 +
98 +/* Function prototypes. */
99 +static unsigned long avr32_isr_value (tree);
100 +static unsigned long avr32_compute_func_type (void);
101 +static tree avr32_handle_isr_attribute (tree *, tree, tree, int, bool *);
102 +static tree avr32_handle_acall_attribute (tree *, tree, tree, int, bool *);
103 +static tree avr32_handle_fndecl_attribute (tree * node, tree name, tree args,
104 +                                          int flags, bool * no_add_attrs);
105 +static void avr32_reorg (void);
106 +bool avr32_return_in_msb (tree type);
107 +bool avr32_vector_mode_supported (enum machine_mode mode);
108 +static void avr32_init_libfuncs (void);
109 +static void avr32_file_end (void);
110 +static void flashvault_decl_list_add (unsigned int vector_num, const char *name);
111 +
112 +
113 +
114 +static void
115 +avr32_add_gc_roots (void)
116 +{
117 +  gcc_obstack_init (&minipool_obstack);
118 +  minipool_startobj = (char *) obstack_alloc (&minipool_obstack, 0);
119 +}
120 +
121 +
122 +/* List of all known AVR32 parts  */
123 +static const struct part_type_s avr32_part_types[] = {
124 +  /* name, part_type, architecture type, macro */
125 +  {"none",            PART_TYPE_AVR32_NONE,            ARCH_TYPE_AVR32_AP,        "__AVR32__"},
126 +  {"ap7000",          PART_TYPE_AVR32_AP7000,          ARCH_TYPE_AVR32_AP,        "__AVR32_AP7000__"},
127 +  {"ap7001",          PART_TYPE_AVR32_AP7001,          ARCH_TYPE_AVR32_AP,        "__AVR32_AP7001__"},
128 +  {"ap7002",          PART_TYPE_AVR32_AP7002,          ARCH_TYPE_AVR32_AP,        "__AVR32_AP7002__"},
129 +  {"ap7200",          PART_TYPE_AVR32_AP7200,          ARCH_TYPE_AVR32_AP,        "__AVR32_AP7200__"},
130 +  {"uc3a0128",        PART_TYPE_AVR32_UC3A0128,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A0128__"},
131 +  {"uc3a0256",        PART_TYPE_AVR32_UC3A0256,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A0256__"},
132 +  {"uc3a0512",        PART_TYPE_AVR32_UC3A0512,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A0512__"},
133 +  {"uc3a0512es",      PART_TYPE_AVR32_UC3A0512ES,      ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3A0512ES__"},
134 +  {"uc3a1128",        PART_TYPE_AVR32_UC3A1128,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A1128__"},
135 +  {"uc3a1256",        PART_TYPE_AVR32_UC3A1256,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A1256__"},
136 +  {"uc3a1512",        PART_TYPE_AVR32_UC3A1512,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A1512__"},
137 +  {"uc3a1512es",      PART_TYPE_AVR32_UC3A1512ES,      ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3A1512ES__"},
138 +  {"uc3a3revd",       PART_TYPE_AVR32_UC3A3REVD,       ARCH_TYPE_AVR32_UCR2NOMUL, "__AVR32_UC3A3256S__"},
139 +  {"uc3a364",         PART_TYPE_AVR32_UC3A364,         ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A364__"},
140 +  {"uc3a364s",        PART_TYPE_AVR32_UC3A364S,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A364S__"},
141 +  {"uc3a3128",        PART_TYPE_AVR32_UC3A3128,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A3128__"},
142 +  {"uc3a3128s",       PART_TYPE_AVR32_UC3A3128S,       ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A3128S__"},
143 +  {"uc3a3256",        PART_TYPE_AVR32_UC3A3256,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A3256__"},
144 +  {"uc3a3256s",       PART_TYPE_AVR32_UC3A3256S,       ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A3256S__"},
145 +  {"uc3a464",         PART_TYPE_AVR32_UC3A464,         ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A464__"},
146 +  {"uc3a464s",        PART_TYPE_AVR32_UC3A464S,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A464S__"},
147 +  {"uc3a4128",        PART_TYPE_AVR32_UC3A4128,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A4128__"},
148 +  {"uc3a4128s",       PART_TYPE_AVR32_UC3A4128S,       ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A4128S__"},
149 +  {"uc3a4256",        PART_TYPE_AVR32_UC3A4256,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A4256__"},
150 +  {"uc3a4256s",       PART_TYPE_AVR32_UC3A4256S,       ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3A4256S__"},
151 +  {"uc3b064",         PART_TYPE_AVR32_UC3B064,         ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B064__"},
152 +  {"uc3b0128",        PART_TYPE_AVR32_UC3B0128,        ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B0128__"},
153 +  {"uc3b0256",        PART_TYPE_AVR32_UC3B0256,        ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B0256__"},
154 +  {"uc3b0256es",      PART_TYPE_AVR32_UC3B0256ES,      ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B0256ES__"},
155 +  {"uc3b0512",        PART_TYPE_AVR32_UC3B0512,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3B0512__"},
156 +  {"uc3b0512revc",    PART_TYPE_AVR32_UC3B0512REVC,    ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3B0512REVC__"},
157 +  {"uc3b164",         PART_TYPE_AVR32_UC3B164,         ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B164__"},
158 +  {"uc3b1128",        PART_TYPE_AVR32_UC3B1128,        ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B1128__"},
159 +  {"uc3b1256",        PART_TYPE_AVR32_UC3B1256,        ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B1256__"},
160 +  {"uc3b1256es",      PART_TYPE_AVR32_UC3B1256ES,      ARCH_TYPE_AVR32_UCR1,      "__AVR32_UC3B1256ES__"},
161 +  {"uc3b1512",        PART_TYPE_AVR32_UC3B1512,        ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3B1512__"},
162 +  {"uc3b1512revc",    PART_TYPE_AVR32_UC3B1512REVC,    ARCH_TYPE_AVR32_UCR2,      "__AVR32_UC3B1512REVC__"},
163 +  {"uc64d3",          PART_TYPE_AVR32_UC64D3,          ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC64D3__"},
164 +  {"uc128d3",         PART_TYPE_AVR32_UC128D3,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC128D3__"},
165 +  {"uc64d4",          PART_TYPE_AVR32_UC64D4,          ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC64D4__"},
166 +  {"uc128d4",         PART_TYPE_AVR32_UC128D4,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC128D4__"},
167 +  {"uc3c0512crevc",   PART_TYPE_AVR32_UC3C0512CREVC,   ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3C0512CREVC__"},
168 +  {"uc3c1512crevc",   PART_TYPE_AVR32_UC3C1512CREVC,   ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3C1512CREVC__"},
169 +  {"uc3c2512crevc",   PART_TYPE_AVR32_UC3C2512CREVC,   ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3C2512CREVC__"},
170 +  {"uc3l0256",        PART_TYPE_AVR32_UC3L0256,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L0256__"},
171 +  {"uc3l0128",        PART_TYPE_AVR32_UC3L0128,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L0128__"},
172 +  {"uc3l064",         PART_TYPE_AVR32_UC3L064,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L064__"},
173 +  {"uc3l032",         PART_TYPE_AVR32_UC3L032,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L032__"},
174 +  {"uc3l016",         PART_TYPE_AVR32_UC3L016,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L016__"},
175 +  {"uc3l064revb",     PART_TYPE_AVR32_UC3L064REVB,     ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC3L064REVB__"},
176 +  {"uc64l3u",         PART_TYPE_AVR32_UC64L3U,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC64L3U__"},
177 +  {"uc128l3u",        PART_TYPE_AVR32_UC128L3U,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC128L3U__"},
178 +  {"uc256l3u",        PART_TYPE_AVR32_UC256L3U,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC256L3U__"},
179 +  {"uc64l4u",         PART_TYPE_AVR32_UC64L4U,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC64L4U__"},
180 +  {"uc128l4u",        PART_TYPE_AVR32_UC128L4U,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC128L4U__"},
181 +  {"uc256l4u",        PART_TYPE_AVR32_UC256L4U,        ARCH_TYPE_AVR32_UCR3,      "__AVR32_UC256L4U__"},
182 +  {"uc3c064c",        PART_TYPE_AVR32_UC3C064C,        ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C064C__"},
183 +  {"uc3c0128c",       PART_TYPE_AVR32_UC3C0128C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C0128C__"},
184 +  {"uc3c0256c",       PART_TYPE_AVR32_UC3C0256C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C0256C__"},
185 +  {"uc3c0512c",       PART_TYPE_AVR32_UC3C0512C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C0512C__"},
186 +  {"uc3c164c",        PART_TYPE_AVR32_UC3C164C,        ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C164C__"},
187 +  {"uc3c1128c",       PART_TYPE_AVR32_UC3C1128C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C1128C__"},
188 +  {"uc3c1256c",       PART_TYPE_AVR32_UC3C1256C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C1256C__"},
189 +  {"uc3c1512c",       PART_TYPE_AVR32_UC3C1512C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C1512C__"},
190 +  {"uc3c264c",        PART_TYPE_AVR32_UC3C264C,        ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C264C__"},
191 +  {"uc3c2128c",       PART_TYPE_AVR32_UC3C2128C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C2128C__"},
192 +  {"uc3c2256c",       PART_TYPE_AVR32_UC3C2256C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C2256C__"},
193 +  {"uc3c2512c",       PART_TYPE_AVR32_UC3C2512C,       ARCH_TYPE_AVR32_UCR3FP,    "__AVR32_UC3C2512C__"},
194 +  {"mxt768e",         PART_TYPE_AVR32_MXT768E,         ARCH_TYPE_AVR32_UCR3,      "__AVR32_MXT768E__"},
195 +  {NULL, 0, 0, NULL}
196 +};
197 +
198 +/* List of all known AVR32 architectures  */
199 +static const struct arch_type_s avr32_arch_types[] = {
200 +  /* name, architecture type, microarchitecture type, feature flags, macro */
201 +  {"ap", ARCH_TYPE_AVR32_AP, UARCH_TYPE_AVR32B,
202 +   (FLAG_AVR32_HAS_DSP
203 +    | FLAG_AVR32_HAS_SIMD
204 +    | FLAG_AVR32_HAS_UNALIGNED_WORD
205 +    | FLAG_AVR32_HAS_BRANCH_PRED | FLAG_AVR32_HAS_RETURN_STACK
206 +    | FLAG_AVR32_HAS_CACHES),
207 +   "__AVR32_AP__"},
208 +  {"ucr1", ARCH_TYPE_AVR32_UCR1, UARCH_TYPE_AVR32A,
209 +   (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW),
210 +   "__AVR32_UC__=1"},
211 +  {"ucr2", ARCH_TYPE_AVR32_UCR2, UARCH_TYPE_AVR32A,
212 +   (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW
213 +    | FLAG_AVR32_HAS_V2_INSNS),
214 +   "__AVR32_UC__=2"},
215 +  {"ucr2nomul", ARCH_TYPE_AVR32_UCR2NOMUL, UARCH_TYPE_AVR32A,
216 +   (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW
217 +    | FLAG_AVR32_HAS_V2_INSNS | FLAG_AVR32_HAS_NO_MUL_INSNS),
218 +   "__AVR32_UC__=2"},
219 +  {"ucr3", ARCH_TYPE_AVR32_UCR3, UARCH_TYPE_AVR32A,
220 +   (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW
221 +    | FLAG_AVR32_HAS_V2_INSNS),
222 +   "__AVR32_UC__=3"},
223 +  {"ucr3fp", ARCH_TYPE_AVR32_UCR3FP, UARCH_TYPE_AVR32A,
224 +   (FLAG_AVR32_HAS_DSP | FLAG_AVR32_HAS_RMW | FLAG_AVR32_HAS_FPU
225 +    | FLAG_AVR32_HAS_V2_INSNS),
226 +   "__AVR32_UC__=3"},
227 +  {NULL, 0, 0, 0, NULL}
228 +};
229 +
230 +/* Default arch name */
231 +const char *avr32_arch_name = "none";
232 +const char *avr32_part_name = "none";
233 +
234 +const struct part_type_s *avr32_part;
235 +const struct arch_type_s *avr32_arch;
236 +
237 +
238 +/* FIXME: needs to use GC.  */
239 +struct flashvault_decl_list
240 +{
241 +  struct flashvault_decl_list *next;
242 +  unsigned int vector_num;
243 +  const char *name;
244 +};
245 +
246 +static struct flashvault_decl_list *flashvault_decl_list_head = NULL;
247 +
248 +
249 +/* Set default target_flags. */
250 +#undef TARGET_DEFAULT_TARGET_FLAGS
251 +#define TARGET_DEFAULT_TARGET_FLAGS \
252 +  (MASK_HAS_ASM_ADDR_PSEUDOS | MASK_MD_REORG_OPTIMIZATION | MASK_COND_EXEC_BEFORE_RELOAD)
253 +
254 +void
255 +avr32_optimization_options (int level, int size)
256 +{
257 +  if (AVR32_ALWAYS_PIC)
258 +    flag_pic = 1;
259 +
260 +  /* Enable section anchors if optimization is enabled. */
261 +  if (level > 0 || size)
262 +    flag_section_anchors = 2;
263 +}
264 +
265 +
266 +/* Override command line options */
267 +void
268 +avr32_override_options (void)
269 +{
270 +  const struct part_type_s *part;
271 +  const struct arch_type_s *arch;
272 +
273 +  /*Add backward compability*/
274 +  if (strcmp ("uc", avr32_arch_name)== 0)
275 +    {
276 +      fprintf (stderr, "Warning: Deprecated arch `%s' specified. "
277 +                       "Please use '-march=ucr1' instead. "
278 +                       "Converting to arch 'ucr1'\n",
279 +               avr32_arch_name);
280 +      avr32_arch_name="ucr1";
281 +    }
282 +
283 +  /* Check if arch type is set. */
284 +  for (arch = avr32_arch_types; arch->name; arch++)
285 +    {
286 +      if (strcmp (arch->name, avr32_arch_name) == 0)
287 +        break;
288 +    }
289 +  avr32_arch = arch;
290 +
291 +  if (!arch->name && strcmp("none", avr32_arch_name) != 0)
292 +    {
293 +      fprintf (stderr, "Unknown arch `%s' specified\n"
294 +                       "Known arch names:\n"
295 +                       "\tuc (deprecated)\n",
296 +               avr32_arch_name);
297 +      for (arch = avr32_arch_types; arch->name; arch++)
298 +        fprintf (stderr, "\t%s\n", arch->name);
299 +      avr32_arch = &avr32_arch_types[ARCH_TYPE_AVR32_AP];
300 +    }
301 +
302 +  /* Check if part type is set. */
303 +  for (part = avr32_part_types; part->name; part++)
304 +    if (strcmp (part->name, avr32_part_name) == 0)
305 +      break;
306 +
307 +  avr32_part = part;
308 +  if (!part->name)
309 +    {
310 +      fprintf (stderr, "Unknown part `%s' specified\nKnown part names:\n",
311 +               avr32_part_name);
312 +      for (part = avr32_part_types; part->name; part++)
313 +        {
314 +          if (strcmp("none", part->name) != 0)
315 +            fprintf (stderr, "\t%s\n", part->name);
316 +        }
317 +      /* Set default to NONE*/
318 +      avr32_part = &avr32_part_types[PART_TYPE_AVR32_NONE];
319 +    }
320 +
321 +  /* NB! option -march= overrides option -mpart
322 +   * if both are used at the same time */
323 +  if (!arch->name)
324 +    avr32_arch = &avr32_arch_types[avr32_part->arch_type];
325 +
326 +  /* If optimization level is two or greater, then align start of loops to a
327 +     word boundary since this will allow folding the first insn of the loop.
328 +     Do this only for targets supporting branch prediction. */
329 +  if (optimize >= 2 && TARGET_BRANCH_PRED)
330 +    align_loops = 2;
331 +
332 +
333 +  /* Enable fast-float library if unsafe math optimizations
334 +     are used. */
335 +  if (flag_unsafe_math_optimizations)
336 +    target_flags |= MASK_FAST_FLOAT;
337 +
338 +  /* Check if we should set avr32_imm_in_const_pool
339 +     based on if caches are present or not. */
340 +  if ( avr32_imm_in_const_pool == -1 )
341 +    {
342 +      if ( TARGET_CACHES )
343 +        avr32_imm_in_const_pool = 1;
344 +      else
345 +        avr32_imm_in_const_pool = 0;
346 +    }
347 +
348 +  if (TARGET_NO_PIC)
349 +    flag_pic = 0;
350 +  avr32_add_gc_roots ();
351 +}
352 +
353 +
354 +/*
355 +If defined, a function that outputs the assembler code for entry to a
356 +function.  The prologue is responsible for setting up the stack frame,
357 +initializing the frame pointer register, saving registers that must be
358 +saved, and allocating size additional bytes of storage for the
359 +local variables.  size is an integer.  file is a stdio
360 +stream to which the assembler code should be output.
361 +
362 +The label for the beginning of the function need not be output by this
363 +macro.  That has already been done when the macro is run.
364 +
365 +To determine which registers to save, the macro can refer to the array
366 +regs_ever_live: element r is nonzero if hard register
367 +r is used anywhere within the function.  This implies the function
368 +prologue should save register r, provided it is not one of the
369 +call-used registers.  (TARGET_ASM_FUNCTION_EPILOGUE must likewise use
370 +regs_ever_live.)
371 +
372 +On machines that have ``register windows'', the function entry code does
373 +not save on the stack the registers that are in the windows, even if
374 +they are supposed to be preserved by function calls; instead it takes
375 +appropriate steps to ``push'' the register stack, if any non-call-used
376 +registers are used in the function.
377 +
378 +On machines where functions may or may not have frame-pointers, the
379 +function entry code must vary accordingly; it must set up the frame
380 +pointer if one is wanted, and not otherwise.  To determine whether a
381 +frame pointer is in wanted, the macro can refer to the variable
382 +frame_pointer_needed.  The variable's value will be 1 at run
383 +time in a function that needs a frame pointer.  (see Elimination).
384 +
385 +The function entry code is responsible for allocating any stack space
386 +required for the function.  This stack space consists of the regions
387 +listed below.  In most cases, these regions are allocated in the
388 +order listed, with the last listed region closest to the top of the
389 +stack (the lowest address if STACK_GROWS_DOWNWARD is defined, and
390 +the highest address if it is not defined).  You can use a different order
391 +for a machine if doing so is more convenient or required for
392 +compatibility reasons.  Except in cases where required by standard
393 +or by a debugger, there is no reason why the stack layout used by GCC
394 +need agree with that used by other compilers for a machine.
395 +*/
396 +
397 +#undef TARGET_ASM_FUNCTION_PROLOGUE
398 +#define TARGET_ASM_FUNCTION_PROLOGUE avr32_target_asm_function_prologue
399 +
400 +#undef TARGET_ASM_FILE_END
401 +#define TARGET_ASM_FILE_END avr32_file_end
402 +
403 +#undef TARGET_DEFAULT_SHORT_ENUMS
404 +#define TARGET_DEFAULT_SHORT_ENUMS hook_bool_void_false
405 +
406 +#undef TARGET_PROMOTE_FUNCTION_ARGS
407 +#define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
408 +
409 +#undef TARGET_PROMOTE_FUNCTION_RETURN
410 +#define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
411 +
412 +#undef TARGET_PROMOTE_PROTOTYPES
413 +#define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
414 +
415 +#undef TARGET_MUST_PASS_IN_STACK
416 +#define TARGET_MUST_PASS_IN_STACK avr32_must_pass_in_stack
417 +
418 +#undef TARGET_PASS_BY_REFERENCE
419 +#define TARGET_PASS_BY_REFERENCE avr32_pass_by_reference
420 +
421 +#undef TARGET_STRICT_ARGUMENT_NAMING
422 +#define TARGET_STRICT_ARGUMENT_NAMING avr32_strict_argument_naming
423 +
424 +#undef TARGET_VECTOR_MODE_SUPPORTED_P
425 +#define TARGET_VECTOR_MODE_SUPPORTED_P avr32_vector_mode_supported
426 +
427 +#undef TARGET_RETURN_IN_MEMORY
428 +#define TARGET_RETURN_IN_MEMORY avr32_return_in_memory
429 +
430 +#undef TARGET_RETURN_IN_MSB
431 +#define TARGET_RETURN_IN_MSB avr32_return_in_msb
432 +
433 +#undef TARGET_ENCODE_SECTION_INFO
434 +#define TARGET_ENCODE_SECTION_INFO avr32_encode_section_info
435 +
436 +#undef TARGET_ARG_PARTIAL_BYTES
437 +#define TARGET_ARG_PARTIAL_BYTES avr32_arg_partial_bytes
438 +
439 +#undef TARGET_STRIP_NAME_ENCODING
440 +#define TARGET_STRIP_NAME_ENCODING avr32_strip_name_encoding
441 +
442 +#define streq(string1, string2) (strcmp (string1, string2) == 0)
443 +
444 +#undef  TARGET_NARROW_VOLATILE_BITFIELD
445 +#define TARGET_NARROW_VOLATILE_BITFIELD hook_bool_void_false
446 +
447 +#undef  TARGET_ATTRIBUTE_TABLE
448 +#define TARGET_ATTRIBUTE_TABLE avr32_attribute_table
449 +
450 +#undef  TARGET_COMP_TYPE_ATTRIBUTES
451 +#define TARGET_COMP_TYPE_ATTRIBUTES avr32_comp_type_attributes
452 +
453 +
454 +#undef  TARGET_RTX_COSTS
455 +#define TARGET_RTX_COSTS avr32_rtx_costs
456 +
457 +#undef  TARGET_CANNOT_FORCE_CONST_MEM
458 +#define  TARGET_CANNOT_FORCE_CONST_MEM avr32_cannot_force_const_mem
459 +
460 +#undef  TARGET_ASM_INTEGER
461 +#define TARGET_ASM_INTEGER avr32_assemble_integer
462 +
463 +#undef  TARGET_FUNCTION_VALUE
464 +#define TARGET_FUNCTION_VALUE avr32_function_value
465 +
466 +#undef  TARGET_MIN_ANCHOR_OFFSET
467 +#define TARGET_MIN_ANCHOR_OFFSET (0)
468 +
469 +#undef  TARGET_MAX_ANCHOR_OFFSET
470 +#define TARGET_MAX_ANCHOR_OFFSET ((1 << 15) - 1)
471 +#undef TARGET_SECONDARY_RELOAD
472 +#define TARGET_SECONDARY_RELOAD avr32_secondary_reload
473 +
474 +
475 +/*
476 + * Defining the option, -mlist-devices to list the devices supported by gcc.
477 + * This option should be used while printing target-help to list all the 
478 + * supported devices.
479 + */
480 +#undef TARGET_HELP
481 +#define TARGET_HELP avr32_target_help
482 +
483 +void avr32_target_help ()
484 +{
485 +  if (avr32_list_supported_parts)
486 +    {
487 +      const struct part_type_s *list;
488 +      fprintf (stdout, "List of parts supported by avr32-gcc:\n");
489 +      for (list = avr32_part_types; list->name; list++)
490 +        {
491 +          if (strcmp("none", list->name) != 0)
492 +            fprintf (stdout, "%-20s%s\n", list->name, list->macro);
493 +        }
494 +      fprintf (stdout, "\n\n");
495 +    }
496 +}
497 +
498 +enum reg_class
499 +avr32_secondary_reload (bool in_p, rtx x, enum reg_class class,
500 +                        enum machine_mode mode, secondary_reload_info *sri)
501 +{
502 +
503 +  if ( avr32_rmw_memory_operand (x, mode) )
504 +    {
505 +      if (!in_p)
506 +        sri->icode = CODE_FOR_reload_out_rmw_memory_operand;
507 +      else
508 +        sri->icode = CODE_FOR_reload_in_rmw_memory_operand;
509 +    }
510 +  return NO_REGS;
511 +
512 +}
513 +/*
514 + * Switches to the appropriate section for output of constant pool
515 + * entry x in mode. You can assume that x is some kind of constant in
516 + * RTL. The argument mode is redundant except in the case of a
517 + * const_int rtx. Select the section by calling readonly_data_ section
518 + * or one of the alternatives for other sections. align is the
519 + * constant alignment in bits.
520 + *
521 + * The default version of this function takes care of putting symbolic
522 + * constants in flag_ pic mode in data_section and everything else in
523 + * readonly_data_section.
524 + */
525 +//#undef TARGET_ASM_SELECT_RTX_SECTION
526 +//#define TARGET_ASM_SELECT_RTX_SECTION avr32_select_rtx_section
527 +
528 +
529 +/*
530 + * If non-null, this hook performs a target-specific pass over the
531 + * instruction stream. The compiler will run it at all optimization
532 + * levels, just before the point at which it normally does
533 + * delayed-branch scheduling.
534 + *
535 + * The exact purpose of the hook varies from target to target. Some
536 + * use it to do transformations that are necessary for correctness,
537 + * such as laying out in-function constant pools or avoiding hardware
538 + * hazards. Others use it as an opportunity to do some
539 + * machine-dependent optimizations.
540 + *
541 + * You need not implement the hook if it has nothing to do. The
542 + * default definition is null.
543 + */
544 +#undef TARGET_MACHINE_DEPENDENT_REORG
545 +#define TARGET_MACHINE_DEPENDENT_REORG avr32_reorg
546 +
547 +/* Target hook for assembling integer objects.
548 +   Need to handle integer vectors */
549 +static bool
550 +avr32_assemble_integer (rtx x, unsigned int size, int aligned_p)
551 +{
552 +  if (avr32_vector_mode_supported (GET_MODE (x)))
553 +    {
554 +      int i, units;
555 +
556 +      if (GET_CODE (x) != CONST_VECTOR)
557 +       abort ();
558 +
559 +      units = CONST_VECTOR_NUNITS (x);
560 +
561 +      switch (GET_MODE (x))
562 +       {
563 +       case V2HImode:
564 +         size = 2;
565 +         break;
566 +       case V4QImode:
567 +         size = 1;
568 +         break;
569 +       default:
570 +         abort ();
571 +       }
572 +
573 +      for (i = 0; i < units; i++)
574 +       {
575 +         rtx elt;
576 +
577 +         elt = CONST_VECTOR_ELT (x, i);
578 +         assemble_integer (elt, size, i == 0 ? 32 : size * BITS_PER_UNIT, 1);
579 +       }
580 +
581 +      return true;
582 +    }
583 +
584 +  return default_assemble_integer (x, size, aligned_p);
585 +}
586 +
587 +
588 +/*
589 + * This target hook describes the relative costs of RTL expressions.
590 + *
591 + * The cost may depend on the precise form of the expression, which is
592 + * available for examination in x, and the rtx code of the expression
593 + * in which it is contained, found in outer_code. code is the
594 + * expression code--redundant, since it can be obtained with GET_CODE
595 + * (x).
596 + *
597 + * In implementing this hook, you can use the construct COSTS_N_INSNS
598 + * (n) to specify a cost equal to n fast instructions.
599 + *
600 + * On entry to the hook, *total contains a default estimate for the
601 + * cost of the expression. The hook should modify this value as
602 + * necessary. Traditionally, the default costs are COSTS_N_INSNS (5)
603 + * for multiplications, COSTS_N_INSNS (7) for division and modulus
604 + * operations, and COSTS_N_INSNS (1) for all other operations.
605 + *
606 + * When optimizing for code size, i.e. when optimize_size is non-zero,
607 + * this target hook should be used to estimate the relative size cost
608 + * of an expression, again relative to COSTS_N_INSNS.
609 + *
610 + * The hook returns true when all subexpressions of x have been
611 + * processed, and false when rtx_cost should recurse.
612 + */
613 +
614 +/* Worker routine for avr32_rtx_costs.  */
615 +static inline int
616 +avr32_rtx_costs_1 (rtx x, enum rtx_code code ATTRIBUTE_UNUSED,
617 +                  enum rtx_code outer ATTRIBUTE_UNUSED)
618 +{
619 +  enum machine_mode mode = GET_MODE (x);
620 +
621 +  switch (GET_CODE (x))
622 +    {
623 +    case MEM:
624 +      /* Using pre decrement / post increment memory operations on the
625 +         avr32_uc architecture means that two writebacks must be performed
626 +         and hence two cycles are needed. */
627 +      if (!optimize_size
628 +         && GET_MODE_SIZE (mode) <= 2 * UNITS_PER_WORD
629 +         && TARGET_ARCH_UC
630 +         && (GET_CODE (XEXP (x, 0)) == PRE_DEC
631 +             || GET_CODE (XEXP (x, 0)) == POST_INC))
632 +       return COSTS_N_INSNS (5);
633 +
634 +      /* Memory costs quite a lot for the first word, but subsequent words
635 +         load at the equivalent of a single insn each.  */
636 +      if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
637 +       return COSTS_N_INSNS (3 + (GET_MODE_SIZE (mode) / UNITS_PER_WORD));
638 +
639 +      return COSTS_N_INSNS (4);
640 +    case SYMBOL_REF:
641 +    case CONST:
642 +      /* These are valid for the pseudo insns: lda.w and call which operates
643 +         on direct addresses. We assume that the cost of a lda.w is the same
644 +         as the cost of a ld.w insn. */
645 +      return (outer == SET) ? COSTS_N_INSNS (4) : COSTS_N_INSNS (1);
646 +    case DIV:
647 +    case MOD:
648 +    case UDIV:
649 +    case UMOD:
650 +      return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16);
651 +
652 +    case ROTATE:
653 +    case ROTATERT:
654 +      if (mode == TImode)
655 +       return COSTS_N_INSNS (100);
656 +
657 +      if (mode == DImode)
658 +       return COSTS_N_INSNS (10);
659 +      return COSTS_N_INSNS (4);
660 +    case ASHIFT:
661 +    case LSHIFTRT:
662 +    case ASHIFTRT:
663 +    case NOT:
664 +      if (mode == TImode)
665 +       return COSTS_N_INSNS (10);
666 +
667 +      if (mode == DImode)
668 +       return COSTS_N_INSNS (4);
669 +      return COSTS_N_INSNS (1);
670 +    case PLUS:
671 +    case MINUS:
672 +    case NEG:
673 +    case COMPARE:
674 +    case ABS:
675 +      if (GET_MODE_CLASS (mode) == MODE_FLOAT)
676 +       return COSTS_N_INSNS (100);
677 +
678 +      if (mode == TImode)
679 +       return COSTS_N_INSNS (50);
680 +
681 +      if (mode == DImode)
682 +       return COSTS_N_INSNS (2);
683 +      return COSTS_N_INSNS (1);
684 +
685 +    case MULT:
686 +      {
687 +       if (GET_MODE_CLASS (mode) == MODE_FLOAT)
688 +         return COSTS_N_INSNS (300);
689 +
690 +       if (mode == TImode)
691 +         return COSTS_N_INSNS (16);
692 +
693 +       if (mode == DImode)
694 +         return COSTS_N_INSNS (4);
695 +
696 +       if (mode == HImode)
697 +         return COSTS_N_INSNS (2);
698 +
699 +       return COSTS_N_INSNS (3);
700 +      }
701 +    case IF_THEN_ELSE:
702 +      if (GET_CODE (XEXP (x, 1)) == PC || GET_CODE (XEXP (x, 2)) == PC)
703 +       return COSTS_N_INSNS (4);
704 +      return COSTS_N_INSNS (1);
705 +    case SIGN_EXTEND:
706 +    case ZERO_EXTEND:
707 +      /* Sign/Zero extensions of registers cost quite much since these
708 +         instrcutions only take one register operand which means that gcc
709 +         often must insert some move instrcutions */
710 +      if (mode == QImode || mode == HImode)
711 +       return (COSTS_N_INSNS (GET_CODE (XEXP (x, 0)) == MEM ? 0 : 1));
712 +      return COSTS_N_INSNS (4);
713 +    case UNSPEC:
714 +      /* divmod operations */
715 +      if (XINT (x, 1) == UNSPEC_UDIVMODSI4_INTERNAL
716 +         || XINT (x, 1) == UNSPEC_DIVMODSI4_INTERNAL)
717 +       {
718 +         return optimize_size ? COSTS_N_INSNS (1) : COSTS_N_INSNS (16);
719 +       }
720 +      /* Fallthrough */
721 +    default:
722 +      return COSTS_N_INSNS (1);
723 +    }
724 +}
725 +
726 +
727 +static bool
728 +avr32_rtx_costs (rtx x, int code, int outer_code, int *total)
729 +{
730 +  *total = avr32_rtx_costs_1 (x, code, outer_code);
731 +  return true;
732 +}
733 +
734 +
735 +bool
736 +avr32_cannot_force_const_mem (rtx x ATTRIBUTE_UNUSED)
737 +{
738 +  /* Do not want symbols in the constant pool when compiling pic or if using
739 +     address pseudo instructions. */
740 +  return ((flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS)
741 +         && avr32_find_symbol (x) != NULL_RTX);
742 +}
743 +
744 +
745 +/* Table of machine attributes.  */
746 +const struct attribute_spec avr32_attribute_table[] = {
747 +  /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
748 +  /* Interrupt Service Routines have special prologue and epilogue
749 +     requirements.  */
750 +  {"isr", 0, 1, false, false, false, avr32_handle_isr_attribute},
751 +  {"interrupt", 0, 1, false, false, false, avr32_handle_isr_attribute},
752 +  {"acall", 0, 1, false, true, true, avr32_handle_acall_attribute},
753 +  {"naked", 0, 0, true, false, false, avr32_handle_fndecl_attribute},
754 +  {"rmw_addressable", 0, 0, true, false, false, NULL},
755 +  {"flashvault", 0, 1, true, false, false, avr32_handle_fndecl_attribute},
756 +  {"flashvault_impl", 0, 1, true, false, false, avr32_handle_fndecl_attribute},
757 +  {NULL, 0, 0, false, false, false, NULL}
758 +};
759 +
760 +
761 +typedef struct
762 +{
763 +  const char *const arg;
764 +  const unsigned long return_value;
765 +}
766 +isr_attribute_arg;
767 +
768 +
769 +static const isr_attribute_arg isr_attribute_args[] = {
770 +  {"FULL", AVR32_FT_ISR_FULL},
771 +  {"full", AVR32_FT_ISR_FULL},
772 +  {"HALF", AVR32_FT_ISR_HALF},
773 +  {"half", AVR32_FT_ISR_HALF},
774 +  {"NONE", AVR32_FT_ISR_NONE},
775 +  {"none", AVR32_FT_ISR_NONE},
776 +  {"UNDEF", AVR32_FT_ISR_NONE},
777 +  {"undef", AVR32_FT_ISR_NONE},
778 +  {"SWI", AVR32_FT_ISR_NONE},
779 +  {"swi", AVR32_FT_ISR_NONE},
780 +  {NULL, AVR32_FT_ISR_NONE}
781 +};
782 +
783 +
784 +/* Returns the (interrupt) function type of the current
785 +   function, or AVR32_FT_UNKNOWN if the type cannot be determined.  */
786 +static unsigned long
787 +avr32_isr_value (tree argument)
788 +{
789 +  const isr_attribute_arg *ptr;
790 +  const char *arg;
791 +
792 +  /* No argument - default to ISR_NONE.  */
793 +  if (argument == NULL_TREE)
794 +    return AVR32_FT_ISR_NONE;
795 +
796 +  /* Get the value of the argument.  */
797 +  if (TREE_VALUE (argument) == NULL_TREE
798 +      || TREE_CODE (TREE_VALUE (argument)) != STRING_CST)
799 +    return AVR32_FT_UNKNOWN;
800 +
801 +  arg = TREE_STRING_POINTER (TREE_VALUE (argument));
802 +
803 +  /* Check it against the list of known arguments.  */
804 +  for (ptr = isr_attribute_args; ptr->arg != NULL; ptr++)
805 +    if (streq (arg, ptr->arg))
806 +      return ptr->return_value;
807 +
808 +  /* An unrecognized interrupt type.  */
809 +  return AVR32_FT_UNKNOWN;
810 +}
811 +
812 +
813 +/*
814 +These hooks specify assembly directives for creating certain kinds
815 +of integer object.  The TARGET_ASM_BYTE_OP directive creates a
816 +byte-sized object, the TARGET_ASM_ALIGNED_HI_OP one creates an
817 +aligned two-byte object, and so on.  Any of the hooks may be
818 +NULL, indicating that no suitable directive is available.
819 +
820 +The compiler will print these strings at the start of a new line,
821 +followed immediately by the object's initial value.  In most cases,
822 +the string should contain a tab, a pseudo-op, and then another tab.
823 +*/
824 +#undef  TARGET_ASM_BYTE_OP
825 +#define TARGET_ASM_BYTE_OP "\t.byte\t"
826 +#undef  TARGET_ASM_ALIGNED_HI_OP
827 +#define TARGET_ASM_ALIGNED_HI_OP "\t.align 1\n\t.short\t"
828 +#undef  TARGET_ASM_ALIGNED_SI_OP
829 +#define TARGET_ASM_ALIGNED_SI_OP "\t.align 2\n\t.int\t"
830 +#undef  TARGET_ASM_ALIGNED_DI_OP
831 +#define TARGET_ASM_ALIGNED_DI_OP NULL
832 +#undef  TARGET_ASM_ALIGNED_TI_OP
833 +#define TARGET_ASM_ALIGNED_TI_OP NULL
834 +#undef  TARGET_ASM_UNALIGNED_HI_OP
835 +#define TARGET_ASM_UNALIGNED_HI_OP "\t.short\t"
836 +#undef  TARGET_ASM_UNALIGNED_SI_OP
837 +#define TARGET_ASM_UNALIGNED_SI_OP "\t.int\t"
838 +#undef  TARGET_ASM_UNALIGNED_DI_OP
839 +#define TARGET_ASM_UNALIGNED_DI_OP NULL
840 +#undef  TARGET_ASM_UNALIGNED_TI_OP
841 +#define TARGET_ASM_UNALIGNED_TI_OP NULL
842 +
843 +#undef TARGET_ASM_OUTPUT_MI_THUNK
844 +#define TARGET_ASM_OUTPUT_MI_THUNK avr32_output_mi_thunk
845 +
846 +#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
847 +#define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
848 +
849 +
850 +static void
851 +avr32_output_mi_thunk (FILE * file,
852 +    tree thunk ATTRIBUTE_UNUSED,
853 +    HOST_WIDE_INT delta,
854 +    HOST_WIDE_INT vcall_offset, tree function)
855 +  {
856 +    int mi_delta = delta;
857 +    int this_regno =
858 +      (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ?
859 +       INTERNAL_REGNUM (11) : INTERNAL_REGNUM (12));
860 +
861 +
862 +    if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")
863 +        || vcall_offset)
864 +      {
865 +        fputs ("\tpushm\tlr\n", file);
866 +      }
867 +
868 +
869 +    if (mi_delta != 0)
870 +      {
871 +        if (avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21"))
872 +          {
873 +            fprintf (file, "\tsub\t%s, %d\n", reg_names[this_regno], -mi_delta);
874 +          }
875 +        else
876 +          {
877 +            /* Immediate is larger than k21 we must make us a temp register by
878 +            pushing a register to the stack. */
879 +            fprintf (file, "\tmov\tlr, lo(%d)\n", mi_delta);
880 +            fprintf (file, "\torh\tlr, hi(%d)\n", mi_delta);
881 +            fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]);
882 +          }
883 +      }
884 +
885 +
886 +    if (vcall_offset != 0)
887 +      {
888 +        fprintf (file, "\tld.w\tlr, %s[0]\n", reg_names[this_regno]);
889 +        fprintf (file, "\tld.w\tlr, lr[%i]\n", (int) vcall_offset);
890 +        fprintf (file, "\tadd\t%s, lr\n", reg_names[this_regno]);
891 +      }
892 +
893 +
894 +    if (!avr32_const_ok_for_constraint_p (mi_delta, 'I', "Is21")
895 +        || vcall_offset)
896 +      {
897 +        fputs ("\tpopm\tlr\n", file);
898 +      }
899 +
900 +    /* Jump to the function. We assume that we can use an rjmp since the
901 +       function to jump to is local and probably not too far away from
902 +       the thunk. If this assumption proves to be wrong we could implement
903 +       this jump by calculating the offset between the jump source and destination
904 +       and put this in the constant pool and then perform an add to pc.
905 +       This would also be legitimate PIC code. But for now we hope that an rjmp
906 +       will be sufficient...
907 +    */
908 +    fputs ("\trjmp\t", file);
909 +    assemble_name (file, XSTR (XEXP (DECL_RTL (function), 0), 0));
910 +    fputc ('\n', file);
911 +  }
912 +
913 +
914 +/* Implements target hook vector_mode_supported.  */
915 +bool
916 +avr32_vector_mode_supported (enum machine_mode mode)
917 +{
918 +  if ((mode == V2HImode) || (mode == V4QImode))
919 +    return true;
920 +
921 +  return false;
922 +}
923 +
924 +
925 +#undef TARGET_INIT_LIBFUNCS
926 +#define TARGET_INIT_LIBFUNCS avr32_init_libfuncs
927 +
928 +#undef  TARGET_INIT_BUILTINS
929 +#define TARGET_INIT_BUILTINS avr32_init_builtins
930 +
931 +#undef  TARGET_EXPAND_BUILTIN
932 +#define TARGET_EXPAND_BUILTIN avr32_expand_builtin
933 +
934 +tree int_ftype_int, int_ftype_void, short_ftype_short, void_ftype_int_int,
935 +  void_ftype_ptr_int;
936 +tree void_ftype_int, void_ftype_ulong, void_ftype_void, int_ftype_ptr_int;
937 +tree short_ftype_short, int_ftype_int_short, int_ftype_short_short,
938 +  short_ftype_short_short;
939 +tree int_ftype_int_int, longlong_ftype_int_short, longlong_ftype_short_short;
940 +tree void_ftype_int_int_int_int_int, void_ftype_int_int_int;
941 +tree longlong_ftype_int_int, void_ftype_int_int_longlong;
942 +tree int_ftype_int_int_int, longlong_ftype_longlong_int_short;
943 +tree longlong_ftype_longlong_short_short, int_ftype_int_short_short;
944 +
945 +#define def_builtin(NAME, TYPE, CODE)                                  \
946 +  add_builtin_function ((NAME), (TYPE), (CODE),                          \
947 +                       BUILT_IN_MD, NULL, NULL_TREE)
948 +
949 +#define def_mbuiltin(MASK, NAME, TYPE, CODE)                           \
950 +  do                                                                   \
951 +    {                                                                  \
952 +      if ((MASK))                                                      \
953 +       add_builtin_function ((NAME), (TYPE), (CODE),                   \
954 +                              BUILT_IN_MD, NULL, NULL_TREE);            \
955 +    }                                                                  \
956 +  while (0)
957 +
958 +struct builtin_description
959 +{
960 +  const unsigned int mask;
961 +  const enum insn_code icode;
962 +  const char *const name;
963 +  const int code;
964 +  const enum rtx_code comparison;
965 +  const unsigned int flag;
966 +  const tree *ftype;
967 +};
968 +
969 +static const struct builtin_description bdesc_2arg[] = {
970 +
971 +#define DSP_BUILTIN(code, builtin, ftype) \
972 +  { 1, CODE_FOR_##code, "__builtin_" #code , \
973 +  AVR32_BUILTIN_##builtin, 0, 0, ftype }
974 +
975 +  DSP_BUILTIN (mulsathh_h,    MULSATHH_H,    &short_ftype_short_short),
976 +  DSP_BUILTIN (mulsathh_w,    MULSATHH_W,    &int_ftype_short_short),
977 +  DSP_BUILTIN (mulsatrndhh_h, MULSATRNDHH_H, &short_ftype_short_short),
978 +  DSP_BUILTIN (mulsatrndwh_w, MULSATRNDWH_W, &int_ftype_int_short),
979 +  DSP_BUILTIN (mulsatwh_w,    MULSATWH_W,    &int_ftype_int_short),
980 +  DSP_BUILTIN (satadd_h,      SATADD_H,      &short_ftype_short_short),
981 +  DSP_BUILTIN (satsub_h,      SATSUB_H,      &short_ftype_short_short),
982 +  DSP_BUILTIN (satadd_w,      SATADD_W,      &int_ftype_int_int),
983 +  DSP_BUILTIN (satsub_w,      SATSUB_W,      &int_ftype_int_int),
984 +  DSP_BUILTIN (mulwh_d,       MULWH_D,       &longlong_ftype_int_short),
985 +  DSP_BUILTIN (mulnwh_d,      MULNWH_D,      &longlong_ftype_int_short)
986 +};
987 +
988 +
989 +void
990 +avr32_init_builtins (void)
991 +{
992 +  unsigned int i;
993 +  const struct builtin_description *d;
994 +  tree endlink = void_list_node;
995 +  tree int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink);
996 +  tree longlong_endlink =
997 +    tree_cons (NULL_TREE, long_long_integer_type_node, endlink);
998 +  tree short_endlink =
999 +    tree_cons (NULL_TREE, short_integer_type_node, endlink);
1000 +  tree void_endlink = tree_cons (NULL_TREE, void_type_node, endlink);
1001 +
1002 +  /* int func (int) */
1003 +  int_ftype_int = build_function_type (integer_type_node, int_endlink);
1004 +
1005 +  /* short func (short) */
1006 +  short_ftype_short
1007 +    = build_function_type (short_integer_type_node, short_endlink);
1008 +
1009 +  /* short func (short, short) */
1010 +  short_ftype_short_short
1011 +    = build_function_type (short_integer_type_node,
1012 +                          tree_cons (NULL_TREE, short_integer_type_node,
1013 +                                     short_endlink));
1014 +
1015 +  /* long long func (long long, short, short) */
1016 +  longlong_ftype_longlong_short_short
1017 +    = build_function_type (long_long_integer_type_node,
1018 +                          tree_cons (NULL_TREE, long_long_integer_type_node,
1019 +                                     tree_cons (NULL_TREE,
1020 +                                                short_integer_type_node,
1021 +                                                short_endlink)));
1022 +
1023 +  /* long long func (short, short) */
1024 +  longlong_ftype_short_short
1025 +    = build_function_type (long_long_integer_type_node,
1026 +                          tree_cons (NULL_TREE, short_integer_type_node,
1027 +                                     short_endlink));
1028 +
1029 +  /* int func (int, int) */
1030 +  int_ftype_int_int
1031 +    = build_function_type (integer_type_node,
1032 +                          tree_cons (NULL_TREE, integer_type_node,
1033 +                                     int_endlink));
1034 +
1035 +  /* long long func (int, int) */
1036 +  longlong_ftype_int_int
1037 +    = build_function_type (long_long_integer_type_node,
1038 +                          tree_cons (NULL_TREE, integer_type_node,
1039 +                                     int_endlink));
1040 +
1041 +  /* long long int func (long long, int, short) */
1042 +  longlong_ftype_longlong_int_short
1043 +    = build_function_type (long_long_integer_type_node,
1044 +                          tree_cons (NULL_TREE, long_long_integer_type_node,
1045 +                                     tree_cons (NULL_TREE, integer_type_node,
1046 +                                                short_endlink)));
1047 +
1048 +  /* long long int func (int, short) */
1049 +  longlong_ftype_int_short
1050 +    = build_function_type (long_long_integer_type_node,
1051 +                          tree_cons (NULL_TREE, integer_type_node,
1052 +                                     short_endlink));
1053 +
1054 +  /* int func (int, short, short) */
1055 +  int_ftype_int_short_short
1056 +    = build_function_type (integer_type_node,
1057 +                          tree_cons (NULL_TREE, integer_type_node,
1058 +                                     tree_cons (NULL_TREE,
1059 +                                                short_integer_type_node,
1060 +                                                short_endlink)));
1061 +
1062 +  /* int func (short, short) */
1063 +  int_ftype_short_short
1064 +    = build_function_type (integer_type_node,
1065 +                          tree_cons (NULL_TREE, short_integer_type_node,
1066 +                                     short_endlink));
1067 +
1068 +  /* int func (int, short) */
1069 +  int_ftype_int_short
1070 +    = build_function_type (integer_type_node,
1071 +                          tree_cons (NULL_TREE, integer_type_node,
1072 +                                     short_endlink));
1073 +
1074 +  /* void func (int, int) */
1075 +  void_ftype_int_int
1076 +    = build_function_type (void_type_node,
1077 +                          tree_cons (NULL_TREE, integer_type_node,
1078 +                                     int_endlink));
1079 +
1080 +  /* void func (int, int, int) */
1081 +  void_ftype_int_int_int
1082 +    = build_function_type (void_type_node,
1083 +                          tree_cons (NULL_TREE, integer_type_node,
1084 +                                     tree_cons (NULL_TREE, integer_type_node,
1085 +                                                int_endlink)));
1086 +
1087 +  /* void func (int, int, long long) */
1088 +  void_ftype_int_int_longlong
1089 +    = build_function_type (void_type_node,
1090 +                          tree_cons (NULL_TREE, integer_type_node,
1091 +                                     tree_cons (NULL_TREE, integer_type_node,
1092 +                                                longlong_endlink)));
1093 +
1094 +  /* void func (int, int, int, int, int) */
1095 +  void_ftype_int_int_int_int_int
1096 +    = build_function_type (void_type_node,
1097 +                          tree_cons (NULL_TREE, integer_type_node,
1098 +                                     tree_cons (NULL_TREE, integer_type_node,
1099 +                                                tree_cons (NULL_TREE,
1100 +                                                           integer_type_node,
1101 +                                                           tree_cons
1102 +                                                           (NULL_TREE,
1103 +                                                            integer_type_node,
1104 +                                                            int_endlink)))));
1105 +
1106 +  /* void func (void *, int) */
1107 +  void_ftype_ptr_int
1108 +    = build_function_type (void_type_node,
1109 +                          tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1110 +
1111 +  /* void func (int) */
1112 +  void_ftype_int = build_function_type (void_type_node, int_endlink);
1113 +
1114 +  /* void func (ulong) */
1115 +  void_ftype_ulong = build_function_type_list (void_type_node,
1116 +                           long_unsigned_type_node, NULL_TREE);
1117 +
1118 +  /* void func (void) */
1119 +  void_ftype_void = build_function_type (void_type_node, void_endlink);
1120 +
1121 +  /* int func (void) */
1122 +  int_ftype_void = build_function_type (integer_type_node, void_endlink);
1123 +
1124 +  /* int func (void *, int) */
1125 +  int_ftype_ptr_int
1126 +    = build_function_type (integer_type_node,
1127 +                          tree_cons (NULL_TREE, ptr_type_node, int_endlink));
1128 +
1129 +  /* int func (int, int, int) */
1130 +  int_ftype_int_int_int
1131 +    = build_function_type (integer_type_node,
1132 +                          tree_cons (NULL_TREE, integer_type_node,
1133 +                                     tree_cons (NULL_TREE, integer_type_node,
1134 +                                                int_endlink)));
1135 +
1136 +  /* Initialize avr32 builtins.  */
1137 +  def_builtin ("__builtin_mfsr", int_ftype_int, AVR32_BUILTIN_MFSR);
1138 +  def_builtin ("__builtin_mtsr", void_ftype_int_int, AVR32_BUILTIN_MTSR);
1139 +  def_builtin ("__builtin_mfdr", int_ftype_int, AVR32_BUILTIN_MFDR);
1140 +  def_builtin ("__builtin_mtdr", void_ftype_int_int, AVR32_BUILTIN_MTDR);
1141 +  def_builtin ("__builtin_cache", void_ftype_ptr_int, AVR32_BUILTIN_CACHE);
1142 +  def_builtin ("__builtin_sync", void_ftype_int, AVR32_BUILTIN_SYNC);
1143 +  def_builtin ("__builtin_ssrf", void_ftype_int, AVR32_BUILTIN_SSRF);
1144 +  def_builtin ("__builtin_csrf", void_ftype_int, AVR32_BUILTIN_CSRF);
1145 +  def_builtin ("__builtin_tlbr", void_ftype_void, AVR32_BUILTIN_TLBR);
1146 +  def_builtin ("__builtin_tlbs", void_ftype_void, AVR32_BUILTIN_TLBS);
1147 +  def_builtin ("__builtin_tlbw", void_ftype_void, AVR32_BUILTIN_TLBW);
1148 +  def_builtin ("__builtin_breakpoint", void_ftype_void,
1149 +              AVR32_BUILTIN_BREAKPOINT);
1150 +  def_builtin ("__builtin_xchg", int_ftype_ptr_int, AVR32_BUILTIN_XCHG);
1151 +  def_builtin ("__builtin_ldxi", int_ftype_ptr_int, AVR32_BUILTIN_LDXI);
1152 +  def_builtin ("__builtin_bswap_16", short_ftype_short,
1153 +              AVR32_BUILTIN_BSWAP16);
1154 +  def_builtin ("__builtin_bswap_32", int_ftype_int, AVR32_BUILTIN_BSWAP32);
1155 +  def_builtin ("__builtin_cop", void_ftype_int_int_int_int_int,
1156 +              AVR32_BUILTIN_COP);
1157 +  def_builtin ("__builtin_mvcr_w", int_ftype_int_int, AVR32_BUILTIN_MVCR_W);
1158 +  def_builtin ("__builtin_mvrc_w", void_ftype_int_int_int,
1159 +              AVR32_BUILTIN_MVRC_W);
1160 +  def_builtin ("__builtin_mvcr_d", longlong_ftype_int_int,
1161 +              AVR32_BUILTIN_MVCR_D);
1162 +  def_builtin ("__builtin_mvrc_d", void_ftype_int_int_longlong,
1163 +              AVR32_BUILTIN_MVRC_D);
1164 +  def_builtin ("__builtin_sats", int_ftype_int_int_int, AVR32_BUILTIN_SATS);
1165 +  def_builtin ("__builtin_satu", int_ftype_int_int_int, AVR32_BUILTIN_SATU);
1166 +  def_builtin ("__builtin_satrnds", int_ftype_int_int_int,
1167 +              AVR32_BUILTIN_SATRNDS);
1168 +  def_builtin ("__builtin_satrndu", int_ftype_int_int_int,
1169 +              AVR32_BUILTIN_SATRNDU);
1170 +  def_builtin ("__builtin_musfr", void_ftype_int, AVR32_BUILTIN_MUSFR);
1171 +  def_builtin ("__builtin_mustr", int_ftype_void, AVR32_BUILTIN_MUSTR);
1172 +  def_builtin ("__builtin_macsathh_w", int_ftype_int_short_short,
1173 +              AVR32_BUILTIN_MACSATHH_W);
1174 +  def_builtin ("__builtin_macwh_d", longlong_ftype_longlong_int_short,
1175 +              AVR32_BUILTIN_MACWH_D);
1176 +  def_builtin ("__builtin_machh_d", longlong_ftype_longlong_short_short,
1177 +              AVR32_BUILTIN_MACHH_D);
1178 +  def_builtin ("__builtin_mems", void_ftype_ptr_int, AVR32_BUILTIN_MEMS);
1179 +  def_builtin ("__builtin_memt", void_ftype_ptr_int, AVR32_BUILTIN_MEMT);
1180 +  def_builtin ("__builtin_memc", void_ftype_ptr_int, AVR32_BUILTIN_MEMC);
1181 +  def_builtin ("__builtin_sleep", void_ftype_int, AVR32_BUILTIN_SLEEP);
1182 +  def_builtin ("__builtin_avr32_delay_cycles", void_ftype_int, AVR32_BUILTIN_DELAY_CYCLES);
1183 +
1184 +  /* Add all builtins that are more or less simple operations on two
1185 +     operands.  */
1186 +  for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
1187 +    {
1188 +      /* Use one of the operands; the target can have a different mode for
1189 +         mask-generating compares.  */
1190 +
1191 +      if (d->name == 0)
1192 +       continue;
1193 +
1194 +      def_mbuiltin (d->mask, d->name, *(d->ftype), d->code);
1195 +    }
1196 +}
1197 +
1198 +
1199 +/* Subroutine of avr32_expand_builtin to take care of binop insns. */
1200 +static rtx
1201 +avr32_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
1202 +{
1203 +  rtx pat;
1204 +  tree arg0 = CALL_EXPR_ARG (exp,0);
1205 +  tree arg1 = CALL_EXPR_ARG (exp,1);
1206 +  rtx op0 = expand_normal (arg0);
1207 +  rtx op1 = expand_normal (arg1);
1208 +  enum machine_mode tmode = insn_data[icode].operand[0].mode;
1209 +  enum machine_mode mode0 = insn_data[icode].operand[1].mode;
1210 +  enum machine_mode mode1 = insn_data[icode].operand[2].mode;
1211 +
1212 +  if (!target
1213 +      || GET_MODE (target) != tmode
1214 +      || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1215 +    target = gen_reg_rtx (tmode);
1216 +
1217 +  /* In case the insn wants input operands in modes different from the
1218 +     result, abort.  */
1219 +  if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1220 +    {
1221 +      /* If op0 is already a reg we must cast it to the correct mode. */
1222 +      if (REG_P (op0))
1223 +       op0 = convert_to_mode (mode0, op0, 1);
1224 +      else
1225 +       op0 = copy_to_mode_reg (mode0, op0);
1226 +    }
1227 +  if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1228 +    {
1229 +      /* If op1 is already a reg we must cast it to the correct mode. */
1230 +      if (REG_P (op1))
1231 +       op1 = convert_to_mode (mode1, op1, 1);
1232 +      else
1233 +       op1 = copy_to_mode_reg (mode1, op1);
1234 +    }
1235 +  pat = GEN_FCN (icode) (target, op0, op1);
1236 +  if (!pat)
1237 +    return 0;
1238 +  emit_insn (pat);
1239 +  return target;
1240 +}
1241 +
1242 +
1243 +/* Expand an expression EXP that calls a built-in function,
1244 +   with result going to TARGET if that's convenient
1245 +   (and in mode MODE if that's convenient).
1246 +   SUBTARGET may be used as the target for computing one of EXP's operands.
1247 +   IGNORE is nonzero if the value is to be ignored.  */
1248 +rtx
1249 +avr32_expand_builtin (tree exp,
1250 +                     rtx target,
1251 +                     rtx subtarget ATTRIBUTE_UNUSED,
1252 +                     enum machine_mode mode ATTRIBUTE_UNUSED,
1253 +                     int ignore ATTRIBUTE_UNUSED)
1254 +{
1255 +  const struct builtin_description *d;
1256 +  unsigned int i;
1257 +  enum insn_code icode = 0;
1258 +  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1259 +  tree arg0, arg1, arg2;
1260 +  rtx op0, op1, op2, pat;
1261 +  enum machine_mode tmode, mode0, mode1;
1262 +  enum machine_mode arg0_mode;
1263 +  int fcode = DECL_FUNCTION_CODE (fndecl);
1264 +
1265 +  switch (fcode)
1266 +    {
1267 +    default:
1268 +      break;
1269 +
1270 +    case AVR32_BUILTIN_SATS:
1271 +    case AVR32_BUILTIN_SATU:
1272 +    case AVR32_BUILTIN_SATRNDS:
1273 +    case AVR32_BUILTIN_SATRNDU:
1274 +      {
1275 +       const char *fname;
1276 +       switch (fcode)
1277 +         {
1278 +         default:
1279 +         case AVR32_BUILTIN_SATS:
1280 +           icode = CODE_FOR_sats;
1281 +           fname = "sats";
1282 +           break;
1283 +         case AVR32_BUILTIN_SATU:
1284 +           icode = CODE_FOR_satu;
1285 +           fname = "satu";
1286 +           break;
1287 +         case AVR32_BUILTIN_SATRNDS:
1288 +           icode = CODE_FOR_satrnds;
1289 +           fname = "satrnds";
1290 +           break;
1291 +         case AVR32_BUILTIN_SATRNDU:
1292 +           icode = CODE_FOR_satrndu;
1293 +           fname = "satrndu";
1294 +           break;
1295 +         }
1296 +
1297 +       arg0 = CALL_EXPR_ARG (exp,0);
1298 +       arg1 = CALL_EXPR_ARG (exp,1);
1299 +       arg2 = CALL_EXPR_ARG (exp,2);
1300 +       op0 = expand_normal (arg0);
1301 +       op1 = expand_normal (arg1);
1302 +       op2 = expand_normal (arg2);
1303 +
1304 +       tmode = insn_data[icode].operand[0].mode;
1305 +
1306 +
1307 +       if (target == 0
1308 +           || GET_MODE (target) != tmode
1309 +           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1310 +         target = gen_reg_rtx (tmode);
1311 +
1312 +
1313 +       if (!(*insn_data[icode].operand[0].predicate) (op0, GET_MODE (op0)))
1314 +         {
1315 +           op0 = copy_to_mode_reg (insn_data[icode].operand[0].mode, op0);
1316 +         }
1317 +
1318 +       if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1319 +         {
1320 +           error ("Parameter 2 to __builtin_%s should be a constant number.",
1321 +                  fname);
1322 +           return NULL_RTX;
1323 +         }
1324 +
1325 +       if (!(*insn_data[icode].operand[1].predicate) (op2, SImode))
1326 +         {
1327 +           error ("Parameter 3 to __builtin_%s should be a constant number.",
1328 +                  fname);
1329 +           return NULL_RTX;
1330 +         }
1331 +
1332 +       emit_move_insn (target, op0);
1333 +       pat = GEN_FCN (icode) (target, op1, op2);
1334 +       if (!pat)
1335 +         return 0;
1336 +       emit_insn (pat);
1337 +
1338 +       return target;
1339 +      }
1340 +    case AVR32_BUILTIN_MUSTR:
1341 +      icode = CODE_FOR_mustr;
1342 +      tmode = insn_data[icode].operand[0].mode;
1343 +
1344 +      if (target == 0
1345 +         || GET_MODE (target) != tmode
1346 +         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1347 +       target = gen_reg_rtx (tmode);
1348 +      pat = GEN_FCN (icode) (target);
1349 +      if (!pat)
1350 +       return 0;
1351 +      emit_insn (pat);
1352 +      return target;
1353 +
1354 +    case AVR32_BUILTIN_MFSR:
1355 +      icode = CODE_FOR_mfsr;
1356 +      arg0 = CALL_EXPR_ARG (exp,0);
1357 +      op0 = expand_normal (arg0);
1358 +      tmode = insn_data[icode].operand[0].mode;
1359 +      mode0 = insn_data[icode].operand[1].mode;
1360 +
1361 +      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1362 +       {
1363 +         error ("Parameter 1 to __builtin_mfsr must be a constant number");
1364 +       }
1365 +
1366 +      if (target == 0
1367 +         || GET_MODE (target) != tmode
1368 +         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1369 +       target = gen_reg_rtx (tmode);
1370 +      pat = GEN_FCN (icode) (target, op0);
1371 +      if (!pat)
1372 +       return 0;
1373 +      emit_insn (pat);
1374 +      return target;
1375 +    case AVR32_BUILTIN_MTSR:
1376 +      icode = CODE_FOR_mtsr;
1377 +      arg0 = CALL_EXPR_ARG (exp,0);
1378 +      arg1 = CALL_EXPR_ARG (exp,1);
1379 +      op0 = expand_normal (arg0);
1380 +      op1 = expand_normal (arg1);
1381 +      mode0 = insn_data[icode].operand[0].mode;
1382 +      mode1 = insn_data[icode].operand[1].mode;
1383 +
1384 +      if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1385 +       {
1386 +         error ("Parameter 1 to __builtin_mtsr must be a constant number");
1387 +         return gen_reg_rtx (mode0);
1388 +       }
1389 +      if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1390 +       op1 = copy_to_mode_reg (mode1, op1);
1391 +      pat = GEN_FCN (icode) (op0, op1);
1392 +      if (!pat)
1393 +       return 0;
1394 +      emit_insn (pat);
1395 +      return NULL_RTX;
1396 +    case AVR32_BUILTIN_MFDR:
1397 +      icode = CODE_FOR_mfdr;
1398 +      arg0 = CALL_EXPR_ARG (exp,0);
1399 +      op0 = expand_normal (arg0);
1400 +      tmode = insn_data[icode].operand[0].mode;
1401 +      mode0 = insn_data[icode].operand[1].mode;
1402 +
1403 +      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1404 +       {
1405 +         error ("Parameter 1 to __builtin_mfdr must be a constant number");
1406 +       }
1407 +
1408 +      if (target == 0
1409 +         || GET_MODE (target) != tmode
1410 +         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1411 +       target = gen_reg_rtx (tmode);
1412 +      pat = GEN_FCN (icode) (target, op0);
1413 +      if (!pat)
1414 +       return 0;
1415 +      emit_insn (pat);
1416 +      return target;
1417 +    case AVR32_BUILTIN_MTDR:
1418 +      icode = CODE_FOR_mtdr;
1419 +      arg0 = CALL_EXPR_ARG (exp,0);
1420 +      arg1 = CALL_EXPR_ARG (exp,1);
1421 +      op0 = expand_normal (arg0);
1422 +      op1 = expand_normal (arg1);
1423 +      mode0 = insn_data[icode].operand[0].mode;
1424 +      mode1 = insn_data[icode].operand[1].mode;
1425 +
1426 +      if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1427 +       {
1428 +         error ("Parameter 1 to __builtin_mtdr must be a constant number");
1429 +         return gen_reg_rtx (mode0);
1430 +       }
1431 +      if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1432 +       op1 = copy_to_mode_reg (mode1, op1);
1433 +      pat = GEN_FCN (icode) (op0, op1);
1434 +      if (!pat)
1435 +       return 0;
1436 +      emit_insn (pat);
1437 +      return NULL_RTX;
1438 +    case AVR32_BUILTIN_CACHE:
1439 +      icode = CODE_FOR_cache;
1440 +      arg0 = CALL_EXPR_ARG (exp,0);
1441 +      arg1 = CALL_EXPR_ARG (exp,1);
1442 +      op0 = expand_normal (arg0);
1443 +      op1 = expand_normal (arg1);
1444 +      mode0 = insn_data[icode].operand[0].mode;
1445 +      mode1 = insn_data[icode].operand[1].mode;
1446 +
1447 +      if (!(*insn_data[icode].operand[1].predicate) (op1, mode1))
1448 +       {
1449 +         error ("Parameter 2 to __builtin_cache must be a constant number");
1450 +         return gen_reg_rtx (mode1);
1451 +       }
1452 +
1453 +      if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1454 +       op0 = copy_to_mode_reg (mode0, op0);
1455 +
1456 +      pat = GEN_FCN (icode) (op0, op1);
1457 +      if (!pat)
1458 +       return 0;
1459 +      emit_insn (pat);
1460 +      return NULL_RTX;
1461 +    case AVR32_BUILTIN_SYNC:
1462 +    case AVR32_BUILTIN_MUSFR:
1463 +    case AVR32_BUILTIN_SSRF:
1464 +    case AVR32_BUILTIN_CSRF:
1465 +      {
1466 +       const char *fname;
1467 +       switch (fcode)
1468 +         {
1469 +         default:
1470 +         case AVR32_BUILTIN_SYNC:
1471 +           icode = CODE_FOR_sync;
1472 +           fname = "sync";
1473 +           break;
1474 +         case AVR32_BUILTIN_MUSFR:
1475 +           icode = CODE_FOR_musfr;
1476 +           fname = "musfr";
1477 +           break;
1478 +         case AVR32_BUILTIN_SSRF:
1479 +           icode = CODE_FOR_ssrf;
1480 +           fname = "ssrf";
1481 +           break;
1482 +         case AVR32_BUILTIN_CSRF:
1483 +           icode = CODE_FOR_csrf;
1484 +           fname = "csrf";
1485 +           break;
1486 +         }
1487 +
1488 +       arg0 = CALL_EXPR_ARG (exp,0);
1489 +       op0 = expand_normal (arg0);
1490 +       mode0 = insn_data[icode].operand[0].mode;
1491 +
1492 +       if (!(*insn_data[icode].operand[0].predicate) (op0, mode0))
1493 +         {
1494 +           if (icode == CODE_FOR_musfr)
1495 +             op0 = copy_to_mode_reg (mode0, op0);
1496 +           else
1497 +             {
1498 +               error ("Parameter to __builtin_%s is illegal.", fname);
1499 +               return gen_reg_rtx (mode0);
1500 +             }
1501 +         }
1502 +       pat = GEN_FCN (icode) (op0);
1503 +       if (!pat)
1504 +         return 0;
1505 +       emit_insn (pat);
1506 +       return NULL_RTX;
1507 +      }
1508 +    case AVR32_BUILTIN_TLBR:
1509 +      icode = CODE_FOR_tlbr;
1510 +      pat = GEN_FCN (icode) (NULL_RTX);
1511 +      if (!pat)
1512 +       return 0;
1513 +      emit_insn (pat);
1514 +      return NULL_RTX;
1515 +    case AVR32_BUILTIN_TLBS:
1516 +      icode = CODE_FOR_tlbs;
1517 +      pat = GEN_FCN (icode) (NULL_RTX);
1518 +      if (!pat)
1519 +       return 0;
1520 +      emit_insn (pat);
1521 +      return NULL_RTX;
1522 +    case AVR32_BUILTIN_TLBW:
1523 +      icode = CODE_FOR_tlbw;
1524 +      pat = GEN_FCN (icode) (NULL_RTX);
1525 +      if (!pat)
1526 +       return 0;
1527 +      emit_insn (pat);
1528 +      return NULL_RTX;
1529 +    case AVR32_BUILTIN_BREAKPOINT:
1530 +      icode = CODE_FOR_breakpoint;
1531 +      pat = GEN_FCN (icode) (NULL_RTX);
1532 +      if (!pat)
1533 +       return 0;
1534 +      emit_insn (pat);
1535 +      return NULL_RTX;
1536 +    case AVR32_BUILTIN_XCHG:
1537 +      icode = CODE_FOR_sync_lock_test_and_setsi;
1538 +      arg0 = CALL_EXPR_ARG (exp,0);
1539 +      arg1 = CALL_EXPR_ARG (exp,1);
1540 +      op0 = expand_normal (arg0);
1541 +      op1 = expand_normal (arg1);
1542 +      tmode = insn_data[icode].operand[0].mode;
1543 +      mode0 = insn_data[icode].operand[1].mode;
1544 +      mode1 = insn_data[icode].operand[2].mode;
1545 +
1546 +      if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1547 +       {
1548 +         op1 = copy_to_mode_reg (mode1, op1);
1549 +       }
1550 +
1551 +      op0 = force_reg (GET_MODE (op0), op0);
1552 +      op0 = gen_rtx_MEM (GET_MODE (op0), op0);
1553 +      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1554 +       {
1555 +         error
1556 +           ("Parameter 1 to __builtin_xchg must be a pointer to an integer.");
1557 +       }
1558 +
1559 +      if (target == 0
1560 +         || GET_MODE (target) != tmode
1561 +         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1562 +       target = gen_reg_rtx (tmode);
1563 +      pat = GEN_FCN (icode) (target, op0, op1);
1564 +      if (!pat)
1565 +       return 0;
1566 +      emit_insn (pat);
1567 +      return target;
1568 +    case AVR32_BUILTIN_LDXI:
1569 +      icode = CODE_FOR_ldxi;
1570 +      arg0 = CALL_EXPR_ARG (exp,0);
1571 +      arg1 = CALL_EXPR_ARG (exp,1);
1572 +      arg2 = CALL_EXPR_ARG (exp,2);
1573 +      op0 = expand_normal (arg0);
1574 +      op1 = expand_normal (arg1);
1575 +      op2 = expand_normal (arg2);
1576 +      tmode = insn_data[icode].operand[0].mode;
1577 +      mode0 = insn_data[icode].operand[1].mode;
1578 +      mode1 = insn_data[icode].operand[2].mode;
1579 +
1580 +      if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1581 +       {
1582 +         op0 = copy_to_mode_reg (mode0, op0);
1583 +       }
1584 +
1585 +      if (!(*insn_data[icode].operand[2].predicate) (op1, mode1))
1586 +       {
1587 +         op1 = copy_to_mode_reg (mode1, op1);
1588 +       }
1589 +
1590 +      if (!(*insn_data[icode].operand[3].predicate) (op2, SImode))
1591 +       {
1592 +         error
1593 +           ("Parameter 3 to __builtin_ldxi must be a valid extract shift operand: (0|8|16|24)");
1594 +         return gen_reg_rtx (mode0);
1595 +       }
1596 +
1597 +      if (target == 0
1598 +         || GET_MODE (target) != tmode
1599 +         || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1600 +       target = gen_reg_rtx (tmode);
1601 +      pat = GEN_FCN (icode) (target, op0, op1, op2);
1602 +      if (!pat)
1603 +       return 0;
1604 +      emit_insn (pat);
1605 +      return target;
1606 +    case AVR32_BUILTIN_BSWAP16:
1607 +      {
1608 +       icode = CODE_FOR_bswap_16;
1609 +       arg0 = CALL_EXPR_ARG (exp,0);
1610 +       arg0_mode = TYPE_MODE (TREE_TYPE (arg0));
1611 +       mode0 = insn_data[icode].operand[1].mode;
1612 +       if (arg0_mode != mode0)
1613 +         arg0 = build1 (NOP_EXPR,
1614 +                        (*lang_hooks.types.type_for_mode) (mode0, 0), arg0);
1615 +
1616 +       op0 = expand_expr (arg0, NULL_RTX, HImode, 0);
1617 +       tmode = insn_data[icode].operand[0].mode;
1618 +
1619 +
1620 +       if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1621 +         {
1622 +            if ( CONST_INT_P (op0) )
1623 +              {
1624 +                HOST_WIDE_INT val = ( ((INTVAL (op0)&0x00ff) << 8) |
1625 +                                      ((INTVAL (op0)&0xff00) >> 8) );
1626 +                /* Sign extend 16-bit value to host wide int */
1627 +                val <<= (HOST_BITS_PER_WIDE_INT - 16);
1628 +                val >>= (HOST_BITS_PER_WIDE_INT - 16);
1629 +                op0 = GEN_INT(val);
1630 +                if (target == 0
1631 +                    || GET_MODE (target) != tmode
1632 +                    || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1633 +                  target = gen_reg_rtx (tmode);
1634 +                emit_move_insn(target, op0);
1635 +                return target;
1636 +              }
1637 +            else
1638 +              op0 = copy_to_mode_reg (mode0, op0);
1639 +         }
1640 +
1641 +       if (target == 0
1642 +           || GET_MODE (target) != tmode
1643 +           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1644 +         {
1645 +           target = gen_reg_rtx (tmode);
1646 +         }
1647 +
1648 +
1649 +       pat = GEN_FCN (icode) (target, op0);
1650 +       if (!pat)
1651 +         return 0;
1652 +       emit_insn (pat);
1653 +
1654 +       return target;
1655 +      }
1656 +    case AVR32_BUILTIN_BSWAP32:
1657 +      {
1658 +       icode = CODE_FOR_bswap_32;
1659 +       arg0 = CALL_EXPR_ARG (exp,0);
1660 +       op0 = expand_normal (arg0);
1661 +       tmode = insn_data[icode].operand[0].mode;
1662 +       mode0 = insn_data[icode].operand[1].mode;
1663 +
1664 +       if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1665 +         {
1666 +            if ( CONST_INT_P (op0) )
1667 +              {
1668 +                HOST_WIDE_INT val = ( ((INTVAL (op0)&0x000000ff) << 24) |
1669 +                                      ((INTVAL (op0)&0x0000ff00) << 8) |
1670 +                                      ((INTVAL (op0)&0x00ff0000) >> 8) |
1671 +                                      ((INTVAL (op0)&0xff000000) >> 24) );
1672 +                /* Sign extend 32-bit value to host wide int */
1673 +                val <<= (HOST_BITS_PER_WIDE_INT - 32);
1674 +                val >>= (HOST_BITS_PER_WIDE_INT - 32);
1675 +                op0 = GEN_INT(val);
1676 +                if (target == 0
1677 +                    || GET_MODE (target) != tmode
1678 +                    || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1679 +                  target = gen_reg_rtx (tmode);
1680 +                emit_move_insn(target, op0);
1681 +                return target;
1682 +              }
1683 +            else
1684 +              op0 = copy_to_mode_reg (mode0, op0);
1685 +         }
1686 +
1687 +       if (target == 0
1688 +           || GET_MODE (target) != tmode
1689 +           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1690 +         target = gen_reg_rtx (tmode);
1691 +
1692 +
1693 +       pat = GEN_FCN (icode) (target, op0);
1694 +       if (!pat)
1695 +         return 0;
1696 +       emit_insn (pat);
1697 +
1698 +       return target;
1699 +      }
1700 +    case AVR32_BUILTIN_MVCR_W:
1701 +    case AVR32_BUILTIN_MVCR_D:
1702 +      {
1703 +       arg0 = CALL_EXPR_ARG (exp,0);
1704 +       arg1 = CALL_EXPR_ARG (exp,1);
1705 +       op0 = expand_normal (arg0);
1706 +       op1 = expand_normal (arg1);
1707 +
1708 +       if (fcode == AVR32_BUILTIN_MVCR_W)
1709 +         icode = CODE_FOR_mvcrsi;
1710 +       else
1711 +         icode = CODE_FOR_mvcrdi;
1712 +
1713 +       tmode = insn_data[icode].operand[0].mode;
1714 +
1715 +       if (target == 0
1716 +           || GET_MODE (target) != tmode
1717 +           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1718 +         target = gen_reg_rtx (tmode);
1719 +
1720 +       if (!(*insn_data[icode].operand[1].predicate) (op0, SImode))
1721 +         {
1722 +           error
1723 +             ("Parameter 1 to __builtin_cop is not a valid coprocessor number.");
1724 +           error ("Number should be between 0 and 7.");
1725 +           return NULL_RTX;
1726 +         }
1727 +
1728 +       if (!(*insn_data[icode].operand[2].predicate) (op1, SImode))
1729 +         {
1730 +           error
1731 +             ("Parameter 2 to __builtin_cop is not a valid coprocessor register number.");
1732 +           error ("Number should be between 0 and 15.");
1733 +           return NULL_RTX;
1734 +         }
1735 +
1736 +       pat = GEN_FCN (icode) (target, op0, op1);
1737 +       if (!pat)
1738 +         return 0;
1739 +       emit_insn (pat);
1740 +
1741 +       return target;
1742 +      }
1743 +    case AVR32_BUILTIN_MACSATHH_W:
1744 +    case AVR32_BUILTIN_MACWH_D:
1745 +    case AVR32_BUILTIN_MACHH_D:
1746 +      {
1747 +       arg0 = CALL_EXPR_ARG (exp,0);
1748 +       arg1 = CALL_EXPR_ARG (exp,1);
1749 +       arg2 = CALL_EXPR_ARG (exp,2);
1750 +       op0 = expand_normal (arg0);
1751 +       op1 = expand_normal (arg1);
1752 +       op2 = expand_normal (arg2);
1753 +
1754 +       icode = ((fcode == AVR32_BUILTIN_MACSATHH_W) ? CODE_FOR_macsathh_w :
1755 +                (fcode == AVR32_BUILTIN_MACWH_D) ? CODE_FOR_macwh_d :
1756 +                CODE_FOR_machh_d);
1757 +
1758 +       tmode = insn_data[icode].operand[0].mode;
1759 +       mode0 = insn_data[icode].operand[1].mode;
1760 +       mode1 = insn_data[icode].operand[2].mode;
1761 +
1762 +
1763 +       if (!target
1764 +           || GET_MODE (target) != tmode
1765 +           || !(*insn_data[icode].operand[0].predicate) (target, tmode))
1766 +         target = gen_reg_rtx (tmode);
1767 +
1768 +       if (!(*insn_data[icode].operand[0].predicate) (op0, tmode))
1769 +         {
1770 +           /* If op0 is already a reg we must cast it to the correct mode. */
1771 +           if (REG_P (op0))
1772 +             op0 = convert_to_mode (tmode, op0, 1);
1773 +           else
1774 +             op0 = copy_to_mode_reg (tmode, op0);
1775 +         }
1776 +
1777 +       if (!(*insn_data[icode].operand[1].predicate) (op1, mode0))
1778 +         {
1779 +           /* If op1 is already a reg we must cast it to the correct mode. */
1780 +           if (REG_P (op1))
1781 +             op1 = convert_to_mode (mode0, op1, 1);
1782 +           else
1783 +             op1 = copy_to_mode_reg (mode0, op1);
1784 +         }
1785 +
1786 +       if (!(*insn_data[icode].operand[2].predicate) (op2, mode1))
1787 +         {
1788 +           /* If op1 is already a reg we must cast it to the correct mode. */
1789 +           if (REG_P (op2))
1790 +             op2 = convert_to_mode (mode1, op2, 1);
1791 +           else
1792 +             op2 = copy_to_mode_reg (mode1, op2);
1793 +         }
1794 +
1795 +       emit_move_insn (target, op0);
1796 +
1797 +       pat = GEN_FCN (icode) (target, op1, op2);
1798 +       if (!pat)
1799 +         return 0;
1800 +       emit_insn (pat);
1801 +       return target;
1802 +      }
1803 +    case AVR32_BUILTIN_MVRC_W:
1804 +    case AVR32_BUILTIN_MVRC_D:
1805 +      {
1806 +       arg0 = CALL_EXPR_ARG (exp,0);
1807 +       arg1 = CALL_EXPR_ARG (exp,1);
1808 +       arg2 = CALL_EXPR_ARG (exp,2);
1809 +       op0 = expand_normal (arg0);
1810 +       op1 = expand_normal (arg1);
1811 +       op2 = expand_normal (arg2);
1812 +
1813 +       if (fcode == AVR32_BUILTIN_MVRC_W)
1814 +         icode = CODE_FOR_mvrcsi;
1815 +       else
1816 +         icode = CODE_FOR_mvrcdi;
1817 +
1818 +       if (!(*insn_data[icode].operand[0].predicate) (op0, SImode))
1819 +         {
1820 +           error ("Parameter 1 is not a valid coprocessor number.");
1821 +           error ("Number should be between 0 and 7.");
1822 +           return NULL_RTX;
1823 +         }
1824 +
1825 +       if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1826 +         {
1827 +           error ("Parameter 2 is not a valid coprocessor register number.");
1828 +           error ("Number should be between 0 and 15.");
1829 +           return NULL_RTX;
1830 +         }
1831 +
1832 +       if (GET_CODE (op2) == CONST_INT
1833 +           || GET_CODE (op2) == CONST
1834 +           || GET_CODE (op2) == SYMBOL_REF || GET_CODE (op2) == LABEL_REF)
1835 +         {
1836 +           op2 = force_const_mem (insn_data[icode].operand[2].mode, op2);
1837 +         }
1838 +
1839 +       if (!(*insn_data[icode].operand[2].predicate) (op2, GET_MODE (op2)))
1840 +         op2 = copy_to_mode_reg (insn_data[icode].operand[2].mode, op2);
1841 +
1842 +
1843 +       pat = GEN_FCN (icode) (op0, op1, op2);
1844 +       if (!pat)
1845 +         return 0;
1846 +       emit_insn (pat);
1847 +
1848 +       return NULL_RTX;
1849 +      }
1850 +    case AVR32_BUILTIN_COP:
1851 +      {
1852 +       rtx op3, op4;
1853 +       tree arg3, arg4;
1854 +       icode = CODE_FOR_cop;
1855 +       arg0 = CALL_EXPR_ARG (exp,0);
1856 +       arg1 = CALL_EXPR_ARG (exp,1);
1857 +       arg2 = CALL_EXPR_ARG (exp,2);
1858 +       arg3 = CALL_EXPR_ARG (exp,3);
1859 +       arg4 = CALL_EXPR_ARG (exp,4);
1860 +       op0 = expand_normal (arg0);
1861 +       op1 = expand_normal (arg1);
1862 +       op2 = expand_normal (arg2);
1863 +       op3 = expand_normal (arg3);
1864 +       op4 = expand_normal (arg4);
1865 +
1866 +       if (!(*insn_data[icode].operand[0].predicate) (op0, SImode))
1867 +         {
1868 +           error
1869 +             ("Parameter 1 to __builtin_cop is not a valid coprocessor number.");
1870 +           error ("Number should be between 0 and 7.");
1871 +           return NULL_RTX;
1872 +         }
1873 +
1874 +       if (!(*insn_data[icode].operand[1].predicate) (op1, SImode))
1875 +         {
1876 +           error
1877 +             ("Parameter 2 to __builtin_cop is not a valid coprocessor register number.");
1878 +           error ("Number should be between 0 and 15.");
1879 +           return NULL_RTX;
1880 +         }
1881 +
1882 +       if (!(*insn_data[icode].operand[2].predicate) (op2, SImode))
1883 +         {
1884 +           error
1885 +             ("Parameter 3 to __builtin_cop is not a valid coprocessor register number.");
1886 +           error ("Number should be between 0 and 15.");
1887 +           return NULL_RTX;
1888 +         }
1889 +
1890 +       if (!(*insn_data[icode].operand[3].predicate) (op3, SImode))
1891 +         {
1892 +           error
1893 +             ("Parameter 4 to __builtin_cop is not a valid coprocessor register number.");
1894 +           error ("Number should be between 0 and 15.");
1895 +           return NULL_RTX;
1896 +         }
1897 +
1898 +       if (!(*insn_data[icode].operand[4].predicate) (op4, SImode))
1899 +         {
1900 +           error
1901 +             ("Parameter 5 to __builtin_cop is not a valid coprocessor operation.");
1902 +           error ("Number should be between 0 and 127.");
1903 +           return NULL_RTX;
1904 +         }
1905 +
1906 +       pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
1907 +       if (!pat)
1908 +         return 0;
1909 +       emit_insn (pat);
1910 +
1911 +       return target;
1912 +      }
1913 +
1914 +     case AVR32_BUILTIN_MEMS:
1915 +     case AVR32_BUILTIN_MEMC:
1916 +     case AVR32_BUILTIN_MEMT:
1917 +       {
1918 +         if (!TARGET_RMW)
1919 +           error ("Trying to use __builtin_mem(s/c/t) when target does not support RMW insns.");
1920 +         
1921 +         switch (fcode) {
1922 +         case AVR32_BUILTIN_MEMS:
1923 +           icode = CODE_FOR_iorsi3;
1924 +           break;
1925 +         case AVR32_BUILTIN_MEMC:
1926 +           icode = CODE_FOR_andsi3;
1927 +           break;
1928 +         case AVR32_BUILTIN_MEMT:
1929 +           icode = CODE_FOR_xorsi3;
1930 +           break;
1931 +         }
1932 +                       arg0 = CALL_EXPR_ARG (exp,0);
1933 +                       arg1 = CALL_EXPR_ARG (exp,1);
1934 +         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1935 +         if ( GET_CODE (op0) == SYMBOL_REF )
1936 +           // This symbol must be RMW addressable
1937 +           SYMBOL_REF_FLAGS (op0) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT);
1938 +         op0 = gen_rtx_MEM(SImode, op0);
1939 +         op1 = expand_expr (arg1, NULL_RTX, VOIDmode, 0);
1940 +         mode0 = insn_data[icode].operand[1].mode;
1941 +         
1942 +         
1943 +         if (!(*insn_data[icode].operand[1].predicate) (op0, mode0))
1944 +           {
1945 +             error ("Parameter 1 to __builtin_mem(s/c/t) must be a Ks15<<2 address or a rmw addressable symbol.");
1946 +           }
1947 +         
1948 +         if ( !CONST_INT_P (op1)
1949 +              || INTVAL (op1) > 31
1950 +              || INTVAL (op1) < 0 )
1951 +           error ("Parameter 2 to __builtin_mem(s/c/t) must be a constant between 0 and 31.");
1952
1953 +         if ( fcode == AVR32_BUILTIN_MEMC )
1954 +           op1 = GEN_INT((~(1 << INTVAL(op1)))&0xffffffff);
1955 +         else
1956 +           op1 = GEN_INT((1 << INTVAL(op1))&0xffffffff);
1957 +         pat = GEN_FCN (icode) (op0, op0, op1);
1958 +         if (!pat)
1959 +           return 0;
1960 +         emit_insn (pat);
1961 +         return op0;
1962 +       }
1963 +       
1964 +     case AVR32_BUILTIN_SLEEP:
1965 +       {
1966 +       arg0 = CALL_EXPR_ARG (exp, 0);
1967 +       op0  = expand_normal (arg0);
1968 +       int intval = INTVAL(op0);
1969
1970 +       /* Check if the argument if integer and if the value of integer
1971 +          is greater than 0. */ 
1972 +        
1973 +       if (!CONSTANT_P (op0))
1974 +         error ("Parameter 1 to __builtin_sleep() is not a valid integer.");
1975 +       if (intval < 0 )
1976 +            error ("Parameter 1 to __builtin_sleep() should be an integer greater than 0.");
1977
1978 +         int strncmpval = strncmp (avr32_part_name,"uc3l", 4);
1979 +  
1980 +       /* Check if op0 is less than 7 for uc3l* and less than 6 for other
1981 +          devices. By this check we are avoiding if operand is less than  
1982 +          256. For more devices, add more such checks. */
1983 +        
1984 +       if ( strncmpval == 0 && intval >= 7)  
1985 +        error ("Parameter 1 to __builtin_sleep() should be less than or equal to 7.");
1986 +       else if ( strncmp != 0 && intval >= 6)
1987 +           error ("Parameter 1 to __builtin_sleep() should be less than or equal to 6.");
1988
1989 +       emit_insn (gen_sleep(op0));
1990 +       return target;
1991
1992 +       }       
1993 +     case AVR32_BUILTIN_DELAY_CYCLES: 
1994 +       {
1995 +       arg0 = CALL_EXPR_ARG (exp, 0);
1996 +       op0 = expand_expr (arg0, NULL_RTX, VOIDmode, 0);
1997
1998 +       if (TARGET_ARCH_AP)
1999 +         error (" __builtin_avr32_delay_cycles() not supported for \'%s\' architecture.", avr32_arch_name);
2000 +       if (!CONSTANT_P (op0))
2001 +        error ("Parameter 1 to __builtin_avr32_delay_cycles() should be an integer.");
2002 +       emit_insn (gen_delay_cycles (op0));
2003 +       return 0;
2004
2005 +       }       
2006 +
2007 +    }
2008 +
2009 +  for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
2010 +    if (d->code == fcode)
2011 +      return avr32_expand_binop_builtin (d->icode, exp, target);
2012 +
2013 +
2014 +  /* @@@ Should really do something sensible here.  */
2015 +  return NULL_RTX;
2016 +}
2017 +
2018 +
2019 +/* Handle an "interrupt" or "isr" attribute;
2020 +   arguments as in struct attribute_spec.handler.  */
2021 +static tree
2022 +avr32_handle_isr_attribute (tree * node, tree name, tree args,
2023 +                           int flags, bool * no_add_attrs)
2024 +{
2025 +  if (DECL_P (*node))
2026 +    {
2027 +      if (TREE_CODE (*node) != FUNCTION_DECL)
2028 +       {
2029 +         warning (OPT_Wattributes,"`%s' attribute only applies to functions",
2030 +                  IDENTIFIER_POINTER (name));
2031 +         *no_add_attrs = true;
2032 +       }
2033 +      /* FIXME: the argument if any is checked for type attributes; should it
2034 +         be checked for decl ones? */
2035 +    }
2036 +  else
2037 +    {
2038 +      if (TREE_CODE (*node) == FUNCTION_TYPE
2039 +         || TREE_CODE (*node) == METHOD_TYPE)
2040 +       {
2041 +         if (avr32_isr_value (args) == AVR32_FT_UNKNOWN)
2042 +           {
2043 +             warning (OPT_Wattributes,"`%s' attribute ignored", IDENTIFIER_POINTER (name));
2044 +             *no_add_attrs = true;
2045 +           }
2046 +       }
2047 +      else if (TREE_CODE (*node) == POINTER_TYPE
2048 +              && (TREE_CODE (TREE_TYPE (*node)) == FUNCTION_TYPE
2049 +                  || TREE_CODE (TREE_TYPE (*node)) == METHOD_TYPE)
2050 +              && avr32_isr_value (args) != AVR32_FT_UNKNOWN)
2051 +       {
2052 +         *node = build_variant_type_copy (*node);
2053 +         TREE_TYPE (*node) = build_type_attribute_variant
2054 +           (TREE_TYPE (*node),
2055 +            tree_cons (name, args, TYPE_ATTRIBUTES (TREE_TYPE (*node))));
2056 +         *no_add_attrs = true;
2057 +       }
2058 +      else
2059 +       {
2060 +         /* Possibly pass this attribute on from the type to a decl.  */
2061 +         if (flags & ((int) ATTR_FLAG_DECL_NEXT
2062 +                      | (int) ATTR_FLAG_FUNCTION_NEXT
2063 +                      | (int) ATTR_FLAG_ARRAY_NEXT))
2064 +           {
2065 +             *no_add_attrs = true;
2066 +             return tree_cons (name, args, NULL_TREE);
2067 +           }
2068 +         else
2069 +           {
2070 +             warning (OPT_Wattributes,"`%s' attribute ignored", IDENTIFIER_POINTER (name));
2071 +           }
2072 +       }
2073 +    }
2074 +
2075 +  return NULL_TREE;
2076 +}
2077 +
2078 +
2079 +/* Handle an attribute requiring a FUNCTION_DECL;
2080 +   arguments as in struct attribute_spec.handler.  */
2081 +static tree
2082 +avr32_handle_fndecl_attribute (tree * node, tree name,
2083 +                              tree args,
2084 +                              int flags ATTRIBUTE_UNUSED,
2085 +                              bool * no_add_attrs)
2086 +{
2087 +  if (TREE_CODE (*node) != FUNCTION_DECL)
2088 +    {
2089 +      warning (OPT_Wattributes,"%qs attribute only applies to functions",
2090 +              IDENTIFIER_POINTER (name));
2091 +      *no_add_attrs = true;
2092 +      return NULL_TREE;
2093 +    }
2094 +
2095 +  fndecl_attribute_args = args;
2096 +  if (args == NULL_TREE)
2097 +         return NULL_TREE;
2098 +
2099 +  tree value = TREE_VALUE (args);
2100 +  if (TREE_CODE (value) != INTEGER_CST)
2101 +    {
2102 +      warning (OPT_Wattributes,
2103 +              "argument of %qs attribute is not an integer constant",
2104 +              IDENTIFIER_POINTER (name));
2105 +      *no_add_attrs = true;
2106 +    }
2107 +
2108 +  return NULL_TREE;
2109 +}
2110 +
2111 +
2112 +/* Handle an acall attribute;
2113 +   arguments as in struct attribute_spec.handler.  */
2114 +
2115 +static tree
2116 +avr32_handle_acall_attribute (tree * node, tree name,
2117 +                             tree args ATTRIBUTE_UNUSED,
2118 +                             int flags ATTRIBUTE_UNUSED, bool * no_add_attrs)
2119 +{
2120 +  if (TREE_CODE (*node) == FUNCTION_TYPE || TREE_CODE (*node) == METHOD_TYPE)
2121 +    {
2122 +      warning (OPT_Wattributes,"`%s' attribute not yet supported...",
2123 +              IDENTIFIER_POINTER (name));
2124 +      *no_add_attrs = true;
2125 +      return NULL_TREE;
2126 +    }
2127 +
2128 +  warning (OPT_Wattributes,"`%s' attribute only applies to functions",
2129 +          IDENTIFIER_POINTER (name));
2130 +  *no_add_attrs = true;
2131 +  return NULL_TREE;
2132 +}
2133 +
2134 +
2135 +bool
2136 +avr32_flashvault_call(tree decl)
2137 +{
2138 +  tree attributes;
2139 +  tree fv_attribute;
2140 +  tree vector_tree;
2141 +  unsigned int vector;
2142 +
2143 +  if (decl && TREE_CODE (decl) == FUNCTION_DECL) 
2144 +    {
2145 +      attributes = DECL_ATTRIBUTES(decl);
2146 +      fv_attribute = lookup_attribute ("flashvault", attributes);
2147 +      if (fv_attribute != NULL_TREE)
2148 +        {
2149 +          /* Get attribute parameter, for the function vector number. */
2150 +          /* 
2151 +          There is probably an easier, standard way to retrieve the
2152 +          attribute parameter which needs to be done here.
2153 +          */
2154 +          vector_tree = TREE_VALUE(fv_attribute);
2155 +          if (vector_tree != NULL_TREE)
2156 +            {
2157 +              vector = (unsigned int)TREE_INT_CST_LOW(TREE_VALUE(vector_tree));
2158 +              fprintf (asm_out_file,
2159 +                       "\tmov\tr8, lo(%i)\t# Load vector number for sscall.\n",
2160 +                       vector);
2161 +            }
2162 +
2163 +          fprintf (asm_out_file,
2164 +                   "\tsscall\t# Secure system call.\n");
2165 +
2166 +          return true;
2167 +        }
2168 +    }
2169 +  
2170 +  return false;
2171 +}
2172 +
2173 +
2174 +static bool has_attribute_p (tree decl, const char *name)
2175 +{
2176 +  if (decl && TREE_CODE (decl) == FUNCTION_DECL) 
2177 +    {
2178 +      return (lookup_attribute (name, DECL_ATTRIBUTES(decl)) != NULL_TREE);
2179 +    }
2180 +  return NULL_TREE;    
2181 +}
2182 +
2183 +
2184 +/* Return 0 if the attributes for two types are incompatible, 1 if they
2185 +   are compatible, and 2 if they are nearly compatible (which causes a
2186 +   warning to be generated).  */
2187 +static int
2188 +avr32_comp_type_attributes (tree type1, tree type2)
2189 +{
2190 +  bool acall1, acall2, isr1, isr2, naked1, naked2, fv1, fv2, fvimpl1, fvimpl2;
2191 +
2192 +  /* Check for mismatch of non-default calling convention.  */
2193 +  if (TREE_CODE (type1) != FUNCTION_TYPE)
2194 +    return 1;
2195 +
2196 +  /* Check for mismatched call attributes.  */
2197 +  acall1 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type1)) != NULL;
2198 +  acall2 = lookup_attribute ("acall", TYPE_ATTRIBUTES (type2)) != NULL;
2199 +  naked1 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type1)) != NULL;
2200 +  naked2 = lookup_attribute ("naked", TYPE_ATTRIBUTES (type2)) != NULL;
2201 +  fv1 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type1)) != NULL;
2202 +  fv2 = lookup_attribute ("flashvault", TYPE_ATTRIBUTES (type2)) != NULL;
2203 +  fvimpl1 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type1)) != NULL;
2204 +  fvimpl2 = lookup_attribute ("flashvault_impl", TYPE_ATTRIBUTES (type2)) != NULL;
2205 +  isr1 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type1)) != NULL;
2206 +  if (!isr1)
2207 +    isr1 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type1)) != NULL;
2208 +
2209 +  isr2 = lookup_attribute ("isr", TYPE_ATTRIBUTES (type2)) != NULL;
2210 +  if (!isr2)
2211 +    isr2 = lookup_attribute ("interrupt", TYPE_ATTRIBUTES (type2)) != NULL;
2212 +
2213 +  if ((acall1 && isr2)
2214 +      || (acall2 && isr1)
2215 +      || (naked1 && isr2)
2216 +      || (naked2 && isr1)
2217 +      || (fv1 && isr2)
2218 +      || (fv2 && isr1)
2219 +      || (fvimpl1 && isr2)
2220 +      || (fvimpl2 && isr1)
2221 +      || (fv1 && fvimpl2)
2222 +      || (fv2 && fvimpl1)
2223 +      )
2224 +    return 0;
2225 +
2226 +  return 1;
2227 +}
2228 +
2229 +
2230 +/* Computes the type of the current function.  */
2231 +static unsigned long
2232 +avr32_compute_func_type (void)
2233 +{
2234 +  unsigned long type = AVR32_FT_UNKNOWN;
2235 +  tree a;
2236 +  tree attr;
2237 +
2238 +  if (TREE_CODE (current_function_decl) != FUNCTION_DECL)
2239 +    abort ();
2240 +
2241 +  /* Decide if the current function is volatile.  Such functions never
2242 +     return, and many memory cycles can be saved by not storing register
2243 +     values that will never be needed again.  This optimization was added to
2244 +     speed up context switching in a kernel application.  */
2245 +  if (optimize > 0
2246 +      && TREE_NOTHROW (current_function_decl)
2247 +      && TREE_THIS_VOLATILE (current_function_decl))
2248 +    type |= AVR32_FT_VOLATILE;
2249 +
2250 +  if (cfun->static_chain_decl != NULL)
2251 +    type |= AVR32_FT_NESTED;
2252 +
2253 +  attr = DECL_ATTRIBUTES (current_function_decl);
2254 +
2255 +  a = lookup_attribute ("isr", attr);
2256 +  if (a == NULL_TREE)
2257 +    a = lookup_attribute ("interrupt", attr);
2258 +
2259 +  if (a == NULL_TREE)
2260 +    type |= AVR32_FT_NORMAL;
2261 +  else
2262 +    type |= avr32_isr_value (TREE_VALUE (a));
2263 +
2264 +
2265 +  a = lookup_attribute ("acall", attr);
2266 +  if (a != NULL_TREE)
2267 +    type |= AVR32_FT_ACALL;
2268 +
2269 +  a = lookup_attribute ("naked", attr);
2270 +  if (a != NULL_TREE)
2271 +    type |= AVR32_FT_NAKED;
2272 +
2273 +  a = lookup_attribute ("flashvault", attr);
2274 +  if (a != NULL_TREE)
2275 +    type |= AVR32_FT_FLASHVAULT;
2276 +
2277 +  a = lookup_attribute ("flashvault_impl", attr);
2278 +  if (a != NULL_TREE)
2279 +    type |= AVR32_FT_FLASHVAULT_IMPL;
2280 +
2281 +  return type;
2282 +}
2283 +
2284 +
2285 +/* Returns the type of the current function.  */
2286 +static unsigned long
2287 +avr32_current_func_type (void)
2288 +{
2289 +  if (AVR32_FUNC_TYPE (cfun->machine->func_type) == AVR32_FT_UNKNOWN)
2290 +    cfun->machine->func_type = avr32_compute_func_type ();
2291 +
2292 +  return cfun->machine->func_type;
2293 +}
2294 +
2295 +
2296 +/*
2297 +This target hook should return true if we should not pass type solely
2298 +in registers. The file expr.h defines a definition that is usually appropriate,
2299 +refer to expr.h for additional documentation.
2300 +*/
2301 +bool
2302 +avr32_must_pass_in_stack (enum machine_mode mode ATTRIBUTE_UNUSED, tree type)
2303 +{
2304 +  if (type && AGGREGATE_TYPE_P (type)
2305 +      /* If the alignment is less than the size then pass in the struct on
2306 +         the stack. */
2307 +      && ((unsigned int) TYPE_ALIGN_UNIT (type) <
2308 +         (unsigned int) int_size_in_bytes (type))
2309 +      /* If we support unaligned word accesses then structs of size 4 and 8
2310 +         can have any alignment and still be passed in registers. */
2311 +      && !(TARGET_UNALIGNED_WORD
2312 +          && (int_size_in_bytes (type) == 4
2313 +              || int_size_in_bytes (type) == 8))
2314 +      /* Double word structs need only a word alignment. */
2315 +      && !(int_size_in_bytes (type) == 8 && TYPE_ALIGN_UNIT (type) >= 4))
2316 +    return true;
2317 +
2318 +  if (type && AGGREGATE_TYPE_P (type)
2319 +      /* Structs of size 3,5,6,7 are always passed in registers. */
2320 +      && (int_size_in_bytes (type) == 3
2321 +         || int_size_in_bytes (type) == 5
2322 +         || int_size_in_bytes (type) == 6 || int_size_in_bytes (type) == 7))
2323 +    return true;
2324 +
2325 +
2326 +  return (type && TREE_ADDRESSABLE (type));
2327 +}
2328 +
2329 +
2330 +bool
2331 +avr32_strict_argument_naming (CUMULATIVE_ARGS * ca ATTRIBUTE_UNUSED)
2332 +{
2333 +  return true;
2334 +}
2335 +
2336 +
2337 +/*
2338 +   This target hook should return true if an argument at the position indicated
2339 +   by cum should be passed by reference. This predicate is queried after target
2340 +   independent reasons for being passed by reference, such as TREE_ADDRESSABLE (type).
2341 +
2342 +   If the hook returns true, a copy of that argument is made in memory and a
2343 +   pointer to the argument is passed instead of the argument itself. The pointer
2344 +   is passed in whatever way is appropriate for passing a pointer to that type.
2345 +*/
2346 +bool
2347 +avr32_pass_by_reference (CUMULATIVE_ARGS * cum ATTRIBUTE_UNUSED,
2348 +                        enum machine_mode mode ATTRIBUTE_UNUSED,
2349 +                        tree type, bool named ATTRIBUTE_UNUSED)
2350 +{
2351 +  return (type && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST));
2352 +}
2353 +
2354 +
2355 +static int
2356 +avr32_arg_partial_bytes (CUMULATIVE_ARGS * pcum ATTRIBUTE_UNUSED,
2357 +                        enum machine_mode mode ATTRIBUTE_UNUSED,
2358 +                        tree type ATTRIBUTE_UNUSED,
2359 +                        bool named ATTRIBUTE_UNUSED)
2360 +{
2361 +  return 0;
2362 +}
2363 +
2364 +
2365 +struct gcc_target targetm = TARGET_INITIALIZER;
2366 +
2367 +/*
2368 +  Table used to convert from register number in the assembler instructions and
2369 +  the register numbers used in gcc.
2370 +*/
2371 +const int avr32_function_arg_reglist[] = {
2372 +  INTERNAL_REGNUM (12),
2373 +  INTERNAL_REGNUM (11),
2374 +  INTERNAL_REGNUM (10),
2375 +  INTERNAL_REGNUM (9),
2376 +  INTERNAL_REGNUM (8)
2377 +};
2378 +
2379 +
2380 +rtx avr32_compare_op0 = NULL_RTX;
2381 +rtx avr32_compare_op1 = NULL_RTX;
2382 +rtx avr32_compare_operator = NULL_RTX;
2383 +rtx avr32_acc_cache = NULL_RTX;
2384 +/* type of branch to use */
2385 +enum avr32_cmp_type avr32_branch_type;
2386 +
2387 +
2388 +/*
2389 +  Returns nonzero if it is allowed to store a value of mode mode in hard
2390 +  register number regno.
2391 +*/
2392 +int
2393 +avr32_hard_regno_mode_ok (int regnr, enum machine_mode mode)
2394 +{
2395 +  switch (mode)
2396 +    {
2397 +      case DImode:             /* long long */
2398 +      case DFmode:             /* double */
2399 +      case SCmode:             /* __complex__ float */
2400 +      case CSImode:            /* __complex__ int */
2401 +        if (regnr < 4)
2402 +         {             /* long long int not supported in r12, sp, lr or pc. */
2403 +           return 0;
2404 +         }
2405 +        else
2406 +         {
2407 +           /* long long int has to be referred in even registers. */
2408 +            if (regnr % 2)
2409 +             return 0;
2410 +           else
2411 +             return 1;
2412 +         }
2413 +      case CDImode:            /* __complex__ long long */
2414 +      case DCmode:             /* __complex__ double */
2415 +      case TImode:             /* 16 bytes */
2416 +        if (regnr < 7)
2417 +         return 0;
2418 +        else if (regnr % 2)
2419 +         return 0;
2420 +        else
2421 +         return 1;
2422 +      default:
2423 +        return 1;
2424 +    }
2425 +}
2426 +
2427 +
2428 +int
2429 +avr32_rnd_operands (rtx add, rtx shift)
2430 +{
2431 +  if (GET_CODE (shift) == CONST_INT &&
2432 +      GET_CODE (add) == CONST_INT && INTVAL (shift) > 0)
2433 +    {
2434 +      if ((1 << (INTVAL (shift) - 1)) == INTVAL (add))
2435 +       return TRUE;
2436 +    }
2437 +
2438 +  return FALSE;
2439 +}
2440 +
2441 +
2442 +int
2443 +avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c, const char *str)
2444 +{
2445 +  switch (c)
2446 +    {
2447 +    case 'K':
2448 +    case 'I':
2449 +      {
2450 +       HOST_WIDE_INT min_value = 0, max_value = 0;
2451 +       char size_str[3];
2452 +       int const_size;
2453 +
2454 +       size_str[0] = str[2];
2455 +       size_str[1] = str[3];
2456 +       size_str[2] = '\0';
2457 +       const_size = atoi (size_str);
2458 +
2459 +       if (TOUPPER (str[1]) == 'U')
2460 +         {
2461 +           min_value = 0;
2462 +           max_value = (1 << const_size) - 1;
2463 +         }
2464 +       else if (TOUPPER (str[1]) == 'S')
2465 +         {
2466 +           min_value = -(1 << (const_size - 1));
2467 +           max_value = (1 << (const_size - 1)) - 1;
2468 +         }
2469 +
2470 +       if (c == 'I')
2471 +         {
2472 +           value = -value;
2473 +         }
2474 +
2475 +       if (value >= min_value && value <= max_value)
2476 +         {
2477 +           return 1;
2478 +         }
2479 +       break;
2480 +      }
2481 +    case 'M':
2482 +      return avr32_mask_upper_bits_operand (GEN_INT (value), VOIDmode);
2483 +    case 'J':
2484 +      return avr32_hi16_immediate_operand (GEN_INT (value), VOIDmode);
2485 +    case 'O':
2486 +      return one_bit_set_operand (GEN_INT (value), VOIDmode);
2487 +    case 'N':
2488 +      return one_bit_cleared_operand (GEN_INT (value), VOIDmode);
2489 +    case 'L':
2490 +      /* The lower 16-bits are set. */
2491 +      return ((value & 0xffff) == 0xffff) ;
2492 +    }
2493 +
2494 +  return 0;
2495 +}
2496 +
2497 +
2498 +/* Compute mask of registers which needs saving upon function entry. */
2499 +static unsigned long
2500 +avr32_compute_save_reg_mask (int push)
2501 +{
2502 +  unsigned long func_type;
2503 +  unsigned int save_reg_mask = 0;
2504 +  unsigned int reg;
2505 +
2506 +  func_type = avr32_current_func_type ();
2507 +
2508 +  if (IS_INTERRUPT (func_type))
2509 +    {
2510 +      unsigned int max_reg = 12;
2511 +
2512 +      /* Get the banking scheme for the interrupt */
2513 +      switch (func_type)
2514 +       {
2515 +       case AVR32_FT_ISR_FULL:
2516 +         max_reg = 0;
2517 +         break;
2518 +       case AVR32_FT_ISR_HALF:
2519 +         max_reg = 7;
2520 +         break;
2521 +       case AVR32_FT_ISR_NONE:
2522 +         max_reg = 12;
2523 +         break;
2524 +       }
2525 +
2526 +      /* Interrupt functions must not corrupt any registers, even call
2527 +         clobbered ones.  If this is a leaf function we can just examine the
2528 +         registers used by the RTL, but otherwise we have to assume that
2529 +         whatever function is called might clobber anything, and so we have
2530 +         to save all the call-clobbered registers as well.  */
2531 +
2532 +      /* Need not push the registers r8-r12 for AVR32A architectures, as this
2533 +         is automatially done in hardware. We also do not have any shadow
2534 +         registers. */
2535 +      if (TARGET_UARCH_AVR32A)
2536 +       {
2537 +         max_reg = 7;
2538 +         func_type = AVR32_FT_ISR_NONE;
2539 +       }
2540 +
2541 +      /* All registers which are used and are not shadowed must be saved. */
2542 +      for (reg = 0; reg <= max_reg; reg++)
2543 +       if (df_regs_ever_live_p (INTERNAL_REGNUM (reg))
2544 +           || (!current_function_is_leaf
2545 +               && call_used_regs[INTERNAL_REGNUM (reg)]))
2546 +         save_reg_mask |= (1 << reg);
2547 +
2548 +      /* Check LR */
2549 +      if ((df_regs_ever_live_p (LR_REGNUM)
2550 +          || !current_function_is_leaf || frame_pointer_needed)
2551 +         /* Only non-shadowed register models */
2552 +         && (func_type == AVR32_FT_ISR_NONE))
2553 +       save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM));
2554 +
2555 +      /* Make sure that the GOT register is pushed. */
2556 +      if (max_reg >= ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM)
2557 +         && crtl->uses_pic_offset_table)
2558 +       save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM));
2559 +
2560 +    }
2561 +  else
2562 +    {
2563 +      int use_pushm = optimize_size;
2564 +
2565 +      /* In the normal case we only need to save those registers which are
2566 +         call saved and which are used by this function.  */
2567 +      for (reg = 0; reg <= 7; reg++)
2568 +       if (df_regs_ever_live_p (INTERNAL_REGNUM (reg))
2569 +           && !call_used_regs[INTERNAL_REGNUM (reg)])
2570 +         save_reg_mask |= (1 << reg);
2571 +
2572 +      /* Make sure that the GOT register is pushed. */
2573 +      if (crtl->uses_pic_offset_table)
2574 +       save_reg_mask |= (1 << ASM_REGNUM (PIC_OFFSET_TABLE_REGNUM));
2575 +
2576 +
2577 +      /* If we optimize for size and do not have anonymous arguments: use
2578 +         pushm/popm always. */
2579 +      if (use_pushm)
2580 +       {
2581 +         if ((save_reg_mask & (1 << 0))
2582 +             || (save_reg_mask & (1 << 1))
2583 +             || (save_reg_mask & (1 << 2)) || (save_reg_mask & (1 << 3)))
2584 +           save_reg_mask |= 0xf;
2585 +
2586 +         if ((save_reg_mask & (1 << 4))
2587 +             || (save_reg_mask & (1 << 5))
2588 +             || (save_reg_mask & (1 << 6)) || (save_reg_mask & (1 << 7)))
2589 +           save_reg_mask |= 0xf0;
2590 +
2591 +         if ((save_reg_mask & (1 << 8)) || (save_reg_mask & (1 << 9)))
2592 +           save_reg_mask |= 0x300;
2593 +       }
2594 +
2595 +
2596 +        /* Check LR */
2597 +        if ((df_regs_ever_live_p (LR_REGNUM)
2598 +        || !current_function_is_leaf
2599 +        || (optimize_size
2600 +        && save_reg_mask
2601 +        && !crtl->calls_eh_return)
2602 +          || frame_pointer_needed)
2603 +          && !IS_FLASHVAULT (func_type))
2604 +       {
2605 +         if (push
2606 +             /* Never pop LR into PC for functions which
2607 +                calls __builtin_eh_return, since we need to
2608 +                fix the SP after the restoring of the registers
2609 +                and before returning. */
2610 +             || crtl->calls_eh_return)
2611 +           {
2612 +             /* Push/Pop LR */
2613 +             save_reg_mask |= (1 << ASM_REGNUM (LR_REGNUM));
2614 +           }
2615 +         else
2616 +           {
2617 +             /* Pop PC */
2618 +             save_reg_mask |= (1 << ASM_REGNUM (PC_REGNUM));
2619 +           }
2620 +       }
2621 +    }
2622 +
2623 +
2624 +  /* Save registers so the exception handler can modify them.  */
2625 +  if (crtl->calls_eh_return)
2626 +    {
2627 +      unsigned int i;
2628 +
2629 +      for (i = 0;; i++)
2630 +       {
2631 +         reg = EH_RETURN_DATA_REGNO (i);
2632 +         if (reg == INVALID_REGNUM)
2633 +           break;
2634 +         save_reg_mask |= 1 << ASM_REGNUM (reg);
2635 +       }
2636 +    }
2637 +
2638 +  return save_reg_mask;
2639 +}
2640 +
2641 +
2642 +/* Compute total size in bytes of all saved registers. */
2643 +static int
2644 +avr32_get_reg_mask_size (int reg_mask)
2645 +{
2646 +  int reg, size;
2647 +  size = 0;
2648 +
2649 +  for (reg = 0; reg <= 15; reg++)
2650 +    if (reg_mask & (1 << reg))
2651 +      size += 4;
2652 +
2653 +  return size;
2654 +}
2655 +
2656 +
2657 +/* Get a register from one of the registers which are saved onto the stack
2658 +  upon function entry. */
2659 +static int
2660 +avr32_get_saved_reg (int save_reg_mask)
2661 +{
2662 +  unsigned int reg;
2663 +
2664 +  /* Find the first register which is saved in the saved_reg_mask */
2665 +  for (reg = 0; reg <= 15; reg++)
2666 +    if (save_reg_mask & (1 << reg))
2667 +      return reg;
2668 +
2669 +  return -1;
2670 +}
2671 +
2672 +
2673 +/* Return 1 if it is possible to return using a single instruction. */
2674 +int
2675 +avr32_use_return_insn (int iscond)
2676 +{
2677 +  unsigned int func_type = avr32_current_func_type ();
2678 +  unsigned long saved_int_regs;
2679 +
2680 +  /* Never use a return instruction before reload has run. */
2681 +  if (!reload_completed)
2682 +    return 0;
2683 +
2684 +  /* Must adjust the stack for vararg functions. */
2685 +  if (crtl->args.info.uses_anonymous_args)
2686 +    return 0;
2687 +
2688 +  /* If there a stack adjstment.  */
2689 +  if (get_frame_size ())
2690 +    return 0;
2691 +
2692 +  saved_int_regs = avr32_compute_save_reg_mask (TRUE);
2693 +
2694 +  /* Conditional returns can not be performed in one instruction if we need
2695 +     to restore registers from the stack */
2696 +  if (iscond && saved_int_regs)
2697 +    return 0;
2698 +
2699 +  /* Conditional return can not be used for interrupt handlers. */
2700 +  if (iscond && IS_INTERRUPT (func_type))
2701 +    return 0;
2702 +
2703 +  /* For interrupt handlers which needs to pop registers */
2704 +  if (saved_int_regs && IS_INTERRUPT (func_type))
2705 +    return 0;
2706 +
2707 +
2708 +  /* If there are saved registers but the LR isn't saved, then we need two
2709 +     instructions for the return.  */
2710 +  if (saved_int_regs && !(saved_int_regs & (1 << ASM_REGNUM (LR_REGNUM))))
2711 +    return 0;
2712 +
2713 +
2714 +  return 1;
2715 +}
2716 +
2717 +
2718 +/* Generate some function prologue info in the assembly file. */
2719 +void
2720 +avr32_target_asm_function_prologue (FILE * f, HOST_WIDE_INT frame_size)
2721 +{
2722 +  unsigned long func_type = avr32_current_func_type ();
2723 +
2724 +  if (IS_NAKED (func_type))
2725 +    fprintf (f,
2726 +      "\t# Function is naked: Prologue and epilogue provided by programmer\n");
2727 +
2728 +  if (IS_FLASHVAULT (func_type))
2729 +  {
2730 +    fprintf(f, 
2731 +      "\t.ident \"flashvault\"\n\t# Function is defined with flashvault attribute.\n");
2732 +  }
2733 +
2734 +  if (IS_FLASHVAULT_IMPL (func_type))
2735 +  {
2736 +    fprintf(f, 
2737 +      "\t.ident \"flashvault\"\n\t# Function is defined with flashvault_impl attribute.\n");
2738 +
2739 +    /* Save information on flashvault function declaration. */
2740 +    tree fv_attribute = lookup_attribute ("flashvault_impl", DECL_ATTRIBUTES(current_function_decl));
2741 +    if (fv_attribute != NULL_TREE)
2742 +      {
2743 +        tree vector_tree = TREE_VALUE(fv_attribute);
2744 +        if (vector_tree != NULL_TREE)
2745 +          {
2746 +            unsigned int vector_num;
2747 +            const char * name;
2748 +
2749 +            vector_num = (unsigned int) TREE_INT_CST_LOW (TREE_VALUE (vector_tree));
2750 +
2751 +            name = XSTR  (XEXP (DECL_RTL (current_function_decl), 0), 0);
2752 +
2753 +            flashvault_decl_list_add (vector_num, name);
2754 +          }
2755 +      }
2756 +  }
2757 +
2758 +  if (IS_INTERRUPT (func_type))
2759 +    {
2760 +      switch (func_type)
2761 +        {
2762 +          case AVR32_FT_ISR_FULL:
2763 +            fprintf (f,
2764 +                     "\t# Interrupt Function: Fully shadowed register file\n");
2765 +            break;
2766 +          case AVR32_FT_ISR_HALF:
2767 +            fprintf (f,
2768 +                     "\t# Interrupt Function: Half shadowed register file\n");
2769 +            break;
2770 +          default:
2771 +          case AVR32_FT_ISR_NONE:
2772 +            fprintf (f, "\t# Interrupt Function: No shadowed register file\n");
2773 +            break;
2774 +        }
2775 +    }
2776 +
2777 +
2778 +  fprintf (f, "\t# args = %i, frame = %li, pretend = %i\n",
2779 +           crtl->args.size, frame_size,
2780 +           crtl->args.pretend_args_size);
2781 +
2782 +  fprintf (f, "\t# frame_needed = %i, leaf_function = %i\n",
2783 +           frame_pointer_needed, current_function_is_leaf);
2784 +
2785 +  fprintf (f, "\t# uses_anonymous_args = %i\n",
2786 +           crtl->args.info.uses_anonymous_args);
2787 +
2788 +  if (crtl->calls_eh_return)
2789 +    fprintf (f, "\t# Calls __builtin_eh_return.\n");
2790 +
2791 +}
2792 +
2793 +
2794 +/* Generate and emit an insn that we will recognize as a pushm or stm.
2795 +   Unfortunately, since this insn does not reflect very well the actual
2796 +   semantics of the operation, we need to annotate the insn for the benefit
2797 +   of DWARF2 frame unwind information.  */
2798 +
2799 +int avr32_convert_to_reglist16 (int reglist8_vect);
2800 +
2801 +static rtx
2802 +emit_multi_reg_push (int reglist, int usePUSHM)
2803 +{
2804 +  rtx insn;
2805 +  rtx dwarf;
2806 +  rtx tmp;
2807 +  rtx reg;
2808 +  int i;
2809 +  int nr_regs;
2810 +  int index = 0;
2811 +
2812 +  if (usePUSHM)
2813 +    {
2814 +      insn = emit_insn (gen_pushm (gen_rtx_CONST_INT (SImode, reglist)));
2815 +      reglist = avr32_convert_to_reglist16 (reglist);
2816 +    }
2817 +  else
2818 +    {
2819 +      insn = emit_insn (gen_stm (stack_pointer_rtx,
2820 +                                gen_rtx_CONST_INT (SImode, reglist),
2821 +                                gen_rtx_CONST_INT (SImode, 1)));
2822 +    }
2823 +
2824 +  nr_regs = avr32_get_reg_mask_size (reglist) / 4;
2825 +  dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (nr_regs + 1));
2826 +
2827 +  for (i = 15; i >= 0; i--)
2828 +    {
2829 +      if (reglist & (1 << i))
2830 +       {
2831 +         reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (i));
2832 +         tmp = gen_rtx_SET (VOIDmode,
2833 +                            gen_rtx_MEM (SImode,
2834 +                                         plus_constant (stack_pointer_rtx,
2835 +                                                        4 * index)), reg);
2836 +         RTX_FRAME_RELATED_P (tmp) = 1;
2837 +         XVECEXP (dwarf, 0, 1 + index++) = tmp;
2838 +       }
2839 +    }
2840 +
2841 +  tmp = gen_rtx_SET (SImode,
2842 +                    stack_pointer_rtx,
2843 +                    gen_rtx_PLUS (SImode,
2844 +                                  stack_pointer_rtx,
2845 +                                  GEN_INT (-4 * nr_regs)));
2846 +  RTX_FRAME_RELATED_P (tmp) = 1;
2847 +  XVECEXP (dwarf, 0, 0) = tmp;
2848 +  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR, dwarf,
2849 +                                       REG_NOTES (insn));
2850 +  return insn;
2851 +}
2852 +
2853 +rtx
2854 +avr32_gen_load_multiple (rtx * regs, int count, rtx from,
2855 +                        int write_back, int in_struct_p, int scalar_p)
2856 +{
2857 +
2858 +  rtx result;
2859 +  int i = 0, j;
2860 +
2861 +  result =
2862 +    gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + (write_back ? 1 : 0)));
2863 +
2864 +  if (write_back)
2865 +    {
2866 +      XVECEXP (result, 0, 0)
2867 +       = gen_rtx_SET (GET_MODE (from), from,
2868 +                      plus_constant (from, count * 4));
2869 +      i = 1;
2870 +      count++;
2871 +    }
2872 +
2873 +
2874 +  for (j = 0; i < count; i++, j++)
2875 +    {
2876 +      rtx unspec;
2877 +      rtx mem = gen_rtx_MEM (SImode, plus_constant (from, j * 4));
2878 +      MEM_IN_STRUCT_P (mem) = in_struct_p;
2879 +      MEM_SCALAR_P (mem) = scalar_p;
2880 +      unspec = gen_rtx_UNSPEC (VOIDmode, gen_rtvec (1, mem), UNSPEC_LDM);
2881 +      XVECEXP (result, 0, i) = gen_rtx_SET (VOIDmode, regs[j], unspec);
2882 +    }
2883 +
2884 +  return result;
2885 +}
2886 +
2887 +
2888 +rtx
2889 +avr32_gen_store_multiple (rtx * regs, int count, rtx to,
2890 +                         int in_struct_p, int scalar_p)
2891 +{
2892 +  rtx result;
2893 +  int i = 0, j;
2894 +
2895 +  result = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2896 +
2897 +  for (j = 0; i < count; i++, j++)
2898 +    {
2899 +      rtx mem = gen_rtx_MEM (SImode, plus_constant (to, j * 4));
2900 +      MEM_IN_STRUCT_P (mem) = in_struct_p;
2901 +      MEM_SCALAR_P (mem) = scalar_p;
2902 +      XVECEXP (result, 0, i)
2903 +       = gen_rtx_SET (VOIDmode, mem,
2904 +                      gen_rtx_UNSPEC (VOIDmode,
2905 +                                      gen_rtvec (1, regs[j]),
2906 +                                      UNSPEC_STORE_MULTIPLE));
2907 +    }
2908 +
2909 +  return result;
2910 +}
2911 +
2912 +
2913 +/* Move a block of memory if it is word aligned or we support unaligned
2914 +   word memory accesses. The size must be maximum 64 bytes. */
2915 +int
2916 +avr32_gen_movmemsi (rtx * operands)
2917 +{
2918 +  HOST_WIDE_INT bytes_to_go;
2919 +  rtx src, dst;
2920 +  rtx st_src, st_dst;
2921 +  int src_offset = 0, dst_offset = 0;
2922 +  int block_size;
2923 +  int dst_in_struct_p, src_in_struct_p;
2924 +  int dst_scalar_p, src_scalar_p;
2925 +  int unaligned;
2926 +
2927 +  if (GET_CODE (operands[2]) != CONST_INT
2928 +      || GET_CODE (operands[3]) != CONST_INT
2929 +      || INTVAL (operands[2]) > 64
2930 +      || ((INTVAL (operands[3]) & 3) && !TARGET_UNALIGNED_WORD))
2931 +    return 0;
2932 +
2933 +  unaligned = (INTVAL (operands[3]) & 3) != 0;
2934 +
2935 +  block_size = 4;
2936 +
2937 +  st_dst = XEXP (operands[0], 0);
2938 +  st_src = XEXP (operands[1], 0);
2939 +
2940 +  dst_in_struct_p = MEM_IN_STRUCT_P (operands[0]);
2941 +  dst_scalar_p = MEM_SCALAR_P (operands[0]);
2942 +  src_in_struct_p = MEM_IN_STRUCT_P (operands[1]);
2943 +  src_scalar_p = MEM_SCALAR_P (operands[1]);
2944 +
2945 +  dst = copy_to_mode_reg (SImode, st_dst);
2946 +  src = copy_to_mode_reg (SImode, st_src);
2947 +
2948 +  bytes_to_go = INTVAL (operands[2]);
2949 +
2950 +  while (bytes_to_go)
2951 +    {
2952 +      enum machine_mode move_mode;
2953 +      /* (Seems to be a problem with reloads for the movti pattern so this is
2954 +         disabled until that problem is resolved)
2955 +         UPDATE: Problem seems to be solved now.... */
2956 +      if (bytes_to_go >= GET_MODE_SIZE (TImode) && !unaligned
2957 +         /* Do not emit ldm/stm for UC3 as ld.d/st.d is more optimal. */
2958 +         && !TARGET_ARCH_UC)
2959 +       move_mode = TImode;
2960 +      else if ((bytes_to_go >= GET_MODE_SIZE (DImode)) && !unaligned)
2961 +       move_mode = DImode;
2962 +      else if (bytes_to_go >= GET_MODE_SIZE (SImode))
2963 +       move_mode = SImode;
2964 +      else
2965 +       move_mode = QImode;
2966 +
2967 +      {
2968 +        rtx src_mem;
2969 +       rtx dst_mem = gen_rtx_MEM (move_mode,
2970 +                                  gen_rtx_PLUS (SImode, dst,
2971 +                                                GEN_INT (dst_offset)));
2972 +        dst_offset += GET_MODE_SIZE (move_mode);
2973 +        if ( 0 /* This causes an error in GCC. Think there is
2974 +                  something wrong in the gcse pass which causes REQ_EQUIV notes
2975 +                  to be wrong so disabling it for now. */
2976 +             && move_mode == TImode
2977 +             && INTVAL (operands[2]) > GET_MODE_SIZE (TImode) )
2978 +          {
2979 +            src_mem = gen_rtx_MEM (move_mode,
2980 +                                  gen_rtx_POST_INC (SImode, src));
2981 +          }
2982 +        else
2983 +          {
2984 +            src_mem = gen_rtx_MEM (move_mode,
2985 +                                  gen_rtx_PLUS (SImode, src,
2986 +                                                GEN_INT (src_offset)));
2987 +            src_offset += GET_MODE_SIZE (move_mode);
2988 +          }
2989 +
2990 +       bytes_to_go -= GET_MODE_SIZE (move_mode);
2991 +
2992 +       MEM_IN_STRUCT_P (dst_mem) = dst_in_struct_p;
2993 +       MEM_SCALAR_P (dst_mem) = dst_scalar_p;
2994 +
2995 +       MEM_IN_STRUCT_P (src_mem) = src_in_struct_p;
2996 +       MEM_SCALAR_P (src_mem) = src_scalar_p;
2997 +       emit_move_insn (dst_mem, src_mem);
2998 +
2999 +      }
3000 +    }
3001 +
3002 +  return 1;
3003 +}
3004 +
3005 +
3006 +/* Expand the prologue instruction. */
3007 +void
3008 +avr32_expand_prologue (void)
3009 +{
3010 +  rtx insn, dwarf;
3011 +  unsigned long saved_reg_mask;
3012 +  int reglist8 = 0;
3013 +
3014 +  /* Naked functions do not have a prologue. */
3015 +  if (IS_NAKED (avr32_current_func_type ()))
3016 +    return;
3017 +
3018 +  saved_reg_mask = avr32_compute_save_reg_mask (TRUE);
3019 +
3020 +  if (saved_reg_mask)
3021 +    {
3022 +      /* Must push used registers. */
3023 +
3024 +      /* Should we use POPM or LDM? */
3025 +      int usePUSHM = TRUE;
3026 +      reglist8 = 0;
3027 +      if (((saved_reg_mask & (1 << 0)) ||
3028 +          (saved_reg_mask & (1 << 1)) ||
3029 +          (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3))))
3030 +       {
3031 +         /* One of R0-R3 should at least be pushed. */
3032 +         if (((saved_reg_mask & (1 << 0)) &&
3033 +              (saved_reg_mask & (1 << 1)) &&
3034 +              (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3))))
3035 +           {
3036 +             /* All should be pushed. */
3037 +             reglist8 |= 0x01;
3038 +           }
3039 +         else
3040 +           {
3041 +             usePUSHM = FALSE;
3042 +           }
3043 +       }
3044 +
3045 +      if (((saved_reg_mask & (1 << 4)) ||
3046 +          (saved_reg_mask & (1 << 5)) ||
3047 +          (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7))))
3048 +       {
3049 +         /* One of R4-R7 should at least be pushed */
3050 +         if (((saved_reg_mask & (1 << 4)) &&
3051 +              (saved_reg_mask & (1 << 5)) &&
3052 +              (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7))))
3053 +           {
3054 +             if (usePUSHM)
3055 +               /* All should be pushed */
3056 +               reglist8 |= 0x02;
3057 +           }
3058 +         else
3059 +           {
3060 +             usePUSHM = FALSE;
3061 +           }
3062 +       }
3063 +
3064 +      if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9))))
3065 +       {
3066 +         /* One of R8-R9 should at least be pushed. */
3067 +         if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9))))
3068 +           {
3069 +             if (usePUSHM)
3070 +               /* All should be pushed. */
3071 +               reglist8 |= 0x04;
3072 +           }
3073 +         else
3074 +           {
3075 +             usePUSHM = FALSE;
3076 +           }
3077 +       }
3078 +
3079 +      if (saved_reg_mask & (1 << 10))
3080 +       reglist8 |= 0x08;
3081 +
3082 +      if (saved_reg_mask & (1 << 11))
3083 +       reglist8 |= 0x10;
3084 +
3085 +      if (saved_reg_mask & (1 << 12))
3086 +       reglist8 |= 0x20;
3087 +
3088 +      if ((saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM)))
3089 +           && !IS_FLASHVAULT (avr32_current_func_type ()))
3090 +       {
3091 +         /* Push LR */
3092 +         reglist8 |= 0x40;
3093 +       }
3094 +
3095 +      if (usePUSHM)
3096 +       {
3097 +         insn = emit_multi_reg_push (reglist8, TRUE);
3098 +       }
3099 +      else
3100 +       {
3101 +         insn = emit_multi_reg_push (saved_reg_mask, FALSE);
3102 +       }
3103 +      RTX_FRAME_RELATED_P (insn) = 1;
3104 +
3105 +      /* Prevent this instruction from being scheduled after any other
3106 +         instructions.  */
3107 +      emit_insn (gen_blockage ());
3108 +    }
3109 +
3110 +  /* Set frame pointer */
3111 +  if (frame_pointer_needed)
3112 +    {
3113 +      insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
3114 +      RTX_FRAME_RELATED_P (insn) = 1;
3115 +    }
3116 +
3117 +  if (get_frame_size () > 0)
3118 +    {
3119 +      if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks21"))
3120 +       {
3121 +         insn = emit_insn (gen_rtx_SET (SImode,
3122 +                                        stack_pointer_rtx,
3123 +                                        gen_rtx_PLUS (SImode,
3124 +                                                      stack_pointer_rtx,
3125 +                                                      gen_rtx_CONST_INT
3126 +                                                      (SImode,
3127 +                                                       -get_frame_size
3128 +                                                       ()))));
3129 +         RTX_FRAME_RELATED_P (insn) = 1;
3130 +       }
3131 +      else
3132 +       {
3133 +         /* Immediate is larger than k21 We must either check if we can use
3134 +            one of the pushed reegisters as temporary storage or we must
3135 +            make us a temp register by pushing a register to the stack. */
3136 +         rtx temp_reg, const_pool_entry, insn;
3137 +         if (saved_reg_mask)
3138 +           {
3139 +             temp_reg =
3140 +               gen_rtx_REG (SImode,
3141 +                            INTERNAL_REGNUM (avr32_get_saved_reg
3142 +                                             (saved_reg_mask)));
3143 +           }
3144 +         else
3145 +           {
3146 +             temp_reg = gen_rtx_REG (SImode, INTERNAL_REGNUM (7));
3147 +             emit_move_insn (gen_rtx_MEM
3148 +                             (SImode,
3149 +                              gen_rtx_PRE_DEC (SImode, stack_pointer_rtx)),
3150 +                             temp_reg);
3151 +           }
3152 +
3153 +         const_pool_entry =
3154 +           force_const_mem (SImode,
3155 +                            gen_rtx_CONST_INT (SImode, get_frame_size ()));
3156 +         emit_move_insn (temp_reg, const_pool_entry);
3157 +
3158 +         insn = emit_insn (gen_rtx_SET (SImode,
3159 +                                        stack_pointer_rtx,
3160 +                                        gen_rtx_MINUS (SImode,
3161 +                                                       stack_pointer_rtx,
3162 +                                                       temp_reg)));
3163 +
3164 +         dwarf = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
3165 +                              gen_rtx_PLUS (SImode, stack_pointer_rtx,
3166 +                                            GEN_INT (-get_frame_size ())));
3167 +         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
3168 +                                               dwarf, REG_NOTES (insn));
3169 +         RTX_FRAME_RELATED_P (insn) = 1;
3170 +
3171 +         if (!saved_reg_mask)
3172 +           {
3173 +             insn =
3174 +               emit_move_insn (temp_reg,
3175 +                               gen_rtx_MEM (SImode,
3176 +                                            gen_rtx_POST_INC (SImode,
3177 +                                                              gen_rtx_REG
3178 +                                                              (SImode,
3179 +                                                               13))));
3180 +           }
3181 +
3182 +         /* Mark the temp register as dead */
3183 +         REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, temp_reg,
3184 +                                               REG_NOTES (insn));
3185 +
3186 +
3187 +       }
3188 +
3189 +      /* Prevent the the stack adjustment to be scheduled after any
3190 +         instructions using the frame pointer.  */
3191 +      emit_insn (gen_blockage ());
3192 +    }
3193 +
3194 +  /* Load GOT */
3195 +  if (flag_pic)
3196 +    {
3197 +      avr32_load_pic_register ();
3198 +
3199 +      /* gcc does not know that load or call instructions might use the pic
3200 +         register so it might schedule these instructions before the loading
3201 +         of the pic register. To avoid this emit a barrier for now. TODO!
3202 +         Find out a better way to let gcc know which instructions might use
3203 +         the pic register. */
3204 +      emit_insn (gen_blockage ());
3205 +    }
3206 +  return;
3207 +}
3208 +
3209 +
3210 +void
3211 +avr32_set_return_address (rtx source, rtx scratch)
3212 +{
3213 +  rtx addr;
3214 +  unsigned long saved_regs;
3215 +
3216 +  saved_regs = avr32_compute_save_reg_mask (TRUE);
3217 +
3218 +  if (!(saved_regs & (1 << ASM_REGNUM (LR_REGNUM))))
3219 +    emit_move_insn (gen_rtx_REG (Pmode, LR_REGNUM), source);
3220 +  else
3221 +    {
3222 +      if (frame_pointer_needed)
3223 +       addr = gen_rtx_REG (Pmode, FRAME_POINTER_REGNUM);
3224 +      else
3225 +       if (avr32_const_ok_for_constraint_p (get_frame_size (), 'K', "Ks16"))
3226 +       {
3227 +         addr = plus_constant (stack_pointer_rtx, get_frame_size ());
3228 +       }
3229 +      else
3230 +       {
3231 +         emit_insn (gen_movsi (scratch, GEN_INT (get_frame_size ())));
3232 +         addr = scratch;
3233 +       }
3234 +      emit_move_insn (gen_rtx_MEM (Pmode, addr), source);
3235 +    }
3236 +}
3237 +
3238 +
3239 +/* Return the length of INSN.  LENGTH is the initial length computed by
3240 +   attributes in the machine-description file.  */
3241 +int
3242 +avr32_adjust_insn_length (rtx insn ATTRIBUTE_UNUSED,
3243 +                         int length ATTRIBUTE_UNUSED)
3244 +{
3245 +  return length;
3246 +}
3247 +
3248 +
3249 +void
3250 +avr32_output_return_instruction (int single_ret_inst ATTRIBUTE_UNUSED,
3251 +                                int iscond ATTRIBUTE_UNUSED,
3252 +                                rtx cond ATTRIBUTE_UNUSED, rtx r12_imm)
3253 +{
3254 +
3255 +  unsigned long saved_reg_mask;
3256 +  int insert_ret = TRUE;
3257 +  int reglist8 = 0;
3258 +  int stack_adjustment = get_frame_size ();
3259 +  unsigned int func_type = avr32_current_func_type ();
3260 +  FILE *f = asm_out_file;
3261 +
3262 +  /* Naked functions does not have an epilogue */
3263 +  if (IS_NAKED (func_type))
3264 +    return;
3265 +
3266 +  saved_reg_mask = avr32_compute_save_reg_mask (FALSE);
3267 +
3268 +  /* Reset frame pointer */
3269 +  if (stack_adjustment > 0)
3270 +    {
3271 +      if (avr32_const_ok_for_constraint_p (stack_adjustment, 'I', "Is21"))
3272 +       {
3273 +         fprintf (f, "\tsub\tsp, %i # Reset Frame Pointer\n",
3274 +                  -stack_adjustment);
3275 +       }
3276 +      else
3277 +       {
3278 +         /* TODO! Is it safe to use r8 as scratch?? */
3279 +         fprintf (f, "\tmov\tr8, lo(%i) # Reset Frame Pointer\n",
3280 +                  -stack_adjustment);
3281 +         fprintf (f, "\torh\tr8, hi(%i) # Reset Frame Pointer\n",
3282 +                  -stack_adjustment);
3283 +         fprintf (f, "\tadd\tsp, r8  # Reset Frame Pointer\n");
3284 +       }
3285 +    }
3286 +
3287 +  if (saved_reg_mask)
3288 +    {
3289 +      /* Must pop used registers */
3290 +
3291 +      /* Should we use POPM or LDM? */
3292 +      int usePOPM = TRUE;
3293 +      if (((saved_reg_mask & (1 << 0)) ||
3294 +          (saved_reg_mask & (1 << 1)) ||
3295 +          (saved_reg_mask & (1 << 2)) || (saved_reg_mask & (1 << 3))))
3296 +       {
3297 +         /* One of R0-R3 should at least be popped */
3298 +         if (((saved_reg_mask & (1 << 0)) &&
3299 +              (saved_reg_mask & (1 << 1)) &&
3300 +              (saved_reg_mask & (1 << 2)) && (saved_reg_mask & (1 << 3))))
3301 +           {
3302 +             /* All should be popped */
3303 +             reglist8 |= 0x01;
3304 +           }
3305 +         else
3306 +           {
3307 +             usePOPM = FALSE;
3308 +           }
3309 +       }
3310 +
3311 +      if (((saved_reg_mask & (1 << 4)) ||
3312 +          (saved_reg_mask & (1 << 5)) ||
3313 +          (saved_reg_mask & (1 << 6)) || (saved_reg_mask & (1 << 7))))
3314 +       {
3315 +         /* One of R0-R3 should at least be popped */
3316 +         if (((saved_reg_mask & (1 << 4)) &&
3317 +              (saved_reg_mask & (1 << 5)) &&
3318 +              (saved_reg_mask & (1 << 6)) && (saved_reg_mask & (1 << 7))))
3319 +           {
3320 +             if (usePOPM)
3321 +               /* All should be popped */
3322 +               reglist8 |= 0x02;
3323 +           }
3324 +         else
3325 +           {
3326 +             usePOPM = FALSE;
3327 +           }
3328 +       }
3329 +
3330 +      if (((saved_reg_mask & (1 << 8)) || (saved_reg_mask & (1 << 9))))
3331 +       {
3332 +         /* One of R8-R9 should at least be pushed */
3333 +         if (((saved_reg_mask & (1 << 8)) && (saved_reg_mask & (1 << 9))))
3334 +           {
3335 +             if (usePOPM)
3336 +               /* All should be pushed */
3337 +               reglist8 |= 0x04;
3338 +           }
3339 +         else
3340 +           {
3341 +             usePOPM = FALSE;
3342 +           }
3343 +       }
3344 +
3345 +      if (saved_reg_mask & (1 << 10))
3346 +       reglist8 |= 0x08;
3347 +
3348 +      if (saved_reg_mask & (1 << 11))
3349 +       reglist8 |= 0x10;
3350 +
3351 +      if (saved_reg_mask & (1 << 12))
3352 +       reglist8 |= 0x20;
3353 +
3354 +      if (saved_reg_mask & (1 << ASM_REGNUM (LR_REGNUM)))
3355 +       /* Pop LR */
3356 +       reglist8 |= 0x40;
3357 +
3358 +      if ((saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM))) 
3359 +           && !IS_FLASHVAULT_IMPL (func_type))
3360 +       /* Pop LR into PC. */
3361 +       reglist8 |= 0x80;
3362 +
3363 +      if (usePOPM)
3364 +       {
3365 +         char reglist[64];     /* 64 bytes should be enough... */
3366 +         avr32_make_reglist8 (reglist8, (char *) reglist);
3367 +
3368 +         if (reglist8 & 0x80)
3369 +           /* This instruction is also a return */
3370 +           insert_ret = FALSE;
3371 +
3372 +         if (r12_imm && !insert_ret)
3373 +           fprintf (f, "\tpopm\t%s, r12=%li\n", reglist, INTVAL (r12_imm));
3374 +         else
3375 +           fprintf (f, "\tpopm\t%s\n", reglist);
3376 +
3377 +       }
3378 +      else
3379 +       {
3380 +         char reglist[64];     /* 64 bytes should be enough... */
3381 +         avr32_make_reglist16 (saved_reg_mask, (char *) reglist);
3382 +         if (saved_reg_mask & (1 << ASM_REGNUM (PC_REGNUM)))
3383 +           /* This instruction is also a return */
3384 +           insert_ret = FALSE;
3385 +
3386 +         if (r12_imm && !insert_ret)
3387 +           fprintf (f, "\tldm\tsp++, %s, r12=%li\n", reglist,
3388 +                    INTVAL (r12_imm));
3389 +         else
3390 +           fprintf (f, "\tldm\tsp++, %s\n", reglist);
3391 +
3392 +       }
3393 +
3394 +    }
3395 +
3396 +  /* Stack adjustment for exception handler.  */
3397 +  if (crtl->calls_eh_return)
3398 +    fprintf (f, "\tadd\tsp, r%d\n", ASM_REGNUM (EH_RETURN_STACKADJ_REGNO));
3399 +
3400 +
3401 +  if (IS_INTERRUPT (func_type))
3402 +    {
3403 +      fprintf (f, "\trete\n");
3404 +    }
3405 +  else if (IS_FLASHVAULT (func_type))
3406 +    {
3407 +      /* Normal return from Secure System call, increment SS_RAR before
3408 +      returning. Use R8 as scratch. */
3409 +      fprintf (f,
3410 +               "\t# Normal return from sscall.\n"
3411 +               "\t# Increment SS_RAR before returning.\n"
3412 +               "\t# Use R8 as scratch.\n"
3413 +               "\tmfsr\tr8,  440\n"
3414 +               "\tsub\tr8,  -2\n"
3415 +               "\tmtsr\t440, r8\n"
3416 +               "\tretss\n");
3417 +    }
3418 +  else if (insert_ret)
3419 +    {
3420 +      if (r12_imm)
3421 +       fprintf (f, "\tretal\t%li\n", INTVAL (r12_imm));
3422 +      else
3423 +       fprintf (f, "\tretal\tr12\n");
3424 +    }
3425 +}
3426 +
3427 +void
3428 +avr32_make_reglist16 (int reglist16_vect, char *reglist16_string)
3429 +{
3430 +  int i;
3431 +  bool first_reg = true;
3432 +  /* Make sure reglist16_string is empty. */
3433 +  reglist16_string[0] = '\0';
3434 +
3435 +  for (i = 0; i < 16; ++i)
3436 +    {
3437 +      if (reglist16_vect & (1 << i))
3438 +       {
3439 +          first_reg == true ?  first_reg = false : strcat(reglist16_string,", ");
3440 +         strcat (reglist16_string, reg_names[INTERNAL_REGNUM (i)]);
3441 +       }
3442 +    }
3443 +}
3444 +
3445 +int
3446 +avr32_convert_to_reglist16 (int reglist8_vect)
3447 +{
3448 +  int reglist16_vect = 0;
3449 +  if (reglist8_vect & 0x1)
3450 +    reglist16_vect |= 0xF;
3451 +  if (reglist8_vect & 0x2)
3452 +    reglist16_vect |= 0xF0;
3453 +  if (reglist8_vect & 0x4)
3454 +    reglist16_vect |= 0x300;
3455 +  if (reglist8_vect & 0x8)
3456 +    reglist16_vect |= 0x400;
3457 +  if (reglist8_vect & 0x10)
3458 +    reglist16_vect |= 0x800;
3459 +  if (reglist8_vect & 0x20)
3460 +    reglist16_vect |= 0x1000;
3461 +  if (reglist8_vect & 0x40)
3462 +    reglist16_vect |= 0x4000;
3463 +  if (reglist8_vect & 0x80)
3464 +    reglist16_vect |= 0x8000;
3465 +
3466 +  return reglist16_vect;
3467 +}
3468 +
3469 +void
3470 +avr32_make_reglist8 (int reglist8_vect, char *reglist8_string)
3471 +{
3472 +  /* Make sure reglist8_string is empty. */
3473 +  reglist8_string[0] = '\0';
3474 +
3475 +  if (reglist8_vect & 0x1)
3476 +    strcpy (reglist8_string, "r0-r3");
3477 +  if (reglist8_vect & 0x2)
3478 +    strlen (reglist8_string) ? strcat (reglist8_string, ", r4-r7") :
3479 +      strcpy (reglist8_string, "r4-r7");
3480 +  if (reglist8_vect & 0x4)
3481 +    strlen (reglist8_string) ? strcat (reglist8_string, ", r8-r9") :
3482 +      strcpy (reglist8_string, "r8-r9");
3483 +  if (reglist8_vect & 0x8)
3484 +    strlen (reglist8_string) ? strcat (reglist8_string, ", r10") :
3485 +      strcpy (reglist8_string, "r10");
3486 +  if (reglist8_vect & 0x10)
3487 +    strlen (reglist8_string) ? strcat (reglist8_string, ", r11") :
3488 +      strcpy (reglist8_string, "r11");
3489 +  if (reglist8_vect & 0x20)
3490 +    strlen (reglist8_string) ? strcat (reglist8_string, ", r12") :
3491 +      strcpy (reglist8_string, "r12");
3492 +  if (reglist8_vect & 0x40)
3493 +    strlen (reglist8_string) ? strcat (reglist8_string, ", lr") :
3494 +      strcpy (reglist8_string, "lr");
3495 +  if (reglist8_vect & 0x80)
3496 +    strlen (reglist8_string) ? strcat (reglist8_string, ", pc") :
3497 +      strcpy (reglist8_string, "pc");
3498 +}
3499 +
3500 +
3501 +int
3502 +avr32_eh_return_data_regno (int n)
3503 +{
3504 +  if (n >= 0 && n <= 3)
3505 +    return 8 + n;
3506 +  else
3507 +    return INVALID_REGNUM;
3508 +}
3509 +
3510 +
3511 +/* Compute the distance from register FROM to register TO.
3512 +   These can be the arg pointer, the frame pointer or
3513 +   the stack pointer.
3514 +   Typical stack layout looks like this:
3515 +
3516 +       old stack pointer -> |    |
3517 +                            ----
3518 +                           |    | \
3519 +                           |    |   saved arguments for
3520 +                           |    |   vararg functions
3521 + arg_pointer   ->          |    | /
3522 +                             --
3523 +                           |    | \
3524 +                           |    |   call saved
3525 +                           |    |   registers
3526 +                           |    | /
3527 +  frame ptr     ->     --
3528 +                           |    | \
3529 +                           |    |   local
3530 +                           |    |   variables
3531 +  stack ptr -->             |    | /
3532 +                             --
3533 +                           |    | \
3534 +                           |    |   outgoing
3535 +                           |    |   arguments
3536 +                           |    | /
3537 +                             --
3538 +
3539 +  For a given funciton some or all of these stack compomnents
3540 +  may not be needed, giving rise to the possibility of
3541 +  eliminating some of the registers.
3542 +
3543 +  The values returned by this function must reflect the behaviour
3544 +  of avr32_expand_prologue() and avr32_compute_save_reg_mask().
3545 +
3546 +  The sign of the number returned reflects the direction of stack
3547 +  growth, so the values are positive for all eliminations except
3548 +  from the soft frame pointer to the hard frame pointer.  */
3549 +int
3550 +avr32_initial_elimination_offset (int from, int to)
3551 +{
3552 +  int i;
3553 +  int call_saved_regs = 0;
3554 +  unsigned long saved_reg_mask;
3555 +  unsigned int local_vars = get_frame_size ();
3556 +
3557 +  saved_reg_mask = avr32_compute_save_reg_mask (TRUE);
3558 +
3559 +  for (i = 0; i < 16; ++i)
3560 +    {
3561 +      if (saved_reg_mask & (1 << i))
3562 +       call_saved_regs += 4;
3563 +    }
3564 +
3565 +  switch (from)
3566 +    {
3567 +    case ARG_POINTER_REGNUM:
3568 +      switch (to)
3569 +       {
3570 +       case STACK_POINTER_REGNUM:
3571 +         return call_saved_regs + local_vars;
3572 +       case FRAME_POINTER_REGNUM:
3573 +         return call_saved_regs;
3574 +       default:
3575 +         abort ();
3576 +       }
3577 +    case FRAME_POINTER_REGNUM:
3578 +      switch (to)
3579 +       {
3580 +       case STACK_POINTER_REGNUM:
3581 +         return local_vars;
3582 +       default:
3583 +         abort ();
3584 +       }
3585 +    default:
3586 +      abort ();
3587 +    }
3588 +}
3589 +
3590 +
3591 +/*
3592 +  Returns a rtx used when passing the next argument to a function.
3593 +  avr32_init_cumulative_args() and avr32_function_arg_advance() sets which
3594 +  register to use.
3595 +*/
3596 +rtx
3597 +avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode,
3598 +                   tree type, int named)
3599 +{
3600 +  int index = -1;
3601 +  //unsigned long func_type = avr32_current_func_type ();
3602 +  //int last_reg_index = (IS_FLASHVAULT(func_type) || IS_FLASHVAULT_IMPL(func_type) || cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX);
3603 +  int last_reg_index = (cum->flashvault_func ? LAST_CUM_REG_INDEX - 1 : LAST_CUM_REG_INDEX);
3604 +
3605 +  HOST_WIDE_INT arg_size, arg_rsize;
3606 +  if (type)
3607 +    {
3608 +      arg_size = int_size_in_bytes (type);
3609 +    }
3610 +  else
3611 +    {
3612 +      arg_size = GET_MODE_SIZE (mode);
3613 +    }
3614 +  arg_rsize = PUSH_ROUNDING (arg_size);
3615 +
3616 +  /*
3617 +     The last time this macro is called, it is called with mode == VOIDmode,
3618 +     and its result is passed to the call or call_value pattern as operands 2
3619 +     and 3 respectively. */
3620 +  if (mode == VOIDmode)
3621 +    {
3622 +      return gen_rtx_CONST_INT (SImode, 22);   /* ToDo: fixme. */
3623 +    }
3624 +
3625 +  if ((*targetm.calls.must_pass_in_stack) (mode, type) || !named)
3626 +    {
3627 +      return NULL_RTX;
3628 +    }
3629 +
3630 +  if (arg_rsize == 8)
3631 +    {
3632 +      /* use r11:r10 or r9:r8. */
3633 +      if (!(GET_USED_INDEX (cum, 1) || GET_USED_INDEX (cum, 2)))
3634 +       index = 1;
3635 +      else if ((last_reg_index == 4) && 
3636 +               !(GET_USED_INDEX (cum, 3) || GET_USED_INDEX (cum, 4)))
3637 +       index = 3;
3638 +      else
3639 +       index = -1;
3640 +    }
3641 +  else if (arg_rsize == 4)
3642 +    {                          /* Use first available register */
3643 +      index = 0;
3644 +      while (index <= last_reg_index && GET_USED_INDEX (cum, index))
3645 +       index++;
3646 +      if (index > last_reg_index)
3647 +       index = -1;
3648 +    }
3649 +
3650 +  SET_REG_INDEX (cum, index);
3651 +
3652 +  if (GET_REG_INDEX (cum) >= 0)
3653 +    return gen_rtx_REG (mode, avr32_function_arg_reglist[GET_REG_INDEX (cum)]);
3654 +
3655 +  return NULL_RTX;
3656 +}
3657 +
3658 +
3659 +/* Set the register used for passing the first argument to a function. */
3660 +void
3661 +avr32_init_cumulative_args (CUMULATIVE_ARGS * cum,
3662 +                            tree fntype ATTRIBUTE_UNUSED,
3663 +                            rtx libname ATTRIBUTE_UNUSED,
3664 +                            tree fndecl)
3665 +{
3666 +  /* Set all registers as unused. */
3667 +  SET_INDEXES_UNUSED (cum);
3668 +
3669 +  /* Reset uses_anonymous_args */
3670 +  cum->uses_anonymous_args = 0;
3671 +
3672 +  /* Reset size of stack pushed arguments */
3673 +  cum->stack_pushed_args_size = 0;
3674 +  
3675 +  cum->flashvault_func = (fndecl && (has_attribute_p (fndecl,"flashvault") || has_attribute_p (fndecl,"flashvault_impl")));
3676 +}
3677 +
3678 +
3679 +/*
3680 +  Set register used for passing the next argument to a function. Only the
3681 +  Scratch Registers are used.
3682 +
3683 +               number  name
3684 +                  15   r15  PC
3685 +                  14   r14  LR
3686 +                  13   r13 _SP_________
3687 +     FIRST_CUM_REG 12   r12 _||_
3688 +                  10   r11  ||
3689 +                  11   r10 _||_  Scratch Registers
3690 +                   8   r9   ||
3691 +  LAST_SCRATCH_REG  9   r8  _\/_________
3692 +                   6   r7   /\
3693 +                   7   r6   ||
3694 +                   4   r5   ||
3695 +                   5   r4   ||
3696 +                   2   r3   ||
3697 +                   3   r2   ||
3698 +                   0   r1   ||
3699 +                   1   r0  _||_________
3700 +
3701 +*/
3702 +void
3703 +avr32_function_arg_advance (CUMULATIVE_ARGS * cum, enum machine_mode mode,
3704 +                           tree type, int named ATTRIBUTE_UNUSED)
3705 +{
3706 +  HOST_WIDE_INT arg_size, arg_rsize;
3707 +
3708 +  if (type)
3709 +    {
3710 +      arg_size = int_size_in_bytes (type);
3711 +    }
3712 +  else
3713 +    {
3714 +      arg_size = GET_MODE_SIZE (mode);
3715 +    }
3716 +  arg_rsize = PUSH_ROUNDING (arg_size);
3717 +
3718 +  /* If the argument had to be passed in stack, no register is used. */
3719 +  if ((*targetm.calls.must_pass_in_stack) (mode, type))
3720 +    {
3721 +      cum->stack_pushed_args_size += PUSH_ROUNDING (int_size_in_bytes (type));
3722 +      return;
3723 +    }
3724 +
3725 +  /* Mark the used registers as "used". */
3726 +  if (GET_REG_INDEX (cum) >= 0)
3727 +    {
3728 +      SET_USED_INDEX (cum, GET_REG_INDEX (cum));
3729 +      if (arg_rsize == 8)
3730 +       {
3731 +         SET_USED_INDEX (cum, (GET_REG_INDEX (cum) + 1));
3732 +       }
3733 +    }
3734 +  else
3735 +    {
3736 +      /* Had to use stack */
3737 +      cum->stack_pushed_args_size += arg_rsize;
3738 +    }
3739 +}
3740 +
3741 +
3742 +/*
3743 +  Defines witch direction to go to find the next register to use if the
3744 +  argument is larger then one register or for arguments shorter than an
3745 +  int which is not promoted, such as the last part of structures with
3746 +  size not a multiple of 4. */
3747 +enum direction
3748 +avr32_function_arg_padding (enum machine_mode mode ATTRIBUTE_UNUSED,
3749 +                           tree type)
3750 +{
3751 +  /* Pad upward for all aggregates except byte and halfword sized aggregates
3752 +     which can be passed in registers. */
3753 +  if (type
3754 +      && AGGREGATE_TYPE_P (type)
3755 +      && (int_size_in_bytes (type) != 1)
3756 +      && !((int_size_in_bytes (type) == 2)
3757 +          && TYPE_ALIGN_UNIT (type) >= 2)
3758 +      && (int_size_in_bytes (type) & 0x3))
3759 +    {
3760 +      return upward;
3761 +    }
3762 +
3763 +  return downward;
3764 +}
3765 +
3766 +
3767 +/* Return a rtx used for the return value from a function call. */
3768 +rtx
3769 +avr32_function_value (tree type, tree func, bool outgoing ATTRIBUTE_UNUSED)
3770 +{
3771 +  if (avr32_return_in_memory (type, func))
3772 +    return NULL_RTX;
3773 +
3774 +  if (int_size_in_bytes (type) <= 4)
3775 +    {
3776 +      enum machine_mode mode = TYPE_MODE (type);
3777 +      int unsignedp = 0;
3778 +      PROMOTE_FUNCTION_MODE (mode, unsignedp, type);
3779 +      return gen_rtx_REG (mode, RET_REGISTER);
3780 +    }
3781 +  else if (int_size_in_bytes (type) <= 8)
3782 +    return gen_rtx_REG (TYPE_MODE (type), INTERNAL_REGNUM (11));
3783 +
3784 +  return NULL_RTX;
3785 +}
3786 +
3787 +
3788 +/* Return a rtx used for the return value from a library function call. */
3789 +rtx
3790 +avr32_libcall_value (enum machine_mode mode)
3791 +{
3792 +
3793 +  if (GET_MODE_SIZE (mode) <= 4)
3794 +    return gen_rtx_REG (mode, RET_REGISTER);
3795 +  else if (GET_MODE_SIZE (mode) <= 8)
3796 +    return gen_rtx_REG (mode, INTERNAL_REGNUM (11));
3797 +  else
3798 +    return NULL_RTX;
3799 +}
3800 +
3801 +
3802 +/* Return TRUE if X references a SYMBOL_REF.  */
3803 +int
3804 +symbol_mentioned_p (rtx x)
3805 +{
3806 +  const char *fmt;
3807 +  int i;
3808 +
3809 +  if (GET_CODE (x) == SYMBOL_REF)
3810 +    return 1;
3811 +
3812 +  fmt = GET_RTX_FORMAT (GET_CODE (x));
3813 +
3814 +  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3815 +    {
3816 +      if (fmt[i] == 'E')
3817 +       {
3818 +         int j;
3819 +
3820 +         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3821 +           if (symbol_mentioned_p (XVECEXP (x, i, j)))
3822 +             return 1;
3823 +       }
3824 +      else if (fmt[i] == 'e' && symbol_mentioned_p (XEXP (x, i)))
3825 +       return 1;
3826 +    }
3827 +
3828 +  return 0;
3829 +}
3830 +
3831 +
3832 +/* Return TRUE if X references a LABEL_REF.  */
3833 +int
3834 +label_mentioned_p (rtx x)
3835 +{
3836 +  const char *fmt;
3837 +  int i;
3838 +
3839 +  if (GET_CODE (x) == LABEL_REF)
3840 +    return 1;
3841 +
3842 +  fmt = GET_RTX_FORMAT (GET_CODE (x));
3843 +  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3844 +    {
3845 +      if (fmt[i] == 'E')
3846 +       {
3847 +         int j;
3848 +
3849 +         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3850 +           if (label_mentioned_p (XVECEXP (x, i, j)))
3851 +             return 1;
3852 +       }
3853 +      else if (fmt[i] == 'e' && label_mentioned_p (XEXP (x, i)))
3854 +       return 1;
3855 +    }
3856 +
3857 +  return 0;
3858 +}
3859 +
3860 +
3861 +/* Return TRUE if X contains a MEM expression.  */
3862 +int
3863 +mem_mentioned_p (rtx x)
3864 +{
3865 +  const char *fmt;
3866 +  int i;
3867 +
3868 +  if (MEM_P (x))
3869 +    return 1;
3870 +
3871 +  fmt = GET_RTX_FORMAT (GET_CODE (x));
3872 +  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
3873 +    {
3874 +      if (fmt[i] == 'E')
3875 +       {
3876 +         int j;
3877 +
3878 +         for (j = XVECLEN (x, i) - 1; j >= 0; j--)
3879 +           if (mem_mentioned_p (XVECEXP (x, i, j)))
3880 +             return 1;
3881 +       }
3882 +      else if (fmt[i] == 'e' && mem_mentioned_p (XEXP (x, i)))
3883 +       return 1;
3884 +    }
3885 +
3886 +  return 0;
3887 +}
3888 +
3889 +
3890 +int
3891 +avr32_legitimate_pic_operand_p (rtx x)
3892 +{
3893 +
3894 +  /* We can't have const, this must be broken down to a symbol. */
3895 +  if (GET_CODE (x) == CONST)
3896 +    return FALSE;
3897 +
3898 +  /* Can't access symbols or labels via the constant pool either */
3899 +  if ((GET_CODE (x) == SYMBOL_REF
3900 +       && CONSTANT_POOL_ADDRESS_P (x)
3901 +       && (symbol_mentioned_p (get_pool_constant (x))
3902 +          || label_mentioned_p (get_pool_constant (x)))))
3903 +    return FALSE;
3904 +
3905 +  return TRUE;
3906 +}
3907 +
3908 +
3909 +rtx
3910 +legitimize_pic_address (rtx orig, enum machine_mode mode ATTRIBUTE_UNUSED,
3911 +                       rtx reg)
3912 +{
3913 +
3914 +  if (GET_CODE (orig) == SYMBOL_REF || GET_CODE (orig) == LABEL_REF)
3915 +    {
3916 +      int subregs = 0;
3917 +
3918 +      if (reg == 0)
3919 +       {
3920 +         if (!can_create_pseudo_p ())
3921 +           abort ();
3922 +         else
3923 +           reg = gen_reg_rtx (Pmode);
3924 +
3925 +         subregs = 1;
3926 +       }
3927 +
3928 +      emit_move_insn (reg, orig);
3929 +
3930 +      /* Only set current function as using pic offset table if flag_pic is
3931 +         set. This is because this function is also used if
3932 +         TARGET_HAS_ASM_ADDR_PSEUDOS is set. */
3933 +      if (flag_pic)
3934 +       crtl->uses_pic_offset_table = 1;
3935 +
3936 +      /* Put a REG_EQUAL note on this insn, so that it can be optimized by
3937 +         loop.  */
3938 +      return reg;
3939 +    }
3940 +  else if (GET_CODE (orig) == CONST)
3941 +    {
3942 +      rtx base, offset;
3943 +
3944 +      if (flag_pic
3945 +         && GET_CODE (XEXP (orig, 0)) == PLUS
3946 +         && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
3947 +       return orig;
3948 +
3949 +      if (reg == 0)
3950 +       {
3951 +         if (!can_create_pseudo_p ())
3952 +           abort ();
3953 +         else
3954 +           reg = gen_reg_rtx (Pmode);
3955 +       }
3956 +
3957 +      if (GET_CODE (XEXP (orig, 0)) == PLUS)
3958 +       {
3959 +         base =
3960 +           legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
3961 +         offset =
3962 +           legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
3963 +                                   base == reg ? 0 : reg);
3964 +       }
3965 +      else
3966 +       abort ();
3967 +
3968 +      if (GET_CODE (offset) == CONST_INT)
3969 +       {
3970 +         /* The base register doesn't really matter, we only want to test
3971 +            the index for the appropriate mode.  */
3972 +         if (!avr32_const_ok_for_constraint_p (INTVAL (offset), 'I', "Is21"))
3973 +           {
3974 +             if (can_create_pseudo_p ())
3975 +               offset = force_reg (Pmode, offset);
3976 +             else
3977 +               abort ();
3978 +           }
3979 +
3980 +         if (GET_CODE (offset) == CONST_INT)
3981 +           return plus_constant (base, INTVAL (offset));
3982 +       }
3983 +
3984 +      return gen_rtx_PLUS (Pmode, base, offset);
3985 +    }
3986 +
3987 +  return orig;
3988 +}
3989 +
3990 +
3991 +/* Generate code to load the PIC register.  */
3992 +void
3993 +avr32_load_pic_register (void)
3994 +{
3995 +  rtx l1, pic_tmp;
3996 +  rtx global_offset_table;
3997 +
3998 +  if ((crtl->uses_pic_offset_table == 0) || TARGET_NO_INIT_GOT)
3999 +    return;
4000 +
4001 +  if (!flag_pic)
4002 +    abort ();
4003 +
4004 +  l1 = gen_label_rtx ();
4005 +
4006 +  global_offset_table = gen_rtx_SYMBOL_REF (Pmode, "_GLOBAL_OFFSET_TABLE_");
4007 +  pic_tmp =
4008 +    gen_rtx_CONST (Pmode,
4009 +                  gen_rtx_MINUS (SImode, gen_rtx_LABEL_REF (Pmode, l1),
4010 +                                 global_offset_table));
4011 +  emit_insn (gen_pic_load_addr
4012 +            (pic_offset_table_rtx, force_const_mem (SImode, pic_tmp)));
4013 +  emit_insn (gen_pic_compute_got_from_pc (pic_offset_table_rtx, l1));
4014 +
4015 +  /* Need to emit this whether or not we obey regdecls, since setjmp/longjmp
4016 +     can cause life info to screw up.  */
4017 +  emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
4018 +}
4019 +
4020 +
4021 +/* This hook should return true if values of type type are returned at the most
4022 +   significant end of a register (in other words, if they are padded at the
4023 +   least significant end). You can assume that type is returned in a register;
4024 +   the caller is required to check this.  Note that the register provided by
4025 +   FUNCTION_VALUE must be able to hold the complete return value. For example,
4026 +   if a 1-, 2- or 3-byte structure is returned at the most significant end of a
4027 +   4-byte register, FUNCTION_VALUE should provide an SImode rtx. */
4028 +bool
4029 +avr32_return_in_msb (tree type ATTRIBUTE_UNUSED)
4030 +{
4031 +  /* if ( AGGREGATE_TYPE_P (type) ) if ((int_size_in_bytes(type) == 1) ||
4032 +     ((int_size_in_bytes(type) == 2) && TYPE_ALIGN_UNIT(type) >= 2)) return
4033 +     false; else return true; */
4034 +
4035 +  return false;
4036 +}
4037 +
4038 +
4039 +/*
4040 +  Returns one if a certain function value is going to be returned in memory
4041 +  and zero if it is going to be returned in a register.
4042 +
4043 +  BLKmode and all other modes that is larger than 64 bits are returned in
4044 +  memory.
4045 +*/
4046 +bool
4047 +avr32_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
4048 +{
4049 +  if (TYPE_MODE (type) == VOIDmode)
4050 +    return false;
4051 +
4052 +  if (int_size_in_bytes (type) > (2 * UNITS_PER_WORD)
4053 +      || int_size_in_bytes (type) == -1)
4054 +    {
4055 +      return true;
4056 +    }
4057 +
4058 +  /* If we have an aggregate then use the same mechanism as when checking if
4059 +     it should be passed on the stack. */
4060 +  if (type
4061 +      && AGGREGATE_TYPE_P (type)
4062 +      && (*targetm.calls.must_pass_in_stack) (TYPE_MODE (type), type))
4063 +    return true;
4064 +
4065 +  return false;
4066 +}
4067 +
4068 +
4069 +/* Output the constant part of the trampoline.
4070 +   lddpc    r0, pc[0x8:e] ; load static chain register
4071 +   lddpc    pc, pc[0x8:e] ; jump to subrutine
4072 +   .long    0           ; Address to static chain,
4073 +                        ; filled in by avr32_initialize_trampoline()
4074 +   .long    0           ; Address to subrutine,
4075 +                        ; filled in by avr32_initialize_trampoline()
4076 +*/
4077 +void
4078 +avr32_trampoline_template (FILE * file)
4079 +{
4080 +  fprintf (file, "\tlddpc    r0, pc[8]\n");
4081 +  fprintf (file, "\tlddpc    pc, pc[8]\n");
4082 +  /* make room for the address of the static chain. */
4083 +  fprintf (file, "\t.long\t0\n");
4084 +  /* make room for the address to the subrutine. */
4085 +  fprintf (file, "\t.long\t0\n");
4086 +}
4087 +
4088 +
4089 +/* Initialize the variable parts of a trampoline. */
4090 +void
4091 +avr32_initialize_trampoline (rtx addr, rtx fnaddr, rtx static_chain)
4092 +{
4093 +  /* Store the address to the static chain. */
4094 +  emit_move_insn (gen_rtx_MEM
4095 +                 (SImode, plus_constant (addr, TRAMPOLINE_SIZE - 4)),
4096 +                 static_chain);
4097 +
4098 +  /* Store the address to the function. */
4099 +  emit_move_insn (gen_rtx_MEM (SImode, plus_constant (addr, TRAMPOLINE_SIZE)),
4100 +                 fnaddr);
4101 +
4102 +  emit_insn (gen_cache (gen_rtx_REG (SImode, 13),
4103 +                       gen_rtx_CONST_INT (SImode,
4104 +                                          AVR32_CACHE_INVALIDATE_ICACHE)));
4105 +}
4106 +
4107 +
4108 +/* Return nonzero if X is valid as an addressing register.  */
4109 +int
4110 +avr32_address_register_rtx_p (rtx x, int strict_p)
4111 +{
4112 +  int regno;
4113 +
4114 +  if (!register_operand(x, GET_MODE(x)))
4115 +    return 0;
4116 +
4117 +  /* If strict we require the register to be a hard register. */
4118 +  if (strict_p
4119 +      && !REG_P(x))
4120 +    return 0;
4121 +
4122 +  regno = REGNO (x);
4123 +
4124 +  if (strict_p)
4125 +    return REGNO_OK_FOR_BASE_P (regno);
4126 +
4127 +  return (regno <= LAST_REGNUM || regno >= FIRST_PSEUDO_REGISTER);
4128 +}
4129 +
4130 +
4131 +/* Return nonzero if INDEX is valid for an address index operand.  */
4132 +int
4133 +avr32_legitimate_index_p (enum machine_mode mode, rtx index, int strict_p)
4134 +{
4135 +  enum rtx_code code = GET_CODE (index);
4136 +
4137 +  if (GET_MODE_SIZE (mode) > 8)
4138 +    return 0;
4139 +
4140 +  /* Standard coprocessor addressing modes.  */
4141 +  if (code == CONST_INT)
4142 +    {
4143 +       return CONST_OK_FOR_CONSTRAINT_P (INTVAL (index), 'K', "Ks16");
4144 +    }
4145 +
4146 +  if (avr32_address_register_rtx_p (index, strict_p))
4147 +    return 1;
4148 +
4149 +  if (code == MULT)
4150 +    {
4151 +      rtx xiop0 = XEXP (index, 0);
4152 +      rtx xiop1 = XEXP (index, 1);
4153 +      return ((avr32_address_register_rtx_p (xiop0, strict_p)
4154 +              && power_of_two_operand (xiop1, SImode)
4155 +              && (INTVAL (xiop1) <= 8))
4156 +             || (avr32_address_register_rtx_p (xiop1, strict_p)
4157 +                 && power_of_two_operand (xiop0, SImode)
4158 +                 && (INTVAL (xiop0) <= 8)));
4159 +    }
4160 +  else if (code == ASHIFT)
4161 +    {
4162 +      rtx op = XEXP (index, 1);
4163 +
4164 +      return (avr32_address_register_rtx_p (XEXP (index, 0), strict_p)
4165 +             && GET_CODE (op) == CONST_INT
4166 +             && INTVAL (op) > 0 && INTVAL (op) <= 3);
4167 +    }
4168 +
4169 +  return 0;
4170 +}
4171 +
4172 +
4173 +/*
4174 +  Used in the GO_IF_LEGITIMATE_ADDRESS macro. Returns a nonzero value if
4175 +  the RTX x is a legitimate memory address.
4176 +
4177 +  Returns NO_REGS if the address is not legatime, GENERAL_REGS or ALL_REGS
4178 +  if it is.
4179 +*/
4180 +
4181 +
4182 +/* Forward declaration */
4183 +int is_minipool_label (rtx label);
4184 +
4185 +int
4186 +avr32_legitimate_address (enum machine_mode mode, rtx x, int strict)
4187 +{
4188 +
4189 +  switch (GET_CODE (x))
4190 +    {
4191 +    case REG:
4192 +      return avr32_address_register_rtx_p (x, strict);
4193 +    case CONST_INT:
4194 +      return ((mode==SImode) && TARGET_RMW_ADDRESSABLE_DATA
4195 +              && CONST_OK_FOR_CONSTRAINT_P(INTVAL(x), 'K', "Ks17"));
4196 +    case CONST:
4197 +      {
4198 +       rtx label = avr32_find_symbol (x);
4199 +       if (label
4200 +           &&
4201 +           (/*
4202 +               If we enable (const (plus (symbol_ref ...))) type constant
4203 +               pool entries we must add support for it in the predicates and
4204 +               in the minipool generation in avr32_reorg().
4205 +               (CONSTANT_POOL_ADDRESS_P (label)
4206 +               && !(flag_pic
4207 +               && (symbol_mentioned_p (get_pool_constant (label))
4208 +               || label_mentioned_p (get_pool_constant (label)))))
4209 +               ||*/
4210 +             ((GET_CODE (label) == LABEL_REF)
4211 +              && GET_CODE (XEXP (label, 0)) == CODE_LABEL
4212 +                 && is_minipool_label (XEXP (label, 0)))
4213 +              /*|| ((GET_CODE (label) == SYMBOL_REF) 
4214 +                  && mode == SImode
4215 +                  && SYMBOL_REF_RMW_ADDR(label))*/))
4216 +         {
4217 +           return TRUE;
4218 +         }
4219 +      }
4220 +      break;
4221 +    case LABEL_REF:
4222 +      if (GET_CODE (XEXP (x, 0)) == CODE_LABEL
4223 +         && is_minipool_label (XEXP (x, 0)))
4224 +       {
4225 +         return TRUE;
4226 +       }
4227 +      break;
4228 +    case SYMBOL_REF:
4229 +      {
4230 +       if (CONSTANT_POOL_ADDRESS_P (x)
4231 +           && !(flag_pic
4232 +                && (symbol_mentioned_p (get_pool_constant (x))
4233 +                    || label_mentioned_p (get_pool_constant (x)))))
4234 +         return TRUE;
4235 +       else if (SYMBOL_REF_RCALL_FUNCTION_P (x)
4236 +                 || (mode == SImode
4237 +                     && SYMBOL_REF_RMW_ADDR (x)))
4238 +         return TRUE;
4239 +       break;
4240 +      }
4241 +    case PRE_DEC:              /* (pre_dec (...)) */
4242 +    case POST_INC:             /* (post_inc (...)) */
4243 +      return avr32_address_register_rtx_p (XEXP (x, 0), strict);
4244 +    case PLUS:                 /* (plus (...) (...)) */
4245 +      {
4246 +       rtx xop0 = XEXP (x, 0);
4247 +       rtx xop1 = XEXP (x, 1);
4248 +
4249 +       return ((avr32_address_register_rtx_p (xop0, strict)
4250 +                && avr32_legitimate_index_p (mode, xop1, strict))
4251 +               || (avr32_address_register_rtx_p (xop1, strict)
4252 +                   && avr32_legitimate_index_p (mode, xop0, strict)));
4253 +      }
4254 +    default:
4255 +      break;
4256 +    }
4257 +
4258 +  return FALSE;
4259 +}
4260 +
4261 +
4262 +int
4263 +avr32_const_ok_for_move (HOST_WIDE_INT c)
4264 +{
4265 +  if ( TARGET_V2_INSNS )
4266 +    return ( avr32_const_ok_for_constraint_p (c, 'K', "Ks21")
4267 +             /* movh instruction */
4268 +             || avr32_hi16_immediate_operand (GEN_INT(c), VOIDmode) );
4269 +  else
4270 +    return avr32_const_ok_for_constraint_p (c, 'K', "Ks21");
4271 +}
4272 +
4273 +
4274 +int
4275 +avr32_const_double_immediate (rtx value)
4276 +{
4277 +  HOST_WIDE_INT hi, lo;
4278 +
4279 +  if (GET_CODE (value) != CONST_DOUBLE)
4280 +    return FALSE;
4281 +
4282 +  if (SCALAR_FLOAT_MODE_P (GET_MODE (value)))
4283 +    {
4284 +      HOST_WIDE_INT target_float[2];
4285 +      hi = lo = 0;
4286 +      real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (value),
4287 +                     GET_MODE (value));
4288 +      lo = target_float[0];
4289 +      hi = target_float[1];
4290 +    }
4291 +  else
4292 +    {
4293 +      hi = CONST_DOUBLE_HIGH (value);
4294 +      lo = CONST_DOUBLE_LOW (value);
4295 +    }
4296 +
4297 +  if (avr32_const_ok_for_constraint_p (lo, 'K', "Ks21")
4298 +      && (GET_MODE (value) == SFmode
4299 +         || avr32_const_ok_for_constraint_p (hi, 'K', "Ks21")))
4300 +    {
4301 +      return TRUE;
4302 +    }
4303 +
4304 +  return FALSE;
4305 +}
4306 +
4307 +
4308 +int
4309 +avr32_legitimate_constant_p (rtx x)
4310 +{
4311 +  switch (GET_CODE (x))
4312 +    {
4313 +    case CONST_INT:
4314 +      /* Check if we should put large immediate into constant pool
4315 +       or load them directly with mov/orh.*/
4316 +      if (!avr32_imm_in_const_pool)
4317 +       return 1;
4318 +
4319 +      return avr32_const_ok_for_move (INTVAL (x));
4320 +    case CONST_DOUBLE:
4321 +      /* Check if we should put large immediate into constant pool
4322 +         or load them directly with mov/orh.*/
4323 +      if (!avr32_imm_in_const_pool)
4324 +       return 1;
4325 +
4326 +      if (GET_MODE (x) == SFmode
4327 +         || GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
4328 +       return avr32_const_double_immediate (x);
4329 +      else
4330 +       return 0;
4331 +    case LABEL_REF:
4332 +    case SYMBOL_REF:
4333 +      return avr32_find_symbol (x) && (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS);
4334 +    case CONST:
4335 +    case HIGH:
4336 +    case CONST_VECTOR:
4337 +      return 0;
4338 +    default:
4339 +      printf ("%s():\n", __FUNCTION__);
4340 +      debug_rtx (x);
4341 +      return 1;
4342 +    }
4343 +}
4344 +
4345 +
4346 +/* Strip any special encoding from labels */
4347 +const char *
4348 +avr32_strip_name_encoding (const char *name)
4349 +{
4350 +  const char *stripped = name;
4351 +
4352 +  while (1)
4353 +    {
4354 +      switch (stripped[0])
4355 +       {
4356 +       case '#':
4357 +         stripped = strchr (name + 1, '#') + 1;
4358 +         break;
4359 +       case '*':
4360 +         stripped = &stripped[1];
4361 +         break;
4362 +       default:
4363 +         return stripped;
4364 +       }
4365 +    }
4366 +}
4367 +
4368 +
4369 +
4370 +/* Do anything needed before RTL is emitted for each function.  */
4371 +static struct machine_function *
4372 +avr32_init_machine_status (void)
4373 +{
4374 +  struct machine_function *machine;
4375 +  machine =
4376 +    (machine_function *) ggc_alloc_cleared (sizeof (machine_function));
4377 +
4378 +#if AVR32_FT_UNKNOWN != 0
4379 +  machine->func_type = AVR32_FT_UNKNOWN;
4380 +#endif
4381 +
4382 +  machine->minipool_label_head = 0;
4383 +  machine->minipool_label_tail = 0;
4384 +  machine->ifcvt_after_reload = 0;
4385 +  return machine;
4386 +}
4387 +
4388 +
4389 +void
4390 +avr32_init_expanders (void)
4391 +{
4392 +  /* Arrange to initialize and mark the machine per-function status.  */
4393 +  init_machine_status = avr32_init_machine_status;
4394 +}
4395 +
4396 +
4397 +/* Return an RTX indicating where the return address to the
4398 +   calling function can be found.  */
4399 +rtx
4400 +avr32_return_addr (int count, rtx frame ATTRIBUTE_UNUSED)
4401 +{
4402 +  if (count != 0)
4403 +    return NULL_RTX;
4404 +
4405 +  return get_hard_reg_initial_val (Pmode, LR_REGNUM);
4406 +}
4407 +
4408 +
4409 +void
4410 +avr32_encode_section_info (tree decl, rtx rtl, int first)
4411 +{
4412 +   default_encode_section_info(decl, rtl, first);
4413 +
4414 +   if ( TREE_CODE (decl) == VAR_DECL
4415 +        && (GET_CODE (XEXP (rtl, 0)) == SYMBOL_REF)
4416 +        && (lookup_attribute ("rmw_addressable", DECL_ATTRIBUTES (decl))
4417 +            || TARGET_RMW_ADDRESSABLE_DATA) ){
4418 +     if ( !TARGET_RMW || flag_pic )
4419 +       return;
4420 +     //  {
4421 +     //    warning ("Using RMW addressable data with an arch that does not support RMW instructions.");
4422 +     //    return;
4423 +     //  } 
4424 +     //
4425 +     //if ( flag_pic )
4426 +     //  {
4427 +     //    warning ("Using RMW addressable data with together with -fpic switch. Can not use RMW instruction when compiling with -fpic.");
4428 +     //    return;
4429 +     //  } 
4430 +     SYMBOL_REF_FLAGS (XEXP (rtl, 0)) |= (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT);
4431 +  }
4432 +}
4433 +
4434 +
4435 +void
4436 +avr32_asm_output_label (FILE * stream, const char *name)
4437 +{
4438 +  name = avr32_strip_name_encoding (name);
4439 +
4440 +  /* Print the label. */
4441 +  assemble_name (stream, name);
4442 +  fprintf (stream, ":\n");
4443 +}
4444 +
4445 +
4446 +void
4447 +avr32_asm_weaken_label (FILE * stream, const char *name)
4448 +{
4449 +  fprintf (stream, "\t.weak ");
4450 +  assemble_name (stream, name);
4451 +  fprintf (stream, "\n");
4452 +}
4453 +
4454 +
4455 +/*
4456 +  Checks if a labelref is equal to a reserved word in the assembler. If it is,
4457 +  insert a '_' before the label name.
4458 +*/
4459 +void
4460 +avr32_asm_output_labelref (FILE * stream, const char *name)
4461 +{
4462 +  int verbatim = FALSE;
4463 +  const char *stripped = name;
4464 +  int strip_finished = FALSE;
4465 +
4466 +  while (!strip_finished)
4467 +    {
4468 +      switch (stripped[0])
4469 +       {
4470 +       case '#':
4471 +         stripped = strchr (name + 1, '#') + 1;
4472 +         break;
4473 +       case '*':
4474 +         stripped = &stripped[1];
4475 +         verbatim = TRUE;
4476 +         break;
4477 +       default:
4478 +         strip_finished = TRUE;
4479 +         break;
4480 +       }
4481 +    }
4482 +
4483 +  if (verbatim)
4484 +    fputs (stripped, stream);
4485 +  else
4486 +    asm_fprintf (stream, "%U%s", stripped);
4487 +}
4488 +
4489 +
4490 +/*
4491 +   Check if the comparison in compare_exp is redundant
4492 +   for the condition given in next_cond given that the
4493 +   needed flags are already set by an earlier instruction.
4494 +   Uses cc_prev_status to check this.
4495 +
4496 +   Returns NULL_RTX if the compare is not redundant
4497 +   or the new condition to use in the conditional
4498 +   instruction if the compare is redundant.
4499 +*/
4500 +static rtx
4501 +is_compare_redundant (rtx compare_exp, rtx next_cond)
4502 +{
4503 +  int z_flag_valid = FALSE;
4504 +  int n_flag_valid = FALSE;
4505 +  rtx new_cond;
4506 +
4507 +  if (GET_CODE (compare_exp) != COMPARE
4508 +      && GET_CODE (compare_exp) != AND)
4509 +    return NULL_RTX;
4510 +
4511 +
4512 +  if (rtx_equal_p (cc_prev_status.mdep.value, compare_exp))
4513 +    {
4514 +      /* cc0 already contains the correct comparison -> delete cmp insn */
4515 +      return next_cond;
4516 +    }
4517 +
4518 +  if (GET_MODE (compare_exp) != SImode)
4519 +    return NULL_RTX;
4520 +
4521 +  switch (cc_prev_status.mdep.flags)
4522 +    {
4523 +    case CC_SET_VNCZ:
4524 +    case CC_SET_NCZ:
4525 +      n_flag_valid = TRUE;
4526 +    case CC_SET_CZ:
4527 +    case CC_SET_Z:
4528 +      z_flag_valid = TRUE;
4529 +    }
4530 +
4531 +  if (cc_prev_status.mdep.value
4532 +      && GET_CODE (compare_exp) == COMPARE
4533 +      && REG_P (XEXP (compare_exp, 0))
4534 +      && REGNO (XEXP (compare_exp, 0)) == REGNO (cc_prev_status.mdep.value)
4535 +      && GET_CODE (XEXP (compare_exp, 1)) == CONST_INT
4536 +      && next_cond != NULL_RTX)
4537 +    {
4538 +      if (INTVAL (XEXP (compare_exp, 1)) == 0
4539 +         && z_flag_valid
4540 +         && (GET_CODE (next_cond) == EQ || GET_CODE (next_cond) == NE))
4541 +       /* We can skip comparison Z flag is already reflecting ops[0] */
4542 +       return next_cond;
4543 +      else if (n_flag_valid
4544 +              && ((INTVAL (XEXP (compare_exp, 1)) == 0
4545 +                   && (GET_CODE (next_cond) == GE
4546 +                       || GET_CODE (next_cond) == LT))
4547 +                  || (INTVAL (XEXP (compare_exp, 1)) == -1
4548 +                      && (GET_CODE (next_cond) == GT
4549 +                          || GET_CODE (next_cond) == LE))))
4550 +       {
4551 +         /* We can skip comparison N flag is already reflecting ops[0],
4552 +            which means that we can use the mi/pl conditions to check if
4553 +            ops[0] is GE or LT 0. */
4554 +         if ((GET_CODE (next_cond) == GE) || (GET_CODE (next_cond) == GT))
4555 +           new_cond =
4556 +             gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx),
4557 +                             UNSPEC_COND_PL);
4558 +         else
4559 +           new_cond =
4560 +             gen_rtx_UNSPEC (GET_MODE (next_cond), gen_rtvec (2, cc0_rtx, const0_rtx),
4561 +                             UNSPEC_COND_MI);
4562 +         return new_cond;
4563 +       }
4564 +    }
4565 +  return NULL_RTX;
4566 +}
4567 +
4568 +
4569 +/* Updates cc_status.  */
4570 +void
4571 +avr32_notice_update_cc (rtx exp, rtx insn)
4572 +{
4573 +  enum attr_cc attr_cc = get_attr_cc (insn);
4574 +
4575 +  if ( attr_cc == CC_SET_Z_IF_NOT_V2 )
4576 +    {
4577 +      if (TARGET_V2_INSNS)
4578 +        attr_cc = CC_NONE;
4579 +      else
4580 +        attr_cc = CC_SET_Z;
4581 +    }
4582 +
4583 +  switch (attr_cc)
4584 +    {
4585 +    case CC_CALL_SET:
4586 +      CC_STATUS_INIT;
4587 +      /* Check if the function call returns a value in r12 */
4588 +      if (REG_P (recog_data.operand[0])
4589 +         && REGNO (recog_data.operand[0]) == RETVAL_REGNUM)
4590 +       {
4591 +         cc_status.flags = 0;
4592 +         cc_status.mdep.value =
4593 +           gen_rtx_COMPARE (SImode, recog_data.operand[0], const0_rtx);
4594 +         cc_status.mdep.flags = CC_SET_VNCZ;
4595 +          cc_status.mdep.cond_exec_cmp_clobbered = 0;
4596 +
4597 +       }
4598 +      break;
4599 +    case CC_COMPARE:
4600 +      {
4601 +        /* Check that compare will not be optimized away if so nothing should
4602 +           be done */
4603 +        rtx compare_exp = SET_SRC (exp);
4604 +        /* Check if we have a tst expression. If so convert it to a
4605 +           compare with 0. */
4606 +        if ( REG_P (SET_SRC (exp)) )
4607 +          compare_exp = gen_rtx_COMPARE (GET_MODE (SET_SRC (exp)),
4608 +                                         SET_SRC (exp),
4609 +                                         const0_rtx);
4610 +
4611 +        if (!next_insn_emits_cmp (insn)
4612 +            && (is_compare_redundant (compare_exp, get_next_insn_cond (insn)) == NULL_RTX))
4613 +          {
4614 +
4615 +            /* Reset the nonstandard flag */
4616 +            CC_STATUS_INIT;
4617 +            cc_status.flags = 0;
4618 +            cc_status.mdep.value = compare_exp;
4619 +            cc_status.mdep.flags = CC_SET_VNCZ;
4620 +            cc_status.mdep.cond_exec_cmp_clobbered = 0;
4621 +         }
4622 +      }
4623 +      break;
4624 +    case CC_CMP_COND_INSN:
4625 +      {
4626 +       /* Conditional insn that emit the compare itself. */
4627 +        rtx cmp;
4628 +        rtx cmp_op0, cmp_op1;
4629 +        rtx cond;
4630 +        rtx dest;
4631 +        rtx next_insn = next_nonnote_insn (insn);
4632 +
4633 +        if ( GET_CODE (exp) == COND_EXEC )
4634 +          {
4635 +            cmp_op0 = XEXP (COND_EXEC_TEST (exp), 0);
4636 +            cmp_op1 = XEXP (COND_EXEC_TEST (exp), 1);
4637 +            cond = COND_EXEC_TEST (exp);
4638 +            dest = SET_DEST (COND_EXEC_CODE (exp));
4639 +          }
4640 +        else
4641 +          {
4642 +            /* If then else conditional. compare operands are in operands
4643 +               4 and 5. */
4644 +            cmp_op0 = recog_data.operand[4];
4645 +            cmp_op1 = recog_data.operand[5];
4646 +            cond = recog_data.operand[1];
4647 +            dest = SET_DEST (exp);
4648 +          }
4649 +
4650 +        if ( GET_CODE (cmp_op0) == AND )
4651 +          cmp = cmp_op0;
4652 +        else
4653 +          cmp = gen_rtx_COMPARE (GET_MODE (cmp_op0),
4654 +                                 cmp_op0,
4655 +                                 cmp_op1);
4656 +
4657 +        /* Check if the conditional insns updates a register present
4658 +           in the comparison, if so then we must reset the cc_status. */
4659 +        if (REG_P (dest)
4660 +            && (reg_mentioned_p (dest, cmp_op0)
4661 +                || reg_mentioned_p (dest, cmp_op1))
4662 +            && GET_CODE (exp) != COND_EXEC )
4663 +          {
4664 +            CC_STATUS_INIT;
4665 +          }
4666 +       else if (is_compare_redundant (cmp, cond) == NULL_RTX)
4667 +         {
4668 +           /* Reset the nonstandard flag */
4669 +           CC_STATUS_INIT;
4670 +            if ( GET_CODE (cmp_op0) == AND )
4671 +              {
4672 +                cc_status.flags = CC_INVERTED;
4673 +                cc_status.mdep.flags = CC_SET_Z;
4674 +              }
4675 +            else
4676 +              {
4677 +                cc_status.flags = 0;
4678 +                cc_status.mdep.flags = CC_SET_VNCZ;
4679 +              }
4680 +           cc_status.mdep.value = cmp;
4681 +            cc_status.mdep.cond_exec_cmp_clobbered = 0;
4682 +         }
4683 +
4684 +
4685 +        /* Check if we have a COND_EXEC insn which updates one
4686 +           of the registers in the compare status. */
4687 +        if (REG_P (dest)
4688 +            && (reg_mentioned_p (dest, cmp_op0)
4689 +                || reg_mentioned_p (dest, cmp_op1))
4690 +            && GET_CODE (exp) == COND_EXEC )
4691 +          cc_status.mdep.cond_exec_cmp_clobbered = 1;
4692 +
4693 +        if ( cc_status.mdep.cond_exec_cmp_clobbered
4694 +             && GET_CODE (exp) == COND_EXEC
4695 +             && next_insn != NULL
4696 +             && INSN_P (next_insn)
4697 +             && !(GET_CODE (PATTERN (next_insn)) == COND_EXEC
4698 +                  && rtx_equal_p (XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 0), cmp_op0)
4699 +                  && rtx_equal_p (XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 1), cmp_op1)
4700 +                  && (GET_CODE (COND_EXEC_TEST (PATTERN (next_insn))) == GET_CODE (cond)
4701 +                      || GET_CODE (COND_EXEC_TEST (PATTERN (next_insn))) == reverse_condition (GET_CODE (cond)))) )
4702 +          {
4703 +            /* We have a sequence of conditional insns where the compare status has been clobbered
4704 +               since the compare no longer reflects the content of the values to compare. */
4705 +            CC_STATUS_INIT;
4706 +            cc_status.mdep.cond_exec_cmp_clobbered = 1;
4707 +          }
4708 +
4709 +      }
4710 +      break;
4711 +    case CC_BLD:
4712 +      /* Bit load is kind of like an inverted testsi, because the Z flag is
4713 +         inverted */
4714 +      CC_STATUS_INIT;
4715 +      cc_status.flags = CC_INVERTED;
4716 +      cc_status.mdep.value = SET_SRC (exp);
4717 +      cc_status.mdep.flags = CC_SET_Z;
4718 +      cc_status.mdep.cond_exec_cmp_clobbered = 0;
4719 +      break;
4720 +    case CC_NONE:
4721 +      /* Insn does not affect CC at all. Check if the instruction updates
4722 +         some of the register currently reflected in cc0 */
4723 +
4724 +      if ((GET_CODE (exp) == SET)
4725 +         && (cc_status.value1 || cc_status.value2 || cc_status.mdep.value)
4726 +         && (reg_mentioned_p (SET_DEST (exp), cc_status.value1)
4727 +             || reg_mentioned_p (SET_DEST (exp), cc_status.value2)
4728 +             || reg_mentioned_p (SET_DEST (exp), cc_status.mdep.value)))
4729 +       {
4730 +         CC_STATUS_INIT;
4731 +       }
4732 +
4733 +      /* If this is a parallel we must step through each of the parallel
4734 +         expressions */
4735 +      if (GET_CODE (exp) == PARALLEL)
4736 +       {
4737 +         int i;
4738 +         for (i = 0; i < XVECLEN (exp, 0); ++i)
4739 +           {
4740 +             rtx vec_exp = XVECEXP (exp, 0, i);
4741 +             if ((GET_CODE (vec_exp) == SET)
4742 +                 && (cc_status.value1 || cc_status.value2
4743 +                     || cc_status.mdep.value)
4744 +                 && (reg_mentioned_p (SET_DEST (vec_exp), cc_status.value1)
4745 +                     || reg_mentioned_p (SET_DEST (vec_exp),
4746 +                                         cc_status.value2)
4747 +                     || reg_mentioned_p (SET_DEST (vec_exp),
4748 +                                         cc_status.mdep.value)))
4749 +               {
4750 +                 CC_STATUS_INIT;
4751 +               }
4752 +           }
4753 +       }
4754 +
4755 +      /* Check if we have memory opartions with post_inc or pre_dec on the
4756 +         register currently reflected in cc0 */
4757 +      if (GET_CODE (exp) == SET
4758 +         && GET_CODE (SET_SRC (exp)) == MEM
4759 +         && (GET_CODE (XEXP (SET_SRC (exp), 0)) == POST_INC
4760 +             || GET_CODE (XEXP (SET_SRC (exp), 0)) == PRE_DEC)
4761 +         &&
4762 +         (reg_mentioned_p
4763 +          (XEXP (XEXP (SET_SRC (exp), 0), 0), cc_status.value1)
4764 +          || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0),
4765 +                              cc_status.value2)
4766 +          || reg_mentioned_p (XEXP (XEXP (SET_SRC (exp), 0), 0),
4767 +                              cc_status.mdep.value)))
4768 +       CC_STATUS_INIT;
4769 +
4770 +      if (GET_CODE (exp) == SET
4771 +         && GET_CODE (SET_DEST (exp)) == MEM
4772 +         && (GET_CODE (XEXP (SET_DEST (exp), 0)) == POST_INC
4773 +             || GET_CODE (XEXP (SET_DEST (exp), 0)) == PRE_DEC)
4774 +         &&
4775 +         (reg_mentioned_p
4776 +          (XEXP (XEXP (SET_DEST (exp), 0), 0), cc_status.value1)
4777 +          || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0),
4778 +                              cc_status.value2)
4779 +          || reg_mentioned_p (XEXP (XEXP (SET_DEST (exp), 0), 0),
4780 +                              cc_status.mdep.value)))
4781 +       CC_STATUS_INIT;
4782 +      break;
4783 +
4784 +    case CC_SET_VNCZ:
4785 +      CC_STATUS_INIT;
4786 +      cc_status.mdep.value = recog_data.operand[0];
4787 +      cc_status.mdep.flags = CC_SET_VNCZ;
4788 +      cc_status.mdep.cond_exec_cmp_clobbered = 0;
4789 +      break;
4790 +
4791 +    case CC_SET_NCZ:
4792 +      CC_STATUS_INIT;
4793 +      cc_status.mdep.value = recog_data.operand[0];
4794 +      cc_status.mdep.flags = CC_SET_NCZ;
4795 +      cc_status.mdep.cond_exec_cmp_clobbered = 0;
4796 +      break;
4797 +
4798 +    case CC_SET_CZ:
4799 +      CC_STATUS_INIT;
4800 +      cc_status.mdep.value = recog_data.operand[0];
4801 +      cc_status.mdep.flags = CC_SET_CZ;
4802 +      cc_status.mdep.cond_exec_cmp_clobbered = 0;
4803 +      break;
4804 +
4805 +    case CC_SET_Z:
4806 +      CC_STATUS_INIT;
4807 +      cc_status.mdep.value = recog_data.operand[0];
4808 +      cc_status.mdep.flags = CC_SET_Z;
4809 +      cc_status.mdep.cond_exec_cmp_clobbered = 0;
4810 +      break;
4811 +
4812 +    case CC_CLOBBER:
4813 +      CC_STATUS_INIT;
4814 +      break;
4815 +
4816 +    default:
4817 +      CC_STATUS_INIT;
4818 +    }
4819 +}
4820 +
4821 +
4822 +/*
4823 +  Outputs to stdio stream stream the assembler syntax for an instruction
4824 +  operand x. x is an RTL expression.
4825 +*/
4826 +void
4827 +avr32_print_operand (FILE * stream, rtx x, int code)
4828 +{
4829 +  int error = 0;
4830 +
4831 +  if ( code == '?' )
4832 +    {
4833 +      /* Predicable instruction, print condition code */
4834 +
4835 +      /* If the insn should not be conditional then do nothing. */
4836 +      if ( current_insn_predicate == NULL_RTX )
4837 +        return;
4838 +
4839 +      /* Set x to the predicate to force printing
4840 +         the condition later on. */
4841 +      x = current_insn_predicate;
4842 +
4843 +      /* Reverse condition if useing bld insn. */
4844 +      if ( GET_CODE (XEXP(current_insn_predicate,0)) == AND )
4845 +        x = reversed_condition (current_insn_predicate);
4846 +    }
4847 +  else if ( code == '!' )
4848 +    {
4849 +      /* Output compare for conditional insn if needed. */
4850 +      rtx new_cond;
4851 +      gcc_assert ( current_insn_predicate != NULL_RTX );
4852 +      new_cond = avr32_output_cmp(current_insn_predicate,
4853 +                                  GET_MODE(XEXP(current_insn_predicate,0)),
4854 +                                  XEXP(current_insn_predicate,0),
4855 +                                  XEXP(current_insn_predicate,1));
4856 +
4857 +      /* Check if the new condition is a special avr32 condition
4858 +         specified using UNSPECs. If so we must handle it differently. */
4859 +      if ( GET_CODE (new_cond) == UNSPEC )
4860 +        {
4861 +          current_insn_predicate =
4862 +            gen_rtx_UNSPEC (CCmode,
4863 +                            gen_rtvec (2,
4864 +                                       XEXP(current_insn_predicate,0),
4865 +                                       XEXP(current_insn_predicate,1)),
4866 +                            XINT (new_cond, 1));
4867 +        }
4868 +      else
4869 +        {
4870 +          PUT_CODE(current_insn_predicate, GET_CODE(new_cond));
4871 +        }
4872 +      return;
4873 +    }
4874 +
4875 +  switch (GET_CODE (x))
4876 +    {
4877 +    case UNSPEC:
4878 +      switch (XINT (x, 1))
4879 +       {
4880 +       case UNSPEC_COND_PL:
4881 +         if (code == 'i')
4882 +           fputs ("mi", stream);
4883 +         else
4884 +           fputs ("pl", stream);
4885 +         break;
4886 +       case UNSPEC_COND_MI:
4887 +         if (code == 'i')
4888 +           fputs ("pl", stream);
4889 +         else
4890 +           fputs ("mi", stream);
4891 +         break;
4892 +       default:
4893 +         error = 1;
4894 +       }
4895 +      break;
4896 +    case EQ:
4897 +      if (code == 'i')
4898 +       fputs ("ne", stream);
4899 +      else
4900 +       fputs ("eq", stream);
4901 +      break;
4902 +    case NE:
4903 +      if (code == 'i')
4904 +       fputs ("eq", stream);
4905 +      else
4906 +       fputs ("ne", stream);
4907 +      break;
4908 +    case GT:
4909 +      if (code == 'i')
4910 +       fputs ("le", stream);
4911 +      else
4912 +       fputs ("gt", stream);
4913 +      break;
4914 +    case GTU:
4915 +      if (code == 'i')
4916 +       fputs ("ls", stream);
4917 +      else
4918 +       fputs ("hi", stream);
4919 +      break;
4920 +    case LT:
4921 +      if (code == 'i')
4922 +       fputs ("ge", stream);
4923 +      else
4924 +       fputs ("lt", stream);
4925 +      break;
4926 +    case LTU:
4927 +      if (code == 'i')
4928 +       fputs ("hs", stream);
4929 +      else
4930 +       fputs ("lo", stream);
4931 +      break;
4932 +    case GE:
4933 +      if (code == 'i')
4934 +       fputs ("lt", stream);
4935 +      else
4936 +       fputs ("ge", stream);
4937 +      break;
4938 +    case GEU:
4939 +      if (code == 'i')
4940 +       fputs ("lo", stream);
4941 +      else
4942 +       fputs ("hs", stream);
4943 +      break;
4944 +    case LE:
4945 +      if (code == 'i')
4946 +       fputs ("gt", stream);
4947 +      else
4948 +       fputs ("le", stream);
4949 +      break;
4950 +    case LEU:
4951 +      if (code == 'i')
4952 +       fputs ("hi", stream);
4953 +      else
4954 +       fputs ("ls", stream);
4955 +      break;
4956 +    case CONST_INT:
4957 +      {
4958 +        HOST_WIDE_INT value = INTVAL (x);
4959 +
4960 +        switch (code)
4961 +          {
4962 +          case 'm':
4963 +            if ( HOST_BITS_PER_WIDE_INT > BITS_PER_WORD )
4964 +              {
4965 +                /* A const_int can be used to represent DImode constants. */
4966 +                value >>= BITS_PER_WORD;
4967 +              }
4968 +            /* We might get a const_int immediate for setting a DI register,
4969 +               we then must then return the correct sign extended DI. The most
4970 +               significant word is just a sign extension. */
4971 +            else if (value < 0)
4972 +              value = -1;
4973 +            else
4974 +              value = 0;
4975 +            break;
4976 +          case 'i':
4977 +            value++;
4978 +            break;
4979 +          case 'p':
4980 +            {
4981 +              /* Set to bit position of first bit set in immediate */
4982 +              int i, bitpos = 32;
4983 +              for (i = 0; i < 32; i++)
4984 +                if (value & (1 << i))
4985 +                  {
4986 +                    bitpos = i;
4987 +                    break;
4988 +                  }
4989 +              value = bitpos;
4990 +            }
4991 +            break;
4992 +          case 'z':
4993 +            {
4994 +              /* Set to bit position of first bit cleared in immediate */
4995 +              int i, bitpos = 32;
4996 +              for (i = 0; i < 32; i++)
4997 +                if (!(value & (1 << i)))
4998 +                  {
4999 +                    bitpos = i;
5000 +                    break;
5001 +                  }
5002 +              value = bitpos;
5003 +            }
5004 +            break;
5005 +          case 'r':
5006 +            {
5007 +              /* Reglist 8 */
5008 +              char op[50];
5009 +              op[0] = '\0';
5010 +
5011 +              if (value & 0x01)
5012 +                strcpy (op, "r0-r3");
5013 +              if (value & 0x02)
5014 +                strlen (op) ? strcat (op, ", r4-r7") : strcpy (op,"r4-r7");
5015 +              if (value & 0x04)
5016 +                strlen (op) ? strcat (op, ", r8-r9") : strcpy (op,"r8-r9");
5017 +              if (value & 0x08)
5018 +                strlen (op) ? strcat (op, ", r10") : strcpy (op,"r10");
5019 +              if (value & 0x10)
5020 +                strlen (op) ? strcat (op, ", r11") : strcpy (op,"r11");
5021 +              if (value & 0x20)
5022 +                strlen (op) ? strcat (op, ", r12") : strcpy (op,"r12");
5023 +              if (value & 0x40)
5024 +                strlen (op) ? strcat (op, ", lr") : strcpy (op, "lr");
5025 +              if (value & 0x80)
5026 +                strlen (op) ? strcat (op, ", pc") : strcpy (op, "pc");
5027 +
5028 +              fputs (op, stream);
5029 +              return;
5030 +            }
5031 +          case 's':
5032 +            {
5033 +              /* Reglist 16 */
5034 +              char reglist16_string[100];
5035 +              int i;
5036 +             bool first_reg = true;
5037 +              reglist16_string[0] = '\0';
5038 +
5039 +             for (i = 0; i < 16; ++i)
5040 +               {
5041 +                 if (value & (1 << i))
5042 +                   {
5043 +                       first_reg == true ?  first_reg = false : strcat(reglist16_string,", ");
5044 +                       strcat(reglist16_string,reg_names[INTERNAL_REGNUM(i)]);               
5045 +                   }
5046 +               }
5047 +             fputs (reglist16_string, stream);
5048 +             return;
5049 +           }
5050 +         case 'h':
5051 +           /* Print halfword part of word */
5052 +           fputs (value ? "b" : "t", stream);
5053 +           return;
5054 +         }
5055 +
5056 +       /* Print Value */
5057 +       fprintf (stream, "%d", value);
5058 +       break;
5059 +      }
5060 +    case CONST_DOUBLE:
5061 +      {
5062 +       HOST_WIDE_INT hi, lo;
5063 +       if (SCALAR_FLOAT_MODE_P (GET_MODE (x)))
5064 +         {
5065 +           HOST_WIDE_INT target_float[2];
5066 +           hi = lo = 0;
5067 +           real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (x),
5068 +                           GET_MODE (x));
5069 +           /* For doubles the most significant part starts at index 0. */
5070 +           if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
5071 +             {
5072 +               hi = target_float[0];
5073 +               lo = target_float[1];
5074 +             }
5075 +           else
5076 +             {
5077 +               lo = target_float[0];
5078 +             }
5079 +         }
5080 +       else
5081 +         {
5082 +           hi = CONST_DOUBLE_HIGH (x);
5083 +           lo = CONST_DOUBLE_LOW (x);
5084 +         }
5085 +
5086 +       if (code == 'm')
5087 +         fprintf (stream, "%ld", hi);
5088 +       else
5089 +         fprintf (stream, "%ld", lo);
5090 +
5091 +       break;
5092 +      }
5093 +    case CONST:
5094 +      output_addr_const (stream, XEXP (XEXP (x, 0), 0));
5095 +      fprintf (stream, "+%ld", INTVAL (XEXP (XEXP (x, 0), 1)));
5096 +      break;
5097 +    case REG:
5098 +      /* Swap register name if the register is DImode or DFmode. */
5099 +      if (GET_MODE (x) == DImode || GET_MODE (x) == DFmode)
5100 +       {
5101 +         /* Double register must have an even numbered address */
5102 +         gcc_assert (!(REGNO (x) % 2));
5103 +         if (code == 'm')
5104 +           fputs (reg_names[true_regnum (x)], stream);
5105 +         else
5106 +           fputs (reg_names[true_regnum (x) + 1], stream);
5107 +       }
5108 +      else if (GET_MODE (x) == TImode)
5109 +       {
5110 +         switch (code)
5111 +           {
5112 +           case 'T':
5113 +             fputs (reg_names[true_regnum (x)], stream);
5114 +             break;
5115 +           case 'U':
5116 +             fputs (reg_names[true_regnum (x) + 1], stream);
5117 +             break;
5118 +           case 'L':
5119 +             fputs (reg_names[true_regnum (x) + 2], stream);
5120 +             break;
5121 +           case 'B':
5122 +             fputs (reg_names[true_regnum (x) + 3], stream);
5123 +             break;
5124 +           default:
5125 +             fprintf (stream, "%s, %s, %s, %s",
5126 +                      reg_names[true_regnum (x) + 3],
5127 +                      reg_names[true_regnum (x) + 2],
5128 +                      reg_names[true_regnum (x) + 1],
5129 +                      reg_names[true_regnum (x)]);
5130 +             break;
5131 +           }
5132 +       }
5133 +      else
5134 +       {
5135 +         fputs (reg_names[true_regnum (x)], stream);
5136 +       }
5137 +      break;
5138 +    case CODE_LABEL:
5139 +    case LABEL_REF:
5140 +    case SYMBOL_REF:
5141 +      output_addr_const (stream, x);
5142 +      break;
5143 +    case MEM:
5144 +      switch (GET_CODE (XEXP (x, 0)))
5145 +       {
5146 +       case LABEL_REF:
5147 +       case SYMBOL_REF:
5148 +         output_addr_const (stream, XEXP (x, 0));
5149 +         break;
5150 +       case MEM:
5151 +         switch (GET_CODE (XEXP (XEXP (x, 0), 0)))
5152 +           {
5153 +           case SYMBOL_REF:
5154 +             output_addr_const (stream, XEXP (XEXP (x, 0), 0));
5155 +             break;
5156 +           default:
5157 +             error = 1;
5158 +             break;
5159 +           }
5160 +         break;
5161 +       case REG:
5162 +         avr32_print_operand (stream, XEXP (x, 0), 0);
5163 +         if (code != 'p')
5164 +           fputs ("[0]", stream);
5165 +         break;
5166 +       case PRE_DEC:
5167 +         fputs ("--", stream);
5168 +         avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0);
5169 +         break;
5170 +       case POST_INC:
5171 +         avr32_print_operand (stream, XEXP (XEXP (x, 0), 0), 0);
5172 +         fputs ("++", stream);
5173 +         break;
5174 +       case PLUS:
5175 +         {
5176 +           rtx op0 = XEXP (XEXP (x, 0), 0);
5177 +           rtx op1 = XEXP (XEXP (x, 0), 1);
5178 +           rtx base = NULL_RTX, offset = NULL_RTX;
5179 +
5180 +           if (avr32_address_register_rtx_p (op0, 1))
5181 +             {
5182 +               base = op0;
5183 +               offset = op1;
5184 +             }
5185 +           else if (avr32_address_register_rtx_p (op1, 1))
5186 +             {
5187 +               /* Operands are switched. */
5188 +               base = op1;
5189 +               offset = op0;
5190 +             }
5191 +
5192 +           gcc_assert (base && offset
5193 +                       && avr32_address_register_rtx_p (base, 1)
5194 +                       && avr32_legitimate_index_p (GET_MODE (x), offset,
5195 +                                                    1));
5196 +
5197 +           avr32_print_operand (stream, base, 0);
5198 +           fputs ("[", stream);
5199 +           avr32_print_operand (stream, offset, 0);
5200 +           fputs ("]", stream);
5201 +           break;
5202 +         }
5203 +       case CONST:
5204 +         output_addr_const (stream, XEXP (XEXP (XEXP (x, 0), 0), 0));
5205 +         fprintf (stream, " + %ld",
5206 +                  INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)));
5207 +         break;
5208 +        case CONST_INT:
5209 +         avr32_print_operand (stream, XEXP (x, 0), 0);
5210 +          break;
5211 +       default:
5212 +         error = 1;
5213 +       }
5214 +      break;
5215 +    case MULT:
5216 +      {
5217 +       int value = INTVAL (XEXP (x, 1));
5218 +
5219 +       /* Convert immediate in multiplication into a shift immediate */
5220 +       switch (value)
5221 +         {
5222 +         case 2:
5223 +           value = 1;
5224 +           break;
5225 +         case 4:
5226 +           value = 2;
5227 +           break;
5228 +         case 8:
5229 +           value = 3;
5230 +           break;
5231 +         default:
5232 +           value = 0;
5233 +         }
5234 +       fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))],
5235 +                value);
5236 +       break;
5237 +      }
5238 +    case ASHIFT:
5239 +      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5240 +       fprintf (stream, "%s << %i", reg_names[true_regnum (XEXP (x, 0))],
5241 +                (int) INTVAL (XEXP (x, 1)));
5242 +      else if (REG_P (XEXP (x, 1)))
5243 +       fprintf (stream, "%s << %s", reg_names[true_regnum (XEXP (x, 0))],
5244 +                reg_names[true_regnum (XEXP (x, 1))]);
5245 +      else
5246 +       {
5247 +         error = 1;
5248 +       }
5249 +      break;
5250 +    case LSHIFTRT:
5251 +      if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5252 +       fprintf (stream, "%s >> %i", reg_names[true_regnum (XEXP (x, 0))],
5253 +                (int) INTVAL (XEXP (x, 1)));
5254 +      else if (REG_P (XEXP (x, 1)))
5255 +       fprintf (stream, "%s >> %s", reg_names[true_regnum (XEXP (x, 0))],
5256 +                reg_names[true_regnum (XEXP (x, 1))]);
5257 +      else
5258 +       {
5259 +         error = 1;
5260 +       }
5261 +      fprintf (stream, ">>");
5262 +      break;
5263 +    case PARALLEL:
5264 +      {
5265 +       /* Load store multiple */
5266 +       int i;
5267 +       int count = XVECLEN (x, 0);
5268 +       int reglist16 = 0;
5269 +       char reglist16_string[100];
5270 +
5271 +       for (i = 0; i < count; ++i)
5272 +         {
5273 +           rtx vec_elm = XVECEXP (x, 0, i);
5274 +           if (GET_MODE (vec_elm) != SET)
5275 +             {
5276 +               debug_rtx (vec_elm);
5277 +               internal_error ("Unknown element in parallel expression!");
5278 +             }
5279 +           if (GET_MODE (XEXP (vec_elm, 0)) == REG)
5280 +             {
5281 +               /* Load multiple */
5282 +               reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 0)));
5283 +             }
5284 +           else
5285 +             {
5286 +               /* Store multiple */
5287 +               reglist16 |= 1 << ASM_REGNUM (REGNO (XEXP (vec_elm, 1)));
5288 +             }
5289 +         }
5290 +
5291 +       avr32_make_reglist16 (reglist16, reglist16_string);
5292 +       fputs (reglist16_string, stream);
5293 +
5294 +       break;
5295 +      }
5296 +
5297 +    case PLUS:
5298 +      {
5299 +        rtx op0 = XEXP (x, 0);
5300 +        rtx op1 = XEXP (x, 1);
5301 +        rtx base = NULL_RTX, offset = NULL_RTX;
5302 +
5303 +        if (avr32_address_register_rtx_p (op0, 1))
5304 +          {
5305 +            base = op0;
5306 +            offset = op1;
5307 +          }
5308 +        else if (avr32_address_register_rtx_p (op1, 1))
5309 +          {
5310 +            /* Operands are switched. */
5311 +            base = op1;
5312 +            offset = op0;
5313 +          }
5314 +
5315 +        gcc_assert (base && offset
5316 +                    && avr32_address_register_rtx_p (base, 1)
5317 +                    && avr32_legitimate_index_p (GET_MODE (x), offset, 1));
5318 +
5319 +        avr32_print_operand (stream, base, 0);
5320 +        fputs ("[", stream);
5321 +        avr32_print_operand (stream, offset, 0);
5322 +        fputs ("]", stream);
5323 +        break;
5324 +      }
5325 +
5326 +    default:
5327 +      error = 1;
5328 +    }
5329 +
5330 +  if (error)
5331 +    {
5332 +      debug_rtx (x);
5333 +      internal_error ("Illegal expression for avr32_print_operand");
5334 +    }
5335 +}
5336 +
5337 +rtx
5338 +avr32_get_note_reg_equiv (rtx insn)
5339 +{
5340 +  rtx note;
5341 +
5342 +  note = find_reg_note (insn, REG_EQUIV, NULL_RTX);
5343 +
5344 +  if (note != NULL_RTX)
5345 +    return XEXP (note, 0);
5346 +  else
5347 +    return NULL_RTX;
5348 +}
5349 +
5350 +
5351 +/*
5352 +  Outputs to stdio stream stream the assembler syntax for an instruction
5353 +  operand that is a memory reference whose address is x. x is an RTL
5354 +  expression.
5355 +
5356 +  ToDo: fixme.
5357 +*/
5358 +void
5359 +avr32_print_operand_address (FILE * stream, rtx x)
5360 +{
5361 +  fprintf (stream, "(%d) /* address */", REGNO (x));
5362 +}
5363 +
5364 +
5365 +/* Return true if _GLOBAL_OFFSET_TABLE_ symbol is mentioned.  */
5366 +bool
5367 +avr32_got_mentioned_p (rtx addr)
5368 +{
5369 +  if (GET_CODE (addr) == MEM)
5370 +    addr = XEXP (addr, 0);
5371 +  while (GET_CODE (addr) == CONST)
5372 +    addr = XEXP (addr, 0);
5373 +  if (GET_CODE (addr) == SYMBOL_REF)
5374 +    {
5375 +      return streq (XSTR (addr, 0), "_GLOBAL_OFFSET_TABLE_");
5376 +    }
5377 +  if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
5378 +    {
5379 +      bool l1, l2;
5380 +
5381 +      l1 = avr32_got_mentioned_p (XEXP (addr, 0));
5382 +      l2 = avr32_got_mentioned_p (XEXP (addr, 1));
5383 +      return l1 || l2;
5384 +    }
5385 +  return false;
5386 +}
5387 +
5388 +
5389 +/* Find the symbol in an address expression.  */
5390 +rtx
5391 +avr32_find_symbol (rtx addr)
5392 +{
5393 +  if (GET_CODE (addr) == MEM)
5394 +    addr = XEXP (addr, 0);
5395 +
5396 +  while (GET_CODE (addr) == CONST)
5397 +    addr = XEXP (addr, 0);
5398 +
5399 +  if (GET_CODE (addr) == SYMBOL_REF || GET_CODE (addr) == LABEL_REF)
5400 +    return addr;
5401 +  if (GET_CODE (addr) == PLUS)
5402 +    {
5403 +      rtx l1, l2;
5404 +
5405 +      l1 = avr32_find_symbol (XEXP (addr, 0));
5406 +      l2 = avr32_find_symbol (XEXP (addr, 1));
5407 +      if (l1 != NULL_RTX && l2 == NULL_RTX)
5408 +       return l1;
5409 +      else if (l1 == NULL_RTX && l2 != NULL_RTX)
5410 +       return l2;
5411 +    }
5412 +
5413 +  return NULL_RTX;
5414 +}
5415 +
5416 +
5417 +/* Routines for manipulation of the constant pool.  */
5418 +
5419 +/* AVR32 instructions cannot load a large constant directly into a
5420 +   register; they have to come from a pc relative load.  The constant
5421 +   must therefore be placed in the addressable range of the pc
5422 +   relative load.  Depending on the precise pc relative load
5423 +   instruction the range is somewhere between 256 bytes and 4k.  This
5424 +   means that we often have to dump a constant inside a function, and
5425 +   generate code to branch around it.
5426 +
5427 +   It is important to minimize this, since the branches will slow
5428 +   things down and make the code larger.
5429 +
5430 +   Normally we can hide the table after an existing unconditional
5431 +   branch so that there is no interruption of the flow, but in the
5432 +   worst case the code looks like this:
5433 +
5434 +       lddpc   rn, L1
5435 +       ...
5436 +       rjmp    L2
5437 +       align
5438 +       L1:     .long value
5439 +       L2:
5440 +       ...
5441 +
5442 +       lddpc   rn, L3
5443 +       ...
5444 +       rjmp    L4
5445 +       align
5446 +       L3:     .long value
5447 +       L4:
5448 +       ...
5449 +
5450 +   We fix this by performing a scan after scheduling, which notices
5451 +   which instructions need to have their operands fetched from the
5452 +   constant table and builds the table.
5453 +
5454 +   The algorithm starts by building a table of all the constants that
5455 +   need fixing up and all the natural barriers in the function (places
5456 +   where a constant table can be dropped without breaking the flow).
5457 +   For each fixup we note how far the pc-relative replacement will be
5458 +   able to reach and the offset of the instruction into the function.
5459 +
5460 +   Having built the table we then group the fixes together to form
5461 +   tables that are as large as possible (subject to addressing
5462 +   constraints) and emit each table of constants after the last
5463 +   barrier that is within range of all the instructions in the group.
5464 +   If a group does not contain a barrier, then we forcibly create one
5465 +   by inserting a jump instruction into the flow.  Once the table has
5466 +   been inserted, the insns are then modified to reference the
5467 +   relevant entry in the pool.
5468 +
5469 +   Possible enhancements to the algorithm (not implemented) are:
5470 +
5471 +   1) For some processors and object formats, there may be benefit in
5472 +   aligning the pools to the start of cache lines; this alignment
5473 +   would need to be taken into account when calculating addressability
5474 +   of a pool.  */
5475 +
5476 +/* These typedefs are located at the start of this file, so that
5477 +   they can be used in the prototypes there.  This comment is to
5478 +   remind readers of that fact so that the following structures
5479 +   can be understood more easily.
5480 +
5481 +     typedef struct minipool_node    Mnode;
5482 +     typedef struct minipool_fixup   Mfix;  */
5483 +
5484 +struct minipool_node
5485 +{
5486 +  /* Doubly linked chain of entries.  */
5487 +  Mnode *next;
5488 +  Mnode *prev;
5489 +  /* The maximum offset into the code that this entry can be placed.  While
5490 +     pushing fixes for forward references, all entries are sorted in order of
5491 +     increasing max_address.  */
5492 +  HOST_WIDE_INT max_address;
5493 +  /* Similarly for an entry inserted for a backwards ref.  */
5494 +  HOST_WIDE_INT min_address;
5495 +  /* The number of fixes referencing this entry.  This can become zero if we
5496 +     "unpush" an entry.  In this case we ignore the entry when we come to
5497 +     emit the code.  */
5498 +  int refcount;
5499 +  /* The offset from the start of the minipool.  */
5500 +  HOST_WIDE_INT offset;
5501 +  /* The value in table.  */
5502 +  rtx value;
5503 +  /* The mode of value.  */
5504 +  enum machine_mode mode;
5505 +  /* The size of the value.  */
5506 +  int fix_size;
5507 +};
5508 +
5509 +
5510 +struct minipool_fixup
5511 +{
5512 +  Mfix *next;
5513 +  rtx insn;
5514 +  HOST_WIDE_INT address;
5515 +  rtx *loc;
5516 +  enum machine_mode mode;
5517 +  int fix_size;
5518 +  rtx value;
5519 +  Mnode *minipool;
5520 +  HOST_WIDE_INT forwards;
5521 +  HOST_WIDE_INT backwards;
5522 +};
5523 +
5524 +
5525 +/* Fixes less than a word need padding out to a word boundary.  */
5526 +#define MINIPOOL_FIX_SIZE(mode, value)                          \
5527 +  (IS_FORCE_MINIPOOL(value) ? 0 :                               \
5528 +   (GET_MODE_SIZE ((mode)) >= 4 ? GET_MODE_SIZE ((mode)) : 4))
5529 +
5530 +#define IS_FORCE_MINIPOOL(x)                    \
5531 +  (GET_CODE(x) == UNSPEC &&                     \
5532 +   XINT(x, 1) == UNSPEC_FORCE_MINIPOOL)
5533 +
5534 +static Mnode *minipool_vector_head;
5535 +static Mnode *minipool_vector_tail;
5536 +
5537 +/* The linked list of all minipool fixes required for this function.  */
5538 +Mfix *minipool_fix_head;
5539 +Mfix *minipool_fix_tail;
5540 +/* The fix entry for the current minipool, once it has been placed.  */
5541 +Mfix *minipool_barrier;
5542 +
5543 +
5544 +/* Determines if INSN is the start of a jump table.  Returns the end
5545 +   of the TABLE or NULL_RTX.  */
5546 +static rtx
5547 +is_jump_table (rtx insn)
5548 +{
5549 +  rtx table;
5550 +
5551 +  if (GET_CODE (insn) == JUMP_INSN
5552 +      && JUMP_LABEL (insn) != NULL
5553 +      && ((table = next_real_insn (JUMP_LABEL (insn)))
5554 +         == next_real_insn (insn))
5555 +      && table != NULL
5556 +      && GET_CODE (table) == JUMP_INSN
5557 +      && (GET_CODE (PATTERN (table)) == ADDR_VEC
5558 +         || GET_CODE (PATTERN (table)) == ADDR_DIFF_VEC))
5559 +    return table;
5560 +
5561 +  return NULL_RTX;
5562 +}
5563 +
5564 +
5565 +static HOST_WIDE_INT
5566 +get_jump_table_size (rtx insn)
5567 +{
5568 +  /* ADDR_VECs only take room if read-only data does into the text section.  */
5569 +  if (JUMP_TABLES_IN_TEXT_SECTION
5570 +#if !defined(READONLY_DATA_SECTION_ASM_OP)
5571 +      || 1
5572 +#endif
5573 +    )
5574 +    {
5575 +      rtx body = PATTERN (insn);
5576 +      int elt = GET_CODE (body) == ADDR_DIFF_VEC ? 1 : 0;
5577 +
5578 +      return GET_MODE_SIZE (GET_MODE (body)) * XVECLEN (body, elt);
5579 +    }
5580 +
5581 +  return 0;
5582 +}
5583 +
5584 +
5585 +/* Move a minipool fix MP from its current location to before MAX_MP.
5586 +   If MAX_MP is NULL, then MP doesn't need moving, but the addressing
5587 +   constraints may need updating.  */
5588 +static Mnode *
5589 +move_minipool_fix_forward_ref (Mnode * mp, Mnode * max_mp,
5590 +                              HOST_WIDE_INT max_address)
5591 +{
5592 +  /* This should never be true and the code below assumes these are
5593 +     different.  */
5594 +  if (mp == max_mp)
5595 +    abort ();
5596 +
5597 +  if (max_mp == NULL)
5598 +    {
5599 +      if (max_address < mp->max_address)
5600 +       mp->max_address = max_address;
5601 +    }
5602 +  else
5603 +    {
5604 +      if (max_address > max_mp->max_address - mp->fix_size)
5605 +       mp->max_address = max_mp->max_address - mp->fix_size;
5606 +      else
5607 +       mp->max_address = max_address;
5608 +
5609 +      /* Unlink MP from its current position.  Since max_mp is non-null,
5610 +         mp->prev must be non-null.  */
5611 +      mp->prev->next = mp->next;
5612 +      if (mp->next != NULL)
5613 +       mp->next->prev = mp->prev;
5614 +      else
5615 +       minipool_vector_tail = mp->prev;
5616 +
5617 +      /* Re-insert it before MAX_MP.  */
5618 +      mp->next = max_mp;
5619 +      mp->prev = max_mp->prev;
5620 +      max_mp->prev = mp;
5621 +
5622 +      if (mp->prev != NULL)
5623 +       mp->prev->next = mp;
5624 +      else
5625 +       minipool_vector_head = mp;
5626 +    }
5627 +
5628 +  /* Save the new entry.  */
5629 +  max_mp = mp;
5630 +
5631 +  /* Scan over the preceding entries and adjust their addresses as required.
5632 +   */
5633 +  while (mp->prev != NULL
5634 +        && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5635 +    {
5636 +      mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5637 +      mp = mp->prev;
5638 +    }
5639 +
5640 +  return max_mp;
5641 +}
5642 +
5643 +
5644 +/* Add a constant to the minipool for a forward reference.  Returns the
5645 +   node added or NULL if the constant will not fit in this pool.  */
5646 +static Mnode *
5647 +add_minipool_forward_ref (Mfix * fix)
5648 +{
5649 +  /* If set, max_mp is the first pool_entry that has a lower constraint than
5650 +     the one we are trying to add.  */
5651 +  Mnode *max_mp = NULL;
5652 +  HOST_WIDE_INT max_address = fix->address + fix->forwards;
5653 +  Mnode *mp;
5654 +
5655 +  /* If this fix's address is greater than the address of the first entry,
5656 +     then we can't put the fix in this pool.  We subtract the size of the
5657 +     current fix to ensure that if the table is fully packed we still have
5658 +     enough room to insert this value by suffling the other fixes forwards.  */
5659 +  if (minipool_vector_head &&
5660 +      fix->address >= minipool_vector_head->max_address - fix->fix_size)
5661 +    return NULL;
5662 +
5663 +  /* Scan the pool to see if a constant with the same value has already been
5664 +     added.  While we are doing this, also note the location where we must
5665 +     insert the constant if it doesn't already exist.  */
5666 +  for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5667 +    {
5668 +      if (GET_CODE (fix->value) == GET_CODE (mp->value)
5669 +         && fix->mode == mp->mode
5670 +         && (GET_CODE (fix->value) != CODE_LABEL
5671 +             || (CODE_LABEL_NUMBER (fix->value)
5672 +                 == CODE_LABEL_NUMBER (mp->value)))
5673 +         && rtx_equal_p (fix->value, mp->value))
5674 +       {
5675 +         /* More than one fix references this entry.  */
5676 +         mp->refcount++;
5677 +         return move_minipool_fix_forward_ref (mp, max_mp, max_address);
5678 +       }
5679 +
5680 +      /* Note the insertion point if necessary.  */
5681 +      if (max_mp == NULL && mp->max_address > max_address)
5682 +       max_mp = mp;
5683 +
5684 +    }
5685 +
5686 +  /* The value is not currently in the minipool, so we need to create a new
5687 +     entry for it.  If MAX_MP is NULL, the entry will be put on the end of
5688 +     the list since the placement is less constrained than any existing
5689 +     entry.  Otherwise, we insert the new fix before MAX_MP and, if
5690 +     necessary, adjust the constraints on the other entries.  */
5691 +  mp = xmalloc (sizeof (*mp));
5692 +  mp->fix_size = fix->fix_size;
5693 +  mp->mode = fix->mode;
5694 +  mp->value = fix->value;
5695 +  mp->refcount = 1;
5696 +  /* Not yet required for a backwards ref.  */
5697 +  mp->min_address = -65536;
5698 +
5699 +  if (max_mp == NULL)
5700 +    {
5701 +      mp->max_address = max_address;
5702 +      mp->next = NULL;
5703 +      mp->prev = minipool_vector_tail;
5704 +
5705 +      if (mp->prev == NULL)
5706 +       {
5707 +         minipool_vector_head = mp;
5708 +         minipool_vector_label = gen_label_rtx ();
5709 +       }
5710 +      else
5711 +       mp->prev->next = mp;
5712 +
5713 +      minipool_vector_tail = mp;
5714 +    }
5715 +  else
5716 +    {
5717 +      if (max_address > max_mp->max_address - mp->fix_size)
5718 +       mp->max_address = max_mp->max_address - mp->fix_size;
5719 +      else
5720 +       mp->max_address = max_address;
5721 +
5722 +      mp->next = max_mp;
5723 +      mp->prev = max_mp->prev;
5724 +      max_mp->prev = mp;
5725 +      if (mp->prev != NULL)
5726 +       mp->prev->next = mp;
5727 +      else
5728 +       minipool_vector_head = mp;
5729 +    }
5730 +
5731 +  /* Save the new entry.  */
5732 +  max_mp = mp;
5733 +
5734 +  /* Scan over the preceding entries and adjust their addresses as required.
5735 +   */
5736 +  while (mp->prev != NULL
5737 +        && mp->prev->max_address > mp->max_address - mp->prev->fix_size)
5738 +    {
5739 +      mp->prev->max_address = mp->max_address - mp->prev->fix_size;
5740 +      mp = mp->prev;
5741 +    }
5742 +
5743 +  return max_mp;
5744 +}
5745 +
5746 +
5747 +static Mnode *
5748 +move_minipool_fix_backward_ref (Mnode * mp, Mnode * min_mp,
5749 +                               HOST_WIDE_INT min_address)
5750 +{
5751 +  HOST_WIDE_INT offset;
5752 +
5753 +  /* This should never be true, and the code below assumes these are
5754 +     different.  */
5755 +  if (mp == min_mp)
5756 +    abort ();
5757 +
5758 +  if (min_mp == NULL)
5759 +    {
5760 +      if (min_address > mp->min_address)
5761 +       mp->min_address = min_address;
5762 +    }
5763 +  else
5764 +    {
5765 +      /* We will adjust this below if it is too loose.  */
5766 +      mp->min_address = min_address;
5767 +
5768 +      /* Unlink MP from its current position.  Since min_mp is non-null,
5769 +         mp->next must be non-null.  */
5770 +      mp->next->prev = mp->prev;
5771 +      if (mp->prev != NULL)
5772 +       mp->prev->next = mp->next;
5773 +      else
5774 +       minipool_vector_head = mp->next;
5775 +
5776 +      /* Reinsert it after MIN_MP.  */
5777 +      mp->prev = min_mp;
5778 +      mp->next = min_mp->next;
5779 +      min_mp->next = mp;
5780 +      if (mp->next != NULL)
5781 +       mp->next->prev = mp;
5782 +      else
5783 +       minipool_vector_tail = mp;
5784 +    }
5785 +
5786 +  min_mp = mp;
5787 +
5788 +  offset = 0;
5789 +  for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5790 +    {
5791 +      mp->offset = offset;
5792 +      if (mp->refcount > 0)
5793 +       offset += mp->fix_size;
5794 +
5795 +      if (mp->next && mp->next->min_address < mp->min_address + mp->fix_size)
5796 +       mp->next->min_address = mp->min_address + mp->fix_size;
5797 +    }
5798 +
5799 +  return min_mp;
5800 +}
5801 +
5802 +
5803 +/* Add a constant to the minipool for a backward reference.  Returns the
5804 +   node added or NULL if the constant will not fit in this pool.
5805 +
5806 +   Note that the code for insertion for a backwards reference can be
5807 +   somewhat confusing because the calculated offsets for each fix do
5808 +   not take into account the size of the pool (which is still under
5809 +   construction.  */
5810 +static Mnode *
5811 +add_minipool_backward_ref (Mfix * fix)
5812 +{
5813 +  /* If set, min_mp is the last pool_entry that has a lower constraint than
5814 +     the one we are trying to add.  */
5815 +  Mnode *min_mp = NULL;
5816 +  /* This can be negative, since it is only a constraint.  */
5817 +  HOST_WIDE_INT min_address = fix->address - fix->backwards;
5818 +  Mnode *mp;
5819 +
5820 +  /* If we can't reach the current pool from this insn, or if we can't insert
5821 +     this entry at the end of the pool without pushing other fixes out of
5822 +     range, then we don't try.  This ensures that we can't fail later on.  */
5823 +  if (min_address >= minipool_barrier->address
5824 +      || (minipool_vector_tail->min_address + fix->fix_size
5825 +         >= minipool_barrier->address))
5826 +    return NULL;
5827 +
5828 +  /* Scan the pool to see if a constant with the same value has already been
5829 +     added.  While we are doing this, also note the location where we must
5830 +     insert the constant if it doesn't already exist.  */
5831 +  for (mp = minipool_vector_tail; mp != NULL; mp = mp->prev)
5832 +    {
5833 +      if (GET_CODE (fix->value) == GET_CODE (mp->value)
5834 +         && fix->mode == mp->mode
5835 +         && (GET_CODE (fix->value) != CODE_LABEL
5836 +             || (CODE_LABEL_NUMBER (fix->value)
5837 +                 == CODE_LABEL_NUMBER (mp->value)))
5838 +         && rtx_equal_p (fix->value, mp->value)
5839 +         /* Check that there is enough slack to move this entry to the end
5840 +            of the table (this is conservative).  */
5841 +         && (mp->max_address
5842 +             > (minipool_barrier->address
5843 +                + minipool_vector_tail->offset
5844 +                + minipool_vector_tail->fix_size)))
5845 +       {
5846 +         mp->refcount++;
5847 +         return move_minipool_fix_backward_ref (mp, min_mp, min_address);
5848 +       }
5849 +
5850 +      if (min_mp != NULL)
5851 +       mp->min_address += fix->fix_size;
5852 +      else
5853 +       {
5854 +         /* Note the insertion point if necessary.  */
5855 +         if (mp->min_address < min_address)
5856 +           {
5857 +             min_mp = mp;
5858 +           }
5859 +         else if (mp->max_address
5860 +                  < minipool_barrier->address + mp->offset + fix->fix_size)
5861 +           {
5862 +             /* Inserting before this entry would push the fix beyond its
5863 +                maximum address (which can happen if we have re-located a
5864 +                forwards fix); force the new fix to come after it.  */
5865 +             min_mp = mp;
5866 +             min_address = mp->min_address + fix->fix_size;
5867 +           }
5868 +       }
5869 +    }
5870 +
5871 +  /* We need to create a new entry.  */
5872 +  mp = xmalloc (sizeof (*mp));
5873 +  mp->fix_size = fix->fix_size;
5874 +  mp->mode = fix->mode;
5875 +  mp->value = fix->value;
5876 +  mp->refcount = 1;
5877 +  mp->max_address = minipool_barrier->address + 65536;
5878 +
5879 +  mp->min_address = min_address;
5880 +
5881 +  if (min_mp == NULL)
5882 +    {
5883 +      mp->prev = NULL;
5884 +      mp->next = minipool_vector_head;
5885 +
5886 +      if (mp->next == NULL)
5887 +       {
5888 +         minipool_vector_tail = mp;
5889 +         minipool_vector_label = gen_label_rtx ();
5890 +       }
5891 +      else
5892 +       mp->next->prev = mp;
5893 +
5894 +      minipool_vector_head = mp;
5895 +    }
5896 +  else
5897 +    {
5898 +      mp->next = min_mp->next;
5899 +      mp->prev = min_mp;
5900 +      min_mp->next = mp;
5901 +
5902 +      if (mp->next != NULL)
5903 +       mp->next->prev = mp;
5904 +      else
5905 +       minipool_vector_tail = mp;
5906 +    }
5907 +
5908 +  /* Save the new entry.  */
5909 +  min_mp = mp;
5910 +
5911 +  if (mp->prev)
5912 +    mp = mp->prev;
5913 +  else
5914 +    mp->offset = 0;
5915 +
5916 +  /* Scan over the following entries and adjust their offsets.  */
5917 +  while (mp->next != NULL)
5918 +    {
5919 +      if (mp->next->min_address < mp->min_address + mp->fix_size)
5920 +       mp->next->min_address = mp->min_address + mp->fix_size;
5921 +
5922 +      if (mp->refcount)
5923 +       mp->next->offset = mp->offset + mp->fix_size;
5924 +      else
5925 +       mp->next->offset = mp->offset;
5926 +
5927 +      mp = mp->next;
5928 +    }
5929 +
5930 +  return min_mp;
5931 +}
5932 +
5933 +
5934 +static void
5935 +assign_minipool_offsets (Mfix * barrier)
5936 +{
5937 +  HOST_WIDE_INT offset = 0;
5938 +  Mnode *mp;
5939 +
5940 +  minipool_barrier = barrier;
5941 +
5942 +  for (mp = minipool_vector_head; mp != NULL; mp = mp->next)
5943 +    {
5944 +      mp->offset = offset;
5945 +
5946 +      if (mp->refcount > 0)
5947 +       offset += mp->fix_size;
5948 +    }
5949 +}
5950 +
5951 +
5952 +/* Print a symbolic form of X to the debug file, F.  */
5953 +static void
5954 +avr32_print_value (FILE * f, rtx x)
5955 +{
5956 +  switch (GET_CODE (x))
5957 +    {
5958 +    case CONST_INT:
5959 +      fprintf (f, "0x%x", (int) INTVAL (x));
5960 +      return;
5961 +
5962 +    case CONST_DOUBLE:
5963 +      fprintf (f, "<0x%lx,0x%lx>", (long) XWINT (x, 2), (long) XWINT (x, 3));
5964 +      return;
5965 +
5966 +    case CONST_VECTOR:
5967 +      {
5968 +       int i;
5969 +
5970 +       fprintf (f, "<");
5971 +       for (i = 0; i < CONST_VECTOR_NUNITS (x); i++)
5972 +         {
5973 +           fprintf (f, "0x%x", (int) INTVAL (CONST_VECTOR_ELT (x, i)));
5974 +           if (i < (CONST_VECTOR_NUNITS (x) - 1))
5975 +             fputc (',', f);
5976 +         }
5977 +       fprintf (f, ">");
5978 +      }
5979 +      return;
5980 +
5981 +    case CONST_STRING:
5982 +      fprintf (f, "\"%s\"", XSTR (x, 0));
5983 +      return;
5984 +
5985 +    case SYMBOL_REF:
5986 +      fprintf (f, "`%s'", XSTR (x, 0));
5987 +      return;
5988 +
5989 +    case LABEL_REF:
5990 +      fprintf (f, "L%d", INSN_UID (XEXP (x, 0)));
5991 +      return;
5992 +
5993 +    case CONST:
5994 +      avr32_print_value (f, XEXP (x, 0));
5995 +      return;
5996 +
5997 +    case PLUS:
5998 +      avr32_print_value (f, XEXP (x, 0));
5999 +      fprintf (f, "+");
6000 +      avr32_print_value (f, XEXP (x, 1));
6001 +      return;
6002 +
6003 +    case PC:
6004 +      fprintf (f, "pc");
6005 +      return;
6006 +
6007 +    default:
6008 +      fprintf (f, "????");
6009 +      return;
6010 +    }
6011 +}
6012 +
6013 +
6014 +int
6015 +is_minipool_label (rtx label)
6016 +{
6017 +  minipool_labels *cur_mp_label = cfun->machine->minipool_label_head;
6018 +
6019 +  if (GET_CODE (label) != CODE_LABEL)
6020 +    return FALSE;
6021 +
6022 +  while (cur_mp_label)
6023 +    {
6024 +      if (CODE_LABEL_NUMBER (label)
6025 +         == CODE_LABEL_NUMBER (cur_mp_label->label))
6026 +       return TRUE;
6027 +      cur_mp_label = cur_mp_label->next;
6028 +    }
6029 +  return FALSE;
6030 +}
6031 +
6032 +
6033 +static void
6034 +new_minipool_label (rtx label)
6035 +{
6036 +  if (!cfun->machine->minipool_label_head)
6037 +    {
6038 +      cfun->machine->minipool_label_head =
6039 +       ggc_alloc (sizeof (minipool_labels));
6040 +      cfun->machine->minipool_label_tail = cfun->machine->minipool_label_head;
6041 +      cfun->machine->minipool_label_head->label = label;
6042 +      cfun->machine->minipool_label_head->next = 0;
6043 +      cfun->machine->minipool_label_head->prev = 0;
6044 +    }
6045 +  else
6046 +    {
6047 +      cfun->machine->minipool_label_tail->next =
6048 +       ggc_alloc (sizeof (minipool_labels));
6049 +      cfun->machine->minipool_label_tail->next->label = label;
6050 +      cfun->machine->minipool_label_tail->next->next = 0;
6051 +      cfun->machine->minipool_label_tail->next->prev =
6052 +       cfun->machine->minipool_label_tail;
6053 +      cfun->machine->minipool_label_tail =
6054 +       cfun->machine->minipool_label_tail->next;
6055 +    }
6056 +}
6057 +
6058 +
6059 +/* Output the literal table */
6060 +static void
6061 +dump_minipool (rtx scan)
6062 +{
6063 +  Mnode *mp;
6064 +  Mnode *nmp;
6065 +
6066 +  if (dump_file)
6067 +    fprintf (dump_file,
6068 +            ";; Emitting minipool after insn %u; address %ld; align %d (bytes)\n",
6069 +            INSN_UID (scan), (unsigned long) minipool_barrier->address, 4);
6070 +
6071 +  scan = emit_insn_after (gen_consttable_start (), scan);
6072 +  scan = emit_insn_after (gen_align_4 (), scan);
6073 +  scan = emit_label_after (minipool_vector_label, scan);
6074 +  new_minipool_label (minipool_vector_label);
6075 +
6076 +  for (mp = minipool_vector_head; mp != NULL; mp = nmp)
6077 +    {
6078 +      if (mp->refcount > 0)
6079 +       {
6080 +         if (dump_file)
6081 +           {
6082 +             fprintf (dump_file,
6083 +                      ";;  Offset %u, min %ld, max %ld ",
6084 +                      (unsigned) mp->offset, (unsigned long) mp->min_address,
6085 +                      (unsigned long) mp->max_address);
6086 +             avr32_print_value (dump_file, mp->value);
6087 +             fputc ('\n', dump_file);
6088 +           }
6089 +
6090 +         switch (mp->fix_size)
6091 +           {
6092 +#ifdef HAVE_consttable_4
6093 +           case 4:
6094 +             scan = emit_insn_after (gen_consttable_4 (mp->value), scan);
6095 +             break;
6096 +
6097 +#endif
6098 +#ifdef HAVE_consttable_8
6099 +           case 8:
6100 +             scan = emit_insn_after (gen_consttable_8 (mp->value), scan);
6101 +             break;
6102 +
6103 +#endif
6104 +#ifdef HAVE_consttable_16
6105 +            case 16:
6106 +              scan = emit_insn_after (gen_consttable_16 (mp->value), scan);
6107 +              break;
6108 +
6109 +#endif
6110 +            case 0:
6111 +              /* This can happen for force-minipool entries which just are
6112 +                there to force the minipool to be generate. */
6113 +             break;
6114 +           default:
6115 +             abort ();
6116 +             break;
6117 +           }
6118 +       }
6119 +
6120 +      nmp = mp->next;
6121 +      free (mp);
6122 +    }
6123 +
6124 +  minipool_vector_head = minipool_vector_tail = NULL;
6125 +  scan = emit_insn_after (gen_consttable_end (), scan);
6126 +  scan = emit_barrier_after (scan);
6127 +}
6128 +
6129 +
6130 +/* Return the cost of forcibly inserting a barrier after INSN.  */
6131 +static int
6132 +avr32_barrier_cost (rtx insn)
6133 +{
6134 +  /* Basing the location of the pool on the loop depth is preferable, but at
6135 +     the moment, the basic block information seems to be corrupt by this
6136 +     stage of the compilation.  */
6137 +  int base_cost = 50;
6138 +  rtx next = next_nonnote_insn (insn);
6139 +
6140 +  if (next != NULL && GET_CODE (next) == CODE_LABEL)
6141 +    base_cost -= 20;
6142 +
6143 +  switch (GET_CODE (insn))
6144 +    {
6145 +    case CODE_LABEL:
6146 +      /* It will always be better to place the table before the label, rather
6147 +         than after it.  */
6148 +      return 50;
6149 +
6150 +    case INSN:
6151 +    case CALL_INSN:
6152 +      return base_cost;
6153 +
6154 +    case JUMP_INSN:
6155 +      return base_cost - 10;
6156 +
6157 +    default:
6158 +      return base_cost + 10;
6159 +    }
6160 +}
6161 +
6162 +
6163 +/* Find the best place in the insn stream in the range
6164 +   (FIX->address,MAX_ADDRESS) to forcibly insert a minipool barrier.
6165 +   Create the barrier by inserting a jump and add a new fix entry for
6166 +   it.  */
6167 +static Mfix *
6168 +create_fix_barrier (Mfix * fix, HOST_WIDE_INT max_address)
6169 +{
6170 +  HOST_WIDE_INT count = 0;
6171 +  rtx barrier;
6172 +  rtx from = fix->insn;
6173 +  rtx selected = from;
6174 +  int selected_cost;
6175 +  HOST_WIDE_INT selected_address;
6176 +  Mfix *new_fix;
6177 +  HOST_WIDE_INT max_count = max_address - fix->address;
6178 +  rtx label = gen_label_rtx ();
6179 +
6180 +  selected_cost = avr32_barrier_cost (from);
6181 +  selected_address = fix->address;
6182 +
6183 +  while (from && count < max_count)
6184 +    {
6185 +      rtx tmp;
6186 +      int new_cost;
6187 +
6188 +      /* This code shouldn't have been called if there was a natural barrier
6189 +         within range.  */
6190 +      if (GET_CODE (from) == BARRIER)
6191 +       abort ();
6192 +
6193 +      /* Count the length of this insn.  */
6194 +      count += get_attr_length (from);
6195 +
6196 +      /* If there is a jump table, add its length.  */
6197 +      tmp = is_jump_table (from);
6198 +      if (tmp != NULL)
6199 +       {
6200 +         count += get_jump_table_size (tmp);
6201 +
6202 +         /* Jump tables aren't in a basic block, so base the cost on the
6203 +            dispatch insn.  If we select this location, we will still put
6204 +            the pool after the table.  */
6205 +         new_cost = avr32_barrier_cost (from);
6206 +
6207 +         if (count < max_count && new_cost <= selected_cost)
6208 +           {
6209 +             selected = tmp;
6210 +             selected_cost = new_cost;
6211 +             selected_address = fix->address + count;
6212 +           }
6213 +
6214 +         /* Continue after the dispatch table.  */
6215 +         from = NEXT_INSN (tmp);
6216 +         continue;
6217 +       }
6218 +
6219 +      new_cost = avr32_barrier_cost (from);
6220 +
6221 +      if (count < max_count && new_cost <= selected_cost)
6222 +       {
6223 +         selected = from;
6224 +         selected_cost = new_cost;
6225 +         selected_address = fix->address + count;
6226 +       }
6227 +
6228 +      from = NEXT_INSN (from);
6229 +    }
6230 +
6231 +  /* Create a new JUMP_INSN that branches around a barrier.  */
6232 +  from = emit_jump_insn_after (gen_jump (label), selected);
6233 +  JUMP_LABEL (from) = label;
6234 +  barrier = emit_barrier_after (from);
6235 +  emit_label_after (label, barrier);
6236 +
6237 +  /* Create a minipool barrier entry for the new barrier.  */
6238 +  new_fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*new_fix));
6239 +  new_fix->insn = barrier;
6240 +  new_fix->address = selected_address;
6241 +  new_fix->next = fix->next;
6242 +  fix->next = new_fix;
6243 +
6244 +  return new_fix;
6245 +}
6246 +
6247 +
6248 +/* Record that there is a natural barrier in the insn stream at
6249 +   ADDRESS.  */
6250 +static void
6251 +push_minipool_barrier (rtx insn, HOST_WIDE_INT address)
6252 +{
6253 +  Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
6254 +
6255 +  fix->insn = insn;
6256 +  fix->address = address;
6257 +
6258 +  fix->next = NULL;
6259 +  if (minipool_fix_head != NULL)
6260 +    minipool_fix_tail->next = fix;
6261 +  else
6262 +    minipool_fix_head = fix;
6263 +
6264 +  minipool_fix_tail = fix;
6265 +}
6266 +
6267 +
6268 +/* Record INSN, which will need fixing up to load a value from the
6269 +   minipool.  ADDRESS is the offset of the insn since the start of the
6270 +   function; LOC is a pointer to the part of the insn which requires
6271 +   fixing; VALUE is the constant that must be loaded, which is of type
6272 +   MODE.  */
6273 +static void
6274 +push_minipool_fix (rtx insn, HOST_WIDE_INT address, rtx * loc,
6275 +                  enum machine_mode mode, rtx value)
6276 +{
6277 +  Mfix *fix = (Mfix *) obstack_alloc (&minipool_obstack, sizeof (*fix));
6278 +  rtx body = PATTERN (insn);
6279 +
6280 +  fix->insn = insn;
6281 +  fix->address = address;
6282 +  fix->loc = loc;
6283 +  fix->mode = mode;
6284 +  fix->fix_size = MINIPOOL_FIX_SIZE (mode, value);
6285 +  fix->value = value;
6286 +
6287 +  if (GET_CODE (body) == PARALLEL)
6288 +    {
6289 +      /* Mcall : Ks16 << 2 */
6290 +      fix->forwards = ((1 << 15) - 1) << 2;
6291 +      fix->backwards = (1 << 15) << 2;
6292 +    }
6293 +  else if (GET_CODE (body) == SET
6294 +           && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 4)
6295 +    {
6296 +          if (optimize_size)
6297 +            {
6298 +              /* Lddpc : Ku7 << 2 */
6299 +              fix->forwards = ((1 << 7) - 1) << 2;
6300 +              fix->backwards = 0;
6301 +            }
6302 +          else
6303 +            {
6304 +              /* Ld.w : Ks16 */
6305 +              fix->forwards = ((1 << 15) - 4);
6306 +              fix->backwards = (1 << 15);
6307 +            }
6308 +        }
6309 +  else if (GET_CODE (body) == SET
6310 +           && GET_MODE_SIZE (GET_MODE (SET_DEST (body))) == 8)
6311 +    {
6312 +          /* Ld.d : Ks16 */
6313 +          fix->forwards = ((1 << 15) - 4);
6314 +          fix->backwards = (1 << 15);
6315 +        }
6316 +  else if (GET_CODE (body) == UNSPEC_VOLATILE
6317 +           && XINT (body, 1) == VUNSPEC_MVRC)
6318 +    {
6319 +      /* Coprocessor load */
6320 +      /* Ldc : Ku8 << 2 */
6321 +      fix->forwards = ((1 << 8) - 1) << 2;
6322 +      fix->backwards = 0;
6323 +    }
6324 +  else
6325 +    {
6326 +      /* Assume worst case which is lddpc insn. */
6327 +      fix->forwards = ((1 << 7) - 1) << 2;
6328 +      fix->backwards = 0;
6329 +    }
6330 +
6331 +  fix->minipool = NULL;
6332 +
6333 +  /* If an insn doesn't have a range defined for it, then it isn't expecting
6334 +     to be reworked by this code.  Better to abort now than to generate duff
6335 +     assembly code.  */
6336 +  if (fix->forwards == 0 && fix->backwards == 0)
6337 +    abort ();
6338 +
6339 +  if (dump_file)
6340 +    {
6341 +      fprintf (dump_file,
6342 +              ";; %smode fixup for i%d; addr %lu, range (%ld,%ld): ",
6343 +              GET_MODE_NAME (mode),
6344 +              INSN_UID (insn), (unsigned long) address,
6345 +              -1 * (long) fix->backwards, (long) fix->forwards);
6346 +      avr32_print_value (dump_file, fix->value);
6347 +      fprintf (dump_file, "\n");
6348 +    }
6349 +
6350 +  /* Add it to the chain of fixes.  */
6351 +  fix->next = NULL;
6352 +
6353 +  if (minipool_fix_head != NULL)
6354 +    minipool_fix_tail->next = fix;
6355 +  else
6356 +    minipool_fix_head = fix;
6357 +
6358 +  minipool_fix_tail = fix;
6359 +}
6360 +
6361 +
6362 +/* Scan INSN and note any of its operands that need fixing.
6363 +   If DO_PUSHES is false we do not actually push any of the fixups
6364 +   needed.  The function returns TRUE is any fixups were needed/pushed.
6365 +   This is used by avr32_memory_load_p() which needs to know about loads
6366 +   of constants that will be converted into minipool loads.  */
6367 +static bool
6368 +note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
6369 +{
6370 +  bool result = false;
6371 +  int opno;
6372 +
6373 +  extract_insn (insn);
6374 +
6375 +  if (!constrain_operands (1))
6376 +    fatal_insn_not_found (insn);
6377 +
6378 +  if (recog_data.n_alternatives == 0)
6379 +    return false;
6380 +
6381 +  /* Fill in recog_op_alt with information about the constraints of this
6382 +     insn.  */
6383 +  preprocess_constraints ();
6384 +
6385 +  for (opno = 0; opno < recog_data.n_operands; opno++)
6386 +    {
6387 +      rtx op;
6388 +
6389 +      /* Things we need to fix can only occur in inputs.  */
6390 +      if (recog_data.operand_type[opno] != OP_IN)
6391 +       continue;
6392 +
6393 +      op = recog_data.operand[opno];
6394 +
6395 +      if (avr32_const_pool_ref_operand (op, GET_MODE (op)))
6396 +       {
6397 +         if (do_pushes)
6398 +           {
6399 +             rtx cop = avoid_constant_pool_reference (op);
6400 +
6401 +             /* Casting the address of something to a mode narrower than a
6402 +                word can cause avoid_constant_pool_reference() to return the
6403 +                pool reference itself.  That's no good to us here.  Lets
6404 +                just hope that we can use the constant pool value directly.
6405 +              */
6406 +             if (op == cop)
6407 +               cop = get_pool_constant (XEXP (op, 0));
6408 +
6409 +             push_minipool_fix (insn, address,
6410 +                                recog_data.operand_loc[opno],
6411 +                                recog_data.operand_mode[opno], cop);
6412 +           }
6413 +
6414 +         result = true;
6415 +       }
6416 +      else if (TARGET_HAS_ASM_ADDR_PSEUDOS
6417 +              && avr32_address_operand (op, GET_MODE (op)))
6418 +       {
6419 +         /* Handle pseudo instructions using a direct address. These pseudo
6420 +            instructions might need entries in the constant pool and we must
6421 +            therefor create a constant pool for them, in case the
6422 +            assembler/linker needs to insert entries. */
6423 +         if (do_pushes)
6424 +           {
6425 +             /* Push a dummy constant pool entry so that the .cpool
6426 +                directive should be inserted on the appropriate place in the
6427 +                code even if there are no real constant pool entries. This
6428 +                is used by the assembler and linker to know where to put
6429 +                generated constant pool entries. */
6430 +             push_minipool_fix (insn, address,
6431 +                                recog_data.operand_loc[opno],
6432 +                                recog_data.operand_mode[opno],
6433 +                                gen_rtx_UNSPEC (VOIDmode,
6434 +                                                gen_rtvec (1, const0_rtx),
6435 +                                                UNSPEC_FORCE_MINIPOOL));
6436 +             result = true;
6437 +           }
6438 +       }
6439 +    }
6440 +  return result;
6441 +}
6442 +
6443 +
6444 +static int
6445 +avr32_insn_is_cast (rtx insn)
6446 +{
6447 +
6448 +  if (NONJUMP_INSN_P (insn)
6449 +      && GET_CODE (PATTERN (insn)) == SET
6450 +      && (GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTEND
6451 +         || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTEND)
6452 +      && REG_P (XEXP (SET_SRC (PATTERN (insn)), 0))
6453 +      && REG_P (SET_DEST (PATTERN (insn))))
6454 +    return true;
6455 +  return false;
6456 +}
6457 +
6458 +
6459 +/* Replace all occurances of reg FROM with reg TO in X. */
6460 +rtx
6461 +avr32_replace_reg (rtx x, rtx from, rtx to)
6462 +{
6463 +  int i, j;
6464 +  const char *fmt;
6465 +
6466 +  gcc_assert ( REG_P (from) && REG_P (to) );
6467 +
6468 +  /* Allow this function to make replacements in EXPR_LISTs.  */
6469 +  if (x == 0)
6470 +    return 0;
6471 +
6472 +  if (rtx_equal_p (x, from))
6473 +    return to;
6474 +
6475 +  if (GET_CODE (x) == SUBREG)
6476 +    {
6477 +      rtx new = avr32_replace_reg (SUBREG_REG (x), from, to);
6478 +
6479 +      if (GET_CODE (new) == CONST_INT)
6480 +       {
6481 +         x = simplify_subreg (GET_MODE (x), new,
6482 +                              GET_MODE (SUBREG_REG (x)),
6483 +                              SUBREG_BYTE (x));
6484 +         gcc_assert (x);
6485 +       }
6486 +      else
6487 +       SUBREG_REG (x) = new;
6488 +
6489 +      return x;
6490 +    }
6491 +  else if (GET_CODE (x) == ZERO_EXTEND)
6492 +    {
6493 +      rtx new = avr32_replace_reg (XEXP (x, 0), from, to);
6494 +
6495 +      if (GET_CODE (new) == CONST_INT)
6496 +       {
6497 +         x = simplify_unary_operation (ZERO_EXTEND, GET_MODE (x),
6498 +                                       new, GET_MODE (XEXP (x, 0)));
6499 +         gcc_assert (x);
6500 +       }
6501 +      else
6502 +       XEXP (x, 0) = new;
6503 +
6504 +      return x;
6505 +    }
6506 +
6507 +  fmt = GET_RTX_FORMAT (GET_CODE (x));
6508 +  for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
6509 +    {
6510 +      if (fmt[i] == 'e')
6511 +       XEXP (x, i) = avr32_replace_reg (XEXP (x, i), from, to);
6512 +      else if (fmt[i] == 'E')
6513 +       for (j = XVECLEN (x, i) - 1; j >= 0; j--)
6514 +         XVECEXP (x, i, j) = avr32_replace_reg (XVECEXP (x, i, j), from, to);
6515 +    }
6516 +
6517 +  return x;
6518 +}
6519 +
6520 +
6521 +/* FIXME: The level of nesting in this function is way too deep. It needs to be
6522 +   torn apart.  */
6523 +static void
6524 +avr32_reorg_optimization (void)
6525 +{
6526 +  rtx first = get_first_nonnote_insn ();
6527 +  rtx insn;
6528 +
6529 +  if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0)))
6530 +    {
6531 +
6532 +      /* Scan through all insns looking for cast operations. */
6533 +      if (dump_file)
6534 +       {
6535 +         fprintf (dump_file, ";; Deleting redundant cast operations:\n");
6536 +       }
6537 +      for (insn = first; insn; insn = NEXT_INSN (insn))
6538 +       {
6539 +         rtx reg, src_reg, scan;
6540 +         enum machine_mode mode;
6541 +         int unused_cast;
6542 +         rtx label_ref;
6543 +
6544 +         if (avr32_insn_is_cast (insn)
6545 +             && (GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == QImode
6546 +                 || GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == HImode))
6547 +           {
6548 +             mode = GET_MODE (XEXP (SET_SRC (PATTERN (insn)), 0));
6549 +             reg = SET_DEST (PATTERN (insn));
6550 +             src_reg = XEXP (SET_SRC (PATTERN (insn)), 0);
6551 +           }
6552 +         else
6553 +           {
6554 +             continue;
6555 +           }
6556 +
6557 +         unused_cast = false;
6558 +         label_ref = NULL_RTX;
6559 +         for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6560 +           {
6561 +             /* Check if we have reached the destination of a simple
6562 +                conditional jump which we have already scanned past. If so,
6563 +                we can safely continue scanning. */
6564 +             if (LABEL_P (scan) && label_ref != NULL_RTX)
6565 +               {
6566 +                 if (CODE_LABEL_NUMBER (scan) ==
6567 +                     CODE_LABEL_NUMBER (XEXP (label_ref, 0)))
6568 +                   label_ref = NULL_RTX;
6569 +                 else
6570 +                   break;
6571 +               }
6572 +
6573 +             if (!INSN_P (scan))
6574 +               continue;
6575 +
6576 +             /* For conditional jumps we can manage to keep on scanning if
6577 +                we meet the destination label later on before any new jump
6578 +                insns occure. */
6579 +             if (GET_CODE (scan) == JUMP_INSN)
6580 +               {
6581 +                 if (any_condjump_p (scan) && label_ref == NULL_RTX)
6582 +                   label_ref = condjump_label (scan);
6583 +                 else
6584 +                   break;
6585 +               }
6586 +
6587 +              /* Check if we have a call and the register is used as an argument. */
6588 +              if (CALL_P (scan)
6589 +                  && find_reg_fusage (scan, USE, reg) )
6590 +                break;
6591 +
6592 +             if (!reg_mentioned_p (reg, PATTERN (scan)))
6593 +               continue;
6594 +
6595 +             /* Check if casted register is used in this insn */
6596 +             if ((regno_use_in (REGNO (reg), PATTERN (scan)) != NULL_RTX)
6597 +                 && (GET_MODE (regno_use_in (REGNO (reg), PATTERN (scan))) ==
6598 +                     GET_MODE (reg)))
6599 +               {
6600 +                 /* If not used in the source to the set or in a memory
6601 +                    expression in the destiantion then the register is used
6602 +                    as a destination and is really dead. */
6603 +                 if (single_set (scan)
6604 +                     && GET_CODE (PATTERN (scan)) == SET
6605 +                     && REG_P (SET_DEST (PATTERN (scan)))
6606 +                     && !regno_use_in (REGNO (reg), SET_SRC (PATTERN (scan)))
6607 +                     && label_ref == NULL_RTX)
6608 +                   {
6609 +                     unused_cast = true;
6610 +                   }
6611 +                 break;
6612 +               }
6613 +
6614 +             /* Check if register is dead or set in this insn */
6615 +             if (dead_or_set_p (scan, reg))
6616 +               {
6617 +                 unused_cast = true;
6618 +                 break;
6619 +               }
6620 +           }
6621 +
6622 +         /* Check if we have unresolved conditional jumps */
6623 +         if (label_ref != NULL_RTX)
6624 +           continue;
6625 +
6626 +         if (unused_cast)
6627 +           {
6628 +             if (REGNO (reg) == REGNO (XEXP (SET_SRC (PATTERN (insn)), 0)))
6629 +               {
6630 +                 /* One operand cast, safe to delete */
6631 +                 if (dump_file)
6632 +                   {
6633 +                     fprintf (dump_file,
6634 +                              ";;  INSN %i removed, casted register %i value not used.\n",
6635 +                              INSN_UID (insn), REGNO (reg));
6636 +                   }
6637 +                 SET_INSN_DELETED (insn);
6638 +                 /* Force the instruction to be recognized again */
6639 +                 INSN_CODE (insn) = -1;
6640 +               }
6641 +             else
6642 +               {
6643 +                 /* Two operand cast, which really could be substituted with
6644 +                    a move, if the source register is dead after the cast
6645 +                    insn and then the insn which sets the source register
6646 +                    could instead directly set the destination register for
6647 +                    the cast. As long as there are no insns in between which
6648 +                    uses the register. */
6649 +                 rtx link = NULL_RTX;
6650 +                 rtx set;
6651 +                 rtx src_reg = XEXP (SET_SRC (PATTERN (insn)), 0);
6652 +                 unused_cast = false;
6653 +
6654 +                 if (!find_reg_note (insn, REG_DEAD, src_reg))
6655 +                   continue;
6656 +
6657 +                 /* Search for the insn which sets the source register */
6658 +                  for (scan = PREV_INSN (insn);
6659 +                       scan && GET_CODE (scan) != CODE_LABEL;
6660 +                       scan = PREV_INSN (scan))
6661 +                    {
6662 +                      if (! INSN_P (scan))
6663 +                        continue;
6664 +
6665 +                     set = single_set (scan);
6666 +                      // Fix for bug #11763 : the following if condition
6667 +                      // has been modified and else part is included to 
6668 +                      // set the link to NULL_RTX. 
6669 +                      // if (set && rtx_equal_p (src_reg, SET_DEST (set)))
6670 +                      if (set && (REGNO(src_reg) == REGNO(SET_DEST(set))))
6671 +                       {
6672 +                         if (rtx_equal_p (src_reg, SET_DEST (set)))
6673 +                         {
6674 +                           link = scan;
6675 +                           break;
6676 +                          }
6677 +                         else
6678 +                          {
6679 +                            link = NULL_RTX;
6680 +                            break;
6681 +                          }
6682 +                       }
6683 +                    }
6684 +
6685 +
6686 +                 /* Found no link or link is a call insn where we can not
6687 +                    change the destination register */
6688 +                 if (link == NULL_RTX || CALL_P (link))
6689 +                   continue;
6690 +
6691 +                 /* Scan through all insn between link and insn */
6692 +                 for (scan = NEXT_INSN (link); scan; scan = NEXT_INSN (scan))
6693 +                   {
6694 +                     /* Don't try to trace forward past a CODE_LABEL if we
6695 +                        haven't seen INSN yet.  Ordinarily, we will only
6696 +                        find the setting insn in LOG_LINKS if it is in the
6697 +                        same basic block.  However, cross-jumping can insert
6698 +                        code labels in between the load and the call, and
6699 +                        can result in situations where a single call insn
6700 +                        may have two targets depending on where we came
6701 +                        from.  */
6702 +
6703 +                     if (GET_CODE (scan) == CODE_LABEL)
6704 +                       break;
6705 +
6706 +                     if (!INSN_P (scan))
6707 +                       continue;
6708 +
6709 +                     /* Don't try to trace forward past a JUMP.  To optimize
6710 +                        safely, we would have to check that all the
6711 +                        instructions at the jump destination did not use REG.
6712 +                      */
6713 +
6714 +                     if (GET_CODE (scan) == JUMP_INSN)
6715 +                       {
6716 +                         break;
6717 +                       }
6718 +
6719 +                     if (!reg_mentioned_p (src_reg, PATTERN (scan)))
6720 +                       continue;
6721 +
6722 +                     /* We have reached the cast insn */
6723 +                     if (scan == insn)
6724 +                       {
6725 +                         /* We can remove cast and replace the destination
6726 +                            register of the link insn with the destination
6727 +                            of the cast */
6728 +                         if (dump_file)
6729 +                           {
6730 +                             fprintf (dump_file,
6731 +                                      ";;  INSN %i removed, casted value unused. "
6732 +                                      "Destination of removed cast operation: register %i,  folded into INSN %i.\n",
6733 +                                      INSN_UID (insn), REGNO (reg),
6734 +                                      INSN_UID (link));
6735 +                           }
6736 +                         /* Update link insn */
6737 +                         SET_DEST (PATTERN (link)) =
6738 +                           gen_rtx_REG (mode, REGNO (reg));
6739 +                         /* Force the instruction to be recognized again */
6740 +                         INSN_CODE (link) = -1;
6741 +
6742 +                         /* Delete insn */
6743 +                         SET_INSN_DELETED (insn);
6744 +                         /* Force the instruction to be recognized again */
6745 +                         INSN_CODE (insn) = -1;
6746 +                         break;
6747 +                       }
6748 +                   }
6749 +               }
6750 +           }
6751 +       }
6752 +    }
6753 +
6754 +  if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0)))
6755 +    {
6756 +
6757 +      /* Scan through all insns looking for shifted add operations */
6758 +      if (dump_file)
6759 +       {
6760 +         fprintf (dump_file,
6761 +                  ";; Deleting redundant shifted add operations:\n");
6762 +       }
6763 +      for (insn = first; insn; insn = NEXT_INSN (insn))
6764 +       {
6765 +         rtx reg, mem_expr, scan, op0, op1;
6766 +         int add_only_used_as_pointer;
6767 +
6768 +         if (INSN_P (insn)
6769 +             && GET_CODE (PATTERN (insn)) == SET
6770 +             && GET_CODE (SET_SRC (PATTERN (insn))) == PLUS
6771 +             && (GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == MULT
6772 +                 || GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0)) == ASHIFT)
6773 +             && GET_CODE (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 1)) ==
6774 +             CONST_INT && REG_P (SET_DEST (PATTERN (insn)))
6775 +             && REG_P (XEXP (SET_SRC (PATTERN (insn)), 1))
6776 +             && REG_P (XEXP (XEXP (SET_SRC (PATTERN (insn)), 0), 0)))
6777 +           {
6778 +             reg = SET_DEST (PATTERN (insn));
6779 +             mem_expr = SET_SRC (PATTERN (insn));
6780 +             op0 = XEXP (XEXP (mem_expr, 0), 0);
6781 +             op1 = XEXP (mem_expr, 1);
6782 +           }
6783 +         else
6784 +           {
6785 +             continue;
6786 +           }
6787 +
6788 +         /* Scan forward the check if the result of the shifted add
6789 +            operation is only used as an address in memory operations and
6790 +            that the operands to the shifted add are not clobbered. */
6791 +         add_only_used_as_pointer = false;
6792 +         for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6793 +           {
6794 +             if (!INSN_P (scan))
6795 +               continue;
6796 +
6797 +             /* Don't try to trace forward past a JUMP or CALL.  To optimize
6798 +                safely, we would have to check that all the instructions at
6799 +                the jump destination did not use REG.  */
6800 +
6801 +             if (GET_CODE (scan) == JUMP_INSN)
6802 +               {
6803 +                 break;
6804 +               }
6805 +
6806 +             /* If used in a call insn then we cannot optimize it away */
6807 +             if (CALL_P (scan) && find_regno_fusage (scan, USE, REGNO (reg)))
6808 +               break;
6809 +
6810 +             /* If any of the operands of the shifted add are clobbered we
6811 +                cannot optimize the shifted adda away */
6812 +             if ((reg_set_p (op0, scan) && (REGNO (op0) != REGNO (reg)))
6813 +                 || (reg_set_p (op1, scan) && (REGNO (op1) != REGNO (reg))))
6814 +               break;
6815 +
6816 +             if (!reg_mentioned_p (reg, PATTERN (scan)))
6817 +               continue;
6818 +
6819 +             /* If used any other place than as a pointer or as the
6820 +                destination register we failed */
6821 +              if (!(single_set (scan)
6822 +                    && GET_CODE (PATTERN (scan)) == SET
6823 +                    && ((MEM_P (SET_DEST (PATTERN (scan)))
6824 +                         && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0))
6825 +                         && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) == REGNO (reg))
6826 +                        || (MEM_P (SET_SRC (PATTERN (scan)))
6827 +                            && REG_P (XEXP (SET_SRC (PATTERN (scan)), 0))
6828 +                            && REGNO (XEXP
6829 +                                      (SET_SRC (PATTERN (scan)), 0)) == REGNO (reg))))
6830 +                  && !(GET_CODE (PATTERN (scan)) == SET
6831 +                       && REG_P (SET_DEST (PATTERN (scan)))
6832 +                       && !regno_use_in (REGNO (reg),
6833 +                                         SET_SRC (PATTERN (scan)))))
6834 +                break;
6835 +
6836 +              /* We cannot replace the pointer in TImode insns
6837 +                 as these has a differene addressing mode than the other
6838 +                 memory insns. */
6839 +              if ( GET_MODE (SET_DEST (PATTERN (scan))) == TImode )
6840 +                break;
6841 +
6842 +             /* Check if register is dead or set in this insn */
6843 +             if (dead_or_set_p (scan, reg))
6844 +               {
6845 +                 add_only_used_as_pointer = true;
6846 +                 break;
6847 +               }
6848 +           }
6849 +
6850 +         if (add_only_used_as_pointer)
6851 +           {
6852 +             /* Lets delete the add insn and replace all memory references
6853 +                which uses the pointer with the full expression. */
6854 +             if (dump_file)
6855 +               {
6856 +                 fprintf (dump_file,
6857 +                          ";; Deleting INSN %i since address expression can be folded into all "
6858 +                          "memory references using this expression\n",
6859 +                          INSN_UID (insn));
6860 +               }
6861 +             SET_INSN_DELETED (insn);
6862 +             /* Force the instruction to be recognized again */
6863 +             INSN_CODE (insn) = -1;
6864 +
6865 +             for (scan = NEXT_INSN (insn); scan; scan = NEXT_INSN (scan))
6866 +               {
6867 +                 if (!INSN_P (scan))
6868 +                   continue;
6869 +
6870 +                 if (!reg_mentioned_p (reg, PATTERN (scan)))
6871 +                   continue;
6872 +
6873 +                 /* If used any other place than as a pointer or as the
6874 +                    destination register we failed */
6875 +                 if ((single_set (scan)
6876 +                      && GET_CODE (PATTERN (scan)) == SET
6877 +                      && ((MEM_P (SET_DEST (PATTERN (scan)))
6878 +                           && REG_P (XEXP (SET_DEST (PATTERN (scan)), 0))
6879 +                           && REGNO (XEXP (SET_DEST (PATTERN (scan)), 0)) ==
6880 +                           REGNO (reg)) || (MEM_P (SET_SRC (PATTERN (scan)))
6881 +                                            &&
6882 +                                            REG_P (XEXP
6883 +                                                   (SET_SRC (PATTERN (scan)),
6884 +                                                    0))
6885 +                                            &&
6886 +                                            REGNO (XEXP
6887 +                                                   (SET_SRC (PATTERN (scan)),
6888 +                                                    0)) == REGNO (reg)))))
6889 +                   {
6890 +                     if (dump_file)
6891 +                       {
6892 +                         fprintf (dump_file,
6893 +                                  ";; Register %i replaced by indexed address in INSN %i\n",
6894 +                                  REGNO (reg), INSN_UID (scan));
6895 +                       }
6896 +                     if (MEM_P (SET_DEST (PATTERN (scan))))
6897 +                       XEXP (SET_DEST (PATTERN (scan)), 0) = mem_expr;
6898 +                     else
6899 +                       XEXP (SET_SRC (PATTERN (scan)), 0) = mem_expr;
6900 +                   }
6901 +
6902 +                 /* Check if register is dead or set in this insn */
6903 +                 if (dead_or_set_p (scan, reg))
6904 +                   {
6905 +                     break;
6906 +                   }
6907 +
6908 +               }
6909 +           }
6910 +       }
6911 +    }
6912 +
6913 +
6914 +  if (TARGET_MD_REORG_OPTIMIZATION && (optimize_size || (optimize > 0)))
6915 +    {
6916 +
6917 +      /* Scan through all insns looking for conditional register to
6918 +         register move operations */
6919 +      if (dump_file)
6920 +       {
6921 +         fprintf (dump_file,
6922 +                  ";; Folding redundant conditional move operations:\n");
6923 +       }
6924 +      for (insn = first; insn; insn = next_nonnote_insn (insn))
6925 +       {
6926 +         rtx src_reg, dst_reg, scan, test;
6927 +
6928 +         if (INSN_P (insn)
6929 +              && GET_CODE (PATTERN (insn)) == COND_EXEC
6930 +             && GET_CODE (COND_EXEC_CODE (PATTERN (insn))) == SET
6931 +             && REG_P (SET_SRC (COND_EXEC_CODE (PATTERN (insn))))
6932 +             && REG_P (SET_DEST (COND_EXEC_CODE (PATTERN (insn))))
6933 +              && find_reg_note (insn, REG_DEAD, SET_SRC (COND_EXEC_CODE (PATTERN (insn)))))
6934 +           {
6935 +             src_reg = SET_SRC (COND_EXEC_CODE (PATTERN (insn)));
6936 +             dst_reg = SET_DEST (COND_EXEC_CODE (PATTERN (insn)));
6937 +              test = COND_EXEC_TEST (PATTERN (insn));
6938 +           }
6939 +         else
6940 +           {
6941 +             continue;
6942 +           }
6943 +
6944 +          /* Scan backward through the rest of insns in this if-then or if-else
6945 +             block and check if we can fold the move into another of the conditional
6946 +             insns in the same block. */
6947 +          scan = prev_nonnote_insn (insn);
6948 +          while (INSN_P (scan)
6949 +                 && GET_CODE (PATTERN (scan)) == COND_EXEC
6950 +                 && rtx_equal_p (COND_EXEC_TEST (PATTERN (scan)), test))
6951 +            {
6952 +              rtx pattern = COND_EXEC_CODE (PATTERN (scan));
6953 +              if ( GET_CODE (pattern) == PARALLEL )
6954 +                pattern = XVECEXP (pattern, 0, 0);
6955 +
6956 +              if ( reg_set_p (src_reg, pattern) )
6957 +                {
6958 +                  /* Fold in the destination register for the cond. move
6959 +                     into this insn. */
6960 +                  SET_DEST (pattern) = dst_reg;
6961 +                  if (dump_file)
6962 +                    {
6963 +                      fprintf (dump_file,
6964 +                               ";; Deleting INSN %i since this operation can be folded into INSN %i\n",
6965 +                               INSN_UID (insn), INSN_UID (scan));
6966 +                    }
6967 +
6968 +                  /* Scan and check if any of the insns in between uses the src_reg. We
6969 +                     must then replace it with the dst_reg. */
6970 +                  while ( (scan = next_nonnote_insn (scan)) != insn ){
6971 +                    avr32_replace_reg (scan, src_reg, dst_reg);
6972 +                  }
6973 +                  /* Delete the insn. */
6974 +                  SET_INSN_DELETED (insn);
6975 +
6976 +                  /* Force the instruction to be recognized again */
6977 +                  INSN_CODE (insn) = -1;
6978 +                  break;
6979 +                }
6980 +
6981 +              /* If the destination register is used but not set in this insn
6982 +                 we cannot fold. */
6983 +              if ( reg_mentioned_p (dst_reg, pattern) )
6984 +                break;
6985 +
6986 +              scan = prev_nonnote_insn (scan);
6987 +            }
6988 +        }
6989 +    }
6990 +
6991 +}
6992 +
6993 +
6994 +/* Exported to toplev.c.
6995 +
6996 +   Do a final pass over the function, just before delayed branch
6997 +   scheduling.  */
6998 +static void
6999 +avr32_reorg (void)
7000 +{
7001 +  rtx insn;
7002 +  HOST_WIDE_INT address = 0;
7003 +  Mfix *fix;
7004 +
7005 +  minipool_fix_head = minipool_fix_tail = NULL;
7006 +
7007 +  /* The first insn must always be a note, or the code below won't scan it
7008 +     properly.  */
7009 +  insn = get_insns ();
7010 +  if (GET_CODE (insn) != NOTE)
7011 +    abort ();
7012 +
7013 +  /* Scan all the insns and record the operands that will need fixing.  */
7014 +  for (insn = next_nonnote_insn (insn); insn; insn = next_nonnote_insn (insn))
7015 +    {
7016 +      if (GET_CODE (insn) == BARRIER)
7017 +       push_minipool_barrier (insn, address);
7018 +      else if (INSN_P (insn))
7019 +       {
7020 +         rtx table;
7021 +
7022 +         note_invalid_constants (insn, address, true);
7023 +         address += get_attr_length (insn);
7024 +
7025 +         /* If the insn is a vector jump, add the size of the table and skip
7026 +            the table.  */
7027 +         if ((table = is_jump_table (insn)) != NULL)
7028 +           {
7029 +             address += get_jump_table_size (table);
7030 +             insn = table;
7031 +           }
7032 +       }
7033 +    }
7034 +
7035 +  fix = minipool_fix_head;
7036 +
7037 +  /* Now scan the fixups and perform the required changes.  */
7038 +  while (fix)
7039 +    {
7040 +      Mfix *ftmp;
7041 +      Mfix *fdel;
7042 +      Mfix *last_added_fix;
7043 +      Mfix *last_barrier = NULL;
7044 +      Mfix *this_fix;
7045 +
7046 +      /* Skip any further barriers before the next fix.  */
7047 +      while (fix && GET_CODE (fix->insn) == BARRIER)
7048 +       fix = fix->next;
7049 +
7050 +      /* No more fixes.  */
7051 +      if (fix == NULL)
7052 +       break;
7053 +
7054 +      last_added_fix = NULL;
7055 +
7056 +      for (ftmp = fix; ftmp; ftmp = ftmp->next)
7057 +       {
7058 +         if (GET_CODE (ftmp->insn) == BARRIER)
7059 +           {
7060 +             if (ftmp->address >= minipool_vector_head->max_address)
7061 +               break;
7062 +
7063 +             last_barrier = ftmp;
7064 +           }
7065 +         else if ((ftmp->minipool = add_minipool_forward_ref (ftmp)) == NULL)
7066 +           break;
7067 +
7068 +         last_added_fix = ftmp;        /* Keep track of the last fix added.
7069 +                                        */
7070 +       }
7071 +
7072 +      /* If we found a barrier, drop back to that; any fixes that we could
7073 +         have reached but come after the barrier will now go in the next
7074 +         mini-pool.  */
7075 +      if (last_barrier != NULL)
7076 +       {
7077 +         /* Reduce the refcount for those fixes that won't go into this pool
7078 +            after all.  */
7079 +         for (fdel = last_barrier->next;
7080 +              fdel && fdel != ftmp; fdel = fdel->next)
7081 +           {
7082 +             fdel->minipool->refcount--;
7083 +             fdel->minipool = NULL;
7084 +           }
7085 +
7086 +         ftmp = last_barrier;
7087 +       }
7088 +      else
7089 +       {
7090 +         /* ftmp is first fix that we can't fit into this pool and there no
7091 +            natural barriers that we could use.  Insert a new barrier in the
7092 +            code somewhere between the previous fix and this one, and
7093 +            arrange to jump around it.  */
7094 +         HOST_WIDE_INT max_address;
7095 +
7096 +         /* The last item on the list of fixes must be a barrier, so we can
7097 +            never run off the end of the list of fixes without last_barrier
7098 +            being set.  */
7099 +         if (ftmp == NULL)
7100 +           abort ();
7101 +
7102 +         max_address = minipool_vector_head->max_address;
7103 +         /* Check that there isn't another fix that is in range that we
7104 +            couldn't fit into this pool because the pool was already too
7105 +            large: we need to put the pool before such an instruction.  */
7106 +         if (ftmp->address < max_address)
7107 +           max_address = ftmp->address;
7108 +
7109 +         last_barrier = create_fix_barrier (last_added_fix, max_address);
7110 +       }
7111 +
7112 +      assign_minipool_offsets (last_barrier);
7113 +
7114 +      while (ftmp)
7115 +       {
7116 +         if (GET_CODE (ftmp->insn) != BARRIER
7117 +             && ((ftmp->minipool = add_minipool_backward_ref (ftmp))
7118 +                 == NULL))
7119 +           break;
7120 +
7121 +         ftmp = ftmp->next;
7122 +       }
7123 +
7124 +      /* Scan over the fixes we have identified for this pool, fixing them up
7125 +         and adding the constants to the pool itself.  */
7126 +        for (this_fix = fix; this_fix && ftmp != this_fix;
7127 +             this_fix = this_fix->next)
7128 +          if (GET_CODE (this_fix->insn) != BARRIER
7129 +              /* Do nothing for entries present just to force the insertion of
7130 +              a minipool. */
7131 +           && !IS_FORCE_MINIPOOL (this_fix->value))
7132 +         {
7133 +           rtx addr = plus_constant (gen_rtx_LABEL_REF (VOIDmode,
7134 +                                                        minipool_vector_label),
7135 +                                     this_fix->minipool->offset);
7136 +           *this_fix->loc = gen_rtx_MEM (this_fix->mode, addr);
7137 +         }
7138 +
7139 +      dump_minipool (last_barrier->insn);
7140 +      fix = ftmp;
7141 +    }
7142 +
7143 +  /* Free the minipool memory.  */
7144 +  obstack_free (&minipool_obstack, minipool_startobj);
7145 +
7146 +  avr32_reorg_optimization ();
7147 +}
7148 +
7149 +
7150 +/* Hook for doing some final scanning of instructions. Does nothing yet...*/
7151 +void
7152 +avr32_final_prescan_insn (rtx insn ATTRIBUTE_UNUSED,
7153 +                         rtx * opvec ATTRIBUTE_UNUSED,
7154 +                         int noperands ATTRIBUTE_UNUSED)
7155 +{
7156 +  return;
7157 +}
7158 +
7159 +
7160 +/* Function for changing the condition on the next instruction,
7161 +   should be used when emmiting compare instructions and
7162 +   the condition of the next instruction needs to change.
7163 +*/
7164 +int
7165 +set_next_insn_cond (rtx cur_insn, rtx new_cond)
7166 +{
7167 +  rtx next_insn = next_nonnote_insn (cur_insn);
7168 +   if ((next_insn != NULL_RTX)
7169 +       && (INSN_P (next_insn)))
7170 +     {
7171 +       if ((GET_CODE (PATTERN (next_insn)) == SET)
7172 +           && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE))
7173 +         {
7174 +           /* Branch instructions */
7175 +           XEXP (SET_SRC (PATTERN (next_insn)), 0) = new_cond;
7176 +           /* Force the instruction to be recognized again */
7177 +           INSN_CODE (next_insn) = -1;
7178 +           return TRUE;
7179 +         }
7180 +       else if ((GET_CODE (PATTERN (next_insn)) == SET)
7181 +                && avr32_comparison_operator (SET_SRC (PATTERN (next_insn)),
7182 +                                              GET_MODE (SET_SRC (PATTERN (next_insn)))))
7183 +         {
7184 +           /* scc with no compare */
7185 +           SET_SRC (PATTERN (next_insn)) = new_cond;
7186 +           /* Force the instruction to be recognized again */
7187 +           INSN_CODE (next_insn) = -1;
7188 +           return TRUE;
7189 +         }
7190 +       else if (GET_CODE (PATTERN (next_insn)) == COND_EXEC)
7191 +         {
7192 +           if ( GET_CODE (new_cond) == UNSPEC )
7193 +             {
7194 +               COND_EXEC_TEST (PATTERN (next_insn)) =
7195 +                 gen_rtx_UNSPEC (CCmode,
7196 +                                 gen_rtvec (2,
7197 +                                            XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 0),
7198 +                                            XEXP (COND_EXEC_TEST (PATTERN (next_insn)), 1)),
7199 +                                 XINT (new_cond, 1));
7200 +             }
7201 +           else
7202 +             {
7203 +               PUT_CODE(COND_EXEC_TEST (PATTERN (next_insn)), GET_CODE(new_cond));
7204 +             }
7205 +         }
7206 +     }
7207 +
7208 +  return FALSE;
7209 +}
7210 +
7211 +
7212 +/* Function for obtaining the condition for the next instruction after cur_insn.
7213 +*/
7214 +rtx
7215 +get_next_insn_cond (rtx cur_insn)
7216 +{
7217 +  rtx next_insn = next_nonnote_insn (cur_insn);
7218 +  rtx cond = NULL_RTX;
7219 +  if (next_insn != NULL_RTX
7220 +      && INSN_P (next_insn))
7221 +    {
7222 +      if ((GET_CODE (PATTERN (next_insn)) == SET)
7223 +          && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE))
7224 +        {
7225 +          /* Branch and cond if then else instructions */
7226 +          cond = XEXP (SET_SRC (PATTERN (next_insn)), 0);
7227 +        }
7228 +      else if ((GET_CODE (PATTERN (next_insn)) == SET)
7229 +               && avr32_comparison_operator (SET_SRC (PATTERN (next_insn)),
7230 +                                             GET_MODE (SET_SRC (PATTERN (next_insn)))))
7231 +        {
7232 +          /* scc with no compare */
7233 +          cond = SET_SRC (PATTERN (next_insn));
7234 +        }
7235 +      else if (GET_CODE (PATTERN (next_insn)) == COND_EXEC)
7236 +        {
7237 +          cond = COND_EXEC_TEST (PATTERN (next_insn));
7238 +        }
7239 +    }
7240 +  return cond;
7241 +}
7242 +
7243 +
7244 +/* Check if the next insn is a conditional insn that will emit a compare
7245 +   for itself.
7246 +*/
7247 +rtx
7248 +next_insn_emits_cmp (rtx cur_insn)
7249 +{
7250 +  rtx next_insn = next_nonnote_insn (cur_insn);
7251 +  rtx cond = NULL_RTX;
7252 +  if (next_insn != NULL_RTX
7253 +      && INSN_P (next_insn))
7254 +    {
7255 +      if ( ((GET_CODE (PATTERN (next_insn)) == SET)
7256 +            && (GET_CODE (SET_SRC (PATTERN (next_insn))) == IF_THEN_ELSE)
7257 +            && (XEXP (XEXP (SET_SRC (PATTERN (next_insn)), 0),0) != cc0_rtx))
7258 +           || GET_CODE (PATTERN (next_insn)) == COND_EXEC )
7259 +        return TRUE;
7260 +    }
7261 +  return FALSE;
7262 +}
7263 +
7264 +
7265 +rtx
7266 +avr32_output_cmp (rtx cond, enum machine_mode mode, rtx op0, rtx op1)
7267 +{
7268 +
7269 +  rtx new_cond = NULL_RTX;
7270 +  rtx ops[2];
7271 +  rtx compare_pattern;
7272 +  ops[0] = op0;
7273 +  ops[1] = op1;
7274 +
7275 +  if ( GET_CODE (op0) == AND )
7276 +    compare_pattern = op0;
7277 +  else
7278 +    compare_pattern = gen_rtx_COMPARE (mode, op0, op1);
7279 +
7280 +  new_cond = is_compare_redundant (compare_pattern, cond);
7281 +
7282 +  if (new_cond != NULL_RTX)
7283 +    return new_cond;
7284 +
7285 +  /* Check if we are inserting a bit-load instead of a compare. */
7286 +  if ( GET_CODE (op0) == AND )
7287 +    {
7288 +      ops[0] = XEXP (op0, 0);
7289 +      ops[1] = XEXP (op0, 1);
7290 +      output_asm_insn ("bld\t%0, %p1", ops);
7291 +      return cond;
7292 +    }
7293 +
7294 +  /* Insert compare */
7295 +  switch (mode)
7296 +    {
7297 +    case QImode:
7298 +      output_asm_insn ("cp.b\t%0, %1", ops);
7299 +      break;
7300 +    case HImode:
7301 +      output_asm_insn ("cp.h\t%0, %1", ops);
7302 +      break;
7303 +    case SImode:
7304 +      output_asm_insn ("cp.w\t%0, %1", ops);
7305 +      break;
7306 +    case DImode:
7307 +      if (GET_CODE (op1) != REG)
7308 +       output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0", ops);
7309 +      else
7310 +       output_asm_insn ("cp.w\t%0, %1\ncpc\t%m0, %m1", ops);
7311 +      break;
7312 +    default:
7313 +      internal_error ("Unknown comparison mode");
7314 +      break;
7315 +    }
7316 +
7317 +  return cond;
7318 +}
7319 +
7320 +
7321 +int
7322 +avr32_load_multiple_operation (rtx op,
7323 +                              enum machine_mode mode ATTRIBUTE_UNUSED)
7324 +{
7325 +  int count = XVECLEN (op, 0);
7326 +  unsigned int dest_regno;
7327 +  rtx src_addr;
7328 +  rtx elt;
7329 +  int i = 1, base = 0;
7330 +
7331 +  if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
7332 +    return 0;
7333 +
7334 +  /* Check to see if this might be a write-back.  */
7335 +  if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
7336 +    {
7337 +      i++;
7338 +      base = 1;
7339 +
7340 +      /* Now check it more carefully.  */
7341 +      if (GET_CODE (SET_DEST (elt)) != REG
7342 +         || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
7343 +         || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
7344 +         || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
7345 +       return 0;
7346 +    }
7347 +
7348 +  /* Perform a quick check so we don't blow up below.  */
7349 +  if (count <= 1
7350 +      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
7351 +      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
7352 +      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC)
7353 +    return 0;
7354 +
7355 +  dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
7356 +  src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
7357 +
7358 +  for (; i < count; i++)
7359 +    {
7360 +      elt = XVECEXP (op, 0, i);
7361 +
7362 +      if (GET_CODE (elt) != SET
7363 +         || GET_CODE (SET_DEST (elt)) != REG
7364 +         || GET_MODE (SET_DEST (elt)) != SImode
7365 +         || GET_CODE (SET_SRC (elt)) != UNSPEC)
7366 +       return 0;
7367 +    }
7368 +
7369 +  return 1;
7370 +}
7371 +
7372 +
7373 +int
7374 +avr32_store_multiple_operation (rtx op,
7375 +                               enum machine_mode mode ATTRIBUTE_UNUSED)
7376 +{
7377 +  int count = XVECLEN (op, 0);
7378 +  int src_regno;
7379 +  rtx dest_addr;
7380 +  rtx elt;
7381 +  int i = 1;
7382 +
7383 +  if (count <= 1 || GET_CODE (XVECEXP (op, 0, 0)) != SET)
7384 +    return 0;
7385 +
7386 +  /* Perform a quick check so we don't blow up below.  */
7387 +  if (count <= i
7388 +      || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
7389 +      || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
7390 +      || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != UNSPEC)
7391 +    return 0;
7392 +
7393 +  src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
7394 +  dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
7395 +
7396 +  for (; i < count; i++)
7397 +    {
7398 +      elt = XVECEXP (op, 0, i);
7399 +
7400 +      if (GET_CODE (elt) != SET
7401 +         || GET_CODE (SET_DEST (elt)) != MEM
7402 +         || GET_MODE (SET_DEST (elt)) != SImode
7403 +         || GET_CODE (SET_SRC (elt)) != UNSPEC)
7404 +       return 0;
7405 +    }
7406 +
7407 +  return 1;
7408 +}
7409 +
7410 +
7411 +int
7412 +avr32_valid_macmac_bypass (rtx insn_out, rtx insn_in)
7413 +{
7414 +  /* Check if they use the same accumulator */
7415 +  if (rtx_equal_p
7416 +      (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
7417 +    {
7418 +      return TRUE;
7419 +    }
7420 +
7421 +  return FALSE;
7422 +}
7423 +
7424 +
7425 +int
7426 +avr32_valid_mulmac_bypass (rtx insn_out, rtx insn_in)
7427 +{
7428 +  /*
7429 +     Check if the mul instruction produces the accumulator for the mac
7430 +     instruction. */
7431 +  if (rtx_equal_p
7432 +      (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
7433 +    {
7434 +      return TRUE;
7435 +    }
7436 +  return FALSE;
7437 +}
7438 +
7439 +
7440 +int
7441 +avr32_store_bypass (rtx insn_out, rtx insn_in)
7442 +{
7443 +  /* Only valid bypass if the output result is used as an src in the store
7444 +     instruction, NOT if used as a pointer or base. */
7445 +  if (rtx_equal_p
7446 +      (SET_DEST (PATTERN (insn_out)), SET_SRC (PATTERN (insn_in))))
7447 +    {
7448 +      return TRUE;
7449 +    }
7450 +
7451 +  return FALSE;
7452 +}
7453 +
7454 +
7455 +int
7456 +avr32_mul_waw_bypass (rtx insn_out, rtx insn_in)
7457 +{
7458 +  /* Check if the register holding the result from the mul instruction is
7459 +     used as a result register in the input instruction. */
7460 +  if (rtx_equal_p
7461 +      (SET_DEST (PATTERN (insn_out)), SET_DEST (PATTERN (insn_in))))
7462 +    {
7463 +      return TRUE;
7464 +    }
7465 +
7466 +  return FALSE;
7467 +}
7468 +
7469 +
7470 +int
7471 +avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in)
7472 +{
7473 +  /* Check if the first loaded word in insn_out is used in insn_in. */
7474 +  rtx dst_reg;
7475 +  rtx second_loaded_reg;
7476 +
7477 +  /* If this is a double alu operation then the bypass is not valid */
7478 +  if ((get_attr_type (insn_in) == TYPE_ALU
7479 +       || get_attr_type (insn_in) == TYPE_ALU2)
7480 +      && (GET_MODE_SIZE (GET_MODE (SET_DEST (PATTERN (insn_out)))) > 4))
7481 +    return FALSE;
7482 +
7483 +  /* Get the destination register in the load */
7484 +  if (!REG_P (SET_DEST (PATTERN (insn_out))))
7485 +    return FALSE;
7486 +
7487 +  dst_reg = SET_DEST (PATTERN (insn_out));
7488 +  second_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 1);
7489 +
7490 +  if (!reg_mentioned_p (second_loaded_reg, PATTERN (insn_in)))
7491 +    return TRUE;
7492 +
7493 +  return FALSE;
7494 +}
7495 +
7496 +
7497 +int
7498 +avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in)
7499 +{
7500 +  /*
7501 +     Check if the two first loaded word in insn_out are used in insn_in. */
7502 +  rtx dst_reg;
7503 +  rtx third_loaded_reg, fourth_loaded_reg;
7504 +
7505 +  /* Get the destination register in the load */
7506 +  if (!REG_P (SET_DEST (PATTERN (insn_out))))
7507 +    return FALSE;
7508 +
7509 +  dst_reg = SET_DEST (PATTERN (insn_out));
7510 +  third_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 2);
7511 +  fourth_loaded_reg = gen_rtx_REG (SImode, REGNO (dst_reg) + 3);
7512 +
7513 +  if (!reg_mentioned_p (third_loaded_reg, PATTERN (insn_in))
7514 +      && !reg_mentioned_p (fourth_loaded_reg, PATTERN (insn_in)))
7515 +    {
7516 +      return TRUE;
7517 +    }
7518 +
7519 +  return FALSE;
7520 +}
7521 +
7522 +
7523 +rtx
7524 +avr32_ifcvt_modify_test (ce_if_block_t *ce_info, rtx test )
7525 +{
7526 +  rtx branch_insn;
7527 +  rtx cmp_test;
7528 +  rtx compare_op0;
7529 +  rtx compare_op1;
7530 +
7531 +
7532 +  if ( !ce_info
7533 +       || test == NULL_RTX
7534 +       || !reg_mentioned_p (cc0_rtx, test))
7535 +    return test;
7536 +
7537 +  branch_insn = BB_END (ce_info->test_bb);
7538 +  cmp_test = PATTERN(prev_nonnote_insn (branch_insn));
7539 +
7540 +  if (GET_CODE(cmp_test) != SET
7541 +      || !CC0_P(XEXP(cmp_test, 0)) )
7542 +    return cmp_test;
7543 +
7544 +  if ( GET_CODE(SET_SRC(cmp_test)) == COMPARE ){
7545 +    compare_op0 = XEXP(SET_SRC(cmp_test), 0);
7546 +    compare_op1 = XEXP(SET_SRC(cmp_test), 1);
7547 +  } else {
7548 +    compare_op0 = SET_SRC(cmp_test);
7549 +    compare_op1 = const0_rtx;
7550 +  }
7551 +
7552 +  return gen_rtx_fmt_ee (GET_CODE(test), GET_MODE (compare_op0),
7553 +                         compare_op0, compare_op1);
7554 +}
7555 +
7556 +
7557 +rtx
7558 +avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, rtx pattern, rtx insn,
7559 +                         int *num_true_changes)
7560 +{
7561 +  rtx test = COND_EXEC_TEST(pattern);
7562 +  rtx op = COND_EXEC_CODE(pattern);
7563 +  rtx cmp_insn;
7564 +  rtx cond_exec_insn;
7565 +  int inputs_set_outside_ifblock = 1;
7566 +  basic_block current_bb = BLOCK_FOR_INSN (insn);
7567 +  rtx bb_insn ;
7568 +  enum machine_mode mode = GET_MODE (XEXP (op, 0));
7569 +
7570 +  if (CC0_P(XEXP(test, 0)))
7571 +    test = avr32_ifcvt_modify_test (ce_info,
7572 +                                    test );
7573 +
7574 +  /* We do not support multiple tests. */
7575 +  if ( ce_info
7576 +       && ce_info->num_multiple_test_blocks > 0 )
7577 +    return NULL_RTX;
7578 +
7579 +  pattern = gen_rtx_COND_EXEC (VOIDmode, test, op);
7580 +
7581 +  if ( !reload_completed )
7582 +    {
7583 +      rtx start;
7584 +      int num_insns;
7585 +      int max_insns = MAX_CONDITIONAL_EXECUTE;
7586 +
7587 +      if ( !ce_info )
7588 +        return op;
7589 +
7590 +      /* Check if the insn is not suitable for conditional
7591 +         execution. */
7592 +      start_sequence ();
7593 +      cond_exec_insn = emit_insn (pattern);
7594 +      if ( recog_memoized (cond_exec_insn) < 0
7595 +           && can_create_pseudo_p () )
7596 +        {
7597 +          /* Insn is not suitable for conditional execution, try
7598 +             to fix it up by using an extra scratch register or
7599 +             by pulling the operation outside the if-then-else
7600 +             and then emiting a conditional move inside the if-then-else. */
7601 +          end_sequence ();
7602 +          if ( GET_CODE (op) != SET
7603 +               || !REG_P (SET_DEST (op))
7604 +               || GET_CODE (SET_SRC (op)) == IF_THEN_ELSE
7605 +               || GET_MODE_SIZE (mode) > UNITS_PER_WORD )
7606 +            return NULL_RTX;
7607 +
7608 +          /* Check if any of the input operands to the insn is set inside the
7609 +             current block. */
7610 +          if ( current_bb->index == ce_info->then_bb->index )
7611 +            start = PREV_INSN (BB_HEAD (ce_info->then_bb));
7612 +          else
7613 +            start = PREV_INSN (BB_HEAD (ce_info->else_bb));
7614 +
7615 +
7616 +          for ( bb_insn = next_nonnote_insn (start); bb_insn != insn; bb_insn = next_nonnote_insn (bb_insn) )
7617 +            {
7618 +              rtx set = single_set (bb_insn);
7619 +
7620 +              if ( set && reg_mentioned_p (SET_DEST (set), SET_SRC (op)))
7621 +                {
7622 +                  inputs_set_outside_ifblock = 0;
7623 +                  break;
7624 +                }
7625 +            }
7626 +
7627 +          cmp_insn = prev_nonnote_insn (BB_END (ce_info->test_bb));
7628 +
7629 +
7630 +          /* Check if we can insert more insns. */
7631 +          num_insns = ( ce_info->num_then_insns +
7632 +                        ce_info->num_else_insns +
7633 +                        ce_info->num_cond_clobber_insns +
7634 +                        ce_info->num_extra_move_insns );
7635 +
7636 +          if ( ce_info->num_else_insns != 0 )
7637 +            max_insns *=2;
7638 +
7639 +          if ( num_insns >= max_insns )
7640 +            return NULL_RTX;
7641 +
7642 +          /* Check if we have an instruction which might be converted to
7643 +             conditional form if we give it a scratch register to clobber. */
7644 +          {
7645 +            rtx clobber_insn;
7646 +            rtx scratch_reg = gen_reg_rtx (mode);
7647 +            rtx new_pattern = copy_rtx (pattern);
7648 +            rtx set_src = SET_SRC (COND_EXEC_CODE (new_pattern));
7649 +
7650 +            rtx clobber = gen_rtx_CLOBBER (mode, scratch_reg);
7651 +            rtx vec[2] = { COND_EXEC_CODE (new_pattern), clobber };
7652 +            COND_EXEC_CODE (new_pattern) = gen_rtx_PARALLEL (mode, gen_rtvec_v (2, vec));
7653 +
7654 +            start_sequence ();
7655 +            clobber_insn = emit_insn (new_pattern);
7656 +
7657 +            if ( recog_memoized (clobber_insn) >= 0
7658 +                 && ( ( GET_RTX_LENGTH (GET_CODE (set_src)) == 2
7659 +                        && CONST_INT_P (XEXP (set_src, 1))
7660 +                        && avr32_const_ok_for_constraint_p (INTVAL (XEXP (set_src, 1)), 'K', "Ks08") )
7661 +                      || !ce_info->else_bb
7662 +                      || current_bb->index == ce_info->else_bb->index ))
7663 +              {
7664 +                end_sequence ();
7665 +                /* Force the insn to be recognized again. */
7666 +                INSN_CODE (insn) = -1;
7667 +
7668 +                /* If this is the first change in this IF-block then
7669 +                   signal that we have made a change. */
7670 +                if ( ce_info->num_cond_clobber_insns == 0
7671 +                     && ce_info->num_extra_move_insns == 0 )
7672 +                  *num_true_changes += 1;
7673 +
7674 +                ce_info->num_cond_clobber_insns++;
7675 +
7676 +                if (dump_file)
7677 +                  fprintf (dump_file,
7678 +                           "\nReplacing INSN %d with an insn using a scratch register for later ifcvt passes...\n",
7679 +                           INSN_UID (insn));
7680 +
7681 +                return COND_EXEC_CODE (new_pattern);
7682 +              }
7683 +            end_sequence ();
7684 +          }
7685 +
7686 +          if ( inputs_set_outside_ifblock )
7687 +            {
7688 +              /* Check if the insn before the cmp is an and which used
7689 +                 together with the cmp can be optimized into a bld. If
7690 +                 so then we should try to put the insn before the and
7691 +                 so that we can catch the bld peephole. */
7692 +              rtx set;
7693 +              rtx insn_before_cmp_insn = prev_nonnote_insn (cmp_insn);
7694 +              if (insn_before_cmp_insn
7695 +                  && (set = single_set (insn_before_cmp_insn))
7696 +                  && GET_CODE (SET_SRC (set)) == AND
7697 +                  && one_bit_set_operand (XEXP (SET_SRC (set), 1), SImode)
7698 +                  /* Also make sure that the insn does not set any
7699 +                     of the input operands to the insn we are pulling out. */
7700 +                  && !reg_mentioned_p (SET_DEST (set), SET_SRC (op)) )
7701 +                cmp_insn = prev_nonnote_insn (cmp_insn);
7702 +
7703 +              /* We can try to put the operation outside the if-then-else
7704 +                 blocks and insert a move. */
7705 +              if ( !insn_invalid_p (insn)
7706 +                   /* Do not allow conditional insns to be moved outside the
7707 +                      if-then-else. */
7708 +                   && !reg_mentioned_p (cc0_rtx, insn)
7709 +                   /* We cannot move memory loads outside of the if-then-else
7710 +                      since the memory access should not be perfomed if the
7711 +                      condition is not met. */
7712 +                   && !mem_mentioned_p (SET_SRC (op)) )
7713 +                {
7714 +                  rtx scratch_reg = gen_reg_rtx (mode);
7715 +                  rtx op_pattern = copy_rtx (op);
7716 +                  rtx new_insn, seq;
7717 +                  rtx link, prev_link;
7718 +                  op = copy_rtx (op);
7719 +                  /* Emit the operation to a temp reg before the compare,
7720 +                     and emit a move inside the if-then-else, hoping that the
7721 +                     whole if-then-else can be converted to conditional
7722 +                     execution. */
7723 +                  SET_DEST (op_pattern) = scratch_reg;
7724 +                  start_sequence ();
7725 +                  new_insn = emit_insn (op_pattern);
7726 +                  seq = get_insns();
7727 +                  end_sequence ();
7728 +
7729 +                  /* Check again that the insn is valid. For some insns the insn might
7730 +                     become invalid if the destination register is changed. Ie. for mulacc
7731 +                     operations. */
7732 +                  if ( insn_invalid_p (new_insn) )
7733 +                    return NULL_RTX;
7734 +
7735 +                  emit_insn_before_setloc (seq, cmp_insn, INSN_LOCATOR (insn));
7736 +
7737 +                  if (dump_file)
7738 +                    fprintf (dump_file,
7739 +                             "\nMoving INSN %d out of IF-block by adding INSN %d...\n",
7740 +                             INSN_UID (insn), INSN_UID (new_insn));
7741 +
7742 +                  ce_info->extra_move_insns[ce_info->num_extra_move_insns] = insn;
7743 +                  ce_info->moved_insns[ce_info->num_extra_move_insns] = new_insn;
7744 +                  XEXP (op, 1) = scratch_reg;
7745 +                  /* Force the insn to be recognized again. */
7746 +                  INSN_CODE (insn) = -1;
7747 +
7748 +                  /* Move REG_DEAD notes to the moved insn. */
7749 +                  prev_link = NULL_RTX;
7750 +                  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
7751 +                    {
7752 +                      if (REG_NOTE_KIND (link) == REG_DEAD)
7753 +                        {
7754 +                          /* Add the REG_DEAD note to the new insn. */
7755 +                          rtx dead_reg = XEXP (link, 0);
7756 +                          REG_NOTES (new_insn) = gen_rtx_EXPR_LIST (REG_DEAD, dead_reg, REG_NOTES (new_insn));
7757 +                          /* Remove the REG_DEAD note from the insn we convert to a move. */
7758 +                          if ( prev_link )
7759 +                            XEXP (prev_link, 1) = XEXP (link, 1);
7760 +                          else
7761 +                            REG_NOTES (insn) = XEXP (link, 1);
7762 +                        }
7763 +                      else
7764 +                        {
7765 +                          prev_link = link;
7766 +                        }
7767 +                    }
7768 +                  /* Add a REG_DEAD note to signal that the scratch register is dead. */
7769 +                  REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_DEAD, scratch_reg, REG_NOTES (insn));
7770 +
7771 +                  /* If this is the first change in this IF-block then
7772 +                     signal that we have made a change. */
7773 +                  if ( ce_info->num_cond_clobber_insns == 0
7774 +                       && ce_info->num_extra_move_insns == 0 )
7775 +                    *num_true_changes += 1;
7776 +
7777 +                  ce_info->num_extra_move_insns++;
7778 +                  return op;
7779 +                }
7780 +            }
7781 +
7782 +          /* We failed to fixup the insns, so this if-then-else can not be made
7783 +             conditional. Just return NULL_RTX so that the if-then-else conversion
7784 +             for this if-then-else will be cancelled. */
7785 +          return NULL_RTX;
7786 +        }
7787 +      end_sequence ();
7788 +      return op;
7789 +    }
7790 +
7791 +  /* Signal that we have started if conversion after reload, which means
7792 +     that it should be safe to split all the predicable clobber insns which
7793 +     did not become cond_exec back into a simpler form if possible. */
7794 +  cfun->machine->ifcvt_after_reload = 1;
7795 +
7796 +  return pattern;
7797 +}
7798 +
7799 +
7800 +void
7801 +avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, int *num_true_changes)
7802 +{
7803 +  int n;
7804 +
7805 +  if ( ce_info->num_extra_move_insns > 0
7806 +       && ce_info->num_cond_clobber_insns == 0)
7807 +    /* Signal that we did not do any changes after all. */
7808 +    *num_true_changes -= 1;
7809 +
7810 +  /* Remove any inserted move insns. */
7811 +  for ( n = 0; n < ce_info->num_extra_move_insns; n++ )
7812 +    {
7813 +      rtx link, prev_link;
7814 +
7815 +      /* Remove REG_DEAD note since we are not needing the scratch register anyway. */
7816 +      prev_link = NULL_RTX;
7817 +      for (link = REG_NOTES (ce_info->extra_move_insns[n]); link; link = XEXP (link, 1))
7818 +        {
7819 +          if (REG_NOTE_KIND (link) == REG_DEAD)
7820 +            {
7821 +              if ( prev_link )
7822 +                XEXP (prev_link, 1) = XEXP (link, 1);
7823 +              else
7824 +                REG_NOTES (ce_info->extra_move_insns[n]) = XEXP (link, 1);
7825 +            }
7826 +          else
7827 +            {
7828 +              prev_link = link;
7829 +            }
7830 +        }
7831 +
7832 +      /* Revert all reg_notes for the moved insn. */
7833 +      for (link = REG_NOTES (ce_info->moved_insns[n]); link; link = XEXP (link, 1))
7834 +        {
7835 +          REG_NOTES (ce_info->extra_move_insns[n]) = gen_rtx_EXPR_LIST (REG_NOTE_KIND (link),
7836 +                                                                        XEXP (link, 0),
7837 +                                                                        REG_NOTES (ce_info->extra_move_insns[n]));
7838 +        }
7839 +
7840 +      /* Remove the moved insn. */
7841 +      remove_insn ( ce_info->moved_insns[n] );
7842 +    }
7843 +}
7844 +
7845 +
7846 +/* Function returning TRUE if INSN with OPERANDS is a splittable
7847 +   conditional immediate clobber insn. We assume that the insn is
7848 +   already a conditional immediate clobber insns and do not check
7849 +   for that. */
7850 +int
7851 +avr32_cond_imm_clobber_splittable (rtx insn, rtx operands[])
7852 +{
7853 +  if ( REGNO (operands[0]) == REGNO (operands[1]) )
7854 +    {
7855 +      if ( (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == PLUS
7856 +            && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'I', "Is21"))
7857 +           || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == MINUS
7858 +               && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21")))
7859 +        return FALSE;
7860 +    }
7861 +  else if ( (logical_binary_operator (SET_SRC (XVECEXP (PATTERN (insn),0,0)), VOIDmode)
7862 +             || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == PLUS
7863 +                 && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'I', "Is16"))
7864 +             || (GET_CODE (SET_SRC (XVECEXP (PATTERN (insn),0,0))) == MINUS
7865 +                 && !avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks16"))) )
7866 +    return FALSE;
7867 +
7868 +  return TRUE;
7869 +}
7870 +
7871 +
7872 +/* Function for getting an integer value from a const_int or const_double
7873 +   expression regardless of the HOST_WIDE_INT size. Each target cpu word
7874 +   will be put into the val array where the LSW will be stored at the lowest
7875 +   address and so forth. Assumes that const_expr is either a const_int or
7876 +   const_double. Only valid for modes which have sizes that are a multiple
7877 +   of the word size.
7878 +*/
7879 +void
7880 +avr32_get_intval (enum machine_mode mode, rtx const_expr, HOST_WIDE_INT *val)
7881 +{
7882 +  int words_in_mode = GET_MODE_SIZE (mode)/UNITS_PER_WORD;
7883 +  const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD;
7884 +
7885 +  if ( GET_CODE(const_expr) == CONST_DOUBLE ){
7886 +    HOST_WIDE_INT hi = CONST_DOUBLE_HIGH(const_expr);
7887 +    HOST_WIDE_INT lo = CONST_DOUBLE_LOW(const_expr);
7888 +    /* Evaluate hi and lo values of const_double. */
7889 +    avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0),
7890 +                      GEN_INT (lo),
7891 +                      &val[0]);
7892 +    avr32_get_intval (mode_for_size (HOST_BITS_PER_WIDE_INT, MODE_INT, 0),
7893 +                      GEN_INT (hi),
7894 +                      &val[words_in_const_int]);
7895 +  } else if ( GET_CODE(const_expr) == CONST_INT ){
7896 +    HOST_WIDE_INT value = INTVAL(const_expr);
7897 +    int word;
7898 +    for ( word = 0; (word < words_in_mode) && (word < words_in_const_int); word++ ){
7899 +      /* Shift word up to the MSW and shift down again to extract the
7900 +         word and sign-extend. */
7901 +      int lshift = (words_in_const_int - word - 1) * BITS_PER_WORD;
7902 +      int rshift = (words_in_const_int-1) * BITS_PER_WORD;
7903 +      val[word] = (value << lshift) >> rshift;
7904 +    }
7905 +
7906 +    for ( ; word < words_in_mode; word++ ){
7907 +      /* Just put the sign bits in the remaining words. */
7908 +      val[word] = value < 0 ? -1 : 0;
7909 +    }
7910 +  }
7911 +}
7912 +
7913 +
7914 +void
7915 +avr32_split_const_expr (enum machine_mode mode, enum machine_mode new_mode,
7916 +                        rtx expr, rtx *split_expr)
7917 +{
7918 +  int i, word;
7919 +  int words_in_intval = GET_MODE_SIZE (mode)/UNITS_PER_WORD;
7920 +  int words_in_split_values = GET_MODE_SIZE (new_mode)/UNITS_PER_WORD;
7921 +  const int words_in_const_int = HOST_BITS_PER_WIDE_INT / BITS_PER_WORD;
7922 +  HOST_WIDE_INT *val = alloca (words_in_intval * UNITS_PER_WORD);
7923 +
7924 +  avr32_get_intval (mode, expr, val);
7925 +
7926 +  for ( i=0; i < (words_in_intval/words_in_split_values); i++ )
7927 +    {
7928 +      HOST_WIDE_INT value_lo = 0, value_hi = 0;
7929 +      for ( word = 0; word < words_in_split_values; word++ )
7930 +        {
7931 +          if ( word >= words_in_const_int )
7932 +            value_hi |= ((val[i * words_in_split_values + word] &
7933 +                          (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1))
7934 +                         << (BITS_PER_WORD * (word - words_in_const_int)));
7935 +          else
7936 +            value_lo |= ((val[i * words_in_split_values + word] &
7937 +                          (((HOST_WIDE_INT)1 << BITS_PER_WORD)-1))
7938 +                         << (BITS_PER_WORD * word));
7939 +        }
7940 +      split_expr[i] = immed_double_const(value_lo, value_hi, new_mode);
7941 +    }
7942 +}
7943 +
7944 +
7945 +/* Set up library functions to comply to AVR32 ABI  */
7946 +static void
7947 +avr32_init_libfuncs (void)
7948 +{
7949 +  /* Convert gcc run-time function names to AVR32 ABI names */
7950 +
7951 +  /* Double-precision floating-point arithmetic. */
7952 +  set_optab_libfunc (neg_optab, DFmode, NULL);
7953 +
7954 +  /* Double-precision comparisons.  */
7955 +  set_optab_libfunc (eq_optab, DFmode, "__avr32_f64_cmp_eq");
7956 +  set_optab_libfunc (ne_optab, DFmode, NULL);
7957 +  set_optab_libfunc (lt_optab, DFmode, "__avr32_f64_cmp_lt");
7958 +  set_optab_libfunc (le_optab, DFmode, NULL);
7959 +  set_optab_libfunc (ge_optab, DFmode, "__avr32_f64_cmp_ge");
7960 +  set_optab_libfunc (gt_optab, DFmode, NULL);
7961 +
7962 +  /* Single-precision floating-point arithmetic. */
7963 +  set_optab_libfunc (smul_optab, SFmode, "__avr32_f32_mul");
7964 +  set_optab_libfunc (neg_optab, SFmode, NULL);
7965 +
7966 +  /* Single-precision comparisons.  */
7967 +  set_optab_libfunc (eq_optab, SFmode, "__avr32_f32_cmp_eq");
7968 +  set_optab_libfunc (ne_optab, SFmode, NULL);
7969 +  set_optab_libfunc (lt_optab, SFmode, "__avr32_f32_cmp_lt");
7970 +  set_optab_libfunc (le_optab, SFmode, NULL);
7971 +  set_optab_libfunc (ge_optab, SFmode, "__avr32_f32_cmp_ge");
7972 +  set_optab_libfunc (gt_optab, SFmode, NULL);
7973 +
7974 +  /* Floating-point to integer conversions. */
7975 +  set_conv_libfunc (sfix_optab, SImode, DFmode, "__avr32_f64_to_s32");
7976 +  set_conv_libfunc (ufix_optab, SImode, DFmode, "__avr32_f64_to_u32");
7977 +  set_conv_libfunc (sfix_optab, DImode, DFmode, "__avr32_f64_to_s64");
7978 +  set_conv_libfunc (ufix_optab, DImode, DFmode, "__avr32_f64_to_u64");
7979 +  set_conv_libfunc (sfix_optab, SImode, SFmode, "__avr32_f32_to_s32");
7980 +  set_conv_libfunc (ufix_optab, SImode, SFmode, "__avr32_f32_to_u32");
7981 +  set_conv_libfunc (sfix_optab, DImode, SFmode, "__avr32_f32_to_s64");
7982 +  set_conv_libfunc (ufix_optab, DImode, SFmode, "__avr32_f32_to_u64");
7983 +
7984 +  /* Conversions between floating types.  */
7985 +  set_conv_libfunc (trunc_optab, SFmode, DFmode, "__avr32_f64_to_f32");
7986 +  set_conv_libfunc (sext_optab, DFmode, SFmode, "__avr32_f32_to_f64");
7987 +
7988 +  /* Integer to floating-point conversions.  Table 8.  */
7989 +  set_conv_libfunc (sfloat_optab, DFmode, SImode, "__avr32_s32_to_f64");
7990 +  set_conv_libfunc (sfloat_optab, DFmode, DImode, "__avr32_s64_to_f64");
7991 +  set_conv_libfunc (sfloat_optab, SFmode, SImode, "__avr32_s32_to_f32");
7992 +  set_conv_libfunc (sfloat_optab, SFmode, DImode, "__avr32_s64_to_f32");
7993 +  set_conv_libfunc (ufloat_optab, DFmode, SImode, "__avr32_u32_to_f64");
7994 +  set_conv_libfunc (ufloat_optab, SFmode, SImode, "__avr32_u32_to_f32");
7995 +  /* TODO: Add these to gcc library functions */
7996 +  //set_conv_libfunc (ufloat_optab, DFmode, DImode, NULL);
7997 +  //set_conv_libfunc (ufloat_optab, SFmode, DImode, NULL);
7998 +
7999 +  /* Long long.  Table 9.  */
8000 +  set_optab_libfunc (smul_optab, DImode, "__avr32_mul64");
8001 +  set_optab_libfunc (sdiv_optab, DImode, "__avr32_sdiv64");
8002 +  set_optab_libfunc (udiv_optab, DImode, "__avr32_udiv64");
8003 +  set_optab_libfunc (smod_optab, DImode, "__avr32_smod64");
8004 +  set_optab_libfunc (umod_optab, DImode, "__avr32_umod64");
8005 +  set_optab_libfunc (ashl_optab, DImode, "__avr32_lsl64");
8006 +  set_optab_libfunc (lshr_optab, DImode, "__avr32_lsr64");
8007 +  set_optab_libfunc (ashr_optab, DImode, "__avr32_asr64");
8008 +
8009 +  /* Floating point library functions which have fast versions. */
8010 +  if ( TARGET_FAST_FLOAT )
8011 +    {
8012 +      set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div_fast");
8013 +      set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul_fast");
8014 +      set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add_fast");
8015 +      set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub_fast");
8016 +      set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add_fast");
8017 +      set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub_fast");
8018 +      set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div_fast");
8019 +    }
8020 +  else
8021 +    {
8022 +      set_optab_libfunc (sdiv_optab, DFmode, "__avr32_f64_div");
8023 +      set_optab_libfunc (smul_optab, DFmode, "__avr32_f64_mul");
8024 +      set_optab_libfunc (add_optab, DFmode, "__avr32_f64_add");
8025 +      set_optab_libfunc (sub_optab, DFmode, "__avr32_f64_sub");
8026 +      set_optab_libfunc (add_optab, SFmode, "__avr32_f32_add");
8027 +      set_optab_libfunc (sub_optab, SFmode, "__avr32_f32_sub");
8028 +      set_optab_libfunc (sdiv_optab, SFmode, "__avr32_f32_div");
8029 +    }
8030 +}
8031 +
8032 +
8033 +/* Record a flashvault declaration.  */
8034 +static void
8035 +flashvault_decl_list_add (unsigned int vector_num, const char *name)
8036 +{
8037 +  struct flashvault_decl_list *p;
8038 +
8039 +  p = (struct flashvault_decl_list *)
8040 +       xmalloc (sizeof (struct flashvault_decl_list));
8041 +  p->next = flashvault_decl_list_head;
8042 +  p->name = name;
8043 +  p->vector_num = vector_num;
8044 +  flashvault_decl_list_head = p;
8045 +}
8046 +
8047 +
8048 +static void
8049 +avr32_file_end (void)
8050 +{
8051 +  struct flashvault_decl_list *p;
8052 +  unsigned int num_entries = 0;
8053 +
8054 +  /* Check if a list of flashvault declarations exists. */
8055 +  if (flashvault_decl_list_head != NULL)
8056 +    {
8057 +      /* Calculate the number of entries in the table. */
8058 +      for (p = flashvault_decl_list_head; p != NULL; p = p->next)
8059 +        {
8060 +           num_entries++;
8061 +        }
8062 +
8063 +      /* Generate the beginning of the flashvault data table. */
8064 +      fputs ("\t.global     __fv_table\n"
8065 +             "\t.data\n"
8066 +             "\t.align 2\n"
8067 +             "\t.set .LFVTABLE, . + 0\n"
8068 +             "\t.type __fv_table, @object\n", asm_out_file);
8069 +      /* Each table entry is 8 bytes. */
8070 +      fprintf (asm_out_file, "\t.size __fv_table, %u\n", (num_entries * 8));
8071 +
8072 +      fputs("__fv_table:\n", asm_out_file);
8073 +
8074 +      for (p = flashvault_decl_list_head; p != NULL; p = p->next)
8075 +        {
8076 +          /* Output table entry. */
8077 +          fprintf (asm_out_file, 
8078 +                   "\t.align 2\n"
8079 +                   "\t.int %u\n", p->vector_num);
8080 +          fprintf (asm_out_file, 
8081 +                   "\t.align 2\n"
8082 +                   "\t.int %s\n", p->name);
8083 +        }
8084 +    }
8085 +}
8086 --- /dev/null
8087 +++ b/gcc/config/avr32/avr32-elf.h
8088 @@ -0,0 +1,91 @@
8089 +/*
8090 +   Elf specific definitions.
8091 +   Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation.
8092 +
8093 +   This file is part of GCC.
8094 +
8095 +   This program is free software; you can redistribute it and/or modify
8096 +   it under the terms of the GNU General Public License as published by
8097 +   the Free Software Foundation; either version 2 of the License, or
8098 +   (at your option) any later version.
8099 +
8100 +   This program is distributed in the hope that it will be useful,
8101 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
8102 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8103 +   GNU General Public License for more details.
8104 +
8105 +   You should have received a copy of the GNU General Public License
8106 +   along with this program; if not, write to the Free Software
8107 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
8108 +
8109 +
8110 +/*****************************************************************************
8111 + * Controlling the Compiler Driver, 'gcc'
8112 + *****************************************************************************/
8113 +
8114 +/* Run-time Target Specification.  */
8115 +#undef  TARGET_VERSION
8116 +#define TARGET_VERSION  fputs (" (AVR32 GNU with ELF)", stderr);
8117 +
8118 +/*
8119 +Another C string constant used much like LINK_SPEC.  The
8120 +difference between the two is that STARTFILE_SPEC is used at
8121 +the very beginning of the command given to the linker.
8122 +
8123 +If this macro is not defined, a default is provided that loads the
8124 +standard C startup file from the usual place.  See gcc.c.
8125 +*/
8126 +#if 0
8127 +#undef  STARTFILE_SPEC
8128 +#define STARTFILE_SPEC "crt0%O%s crti%O%s crtbegin%O%s"
8129 +#endif
8130 +#undef  STARTFILE_SPEC 
8131 +#define STARTFILE_SPEC "%{mflashvault: crtfv.o%s} %{!mflashvault: crt0.o%s} \
8132 +                       crti.o%s crtbegin.o%s"
8133 +
8134 +#undef LINK_SPEC
8135 +#define LINK_SPEC "%{muse-oscall:--defsym __do_not_use_oscall_coproc__=0} %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}} %{mpart=uc3a3revd:-mavr32elf_uc3a3256s;:%{mpart=*:-mavr32elf_%*}} %{mcpu=*:-mavr32elf_%*}"
8136 +
8137 +
8138 +/*
8139 +Another C string constant used much like LINK_SPEC.  The
8140 +difference between the two is that ENDFILE_SPEC is used at
8141 +the very end of the command given to the linker.
8142 +
8143 +Do not define this macro if it does not need to do anything.
8144 +*/
8145 +#undef  ENDFILE_SPEC
8146 +#define ENDFILE_SPEC "crtend%O%s crtn%O%s"
8147 +
8148 +
8149 +/* Target CPU builtins.  */
8150 +#define TARGET_CPU_CPP_BUILTINS()                                                              \
8151 +  do                                                                                                                   \
8152 +    {                                                                                                                  \
8153 +      builtin_define ("__avr32__");                                                            \
8154 +      builtin_define ("__AVR32__");                                                            \
8155 +      builtin_define ("__AVR32_ELF__");                                                        \
8156 +      builtin_define (avr32_part->macro);                                              \
8157 +      builtin_define (avr32_arch->macro);                                              \
8158 +      if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A)                 \
8159 +        builtin_define ("__AVR32_AVR32A__");                                   \
8160 +      else                                                                                                             \
8161 +        builtin_define ("__AVR32_AVR32B__");                                   \
8162 +      if (TARGET_UNALIGNED_WORD)                                                               \
8163 +        builtin_define ("__AVR32_HAS_UNALIGNED_WORD__");               \
8164 +      if (TARGET_SIMD)                                                                                 \
8165 +        builtin_define ("__AVR32_HAS_SIMD__");                                 \
8166 +      if (TARGET_DSP)                                                                                  \
8167 +        builtin_define ("__AVR32_HAS_DSP__");                                  \
8168 +      if (TARGET_RMW)                                                                                  \
8169 +        builtin_define ("__AVR32_HAS_RMW__");                                  \
8170 +      if (TARGET_BRANCH_PRED)                                                                  \
8171 +        builtin_define ("__AVR32_HAS_BRANCH_PRED__");                  \
8172 +      if (TARGET_FAST_FLOAT)                                    \
8173 +        builtin_define ("__AVR32_FAST_FLOAT__");                \
8174 +      if (TARGET_FLASHVAULT)                                    \
8175 +        builtin_define ("__AVR32_FLASHVAULT__");                \
8176 +      if (TARGET_NO_MUL_INSNS)                                  \
8177 +        builtin_define ("__AVR32_NO_MUL__");                    \
8178 +    }                                                                                                                  \
8179 +  while (0)
8180 --- /dev/null
8181 +++ b/gcc/config/avr32/avr32.h
8182 @@ -0,0 +1,3316 @@
8183 +/*
8184 +   Definitions of target machine for AVR32.
8185 +   Copyright 2003,2004,2005,2006,2007,2008,2009,2010 Atmel Corporation.
8186 +
8187 +   This file is part of GCC.
8188 +
8189 +   This program is free software; you can redistribute it and/or modify
8190 +   it under the terms of the GNU General Public License as published by
8191 +   the Free Software Foundation; either version 2 of the License, or
8192 +   (at your option) any later version.
8193 +
8194 +   This program is distributed in the hope that it will be useful,
8195 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
8196 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
8197 +   GNU General Public License for more details.
8198 +
8199 +   You should have received a copy of the GNU General Public License
8200 +   along with this program; if not, write to the Free Software
8201 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
8202 +
8203 +#ifndef GCC_AVR32_H
8204 +#define GCC_AVR32_H
8205 +
8206 +
8207 +#ifndef OBJECT_FORMAT_ELF
8208 +#error avr32.h included before elfos.h
8209 +#endif
8210 +
8211 +#ifndef LOCAL_LABEL_PREFIX
8212 +#define LOCAL_LABEL_PREFIX "."
8213 +#endif
8214 +
8215 +#ifndef SUBTARGET_CPP_SPEC
8216 +#define SUBTARGET_CPP_SPEC  "-D__ELF__"
8217 +#endif
8218 +
8219 +
8220 +extern struct rtx_def *avr32_compare_op0;
8221 +extern struct rtx_def *avr32_compare_op1;
8222 +
8223 +/* comparison type */
8224 +enum avr32_cmp_type {
8225 +  CMP_QI,                              /* 1 byte ->char */
8226 +  CMP_HI,                              /* 2 byte->half word */
8227 +  CMP_SI,                              /* four byte->word*/
8228 +  CMP_DI,                              /* eight byte->double word */
8229 +  CMP_SF,                              /* single precision floats */
8230 +  CMP_MAX                              /* max comparison type */
8231 +};
8232 +
8233 +extern enum avr32_cmp_type avr32_branch_type;  /* type of branch to use */
8234 +
8235 +
8236 +extern struct rtx_def *avr32_acc_cache;
8237 +
8238 +/* cache instruction op5 codes */
8239 +#define AVR32_CACHE_INVALIDATE_ICACHE 1
8240 +
8241 +/* 
8242 +These bits describe the different types of function supported by the AVR32
8243 +backend. They are exclusive, e.g. a function cannot be both a normal function
8244 +and an interworked function.  Knowing the type of a function is important for
8245 +determining its prologue and epilogue sequences. Note value 7 is currently 
8246 +unassigned.  Also note that the interrupt function types all have bit 2 set, 
8247 +so that they can be tested for easily. Note that 0 is deliberately chosen for
8248 +AVR32_FT_UNKNOWN so that when the machine_function structure is initialized
8249 +(to zero) func_type will default to unknown. This will force the first use of
8250 +avr32_current_func_type to call avr32_compute_func_type. 
8251 +*/
8252 +#define AVR32_FT_UNKNOWN           0  /* Type has not yet been determined. */
8253 +#define AVR32_FT_NORMAL            1  /* Normal function. */
8254 +#define AVR32_FT_ACALL             2  /* An acall function. */
8255 +#define AVR32_FT_EXCEPTION_HANDLER 3  /* A C++ exception handler. */
8256 +#define AVR32_FT_ISR_FULL          4  /* A fully shadowed interrupt mode. */
8257 +#define AVR32_FT_ISR_HALF          5  /* A half shadowed interrupt mode. */
8258 +#define AVR32_FT_ISR_NONE          6  /* No shadow registers. */
8259 +
8260 +#define AVR32_FT_TYPE_MASK     ((1 << 3) - 1)
8261 +
8262 +/* In addition functions can have several type modifiers, outlined by these bit masks: */
8263 +#define AVR32_FT_INTERRUPT       (1 << 2)  /* Note overlap with FT_ISR and above. */
8264 +#define AVR32_FT_NAKED           (1 << 3)  /* No prologue or epilogue. */
8265 +#define AVR32_FT_VOLATILE        (1 << 4)  /* Does not return. */
8266 +#define AVR32_FT_NESTED          (1 << 5)  /* Embedded inside another func. */
8267 +#define AVR32_FT_FLASHVAULT      (1 << 6)  /* Flashvault function call. */
8268 +#define AVR32_FT_FLASHVAULT_IMPL (1 << 7)  /* Function definition in FlashVault. */
8269 +
8270 +
8271 +/* Some macros to test these flags.  */
8272 +#define AVR32_FUNC_TYPE(t)     (t & AVR32_FT_TYPE_MASK)
8273 +#define IS_INTERRUPT(t)        (t & AVR32_FT_INTERRUPT)
8274 +#define IS_NAKED(t)            (t & AVR32_FT_NAKED)
8275 +#define IS_VOLATILE(t)         (t & AVR32_FT_VOLATILE)
8276 +#define IS_NESTED(t)           (t & AVR32_FT_NESTED)
8277 +#define IS_FLASHVAULT(t)       (t & AVR32_FT_FLASHVAULT)
8278 +#define IS_FLASHVAULT_IMPL(t)  (t & AVR32_FT_FLASHVAULT_IMPL)
8279 +
8280 +#define SYMBOL_FLAG_RMW_ADDR_SHIFT    SYMBOL_FLAG_MACH_DEP_SHIFT
8281 +#define SYMBOL_REF_RMW_ADDR(RTX)                                        \
8282 +  ((SYMBOL_REF_FLAGS (RTX) & (1 << SYMBOL_FLAG_RMW_ADDR_SHIFT)) != 0)
8283 +
8284 +
8285 +typedef struct minipool_labels
8286 +GTY ((chain_next ("%h.next"), chain_prev ("%h.prev")))
8287 +{
8288 +  rtx label;
8289 +  struct minipool_labels *prev;
8290 +  struct minipool_labels *next;
8291 +} minipool_labels;
8292 +
8293 +/* A C structure for machine-specific, per-function data.
8294 +   This is added to the cfun structure.  */
8295 +
8296 +typedef struct machine_function
8297 +GTY (())
8298 +{
8299 +  /* Records the type of the current function.  */
8300 +  unsigned long func_type;
8301 +  /* List of minipool labels, use for checking if code label is valid in a
8302 +     memory expression */
8303 +  minipool_labels *minipool_label_head;
8304 +  minipool_labels *minipool_label_tail;
8305 +  int ifcvt_after_reload;
8306 +} machine_function;
8307 +
8308 +/* Initialize data used by insn expanders.  This is called from insn_emit,
8309 +   once for every function before code is generated.  */
8310 +#define INIT_EXPANDERS avr32_init_expanders ()
8311 +
8312 +/******************************************************************************
8313 + * SPECS
8314 + *****************************************************************************/
8315 +
8316 +#ifndef ASM_SPEC
8317 +#define ASM_SPEC "%{fpic:--pic} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{march=ucr2nomul:-march=ucr2;:%{march=*:-march=%*}} %{mpart=uc3a3revd:-mpart=uc3a3256s;:%{mpart=*:-mpart=%*}}"
8318 +#endif
8319 +
8320 +#ifndef MULTILIB_DEFAULTS
8321 +#define MULTILIB_DEFAULTS { "march=ap", "" }
8322 +#endif
8323 +
8324 +/******************************************************************************
8325 + * Run-time Target Specification
8326 + *****************************************************************************/
8327 +#ifndef TARGET_VERSION
8328 +#define TARGET_VERSION fprintf(stderr, " (AVR32, GNU assembler syntax)");
8329 +#endif
8330 +
8331 +
8332 +/* Part types. Keep this in sync with the order of avr32_part_types in avr32.c*/
8333 +enum part_type
8334 +{
8335 +  PART_TYPE_AVR32_NONE,
8336 +  PART_TYPE_AVR32_AP7000,
8337 +  PART_TYPE_AVR32_AP7001,
8338 +  PART_TYPE_AVR32_AP7002,
8339 +  PART_TYPE_AVR32_AP7200,
8340 +  PART_TYPE_AVR32_UC3A0128,
8341 +  PART_TYPE_AVR32_UC3A0256,
8342 +  PART_TYPE_AVR32_UC3A0512,
8343 +  PART_TYPE_AVR32_UC3A0512ES,
8344 +  PART_TYPE_AVR32_UC3A1128,
8345 +  PART_TYPE_AVR32_UC3A1256,
8346 +  PART_TYPE_AVR32_UC3A1512,
8347 +  PART_TYPE_AVR32_UC3A1512ES,
8348 +  PART_TYPE_AVR32_UC3A3REVD,
8349 +  PART_TYPE_AVR32_UC3A364,
8350 +  PART_TYPE_AVR32_UC3A364S,
8351 +  PART_TYPE_AVR32_UC3A3128,
8352 +  PART_TYPE_AVR32_UC3A3128S,
8353 +  PART_TYPE_AVR32_UC3A3256,
8354 +  PART_TYPE_AVR32_UC3A3256S,
8355 +  PART_TYPE_AVR32_UC3A464,
8356 +  PART_TYPE_AVR32_UC3A464S,
8357 +  PART_TYPE_AVR32_UC3A4128,
8358 +  PART_TYPE_AVR32_UC3A4128S,
8359 +  PART_TYPE_AVR32_UC3A4256,
8360 +  PART_TYPE_AVR32_UC3A4256S,
8361 +  PART_TYPE_AVR32_UC3B064,
8362 +  PART_TYPE_AVR32_UC3B0128,
8363 +  PART_TYPE_AVR32_UC3B0256,
8364 +  PART_TYPE_AVR32_UC3B0256ES,
8365 +  PART_TYPE_AVR32_UC3B0512,
8366 +  PART_TYPE_AVR32_UC3B0512REVC,
8367 +  PART_TYPE_AVR32_UC3B164,
8368 +  PART_TYPE_AVR32_UC3B1128,
8369 +  PART_TYPE_AVR32_UC3B1256,
8370 +  PART_TYPE_AVR32_UC3B1256ES,
8371 +  PART_TYPE_AVR32_UC3B1512,
8372 +  PART_TYPE_AVR32_UC3B1512REVC,
8373 +  PART_TYPE_AVR32_UC64D3,
8374 +  PART_TYPE_AVR32_UC128D3,
8375 +  PART_TYPE_AVR32_UC64D4,
8376 +  PART_TYPE_AVR32_UC128D4,
8377 +  PART_TYPE_AVR32_UC3C0512CREVC,
8378 +  PART_TYPE_AVR32_UC3C1512CREVC,
8379 +  PART_TYPE_AVR32_UC3C2512CREVC,
8380 +  PART_TYPE_AVR32_UC3L0256,
8381 +  PART_TYPE_AVR32_UC3L0128,
8382 +  PART_TYPE_AVR32_UC3L064,
8383 +  PART_TYPE_AVR32_UC3L032,
8384 +  PART_TYPE_AVR32_UC3L016,
8385 +  PART_TYPE_AVR32_UC3L064REVB,
8386 +  PART_TYPE_AVR32_UC64L3U,
8387 +  PART_TYPE_AVR32_UC128L3U,
8388 +  PART_TYPE_AVR32_UC256L3U,
8389 +  PART_TYPE_AVR32_UC64L4U,
8390 +  PART_TYPE_AVR32_UC128L4U,
8391 +  PART_TYPE_AVR32_UC256L4U,
8392 +  PART_TYPE_AVR32_UC3C064C,
8393 +  PART_TYPE_AVR32_UC3C0128C,
8394 +  PART_TYPE_AVR32_UC3C0256C,
8395 +  PART_TYPE_AVR32_UC3C0512C,
8396 +  PART_TYPE_AVR32_UC3C164C,
8397 +  PART_TYPE_AVR32_UC3C1128C,
8398 +  PART_TYPE_AVR32_UC3C1256C,
8399 +  PART_TYPE_AVR32_UC3C1512C,
8400 +  PART_TYPE_AVR32_UC3C264C,
8401 +  PART_TYPE_AVR32_UC3C2128C,
8402 +  PART_TYPE_AVR32_UC3C2256C,
8403 +  PART_TYPE_AVR32_UC3C2512C,
8404 +  PART_TYPE_AVR32_MXT768E
8405 +};
8406 +
8407 +/* Microarchitectures. */
8408 +enum microarchitecture_type
8409 +{
8410 +  UARCH_TYPE_AVR32A,
8411 +  UARCH_TYPE_AVR32B,
8412 +  UARCH_TYPE_NONE
8413 +};
8414 +
8415 +/* Architectures types which specifies the pipeline.
8416 + Keep this in sync with avr32_arch_types in avr32.c
8417 + and the pipeline attribute in avr32.md */
8418 +enum architecture_type
8419 +{
8420 +  ARCH_TYPE_AVR32_AP,
8421 +  ARCH_TYPE_AVR32_UCR1,
8422 +  ARCH_TYPE_AVR32_UCR2,
8423 +  ARCH_TYPE_AVR32_UCR2NOMUL,
8424 +  ARCH_TYPE_AVR32_UCR3,
8425 +  ARCH_TYPE_AVR32_UCR3FP,
8426 +  ARCH_TYPE_AVR32_NONE
8427 +};
8428 +
8429 +/* Flag specifying if the cpu has support for DSP instructions.*/
8430 +#define FLAG_AVR32_HAS_DSP (1 << 0)
8431 +/* Flag specifying if the cpu has support for Read-Modify-Write
8432 +   instructions.*/
8433 +#define FLAG_AVR32_HAS_RMW (1 << 1)
8434 +/* Flag specifying if the cpu has support for SIMD instructions. */
8435 +#define FLAG_AVR32_HAS_SIMD (1 << 2)
8436 +/* Flag specifying if the cpu has support for unaligned memory word access. */
8437 +#define FLAG_AVR32_HAS_UNALIGNED_WORD (1 << 3)
8438 +/* Flag specifying if the cpu has support for branch prediction. */
8439 +#define FLAG_AVR32_HAS_BRANCH_PRED (1 << 4)
8440 +/* Flag specifying if the cpu has support for a return stack. */
8441 +#define FLAG_AVR32_HAS_RETURN_STACK (1 << 5)
8442 +/* Flag specifying if the cpu has caches. */
8443 +#define FLAG_AVR32_HAS_CACHES (1 << 6)
8444 +/* Flag specifying if the cpu has support for v2 insns. */
8445 +#define FLAG_AVR32_HAS_V2_INSNS (1 << 7)
8446 +/* Flag specifying that the cpu has buggy mul insns. */
8447 +#define FLAG_AVR32_HAS_NO_MUL_INSNS (1 << 8)
8448 +/* Flag specifying that the device has FPU instructions according 
8449 +   to AVR32002 specifications*/
8450 +#define FLAG_AVR32_HAS_FPU (1 << 9)
8451 +
8452 +/* Structure for holding information about different avr32 CPUs/parts */
8453 +struct part_type_s
8454 +{
8455 +  const char *const name;
8456 +  enum part_type part_type;
8457 +  enum architecture_type arch_type;
8458 +  /* Must lie outside user's namespace.  NULL == no macro.  */
8459 +  const char *const macro;
8460 +};
8461 +
8462 +/* Structure for holding information about different avr32 pipeline
8463 + architectures. */
8464 +struct arch_type_s
8465 +{
8466 +  const char *const name;
8467 +  enum architecture_type arch_type;
8468 +  enum microarchitecture_type uarch_type;
8469 +  const unsigned long feature_flags;
8470 +  /* Must lie outside user's namespace.  NULL == no macro.  */
8471 +  const char *const macro;
8472 +};
8473 +
8474 +extern const struct part_type_s *avr32_part;
8475 +extern const struct arch_type_s *avr32_arch;
8476 +
8477 +#define TARGET_SIMD  (avr32_arch->feature_flags & FLAG_AVR32_HAS_SIMD)
8478 +#define TARGET_DSP  (avr32_arch->feature_flags & FLAG_AVR32_HAS_DSP)
8479 +#define TARGET_RMW  (avr32_arch->feature_flags & FLAG_AVR32_HAS_RMW)
8480 +#define TARGET_UNALIGNED_WORD  (avr32_arch->feature_flags & FLAG_AVR32_HAS_UNALIGNED_WORD)
8481 +#define TARGET_BRANCH_PRED  (avr32_arch->feature_flags & FLAG_AVR32_HAS_BRANCH_PRED)
8482 +#define TARGET_RETURN_STACK  (avr32_arch->feature_flags & FLAG_AVR32_HAS_RETURN_STACK)
8483 +#define TARGET_V2_INSNS  (avr32_arch->feature_flags & FLAG_AVR32_HAS_V2_INSNS)
8484 +#define TARGET_CACHES  (avr32_arch->feature_flags & FLAG_AVR32_HAS_CACHES)
8485 +#define TARGET_NO_MUL_INSNS  (avr32_arch->feature_flags & FLAG_AVR32_HAS_NO_MUL_INSNS)
8486 +#define TARGET_ARCH_AP (avr32_arch->arch_type == ARCH_TYPE_AVR32_AP)
8487 +#define TARGET_ARCH_UCR1 (avr32_arch->arch_type == ARCH_TYPE_AVR32_UCR1)
8488 +#define TARGET_ARCH_UCR2 (avr32_arch->arch_type == ARCH_TYPE_AVR32_UCR2)
8489 +#define TARGET_ARCH_UC (TARGET_ARCH_UCR1 || TARGET_ARCH_UCR2)
8490 +#define TARGET_UARCH_AVR32A (avr32_arch->uarch_type == UARCH_TYPE_AVR32A)
8491 +#define TARGET_UARCH_AVR32B (avr32_arch->uarch_type == UARCH_TYPE_AVR32B)
8492 +#define TARGET_ARCH_FPU (avr32_arch->feature_flags & FLAG_AVR32_HAS_FPU)
8493 +
8494 +#define CAN_DEBUG_WITHOUT_FP
8495 +
8496 +
8497 +
8498 +
8499 +/******************************************************************************
8500 + * Storage Layout
8501 + *****************************************************************************/
8502 +
8503 +/*
8504 +Define this macro to have the value 1 if the most significant bit in a
8505 +byte has the lowest number; otherwise define it to have the value zero.
8506 +This means that bit-field instructions count from the most significant
8507 +bit.  If the machine has no bit-field instructions, then this must still
8508 +be defined, but it doesn't matter which value it is defined to.  This
8509 +macro need not be a constant.
8510 +
8511 +This macro does not affect the way structure fields are packed into
8512 +bytes or words; that is controlled by BYTES_BIG_ENDIAN.
8513 +*/
8514 +#define BITS_BIG_ENDIAN 0
8515 +
8516 +/*
8517 +Define this macro to have the value 1 if the most significant byte in a
8518 +word has the lowest number. This macro need not be a constant.
8519 +*/
8520 +/*
8521 +  Data is stored in an big-endian way.
8522 +*/
8523 +#define BYTES_BIG_ENDIAN 1
8524 +
8525 +/*
8526 +Define this macro to have the value 1 if, in a multiword object, the
8527 +most significant word has the lowest number.  This applies to both
8528 +memory locations and registers; GCC fundamentally assumes that the
8529 +order of words in memory is the same as the order in registers.  This
8530 +macro need not be a constant.
8531 +*/
8532 +/*
8533 +  Data is stored in an bin-endian way.
8534 +*/
8535 +#define WORDS_BIG_ENDIAN 1
8536 +
8537 +/*
8538 +Define this macro if WORDS_BIG_ENDIAN is not constant.  This must be a
8539 +constant value with the same meaning as WORDS_BIG_ENDIAN, which will be
8540 +used only when compiling libgcc2.c.  Typically the value will be set
8541 +based on preprocessor defines.
8542 +*/
8543 +#define LIBGCC2_WORDS_BIG_ENDIAN WORDS_BIG_ENDIAN
8544 +
8545 +/*
8546 +Define this macro to have the value 1 if DFmode, XFmode or
8547 +TFmode floating point numbers are stored in memory with the word
8548 +containing the sign bit at the lowest address; otherwise define it to
8549 +have the value 0.  This macro need not be a constant.
8550 +
8551 +You need not define this macro if the ordering is the same as for
8552 +multi-word integers.
8553 +*/
8554 +/* #define FLOAT_WORDS_BIG_ENDIAN 1 */
8555 +
8556 +/*
8557 +Define this macro to be the number of bits in an addressable storage
8558 +unit (byte); normally 8.
8559 +*/
8560 +#define BITS_PER_UNIT 8
8561 +
8562 +/*
8563 +Number of bits in a word; normally 32.
8564 +*/
8565 +#define BITS_PER_WORD 32
8566 +
8567 +/*
8568 +Maximum number of bits in a word.  If this is undefined, the default is
8569 +BITS_PER_WORD.  Otherwise, it is the constant value that is the
8570 +largest value that BITS_PER_WORD can have at run-time.
8571 +*/
8572 +/* MAX_BITS_PER_WORD not defined*/
8573 +
8574 +/*
8575 +Number of storage units in a word; normally 4.
8576 +*/
8577 +#define UNITS_PER_WORD 4
8578 +
8579 +/*
8580 +Minimum number of units in a word.  If this is undefined, the default is
8581 +UNITS_PER_WORD.  Otherwise, it is the constant value that is the
8582 +smallest value that UNITS_PER_WORD can have at run-time.
8583 +*/
8584 +/* MIN_UNITS_PER_WORD not defined */
8585 +
8586 +/*
8587 +Width of a pointer, in bits.  You must specify a value no wider than the
8588 +width of Pmode.  If it is not equal to the width of Pmode,
8589 +you must define POINTERS_EXTEND_UNSIGNED.
8590 +*/
8591 +#define POINTER_SIZE 32
8592 +
8593 +/*
8594 +A C expression whose value is greater than zero if pointers that need to be
8595 +extended from being POINTER_SIZE bits wide to Pmode are to
8596 +be zero-extended and zero if they are to be sign-extended.  If the value
8597 +is less then zero then there must be an "ptr_extend" instruction that
8598 +extends a pointer from POINTER_SIZE to Pmode.
8599 +
8600 +You need not define this macro if the POINTER_SIZE is equal
8601 +to the width of Pmode.
8602 +*/
8603 +/* #define POINTERS_EXTEND_UNSIGNED */
8604 +
8605 +/*
8606 +A Macro to update M and UNSIGNEDP when an object whose type
8607 +is TYPE and which has the specified mode and signedness is to be
8608 +stored in a register.  This macro is only called when TYPE is a
8609 +scalar type.
8610 +
8611 +On most RISC machines, which only have operations that operate on a full
8612 +register, define this macro to set M to word_mode if
8613 +M is an integer mode narrower than BITS_PER_WORD.  In most
8614 +cases, only integer modes should be widened because wider-precision
8615 +floating-point operations are usually more expensive than their narrower
8616 +counterparts.
8617 +
8618 +For most machines, the macro definition does not change UNSIGNEDP.
8619 +However, some machines, have instructions that preferentially handle
8620 +either signed or unsigned quantities of certain modes.  For example, on
8621 +the DEC Alpha, 32-bit loads from memory and 32-bit add instructions
8622 +sign-extend the result to 64 bits.  On such machines, set
8623 +UNSIGNEDP according to which kind of extension is more efficient.
8624 +
8625 +Do not define this macro if it would never modify M.
8626 +*/
8627 +#define PROMOTE_MODE(M, UNSIGNEDP, TYPE)                                \
8628 +  {                                                                     \
8629 +    if (!AGGREGATE_TYPE_P (TYPE)                                        \
8630 +        && GET_MODE_CLASS (mode) == MODE_INT                            \
8631 +        && GET_MODE_SIZE (mode) < 4)                                    \
8632 +      {                                                                 \
8633 +        if (M == QImode)                                                \
8634 +          (UNSIGNEDP) = 1;                                              \
8635 +        else if (M == HImode)                                           \
8636 +          (UNSIGNEDP) = 0;                                              \
8637 +        (M) = SImode;                                                   \
8638 +      }                                                                 \
8639 +  }
8640 +
8641 +#define PROMOTE_FUNCTION_MODE(M, UNSIGNEDP, TYPE)  \
8642 +        PROMOTE_MODE(M, UNSIGNEDP, TYPE)
8643 +
8644 +/* Define if operations between registers always perform the operation
8645 +   on the full register even if a narrower mode is specified.  */
8646 +#define WORD_REGISTER_OPERATIONS
8647 +
8648 +/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
8649 +   will either zero-extend or sign-extend.  The value of this macro should
8650 +   be the code that says which one of the two operations is implicitly
8651 +   done, UNKNOWN if not known.  */
8652 +#define LOAD_EXTEND_OP(MODE)                           \
8653 +   (((MODE) == QImode) ? ZERO_EXTEND                   \
8654 +   : ((MODE) == HImode) ? SIGN_EXTEND : UNKNOWN)
8655 +
8656 +
8657 +/*
8658 +Normal alignment required for function parameters on the stack, in
8659 +bits.  All stack parameters receive at least this much alignment
8660 +regardless of data type.  On most machines, this is the same as the
8661 +size of an integer.
8662 +*/
8663 +#define PARM_BOUNDARY 32
8664 +
8665 +/*
8666 +Define this macro to the minimum alignment enforced by hardware for the
8667 +stack pointer on this machine.  The definition is a C expression for the
8668 +desired alignment (measured in bits).  This value is used as a default
8669 +if PREFERRED_STACK_BOUNDARY is not defined.  On most machines,
8670 +this should be the same as PARM_BOUNDARY.
8671 +*/
8672 +#define STACK_BOUNDARY 32
8673 +
8674 +/*
8675 +Define this macro if you wish to preserve a certain alignment for the
8676 +stack pointer, greater than what the hardware enforces.  The definition
8677 +is a C expression for the desired alignment (measured in bits).  This
8678 +macro must evaluate to a value equal to or larger than
8679 +STACK_BOUNDARY.
8680 +*/
8681 +#define PREFERRED_STACK_BOUNDARY (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 )
8682 +
8683 +/*
8684 +Alignment required for a function entry point, in bits.
8685 +*/
8686 +#define FUNCTION_BOUNDARY 16
8687 +
8688 +/*
8689 +Biggest alignment that any data type can require on this machine, in bits.
8690 +*/
8691 +#define BIGGEST_ALIGNMENT  (TARGET_FORCE_DOUBLE_ALIGN ? 64 : 32 )
8692 +
8693 +/*
8694 +If defined, the smallest alignment, in bits, that can be given to an
8695 +object that can be referenced in one operation, without disturbing any
8696 +nearby object.  Normally, this is BITS_PER_UNIT, but may be larger
8697 +on machines that don't have byte or half-word store operations.
8698 +*/
8699 +#define MINIMUM_ATOMIC_ALIGNMENT BITS_PER_UNIT
8700 +
8701 +
8702 +/*
8703 +An integer expression for the size in bits of the largest integer machine mode that
8704 +should actually be used. All integer machine modes of this size or smaller can be
8705 +used for structures and unions with the appropriate sizes. If this macro is undefined,
8706 +GET_MODE_BITSIZE (DImode) is assumed.*/
8707 +#define MAX_FIXED_MODE_SIZE  GET_MODE_BITSIZE (DImode)
8708 +
8709 +
8710 +/*
8711 +If defined, a C expression to compute the alignment given to a constant
8712 +that is being placed in memory.  CONSTANT is the constant and
8713 +BASIC_ALIGN is the alignment that the object would ordinarily
8714 +have.  The value of this macro is used instead of that alignment to
8715 +align the object.
8716 +
8717 +If this macro is not defined, then BASIC_ALIGN is used.
8718 +
8719 +The typical use of this macro is to increase alignment for string
8720 +constants to be word aligned so that strcpy calls that copy
8721 +constants can be done inline.
8722 +*/
8723 +#define CONSTANT_ALIGNMENT(CONSTANT, BASIC_ALIGN) \
8724 + ((TREE_CODE(CONSTANT) == STRING_CST) ? BITS_PER_WORD : BASIC_ALIGN)
8725 +
8726 +/* Try to align string to a word. */
8727 +#define DATA_ALIGNMENT(TYPE, ALIGN)                                     \
8728 +  ({(TREE_CODE (TYPE) == ARRAY_TYPE                                     \
8729 +     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode                          \
8730 +     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));})
8731 +
8732 +/* Try to align local store strings to a word. */
8733 +#define LOCAL_ALIGNMENT(TYPE, ALIGN)                                    \
8734 +  ({(TREE_CODE (TYPE) == ARRAY_TYPE                                     \
8735 +     && TYPE_MODE (TREE_TYPE (TYPE)) == QImode                          \
8736 +     && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN));})
8737 +
8738 +/*
8739 +Define this macro to be the value 1 if instructions will fail to work
8740 +if given data not on the nominal alignment.  If instructions will merely
8741 +go slower in that case, define this macro as 0.
8742 +*/
8743 +#define STRICT_ALIGNMENT 1
8744 +
8745 +/*
8746 +Define this if you wish to imitate the way many other C compilers handle
8747 +alignment of bit-fields and the structures that contain them.
8748 +
8749 +The behavior is that the type written for a bit-field (int,
8750 +short, or other integer type) imposes an alignment for the
8751 +entire structure, as if the structure really did contain an ordinary
8752 +field of that type.  In addition, the bit-field is placed within the
8753 +structure so that it would fit within such a field, not crossing a
8754 +boundary for it.
8755 +
8756 +Thus, on most machines, a bit-field whose type is written as int
8757 +would not cross a four-byte boundary, and would force four-byte
8758 +alignment for the whole structure.  (The alignment used may not be four
8759 +bytes; it is controlled by the other alignment parameters.)
8760 +
8761 +If the macro is defined, its definition should be a C expression;
8762 +a nonzero value for the expression enables this behavior.
8763 +
8764 +Note that if this macro is not defined, or its value is zero, some
8765 +bit-fields may cross more than one alignment boundary.  The compiler can
8766 +support such references if there are insv, extv, and
8767 +extzv insns that can directly reference memory.
8768 +
8769 +The other known way of making bit-fields work is to define
8770 +STRUCTURE_SIZE_BOUNDARY as large as BIGGEST_ALIGNMENT.
8771 +Then every structure can be accessed with fullwords.
8772 +
8773 +Unless the machine has bit-field instructions or you define
8774 +STRUCTURE_SIZE_BOUNDARY that way, you must define
8775 +PCC_BITFIELD_TYPE_MATTERS to have a nonzero value.
8776 +
8777 +If your aim is to make GCC use the same conventions for laying out
8778 +bit-fields as are used by another compiler, here is how to investigate
8779 +what the other compiler does.  Compile and run this program:
8780 +
8781 +struct foo1
8782 +{
8783 +  char x;
8784 +  char :0;
8785 +  char y;
8786 +};
8787 +
8788 +struct foo2
8789 +{
8790 +  char x;
8791 +  int :0;
8792 +  char y;
8793 +};
8794 +
8795 +main ()
8796 +{
8797 +  printf ("Size of foo1 is %d\n",
8798 +          sizeof (struct foo1));
8799 +  printf ("Size of foo2 is %d\n",
8800 +          sizeof (struct foo2));
8801 +  exit (0);
8802 +}
8803 +
8804 +If this prints 2 and 5, then the compiler's behavior is what you would
8805 +get from PCC_BITFIELD_TYPE_MATTERS.
8806 +*/
8807 +#define PCC_BITFIELD_TYPE_MATTERS 1
8808 +
8809 +
8810 +/******************************************************************************
8811 + * Layout of Source Language Data Types
8812 + *****************************************************************************/
8813 +
8814 +/*
8815 +A C expression for the size in bits of the type int on the
8816 +target machine.  If you don't define this, the default is one word.
8817 +*/
8818 +#define INT_TYPE_SIZE 32
8819 +
8820 +/*
8821 +A C expression for the size in bits of the type short on the
8822 +target machine.  If you don't define this, the default is half a word. (If
8823 +this would be less than one storage unit, it is rounded up to one unit.)
8824 +*/
8825 +#define SHORT_TYPE_SIZE 16
8826 +
8827 +/*
8828 +A C expression for the size in bits of the type long on the
8829 +target machine.  If you don't define this, the default is one word.
8830 +*/
8831 +#define LONG_TYPE_SIZE 32
8832 +
8833 +
8834 +/*
8835 +A C expression for the size in bits of the type long long on the
8836 +target machine.  If you don't define this, the default is two
8837 +words.  If you want to support GNU Ada on your machine, the value of this
8838 +macro must be at least 64.
8839 +*/
8840 +#define LONG_LONG_TYPE_SIZE 64
8841 +
8842 +/*
8843 +A C expression for the size in bits of the type char on the
8844 +target machine.  If you don't define this, the default is
8845 +BITS_PER_UNIT.
8846 +*/
8847 +#define CHAR_TYPE_SIZE 8
8848 +
8849 +
8850 +/*
8851 +A C expression for the size in bits of the C++ type bool and
8852 +C99 type _Bool on the target machine.  If you don't define
8853 +this, and you probably shouldn't, the default is CHAR_TYPE_SIZE.
8854 +*/
8855 +#define BOOL_TYPE_SIZE 8
8856 +
8857 +
8858 +/*
8859 +An expression whose value is 1 or 0, according to whether the type
8860 +char should be signed or unsigned by default.  The user can
8861 +always override this default with the options -fsigned-char
8862 +and -funsigned-char.
8863 +*/
8864 +/* We are using unsigned char */
8865 +#define DEFAULT_SIGNED_CHAR 0
8866 +
8867 +
8868 +/*
8869 +A C expression for a string describing the name of the data type to use
8870 +for size values.  The typedef name size_t is defined using the
8871 +contents of the string.
8872 +
8873 +The string can contain more than one keyword.  If so, separate them with
8874 +spaces, and write first any length keyword, then unsigned if
8875 +appropriate, and finally int.  The string must exactly match one
8876 +of the data type names defined in the function
8877 +init_decl_processing in the file c-decl.c.  You may not
8878 +omit int or change the order - that would cause the compiler to
8879 +crash on startup.
8880 +
8881 +If you don't define this macro, the default is "long unsigned int".
8882 +*/
8883 +#define SIZE_TYPE "long unsigned int"
8884 +
8885 +/*
8886 +A C expression for a string describing the name of the data type to use
8887 +for the result of subtracting two pointers.  The typedef name
8888 +ptrdiff_t is defined using the contents of the string.  See
8889 +SIZE_TYPE above for more information.
8890 +
8891 +If you don't define this macro, the default is "long int".
8892 +*/
8893 +#define PTRDIFF_TYPE "long int"
8894 +
8895 +
8896 +/*
8897 +A C expression for the size in bits of the data type for wide
8898 +characters.  This is used in cpp, which cannot make use of
8899 +WCHAR_TYPE.
8900 +*/
8901 +#define WCHAR_TYPE_SIZE 32
8902 +
8903 +
8904 +/*
8905 +A C expression for a string describing the name of the data type to
8906 +use for wide characters passed to printf and returned from
8907 +getwc.  The typedef name wint_t is defined using the
8908 +contents of the string.  See SIZE_TYPE above for more
8909 +information.
8910 +
8911 +If you don't define this macro, the default is "unsigned int".
8912 +*/
8913 +#define WINT_TYPE "unsigned int"
8914 +
8915 +/*
8916 +A C expression for a string describing the name of the data type that
8917 +can represent any value of any standard or extended signed integer type.
8918 +The typedef name intmax_t is defined using the contents of the
8919 +string.  See SIZE_TYPE above for more information.
8920 +
8921 +If you don't define this macro, the default is the first of
8922 +"int", "long int", or "long long int" that has as
8923 +much precision as long long int.
8924 +*/
8925 +#define INTMAX_TYPE "long long int"
8926 +
8927 +/*
8928 +A C expression for a string describing the name of the data type that
8929 +can represent any value of any standard or extended unsigned integer
8930 +type.  The typedef name uintmax_t is defined using the contents
8931 +of the string.  See SIZE_TYPE above for more information.
8932 +
8933 +If you don't define this macro, the default is the first of
8934 +"unsigned int", "long unsigned int", or "long long unsigned int"
8935 +that has as much precision as long long unsigned int.
8936 +*/
8937 +#define UINTMAX_TYPE "long long unsigned int"
8938 +
8939 +
8940 +/******************************************************************************
8941 + * Register Usage
8942 + *****************************************************************************/
8943 +
8944 +/* Convert from gcc internal register number to register number
8945 +   used in assembly code */
8946 +#define ASM_REGNUM(reg) (LAST_REGNUM - (reg))
8947 +
8948 +/* Convert between register number used in assembly to gcc
8949 +   internal register number  */
8950 +#define INTERNAL_REGNUM(reg) (LAST_REGNUM - (reg))
8951 +
8952 +/** Basic Characteristics of Registers **/
8953 +
8954 +/*
8955 +Number of hardware registers known to the compiler.  They receive
8956 +numbers 0 through FIRST_PSEUDO_REGISTER-1; thus, the first
8957 +pseudo register's number really is assigned the number
8958 +FIRST_PSEUDO_REGISTER.
8959 +*/
8960 +#define FIRST_PSEUDO_REGISTER (LAST_REGNUM + 1)
8961 +
8962 +#define FIRST_REGNUM 0
8963 +#define LAST_REGNUM 15
8964 +
8965 +/*
8966 +An initializer that says which registers are used for fixed purposes
8967 +all throughout the compiled code and are therefore not available for
8968 +general allocation.  These would include the stack pointer, the frame
8969 +pointer (except on machines where that can be used as a general
8970 +register when no frame pointer is needed), the program counter on
8971 +machines where that is considered one of the addressable registers,
8972 +and any other numbered register with a standard use.
8973 +
8974 +This information is expressed as a sequence of numbers, separated by
8975 +commas and surrounded by braces.  The nth number is 1 if
8976 +register n is fixed, 0 otherwise.
8977 +
8978 +The table initialized from this macro, and the table initialized by
8979 +the following one, may be overridden at run time either automatically,
8980 +by the actions of the macro CONDITIONAL_REGISTER_USAGE, or by
8981 +the user with the command options -ffixed-[reg],
8982 +-fcall-used-[reg] and -fcall-saved-[reg].
8983 +*/
8984 +
8985 +/* The internal gcc register numbers are reversed
8986 +   compared to the real register numbers since
8987 +   gcc expects data types stored over multiple
8988 +   registers in the register file to be big endian
8989 +   if the memory layout is big endian. But this
8990 +   is not the case for avr32 so we fake a big
8991 +   endian register file. */
8992 +
8993 +#define FIXED_REGISTERS {      \
8994 +  1, /* Program Counter */     \
8995 +  0, /* Link Register */       \
8996 +  1, /* Stack Pointer */       \
8997 +  0, /* r12 */                 \
8998 +  0, /* r11 */                 \
8999 +  0, /* r10 */                 \
9000 +  0, /* r9 */                  \
9001 +  0, /* r8 */                  \
9002 +  0, /* r7 */                  \
9003 +  0, /* r6 */                  \
9004 +  0, /* r5 */                  \
9005 +  0, /* r4 */                  \
9006 +  0, /* r3 */                  \
9007 +  0, /* r2 */                  \
9008 +  0, /* r1 */                  \
9009 +  0, /* r0 */                  \
9010 +}
9011 +
9012 +/*
9013 +Like FIXED_REGISTERS but has 1 for each register that is
9014 +clobbered (in general) by function calls as well as for fixed
9015 +registers.  This macro therefore identifies the registers that are not
9016 +available for general allocation of values that must live across
9017 +function calls.
9018 +
9019 +If a register has 0 in CALL_USED_REGISTERS, the compiler
9020 +automatically saves it on function entry and restores it on function
9021 +exit, if the register is used within the function.
9022 +*/
9023 +#define CALL_USED_REGISTERS {  \
9024 +  1, /* Program Counter */     \
9025 +  0, /* Link Register */       \
9026 +  1, /* Stack Pointer */       \
9027 +  1, /* r12 */                 \
9028 +  1, /* r11 */                 \
9029 +  1, /* r10 */                 \
9030 +  1, /* r9 */                  \
9031 +  1, /* r8 */                  \
9032 +  0, /* r7 */                  \
9033 +  0, /* r6 */                  \
9034 +  0, /* r5 */                  \
9035 +  0, /* r4 */                  \
9036 +  0, /* r3 */                  \
9037 +  0, /* r2 */                  \
9038 +  0, /* r1 */                  \
9039 +  0, /* r0 */                  \
9040 +}
9041 +
9042 +/* Interrupt functions can only use registers that have already been
9043 +   saved by the prologue, even if they would normally be
9044 +   call-clobbered.  */
9045 +#define HARD_REGNO_RENAME_OK(SRC, DST)                                 \
9046 +       (! IS_INTERRUPT (cfun->machine->func_type) ||                   \
9047 +         df_regs_ever_live_p (DST))
9048 +
9049 +
9050 +/*
9051 +Zero or more C statements that may conditionally modify five variables
9052 +fixed_regs, call_used_regs, global_regs,
9053 +reg_names, and reg_class_contents, to take into account
9054 +any dependence of these register sets on target flags.  The first three
9055 +of these are of type char [] (interpreted as Boolean vectors).
9056 +global_regs is a const char *[], and
9057 +reg_class_contents is a HARD_REG_SET.  Before the macro is
9058 +called, fixed_regs, call_used_regs,
9059 +reg_class_contents, and reg_names have been initialized
9060 +from FIXED_REGISTERS, CALL_USED_REGISTERS,
9061 +REG_CLASS_CONTENTS, and REGISTER_NAMES, respectively.
9062 +global_regs has been cleared, and any -ffixed-[reg],
9063 +-fcall-used-[reg] and -fcall-saved-[reg]
9064 +command options have been applied.
9065 +
9066 +You need not define this macro if it has no work to do.
9067 +
9068 +If the usage of an entire class of registers depends on the target
9069 +flags, you may indicate this to GCC by using this macro to modify
9070 +fixed_regs and call_used_regs to 1 for each of the
9071 +registers in the classes which should not be used by GCC.  Also define
9072 +the macro REG_CLASS_FROM_LETTER to return NO_REGS if it
9073 +is called with a letter for a class that shouldn't be used.
9074 +
9075 + (However, if this class is not included in GENERAL_REGS and all
9076 +of the insn patterns whose constraints permit this class are
9077 +controlled by target switches, then GCC will automatically avoid using
9078 +these registers when the target switches are opposed to them.)
9079 +*/
9080 +#define CONDITIONAL_REGISTER_USAGE                              \
9081 +  do                                                           \
9082 +    {                                                          \
9083 +      if (flag_pic)                                            \
9084 +       {                                                       \
9085 +         fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1;              \
9086 +         call_used_regs[PIC_OFFSET_TABLE_REGNUM] = 1;          \
9087 +       }                                                       \
9088 +    }                                                          \
9089 +  while (0)
9090 +
9091 +
9092 +/*
9093 +If the program counter has a register number, define this as that
9094 +register number.  Otherwise, do not define it.
9095 +*/
9096 +
9097 +#define LAST_AVR32_REGNUM 16
9098 +
9099 +
9100 +/** Order of Allocation of Registers **/
9101 +
9102 +/*
9103 +If defined, an initializer for a vector of integers, containing the
9104 +numbers of hard registers in the order in which GCC should prefer
9105 +to use them (from most preferred to least).
9106 +
9107 +If this macro is not defined, registers are used lowest numbered first
9108 +(all else being equal).
9109 +
9110 +One use of this macro is on machines where the highest numbered
9111 +registers must always be saved and the save-multiple-registers
9112 +instruction supports only sequences of consecutive registers.  On such
9113 +machines, define REG_ALLOC_ORDER to be an initializer that lists
9114 +the highest numbered allocable register first.
9115 +*/
9116 +#define REG_ALLOC_ORDER        \
9117 +{                              \
9118 +  INTERNAL_REGNUM(8),          \
9119 +  INTERNAL_REGNUM(9),          \
9120 +  INTERNAL_REGNUM(10),         \
9121 +  INTERNAL_REGNUM(11),         \
9122 +  INTERNAL_REGNUM(12),         \
9123 +  LR_REGNUM,                   \
9124 +  INTERNAL_REGNUM(7),          \
9125 +  INTERNAL_REGNUM(6),          \
9126 +  INTERNAL_REGNUM(5),          \
9127 +  INTERNAL_REGNUM(4),          \
9128 +  INTERNAL_REGNUM(3),          \
9129 +  INTERNAL_REGNUM(2),          \
9130 +  INTERNAL_REGNUM(1),          \
9131 +  INTERNAL_REGNUM(0),          \
9132 +  SP_REGNUM,                           \
9133 +  PC_REGNUM                    \
9134 +}
9135 +
9136 +
9137 +/** How Values Fit in Registers **/
9138 +
9139 +/*
9140 +A C expression for the number of consecutive hard registers, starting
9141 +at register number REGNO, required to hold a value of mode
9142 +MODE.
9143 +
9144 +On a machine where all registers are exactly one word, a suitable
9145 +definition of this macro is
9146 +
9147 +#define HARD_REGNO_NREGS(REGNO, MODE)            \
9148 +   ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1)  \
9149 +    / UNITS_PER_WORD)
9150 +*/
9151 +#define HARD_REGNO_NREGS(REGNO, MODE) \
9152 +  ((unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD -1 ) / UNITS_PER_WORD))
9153 +
9154 +/*
9155 +A C expression that is nonzero if it is permissible to store a value
9156 +of mode MODE in hard register number REGNO (or in several
9157 +registers starting with that one).  For a machine where all registers
9158 +are equivalent, a suitable definition is
9159 +
9160 +  #define HARD_REGNO_MODE_OK(REGNO, MODE) 1
9161 +
9162 +You need not include code to check for the numbers of fixed registers,
9163 +because the allocation mechanism considers them to be always occupied.
9164 +
9165 +On some machines, double-precision values must be kept in even/odd
9166 +register pairs.  You can implement that by defining this macro to reject
9167 +odd register numbers for such modes.
9168 +
9169 +The minimum requirement for a mode to be OK in a register is that the
9170 +mov[mode] instruction pattern support moves between the
9171 +register and other hard register in the same class and that moving a
9172 +value into the register and back out not alter it.
9173 +
9174 +Since the same instruction used to move word_mode will work for
9175 +all narrower integer modes, it is not necessary on any machine for
9176 +HARD_REGNO_MODE_OK to distinguish between these modes, provided
9177 +you define patterns movhi, etc., to take advantage of this.  This
9178 +is useful because of the interaction between HARD_REGNO_MODE_OK
9179 +and MODES_TIEABLE_P; it is very desirable for all integer modes
9180 +to be tieable.
9181 +
9182 +Many machines have special registers for floating point arithmetic.
9183 +Often people assume that floating point machine modes are allowed only
9184 +in floating point registers.  This is not true.  Any registers that
9185 +can hold integers can safely hold a floating point machine
9186 +mode, whether or not floating arithmetic can be done on it in those
9187 +registers.  Integer move instructions can be used to move the values.
9188 +
9189 +On some machines, though, the converse is true: fixed-point machine
9190 +modes may not go in floating registers.  This is true if the floating
9191 +registers normalize any value stored in them, because storing a
9192 +non-floating value there would garble it.  In this case,
9193 +HARD_REGNO_MODE_OK should reject fixed-point machine modes in
9194 +floating registers.  But if the floating registers do not automatically
9195 +normalize, if you can store any bit pattern in one and retrieve it
9196 +unchanged without a trap, then any machine mode may go in a floating
9197 +register, so you can define this macro to say so.
9198 +
9199 +The primary significance of special floating registers is rather that
9200 +they are the registers acceptable in floating point arithmetic
9201 +instructions.  However, this is of no concern to
9202 +HARD_REGNO_MODE_OK.  You handle it by writing the proper
9203 +constraints for those instructions.
9204 +
9205 +On some machines, the floating registers are especially slow to access,
9206 +so that it is better to store a value in a stack frame than in such a
9207 +register if floating point arithmetic is not being done.  As long as the
9208 +floating registers are not in class GENERAL_REGS, they will not
9209 +be used unless some pattern's constraint asks for one.
9210 +*/
9211 +#define HARD_REGNO_MODE_OK(REGNO, MODE) avr32_hard_regno_mode_ok(REGNO, MODE)
9212 +
9213 +/*
9214 +A C expression that is nonzero if a value of mode
9215 +MODE1 is accessible in mode MODE2 without copying.
9216 +
9217 +If HARD_REGNO_MODE_OK(R, MODE1) and
9218 +HARD_REGNO_MODE_OK(R, MODE2) are always the same for
9219 +any R, then MODES_TIEABLE_P(MODE1, MODE2)
9220 +should be nonzero.  If they differ for any R, you should define
9221 +this macro to return zero unless some other mechanism ensures the
9222 +accessibility of the value in a narrower mode.
9223 +
9224 +You should define this macro to return nonzero in as many cases as
9225 +possible since doing so will allow GCC to perform better register
9226 +allocation.
9227 +*/
9228 +#define MODES_TIEABLE_P(MODE1, MODE2)  \
9229 +  (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
9230 +
9231 +
9232 +
9233 +/******************************************************************************
9234 + * Register Classes
9235 + *****************************************************************************/
9236 +
9237 +/*
9238 +An enumeral type that must be defined with all the register class names
9239 +as enumeral values.  NO_REGS must be first.  ALL_REGS
9240 +must be the last register class, followed by one more enumeral value,
9241 +LIM_REG_CLASSES, which is not a register class but rather
9242 +tells how many classes there are.
9243 +
9244 +Each register class has a number, which is the value of casting
9245 +the class name to type int.  The number serves as an index
9246 +in many of the tables described below.
9247 +*/
9248 +enum reg_class
9249 +{
9250 +  NO_REGS,
9251 +  GENERAL_REGS,
9252 +  ALL_REGS,
9253 +  LIM_REG_CLASSES
9254 +};
9255 +
9256 +/*
9257 +The number of distinct register classes, defined as follows:
9258 +  #define N_REG_CLASSES (int) LIM_REG_CLASSES
9259 +*/
9260 +#define N_REG_CLASSES (int)LIM_REG_CLASSES
9261 +
9262 +/*
9263 +An initializer containing the names of the register classes as C string
9264 +constants.  These names are used in writing some of the debugging dumps.
9265 +*/
9266 +#define REG_CLASS_NAMES                \
9267 +{                              \
9268 +  "NO_REGS",                   \
9269 +  "GENERAL_REGS",              \
9270 +  "ALL_REGS"                   \
9271 +}
9272 +
9273 +/*
9274 +An initializer containing the contents of the register classes, as integers
9275 +which are bit masks.  The nth integer specifies the contents of class
9276 +n.  The way the integer mask is interpreted is that
9277 +register r is in the class if mask & (1 << r) is 1.
9278 +
9279 +When the machine has more than 32 registers, an integer does not suffice.
9280 +Then the integers are replaced by sub-initializers, braced groupings containing
9281 +several integers.  Each sub-initializer must be suitable as an initializer
9282 +for the type HARD_REG_SET which is defined in hard-reg-set.h.
9283 +In this situation, the first integer in each sub-initializer corresponds to
9284 +registers 0 through 31, the second integer to registers 32 through 63, and
9285 +so on.
9286 +*/
9287 +#define REG_CLASS_CONTENTS {           \
9288 +  {0x00000000}, /* NO_REGS */          \
9289 +  {0x0000FFFF}, /* GENERAL_REGS */     \
9290 +  {0x7FFFFFFF}, /* ALL_REGS */         \
9291 +}
9292 +
9293 +
9294 +/*
9295 +A C expression whose value is a register class containing hard register
9296 +REGNO.  In general there is more than one such class; choose a class
9297 +which is minimal, meaning that no smaller class also contains the
9298 +register.
9299 +*/
9300 +#define REGNO_REG_CLASS(REGNO) (GENERAL_REGS)
9301 +
9302 +/*
9303 +A macro whose definition is the name of the class to which a valid
9304 +base register must belong.  A base register is one used in an address
9305 +which is the register value plus a displacement.
9306 +*/
9307 +#define BASE_REG_CLASS GENERAL_REGS
9308 +
9309 +/*
9310 +This is a variation of the BASE_REG_CLASS macro which allows
9311 +the selection of a base register in a mode depenedent manner.  If
9312 +mode is VOIDmode then it should return the same value as
9313 +BASE_REG_CLASS.
9314 +*/
9315 +#define MODE_BASE_REG_CLASS(MODE) BASE_REG_CLASS
9316 +
9317 +/*
9318 +A macro whose definition is the name of the class to which a valid
9319 +index register must belong.  An index register is one used in an
9320 +address where its value is either multiplied by a scale factor or
9321 +added to another register (as well as added to a displacement).
9322 +*/
9323 +#define INDEX_REG_CLASS BASE_REG_CLASS
9324 +
9325 +/*
9326 +A C expression which defines the machine-dependent operand constraint
9327 +letters for register classes.  If CHAR is such a letter, the
9328 +value should be the register class corresponding to it.  Otherwise,
9329 +the value should be NO_REGS.  The register letter r,
9330 +corresponding to class GENERAL_REGS, will not be passed
9331 +to this macro; you do not need to handle it.
9332 +*/
9333 +#define REG_CLASS_FROM_LETTER(CHAR) NO_REGS
9334 +
9335 +/* These assume that REGNO is a hard or pseudo reg number.
9336 +   They give nonzero only if REGNO is a hard reg of the suitable class
9337 +   or a pseudo reg currently allocated to a suitable hard reg.
9338 +   Since they use reg_renumber, they are safe only once reg_renumber
9339 +   has been allocated, which happens in local-alloc.c.  */
9340 +#define TEST_REGNO(R, TEST, VALUE) \
9341 +  ((R TEST VALUE) || ((unsigned) reg_renumber[R] TEST VALUE))
9342 +
9343 +/*
9344 +A C expression which is nonzero if register number num is suitable for use as a base
9345 +register in operand addresses. It may be either a suitable hard register or a pseudo
9346 +register that has been allocated such a hard register.
9347 +*/
9348 +#define REGNO_OK_FOR_BASE_P(NUM)  TEST_REGNO(NUM, <=, LAST_REGNUM)
9349 +
9350 +/* The following macro defines cover classes for Integrated Register
9351 +   Allocator.  Cover classes is a set of non-intersected register
9352 +   classes covering all hard registers used for register allocation
9353 +   purpose.  Any move between two registers of a cover class should be
9354 +   cheaper than load or store of the registers.  The macro value is
9355 +   array of register classes with LIM_REG_CLASSES used as the end
9356 +   marker.  */
9357 +
9358 +#define IRA_COVER_CLASSES               \
9359 +{                                       \
9360 +  GENERAL_REGS, LIM_REG_CLASSES         \
9361 +}
9362 +
9363 +/*
9364 +A C expression which is nonzero if register number NUM is
9365 +suitable for use as an index register in operand addresses.  It may be
9366 +either a suitable hard register or a pseudo register that has been
9367 +allocated such a hard register.
9368 +
9369 +The difference between an index register and a base register is that
9370 +the index register may be scaled.  If an address involves the sum of
9371 +two registers, neither one of them scaled, then either one may be
9372 +labeled the ``base'' and the other the ``index''; but whichever
9373 +labeling is used must fit the machine's constraints of which registers
9374 +may serve in each capacity.  The compiler will try both labelings,
9375 +looking for one that is valid, and will reload one or both registers
9376 +only if neither labeling works.
9377 +*/
9378 +#define REGNO_OK_FOR_INDEX_P(NUM) TEST_REGNO(NUM, <=, LAST_REGNUM)
9379 +
9380 +/*
9381 +A C expression that places additional restrictions on the register class
9382 +to use when it is necessary to copy value X into a register in class
9383 +CLASS.  The value is a register class; perhaps CLASS, or perhaps
9384 +another, smaller class.  On many machines, the following definition is
9385 +safe: #define PREFERRED_RELOAD_CLASS(X,CLASS) CLASS
9386 +
9387 +Sometimes returning a more restrictive class makes better code.  For
9388 +example, on the 68000, when X is an integer constant that is in range
9389 +for a 'moveq' instruction, the value of this macro is always
9390 +DATA_REGS as long as CLASS includes the data registers.
9391 +Requiring a data register guarantees that a 'moveq' will be used.
9392 +
9393 +If X is a const_double, by returning NO_REGS
9394 +you can force X into a memory constant.  This is useful on
9395 +certain machines where immediate floating values cannot be loaded into
9396 +certain kinds of registers.
9397 +*/
9398 +#define PREFERRED_RELOAD_CLASS(X, CLASS)  CLASS
9399 +
9400 +
9401 +
9402 +/*
9403 +A C expression for the maximum number of consecutive registers
9404 +of class CLASS needed to hold a value of mode MODE.
9405 +
9406 +This is closely related to the macro HARD_REGNO_NREGS.  In fact,
9407 +the value of the macro CLASS_MAX_NREGS(CLASS, MODE)
9408 +should be the maximum value of HARD_REGNO_NREGS(REGNO, MODE)
9409 +for all REGNO values in the class CLASS.
9410 +
9411 +This macro helps control the handling of multiple-word values
9412 +in the reload pass.
9413 +*/
9414 +#define CLASS_MAX_NREGS(CLASS, MODE) /* ToDo:fixme */ \
9415 +  (unsigned int)((GET_MODE_SIZE(MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
9416 +
9417 +
9418 +/*
9419 +  Using CONST_OK_FOR_CONSTRAINT_P instead of CONS_OK_FOR_LETTER_P
9420 +  in order to support constraints with more than one letter.
9421 +  Only two letters are then used for constant constraints,
9422 +  the letter 'K' and the letter 'I'. The constraint starting with
9423 +  these letters must consist of four characters. The character following
9424 +  'K' or 'I' must be either 'u' (unsigned) or 's' (signed) to specify
9425 +  if the constant is zero or sign extended. The last two characters specify
9426 +  the length in bits of the constant. The base constraint letter 'I' means
9427 +  that this is an negated constant, meaning that actually -VAL should be
9428 +  checked to lie withing the valid range instead of VAL which is used when
9429 +  'K' is the base constraint letter.
9430 +
9431 +*/
9432 +
9433 +#define CONSTRAINT_LEN(C, STR)                         \
9434 +  ( ((C) == 'K' || (C) == 'I') ?  4 :                  \
9435 +    ((C) == 'R') ?  5 :                                        \
9436 +    ((C) == 'P') ? -1 :                                 \
9437 +    DEFAULT_CONSTRAINT_LEN((C), (STR)) )
9438 +
9439 +#define CONST_OK_FOR_CONSTRAINT_P(VALUE, C, STR)       \
9440 +  avr32_const_ok_for_constraint_p(VALUE, C, STR)
9441 +
9442 +/*
9443 +A C expression that defines the machine-dependent operand constraint
9444 +letters that specify particular ranges of const_double values ('G' or 'H').
9445 +
9446 +If C is one of those letters, the expression should check that
9447 +VALUE, an RTX of code const_double, is in the appropriate
9448 +range and return 1 if so, 0 otherwise.  If C is not one of those
9449 +letters, the value should be 0 regardless of VALUE.
9450 +
9451 +const_double is used for all floating-point constants and for
9452 +DImode fixed-point constants.  A given letter can accept either
9453 +or both kinds of values.  It can use GET_MODE to distinguish
9454 +between these kinds.
9455 +*/
9456 +#define CONST_DOUBLE_OK_FOR_LETTER_P(OP, C) \
9457 +  ((C) == 'G' ? avr32_const_double_immediate(OP) : 0)
9458 +
9459 +/*
9460 +A C expression that defines the optional machine-dependent constraint
9461 +letters that can be used to segregate specific types of operands, usually
9462 +memory references, for the target machine.  Any letter that is not
9463 +elsewhere defined and not matched by REG_CLASS_FROM_LETTER
9464 +may be used.  Normally this macro will not be defined.
9465 +
9466 +If it is required for a particular target machine, it should return 1
9467 +if VALUE corresponds to the operand type represented by the
9468 +constraint letter C.  If C is not defined as an extra
9469 +constraint, the value returned should be 0 regardless of VALUE.
9470 +
9471 +For example, on the ROMP, load instructions cannot have their output
9472 +in r0 if the memory reference contains a symbolic address.  Constraint
9473 +letter 'Q' is defined as representing a memory address that does
9474 +not contain a symbolic address.  An alternative is specified with
9475 +a 'Q' constraint on the input and 'r' on the output.  The next
9476 +alternative specifies 'm' on the input and a register class that
9477 +does not include r0 on the output.
9478 +*/
9479 +#define EXTRA_CONSTRAINT_STR(OP, C, STR)                               \
9480 +  ((C) == 'W' ? avr32_address_operand(OP, GET_MODE(OP)) :              \
9481 +   (C) == 'R' ? (avr32_indirect_register_operand(OP, GET_MODE(OP)) ||  \
9482 +                 (avr32_imm_disp_memory_operand(OP, GET_MODE(OP))      \
9483 +                  && avr32_const_ok_for_constraint_p(                  \
9484 +                               INTVAL(XEXP(XEXP(OP, 0), 1)),           \
9485 +                               (STR)[1], &(STR)[1]))) :                \
9486 +   (C) == 'S' ? avr32_indexed_memory_operand(OP, GET_MODE(OP)) :       \
9487 +   (C) == 'T' ? avr32_const_pool_ref_operand(OP, GET_MODE(OP)) :       \
9488 +   (C) == 'U' ? SYMBOL_REF_RCALL_FUNCTION_P(OP) :                      \
9489 +   (C) == 'Z' ? avr32_cop_memory_operand(OP, GET_MODE(OP)) :           \
9490 +   (C) == 'Q' ? avr32_non_rmw_memory_operand(OP, GET_MODE(OP)) :               \
9491 +   (C) == 'Y' ? avr32_rmw_memory_operand(OP, GET_MODE(OP)) :            \
9492 +   0)
9493 +
9494 +
9495 +#define EXTRA_MEMORY_CONSTRAINT(C, STR) ( ((C) == 'R') ||               \
9496 +                                          ((C) == 'Q') ||               \
9497 +                                          ((C) == 'S') ||               \
9498 +                                          ((C) == 'Y') ||               \
9499 +                                          ((C) == 'Z') )
9500 +
9501 +
9502 +/* Returns nonzero if op is a function SYMBOL_REF which
9503 +   can be called using an rcall instruction */
9504 +#define SYMBOL_REF_RCALL_FUNCTION_P(op)  \
9505 +  ( GET_CODE(op) == SYMBOL_REF           \
9506 +    && SYMBOL_REF_FUNCTION_P(op)         \
9507 +    && SYMBOL_REF_LOCAL_P(op)            \
9508 +    && !SYMBOL_REF_EXTERNAL_P(op)        \
9509 +    && !TARGET_HAS_ASM_ADDR_PSEUDOS )
9510 +
9511 +/******************************************************************************
9512 + * Stack Layout and Calling Conventions
9513 + *****************************************************************************/
9514 +
9515 +/** Basic Stack Layout **/
9516 +
9517 +/*
9518 +Define this macro if pushing a word onto the stack moves the stack
9519 +pointer to a smaller address.
9520 +
9521 +When we say, ``define this macro if ...,'' it means that the
9522 +compiler checks this macro only with #ifdef so the precise
9523 +definition used does not matter.
9524 +*/
9525 +/* pushm decrece SP: *(--SP) <-- Rx */
9526 +#define STACK_GROWS_DOWNWARD
9527 +
9528 +/*
9529 +This macro defines the operation used when something is pushed
9530 +on the stack.  In RTL, a push operation will be
9531 +(set (mem (STACK_PUSH_CODE (reg sp))) ...)
9532 +
9533 +The choices are PRE_DEC, POST_DEC, PRE_INC,
9534 +and POST_INC.  Which of these is correct depends on
9535 +the stack direction and on whether the stack pointer points
9536 +to the last item on the stack or whether it points to the
9537 +space for the next item on the stack.
9538 +
9539 +The default is PRE_DEC when STACK_GROWS_DOWNWARD is
9540 +defined, which is almost always right, and PRE_INC otherwise,
9541 +which is often wrong.
9542 +*/
9543 +/* pushm: *(--SP) <-- Rx */
9544 +#define STACK_PUSH_CODE PRE_DEC
9545 +
9546 +/* Define this to nonzero if the nominal address of the stack frame
9547 +   is at the high-address end of the local variables;
9548 +   that is, each additional local variable allocated
9549 +   goes at a more negative offset in the frame.  */
9550 +#define FRAME_GROWS_DOWNWARD 1
9551 +
9552 +
9553 +/*
9554 +Offset from the frame pointer to the first local variable slot to be allocated.
9555 +
9556 +If FRAME_GROWS_DOWNWARD, find the next slot's offset by
9557 +subtracting the first slot's length from STARTING_FRAME_OFFSET.
9558 +Otherwise, it is found by adding the length of the first slot to the
9559 +value STARTING_FRAME_OFFSET.
9560 +  (i'm not sure if the above is still correct.. had to change it to get
9561 +   rid of an overfull.  --mew 2feb93 )
9562 +*/
9563 +#define STARTING_FRAME_OFFSET 0
9564 +
9565 +/*
9566 +Offset from the stack pointer register to the first location at which
9567 +outgoing arguments are placed.  If not specified, the default value of
9568 +zero is used.  This is the proper value for most machines.
9569 +
9570 +If ARGS_GROW_DOWNWARD, this is the offset to the location above
9571 +the first location at which outgoing arguments are placed.
9572 +*/
9573 +#define STACK_POINTER_OFFSET 0
9574 +
9575 +/*
9576 +Offset from the argument pointer register to the first argument's
9577 +address.  On some machines it may depend on the data type of the
9578 +function.
9579 +
9580 +If ARGS_GROW_DOWNWARD, this is the offset to the location above
9581 +the first argument's address.
9582 +*/
9583 +#define FIRST_PARM_OFFSET(FUNDECL) 0
9584 +
9585 +
9586 +/*
9587 +A C expression whose value is RTL representing the address in a stack
9588 +frame where the pointer to the caller's frame is stored.  Assume that
9589 +FRAMEADDR is an RTL expression for the address of the stack frame
9590 +itself.
9591 +
9592 +If you don't define this macro, the default is to return the value
9593 +of FRAMEADDR - that is, the stack frame address is also the
9594 +address of the stack word that points to the previous frame.
9595 +*/
9596 +#define DYNAMIC_CHAIN_ADDRESS(FRAMEADDR) plus_constant ((FRAMEADDR), 4)
9597 +
9598 +
9599 +/*
9600 +A C expression whose value is RTL representing the value of the return
9601 +address for the frame COUNT steps up from the current frame, after
9602 +the prologue.  FRAMEADDR is the frame pointer of the COUNT
9603 +frame, or the frame pointer of the COUNT - 1 frame if
9604 +RETURN_ADDR_IN_PREVIOUS_FRAME is defined.
9605 +
9606 +The value of the expression must always be the correct address when
9607 +COUNT is zero, but may be NULL_RTX if there is not way to
9608 +determine the return address of other frames.
9609 +*/
9610 +#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) avr32_return_addr(COUNT, FRAMEADDR)
9611 +
9612 +
9613 +/*
9614 +A C expression whose value is RTL representing the location of the
9615 +incoming return address at the beginning of any function, before the
9616 +prologue.  This RTL is either a REG, indicating that the return
9617 +value is saved in 'REG', or a MEM representing a location in
9618 +the stack.
9619 +
9620 +You only need to define this macro if you want to support call frame
9621 +debugging information like that provided by DWARF 2.
9622 +
9623 +If this RTL is a REG, you should also define
9624 +DWARF_FRAME_RETURN_COLUMN to DWARF_FRAME_REGNUM (REGNO).
9625 +*/
9626 +#define INCOMING_RETURN_ADDR_RTX gen_rtx_REG (Pmode, LR_REGNUM)
9627 +
9628 +/*
9629 +A C expression whose value is an integer giving the offset, in bytes,
9630 +from the value of the stack pointer register to the top of the stack
9631 +frame at the beginning of any function, before the prologue.  The top of
9632 +the frame is defined to be the value of the stack pointer in the
9633 +previous frame, just before the call instruction.
9634 +
9635 +You only need to define this macro if you want to support call frame
9636 +debugging information like that provided by DWARF 2.
9637 +*/
9638 +#define INCOMING_FRAME_SP_OFFSET 0
9639 +
9640 +
9641 +/** Exception Handling Support **/
9642 +
9643 +/* Use setjump/longjump for exception handling. */
9644 +#define DWARF2_UNWIND_INFO 0
9645 +#define MUST_USE_SJLJ_EXCEPTIONS 1
9646 +
9647 +/*
9648 +A C expression whose value is the Nth register number used for
9649 +data by exception handlers, or INVALID_REGNUM if fewer than
9650 +N registers are usable.
9651 +
9652 +The exception handling library routines communicate with the exception
9653 +handlers via a set of agreed upon registers.  Ideally these registers
9654 +should be call-clobbered; it is possible to use call-saved registers,
9655 +but may negatively impact code size.  The target must support at least
9656 +2 data registers, but should define 4 if there are enough free registers.
9657 +
9658 +You must define this macro if you want to support call frame exception
9659 +handling like that provided by DWARF 2.
9660 +*/
9661 +/*
9662 +  Use r9-r11
9663 +*/
9664 +#define EH_RETURN_DATA_REGNO(N)                                         \
9665 +  ((N<3) ? INTERNAL_REGNUM(N+9) : INVALID_REGNUM)
9666 +
9667 +/*
9668 +A C expression whose value is RTL representing a location in which
9669 +to store a stack adjustment to be applied before function return.
9670 +This is used to unwind the stack to an exception handler's call frame.
9671 +It will be assigned zero on code paths that return normally.
9672 +
9673 +Typically this is a call-clobbered hard register that is otherwise
9674 +untouched by the epilogue, but could also be a stack slot.
9675 +
9676 +You must define this macro if you want to support call frame exception
9677 +handling like that provided by DWARF 2.
9678 +*/
9679 +/*
9680 +  Use r8
9681 +*/
9682 +#define EH_RETURN_STACKADJ_REGNO INTERNAL_REGNUM(8)
9683 +#define EH_RETURN_STACKADJ_RTX gen_rtx_REG(SImode, EH_RETURN_STACKADJ_REGNO)
9684 +
9685 +/*
9686 +A C expression whose value is RTL representing a location in which
9687 +to store the address of an exception handler to which we should
9688 +return.  It will not be assigned on code paths that return normally.
9689 +
9690 +Typically this is the location in the call frame at which the normal
9691 +return address is stored.  For targets that return by popping an
9692 +address off the stack, this might be a memory address just below
9693 +the target call frame rather than inside the current call
9694 +frame.  EH_RETURN_STACKADJ_RTX will have already been assigned,
9695 +so it may be used to calculate the location of the target call frame.
9696 +
9697 +Some targets have more complex requirements than storing to an
9698 +address calculable during initial code generation.  In that case
9699 +the eh_return instruction pattern should be used instead.
9700 +
9701 +If you want to support call frame exception handling, you must
9702 +define either this macro or the eh_return instruction pattern.
9703 +*/
9704 +/*
9705 +  We define the eh_return instruction pattern, so this isn't needed.
9706 +*/
9707 +/* #define EH_RETURN_HANDLER_RTX gen_rtx_REG(Pmode, RET_REGISTER) */
9708 +
9709 +/*
9710 +  This macro chooses the encoding of pointers embedded in the
9711 +  exception handling sections. If at all possible, this should be
9712 +  defined such that the exception handling section will not require
9713 +  dynamic relocations, and so may be read-only.
9714 +
9715 +  code is 0 for data, 1 for code labels, 2 for function
9716 +  pointers. global is true if the symbol may be affected by dynamic
9717 +  relocations. The macro should return a combination of the DW_EH_PE_*
9718 +  defines as found in dwarf2.h.
9719 +
9720 +  If this macro is not defined, pointers will not be encoded but
9721 +  represented directly.
9722 +*/
9723 +#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)     \
9724 +  ((flag_pic && (GLOBAL) ? DW_EH_PE_indirect : 0)      \
9725 +   | (flag_pic ? DW_EH_PE_pcrel : DW_EH_PE_absptr)     \
9726 +   | DW_EH_PE_sdata4)
9727 +
9728 +/* ToDo: The rest of this subsection */
9729 +
9730 +/** Specifying How Stack Checking is Done **/
9731 +/* ToDo: All in this subsection */
9732 +
9733 +/** Registers That Address the Stack Frame **/
9734 +
9735 +/*
9736 +The register number of the stack pointer register, which must also be a
9737 +fixed register according to FIXED_REGISTERS.  On most machines,
9738 +the hardware determines which register this is.
9739 +*/
9740 +/* Using r13 as stack pointer. */
9741 +#define STACK_POINTER_REGNUM INTERNAL_REGNUM(13)
9742 +
9743 +/*
9744 +The register number of the frame pointer register, which is used to
9745 +access automatic variables in the stack frame.  On some machines, the
9746 +hardware determines which register this is.  On other machines, you can
9747 +choose any register you wish for this purpose.
9748 +*/
9749 +/* Use r7 */
9750 +#define FRAME_POINTER_REGNUM INTERNAL_REGNUM(7)
9751 +
9752 +/*
9753 +The register number of the arg pointer register, which is used to access
9754 +the function's argument list.  On some machines, this is the same as the
9755 +frame pointer register.  On some machines, the hardware determines which
9756 +register this is.  On other machines, you can choose any register you
9757 +wish for this purpose.  If this is not the same register as the frame
9758 +pointer register, then you must mark it as a fixed register according to
9759 +FIXED_REGISTERS, or arrange to be able to eliminate it (see Section
9760 +10.10.5 [Elimination], page 224).
9761 +*/
9762 +/* Using r5 */
9763 +#define ARG_POINTER_REGNUM INTERNAL_REGNUM(4)
9764 +
9765 +
9766 +/*
9767 +Register numbers used for passing a function's static chain pointer.  If
9768 +register windows are used, the register number as seen by the called
9769 +function is STATIC_CHAIN_INCOMING_REGNUM, while the register
9770 +number as seen by the calling function is STATIC_CHAIN_REGNUM.  If
9771 +these registers are the same, STATIC_CHAIN_INCOMING_REGNUM need
9772 +not be defined.
9773 +
9774 +The static chain register need not be a fixed register.
9775 +
9776 +If the static chain is passed in memory, these macros should not be
9777 +defined; instead, the next two macros should be defined.
9778 +*/
9779 +/* Using r0 */
9780 +#define STATIC_CHAIN_REGNUM INTERNAL_REGNUM(0)
9781 +
9782 +/** Eliminating Frame Pointer and Arg Pointer **/
9783 +
9784 +/*
9785 +A C expression which is nonzero if a function must have and use a frame
9786 +pointer.  This expression is evaluated  in the reload pass.  If its value is
9787 +nonzero the function will have a frame pointer.
9788 +
9789 +The expression can in principle examine the current function and decide
9790 +according to the facts, but on most machines the constant 0 or the
9791 +constant 1 suffices.  Use 0 when the machine allows code to be generated
9792 +with no frame pointer, and doing so saves some time or space.  Use 1
9793 +when there is no possible advantage to avoiding a frame pointer.
9794 +
9795 +In certain cases, the compiler does not know how to produce valid code
9796 +without a frame pointer.  The compiler recognizes those cases and
9797 +automatically gives the function a frame pointer regardless of what
9798 +FRAME_POINTER_REQUIRED says.  You don't need to worry about
9799 +them.
9800 +
9801 +In a function that does not require a frame pointer, the frame pointer
9802 +register can be allocated for ordinary usage, unless you mark it as a
9803 +fixed register.  See FIXED_REGISTERS for more information.
9804 +*/
9805 +/* We need the frame pointer when compiling for profiling */
9806 +#define FRAME_POINTER_REQUIRED (crtl->profile)
9807 +
9808 +/*
9809 +A C statement to store in the variable DEPTH_VAR the difference
9810 +between the frame pointer and the stack pointer values immediately after
9811 +the function prologue.  The value would be computed from information
9812 +such as the result of get_frame_size () and the tables of
9813 +registers regs_ever_live and call_used_regs.
9814 +
9815 +If ELIMINABLE_REGS is defined, this macro will be not be used and
9816 +need not be defined.  Otherwise, it must be defined even if
9817 +FRAME_POINTER_REQUIRED is defined to always be true; in that
9818 +case, you may set DEPTH_VAR to anything.
9819 +*/
9820 +#define INITIAL_FRAME_POINTER_OFFSET(DEPTH_VAR) ((DEPTH_VAR) = get_frame_size())
9821 +
9822 +/*
9823 +If defined, this macro specifies a table of register pairs used to
9824 +eliminate unneeded registers that point into the stack frame.  If it is not
9825 +defined, the only elimination attempted by the compiler is to replace
9826 +references to the frame pointer with references to the stack pointer.
9827 +
9828 +The definition of this macro is a list of structure initializations, each
9829 +of which specifies an original and replacement register.
9830 +
9831 +On some machines, the position of the argument pointer is not known until
9832 +the compilation is completed.  In such a case, a separate hard register
9833 +must be used for the argument pointer.  This register can be eliminated by
9834 +replacing it with either the frame pointer or the argument pointer,
9835 +depending on whether or not the frame pointer has been eliminated.
9836 +
9837 +In this case, you might specify:
9838 +  #define ELIMINABLE_REGS  \
9839 +  {{ARG_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
9840 +   {ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM}, \
9841 +   {FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}}
9842 +
9843 +Note that the elimination of the argument pointer with the stack pointer is
9844 +specified first since that is the preferred elimination.
9845 +*/
9846 +#define ELIMINABLE_REGS                                        \
9847 +{                                                      \
9848 +  { FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM },      \
9849 +  { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM },                \
9850 +  { ARG_POINTER_REGNUM, FRAME_POINTER_REGNUM }         \
9851 +}
9852 +
9853 +/*
9854 +A C expression that returns nonzero if the compiler is allowed to try
9855 +to replace register number FROM with register number
9856 +TO.  This macro need only be defined if ELIMINABLE_REGS
9857 +is defined, and will usually be the constant 1, since most of the cases
9858 +preventing register elimination are things that the compiler already
9859 +knows about.
9860 +*/
9861 +#define CAN_ELIMINATE(FROM, TO) 1
9862 +
9863 +/*
9864 +This macro is similar to INITIAL_FRAME_POINTER_OFFSET.  It
9865 +specifies the initial difference between the specified pair of
9866 +registers.  This macro must be defined if ELIMINABLE_REGS is
9867 +defined.
9868 +*/
9869 +#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)           \
9870 +  ((OFFSET) = avr32_initial_elimination_offset(FROM, TO))
9871 +
9872 +/** Passing Function Arguments on the Stack **/
9873 +
9874 +
9875 +/*
9876 +A C expression.  If nonzero, push insns will be used to pass
9877 +outgoing arguments.
9878 +If the target machine does not have a push instruction, set it to zero.
9879 +That directs GCC to use an alternate strategy: to
9880 +allocate the entire argument block and then store the arguments into
9881 +it.  When PUSH_ARGS is nonzero, PUSH_ROUNDING must be defined too.
9882 +*/
9883 +#define PUSH_ARGS 1
9884 +
9885 +/*
9886 +A C expression that is the number of bytes actually pushed onto the
9887 +stack when an instruction attempts to push NPUSHED bytes.
9888 +
9889 +On some machines, the definition
9890 +
9891 +  #define PUSH_ROUNDING(BYTES) (BYTES)
9892 +
9893 +will suffice.  But on other machines, instructions that appear
9894 +to push one byte actually push two bytes in an attempt to maintain
9895 +alignment.  Then the definition should be
9896 +
9897 +  #define PUSH_ROUNDING(BYTES) (((BYTES) + 1) & ~1)
9898 +*/
9899 +/* Push 4 bytes at the time. */
9900 +#define PUSH_ROUNDING(NPUSHED) (((NPUSHED) + 3) & ~3)
9901 +
9902 +/*
9903 +A C expression.  If nonzero, the maximum amount of space required for
9904 +outgoing arguments will be computed and placed into the variable
9905 +current_function_outgoing_args_size.  No space will be pushed
9906 +onto the stack for each call; instead, the function prologue should
9907 +increase the stack frame size by this amount.
9908 +
9909 +Setting both PUSH_ARGS and ACCUMULATE_OUTGOING_ARGS is not proper.
9910 +*/
9911 +#define ACCUMULATE_OUTGOING_ARGS 0
9912 +
9913 +/*
9914 +A C expression that should indicate the number of bytes of its own
9915 +arguments that a function pops on returning, or 0 if the
9916 +function pops no arguments and the caller must therefore pop them all
9917 +after the function returns.
9918 +
9919 +FUNDECL is a C variable whose value is a tree node that describes
9920 +the function in question.  Normally it is a node of type
9921 +FUNCTION_DECL that describes the declaration of the function.
9922 +From this you can obtain the DECL_ATTRIBUTES of the function.
9923 +
9924 +FUNTYPE is a C variable whose value is a tree node that
9925 +describes the function in question.  Normally it is a node of type
9926 +FUNCTION_TYPE that describes the data type of the function.
9927 +From this it is possible to obtain the data types of the value and
9928 +arguments (if known).
9929 +
9930 +When a call to a library function is being considered, FUNDECL
9931 +will contain an identifier node for the library function.  Thus, if
9932 +you need to distinguish among various library functions, you can do so
9933 +by their names.  Note that ``library function'' in this context means
9934 +a function used to perform arithmetic, whose name is known specially
9935 +in the compiler and was not mentioned in the C code being compiled.
9936 +
9937 +STACK_SIZE is the number of bytes of arguments passed on the
9938 +stack.  If a variable number of bytes is passed, it is zero, and
9939 +argument popping will always be the responsibility of the calling function.
9940 +
9941 +On the VAX, all functions always pop their arguments, so the definition
9942 +of this macro is STACK_SIZE.  On the 68000, using the standard
9943 +calling convention, no functions pop their arguments, so the value of
9944 +the macro is always 0 in this case.  But an alternative calling
9945 +convention is available in which functions that take a fixed number of
9946 +arguments pop them but other functions (such as printf) pop
9947 +nothing (the caller pops all).  When this convention is in use,
9948 +FUNTYPE is examined to determine whether a function takes a fixed
9949 +number of arguments.
9950 +*/
9951 +#define RETURN_POPS_ARGS(FUNDECL, FUNTYPE, STACK_SIZE) 0
9952 +
9953 +
9954 +/*Return true if this function can we use a single return instruction*/
9955 +#define USE_RETURN_INSN(ISCOND) avr32_use_return_insn(ISCOND)
9956 +
9957 +/*
9958 +A C expression that should indicate the number of bytes a call sequence
9959 +pops off the stack.  It is added to the value of RETURN_POPS_ARGS
9960 +when compiling a function call.
9961 +
9962 +CUM is the variable in which all arguments to the called function
9963 +have been accumulated.
9964 +
9965 +On certain architectures, such as the SH5, a call trampoline is used
9966 +that pops certain registers off the stack, depending on the arguments
9967 +that have been passed to the function.  Since this is a property of the
9968 +call site, not of the called function, RETURN_POPS_ARGS is not
9969 +appropriate.
9970 +*/
9971 +#define CALL_POPS_ARGS(CUM) 0
9972 +
9973 +/* Passing Arguments in Registers */
9974 +
9975 +/*
9976 +A C expression that controls whether a function argument is passed
9977 +in a register, and which register.
9978 +
9979 +The arguments are CUM, which summarizes all the previous
9980 +arguments; MODE, the machine mode of the argument; TYPE,
9981 +the data type of the argument as a tree node or 0 if that is not known
9982 +(which happens for C support library functions); and NAMED,
9983 +which is 1 for an ordinary argument and 0 for nameless arguments that
9984 +correspond to '...' in the called function's prototype.
9985 +TYPE can be an incomplete type if a syntax error has previously
9986 +occurred.
9987 +
9988 +The value of the expression is usually either a reg RTX for the
9989 +hard register in which to pass the argument, or zero to pass the
9990 +argument on the stack.
9991 +
9992 +For machines like the VAX and 68000, where normally all arguments are
9993 +pushed, zero suffices as a definition.
9994 +
9995 +The value of the expression can also be a parallel RTX.  This is
9996 +used when an argument is passed in multiple locations.  The mode of the
9997 +of the parallel should be the mode of the entire argument.  The
9998 +parallel holds any number of expr_list pairs; each one
9999 +describes where part of the argument is passed.  In each
10000 +expr_list the first operand must be a reg RTX for the hard
10001 +register in which to pass this part of the argument, and the mode of the
10002 +register RTX indicates how large this part of the argument is.  The
10003 +second operand of the expr_list is a const_int which gives
10004 +the offset in bytes into the entire argument of where this part starts.
10005 +As a special exception the first expr_list in the parallel
10006 +RTX may have a first operand of zero.  This indicates that the entire
10007 +argument is also stored on the stack.
10008 +
10009 +The last time this macro is called, it is called with MODE == VOIDmode,
10010 +and its result is passed to the call or call_value
10011 +pattern as operands 2 and 3 respectively.
10012 +
10013 +The usual way to make the ISO library 'stdarg.h' work on a machine
10014 +where some arguments are usually passed in registers, is to cause
10015 +nameless arguments to be passed on the stack instead.  This is done
10016 +by making FUNCTION_ARG return 0 whenever NAMED is 0.
10017 +
10018 +You may use the macro MUST_PASS_IN_STACK (MODE, TYPE)
10019 +in the definition of this macro to determine if this argument is of a
10020 +type that must be passed in the stack.  If REG_PARM_STACK_SPACE
10021 +is not defined and FUNCTION_ARG returns nonzero for such an
10022 +argument, the compiler will abort.  If REG_PARM_STACK_SPACE is
10023 +defined, the argument will be computed in the stack and then loaded into
10024 +a register.  */
10025 +
10026 +#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
10027 +  avr32_function_arg(&(CUM), MODE, TYPE, NAMED)
10028 +
10029 +/*
10030 +A C type for declaring a variable that is used as the first argument of
10031 +FUNCTION_ARG and other related values.  For some target machines,
10032 +the type int suffices and can hold the number of bytes of
10033 +argument so far.
10034 +
10035 +There is no need to record in CUMULATIVE_ARGS anything about the
10036 +arguments that have been passed on the stack.  The compiler has other
10037 +variables to keep track of that.  For target machines on which all
10038 +arguments are passed on the stack, there is no need to store anything in
10039 +CUMULATIVE_ARGS; however, the data structure must exist and
10040 +should not be empty, so use int.
10041 +*/
10042 +typedef struct avr32_args
10043 +{
10044 +  /* Index representing the argument register the current function argument
10045 +     will occupy */
10046 +  int index;
10047 +  /* A mask with bits representing the argument registers: if a bit is set
10048 +     then this register is used for an argument */
10049 +  int used_index;
10050 +  /* TRUE if this function has anonymous arguments */
10051 +  int uses_anonymous_args;
10052 +  /* The size in bytes of the named arguments pushed on the stack */
10053 +  int stack_pushed_args_size;
10054 +  /* Set to true if this function needs a Return Value Pointer */
10055 +  int use_rvp;
10056 +  /* Set to true if function is a flashvault function. */
10057 +  int flashvault_func;
10058 +
10059 +} CUMULATIVE_ARGS;
10060 +
10061 +
10062 +#define FIRST_CUM_REG_INDEX 0
10063 +#define LAST_CUM_REG_INDEX 4
10064 +#define GET_REG_INDEX(CUM) ((CUM)->index)
10065 +#define SET_REG_INDEX(CUM, INDEX) ((CUM)->index = (INDEX));
10066 +#define GET_USED_INDEX(CUM, INDEX) ((CUM)->used_index & (1 << (INDEX)))
10067 +#define SET_USED_INDEX(CUM, INDEX)             \
10068 +  do                                           \
10069 +    {                                          \
10070 +      if (INDEX >= 0)                          \
10071 +        (CUM)->used_index |= (1 << (INDEX));   \
10072 +    }                                          \
10073 +  while (0)
10074 +#define SET_INDEXES_UNUSED(CUM) ((CUM)->used_index = 0)
10075 +
10076 +/*
10077 +   A C statement (sans semicolon) for initializing the variable cum for the
10078 +   state at the beginning of the argument list. The variable has type
10079 +   CUMULATIVE_ARGS. The value of FNTYPE is the tree node for the data type of
10080 +   the function which will receive the args, or 0 if the args are to a compiler
10081 +   support library function. For direct calls that are not libcalls, FNDECL
10082 +   contain the declaration node of the function. FNDECL is also set when
10083 +   INIT_CUMULATIVE_ARGS is used to find arguments for the function being
10084 +   compiled.  N_NAMED_ARGS is set to the number of named arguments, including a
10085 +   structure return address if it is passed as a parameter, when making a call.
10086 +   When processing incoming arguments, N_NAMED_ARGS is set to -1.
10087 +
10088 +   When processing a call to a compiler support library function, LIBNAME
10089 +   identifies which one.  It is a symbol_ref rtx which contains the name of the
10090 +   function, as a string. LIBNAME is 0 when an ordinary C function call is
10091 +   being processed. Thus, each time this macro is called, either LIBNAME or
10092 +   FNTYPE is nonzero, but never both of them at once.
10093 +*/
10094 +#define INIT_CUMULATIVE_ARGS(CUM, FNTYPE, LIBNAME, FNDECL, N_NAMED_ARGS) \
10095 +  avr32_init_cumulative_args(&(CUM), FNTYPE, LIBNAME, FNDECL)
10096 +
10097 +/*
10098 +A C statement (sans semicolon) to update the summarizer variable
10099 +CUM to advance past an argument in the argument list.  The
10100 +values MODE, TYPE and NAMED describe that argument.
10101 +Once this is done, the variable CUM is suitable for analyzing
10102 +the following argument with FUNCTION_ARG, etc.
10103 +
10104 +This macro need not do anything if the argument in question was passed
10105 +on the stack.  The compiler knows how to track the amount of stack space
10106 +used for arguments without any special help.
10107 +*/
10108 +#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
10109 +  avr32_function_arg_advance(&(CUM), MODE, TYPE, NAMED)
10110 +
10111 +/*
10112 +If defined, a C expression which determines whether, and in which direction,
10113 +to pad out an argument with extra space.  The value should be of type
10114 +enum direction: either 'upward' to pad above the argument,
10115 +'downward' to pad below, or 'none' to inhibit padding.
10116 +
10117 +The amount of padding is always just enough to reach the next
10118 +multiple of FUNCTION_ARG_BOUNDARY; this macro does not control
10119 +it.
10120 +
10121 +This macro has a default definition which is right for most systems.
10122 +For little-endian machines, the default is to pad upward.  For
10123 +big-endian machines, the default is to pad downward for an argument of
10124 +constant size shorter than an int, and upward otherwise.
10125 +*/
10126 +#define FUNCTION_ARG_PADDING(MODE, TYPE) \
10127 +  avr32_function_arg_padding(MODE, TYPE)
10128 +
10129 +/*
10130 +  Specify padding for the last element of a block move between registers
10131 +  and memory. First is nonzero if this is the only element. Defining
10132 +  this macro allows better control of register function parameters on
10133 +  big-endian machines, without using PARALLEL rtl. In particular,
10134 +  MUST_PASS_IN_STACK need not test padding and mode of types in registers,
10135 +  as there is no longer a "wrong" part of a register; For example, a three
10136 +  byte aggregate may be passed in the high part of a register if so required.
10137 +*/
10138 +#define BLOCK_REG_PADDING(MODE, TYPE, FIRST) \
10139 +  avr32_function_arg_padding(MODE, TYPE)
10140 +
10141 +/*
10142 +If defined, a C expression which determines whether the default
10143 +implementation of va_arg will attempt to pad down before reading the
10144 +next argument, if that argument is smaller than its aligned space as
10145 +controlled by PARM_BOUNDARY.  If this macro is not defined, all such
10146 +arguments are padded down if BYTES_BIG_ENDIAN is true.
10147 +*/
10148 +#define PAD_VARARGS_DOWN \
10149 +  (FUNCTION_ARG_PADDING (TYPE_MODE (type), type) == downward)
10150 +
10151 +/*
10152 +A C expression that is nonzero if REGNO is the number of a hard
10153 +register in which function arguments are sometimes passed.  This does
10154 +not include implicit arguments such as the static chain and
10155 +the structure-value address.  On many machines, no registers can be
10156 +used for this purpose since all function arguments are pushed on the
10157 +stack.
10158 +*/
10159 +/*
10160 +  Use r8 - r12 for function arguments.
10161 +*/
10162 +#define FUNCTION_ARG_REGNO_P(REGNO) \
10163 +  (REGNO >= 3 && REGNO <= 7)
10164 +
10165 +/* Number of registers used for passing function arguments */
10166 +#define NUM_ARG_REGS 5
10167 +
10168 +/*
10169 +If defined, the order in which arguments are loaded into their
10170 +respective argument registers is reversed so that the last
10171 +argument is loaded first.  This macro only affects arguments
10172 +passed in registers.
10173 +*/
10174 +/* #define LOAD_ARGS_REVERSED */
10175 +
10176 +/** How Scalar Function Values Are Returned **/
10177 +
10178 +/* AVR32 is using r12 as return register. */
10179 +#define RET_REGISTER (15 - 12)
10180 +
10181 +/*
10182 +A C expression to create an RTX representing the place where a library
10183 +function returns a value of mode MODE.  If the precise function
10184 +being called is known, FUNC is a tree node
10185 +(FUNCTION_DECL) for it; otherwise, func is a null
10186 +pointer.  This makes it possible to use a different value-returning
10187 +convention for specific functions when all their calls are
10188 +known.
10189 +
10190 +Note that "library function" in this context means a compiler
10191 +support routine, used to perform arithmetic, whose name is known
10192 +specially by the compiler and was not mentioned in the C code being
10193 +compiled.
10194 +
10195 +The definition of LIBRARY_VALUE need not be concerned aggregate
10196 +data types, because none of the library functions returns such types.
10197 +*/
10198 +#define LIBCALL_VALUE(MODE) avr32_libcall_value(MODE)
10199 +
10200 +/*
10201 +A C expression that is nonzero if REGNO is the number of a hard
10202 +register in which the values of called function may come back.
10203 +
10204 +A register whose use for returning values is limited to serving as the
10205 +second of a pair (for a value of type double, say) need not be
10206 +recognized by this macro.  So for most machines, this definition
10207 +suffices:
10208 +  #define FUNCTION_VALUE_REGNO_P(N) ((N) == 0)
10209 +
10210 +If the machine has register windows, so that the caller and the called
10211 +function use different registers for the return value, this macro
10212 +should recognize only the caller's register numbers.
10213 +*/
10214 +/*
10215 +  When returning a value of mode DImode, r11:r10 is used, else r12 is used.
10216 +*/
10217 +#define FUNCTION_VALUE_REGNO_P(REGNO) ((REGNO) == RET_REGISTER \
10218 +                                       || (REGNO) == INTERNAL_REGNUM(11))
10219 +
10220 +
10221 +/** How Large Values Are Returned **/
10222 +
10223 +
10224 +/*
10225 +Define this macro to be 1 if all structure and union return values must be
10226 +in memory.  Since this results in slower code, this should be defined
10227 +only if needed for compatibility with other compilers or with an ABI.
10228 +If you define this macro to be 0, then the conventions used for structure
10229 +and union return values are decided by the RETURN_IN_MEMORY macro.
10230 +
10231 +If not defined, this defaults to the value 1.
10232 +*/
10233 +#define DEFAULT_PCC_STRUCT_RETURN 0
10234 +
10235 +
10236 +
10237 +
10238 +/** Generating Code for Profiling **/
10239 +
10240 +/*
10241 +A C statement or compound statement to output to FILE some
10242 +assembler code to call the profiling subroutine mcount.
10243 +
10244 +The details of how mcount expects to be called are determined by
10245 +your operating system environment, not by GCC.  To figure them out,
10246 +compile a small program for profiling using the system's installed C
10247 +compiler and look at the assembler code that results.
10248 +
10249 +Older implementations of mcount expect the address of a counter
10250 +variable to be loaded into some register.  The name of this variable is
10251 +'LP' followed by the number LABELNO, so you would generate
10252 +the name using 'LP%d' in a fprintf.
10253 +*/
10254 +/* ToDo: fixme */
10255 +#ifndef FUNCTION_PROFILER
10256 +#define FUNCTION_PROFILER(FILE, LABELNO) \
10257 +  fprintf((FILE), "/* profiler %d */", (LABELNO))
10258 +#endif
10259 +
10260 +
10261 +/*****************************************************************************
10262 + * Trampolines for Nested Functions                                          *
10263 + *****************************************************************************/
10264 +
10265 +/*
10266 +A C statement to output, on the stream FILE, assembler code for a
10267 +block of data that contains the constant parts of a trampoline.  This
10268 +code should not include a label - the label is taken care of
10269 +automatically.
10270 +
10271 +If you do not define this macro, it means no template is needed
10272 +for the target.  Do not define this macro on systems where the block move
10273 +code to copy the trampoline into place would be larger than the code
10274 +to generate it on the spot.
10275 +*/
10276 +/* ToDo: correct? */
10277 +#define TRAMPOLINE_TEMPLATE(FILE) avr32_trampoline_template(FILE);
10278 +
10279 +
10280 +/*
10281 +A C expression for the size in bytes of the trampoline, as an integer.
10282 +*/
10283 +/* ToDo: fixme */
10284 +#define TRAMPOLINE_SIZE 0x0C
10285 +
10286 +/*
10287 +Alignment required for trampolines, in bits.
10288 +
10289 +If you don't define this macro, the value of BIGGEST_ALIGNMENT
10290 +is used for aligning trampolines.
10291 +*/
10292 +#define TRAMPOLINE_ALIGNMENT 16
10293 +
10294 +/*
10295 +A C statement to initialize the variable parts of a trampoline.
10296 +ADDR is an RTX for the address of the trampoline; FNADDR is
10297 +an RTX for the address of the nested function; STATIC_CHAIN is an
10298 +RTX for the static chain value that should be passed to the function
10299 +when it is called.
10300 +*/
10301 +#define INITIALIZE_TRAMPOLINE(ADDR, FNADDR, STATIC_CHAIN) \
10302 +  avr32_initialize_trampoline(ADDR, FNADDR, STATIC_CHAIN)
10303 +
10304 +
10305 +/******************************************************************************
10306 + * Implicit Calls to Library Routines
10307 + *****************************************************************************/
10308 +
10309 +/* Tail calling.  */
10310 +
10311 +/* A C expression that evaluates to true if it is ok to perform a sibling
10312 +   call to DECL.  */
10313 +#define FUNCTION_OK_FOR_SIBCALL(DECL) 0
10314 +
10315 +#define OVERRIDE_OPTIONS  avr32_override_options ()
10316 +
10317 +#define OPTIMIZATION_OPTIONS(LEVEL, SIZE) avr32_optimization_options (LEVEL, SIZE)
10318 +
10319 +/******************************************************************************
10320 + * Addressing Modes
10321 + *****************************************************************************/
10322 +
10323 +/*
10324 +A C expression that is nonzero if the machine supports pre-increment,
10325 +pre-decrement, post-increment, or post-decrement addressing respectively.
10326 +*/
10327 +/*
10328 +  AVR32 supports Rp++ and --Rp
10329 +*/
10330 +#define HAVE_PRE_INCREMENT 0
10331 +#define HAVE_PRE_DECREMENT 1
10332 +#define HAVE_POST_INCREMENT 1
10333 +#define HAVE_POST_DECREMENT 0
10334 +
10335 +/*
10336 +A C expression that is nonzero if the machine supports pre- or
10337 +post-address side-effect generation involving constants other than
10338 +the size of the memory operand.
10339 +*/
10340 +#define HAVE_PRE_MODIFY_DISP 0
10341 +#define HAVE_POST_MODIFY_DISP 0
10342 +
10343 +/*
10344 +A C expression that is nonzero if the machine supports pre- or
10345 +post-address side-effect generation involving a register displacement.
10346 +*/
10347 +#define HAVE_PRE_MODIFY_REG 0
10348 +#define HAVE_POST_MODIFY_REG 0
10349 +
10350 +/*
10351 +A C expression that is 1 if the RTX X is a constant which
10352 +is a valid address.  On most machines, this can be defined as
10353 +CONSTANT_P (X), but a few machines are more restrictive
10354 +in which constant addresses are supported.
10355 +
10356 +CONSTANT_P accepts integer-values expressions whose values are
10357 +not explicitly known, such as symbol_ref, label_ref, and
10358 +high expressions and const arithmetic expressions, in
10359 +addition to const_int and const_double expressions.
10360 +*/
10361 +#define CONSTANT_ADDRESS_P(X) CONSTANT_P(X)
10362 +
10363 +/*
10364 +A number, the maximum number of registers that can appear in a valid
10365 +memory address.  Note that it is up to you to specify a value equal to
10366 +the maximum number that GO_IF_LEGITIMATE_ADDRESS would ever
10367 +accept.
10368 +*/
10369 +#define MAX_REGS_PER_ADDRESS 2
10370 +
10371 +/*
10372 +A C compound statement with a conditional goto LABEL;
10373 +executed if X (an RTX) is a legitimate memory address on the
10374 +target machine for a memory operand of mode MODE.
10375 +
10376 +It usually pays to define several simpler macros to serve as
10377 +subroutines for this one.  Otherwise it may be too complicated to
10378 +understand.
10379 +
10380 +This macro must exist in two variants: a strict variant and a
10381 +non-strict one.  The strict variant is used in the reload pass.  It
10382 +must be defined so that any pseudo-register that has not been
10383 +allocated a hard register is considered a memory reference.  In
10384 +contexts where some kind of register is required, a pseudo-register
10385 +with no hard register must be rejected.
10386 +
10387 +The non-strict variant is used in other passes.  It must be defined to
10388 +accept all pseudo-registers in every context where some kind of
10389 +register is required.
10390 +
10391 +Compiler source files that want to use the strict variant of this
10392 +macro define the macro REG_OK_STRICT.  You should use an
10393 +#ifdef REG_OK_STRICT conditional to define the strict variant
10394 +in that case and the non-strict variant otherwise.
10395 +
10396 +Subroutines to check for acceptable registers for various purposes (one
10397 +for base registers, one for index registers, and so on) are typically
10398 +among the subroutines used to define GO_IF_LEGITIMATE_ADDRESS.
10399 +Then only these subroutine macros need have two variants; the higher
10400 +levels of macros may be the same whether strict or not.
10401 +
10402 +Normally, constant addresses which are the sum of a symbol_ref
10403 +and an integer are stored inside a const RTX to mark them as
10404 +constant.  Therefore, there is no need to recognize such sums
10405 +specifically as legitimate addresses.  Normally you would simply
10406 +recognize any const as legitimate.
10407 +
10408 +Usually PRINT_OPERAND_ADDRESS is not prepared to handle constant
10409 +sums that are not marked with  const.  It assumes that a naked
10410 +plus indicates indexing.  If so, then you must reject such
10411 +naked constant sums as illegitimate addresses, so that none of them will
10412 +be given to PRINT_OPERAND_ADDRESS.
10413 +
10414 +On some machines, whether a symbolic address is legitimate depends on
10415 +the section that the address refers to.  On these machines, define the
10416 +macro ENCODE_SECTION_INFO to store the information into the
10417 +symbol_ref, and then check for it here.  When you see a
10418 +const, you will have to look inside it to find the
10419 +symbol_ref in order to determine the section.
10420 +
10421 +The best way to modify the name string is by adding text to the
10422 +beginning, with suitable punctuation to prevent any ambiguity.  Allocate
10423 +the new name in saveable_obstack.  You will have to modify
10424 +ASM_OUTPUT_LABELREF to remove and decode the added text and
10425 +output the name accordingly, and define STRIP_NAME_ENCODING to
10426 +access the original name string.
10427 +
10428 +You can check the information stored here into the symbol_ref in
10429 +the definitions of the macros GO_IF_LEGITIMATE_ADDRESS and
10430 +PRINT_OPERAND_ADDRESS.
10431 +*/
10432 +#ifdef REG_OK_STRICT
10433 +#  define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)     \
10434 +  do                                                   \
10435 +    {                                                  \
10436 +      if (avr32_legitimate_address(MODE, X, 1))                \
10437 +       goto LABEL;                                     \
10438 +    }                                                  \
10439 +  while (0)
10440 +#else
10441 +#  define GO_IF_LEGITIMATE_ADDRESS(MODE, X, LABEL)     \
10442 +  do                                                   \
10443 +    {                                                  \
10444 +      if (avr32_legitimate_address(MODE, X, 0))                \
10445 +       goto LABEL;                                     \
10446 +    }                                                  \
10447 +  while (0)
10448 +#endif
10449 +
10450 +
10451 +
10452 +/*
10453 +A C compound statement that attempts to replace X with a valid
10454 +memory address for an operand of mode MODE.  win will be a
10455 +C statement label elsewhere in the code; the macro definition may use
10456 +
10457 +  GO_IF_LEGITIMATE_ADDRESS (MODE, X, WIN);
10458 +
10459 +to avoid further processing if the address has become legitimate.
10460 +
10461 +X will always be the result of a call to break_out_memory_refs,
10462 +and OLDX will be the operand that was given to that function to produce
10463 +X.
10464 +
10465 +The code generated by this macro should not alter the substructure of
10466 +X.  If it transforms X into a more legitimate form, it
10467 +should assign X (which will always be a C variable) a new value.
10468 +
10469 +It is not necessary for this macro to come up with a legitimate
10470 +address.  The compiler has standard ways of doing so in all cases.  In
10471 +fact, it is safe for this macro to do nothing.  But often a
10472 +machine-dependent strategy can generate better code.
10473 +*/
10474 +#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN)                 \
10475 +  do                                                           \
10476 +    {                                                          \
10477 +      if (GET_CODE(X) == PLUS                                  \
10478 +         && GET_CODE(XEXP(X, 0)) == REG                        \
10479 +         && GET_CODE(XEXP(X, 1)) == CONST_INT                  \
10480 +         && !CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(X, 1)),     \
10481 +                                       'K', "Ks16"))           \
10482 +       {                                                       \
10483 +         rtx index = force_reg(SImode, XEXP(X, 1));            \
10484 +         X = gen_rtx_PLUS( SImode, XEXP(X, 0), index);         \
10485 +       }                                                       \
10486 +      GO_IF_LEGITIMATE_ADDRESS(MODE, X, WIN);                  \
10487 +    }                                                          \
10488 +  while(0)
10489 +
10490 +
10491 +/*
10492 +A C statement or compound statement with a conditional
10493 +goto LABEL; executed if memory address X (an RTX) can have
10494 +different meanings depending on the machine mode of the memory
10495 +reference it is used for or if the address is valid for some modes
10496 +but not others.
10497 +
10498 +Autoincrement and autodecrement addresses typically have mode-dependent
10499 +effects because the amount of the increment or decrement is the size
10500 +of the operand being addressed.  Some machines have other mode-dependent
10501 +addresses.  Many RISC machines have no mode-dependent addresses.
10502 +
10503 +You may assume that ADDR is a valid address for the machine.
10504 +*/
10505 +#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR, LABEL)      \
10506 +  do                                                   \
10507 +    {                                                  \
10508 +      if (GET_CODE (ADDR) == POST_INC                  \
10509 +         || GET_CODE (ADDR) == PRE_DEC)                \
10510 +       goto LABEL;                                     \
10511 +    }                                                  \
10512 +  while (0)
10513 +
10514 +/*
10515 +A C expression that is nonzero if X is a legitimate constant for
10516 +an immediate operand on the target machine.  You can assume that
10517 +X satisfies CONSTANT_P, so you need not check this.  In fact,
10518 +'1' is a suitable definition for this macro on machines where
10519 +anything CONSTANT_P is valid.
10520 +*/
10521 +#define LEGITIMATE_CONSTANT_P(X) avr32_legitimate_constant_p(X)
10522 +
10523 +
10524 +/******************************************************************************
10525 + * Condition Code Status
10526 + *****************************************************************************/
10527 +
10528 +/*
10529 +C code for a data type which is used for declaring the mdep
10530 +component of cc_status.  It defaults to int.
10531 +
10532 +This macro is not used on machines that do not use cc0.
10533 +*/
10534 +
10535 +typedef struct
10536 +{
10537 +  int flags;
10538 +  rtx value;
10539 +  int cond_exec_cmp_clobbered;
10540 +} avr32_status_reg;
10541 +
10542 +
10543 +#define CC_STATUS_MDEP avr32_status_reg
10544 +
10545 +/*
10546 +A C expression to initialize the mdep field to "empty".
10547 +The default definition does nothing, since most machines don't use
10548 +the field anyway.  If you want to use the field, you should probably
10549 +define this macro to initialize it.
10550 +
10551 +This macro is not used on machines that do not use cc0.
10552 +*/
10553 +
10554 +#define CC_STATUS_MDEP_INIT  \
10555 +   (cc_status.mdep.flags = CC_NONE , cc_status.mdep.cond_exec_cmp_clobbered = 0, cc_status.mdep.value = 0)
10556 +
10557 +/*
10558 +A C compound statement to set the components of cc_status
10559 +appropriately for an insn INSN whose body is EXP.  It is
10560 +this macro's responsibility to recognize insns that set the condition
10561 +code as a byproduct of other activity as well as those that explicitly
10562 +set (cc0).
10563 +
10564 +This macro is not used on machines that do not use cc0.
10565 +
10566 +If there are insns that do not set the condition code but do alter
10567 +other machine registers, this macro must check to see whether they
10568 +invalidate the expressions that the condition code is recorded as
10569 +reflecting.  For example, on the 68000, insns that store in address
10570 +registers do not set the condition code, which means that usually
10571 +NOTICE_UPDATE_CC can leave cc_status unaltered for such
10572 +insns.  But suppose that the previous insn set the condition code
10573 +based on location 'a4@@(102)' and the current insn stores a new
10574 +value in 'a4'.  Although the condition code is not changed by
10575 +this, it will no longer be true that it reflects the contents of
10576 +'a4@@(102)'.  Therefore, NOTICE_UPDATE_CC must alter
10577 +cc_status in this case to say that nothing is known about the
10578 +condition code value.
10579 +
10580 +The definition of NOTICE_UPDATE_CC must be prepared to deal
10581 +with the results of peephole optimization: insns whose patterns are
10582 +parallel RTXs containing various reg, mem or
10583 +constants which are just the operands.  The RTL structure of these
10584 +insns is not sufficient to indicate what the insns actually do.  What
10585 +NOTICE_UPDATE_CC should do when it sees one is just to run
10586 +CC_STATUS_INIT.
10587 +
10588 +A possible definition of NOTICE_UPDATE_CC is to call a function
10589 +that looks at an attribute (see Insn Attributes) named, for example,
10590 +'cc'.  This avoids having detailed information about patterns in
10591 +two places, the 'md' file and in NOTICE_UPDATE_CC.
10592 +*/
10593 +
10594 +#define NOTICE_UPDATE_CC(EXP, INSN) avr32_notice_update_cc(EXP, INSN)
10595 +
10596 +
10597 +
10598 +
10599 +/******************************************************************************
10600 + * Describing Relative Costs of Operations
10601 + *****************************************************************************/
10602 +
10603 +
10604 +
10605 +/*
10606 +A C expression for the cost of moving data of mode MODE from a
10607 +register in class FROM to one in class TO.  The classes are
10608 +expressed using the enumeration values such as GENERAL_REGS.  A
10609 +value of 2 is the default; other values are interpreted relative to
10610 +that.
10611 +
10612 +It is not required that the cost always equal 2 when FROM is the
10613 +same as TO; on some machines it is expensive to move between
10614 +registers if they are not general registers.
10615 +
10616 +If reload sees an insn consisting of a single set between two
10617 +hard registers, and if REGISTER_MOVE_COST applied to their
10618 +classes returns a value of 2, reload does not check to ensure that the
10619 +constraints of the insn are met.  Setting a cost of other than 2 will
10620 +allow reload to verify that the constraints are met.  You should do this
10621 +if the movm pattern's constraints do not allow such copying.
10622 +*/
10623 +#define REGISTER_MOVE_COST(MODE, FROM, TO) \
10624 +  ((GET_MODE_SIZE(MODE) <= 4) ? 2:         \
10625 +   (GET_MODE_SIZE(MODE) <= 8) ? 3:         \
10626 +   4)
10627 +
10628 +/*
10629 +A C expression for the cost of moving data of mode MODE between a
10630 +register of class CLASS and memory; IN is zero if the value
10631 +is to be written to memory, nonzero if it is to be read in.  This cost
10632 +is relative to those in REGISTER_MOVE_COST.  If moving between
10633 +registers and memory is more expensive than between two registers, you
10634 +should define this macro to express the relative cost.
10635 +
10636 +If you do not define this macro, GCC uses a default cost of 4 plus
10637 +the cost of copying via a secondary reload register, if one is
10638 +needed.  If your machine requires a secondary reload register to copy
10639 +between memory and a register of CLASS but the reload mechanism is
10640 +more complex than copying via an intermediate, define this macro to
10641 +reflect the actual cost of the move.
10642 +
10643 +GCC defines the function memory_move_secondary_cost if
10644 +secondary reloads are needed.  It computes the costs due to copying via
10645 +a secondary register.  If your machine copies from memory using a
10646 +secondary register in the conventional way but the default base value of
10647 +4 is not correct for your machine, define this macro to add some other
10648 +value to the result of that function.  The arguments to that function
10649 +are the same as to this macro.
10650 +*/
10651 +/*
10652 +  Memory moves are costly
10653 +*/
10654 +#define MEMORY_MOVE_COST(MODE, CLASS, IN)            \
10655 +  (((IN) ? ((GET_MODE_SIZE(MODE) < 4) ? 4 :          \
10656 +            (GET_MODE_SIZE(MODE) > 8) ? 6 :          \
10657 +            3)                                       \
10658 +    : ((GET_MODE_SIZE(MODE) > 8) ? 6 : 3)))
10659 +
10660 +/*
10661 +A C expression for the cost of a branch instruction.  A value of 1 is
10662 +the default; other values are interpreted relative to that.
10663 +*/
10664 +  /* Try to use conditionals as much as possible */
10665 +#define BRANCH_COST(speed_p, predictable_p) (TARGET_BRANCH_PRED ? 3 : 4)
10666 +
10667 +/*A C expression for the maximum number of instructions to execute via conditional
10668 +  execution instructions instead of a branch. A value of BRANCH_COST+1 is the default
10669 +  if the machine does not use cc0, and 1 if it does use cc0.*/
10670 +#define MAX_CONDITIONAL_EXECUTE 4
10671 +
10672 +/*
10673 +Define this macro as a C expression which is nonzero if accessing less
10674 +than a word of memory (i.e.: a char or a short) is no
10675 +faster than accessing a word of memory, i.e., if such access
10676 +require more than one instruction or if there is no difference in cost
10677 +between byte and (aligned) word loads.
10678 +
10679 +When this macro is not defined, the compiler will access a field by
10680 +finding the smallest containing object; when it is defined, a fullword
10681 +load will be used if alignment permits.  Unless bytes accesses are
10682 +faster than word accesses, using word accesses is preferable since it
10683 +may eliminate subsequent memory access if subsequent accesses occur to
10684 +other fields in the same word of the structure, but to different bytes.
10685 +*/
10686 +#define SLOW_BYTE_ACCESS 1
10687 +
10688 +
10689 +/*
10690 +Define this macro if it is as good or better to call a constant
10691 +function address than to call an address kept in a register.
10692 +*/
10693 +#define NO_FUNCTION_CSE
10694 +
10695 +
10696 +/******************************************************************************
10697 + * Adjusting the Instruction Scheduler
10698 + *****************************************************************************/
10699 +
10700 +/*****************************************************************************
10701 + * Dividing the Output into Sections (Texts, Data, ...)                      *
10702 + *****************************************************************************/
10703 +
10704 +/*
10705 +A C expression whose value is a string, including spacing, containing the
10706 +assembler operation that should precede instructions and read-only data.
10707 +Normally "\t.text" is right.
10708 +*/
10709 +#define TEXT_SECTION_ASM_OP "\t.text"
10710 +/*
10711 +A C statement that switches to the default section containing instructions.
10712 +Normally this is not needed, as simply defining TEXT_SECTION_ASM_OP
10713 +is enough.  The MIPS port uses this to sort all functions after all data
10714 +declarations.
10715 +*/
10716 +/* #define TEXT_SECTION */
10717 +
10718 +/*
10719 +A C expression whose value is a string, including spacing, containing the
10720 +assembler operation to identify the following data as writable initialized
10721 +data.  Normally "\t.data" is right.
10722 +*/
10723 +#define DATA_SECTION_ASM_OP "\t.data"
10724 +
10725 +/*
10726 +If defined, a C expression whose value is a string, including spacing,
10727 +containing the assembler operation to identify the following data as
10728 +shared data.  If not defined, DATA_SECTION_ASM_OP will be used.
10729 +*/
10730 +
10731 +/*
10732 +A C expression whose value is a string, including spacing, containing
10733 +the assembler operation to identify the following data as read-only
10734 +initialized data.
10735 +*/
10736 +#undef READONLY_DATA_SECTION_ASM_OP
10737 +#define READONLY_DATA_SECTION_ASM_OP \
10738 +  ((TARGET_USE_RODATA_SECTION) ?  \
10739 +   "\t.section\t.rodata" :                \
10740 +   TEXT_SECTION_ASM_OP )
10741 +
10742 +
10743 +/*
10744 +If defined, a C expression whose value is a string, including spacing,
10745 +containing the assembler operation to identify the following data as
10746 +uninitialized global data.  If not defined, and neither
10747 +ASM_OUTPUT_BSS nor ASM_OUTPUT_ALIGNED_BSS are defined,
10748 +uninitialized global data will be output in the data section if
10749 +-fno-common is passed, otherwise ASM_OUTPUT_COMMON will be
10750 +used.
10751 +*/
10752 +#define BSS_SECTION_ASM_OP     "\t.section\t.bss"
10753 +
10754 +/*
10755 +If defined, a C expression whose value is a string, including spacing,
10756 +containing the assembler operation to identify the following data as
10757 +uninitialized global shared data.  If not defined, and
10758 +BSS_SECTION_ASM_OP is, the latter will be used.
10759 +*/
10760 +/*#define SHARED_BSS_SECTION_ASM_OP "\trseg\tshared_bbs_section:data:noroot(0)\n"*/
10761 +/*
10762 +If defined, a C expression whose value is a string, including spacing,
10763 +containing the assembler operation to identify the following data as
10764 +initialization code.  If not defined, GCC will assume such a section does
10765 +not exist.
10766 +*/
10767 +#undef  INIT_SECTION_ASM_OP
10768 +#define INIT_SECTION_ASM_OP "\t.section\t.init"
10769 +
10770 +/*
10771 +If defined, a C expression whose value is a string, including spacing,
10772 +containing the assembler operation to identify the following data as
10773 +finalization code.  If not defined, GCC will assume such a section does
10774 +not exist.
10775 +*/
10776 +#undef  FINI_SECTION_ASM_OP
10777 +#define FINI_SECTION_ASM_OP "\t.section\t.fini"
10778 +
10779 +/*
10780 +If defined, an ASM statement that switches to a different section
10781 +via SECTION_OP, calls FUNCTION, and switches back to
10782 +the text section.  This is used in crtstuff.c if
10783 +INIT_SECTION_ASM_OP or FINI_SECTION_ASM_OP to calls
10784 +to initialization and finalization functions from the init and fini
10785 +sections.  By default, this macro uses a simple function call.  Some
10786 +ports need hand-crafted assembly code to avoid dependencies on
10787 +registers initialized in the function prologue or to ensure that
10788 +constant pools don't end up too far way in the text section.
10789 +*/
10790 +#define CRT_CALL_STATIC_FUNCTION(SECTION_OP, FUNC)      \
10791 +   asm ( SECTION_OP "\n" \
10792 +         "mcall   r6[" USER_LABEL_PREFIX #FUNC "@got]\n" \
10793 +         TEXT_SECTION_ASM_OP);
10794 +
10795 +
10796 +/*
10797 +Define this macro to be an expression with a nonzero value if jump
10798 +tables (for tablejump insns) should be output in the text
10799 +section, along with the assembler instructions.  Otherwise, the
10800 +readonly data section is used.
10801 +
10802 +This macro is irrelevant if there is no separate readonly data section.
10803 +*/
10804 +/* Put jump tables in text section if we have caches. Otherwise assume that
10805 +   loading data from code memory is slow. */
10806 +#define JUMP_TABLES_IN_TEXT_SECTION    \
10807 +    (TARGET_CACHES ? 1 : 0)
10808 +
10809 +
10810 +/******************************************************************************
10811 + * Position Independent Code (PIC)
10812 + *****************************************************************************/
10813 +
10814 +#ifndef AVR32_ALWAYS_PIC
10815 +#define AVR32_ALWAYS_PIC 0
10816 +#endif
10817 +
10818 +/* GOT is set to r6 */
10819 +#define PIC_OFFSET_TABLE_REGNUM INTERNAL_REGNUM(6)
10820 +
10821 +/*
10822 +A C expression that is nonzero if X is a legitimate immediate
10823 +operand on the target machine when generating position independent code.
10824 +You can assume that X satisfies CONSTANT_P, so you need not
10825 +check this.  You can also assume flag_pic is true, so you need not
10826 +check it either.  You need not define this macro if all constants
10827 +(including SYMBOL_REF) can be immediate operands when generating
10828 +position independent code.
10829 +*/
10830 +/* We can't directly access anything that contains a symbol,
10831 +   nor can we indirect via the constant pool.  */
10832 +#define LEGITIMATE_PIC_OPERAND_P(X) avr32_legitimate_pic_operand_p(X)
10833 +
10834 +
10835 +/* We need to know when we are making a constant pool; this determines
10836 +   whether data needs to be in the GOT or can be referenced via a GOT
10837 +   offset.  */
10838 +extern int making_const_table;
10839 +
10840 +/******************************************************************************
10841 + * Defining the Output Assembler Language
10842 + *****************************************************************************/
10843 +
10844 +
10845 +/*
10846 +A C string constant describing how to begin a comment in the target
10847 +assembler language.  The compiler assumes that the comment will end at
10848 +the end of the line.
10849 +*/
10850 +#define ASM_COMMENT_START "# "
10851 +
10852 +/*
10853 +A C string constant for text to be output before each asm
10854 +statement or group of consecutive ones.  Normally this is
10855 +"#APP", which is a comment that has no effect on most
10856 +assemblers but tells the GNU assembler that it must check the lines
10857 +that follow for all valid assembler constructs.
10858 +*/
10859 +#undef ASM_APP_ON
10860 +#define ASM_APP_ON "#APP\n"
10861 +
10862 +/*
10863 +A C string constant for text to be output after each asm
10864 +statement or group of consecutive ones.  Normally this is
10865 +"#NO_APP", which tells the GNU assembler to resume making the
10866 +time-saving assumptions that are valid for ordinary compiler output.
10867 +*/
10868 +#undef ASM_APP_OFF
10869 +#define ASM_APP_OFF "#NO_APP\n"
10870 +
10871 +
10872 +
10873 +#define FILE_ASM_OP            "\t.file\n"
10874 +#define IDENT_ASM_OP           "\t.ident\t"
10875 +#define SET_ASM_OP             "\t.set\t"
10876 +
10877 +
10878 +/*
10879 + * Output assembly directives to switch to section name. The section
10880 + * should have attributes as specified by flags, which is a bit mask
10881 + * of the SECTION_* flags defined in 'output.h'. If align is nonzero,
10882 + * it contains an alignment in bytes to be used for the section,
10883 + * otherwise some target default should be used. Only targets that
10884 + * must specify an alignment within the section directive need pay
10885 + * attention to align -- we will still use ASM_OUTPUT_ALIGN.
10886 + *
10887 + * NOTE: This one must not be moved to avr32.c
10888 + */
10889 +#undef TARGET_ASM_NAMED_SECTION
10890 +#define TARGET_ASM_NAMED_SECTION default_elf_asm_named_section
10891 +
10892 +
10893 +/*
10894 +You may define this macro as a C expression.  You should define the
10895 +expression to have a nonzero value if GCC should output the constant
10896 +pool for a function before the code for the function, or a zero value if
10897 +GCC should output the constant pool after the function.  If you do
10898 +not define this macro, the usual case, GCC will output the constant
10899 +pool before the function.
10900 +*/
10901 +#define CONSTANT_POOL_BEFORE_FUNCTION 0
10902 +
10903 +
10904 +/*
10905 +Define this macro as a C expression which is nonzero if the constant
10906 +EXP, of type tree, should be output after the code for a
10907 +function.  The compiler will normally output all constants before the
10908 +function; you need not define this macro if this is OK.
10909 +*/
10910 +#define CONSTANT_AFTER_FUNCTION_P(EXP) 1
10911 +
10912 +
10913 +/*
10914 +Define this macro as a C expression which is nonzero if C is
10915 +as a logical line separator by the assembler.  STR points to the
10916 +position in the string where C was found; this can be used if a
10917 +line separator uses multiple characters.
10918 +
10919 +If you do not define this macro, the default is that only
10920 +the character ';' is treated as a logical line separator.
10921 +*/
10922 +#define IS_ASM_LOGICAL_LINE_SEPARATOR(C,STR) (((C) == '\n') || ((C) == ';'))
10923 +
10924 +
10925 +/** Output of Uninitialized Variables **/
10926 +
10927 +/*
10928 +A C statement (sans semicolon) to output to the stdio stream
10929 +STREAM the assembler definition of a common-label named
10930 +NAME whose size is SIZE bytes.  The variable ROUNDED
10931 +is the size rounded up to whatever alignment the caller wants.
10932 +
10933 +Use the expression assemble_name(STREAM, NAME) to
10934 +output the name itself; before and after that, output the additional
10935 +assembler syntax for defining the name, and a newline.
10936 +
10937 +This macro controls how the assembler definitions of uninitialized
10938 +common global variables are output.
10939 +*/
10940 +/*
10941 +#define ASM_OUTPUT_COMMON(STREAM, NAME, SIZE, ROUNDED) \
10942 +  avr32_asm_output_common(STREAM, NAME, SIZE, ROUNDED)
10943 +*/
10944 +
10945 +#define ASM_OUTPUT_COMMON(FILE, NAME, SIZE, ROUNDED)   \
10946 +  do                                                   \
10947 +    {                                                  \
10948 +      fputs ("\t.comm ", (FILE));                      \
10949 +      assemble_name ((FILE), (NAME));                  \
10950 +      fprintf ((FILE), ",%d\n", (SIZE));               \
10951 +    }                                                  \
10952 +  while (0)
10953 +
10954 +/*
10955 + * Like ASM_OUTPUT_BSS except takes the required alignment as a
10956 + * separate, explicit argument.  If you define this macro, it is used
10957 + * in place of ASM_OUTPUT_BSS, and gives you more flexibility in
10958 + * handling the required alignment of the variable.  The alignment is
10959 + * specified as the number of bits.
10960 + *
10961 + * Try to use function asm_output_aligned_bss defined in file varasm.c
10962 + * when defining this macro.
10963 + */
10964 +#define ASM_OUTPUT_ALIGNED_BSS(STREAM, DECL, NAME, SIZE, ALIGNMENT) \
10965 +  asm_output_aligned_bss (STREAM, DECL, NAME, SIZE, ALIGNMENT)
10966 +
10967 +/*
10968 +A C statement (sans semicolon) to output to the stdio stream
10969 +STREAM the assembler definition of a local-common-label named
10970 +NAME whose size is SIZE bytes.  The variable ROUNDED
10971 +is the size rounded up to whatever alignment the caller wants.
10972 +
10973 +Use the expression assemble_name(STREAM, NAME) to
10974 +output the name itself; before and after that, output the additional
10975 +assembler syntax for defining the name, and a newline.
10976 +
10977 +This macro controls how the assembler definitions of uninitialized
10978 +static variables are output.
10979 +*/
10980 +#define ASM_OUTPUT_LOCAL(FILE, NAME, SIZE, ROUNDED)    \
10981 +  do                                                   \
10982 +    {                                                  \
10983 +      fputs ("\t.lcomm ", (FILE));                     \
10984 +      assemble_name ((FILE), (NAME));                  \
10985 +      fprintf ((FILE), ",%d, %d\n", (SIZE), 2);                \
10986 +    }                                                  \
10987 +  while (0)
10988 +
10989 +
10990 +/*
10991 +A C statement (sans semicolon) to output to the stdio stream
10992 +STREAM the assembler definition of a label named NAME.
10993 +Use the expression assemble_name(STREAM, NAME) to
10994 +output the name itself; before and after that, output the additional
10995 +assembler syntax for defining the name, and a newline.
10996 +*/
10997 +#define ASM_OUTPUT_LABEL(STREAM, NAME) avr32_asm_output_label(STREAM, NAME)
10998 +
10999 +/* A C string containing the appropriate assembler directive to
11000 + * specify the size of a symbol, without any arguments. On systems
11001 + * that use ELF, the default (in 'config/elfos.h') is '"\t.size\t"';
11002 + * on other systems, the default is not to define this macro.
11003 + *
11004 + * Define this macro only if it is correct to use the default
11005 + * definitions of ASM_ OUTPUT_SIZE_DIRECTIVE and
11006 + * ASM_OUTPUT_MEASURED_SIZE for your system. If you need your own
11007 + * custom definitions of those macros, or if you do not need explicit
11008 + * symbol sizes at all, do not define this macro.
11009 + */
11010 +#define SIZE_ASM_OP "\t.size\t"
11011 +
11012 +
11013 +/*
11014 +A C statement (sans semicolon) to output to the stdio stream
11015 +STREAM some commands that will make the label NAME global;
11016 +that is, available for reference from other files.  Use the expression
11017 +assemble_name(STREAM, NAME) to output the name
11018 +itself; before and after that, output the additional assembler syntax
11019 +for making that name global, and a newline.
11020 +*/
11021 +#define GLOBAL_ASM_OP "\t.global\t"
11022 +
11023 +
11024 +
11025 +/*
11026 +A C expression which evaluates to true if the target supports weak symbols.
11027 +
11028 +If you don't define this macro, defaults.h provides a default
11029 +definition.  If either ASM_WEAKEN_LABEL or ASM_WEAKEN_DECL
11030 +is defined, the default definition is '1'; otherwise, it is
11031 +'0'.  Define this macro if you want to control weak symbol support
11032 +with a compiler flag such as -melf.
11033 +*/
11034 +#define SUPPORTS_WEAK 1
11035 +
11036 +/*
11037 +A C statement (sans semicolon) to output to the stdio stream
11038 +STREAM a reference in assembler syntax to a label named
11039 +NAME.  This should add '_' to the front of the name, if that
11040 +is customary on your operating system, as it is in most Berkeley Unix
11041 +systems.  This macro is used in assemble_name.
11042 +*/
11043 +#define ASM_OUTPUT_LABELREF(STREAM, NAME) \
11044 +  avr32_asm_output_labelref(STREAM, NAME)
11045 +
11046 +
11047 +
11048 +/*
11049 +A C expression to assign to OUTVAR (which is a variable of type
11050 +char *) a newly allocated string made from the string
11051 +NAME and the number NUMBER, with some suitable punctuation
11052 +added.  Use alloca to get space for the string.
11053 +
11054 +The string will be used as an argument to ASM_OUTPUT_LABELREF to
11055 +produce an assembler label for an internal static variable whose name is
11056 +NAME.  Therefore, the string must be such as to result in valid
11057 +assembler code.  The argument NUMBER is different each time this
11058 +macro is executed; it prevents conflicts between similarly-named
11059 +internal static variables in different scopes.
11060 +
11061 +Ideally this string should not be a valid C identifier, to prevent any
11062 +conflict with the user's own symbols.  Most assemblers allow periods
11063 +or percent signs in assembler symbols; putting at least one of these
11064 +between the name and the number will suffice.
11065 +*/
11066 +#define ASM_FORMAT_PRIVATE_NAME(OUTVAR, NAME, NUMBER)          \
11067 +  do                                                           \
11068 +    {                                                          \
11069 +      (OUTVAR) = (char *) alloca (strlen ((NAME)) + 10);       \
11070 +      sprintf ((OUTVAR), "%s.%d", (NAME), (NUMBER));           \
11071 +    }                                                          \
11072 +  while (0)
11073 +
11074 +
11075 +/** Macros Controlling Initialization Routines **/
11076 +
11077 +
11078 +/*
11079 +If defined, main will not call __main as described above.
11080 +This macro should be defined for systems that control start-up code
11081 +on a symbol-by-symbol basis, such as OSF/1, and should not
11082 +be defined explicitly for systems that support INIT_SECTION_ASM_OP.
11083 +*/
11084 +/*
11085 +  __main is not defined when debugging.
11086 +*/
11087 +#define HAS_INIT_SECTION
11088 +
11089 +
11090 +/** Output of Assembler Instructions **/
11091 +
11092 +/*
11093 +A C initializer containing the assembler's names for the machine
11094 +registers, each one as a C string constant.  This is what translates
11095 +register numbers in the compiler into assembler language.
11096 +*/
11097 +
11098 +#define REGISTER_NAMES \
11099 +{                      \
11100 +  "pc",  "lr",         \
11101 +  "sp",  "r12",                \
11102 +  "r11", "r10",                \
11103 +  "r9",  "r8",         \
11104 +  "r7",  "r6",         \
11105 +  "r5",  "r4",         \
11106 +  "r3",  "r2",         \
11107 +  "r1",  "r0",         \
11108 +}
11109 +
11110 +/*
11111 +A C compound statement to output to stdio stream STREAM the
11112 +assembler syntax for an instruction operand X.  X is an
11113 +RTL expression.
11114 +
11115 +CODE is a value that can be used to specify one of several ways
11116 +of printing the operand.  It is used when identical operands must be
11117 +printed differently depending on the context.  CODE comes from
11118 +the '%' specification that was used to request printing of the
11119 +operand.  If the specification was just '%digit' then
11120 +CODE is 0; if the specification was '%ltr digit'
11121 +then CODE is the ASCII code for ltr.
11122 +
11123 +If X is a register, this macro should print the register's name.
11124 +The names can be found in an array reg_names whose type is
11125 +char *[].  reg_names is initialized from REGISTER_NAMES.
11126 +
11127 +When the machine description has a specification '%punct'
11128 +(a '%' followed by a punctuation character), this macro is called
11129 +with a null pointer for X and the punctuation character for
11130 +CODE.
11131 +*/
11132 +#define PRINT_OPERAND(STREAM, X, CODE) avr32_print_operand(STREAM, X, CODE)
11133 +
11134 +/* A C statement to be executed just prior to the output of
11135 +   assembler code for INSN, to modify the extracted operands so
11136 +   they will be output differently.
11137 +
11138 +   Here the argument OPVEC is the vector containing the operands
11139 +   extracted from INSN, and NOPERANDS is the number of elements of
11140 +   the vector which contain meaningful data for this insn.
11141 +   The contents of this vector are what will be used to convert the insn
11142 +   template into assembler code, so you can change the assembler output
11143 +   by changing the contents of the vector.  */
11144 +#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
11145 +  avr32_final_prescan_insn ((INSN), (OPVEC), (NOPERANDS))
11146 +
11147 +/*
11148 +A C expression which evaluates to true if CODE is a valid
11149 +punctuation character for use in the PRINT_OPERAND macro.  If
11150 +PRINT_OPERAND_PUNCT_VALID_P is not defined, it means that no
11151 +punctuation characters (except for the standard one, '%') are used
11152 +in this way.
11153 +*/
11154 +#define PRINT_OPERAND_PUNCT_VALID_P(CODE)                          \
11155 +  (((CODE) == '?')                                                 \
11156 +   || ((CODE) == '!'))
11157 +
11158 +/*
11159 +A C compound statement to output to stdio stream STREAM the
11160 +assembler syntax for an instruction operand that is a memory reference
11161 +whose address is X.  X is an RTL expression.
11162 +
11163 +On some machines, the syntax for a symbolic address depends on the
11164 +section that the address refers to.  On these machines, define the macro
11165 +ENCODE_SECTION_INFO to store the information into the
11166 +symbol_ref, and then check for it here.  (see Assembler Format.)
11167 +*/
11168 +#define PRINT_OPERAND_ADDRESS(STREAM, X) avr32_print_operand_address(STREAM, X)
11169 +
11170 +
11171 +/** Output of Dispatch Tables **/
11172 +
11173 +/*
11174 + * A C statement to output to the stdio stream stream an assembler
11175 + * pseudo-instruction to generate a difference between two
11176 + * labels. value and rel are the numbers of two internal labels. The
11177 + * definitions of these labels are output using
11178 + * (*targetm.asm_out.internal_label), and they must be printed in the
11179 + * same way here. For example,
11180 + *
11181 + *         fprintf (stream, "\t.word L%d-L%d\n",
11182 + *                  value, rel)
11183 + *
11184 + * You must provide this macro on machines where the addresses in a
11185 + * dispatch table are relative to the table's own address. If defined,
11186 + * GCC will also use this macro on all machines when producing
11187 + * PIC. body is the body of the ADDR_DIFF_VEC; it is provided so that
11188 + * the mode and flags can be read.
11189 + */
11190 +#define ASM_OUTPUT_ADDR_DIFF_ELT(STREAM, BODY, VALUE, REL)         \
11191 +    fprintf(STREAM, "\tbral\t%sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
11192 +
11193 +/*
11194 +This macro should be provided on machines where the addresses
11195 +in a dispatch table are absolute.
11196 +
11197 +The definition should be a C statement to output to the stdio stream
11198 +STREAM an assembler pseudo-instruction to generate a reference to
11199 +a label.  VALUE is the number of an internal label whose
11200 +definition is output using ASM_OUTPUT_INTERNAL_LABEL.
11201 +For example,
11202 +
11203 +fprintf(STREAM, "\t.word L%d\n", VALUE)
11204 +*/
11205 +
11206 +#define ASM_OUTPUT_ADDR_VEC_ELT(STREAM, VALUE)  \
11207 +  fprintf(STREAM, "\t.long %sL%d\n", LOCAL_LABEL_PREFIX, VALUE)
11208 +
11209 +/** Assembler Commands for Exception Regions */
11210 +
11211 +/* ToDo: All of this subsection */
11212 +
11213 +/** Assembler Commands for Alignment */
11214 +
11215 +
11216 +/*
11217 +A C statement to output to the stdio stream STREAM an assembler
11218 +command to advance the location counter to a multiple of 2 to the
11219 +POWER bytes.  POWER will be a C expression of type int.
11220 +*/
11221 +#define ASM_OUTPUT_ALIGN(STREAM, POWER)                        \
11222 +  do                                                   \
11223 +    {                                                  \
11224 +      if ((POWER) != 0)                                        \
11225 +       fprintf(STREAM, "\t.align\t%d\n", POWER);       \
11226 +    }                                                  \
11227 +  while (0)
11228 +
11229 +/*
11230 +Like ASM_OUTPUT_ALIGN, except that the \nop" instruction is used for padding, if
11231 +necessary.
11232 +*/
11233 +#define ASM_OUTPUT_ALIGN_WITH_NOP(STREAM, POWER) \
11234 + fprintf(STREAM, "\t.balignw\t%d, 0xd703\n", (1 << POWER))
11235 +
11236 +
11237 +
11238 +/******************************************************************************
11239 + * Controlling Debugging Information Format
11240 + *****************************************************************************/
11241 +
11242 +/* How to renumber registers for dbx and gdb.  */
11243 +#define DBX_REGISTER_NUMBER(REGNO) ASM_REGNUM (REGNO)
11244 +
11245 +/* The DWARF 2 CFA column which tracks the return address.  */
11246 +#define DWARF_FRAME_RETURN_COLUMN DWARF_FRAME_REGNUM(LR_REGNUM)
11247 +
11248 +/*
11249 +Define this macro if GCC should produce dwarf version 2 format
11250 +debugging output in response to the -g option.
11251 +
11252 +To support optional call frame debugging information, you must also
11253 +define INCOMING_RETURN_ADDR_RTX and either set
11254 +RTX_FRAME_RELATED_P on the prologue insns if you use RTL for the
11255 +prologue, or call dwarf2out_def_cfa and dwarf2out_reg_save
11256 +as appropriate from TARGET_ASM_FUNCTION_PROLOGUE if you don't.
11257 +*/
11258 +#define DWARF2_DEBUGGING_INFO 1
11259 +
11260 +
11261 +#define DWARF2_ASM_LINE_DEBUG_INFO 1
11262 +#define DWARF2_FRAME_INFO 1
11263 +
11264 +
11265 +/******************************************************************************
11266 + * Miscellaneous Parameters
11267 + *****************************************************************************/
11268 +
11269 +/* ToDo: a lot */
11270 +
11271 +/*
11272 +An alias for a machine mode name.  This is the machine mode that
11273 +elements of a jump-table should have.
11274 +*/
11275 +#define CASE_VECTOR_MODE SImode
11276 +
11277 +/*
11278 +Define this macro to be a C expression to indicate when jump-tables
11279 +should contain relative addresses.  If jump-tables never contain
11280 +relative addresses, then you need not define this macro.
11281 +*/
11282 +#define CASE_VECTOR_PC_RELATIVE 0
11283 +
11284 +/* Increase the threshold for using table jumps on the UC arch. */
11285 +#define CASE_VALUES_THRESHOLD  (TARGET_BRANCH_PRED ? 4 : 7)
11286 +
11287 +/*
11288 +The maximum number of bytes that a single instruction can move quickly
11289 +between memory and registers or between two memory locations.
11290 +*/
11291 +#define MOVE_MAX (2*UNITS_PER_WORD)
11292 +
11293 +
11294 +/* A C expression that is nonzero if on this machine the number of bits actually used
11295 +   for the count of a shift operation is equal to the number of bits needed to represent
11296 +   the size of the object being shifted. When this macro is nonzero, the compiler will
11297 +   assume that it is safe to omit a sign-extend, zero-extend, and certain bitwise 'and'
11298 +   instructions that truncates the count of a shift operation. On machines that have
11299 +   instructions that act on bit-fields at variable positions, which may include 'bit test'
11300 +   378 GNU Compiler Collection (GCC) Internals
11301 +   instructions, a nonzero SHIFT_COUNT_TRUNCATED also enables deletion of truncations
11302 +   of the values that serve as arguments to bit-field instructions.
11303 +   If both types of instructions truncate the count (for shifts) and position (for bit-field
11304 +   operations), or if no variable-position bit-field instructions exist, you should define
11305 +   this macro.
11306 +   However, on some machines, such as the 80386 and the 680x0, truncation only applies
11307 +   to shift operations and not the (real or pretended) bit-field operations. Define SHIFT_
11308 +   COUNT_TRUNCATED to be zero on such machines. Instead, add patterns to the 'md' file
11309 +   that include the implied truncation of the shift instructions.
11310 +   You need not de\fne this macro if it would always have the value of zero. */
11311 +#define SHIFT_COUNT_TRUNCATED 1
11312 +
11313 +/*
11314 +A C expression which is nonzero if on this machine it is safe to
11315 +convert an integer of INPREC bits to one of OUTPREC
11316 +bits (where OUTPREC is smaller than INPREC) by merely
11317 +operating on it as if it had only OUTPREC bits.
11318 +
11319 +On many machines, this expression can be 1.
11320 +
11321 +When TRULY_NOOP_TRUNCATION returns 1 for a pair of sizes for
11322 +modes for which MODES_TIEABLE_P is 0, suboptimal code can result.
11323 +If this is the case, making TRULY_NOOP_TRUNCATION return 0 in
11324 +such cases may improve things.
11325 +*/
11326 +#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
11327 +
11328 +/*
11329 +An alias for the machine mode for pointers.  On most machines, define
11330 +this to be the integer mode corresponding to the width of a hardware
11331 +pointer; SImode on 32-bit machine or DImode on 64-bit machines.
11332 +On some machines you must define this to be one of the partial integer
11333 +modes, such as PSImode.
11334 +
11335 +The width of Pmode must be at least as large as the value of
11336 +POINTER_SIZE.  If it is not equal, you must define the macro
11337 +POINTERS_EXTEND_UNSIGNED to specify how pointers are extended
11338 +to Pmode.
11339 +*/
11340 +#define Pmode SImode
11341 +
11342 +/*
11343 +An alias for the machine mode used for memory references to functions
11344 +being called, in call RTL expressions.  On most machines this
11345 +should be QImode.
11346 +*/
11347 +#define FUNCTION_MODE SImode
11348 +
11349 +
11350 +#define REG_S_P(x) \
11351 + (REG_P (x) || (GET_CODE (x) == SUBREG && REG_P (XEXP (x, 0))))
11352 +
11353 +
11354 +/* If defined, modifies the length assigned to instruction INSN as a
11355 +   function of the context in which it is used.  LENGTH is an lvalue
11356 +   that contains the initially computed length of the insn and should
11357 +   be updated with the correct length of the insn.  */
11358 +#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
11359 +  ((LENGTH) = avr32_adjust_insn_length ((INSN), (LENGTH)))
11360 +
11361 +
11362 +#define CLZ_DEFINED_VALUE_AT_ZERO(mode, value) \
11363 +  (value = 32, (mode == SImode))
11364 +
11365 +#define CTZ_DEFINED_VALUE_AT_ZERO(mode, value) \
11366 +  (value = 32, (mode == SImode))
11367 +
11368 +#define UNITS_PER_SIMD_WORD(mode) UNITS_PER_WORD
11369 +
11370 +#define STORE_FLAG_VALUE 1
11371 +
11372 +
11373 +/* IF-conversion macros. */
11374 +#define IFCVT_MODIFY_INSN( CE_INFO, PATTERN, INSN )                     \
11375 +  {                                                                     \
11376 +    (PATTERN) = avr32_ifcvt_modify_insn (CE_INFO, PATTERN, INSN, &num_true_changes); \
11377 +  }
11378 +
11379 +#define IFCVT_EXTRA_FIELDS                              \
11380 +  int num_cond_clobber_insns;                           \
11381 +  int num_extra_move_insns;                             \
11382 +  rtx extra_move_insns[MAX_CONDITIONAL_EXECUTE];        \
11383 +  rtx moved_insns[MAX_CONDITIONAL_EXECUTE];
11384 +
11385 +#define IFCVT_INIT_EXTRA_FIELDS( CE_INFO )       \
11386 +  {                                              \
11387 +    (CE_INFO)->num_cond_clobber_insns = 0;       \
11388 +    (CE_INFO)->num_extra_move_insns = 0;         \
11389 +  }
11390 +
11391 +
11392 +#define IFCVT_MODIFY_CANCEL( CE_INFO )  avr32_ifcvt_modify_cancel (CE_INFO, &num_true_changes)
11393 +
11394 +#define IFCVT_ALLOW_MODIFY_TEST_IN_INSN 1
11395 +#define IFCVT_COND_EXEC_BEFORE_RELOAD (TARGET_COND_EXEC_BEFORE_RELOAD)
11396 +
11397 +enum avr32_builtins
11398 +{
11399 +  AVR32_BUILTIN_MTSR,
11400 +  AVR32_BUILTIN_MFSR,
11401 +  AVR32_BUILTIN_MTDR,
11402 +  AVR32_BUILTIN_MFDR,
11403 +  AVR32_BUILTIN_CACHE,
11404 +  AVR32_BUILTIN_SYNC,
11405 +  AVR32_BUILTIN_SSRF,
11406 +  AVR32_BUILTIN_CSRF,
11407 +  AVR32_BUILTIN_TLBR,
11408 +  AVR32_BUILTIN_TLBS,
11409 +  AVR32_BUILTIN_TLBW,
11410 +  AVR32_BUILTIN_BREAKPOINT,
11411 +  AVR32_BUILTIN_XCHG,
11412 +  AVR32_BUILTIN_LDXI,
11413 +  AVR32_BUILTIN_BSWAP16,
11414 +  AVR32_BUILTIN_BSWAP32,
11415 +  AVR32_BUILTIN_COP,
11416 +  AVR32_BUILTIN_MVCR_W,
11417 +  AVR32_BUILTIN_MVRC_W,
11418 +  AVR32_BUILTIN_MVCR_D,
11419 +  AVR32_BUILTIN_MVRC_D,
11420 +  AVR32_BUILTIN_MULSATHH_H,
11421 +  AVR32_BUILTIN_MULSATHH_W,
11422 +  AVR32_BUILTIN_MULSATRNDHH_H,
11423 +  AVR32_BUILTIN_MULSATRNDWH_W,
11424 +  AVR32_BUILTIN_MULSATWH_W,
11425 +  AVR32_BUILTIN_MACSATHH_W,
11426 +  AVR32_BUILTIN_SATADD_H,
11427 +  AVR32_BUILTIN_SATSUB_H,
11428 +  AVR32_BUILTIN_SATADD_W,
11429 +  AVR32_BUILTIN_SATSUB_W,
11430 +  AVR32_BUILTIN_MULWH_D,
11431 +  AVR32_BUILTIN_MULNWH_D,
11432 +  AVR32_BUILTIN_MACWH_D,
11433 +  AVR32_BUILTIN_MACHH_D,
11434 +  AVR32_BUILTIN_MUSFR,
11435 +  AVR32_BUILTIN_MUSTR,
11436 +  AVR32_BUILTIN_SATS,
11437 +  AVR32_BUILTIN_SATU,
11438 +  AVR32_BUILTIN_SATRNDS,
11439 +  AVR32_BUILTIN_SATRNDU,
11440 +  AVR32_BUILTIN_MEMS,
11441 +  AVR32_BUILTIN_MEMC,
11442 +  AVR32_BUILTIN_MEMT,
11443 +  AVR32_BUILTIN_SLEEP,
11444 +  AVR32_BUILTIN_DELAY_CYCLES
11445 +};
11446 +
11447 +
11448 +#define FLOAT_LIB_COMPARE_RETURNS_BOOL(MODE, COMPARISON) \
11449 +  ((MODE == SFmode) || (MODE == DFmode))
11450 +
11451 +#define RENAME_LIBRARY_SET ".set"
11452 +
11453 +/* Make ABI_NAME an alias for __GCC_NAME.  */
11454 +#define RENAME_LIBRARY(GCC_NAME, ABI_NAME)             \
11455 +  __asm__ (".globl\t__avr32_" #ABI_NAME "\n"           \
11456 +          ".set\t__avr32_" #ABI_NAME   \
11457 +            ", __" #GCC_NAME "\n");
11458 +
11459 +/* Give libgcc functions avr32 ABI name.  */
11460 +#ifdef L_muldi3
11461 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (muldi3, mul64)
11462 +#endif
11463 +#ifdef L_divdi3
11464 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (divdi3, sdiv64)
11465 +#endif
11466 +#ifdef L_udivdi3
11467 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (udivdi3, udiv64)
11468 +#endif
11469 +#ifdef L_moddi3
11470 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (moddi3, smod64)
11471 +#endif
11472 +#ifdef L_umoddi3
11473 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (umoddi3, umod64)
11474 +#endif
11475 +#ifdef L_ashldi3
11476 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashldi3, lsl64)
11477 +#endif
11478 +#ifdef L_lshrdi3
11479 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (lshrdi3, lsr64)
11480 +#endif
11481 +#ifdef L_ashrdi3
11482 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (ashrdi3, asr64)
11483 +#endif
11484 +
11485 +#ifdef L_fixsfdi
11486 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixsfdi, f32_to_s64)
11487 +#endif
11488 +#ifdef L_fixunssfdi
11489 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (fixunssfdi, f32_to_u64)
11490 +#endif
11491 +#ifdef L_floatdidf
11492 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdidf, s64_to_f64)
11493 +#endif
11494 +#ifdef L_floatdisf
11495 +#define DECLARE_LIBRARY_RENAMES RENAME_LIBRARY (floatdisf, s64_to_f32)
11496 +#endif
11497 +
11498 +#endif
11499 --- /dev/null
11500 +++ b/gcc/config/avr32/avr32.md
11501 @@ -0,0 +1,5198 @@
11502 +;;   AVR32 machine description file.
11503 +;;   Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation.
11504 +;;
11505 +;;   This file is part of GCC.
11506 +;;
11507 +;;   This program is free software; you can redistribute it and/or modify
11508 +;;   it under the terms of the GNU General Public License as published by
11509 +;;   the Free Software Foundation; either version 2 of the License, or
11510 +;;   (at your option) any later version.
11511 +;;
11512 +;;   This program is distributed in the hope that it will be useful,
11513 +;;   but WITHOUT ANY WARRANTY; without even the implied warranty of
11514 +;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11515 +;;   GNU General Public License for more details.
11516 +;;
11517 +;;   You should have received a copy of the GNU General Public License
11518 +;;   along with this program; if not, write to the Free Software
11519 +;;   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
11520 +
11521 +;; -*- Mode: Scheme -*-
11522 +
11523 +(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"
11524 +  (const_string "alu"))
11525 +
11526 +
11527 +(define_attr "cc" "none,set_vncz,set_ncz,set_cz,set_z,set_z_if_not_v2,bld,compare,cmp_cond_insn,clobber,call_set,fpcompare,from_fpcc"
11528 +  (const_string "none"))
11529 +
11530 +
11531 +; NB! Keep this in sync with enum architecture_type in avr32.h
11532 +(define_attr "pipeline" "ap,ucr1,ucr2,ucr2nomul,ucr3,ucr3fp"
11533 +  (const (symbol_ref "avr32_arch->arch_type")))
11534 +
11535 +; Insn length in bytes
11536 +(define_attr "length" ""
11537 +  (const_int 4))
11538 +
11539 +; Signal if an insn is predicable and hence can be conditionally executed.
11540 +(define_attr "predicable" "no,yes" (const_string "no"))
11541 +
11542 +;; Uses of UNSPEC in this file:
11543 +(define_constants
11544 +  [(UNSPEC_PUSHM                0)
11545 +   (UNSPEC_POPM                 1)
11546 +   (UNSPEC_UDIVMODSI4_INTERNAL 2)
11547 +   (UNSPEC_DIVMODSI4_INTERNAL   3)
11548 +   (UNSPEC_STM                  4)
11549 +   (UNSPEC_LDM                  5)
11550 +   (UNSPEC_MOVSICC              6)
11551 +   (UNSPEC_ADDSICC              7)
11552 +   (UNSPEC_COND_MI              8)
11553 +   (UNSPEC_COND_PL              9)
11554 +   (UNSPEC_PIC_SYM              10)
11555 +   (UNSPEC_PIC_BASE             11)
11556 +   (UNSPEC_STORE_MULTIPLE       12)
11557 +   (UNSPEC_STMFP                13)
11558 +   (UNSPEC_FRCPA                14)
11559 +   (UNSPEC_REG_TO_CC            15)
11560 +   (UNSPEC_FORCE_MINIPOOL       16)
11561 +   (UNSPEC_SATS                 17)
11562 +   (UNSPEC_SATU                 18)
11563 +   (UNSPEC_SATRNDS              19)
11564 +   (UNSPEC_SATRNDU              20)
11565 +  ])
11566 +
11567 +(define_constants
11568 +  [(VUNSPEC_EPILOGUE                  0)
11569 +   (VUNSPEC_CACHE                     1)
11570 +   (VUNSPEC_MTSR                      2)
11571 +   (VUNSPEC_MFSR                      3)
11572 +   (VUNSPEC_BLOCKAGE                  4)
11573 +   (VUNSPEC_SYNC                      5)
11574 +   (VUNSPEC_TLBR                      6)
11575 +   (VUNSPEC_TLBW                      7)
11576 +   (VUNSPEC_TLBS                      8)
11577 +   (VUNSPEC_BREAKPOINT                9)
11578 +   (VUNSPEC_MTDR                      10)
11579 +   (VUNSPEC_MFDR                      11)
11580 +   (VUNSPEC_MVCR                      12)
11581 +   (VUNSPEC_MVRC                      13)
11582 +   (VUNSPEC_COP                       14)
11583 +   (VUNSPEC_ALIGN                     15)
11584 +   (VUNSPEC_POOL_START                16)
11585 +   (VUNSPEC_POOL_END                  17)
11586 +   (VUNSPEC_POOL_4                    18)
11587 +   (VUNSPEC_POOL_8                    19)
11588 +   (VUNSPEC_POOL_16                   20)
11589 +   (VUNSPEC_MUSFR                     21)
11590 +   (VUNSPEC_MUSTR                     22)
11591 +   (VUNSPEC_SYNC_CMPXCHG              23)
11592 +   (VUNSPEC_SYNC_SET_LOCK_AND_LOAD    24)
11593 +   (VUNSPEC_SYNC_STORE_IF_LOCK        25)
11594 +   (VUNSPEC_EH_RETURN                 26)
11595 +   (VUNSPEC_FRS                       27)
11596 +   (VUNSPEC_CSRF                      28)
11597 +   (VUNSPEC_SSRF                      29)
11598 +   (VUNSPEC_SLEEP                     30)
11599 +   (VUNSPEC_DELAY_CYCLES              31)
11600 +   (VUNSPEC_DELAY_CYCLES_1            32)
11601 +   (VUNSPEC_DELAY_CYCLES_2            33)
11602 +   (VUNSPEC_NOP                       34)
11603 +   (VUNSPEC_NOP3                      35)
11604 +   ])
11605 +
11606 +(define_constants
11607 +  [
11608 +   ;; R7 = 15-7 = 8
11609 +   (FP_REGNUM   8)
11610 +   ;; Return Register = R12 = 15 - 12 = 3
11611 +   (RETVAL_REGNUM   3)
11612 +   ;; SP = R13 = 15 - 13 = 2
11613 +   (SP_REGNUM   2)
11614 +   ;; LR = R14 = 15 - 14 = 1
11615 +   (LR_REGNUM   1)
11616 +   ;; PC = R15 = 15 - 15 = 0
11617 +   (PC_REGNUM   0)
11618 +   ;; FPSR = GENERAL_REGS + 1 = 17
11619 +   (FPCC_REGNUM 17)
11620 +   ])
11621 +
11622 +
11623 +
11624 +
11625 +;;******************************************************************************
11626 +;; Macros
11627 +;;******************************************************************************
11628 +
11629 +;; Integer Modes for basic alu insns
11630 +(define_mode_iterator INTM [SI HI QI])
11631 +(define_mode_attr  alu_cc_attr [(SI "set_vncz") (HI "clobber") (QI "clobber")])
11632 +
11633 +;; Move word modes
11634 +(define_mode_iterator MOVM [SI V2HI V4QI])
11635 +
11636 +;; For mov/addcc insns
11637 +(define_mode_iterator ADDCC [SI HI QI])
11638 +(define_mode_iterator MOVCC [SF SI HI QI])
11639 +(define_mode_iterator CMP [DI SI HI QI])
11640 +(define_mode_attr  store_postfix [(SF ".w") (SI ".w") (HI ".h") (QI ".b")])
11641 +(define_mode_attr  load_postfix [(SF ".w") (SI ".w") (HI ".sh") (QI ".ub")])
11642 +(define_mode_attr  load_postfix_s [(SI ".w") (HI ".sh") (QI ".sb")])
11643 +(define_mode_attr  load_postfix_u [(SI ".w") (HI ".uh") (QI ".ub")])
11644 +(define_mode_attr  pred_mem_constraint [(SF "RKu11") (SI "RKu11") (HI "RKu10") (QI "RKu09")])
11645 +(define_mode_attr  cmp_constraint [(DI "rKu20") (SI "rKs21") (HI "r") (QI "r")])
11646 +(define_mode_attr  cmp_predicate [(DI "register_immediate_operand")
11647 +                                  (SI "register_const_int_operand")
11648 +                                  (HI "register_operand")
11649 +                                  (QI "register_operand")])
11650 +(define_mode_attr  cmp_length [(DI "6")
11651 +                               (SI "4")
11652 +                               (HI "4")
11653 +                               (QI "4")])
11654 +
11655 +;; For all conditional insns
11656 +(define_code_iterator any_cond_b [ge lt geu ltu])
11657 +(define_code_iterator any_cond [gt ge lt le gtu geu ltu leu])
11658 +(define_code_iterator any_cond4 [gt le gtu leu])
11659 +(define_code_attr cond [(eq "eq") (ne "ne") (gt "gt") (ge "ge") (lt "lt") (le "le")
11660 +                        (gtu "hi") (geu "hs") (ltu "lo") (leu "ls")])
11661 +(define_code_attr invcond [(eq "ne") (ne "eq") (gt "le") (ge "lt") (lt "ge") (le "gt")
11662 +                           (gtu "ls") (geu "lo") (ltu "hs") (leu "hi")])
11663 +
11664 +;; For logical operations
11665 +(define_code_iterator logical [and ior xor])
11666 +(define_code_attr logical_insn [(and "and") (ior "or") (xor "eor")])
11667 +
11668 +;; Predicable operations with three register operands 
11669 +(define_code_iterator predicable_op3 [and ior xor plus minus])
11670 +(define_code_attr predicable_insn3 [(and "and") (ior "or") (xor "eor") (plus "add") (minus "sub")])
11671 +(define_code_attr predicable_commutative3 [(and "%") (ior "%") (xor "%") (plus "%") (minus "")])
11672 +
11673 +;; Load the predicates
11674 +(include "predicates.md")
11675 +
11676 +
11677 +;;******************************************************************************
11678 +;; Automaton pipeline description for avr32
11679 +;;******************************************************************************
11680 +
11681 +(define_automaton "avr32_ap")
11682 +
11683 +
11684 +(define_cpu_unit "is" "avr32_ap")
11685 +(define_cpu_unit "a1,m1,da" "avr32_ap")
11686 +(define_cpu_unit "a2,m2,d" "avr32_ap")
11687 +
11688 +;;Alu instructions
11689 +(define_insn_reservation "alu_op" 1
11690 +  (and (eq_attr "pipeline" "ap")
11691 +       (eq_attr "type" "alu"))
11692 +  "is,a1,a2")
11693 +
11694 +(define_insn_reservation "alu2_op" 2
11695 +  (and (eq_attr "pipeline" "ap")
11696 +       (eq_attr "type" "alu2"))
11697 +  "is,is+a1,a1+a2,a2")
11698 +
11699 +(define_insn_reservation "alu_sat_op" 2
11700 +  (and (eq_attr "pipeline" "ap")
11701 +       (eq_attr "type" "alu_sat"))
11702 +  "is,a1,a2")
11703 +
11704 +
11705 +;;Mul instructions
11706 +(define_insn_reservation "mulhh_op" 2
11707 +  (and (eq_attr "pipeline" "ap")
11708 +       (eq_attr "type" "mulhh,mulwh"))
11709 +  "is,m1,m2")
11710 +
11711 +(define_insn_reservation "mulww_w_op" 3
11712 +  (and (eq_attr "pipeline" "ap")
11713 +       (eq_attr "type" "mulww_w"))
11714 +  "is,m1,m1+m2,m2")
11715 +
11716 +(define_insn_reservation "mulww_d_op" 5
11717 +  (and (eq_attr "pipeline" "ap")
11718 +       (eq_attr "type" "mulww_d"))
11719 +  "is,m1,m1+m2,m1+m2,m2,m2")
11720 +
11721 +(define_insn_reservation "div_op" 33
11722 +  (and (eq_attr "pipeline" "ap")
11723 +       (eq_attr "type" "div"))
11724 +  "is,m1,m1*31 + m2*31,m2")
11725 +
11726 +(define_insn_reservation "machh_w_op" 3
11727 +  (and (eq_attr "pipeline" "ap")
11728 +       (eq_attr "type" "machh_w"))
11729 +  "is*2,m1,m2")
11730 +
11731 +
11732 +(define_insn_reservation "macww_w_op" 4
11733 +  (and (eq_attr "pipeline" "ap")
11734 +       (eq_attr "type" "macww_w"))
11735 +  "is*2,m1,m1,m2")
11736 +
11737 +
11738 +(define_insn_reservation "macww_d_op" 6
11739 +  (and (eq_attr "pipeline" "ap")
11740 +       (eq_attr "type" "macww_d"))
11741 +  "is*2,m1,m1+m2,m1+m2,m2")
11742 +
11743 +;;Bypasses for Mac instructions, because of accumulator cache.
11744 +;;Set latency as low as possible in order to let the compiler let
11745 +;;mul -> mac and mac -> mac combinations which use the same
11746 +;;accumulator cache be placed close together to avoid any
11747 +;;instructions which can ruin the accumulator cache come inbetween.
11748 +(define_bypass 4 "machh_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11749 +(define_bypass 5 "macww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11750 +(define_bypass 7 "macww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11751 +
11752 +(define_bypass 3 "mulhh_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11753 +(define_bypass 4 "mulww_w_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11754 +(define_bypass 6 "mulww_d_op" "alu_op,alu2_op,alu_sat_op,load_op" "avr32_mul_waw_bypass")
11755 +
11756 +
11757 +;;Bypasses for all mul/mac instructions followed by an instruction
11758 +;;which reads the output AND writes the result to the same register.
11759 +;;This will generate an Write After Write hazard which gives an
11760 +;;extra cycle before the result is ready.
11761 +(define_bypass 0 "machh_w_op" "machh_w_op" "avr32_valid_macmac_bypass")
11762 +(define_bypass 0 "macww_w_op" "macww_w_op" "avr32_valid_macmac_bypass")
11763 +(define_bypass 0 "macww_d_op" "macww_d_op" "avr32_valid_macmac_bypass")
11764 +
11765 +(define_bypass 0 "mulhh_op" "machh_w_op" "avr32_valid_mulmac_bypass")
11766 +(define_bypass 0 "mulww_w_op" "macww_w_op" "avr32_valid_mulmac_bypass")
11767 +(define_bypass 0 "mulww_d_op" "macww_d_op" "avr32_valid_mulmac_bypass")
11768 +
11769 +;;Branch and call instructions
11770 +;;We assume that all branches and rcalls are predicted correctly :-)
11771 +;;while calls use a lot of cycles.
11772 +(define_insn_reservation "branch_op" 0
11773 +  (and (eq_attr "pipeline" "ap")
11774 +       (eq_attr "type" "branch"))
11775 +  "nothing")
11776 +
11777 +(define_insn_reservation "call_op" 10
11778 +  (and (eq_attr "pipeline" "ap")
11779 +       (eq_attr "type" "call"))
11780 +  "nothing")
11781 +
11782 +
11783 +;;Load store instructions
11784 +(define_insn_reservation "load_op" 2
11785 +  (and (eq_attr "pipeline" "ap")
11786 +       (eq_attr "type" "load"))
11787 +  "is,da,d")
11788 +
11789 +(define_insn_reservation "load_rm_op" 3
11790 +  (and (eq_attr "pipeline" "ap")
11791 +       (eq_attr "type" "load_rm"))
11792 +  "is,da,d")
11793 +
11794 +
11795 +(define_insn_reservation "store_op" 0
11796 +  (and (eq_attr "pipeline" "ap")
11797 +       (eq_attr "type" "store"))
11798 +  "is,da,d")
11799 +
11800 +
11801 +(define_insn_reservation "load_double_op" 3
11802 +  (and (eq_attr "pipeline" "ap")
11803 +       (eq_attr "type" "load2"))
11804 +  "is,da,da+d,d")
11805 +
11806 +(define_insn_reservation "load_quad_op" 4
11807 +  (and (eq_attr "pipeline" "ap")
11808 +       (eq_attr "type" "load4"))
11809 +  "is,da,da+d,da+d,d")
11810 +
11811 +(define_insn_reservation "store_double_op" 0
11812 +  (and (eq_attr "pipeline" "ap")
11813 +       (eq_attr "type" "store2"))
11814 +  "is,da,da+d,d")
11815 +
11816 +
11817 +(define_insn_reservation "store_quad_op" 0
11818 +  (and (eq_attr "pipeline" "ap")
11819 +       (eq_attr "type" "store4"))
11820 +  "is,da,da+d,da+d,d")
11821 +
11822 +;;For store the operand to write to memory is read in d and
11823 +;;the real latency between any instruction and a store is therefore
11824 +;;one less than for the instructions which reads the operands in the first
11825 +;;excecution stage
11826 +(define_bypass 2 "load_double_op" "store_double_op" "avr32_store_bypass")
11827 +(define_bypass 3 "load_quad_op" "store_quad_op" "avr32_store_bypass")
11828 +(define_bypass 1 "load_op" "store_op" "avr32_store_bypass")
11829 +(define_bypass 2 "load_rm_op" "store_op" "avr32_store_bypass")
11830 +(define_bypass 1 "alu_sat_op" "store_op" "avr32_store_bypass")
11831 +(define_bypass 1 "alu2_op" "store_op" "avr32_store_bypass")
11832 +(define_bypass 1 "mulhh_op" "store_op" "avr32_store_bypass")
11833 +(define_bypass 2 "mulww_w_op" "store_op" "avr32_store_bypass")
11834 +(define_bypass 4 "mulww_d_op" "store_op" "avr32_store_bypass" )
11835 +(define_bypass 2 "machh_w_op" "store_op" "avr32_store_bypass")
11836 +(define_bypass 3 "macww_w_op" "store_op" "avr32_store_bypass")
11837 +(define_bypass 5 "macww_d_op" "store_op" "avr32_store_bypass")
11838 +
11839 +
11840 +; Bypass for load double operation. If only the first loaded word is needed
11841 +; then the latency is 2
11842 +(define_bypass 2 "load_double_op"
11843 +                 "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op,
11844 +                  mulww_d_op, machh_w_op, macww_w_op, macww_d_op"
11845 +                 "avr32_valid_load_double_bypass")
11846 +
11847 +; Bypass for load quad operation. If only the first or second loaded word is needed
11848 +; we set the latency to 2
11849 +(define_bypass 2 "load_quad_op"
11850 +                 "load_op,load_rm_op,alu_sat_op, alu2_op, alu_op, mulhh_op, mulww_w_op,
11851 +                  mulww_d_op, machh_w_op, macww_w_op, macww_d_op"
11852 +                 "avr32_valid_load_quad_bypass")
11853 +
11854 +
11855 +;;******************************************************************************
11856 +;; End of Automaton pipeline description for avr32
11857 +;;******************************************************************************
11858 +
11859 +(define_cond_exec
11860 +  [(match_operator 0 "avr32_comparison_operator"
11861 +    [(match_operand:CMP 1 "register_operand" "r")         
11862 +     (match_operand:CMP 2 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>")])]
11863 +  "TARGET_V2_INSNS" 
11864 +  "%!"
11865 +)
11866 +
11867 +(define_cond_exec
11868 +  [(match_operator 0 "avr32_comparison_operator"
11869 +     [(and:SI (match_operand:SI 1 "register_operand" "r")         
11870 +              (match_operand:SI 2 "one_bit_set_operand" "i"))
11871 +      (const_int 0)])]
11872 +  "TARGET_V2_INSNS" 
11873 +  "%!"
11874 +  )
11875 +
11876 +;;=============================================================================
11877 +;; move
11878 +;;-----------------------------------------------------------------------------
11879 +
11880 +
11881 +;;== char - 8 bits ============================================================
11882 +(define_expand "movqi"
11883 +  [(set (match_operand:QI 0 "nonimmediate_operand" "")
11884 +       (match_operand:QI 1 "general_operand" ""))]
11885 +  ""
11886 +  {
11887 +   if ( can_create_pseudo_p () ){
11888 +     if (GET_CODE (operands[1]) == MEM && optimize){
11889 +         rtx reg = gen_reg_rtx (SImode);
11890 +
11891 +         emit_insn (gen_zero_extendqisi2 (reg, operands[1]));
11892 +         operands[1] = gen_lowpart (QImode, reg);
11893 +     }
11894 +
11895 +     /* One of the ops has to be in a register.  */
11896 +     if (GET_CODE (operands[0]) == MEM)
11897 +       operands[1] = force_reg (QImode, operands[1]);
11898 +   }
11899 +
11900 +  })
11901 +
11902 +(define_insn "*movqi_internal"
11903 +  [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r")
11904 +       (match_operand:QI 1 "general_operand"  "rKs08,m,r,i"))]
11905 +  "register_operand (operands[0], QImode)
11906 +   || register_operand (operands[1], QImode)"
11907 +  "@
11908 +   mov\t%0, %1
11909 +   ld.ub\t%0, %1
11910 +   st.b\t%0, %1
11911 +   mov\t%0, %1"
11912 +  [(set_attr "length" "2,4,4,4")
11913 +   (set_attr "type" "alu,load_rm,store,alu")])
11914 +
11915 +
11916 +
11917 +;;== short - 16 bits ==========================================================
11918 +(define_expand "movhi"
11919 +  [(set (match_operand:HI 0 "nonimmediate_operand" "")
11920 +       (match_operand:HI 1 "general_operand" ""))]
11921 +  ""
11922 +  {
11923 +   if ( can_create_pseudo_p () ){
11924 +     if (GET_CODE (operands[1]) == MEM && optimize){
11925 +         rtx reg = gen_reg_rtx (SImode);
11926 +
11927 +         emit_insn (gen_extendhisi2 (reg, operands[1]));
11928 +         operands[1] = gen_lowpart (HImode, reg);
11929 +     }
11930 +
11931 +     /* One of the ops has to be in a register.  */
11932 +     if (GET_CODE (operands[0]) == MEM)
11933 +       operands[1] = force_reg (HImode, operands[1]);
11934 +   }
11935 +
11936 +  })
11937 +
11938 +
11939 +(define_insn "*movhi_internal"
11940 +  [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
11941 +       (match_operand:HI 1 "general_operand"  "rKs08,m,r,i"))]
11942 +  "register_operand (operands[0], HImode)
11943 +   || register_operand (operands[1], HImode)"
11944 +  "@
11945 +   mov\t%0, %1
11946 +   ld.sh\t%0, %1
11947 +   st.h\t%0, %1
11948 +   mov\t%0, %1"
11949 +  [(set_attr "length" "2,4,4,4")
11950 +   (set_attr "type" "alu,load_rm,store,alu")])
11951 +
11952 +
11953 +;;== int - 32 bits ============================================================
11954 +
11955 +(define_expand "movmisalignsi"
11956 +  [(set (match_operand:SI 0 "nonimmediate_operand" "")
11957 +       (match_operand:SI 1 "nonimmediate_operand" ""))]
11958 +  "TARGET_UNALIGNED_WORD"
11959 +  {
11960 +  }
11961 +)
11962 +
11963 +(define_expand "mov<mode>"
11964 +  [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "")
11965 +       (match_operand:MOVM 1 "avr32_non_rmw_general_operand" ""))]
11966 +  ""
11967 +  {
11968 +
11969 +    /* One of the ops has to be in a register.  */
11970 +    if (GET_CODE (operands[0]) == MEM)
11971 +      operands[1] = force_reg (<MODE>mode, operands[1]);
11972 +
11973 +    /* Check for out of range immediate constants as these may
11974 +       occur during reloading, since it seems like reload does
11975 +       not check if the immediate is legitimate. Don't know if
11976 +       this is a bug? */
11977 +    if ( reload_in_progress
11978 +         && avr32_imm_in_const_pool
11979 +         && GET_CODE(operands[1]) == CONST_INT
11980 +         && !avr32_const_ok_for_constraint_p(INTVAL(operands[1]), 'K', "Ks21") ){
11981 +        operands[1] = force_const_mem(SImode, operands[1]);
11982 +    }
11983 +    /* Check for RMW memory operands. They are not allowed for mov operations
11984 +       only the atomic memc/s/t operations */
11985 +    if ( !reload_in_progress
11986 +         && avr32_rmw_memory_operand (operands[0], <MODE>mode) ){
11987 +       operands[0] = copy_rtx (operands[0]);                                                              
11988 +       XEXP(operands[0], 0) = force_reg (<MODE>mode, XEXP(operands[0], 0));
11989 +    }
11990 +
11991 +    if ( !reload_in_progress
11992 +         && avr32_rmw_memory_operand (operands[1], <MODE>mode) ){
11993 +       operands[1] = copy_rtx (operands[1]);                                                              
11994 +      XEXP(operands[1], 0) = force_reg (<MODE>mode, XEXP(operands[1], 0));
11995 +    }
11996 +    if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS)
11997 +         && !avr32_legitimate_pic_operand_p(operands[1]) )
11998 +      operands[1] = legitimize_pic_address (operands[1], <MODE>mode,
11999 +                                            (can_create_pseudo_p () ? 0: operands[0]));
12000 +    else if ( flag_pic && avr32_address_operand(operands[1], GET_MODE(operands[1])) )
12001 +      /* If we have an address operand then this function uses the pic register. */
12002 +      crtl->uses_pic_offset_table = 1;
12003 +  })
12004 +
12005 +
12006 +(define_insn "mov<mode>_internal"
12007 +  [(set (match_operand:MOVM 0 "avr32_non_rmw_nonimmediate_operand" "=r,   r,   r,r,r,Q,r")
12008 +       (match_operand:MOVM 1 "avr32_non_rmw_general_operand"      "rKs08,Ks21,J,n,Q,r,W"))]
12009 +  "(register_operand (operands[0], <MODE>mode)
12010 +    || register_operand (operands[1], <MODE>mode))
12011 +    && !avr32_rmw_memory_operand (operands[0], <MODE>mode) 
12012 +    && !avr32_rmw_memory_operand (operands[1], <MODE>mode)"
12013 +  {
12014 +    switch (which_alternative) {
12015 +      case 0:
12016 +      case 1: return "mov\t%0, %1";
12017 +      case 2:
12018 +        if ( TARGET_V2_INSNS )
12019 +           return "movh\t%0, hi(%1)";
12020 +        /* Fallthrough */
12021 +      case 3: return "mov\t%0, lo(%1)\;orh\t%0,hi(%1)";
12022 +      case 4:
12023 +        if ( (REG_P(XEXP(operands[1], 0))
12024 +              && REGNO(XEXP(operands[1], 0)) == SP_REGNUM)
12025 +             || (GET_CODE(XEXP(operands[1], 0)) == PLUS
12026 +                 && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM
12027 +                && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT
12028 +                && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0
12029 +                && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) )
12030 +          return "lddsp\t%0, %1";
12031 +       else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) )
12032 +          return "lddpc\t%0, %1";
12033 +        else
12034 +          return "ld.w\t%0, %1";
12035 +      case 5:
12036 +        if ( (REG_P(XEXP(operands[0], 0))
12037 +              && REGNO(XEXP(operands[0], 0)) == SP_REGNUM)
12038 +             || (GET_CODE(XEXP(operands[0], 0)) == PLUS
12039 +                 && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM
12040 +                && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT
12041 +                && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0
12042 +                && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) )
12043 +          return "stdsp\t%0, %1";
12044 +       else
12045 +          return "st.w\t%0, %1";
12046 +      case 6:
12047 +        if ( TARGET_HAS_ASM_ADDR_PSEUDOS )
12048 +          return "lda.w\t%0, %1";
12049 +        else
12050 +          return "ld.w\t%0, r6[%1@got]";
12051 +      default:
12052 +       abort();
12053 +    }
12054 +  }
12055 +  
12056 +  [(set_attr "length" "2,4,4,8,4,4,8")
12057 +   (set_attr "type" "alu,alu,alu,alu2,load,store,load")
12058 +   (set_attr "cc" "none,none,set_z_if_not_v2,set_z,none,none,clobber")])
12059 +
12060 +
12061 +(define_expand "reload_out_rmw_memory_operand"
12062 +  [(set (match_operand:SI 2 "register_operand" "=r")
12063 +        (match_operand:SI 0 "address_operand" ""))
12064 +   (set (mem:SI (match_dup 2))
12065 +        (match_operand:SI 1 "register_operand" ""))]
12066 +  ""
12067 +  {
12068 +   operands[0] = XEXP(operands[0], 0);
12069 +  }
12070 +)
12071 +
12072 +(define_expand "reload_in_rmw_memory_operand"
12073 +  [(set (match_operand:SI 2 "register_operand" "=r")
12074 +        (match_operand:SI 1 "address_operand" ""))
12075 +   (set (match_operand:SI 0 "register_operand" "")
12076 +        (mem:SI (match_dup 2)))]
12077 +  ""
12078 +  {
12079 +   operands[1] = XEXP(operands[1], 0);
12080 +  }
12081 +)
12082 +
12083 +
12084 +;; These instructions are for loading constants which cannot be loaded
12085 +;; directly from the constant pool because the offset is too large
12086 +;; high and lo_sum are used even tough for our case it should be
12087 +;; low and high sum :-)
12088 +(define_insn "mov_symbol_lo"
12089 +  [(set (match_operand:SI 0 "register_operand" "=r")
12090 +       (high:SI (match_operand:SI 1 "immediate_operand" "i" )))]
12091 +  ""
12092 +  "mov\t%0, lo(%1)"
12093 +  [(set_attr "type" "alu")
12094 +   (set_attr "length" "4")]
12095 +)
12096 +
12097 +(define_insn "add_symbol_hi"
12098 +  [(set (match_operand:SI 0 "register_operand" "=r")
12099 +       (lo_sum:SI (match_dup 0)
12100 +                   (match_operand:SI 1 "immediate_operand" "i" )))]
12101 +  ""
12102 +  "orh\t%0, hi(%1)"
12103 +  [(set_attr "type" "alu")
12104 +   (set_attr "length" "4")]
12105 +)
12106 +
12107 +
12108 +
12109 +;; When generating pic, we need to load the symbol offset into a register.
12110 +;; So that the optimizer does not confuse this with a normal symbol load
12111 +;; we use an unspec.  The offset will be loaded from a constant pool entry,
12112 +;; since that is the only type of relocation we can use.
12113 +(define_insn "pic_load_addr"
12114 +  [(set (match_operand:SI 0 "register_operand" "=r")
12115 +       (unspec:SI [(match_operand:SI 1 "" "")] UNSPEC_PIC_SYM))]
12116 +  "flag_pic && CONSTANT_POOL_ADDRESS_P(XEXP(operands[1], 0))"
12117 +  "lddpc\t%0, %1"
12118 +  [(set_attr "type" "load")
12119 +   (set_attr "length" "4")]
12120 +)
12121 +
12122 +(define_insn "pic_compute_got_from_pc"
12123 +  [(set (match_operand:SI 0 "register_operand" "+r")
12124 +       (unspec:SI [(minus:SI (pc)
12125 +                              (match_dup 0))] UNSPEC_PIC_BASE))
12126 +   (use (label_ref (match_operand 1 "" "")))]
12127 +  "flag_pic"
12128 +  {
12129 +   (*targetm.asm_out.internal_label) (asm_out_file, "L",
12130 +                            CODE_LABEL_NUMBER (operands[1]));
12131 +   return \"rsub\t%0, pc\";
12132 +  }
12133 +  [(set_attr "cc" "clobber")
12134 +   (set_attr "length" "2")]
12135 +)
12136 +
12137 +;;== long long int - 64 bits ==================================================
12138 +
12139 +(define_expand "movdi"
12140 +  [(set (match_operand:DI 0 "nonimmediate_operand" "")
12141 +       (match_operand:DI 1 "general_operand" ""))]
12142 +  ""
12143 +  {
12144 +
12145 +    /* One of the ops has to be in a register.  */
12146 +    if (GET_CODE (operands[0]) != REG)
12147 +      operands[1] = force_reg (DImode, operands[1]);
12148 +
12149 +  })
12150 +
12151 +
12152 +(define_insn_and_split "*movdi_internal"
12153 +  [(set (match_operand:DI 0 "nonimmediate_operand"     "=r,r,   r,   r,r,r,m")
12154 +       (match_operand:DI 1 "general_operand"          "r, Ks08,Ks21,G,n,m,r"))]
12155 +  "register_operand (operands[0], DImode)
12156 +   || register_operand (operands[1], DImode)"
12157 +  {
12158 +    switch (which_alternative ){
12159 +    case 0:
12160 +    case 1:
12161 +    case 2:
12162 +    case 3:
12163 +    case 4:
12164 +        return "#";
12165 +    case 5:
12166 +      if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])))
12167 +        return "ld.d\t%0, pc[%1 - .]";
12168 +      else
12169 +        return "ld.d\t%0, %1";
12170 +    case 6:
12171 +      return "st.d\t%0, %1";
12172 +    default:
12173 +      abort();
12174 +    }
12175 +  }
12176 +;; Lets split all reg->reg or imm->reg transfers into two SImode transfers 
12177 +  "reload_completed &&
12178 +   (REG_P (operands[0]) &&
12179 +   (REG_P (operands[1]) 
12180 +    || GET_CODE (operands[1]) == CONST_INT
12181 +    || GET_CODE (operands[1]) == CONST_DOUBLE))"
12182 +  [(set (match_dup 0) (match_dup 1))
12183 +   (set (match_dup 2) (match_dup 3))]
12184 +  {
12185 +    operands[2] = gen_highpart (SImode, operands[0]);
12186 +    operands[0] = gen_lowpart (SImode, operands[0]);
12187 +    if ( REG_P(operands[1]) ){
12188 +      operands[3] = gen_highpart(SImode, operands[1]);
12189 +      operands[1] = gen_lowpart(SImode, operands[1]);
12190 +    } else if ( GET_CODE(operands[1]) == CONST_DOUBLE 
12191 +                || GET_CODE(operands[1]) == CONST_INT ){
12192 +      rtx split_const[2];
12193 +      avr32_split_const_expr (DImode, SImode, operands[1], split_const);
12194 +      operands[3] = split_const[1];
12195 +      operands[1] = split_const[0];
12196 +    } else {
12197 +      internal_error("Illegal operand[1] for movdi split!");
12198 +    }
12199 +  }
12200 +
12201 +  [(set_attr "length" "*,*,*,*,*,4,4")
12202 +   (set_attr "type" "*,*,*,*,*,load2,store2")
12203 +   (set_attr "cc" "*,*,*,*,*,none,none")])
12204 +
12205 +
12206 +;;== 128 bits ==================================================
12207 +(define_expand "movti"
12208 +  [(set (match_operand:TI 0 "nonimmediate_operand" "")
12209 +       (match_operand:TI 1 "nonimmediate_operand" ""))]
12210 +  "TARGET_ARCH_AP"    
12211 +  {     
12212 +        
12213 +    /* One of the ops has to be in a register.  */
12214 +    if (GET_CODE (operands[0]) != REG)
12215 +      operands[1] = force_reg (TImode, operands[1]);
12216 +
12217 +    /* We must fix any pre_dec for loads and post_inc stores */
12218 +    if ( GET_CODE (operands[0]) == MEM
12219 +         && GET_CODE (XEXP(operands[0],0)) == POST_INC ){
12220 +       emit_move_insn(gen_rtx_MEM(TImode, XEXP(XEXP(operands[0],0),0)), operands[1]);
12221 +       emit_insn(gen_addsi3(XEXP(XEXP(operands[0],0),0), XEXP(XEXP(operands[0],0),0), GEN_INT(GET_MODE_SIZE(TImode))));
12222 +       DONE;
12223 +    }
12224 +
12225 +    if ( GET_CODE (operands[1]) == MEM
12226 +         && GET_CODE (XEXP(operands[1],0)) == PRE_DEC ){
12227 +       emit_insn(gen_addsi3(XEXP(XEXP(operands[1],0),0), XEXP(XEXP(operands[1],0),0), GEN_INT(-GET_MODE_SIZE(TImode))));
12228 +       emit_move_insn(operands[0], gen_rtx_MEM(TImode, XEXP(XEXP(operands[1],0),0)));
12229 +       DONE;
12230 +    }
12231 +  })
12232 +
12233 +
12234 +(define_insn_and_split "*movti_internal"
12235 +  [(set (match_operand:TI 0 "avr32_movti_dst_operand"  "=r,&r,    r,    <RKu00,r,r")
12236 +       (match_operand:TI 1 "avr32_movti_src_operand"  " r,RKu00>,RKu00,r,     n,T"))]
12237 +  "(register_operand (operands[0], TImode)
12238 +    || register_operand (operands[1], TImode))"
12239 +  {
12240 +    switch (which_alternative ){
12241 +    case 0:
12242 +    case 2:
12243 +    case 4:
12244 +        return "#";
12245 +    case 1:
12246 +        return "ldm\t%p1, %0";
12247 +    case 3:
12248 +        return "stm\t%p0, %1";
12249 +    case 5:
12250 +        return "ld.d\t%U0, pc[%1 - .]\;ld.d\t%B0, pc[%1 - . + 8]";
12251 +    }
12252 +  }
12253 +
12254 +  "reload_completed &&
12255 +   (REG_P (operands[0]) &&
12256 +   (REG_P (operands[1]) 
12257 +    /* If this is a load from the constant pool we split it into
12258 +       two double loads. */
12259 +    || (GET_CODE (operands[1]) == MEM
12260 +        && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
12261 +        && CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0)))               
12262 +    /* If this is a load where the pointer register is a part
12263 +       of the register list, we must split it into two double
12264 +       loads in order for it to be exception safe. */
12265 +    || (GET_CODE (operands[1]) == MEM
12266 +        && register_operand (XEXP (operands[1], 0), SImode)
12267 +        && reg_overlap_mentioned_p (operands[0], XEXP (operands[1], 0)))               
12268 +    || GET_CODE (operands[1]) == CONST_INT
12269 +    || GET_CODE (operands[1]) == CONST_DOUBLE))"
12270 +  [(set (match_dup 0) (match_dup 1))
12271 +   (set (match_dup 2) (match_dup 3))]
12272 +  {
12273 +    operands[2] = simplify_gen_subreg ( DImode, operands[0], 
12274 +                                        TImode, 0 );
12275 +    operands[0] = simplify_gen_subreg ( DImode, operands[0], 
12276 +                                        TImode, 8 );
12277 +    if ( REG_P(operands[1]) ){
12278 +      operands[3] = simplify_gen_subreg ( DImode, operands[1], 
12279 +                                          TImode, 0 );
12280 +      operands[1] = simplify_gen_subreg ( DImode, operands[1], 
12281 +                                          TImode, 8 );
12282 +    } else if ( GET_CODE(operands[1]) == CONST_DOUBLE 
12283 +                || GET_CODE(operands[1]) == CONST_INT ){
12284 +      rtx split_const[2];
12285 +      avr32_split_const_expr (TImode, DImode, operands[1], split_const);
12286 +      operands[3] = split_const[1];
12287 +      operands[1] = split_const[0];
12288 +    } else if (avr32_const_pool_ref_operand (operands[1], GET_MODE(operands[1]))){
12289 +      rtx split_const[2];
12290 +      rtx cop = avoid_constant_pool_reference (operands[1]);
12291 +      if (operands[1] == cop)
12292 +        cop = get_pool_constant (XEXP (operands[1], 0));
12293 +      avr32_split_const_expr (TImode, DImode, cop, split_const);
12294 +      operands[3] = force_const_mem (DImode, split_const[1]); 
12295 +      operands[1] = force_const_mem (DImode, split_const[0]); 
12296 +   } else {
12297 +      rtx ptr_reg = XEXP (operands[1], 0);
12298 +      operands[1] = gen_rtx_MEM (DImode, 
12299 +                                 gen_rtx_PLUS ( SImode,
12300 +                                                ptr_reg,
12301 +                                                GEN_INT (8) ));
12302 +      operands[3] = gen_rtx_MEM (DImode,
12303 +                                 ptr_reg);
12304 +              
12305 +      /* Check if the first load will clobber the pointer.
12306 +         If so, we must switch the order of the operations. */
12307 +      if ( reg_overlap_mentioned_p (operands[0], ptr_reg) )
12308 +        {
12309 +          /* We need to switch the order of the operations
12310 +             so that the pointer register does not get clobbered
12311 +             after the first double word load. */
12312 +          rtx tmp;
12313 +          tmp = operands[0];
12314 +          operands[0] = operands[2];
12315 +          operands[2] = tmp;
12316 +          tmp = operands[1];
12317 +          operands[1] = operands[3];
12318 +          operands[3] = tmp;
12319 +        }
12320 +
12321 +
12322 +   }
12323 +  }
12324 +  [(set_attr "length" "*,*,4,4,*,8")
12325 +   (set_attr "type" "*,*,load4,store4,*,load4")])
12326 +
12327 +
12328 +;;== float - 32 bits ==========================================================
12329 +(define_expand "movsf"
12330 +  [(set (match_operand:SF 0 "nonimmediate_operand" "")
12331 +       (match_operand:SF 1 "general_operand" ""))]
12332 +  ""
12333 +  {
12334 +
12335 +
12336 +    /* One of the ops has to be in a register.  */
12337 +    if (GET_CODE (operands[0]) != REG)
12338 +      operands[1] = force_reg (SFmode, operands[1]);
12339 +
12340 +  })
12341 +
12342 +(define_insn "*movsf_internal"
12343 +  [(set (match_operand:SF 0 "nonimmediate_operand"     "=r,r,r,r,m")
12344 +       (match_operand:SF 1 "general_operand"          "r, G,F,m,r"))]
12345 +  "(register_operand (operands[0], SFmode)
12346 +    || register_operand (operands[1], SFmode))"
12347 +  {
12348 +    switch (which_alternative) {
12349 +      case 0:
12350 +      case 1: return "mov\t%0, %1";
12351 +      case 2: 
12352 +       {
12353 +        HOST_WIDE_INT target_float[2];
12354 +        real_to_target (target_float, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode);
12355 +        if ( TARGET_V2_INSNS 
12356 +             && avr32_hi16_immediate_operand (GEN_INT (target_float[0]), VOIDmode) )
12357 +           return "movh\t%0, hi(%1)";
12358 +        else
12359 +           return "mov\t%0, lo(%1)\;orh\t%0, hi(%1)";
12360 +       }
12361 +      case 3:
12362 +        if ( (REG_P(XEXP(operands[1], 0))
12363 +              && REGNO(XEXP(operands[1], 0)) == SP_REGNUM)
12364 +             || (GET_CODE(XEXP(operands[1], 0)) == PLUS
12365 +                 && REGNO(XEXP(XEXP(operands[1], 0), 0)) == SP_REGNUM
12366 +                && GET_CODE(XEXP(XEXP(operands[1], 0), 1)) == CONST_INT
12367 +                && INTVAL(XEXP(XEXP(operands[1], 0), 1)) % 4 == 0
12368 +                && INTVAL(XEXP(XEXP(operands[1], 0), 1)) <= 0x1FC) )
12369 +          return "lddsp\t%0, %1";
12370 +          else if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])) )
12371 +          return "lddpc\t%0, %1";
12372 +        else
12373 +          return "ld.w\t%0, %1";
12374 +      case 4:
12375 +        if ( (REG_P(XEXP(operands[0], 0))
12376 +              && REGNO(XEXP(operands[0], 0)) == SP_REGNUM)
12377 +             || (GET_CODE(XEXP(operands[0], 0)) == PLUS
12378 +                 && REGNO(XEXP(XEXP(operands[0], 0), 0)) == SP_REGNUM
12379 +                && GET_CODE(XEXP(XEXP(operands[0], 0), 1)) == CONST_INT
12380 +                && INTVAL(XEXP(XEXP(operands[0], 0), 1)) % 4 == 0
12381 +                && INTVAL(XEXP(XEXP(operands[0], 0), 1)) <= 0x1FC) )
12382 +          return "stdsp\t%0, %1";
12383 +       else
12384 +          return "st.w\t%0, %1";
12385 +      default:
12386 +       abort();
12387 +    }
12388 +  }
12389 +
12390 +  [(set_attr "length" "2,4,8,4,4")
12391 +   (set_attr "type" "alu,alu,alu2,load,store")
12392 +   (set_attr "cc" "none,none,clobber,none,none")])
12393 +
12394 +
12395 +
12396 +;;== double - 64 bits =========================================================
12397 +(define_expand "movdf"
12398 +  [(set (match_operand:DF 0 "nonimmediate_operand" "")
12399 +       (match_operand:DF 1 "general_operand" ""))]
12400 +  ""
12401 +  {
12402 +    /* One of the ops has to be in a register.  */
12403 +    if (GET_CODE (operands[0]) != REG){
12404 +      operands[1] = force_reg (DFmode, operands[1]);
12405 +    }
12406 +  })
12407 +
12408 +
12409 +(define_insn_and_split "*movdf_internal"
12410 +  [(set (match_operand:DF 0 "nonimmediate_operand"     "=r,r,r,r,m")
12411 +       (match_operand:DF 1 "general_operand"          " r,G,F,m,r"))]
12412 +  "(register_operand (operands[0], DFmode)
12413 +       || register_operand (operands[1], DFmode))"
12414 +  {
12415 +    switch (which_alternative ){
12416 +    case 0:
12417 +    case 1:
12418 +    case 2: 
12419 +        return "#";
12420 +    case 3:
12421 +      if ( avr32_const_pool_ref_operand(operands[1], GET_MODE(operands[1])))
12422 +        return "ld.d\t%0, pc[%1 - .]";
12423 +      else
12424 +        return "ld.d\t%0, %1";
12425 +    case 4:
12426 +      return "st.d\t%0, %1";
12427 +    default:
12428 +      abort();
12429 +    }
12430 +  }
12431 +  "reload_completed
12432 +   && (REG_P (operands[0]) 
12433 +        && (REG_P (operands[1])
12434 +            || GET_CODE (operands[1]) == CONST_DOUBLE))"
12435 +  [(set (match_dup 0) (match_dup 1))
12436 +   (set (match_dup 2) (match_dup 3))]
12437 +  "
12438 +   {
12439 +    operands[2] = gen_highpart (SImode, operands[0]);
12440 +    operands[0] = gen_lowpart (SImode, operands[0]);
12441 +    operands[3] = gen_highpart(SImode, operands[1]);
12442 +    operands[1] = gen_lowpart(SImode, operands[1]);
12443 +   }
12444 +  "
12445 +
12446 +  [(set_attr "length" "*,*,*,4,4")
12447 +   (set_attr "type" "*,*,*,load2,store2")
12448 +   (set_attr "cc" "*,*,*,none,none")])
12449 +
12450 +
12451 +;;=============================================================================
12452 +;; Conditional Moves
12453 +;;=============================================================================
12454 +(define_insn "ld<mode>_predicable"
12455 +  [(set (match_operand:MOVCC 0 "register_operand" "=r")
12456 +       (match_operand:MOVCC 1 "avr32_non_rmw_memory_operand" "<MOVCC:pred_mem_constraint>"))]
12457 +  "TARGET_V2_INSNS"
12458 +  "ld<MOVCC:load_postfix>%?\t%0, %1"
12459 +  [(set_attr "length" "4")
12460 +   (set_attr "cc" "cmp_cond_insn")
12461 +   (set_attr "type" "load")
12462 +   (set_attr "predicable" "yes")]
12463 +)
12464 +
12465 +
12466 +(define_insn "st<mode>_predicable"
12467 +  [(set (match_operand:MOVCC 0 "avr32_non_rmw_memory_operand" "=<MOVCC:pred_mem_constraint>")
12468 +       (match_operand:MOVCC 1 "register_operand" "r"))]
12469 +  "TARGET_V2_INSNS"
12470 +  "st<MOVCC:store_postfix>%?\t%0, %1"
12471 +  [(set_attr "length" "4")
12472 +   (set_attr "cc" "cmp_cond_insn")
12473 +   (set_attr "type" "store")
12474 +   (set_attr "predicable" "yes")]
12475 +)
12476 +
12477 +(define_insn "mov<mode>_predicable"
12478 +  [(set (match_operand:MOVCC 0 "register_operand" "=r")
12479 +       (match_operand:MOVCC 1 "avr32_cond_register_immediate_operand" "rKs08"))]
12480 +  ""
12481 +  "mov%?\t%0, %1"
12482 +  [(set_attr "length" "4")
12483 +   (set_attr "cc" "cmp_cond_insn")
12484 +   (set_attr "type" "alu")
12485 +   (set_attr "predicable" "yes")]
12486 +)
12487 +
12488 +
12489 +;;=============================================================================
12490 +;; Move chunks of memory
12491 +;;=============================================================================
12492 +
12493 +(define_expand "movmemsi"
12494 +  [(match_operand:BLK 0 "general_operand" "")
12495 +   (match_operand:BLK 1 "general_operand" "")
12496 +   (match_operand:SI 2 "const_int_operand" "")
12497 +   (match_operand:SI 3 "const_int_operand" "")]
12498 +  ""
12499 +  "
12500 +   if (avr32_gen_movmemsi (operands))
12501 +     DONE;
12502 +   FAIL;
12503 +  "
12504 +  )
12505 +
12506 +
12507 +
12508 +
12509 +;;=============================================================================
12510 +;; Bit field instructions
12511 +;;-----------------------------------------------------------------------------
12512 +;; Instructions to insert or extract bit-fields
12513 +;;=============================================================================
12514 +
12515 +(define_insn "insv"
12516 +  [ (set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
12517 +                          (match_operand:SI 1 "immediate_operand" "Ku05")
12518 +                          (match_operand:SI 2 "immediate_operand" "Ku05"))
12519 +         (match_operand 3 "register_operand" "r"))]
12520 +  ""
12521 +  "bfins\t%0, %3, %2, %1"
12522 +  [(set_attr "type" "alu")
12523 +   (set_attr "length" "4")
12524 +   (set_attr "cc" "set_ncz")])
12525 +
12526 +
12527 +
12528 +(define_expand "extv"
12529 +  [ (set (match_operand:SI 0 "register_operand" "")
12530 +         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12531 +                          (match_operand:SI 2 "immediate_operand" "")
12532 +                          (match_operand:SI 3 "immediate_operand" "")))]
12533 +  ""
12534 +  {
12535 +   if ( INTVAL(operands[2]) >= 32 )
12536 +      FAIL;
12537 +  }
12538 +)
12539 +
12540 +(define_expand "extzv"
12541 +  [ (set (match_operand:SI 0 "register_operand" "")
12542 +         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
12543 +                          (match_operand:SI 2 "immediate_operand" "")
12544 +                          (match_operand:SI 3 "immediate_operand" "")))]
12545 +  ""
12546 +  {
12547 +   if ( INTVAL(operands[2]) >= 32 )
12548 +      FAIL;
12549 +  }
12550 +)
12551 +
12552 +(define_insn "extv_internal"
12553 +  [ (set (match_operand:SI 0 "register_operand" "=r")
12554 +         (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
12555 +                          (match_operand:SI 2 "immediate_operand" "Ku05")
12556 +                          (match_operand:SI 3 "immediate_operand" "Ku05")))]
12557 +  "INTVAL(operands[2]) < 32"
12558 +  "bfexts\t%0, %1, %3, %2"
12559 +  [(set_attr "type" "alu")
12560 +   (set_attr "length" "4")
12561 +   (set_attr "cc" "set_ncz")])
12562 +
12563 +
12564 +(define_insn "extzv_internal"
12565 +  [ (set (match_operand:SI 0 "register_operand" "=r")
12566 +         (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
12567 +                          (match_operand:SI 2 "immediate_operand" "Ku05")
12568 +                          (match_operand:SI 3 "immediate_operand" "Ku05")))]
12569 +  "INTVAL(operands[2]) < 32"
12570 +  "bfextu\t%0, %1, %3, %2"
12571 +  [(set_attr "type" "alu")
12572 +   (set_attr "length" "4")
12573 +   (set_attr "cc" "set_ncz")])
12574 +
12575 +
12576 +
12577 +;;=============================================================================
12578 +;; Some peepholes for avoiding unnecessary cast instructions
12579 +;; followed by bfins.
12580 +;;-----------------------------------------------------------------------------
12581 +
12582 +(define_peephole2
12583 +  [(set (match_operand:SI 0 "register_operand" "")
12584 +        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
12585 +   (set (zero_extract:SI (match_operand 2 "register_operand" "")
12586 +                         (match_operand:SI 3 "immediate_operand" "")
12587 +                         (match_operand:SI 4 "immediate_operand" ""))
12588 +        (match_dup 0))]
12589 +  "((peep2_reg_dead_p(2, operands[0]) &&
12590 +    (INTVAL(operands[3]) <= 8)))"
12591 +  [(set (zero_extract:SI (match_dup 2)
12592 +                         (match_dup 3)
12593 +                         (match_dup 4))
12594 +        (match_dup 1))]
12595 +  )
12596 +
12597 +(define_peephole2
12598 +  [(set (match_operand:SI 0 "register_operand" "")
12599 +        (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
12600 +   (set (zero_extract:SI (match_operand 2 "register_operand" "")
12601 +                         (match_operand:SI 3 "immediate_operand" "")
12602 +                         (match_operand:SI 4 "immediate_operand" ""))
12603 +        (match_dup 0))]
12604 +  "((peep2_reg_dead_p(2, operands[0]) &&
12605 +    (INTVAL(operands[3]) <= 16)))"
12606 +  [(set (zero_extract:SI (match_dup 2)
12607 +                         (match_dup 3)
12608 +                         (match_dup 4))
12609 +        (match_dup 1))]
12610 +  )
12611 +
12612 +;;=============================================================================
12613 +;; push bytes
12614 +;;-----------------------------------------------------------------------------
12615 +;; Implements the push instruction
12616 +;;=============================================================================
12617 +(define_insn "pushm"
12618 +  [(set (mem:BLK (pre_dec:BLK (reg:SI SP_REGNUM)))
12619 +        (unspec:BLK [(match_operand 0 "const_int_operand" "")]
12620 +                    UNSPEC_PUSHM))]
12621 +  ""
12622 +  {
12623 +    if (INTVAL(operands[0])) {
12624 +      return "pushm\t%r0";
12625 +    } else {
12626 +      return "";
12627 +    }
12628 +  }
12629 +  [(set_attr "type" "store")
12630 +   (set_attr "length" "2")
12631 +   (set_attr "cc" "none")])
12632 +
12633 +(define_insn "stm"
12634 +  [(unspec [(match_operand 0 "register_operand" "r")
12635 +            (match_operand 1 "const_int_operand" "")
12636 +            (match_operand 2 "const_int_operand" "")]
12637 +          UNSPEC_STM)]
12638 +  ""
12639 +  {
12640 +    if (INTVAL(operands[1])) {
12641 +      if (INTVAL(operands[2]) != 0)
12642 +         return "stm\t--%0, %s1";
12643 +      else
12644 +         return "stm\t%0, %s1";
12645 +    } else {
12646 +      return "";
12647 +    }
12648 +  }
12649 +  [(set_attr "type" "store")
12650 +   (set_attr "length" "4")
12651 +   (set_attr "cc" "none")])
12652 +
12653 +
12654 +
12655 +(define_insn "popm"
12656 +  [(unspec [(match_operand 0 "const_int_operand" "")]
12657 +          UNSPEC_POPM)]
12658 +  ""
12659 +  {
12660 +    if (INTVAL(operands[0])) {
12661 +      return "popm   %r0";
12662 +    } else {
12663 +      return "";
12664 +    }
12665 +  }
12666 +  [(set_attr "type" "load")
12667 +   (set_attr "length" "2")])
12668 +
12669 +
12670 +
12671 +;;=============================================================================
12672 +;; add
12673 +;;-----------------------------------------------------------------------------
12674 +;; Adds reg1 with reg2 and puts the result in reg0.
12675 +;;=============================================================================
12676 +(define_insn "add<mode>3"
12677 +  [(set (match_operand:INTM 0 "register_operand" "=r,r,r,r,r")
12678 +       (plus:INTM (match_operand:INTM 1 "register_operand" "%0,r,0,r,0")
12679 +                   (match_operand:INTM 2 "avr32_add_operand" "r,r,Is08,Is16,Is21")))]
12680 +  ""
12681 +  "@
12682 +   add     %0, %2
12683 +   add     %0, %1, %2
12684 +   sub     %0, %n2
12685 +   sub     %0, %1, %n2
12686 +   sub     %0, %n2"
12687 +
12688 +  [(set_attr "length" "2,4,2,4,4")
12689 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12690 +
12691 +(define_insn "add<mode>3_lsl"
12692 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12693 +       (plus:INTM (ashift:INTM (match_operand:INTM 1 "register_operand" "r")
12694 +                                (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02"))
12695 +                   (match_operand:INTM 2 "register_operand" "r")))]
12696 +  ""
12697 +  "add     %0, %2, %1 << %3"
12698 +  [(set_attr "length" "4")
12699 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12700 +
12701 +(define_insn "add<mode>3_lsl2"
12702 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12703 +       (plus:INTM (match_operand:INTM 1 "register_operand" "r")
12704 +                   (ashift:INTM (match_operand:INTM 2 "register_operand" "r")
12705 +                                (match_operand:INTM 3 "avr32_add_shift_immediate_operand" "Ku02"))))]
12706 +  ""
12707 +  "add     %0, %1, %2 << %3"
12708 +  [(set_attr "length" "4")
12709 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12710 +
12711 +
12712 +(define_insn "add<mode>3_mul"
12713 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12714 +       (plus:INTM (mult:INTM (match_operand:INTM 1 "register_operand" "r")
12715 +                              (match_operand:INTM 3 "immediate_operand" "Ku04" ))
12716 +                   (match_operand:INTM 2 "register_operand" "r")))]
12717 +  "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
12718 +   (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
12719 +  "add     %0, %2, %1 << %p3"
12720 +  [(set_attr "length" "4")
12721 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12722 +
12723 +(define_insn "add<mode>3_mul2"
12724 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12725 +       (plus:INTM (match_operand:INTM 1 "register_operand" "r")
12726 +                   (mult:INTM (match_operand:INTM 2 "register_operand" "r")
12727 +                              (match_operand:INTM 3 "immediate_operand" "Ku04" ))))]
12728 +  "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
12729 +   (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
12730 +  "add     %0, %1, %2 << %p3"
12731 +  [(set_attr "length" "4")
12732 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12733 +
12734 +
12735 +(define_peephole2
12736 +  [(set (match_operand:SI 0 "register_operand" "")
12737 +        (ashift:SI (match_operand:SI 1 "register_operand" "")
12738 +                   (match_operand:SI 2 "immediate_operand" "")))
12739 +   (set (match_operand:SI 3 "register_operand" "")
12740 +       (plus:SI (match_dup 0)
12741 +                 (match_operand:SI 4 "register_operand" "")))]
12742 +  "(peep2_reg_dead_p(2, operands[0]) &&
12743 +    (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))"
12744 +  [(set (match_dup 3)
12745 +       (plus:SI (ashift:SI (match_dup 1)
12746 +                            (match_dup 2))
12747 +                 (match_dup 4)))]
12748 +  )
12749 +
12750 +(define_peephole2
12751 +  [(set (match_operand:SI 0 "register_operand" "")
12752 +        (ashift:SI (match_operand:SI 1 "register_operand" "")
12753 +                   (match_operand:SI 2 "immediate_operand" "")))
12754 +   (set (match_operand:SI 3 "register_operand" "")
12755 +       (plus:SI (match_operand:SI 4 "register_operand" "")
12756 +                 (match_dup 0)))]
12757 +  "(peep2_reg_dead_p(2, operands[0]) &&
12758 +    (INTVAL(operands[2]) < 4 && INTVAL(operands[2]) > 0))"
12759 +  [(set (match_dup 3)
12760 +       (plus:SI (ashift:SI (match_dup 1)
12761 +                            (match_dup 2))
12762 +                 (match_dup 4)))]
12763 +  )
12764 +
12765 +(define_insn "adddi3"
12766 +  [(set (match_operand:DI 0 "register_operand" "=r,r")
12767 +       (plus:DI (match_operand:DI 1 "register_operand" "%0,r")
12768 +                (match_operand:DI 2 "register_operand" "r,r")))]
12769 +  ""
12770 +  "@
12771 +   add     %0, %2\;adc    %m0, %m0, %m2
12772 +   add     %0, %1, %2\;adc    %m0, %m1, %m2"
12773 +  [(set_attr "length" "6,8")
12774 +   (set_attr "type" "alu2")
12775 +   (set_attr "cc" "set_vncz")])
12776 +
12777 +
12778 +(define_insn "add<mode>_imm_predicable"
12779 +  [(set (match_operand:INTM 0 "register_operand" "+r")
12780 +       (plus:INTM (match_dup 0)
12781 +                   (match_operand:INTM 1 "avr32_cond_immediate_operand" "%Is08")))]
12782 +  ""
12783 +  "sub%?\t%0, -%1"
12784 +  [(set_attr "length" "4")
12785 +   (set_attr "cc" "cmp_cond_insn")
12786 +   (set_attr "predicable" "yes")]
12787 +)
12788 +
12789 +;;=============================================================================
12790 +;; subtract
12791 +;;-----------------------------------------------------------------------------
12792 +;; Subtract reg2 or immediate value from reg0 and puts the result in reg0.
12793 +;;=============================================================================
12794 +
12795 +(define_insn "sub<mode>3"
12796 +  [(set (match_operand:INTM 0 "general_operand" "=r,r,r,r,r,r,r")
12797 +       (minus:INTM (match_operand:INTM 1 "register_const_int_operand" "0,r,0,r,0,r,Ks08")
12798 +                 (match_operand:INTM 2 "register_const_int_operand" "r,r,Ks08,Ks16,Ks21,0,r")))]
12799 +  ""
12800 +  "@
12801 +   sub     %0, %2
12802 +   sub     %0, %1, %2
12803 +   sub     %0, %2
12804 +   sub     %0, %1, %2
12805 +   sub     %0, %2
12806 +   rsub    %0, %1
12807 +   rsub    %0, %2, %1"
12808 +  [(set_attr "length" "2,4,2,4,4,2,4")
12809 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12810 +
12811 +(define_insn "*sub<mode>3_mul"
12812 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12813 +       (minus:INTM (match_operand:INTM 1 "register_operand" "r")
12814 +                    (mult:INTM (match_operand:INTM 2 "register_operand" "r")
12815 +                               (match_operand:SI 3 "immediate_operand" "Ku04" ))))]
12816 +  "(INTVAL(operands[3]) == 0) || (INTVAL(operands[3]) == 2) ||
12817 +   (INTVAL(operands[3]) == 4) || (INTVAL(operands[3]) == 8)"
12818 +  "sub     %0, %1, %2 << %p3"
12819 +  [(set_attr "length" "4")
12820 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12821 +
12822 +(define_insn "*sub<mode>3_lsl"
12823 +  [(set (match_operand:INTM 0 "register_operand" "=r")
12824 +       (minus:INTM  (match_operand:INTM 1 "register_operand" "r")
12825 +                     (ashift:INTM (match_operand:INTM 2 "register_operand" "r")
12826 +                                  (match_operand:SI 3 "avr32_add_shift_immediate_operand" "Ku02"))))]
12827 +  ""
12828 +  "sub     %0, %1, %2 << %3"
12829 +  [(set_attr "length" "4")
12830 +   (set_attr "cc" "<INTM:alu_cc_attr>")])
12831 +
12832 +
12833 +(define_insn "subdi3"
12834 +  [(set (match_operand:DI 0 "register_operand" "=r,r")
12835 +       (minus:DI (match_operand:DI 1 "register_operand" "%0,r")
12836 +                (match_operand:DI 2 "register_operand" "r,r")))]
12837 +  ""
12838 +  "@
12839 +   sub     %0, %2\;sbc    %m0, %m0, %m2
12840 +   sub     %0, %1, %2\;sbc    %m0, %m1, %m2"
12841 +  [(set_attr "length" "6,8")
12842 +   (set_attr "type" "alu2")
12843 +   (set_attr "cc" "set_vncz")])
12844 +
12845 +
12846 +(define_insn "sub<mode>_imm_predicable"
12847 +  [(set (match_operand:INTM 0 "register_operand" "+r")
12848 +       (minus:INTM (match_dup 0)
12849 +                    (match_operand:INTM 1 "avr32_cond_immediate_operand" "Ks08")))]
12850 +  ""
12851 +  "sub%?\t%0, %1"
12852 +  [(set_attr "length" "4")
12853 +   (set_attr "cc" "cmp_cond_insn")
12854 +   (set_attr "predicable" "yes")])
12855 +
12856 +(define_insn "rsub<mode>_imm_predicable"
12857 +  [(set (match_operand:INTM 0 "register_operand" "+r")
12858 +       (minus:INTM (match_operand:INTM 1 "avr32_cond_immediate_operand"  "Ks08")
12859 +                    (match_dup 0)))]
12860 +  ""
12861 +  "rsub%?\t%0, %1"
12862 +  [(set_attr "length" "4")
12863 +   (set_attr "cc" "cmp_cond_insn")
12864 +   (set_attr "predicable" "yes")])
12865 +
12866 +;;=============================================================================
12867 +;; multiply
12868 +;;-----------------------------------------------------------------------------
12869 +;; Multiply op1 and op2 and put the value in op0.
12870 +;;=============================================================================
12871 +
12872 +
12873 +(define_insn "mulqi3"
12874 +  [(set (match_operand:QI 0 "register_operand"         "=r,r,r")
12875 +       (mult:QI (match_operand:QI 1 "register_operand" "%0,r,r")
12876 +                (match_operand:QI 2 "avr32_mul_operand" "r,r,Ks08")))]
12877 +  "!TARGET_NO_MUL_INSNS"
12878 +  {
12879 +   switch (which_alternative){
12880 +    case 0:
12881 +      return "mul     %0, %2";
12882 +    case 1:
12883 +      return "mul     %0, %1, %2";
12884 +    case 2:
12885 +      return "mul     %0, %1, %2";
12886 +    default:
12887 +      gcc_unreachable();
12888 +   }
12889 +  }
12890 +  [(set_attr "type" "mulww_w,mulww_w,mulwh")
12891 +   (set_attr "length" "2,4,4")
12892 +   (set_attr "cc" "none")])
12893 +
12894 +(define_insn "mulsi3"
12895 +  [(set (match_operand:SI 0 "register_operand"         "=r,r,r")
12896 +       (mult:SI (match_operand:SI 1 "register_operand" "%0,r,r")
12897 +                (match_operand:SI 2 "avr32_mul_operand" "r,r,Ks08")))]
12898 +  "!TARGET_NO_MUL_INSNS"
12899 +  {
12900 +   switch (which_alternative){
12901 +    case 0:
12902 +      return "mul     %0, %2";
12903 +    case 1:
12904 +      return "mul     %0, %1, %2";
12905 +    case 2:
12906 +      return "mul     %0, %1, %2";
12907 +    default:
12908 +      gcc_unreachable();
12909 +   }
12910 +  }
12911 +  [(set_attr "type" "mulww_w,mulww_w,mulwh")
12912 +   (set_attr "length" "2,4,4")
12913 +   (set_attr "cc" "none")])
12914 +
12915 +
12916 +(define_insn "mulhisi3"
12917 +  [(set (match_operand:SI 0 "register_operand" "=r")
12918 +       (mult:SI
12919 +        (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
12920 +        (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
12921 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
12922 +  "mulhh.w %0, %1:b, %2:b"
12923 +  [(set_attr "type" "mulhh")
12924 +   (set_attr "length" "4")
12925 +   (set_attr "cc" "none")])
12926 +
12927 +(define_peephole2
12928 +  [(match_scratch:DI 6 "r")
12929 +   (set (match_operand:SI 0 "register_operand" "")
12930 +       (mult:SI
12931 +        (sign_extend:SI (match_operand:HI 1 "register_operand" ""))
12932 +         (sign_extend:SI (match_operand:HI 2 "register_operand" ""))))
12933 +   (set (match_operand:SI 3 "register_operand" "")
12934 +        (ashiftrt:SI (match_dup 0)
12935 +                     (const_int 16)))]
12936 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP
12937 +   && (peep2_reg_dead_p(1, operands[0]) || (REGNO(operands[0]) == REGNO(operands[3])))"
12938 +  [(set (match_dup 4) (sign_extend:SI (match_dup 1)))
12939 +   (set (match_dup 6)
12940 +        (ashift:DI (mult:DI (sign_extend:DI (match_dup 4))
12941 +                            (sign_extend:DI (match_dup 2)))
12942 +                   (const_int 16)))
12943 +   (set (match_dup 3) (match_dup 5))]
12944 +
12945 +  "{
12946 +     operands[4] = gen_rtx_REG(SImode, REGNO(operands[1]));
12947 +     operands[5] = gen_highpart (SImode, operands[4]);
12948 +   }"
12949 +  )
12950 +
12951 +(define_insn "mulnhisi3"
12952 +  [(set (match_operand:SI 0 "register_operand" "=r")
12953 +        (mult:SI
12954 +         (sign_extend:SI (neg:HI (match_operand:HI 1 "register_operand" "r")))
12955 +         (sign_extend:SI (match_operand:HI 2 "register_operand" "r"))))]
12956 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
12957 +  "mulnhh.w %0, %1:b, %2:b"
12958 +  [(set_attr "type" "mulhh")
12959 +   (set_attr "length" "4")
12960 +   (set_attr "cc" "none")])
12961 +
12962 +(define_insn "machisi3"
12963 +  [(set (match_operand:SI 0 "register_operand" "+r")
12964 +       (plus:SI (mult:SI
12965 +                  (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
12966 +                  (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
12967 +                 (match_dup 0)))]
12968 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
12969 +  "machh.w %0, %1:b, %2:b"
12970 +  [(set_attr "type" "machh_w")
12971 +   (set_attr "length" "4")
12972 +   (set_attr "cc" "none")])
12973 +
12974 +
12975 +
12976 +(define_insn "mulsidi3"
12977 +  [(set (match_operand:DI 0 "register_operand" "=r")
12978 +       (mult:DI
12979 +        (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
12980 +        (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
12981 +  "!TARGET_NO_MUL_INSNS"
12982 +  "muls.d  %0, %1, %2"
12983 +  [(set_attr "type" "mulww_d")
12984 +   (set_attr "length" "4")
12985 +   (set_attr "cc" "none")])
12986 +
12987 +(define_insn "umulsidi3"
12988 +  [(set (match_operand:DI 0 "register_operand" "=r")
12989 +       (mult:DI
12990 +        (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
12991 +        (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))))]
12992 +  "!TARGET_NO_MUL_INSNS"
12993 +  "mulu.d  %0, %1, %2"
12994 +  [(set_attr "type" "mulww_d")
12995 +   (set_attr "length" "4")
12996 +   (set_attr "cc" "none")])
12997 +
12998 +(define_insn "*mulaccsi3"
12999 +  [(set (match_operand:SI 0 "register_operand" "+r")
13000 +       (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "%r")
13001 +                         (match_operand:SI 2 "register_operand" "r"))
13002 +                (match_dup 0)))]
13003 +  "!TARGET_NO_MUL_INSNS"
13004 +  "mac     %0, %1, %2"
13005 +  [(set_attr "type" "macww_w")
13006 +   (set_attr "length" "4")
13007 +   (set_attr "cc" "none")])
13008 +
13009 +(define_insn "*mulaccsidi3"
13010 +  [(set (match_operand:DI 0 "register_operand" "+r")
13011 +       (plus:DI (mult:DI
13012 +                 (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
13013 +                 (sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
13014 +                (match_dup 0)))]
13015 +  "!TARGET_NO_MUL_INSNS"
13016 +  "macs.d  %0, %1, %2"
13017 +  [(set_attr "type" "macww_d")
13018 +   (set_attr "length" "4")
13019 +   (set_attr "cc" "none")])
13020 +
13021 +(define_insn "*umulaccsidi3"
13022 +  [(set (match_operand:DI 0 "register_operand" "+r")
13023 +       (plus:DI (mult:DI
13024 +                 (zero_extend:DI (match_operand:SI 1 "register_operand" "%r"))
13025 +                 (zero_extend:DI (match_operand:SI 2 "register_operand" "r")))
13026 +                (match_dup 0)))]
13027 +  "!TARGET_NO_MUL_INSNS"
13028 +  "macu.d  %0, %1, %2"
13029 +  [(set_attr "type" "macww_d")
13030 +   (set_attr "length" "4")
13031 +   (set_attr "cc" "none")])
13032 +
13033 +
13034 +
13035 +;; Try to avoid Write-After-Write hazards for mul operations
13036 +;; if it can be done
13037 +(define_peephole2
13038 +  [(set (match_operand:SI 0 "register_operand" "")
13039 +       (mult:SI
13040 +        (sign_extend:SI (match_operand 1 "general_operand" ""))
13041 +         (sign_extend:SI (match_operand 2 "general_operand" ""))))
13042 +   (set (match_dup 0)
13043 +       (match_operator:SI 3 "alu_operator" [(match_dup 0)
13044 +                                             (match_operand 4 "general_operand" "")]))]
13045 +  "peep2_reg_dead_p(1, operands[2])"
13046 +  [(set (match_dup 5)
13047 +        (mult:SI
13048 +         (sign_extend:SI (match_dup 1))
13049 +         (sign_extend:SI (match_dup 2))))
13050 +   (set (match_dup 0)
13051 +       (match_op_dup 3 [(match_dup 5)
13052 +                         (match_dup 4)]))]
13053 +  "{operands[5] = gen_rtx_REG(SImode, REGNO(operands[2]));}"
13054 +  )
13055 +
13056 +
13057 +
13058 +;;=============================================================================
13059 +;; DSP instructions
13060 +;;=============================================================================
13061 +(define_insn "mulsathh_h"
13062 +  [(set (match_operand:HI 0 "register_operand" "=r")
13063 +        (ss_truncate:HI (ashiftrt:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
13064 +                                              (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
13065 +                                     (const_int 15))))]
13066 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13067 +  "mulsathh.h\t%0, %1:b, %2:b"
13068 +  [(set_attr "length" "4")
13069 +   (set_attr "cc" "none")
13070 +   (set_attr "type" "mulhh")])
13071 +
13072 +(define_insn "mulsatrndhh_h"
13073 +  [(set (match_operand:HI 0 "register_operand" "=r")
13074 +        (ss_truncate:HI (ashiftrt:SI
13075 +                         (plus:SI (mult:SI (sign_extend:SI (match_operand:HI 1 "register_operand" "%r"))
13076 +                                           (sign_extend:SI (match_operand:HI 2 "register_operand" "r")))
13077 +                                  (const_int 1073741824))
13078 +                         (const_int 15))))]
13079 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13080 +  "mulsatrndhh.h\t%0, %1:b, %2:b"
13081 +  [(set_attr "length" "4")
13082 +   (set_attr "cc" "none")
13083 +   (set_attr "type" "mulhh")])
13084 +
13085 +(define_insn "mulsathh_w"
13086 +  [(set (match_operand:SI 0 "register_operand" "=r")
13087 +        (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
13088 +                                            (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13089 +                                   (const_int 1))))]
13090 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13091 +  "mulsathh.w\t%0, %1:b, %2:b"
13092 +  [(set_attr "length" "4")
13093 +   (set_attr "cc" "none")
13094 +   (set_attr "type" "mulhh")])
13095 +
13096 +(define_insn "mulsatwh_w"
13097 +  [(set (match_operand:SI 0 "register_operand" "=r")
13098 +        (ss_truncate:SI (ashiftrt:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
13099 +                                              (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13100 +                                     (const_int 15))))]
13101 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13102 +  "mulsatwh.w\t%0, %1, %2:b"
13103 +  [(set_attr "length" "4")
13104 +   (set_attr "cc" "none")
13105 +   (set_attr "type" "mulwh")])
13106 +
13107 +(define_insn "mulsatrndwh_w"
13108 +  [(set (match_operand:SI 0 "register_operand" "=r")
13109 +        (ss_truncate:SI (ashiftrt:DI (plus:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
13110 +                                                       (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13111 +                                              (const_int 1073741824))
13112 +                                     (const_int 15))))]
13113 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13114 +  "mulsatrndwh.w\t%0, %1, %2:b"
13115 +  [(set_attr "length" "4")
13116 +   (set_attr "cc" "none")
13117 +   (set_attr "type" "mulwh")])
13118 +
13119 +(define_insn "macsathh_w"
13120 +  [(set (match_operand:SI 0 "register_operand" "+r")
13121 +        (plus:SI (match_dup 0)
13122 +                 (ss_truncate:SI (ashift:DI (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
13123 +                                                     (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13124 +                                            (const_int 1)))))]
13125 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13126 +  "macsathh.w\t%0, %1:b, %2:b"
13127 +  [(set_attr "length" "4")
13128 +   (set_attr "cc" "none")
13129 +   (set_attr "type" "mulhh")])
13130 +
13131 +
13132 +(define_insn "mulwh_d"
13133 +  [(set (match_operand:DI 0 "register_operand" "=r")
13134 +        (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r"))
13135 +                            (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13136 +                   (const_int 16)))]
13137 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13138 +  "mulwh.d\t%0, %1, %2:b"
13139 +  [(set_attr "length" "4")
13140 +   (set_attr "cc" "none")
13141 +   (set_attr "type" "mulwh")])
13142 +
13143 +
13144 +(define_insn "mulnwh_d"
13145 +  [(set (match_operand:DI 0 "register_operand" "=r")
13146 +        (ashift:DI (mult:DI (not:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "r")))
13147 +                            (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13148 +                   (const_int 16)))]
13149 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13150 +  "mulnwh.d\t%0, %1, %2:b"
13151 +  [(set_attr "length" "4")
13152 +   (set_attr "cc" "none")
13153 +   (set_attr "type" "mulwh")])
13154 +
13155 +(define_insn "macwh_d"
13156 +  [(set (match_operand:DI 0 "register_operand" "+r")
13157 +        (plus:DI (match_dup 0)
13158 +                 (ashift:DI (mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
13159 +                                     (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))
13160 +                            (const_int 16))))]
13161 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13162 +  "macwh.d\t%0, %1, %2:b"
13163 +  [(set_attr "length" "4")
13164 +   (set_attr "cc" "none")
13165 +   (set_attr "type" "mulwh")])
13166 +
13167 +(define_insn "machh_d"
13168 +  [(set (match_operand:DI 0 "register_operand" "+r")
13169 +        (plus:DI (match_dup 0)
13170 +                 (mult:DI (sign_extend:DI (match_operand:HI 1 "register_operand" "%r"))
13171 +                          (sign_extend:DI (match_operand:HI 2 "register_operand" "r")))))]
13172 +  "!TARGET_NO_MUL_INSNS && TARGET_DSP"
13173 +  "machh.d\t%0, %1:b, %2:b"
13174 +  [(set_attr "length" "4")
13175 +   (set_attr "cc" "none")
13176 +   (set_attr "type" "mulwh")])
13177 +
13178 +(define_insn "satadd_w"
13179 +  [(set (match_operand:SI 0 "register_operand" "=r")
13180 +        (ss_plus:SI (match_operand:SI 1 "register_operand" "r")
13181 +                    (match_operand:SI 2 "register_operand" "r")))]
13182 +  "TARGET_DSP"
13183 +  "satadd.w\t%0, %1, %2"
13184 +  [(set_attr "length" "4")
13185 +   (set_attr "cc" "none")
13186 +   (set_attr "type" "alu_sat")])
13187 +
13188 +(define_insn "satsub_w"
13189 +  [(set (match_operand:SI 0 "register_operand" "=r")
13190 +        (ss_minus:SI (match_operand:SI 1 "register_operand" "r")
13191 +                     (match_operand:SI 2 "register_operand" "r")))]
13192 +  "TARGET_DSP"
13193 +  "satsub.w\t%0, %1, %2"
13194 +  [(set_attr "length" "4")
13195 +   (set_attr "cc" "none")
13196 +   (set_attr "type" "alu_sat")])
13197 +
13198 +(define_insn "satadd_h"
13199 +  [(set (match_operand:HI 0 "register_operand" "=r")
13200 +        (ss_plus:HI (match_operand:HI 1 "register_operand" "r")
13201 +                    (match_operand:HI 2 "register_operand" "r")))]
13202 +  "TARGET_DSP"
13203 +  "satadd.h\t%0, %1, %2"
13204 +  [(set_attr "length" "4")
13205 +   (set_attr "cc" "none")
13206 +   (set_attr "type" "alu_sat")])
13207 +
13208 +(define_insn "satsub_h"
13209 +  [(set (match_operand:HI 0 "register_operand" "=r")
13210 +        (ss_minus:HI (match_operand:HI 1 "register_operand" "r")
13211 +                     (match_operand:HI 2 "register_operand" "r")))]
13212 +  "TARGET_DSP"
13213 +  "satsub.h\t%0, %1, %2"
13214 +  [(set_attr "length" "4")
13215 +   (set_attr "cc" "none")
13216 +   (set_attr "type" "alu_sat")])
13217 +
13218 +
13219 +;;=============================================================================
13220 +;; smin
13221 +;;-----------------------------------------------------------------------------
13222 +;; Set reg0 to the smallest value of reg1 and reg2. It is used for signed
13223 +;; values in the registers.
13224 +;;=============================================================================
13225 +(define_insn "sminsi3"
13226 +  [(set (match_operand:SI 0 "register_operand" "=r")
13227 +       (smin:SI (match_operand:SI 1 "register_operand" "r")
13228 +                (match_operand:SI 2 "register_operand" "r")))]
13229 +  ""
13230 +  "min     %0, %1, %2"
13231 +  [(set_attr "length" "4")
13232 +   (set_attr "cc" "none")])
13233 +
13234 +;;=============================================================================
13235 +;; smax
13236 +;;-----------------------------------------------------------------------------
13237 +;; Set reg0 to the largest value of reg1 and reg2. It is used for signed
13238 +;; values in the registers.
13239 +;;=============================================================================
13240 +(define_insn "smaxsi3"
13241 +  [(set (match_operand:SI 0 "register_operand" "=r")
13242 +       (smax:SI (match_operand:SI 1 "register_operand" "r")
13243 +                (match_operand:SI 2 "register_operand" "r")))]
13244 +  ""
13245 +  "max     %0, %1, %2"
13246 +  [(set_attr "length" "4")
13247 +   (set_attr "cc" "none")])
13248 +
13249 +
13250 +
13251 +;;=============================================================================
13252 +;; Logical operations
13253 +;;-----------------------------------------------------------------------------
13254 +
13255 +
13256 +;; Split up simple DImode logical operations.  Simply perform the logical
13257 +;; operation on the upper and lower halves of the registers.
13258 +(define_split
13259 +  [(set (match_operand:DI 0 "register_operand" "")
13260 +       (match_operator:DI 6 "logical_binary_operator"
13261 +         [(match_operand:DI 1 "register_operand" "")
13262 +          (match_operand:DI 2 "register_operand" "")]))]
13263 +  "reload_completed"
13264 +  [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)]))
13265 +   (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))]
13266 +  "
13267 +  {
13268 +    operands[3] = gen_highpart (SImode, operands[0]);
13269 +    operands[0] = gen_lowpart (SImode, operands[0]);
13270 +    operands[4] = gen_highpart (SImode, operands[1]);
13271 +    operands[1] = gen_lowpart (SImode, operands[1]);
13272 +    operands[5] = gen_highpart (SImode, operands[2]);
13273 +    operands[2] = gen_lowpart (SImode, operands[2]);
13274 +  }"
13275 +)
13276 +
13277 +;;=============================================================================
13278 +;; Logical operations with shifted operand
13279 +;;=============================================================================
13280 +(define_insn "<code>si_lshift"
13281 +  [(set (match_operand:SI 0 "register_operand" "=r")
13282 +        (logical:SI (match_operator:SI 4 "logical_shift_operator"
13283 +                                       [(match_operand:SI 2 "register_operand" "r")
13284 +                                        (match_operand:SI 3 "immediate_operand" "Ku05")])
13285 +                    (match_operand:SI 1 "register_operand" "r")))]
13286 +  ""
13287 +  {
13288 +   if ( GET_CODE(operands[4]) == ASHIFT )
13289 +      return "<logical_insn>\t%0, %1, %2 << %3";
13290 +   else
13291 +      return "<logical_insn>\t%0, %1, %2 >> %3";
13292 +      }
13293 +
13294 +  [(set_attr "cc" "set_z")]
13295 +)
13296 +
13297 +
13298 +;;************************************************
13299 +;; Peepholes for detecting logical operantions
13300 +;; with shifted operands
13301 +;;************************************************
13302 +
13303 +(define_peephole
13304 +  [(set (match_operand:SI 3 "register_operand" "")
13305 +        (match_operator:SI 5 "logical_shift_operator"
13306 +                           [(match_operand:SI 1 "register_operand" "")
13307 +                            (match_operand:SI 2 "immediate_operand" "")]))
13308 +   (set (match_operand:SI 0 "register_operand" "")
13309 +        (logical:SI (match_operand:SI 4 "register_operand" "")
13310 +                    (match_dup 3)))]
13311 +  "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))"
13312 +  {
13313 +   if ( GET_CODE(operands[5]) == ASHIFT )
13314 +      return "<logical_insn>\t%0, %4, %1 << %2";
13315 +   else
13316 +      return "<logical_insn>\t%0, %4, %1 >> %2";
13317 +  }
13318 +  [(set_attr "cc" "set_z")]
13319 +  )
13320 +
13321 +(define_peephole
13322 +  [(set (match_operand:SI 3 "register_operand" "")
13323 +        (match_operator:SI 5 "logical_shift_operator"
13324 +                           [(match_operand:SI 1 "register_operand" "")
13325 +                            (match_operand:SI 2 "immediate_operand" "")]))
13326 +   (set (match_operand:SI 0 "register_operand" "")
13327 +        (logical:SI (match_dup 3)
13328 +                    (match_operand:SI 4 "register_operand" "")))]
13329 +  "(dead_or_set_p(insn, operands[3])) || (REGNO(operands[3]) == REGNO(operands[0]))"
13330 +  {
13331 +   if ( GET_CODE(operands[5]) == ASHIFT )
13332 +      return "<logical_insn>\t%0, %4, %1 << %2";
13333 +   else
13334 +      return "<logical_insn>\t%0, %4, %1 >> %2";
13335 +  }
13336 +  [(set_attr "cc" "set_z")]
13337 +  )
13338 +
13339 +
13340 +(define_peephole2
13341 +  [(set (match_operand:SI 0 "register_operand" "")
13342 +        (match_operator:SI 5 "logical_shift_operator"
13343 +                           [(match_operand:SI 1 "register_operand" "")
13344 +                            (match_operand:SI 2 "immediate_operand" "")]))
13345 +   (set (match_operand:SI 3 "register_operand" "")
13346 +        (logical:SI (match_operand:SI 4 "register_operand" "")
13347 +                    (match_dup 0)))]
13348 +  "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))"
13349 +
13350 +  [(set (match_dup 3)
13351 +        (logical:SI  (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)])
13352 +                     (match_dup 4)))]
13353 +
13354 +  ""
13355 +)
13356 +
13357 +(define_peephole2
13358 +  [(set (match_operand:SI 0 "register_operand" "")
13359 +        (match_operator:SI 5 "logical_shift_operator"
13360 +                           [(match_operand:SI 1 "register_operand" "")
13361 +                            (match_operand:SI 2 "immediate_operand" "")]))
13362 +   (set (match_operand:SI 3 "register_operand" "")
13363 +        (logical:SI (match_dup 0)
13364 +                    (match_operand:SI 4 "register_operand" "")))]
13365 +  "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[3]) == REGNO(operands[0]))"
13366 +
13367 +  [(set (match_dup 3)
13368 +        (logical:SI (match_op_dup:SI 5 [(match_dup 1) (match_dup 2)])
13369 +                    (match_dup 4)))]
13370 +
13371 +  ""
13372 +)
13373 +
13374 +
13375 +;;=============================================================================
13376 +;; and
13377 +;;-----------------------------------------------------------------------------
13378 +;; Store the result after a bitwise logical-and between reg0 and reg2 in reg0.
13379 +;;=============================================================================
13380 +
13381 +(define_insn "andnsi"
13382 +  [(set (match_operand:SI 0 "register_operand" "+r")
13383 +        (and:SI (match_dup 0)
13384 +                (not:SI (match_operand:SI 1 "register_operand" "r"))))]
13385 +  ""
13386 +  "andn    %0, %1"
13387 +  [(set_attr "cc" "set_z")
13388 +   (set_attr "length" "2")]
13389 +)
13390 +
13391 +
13392 +(define_insn "andsi3"
13393 +   [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand"          "=Y,r,r,r,   r,   r,r,r,r,r")
13394 +       (and:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand"  "%0,r,0,0,   0,   0,0,0,0,r" )
13395 +               (match_operand:SI 2 "nonmemory_operand"                     " N,M,N,Ku16,Ks17,J,L,r,i,r")))]
13396 +  ""
13397 +   "@
13398 +    memc\t%0, %z2
13399 +    bfextu\t%0, %1, 0, %z2
13400 +    cbr\t%0, %z2
13401 +    andl\t%0, %2, COH
13402 +    andl\t%0, lo(%2)
13403 +    andh\t%0, hi(%2), COH
13404 +    andh\t%0, hi(%2)
13405 +    and\t%0, %2
13406 +    andh\t%0, hi(%2)\;andl\t%0, lo(%2)
13407 +    and\t%0, %1, %2"
13408 +
13409 +   [(set_attr "length" "4,4,2,4,4,4,4,2,8,4")
13410 +    (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z,set_z")])
13411 +
13412 +  
13413 +
13414 +(define_insn "anddi3"
13415 +  [(set (match_operand:DI 0 "register_operand" "=&r,&r")
13416 +       (and:DI (match_operand:DI 1 "register_operand" "%0,r")
13417 +                (match_operand:DI 2 "register_operand" "r,r")))]
13418 +  ""
13419 +  "#"
13420 +  [(set_attr "length" "8")
13421 +   (set_attr "cc" "clobber")]
13422 +)
13423 +
13424 +;;=============================================================================
13425 +;; or
13426 +;;-----------------------------------------------------------------------------
13427 +;; Store the result after a bitwise inclusive-or between reg0 and reg2 in reg0.
13428 +;;=============================================================================
13429 +
13430 +(define_insn "iorsi3"
13431 +  [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand"          "=Y,r,r,   r,r,r,r")
13432 +       (ior:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand"  "%0,0,0,   0,0,0,r" )
13433 +               (match_operand:SI 2 "nonmemory_operand"                     " O,O,Ku16,J,r,i,r")))]
13434 +  ""
13435 +  "@
13436 +   mems\t%0, %p2
13437 +   sbr\t%0, %p2
13438 +   orl\t%0, %2
13439 +   orh\t%0, hi(%2)
13440 +   or\t%0, %2
13441 +   orh\t%0, hi(%2)\;orl\t%0, lo(%2)
13442 +   or\t%0, %1, %2"
13443 +
13444 +  [(set_attr "length" "4,2,4,4,2,8,4")
13445 +   (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z,set_z")])
13446 +
13447 +
13448 +(define_insn "iordi3"
13449 +  [(set (match_operand:DI 0 "register_operand" "=&r,&r")
13450 +       (ior:DI (match_operand:DI 1 "register_operand" "%0,r")
13451 +                (match_operand:DI 2 "register_operand" "r,r")))]
13452 +  ""
13453 +  "#"
13454 +  [(set_attr "length" "8")
13455 +   (set_attr "cc" "clobber")]
13456 +)
13457 +
13458 +;;=============================================================================
13459 +;; xor bytes
13460 +;;-----------------------------------------------------------------------------
13461 +;; Store the result after a bitwise exclusive-or between reg0 and reg2 in reg0.
13462 +;;=============================================================================
13463 +
13464 +(define_insn "xorsi3"
13465 +   [(set (match_operand:SI 0 "avr32_rmw_memory_or_register_operand"          "=Y,r,   r,r,r,r")
13466 +       (xor:SI (match_operand:SI 1 "avr32_rmw_memory_or_register_operand"  "%0,0,   0,0,0,r" )
13467 +               (match_operand:SI 2 "nonmemory_operand"                     " O,Ku16,J,r,i,r")))]
13468 +  ""
13469 +   "@
13470 +    memt\t%0, %p2
13471 +    eorl\t%0, %2
13472 +    eorh\t%0, hi(%2)
13473 +    eor\t%0, %2
13474 +    eorh\t%0, hi(%2)\;eorl\t%0, lo(%2)
13475 +    eor\t%0, %1, %2"
13476 +
13477 +   [(set_attr "length" "4,4,4,2,8,4")
13478 +    (set_attr "cc" "none,set_z,set_z,set_z,set_z,set_z")])
13479 +
13480 +(define_insn "xordi3"
13481 +  [(set (match_operand:DI 0 "register_operand" "=&r,&r")
13482 +       (xor:DI (match_operand:DI 1 "register_operand" "%0,r")
13483 +                (match_operand:DI 2 "register_operand" "r,r")))]
13484 +  ""
13485 +  "#"
13486 +  [(set_attr "length" "8")
13487 +   (set_attr "cc" "clobber")]
13488 +)
13489 +
13490 +;;=============================================================================
13491 +;; Three operand predicable insns
13492 +;;=============================================================================
13493 +
13494 +(define_insn "<predicable_insn3><mode>_predicable"
13495 +  [(set (match_operand:INTM 0 "register_operand" "=r")
13496 +       (predicable_op3:INTM (match_operand:INTM 1 "register_operand" "<predicable_commutative3>r")
13497 +                             (match_operand:INTM 2 "register_operand" "r")))]
13498 +  "TARGET_V2_INSNS"
13499 +  "<predicable_insn3>%?\t%0, %1, %2"
13500 +  [(set_attr "length" "4")
13501 +   (set_attr "cc" "cmp_cond_insn")
13502 +   (set_attr "predicable" "yes")]
13503 +)
13504 +
13505 +(define_insn_and_split "<predicable_insn3><mode>_imm_clobber_predicable"
13506 +  [(parallel 
13507 +    [(set (match_operand:INTM 0 "register_operand" "=r")
13508 +          (predicable_op3:INTM (match_operand:INTM 1 "register_operand" "<predicable_commutative3>r")
13509 +                               (match_operand:INTM 2 "avr32_mov_immediate_operand" "JKs21")))
13510 +     (clobber (match_operand:INTM 3 "register_operand" "=&r"))])]
13511 +  "TARGET_V2_INSNS"
13512 +  {
13513 +   if ( current_insn_predicate != NULL_RTX ) 
13514 +      {
13515 +       if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08") )
13516 +          return "%! mov%?\t%3, %2\;<predicable_insn3>%?\t%0, %1, %3";
13517 +       else if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21") )
13518 +          return "%! mov\t%3, %2\;<predicable_insn3>%?\t%0, %1, %3";
13519 +       else
13520 +          return "%! movh\t%3, hi(%2)\;<predicable_insn3>%?\t%0, %1, %3";
13521 +       }
13522 +   else
13523 +      {
13524 +       if ( !avr32_cond_imm_clobber_splittable (insn, operands) )
13525 +          {
13526 +                if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks08") )
13527 +                   return "mov%?\t%3, %2\;<predicable_insn3>%?\t%0, %1, %3";
13528 +                else if ( avr32_const_ok_for_constraint_p (INTVAL (operands[2]), 'K', "Ks21") )
13529 +                   return "mov\t%3, %2\;<predicable_insn3>%?\t%0, %1, %3";
13530 +                else
13531 +                   return "movh\t%3, hi(%2)\;<predicable_insn3>%?\t%0, %1, %3";
13532 +          }
13533 +       return "#";
13534 +      }
13535 +      
13536 +  }
13537 +  ;; If we find out that we could not actually do if-conversion on the block
13538 +  ;; containing this insn we convert it back to normal immediate format
13539 +  ;; to avoid outputing a redundant move insn
13540 +  ;; Do not split until after we have checked if we can make the insn 
13541 +  ;; conditional.
13542 +  "(GET_CODE (PATTERN (insn)) != COND_EXEC
13543 +    && cfun->machine->ifcvt_after_reload
13544 +    && avr32_cond_imm_clobber_splittable (insn, operands))"
13545 +  [(set (match_dup 0)
13546 +        (predicable_op3:INTM (match_dup 1)
13547 +                             (match_dup 2)))]
13548 +  ""
13549 +  [(set_attr "length" "8")
13550 +   (set_attr "cc" "cmp_cond_insn")
13551 +   (set_attr "predicable" "yes")]
13552 +  )
13553 +
13554 +
13555 +;;=============================================================================
13556 +;; Zero extend predicable insns
13557 +;;=============================================================================
13558 +(define_insn_and_split "zero_extendhisi_clobber_predicable"
13559 +  [(parallel 
13560 +    [(set (match_operand:SI 0 "register_operand" "=r")
13561 +          (zero_extend:SI (match_operand:HI 1 "register_operand" "r")))
13562 +     (clobber (match_operand:SI 2 "register_operand" "=&r"))])]
13563 +  "TARGET_V2_INSNS"
13564 +  {
13565 +   if ( current_insn_predicate != NULL_RTX ) 
13566 +      {
13567 +         return "%! mov\t%2, 0xffff\;and%?\t%0, %1, %2";
13568 +       }
13569 +   else
13570 +      {
13571 +       return "#";
13572 +      }
13573 +      
13574 +  }
13575 +  ;; If we find out that we could not actually do if-conversion on the block
13576 +  ;; containing this insn we convert it back to normal immediate format
13577 +  ;; to avoid outputing a redundant move insn
13578 +  ;; Do not split until after we have checked if we can make the insn 
13579 +  ;; conditional.
13580 +  "(GET_CODE (PATTERN (insn)) != COND_EXEC
13581 +    && cfun->machine->ifcvt_after_reload)"
13582 +  [(set (match_dup 0)
13583 +        (zero_extend:SI (match_dup 1)))]
13584 +  ""
13585 +  [(set_attr "length" "8")
13586 +   (set_attr "cc" "cmp_cond_insn")
13587 +   (set_attr "predicable" "yes")]
13588 +  )
13589 +
13590 +(define_insn_and_split "zero_extendqisi_clobber_predicable"
13591 +  [(parallel 
13592 +    [(set (match_operand:SI 0 "register_operand" "=r")
13593 +          (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))
13594 +     (clobber (match_operand:SI 2 "register_operand" "=&r"))])]
13595 +  "TARGET_V2_INSNS"
13596 +  {
13597 +   if ( current_insn_predicate != NULL_RTX ) 
13598 +      {
13599 +         return "%! mov\t%2, 0xff\;and%?\t%0, %1, %2";
13600 +       }
13601 +   else
13602 +      {
13603 +       return "#";
13604 +      }
13605 +      
13606 +  }
13607 +  ;; If we find out that we could not actually do if-conversion on the block
13608 +  ;; containing this insn we convert it back to normal immediate format
13609 +  ;; to avoid outputing a redundant move insn
13610 +  ;; Do not split until after we have checked if we can make the insn 
13611 +  ;; conditional.
13612 +  "(GET_CODE (PATTERN (insn)) != COND_EXEC
13613 +    && cfun->machine->ifcvt_after_reload)"
13614 +  [(set (match_dup 0)
13615 +        (zero_extend:SI (match_dup 1)))]
13616 +  ""
13617 +  [(set_attr "length" "8")
13618 +   (set_attr "cc" "cmp_cond_insn")
13619 +   (set_attr "predicable" "yes")]
13620 +  )
13621 +
13622 +(define_insn_and_split "zero_extendqihi_clobber_predicable"
13623 +  [(parallel 
13624 +    [(set (match_operand:HI 0 "register_operand" "=r")
13625 +          (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))
13626 +     (clobber (match_operand:SI 2 "register_operand" "=&r"))])]
13627 +  "TARGET_V2_INSNS"
13628 +  {
13629 +   if ( current_insn_predicate != NULL_RTX ) 
13630 +      {
13631 +         return "%! mov\t%2, 0xff\;and%?\t%0, %1, %2";
13632 +       }
13633 +   else
13634 +      {
13635 +       return "#";
13636 +      }
13637 +      
13638 +  }
13639 +  ;; If we find out that we could not actually do if-conversion on the block
13640 +  ;; containing this insn we convert it back to normal immediate format
13641 +  ;; to avoid outputing a redundant move insn
13642 +  ;; Do not split until after we have checked if we can make the insn 
13643 +  ;; conditional.
13644 +  "(GET_CODE (PATTERN (insn)) != COND_EXEC
13645 +    && cfun->machine->ifcvt_after_reload)"
13646 +  [(set (match_dup 0)
13647 +        (zero_extend:HI (match_dup 1)))]
13648 +  ""
13649 +  [(set_attr "length" "8")
13650 +   (set_attr "cc" "cmp_cond_insn")
13651 +   (set_attr "predicable" "yes")]
13652 +  )
13653 +;;=============================================================================
13654 +;; divmod
13655 +;;-----------------------------------------------------------------------------
13656 +;; Signed division that produces both a quotient and a remainder.
13657 +;;=============================================================================
13658 +
13659 +(define_expand "divmodsi4"
13660 +  [(parallel [
13661 +     (parallel [
13662 +       (set (match_operand:SI 0 "register_operand" "=r")
13663 +           (div:SI (match_operand:SI 1 "register_operand" "r")
13664 +                   (match_operand:SI 2 "register_operand" "r")))
13665 +       (set (match_operand:SI 3 "register_operand" "=r")
13666 +           (mod:SI (match_dup 1)
13667 +                   (match_dup 2)))])
13668 +     (use (match_dup 4))])]
13669 +  ""
13670 +  {
13671 +    if (can_create_pseudo_p ()) {
13672 +      operands[4] = gen_reg_rtx (DImode);
13673 +      emit_insn(gen_divmodsi4_internal(operands[4],operands[1],operands[2]));
13674 +      emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4));
13675 +      emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0));
13676 +      DONE;
13677 +    } else {
13678 +      FAIL;
13679 +    }
13680 +  })
13681 +
13682 +
13683 +(define_insn "divmodsi4_internal"
13684 +  [(set (match_operand:DI 0 "register_operand" "=r")
13685 +       (unspec:DI [(match_operand:SI 1 "register_operand" "r")
13686 +                   (match_operand:SI 2 "register_operand" "r")]
13687 +                  UNSPEC_DIVMODSI4_INTERNAL))]
13688 +  ""
13689 +  "divs    %0, %1, %2"
13690 +  [(set_attr "type" "div")
13691 +   (set_attr "cc" "none")])
13692 +
13693 +
13694 +;;=============================================================================
13695 +;; udivmod
13696 +;;-----------------------------------------------------------------------------
13697 +;; Unsigned division that produces both a quotient and a remainder.
13698 +;;=============================================================================
13699 +(define_expand "udivmodsi4"
13700 + [(parallel [
13701 +    (parallel [
13702 +      (set (match_operand:SI 0 "register_operand" "=r")
13703 +          (udiv:SI (match_operand:SI 1 "register_operand" "r")
13704 +                   (match_operand:SI 2 "register_operand" "r")))
13705 +      (set (match_operand:SI 3 "register_operand" "=r")
13706 +          (umod:SI (match_dup 1)
13707 +                   (match_dup 2)))])
13708 +    (use (match_dup 4))])]
13709 +  ""
13710 +  {
13711 +    if (can_create_pseudo_p ()) {
13712 +      operands[4] = gen_reg_rtx (DImode);
13713 +
13714 +      emit_insn(gen_udivmodsi4_internal(operands[4],operands[1],operands[2]));
13715 +      emit_move_insn(operands[0], gen_rtx_SUBREG( SImode, operands[4], 4));
13716 +      emit_move_insn(operands[3], gen_rtx_SUBREG( SImode, operands[4], 0));
13717 +
13718 +      DONE;
13719 +    } else {
13720 +      FAIL;
13721 +    }
13722 +  })
13723 +
13724 +(define_insn "udivmodsi4_internal"
13725 +  [(set (match_operand:DI 0 "register_operand" "=r")
13726 +       (unspec:DI [(match_operand:SI 1 "register_operand" "r")
13727 +                   (match_operand:SI 2 "register_operand" "r")]
13728 +                  UNSPEC_UDIVMODSI4_INTERNAL))]
13729 +  ""
13730 +  "divu    %0, %1, %2"
13731 +  [(set_attr "type" "div")
13732 +   (set_attr "cc" "none")])
13733 +
13734 +
13735 +;;=============================================================================
13736 +;; Arithmetic-shift left
13737 +;;-----------------------------------------------------------------------------
13738 +;; Arithmetic-shift reg0 left by reg2 or immediate value.
13739 +;;=============================================================================
13740 +
13741 +(define_insn "ashlsi3"
13742 +  [(set (match_operand:SI 0 "register_operand"                      "=r,r,r")
13743 +       (ashift:SI (match_operand:SI 1 "register_operand"           "r,0,r")
13744 +                  (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))]
13745 +  ""
13746 +  "@
13747 +   lsl     %0, %1, %2
13748 +   lsl     %0, %2
13749 +   lsl     %0, %1, %2"
13750 +  [(set_attr "length" "4,2,4")
13751 +   (set_attr "cc" "set_ncz")])
13752 +
13753 +;;=============================================================================
13754 +;; Arithmetic-shift right
13755 +;;-----------------------------------------------------------------------------
13756 +;; Arithmetic-shift reg0 right by an immediate value.
13757 +;;=============================================================================
13758 +
13759 +(define_insn "ashrsi3"
13760 +  [(set (match_operand:SI 0 "register_operand"                        "=r,r,r")
13761 +       (ashiftrt:SI (match_operand:SI 1 "register_operand"           "r,0,r")
13762 +                    (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))]
13763 +  ""
13764 +  "@
13765 +   asr     %0, %1, %2
13766 +   asr     %0, %2
13767 +   asr     %0, %1, %2"
13768 +  [(set_attr "length" "4,2,4")
13769 +   (set_attr "cc" "set_ncz")])
13770 +
13771 +;;=============================================================================
13772 +;; Logical shift right
13773 +;;-----------------------------------------------------------------------------
13774 +;; Logical shift reg0 right by an immediate value.
13775 +;;=============================================================================
13776 +
13777 +(define_insn "lshrsi3"
13778 +  [(set (match_operand:SI 0 "register_operand"                        "=r,r,r")
13779 +       (lshiftrt:SI (match_operand:SI 1 "register_operand"           "r,0,r")
13780 +                    (match_operand:SI 2 "register_const_int_operand" "r,Ku05,Ku05")))]
13781 +  ""
13782 +  "@
13783 +   lsr     %0, %1, %2
13784 +   lsr     %0, %2
13785 +   lsr     %0, %1, %2"
13786 +  [(set_attr "length" "4,2,4")
13787 +   (set_attr "cc" "set_ncz")])
13788 +
13789 +
13790 +;;=============================================================================
13791 +;; neg
13792 +;;-----------------------------------------------------------------------------
13793 +;; Negate operand 1 and store the result in operand 0.
13794 +;;=============================================================================
13795 +(define_insn "negsi2"
13796 +  [(set (match_operand:SI 0 "register_operand" "=r,r")
13797 +       (neg:SI (match_operand:SI 1 "register_operand" "0,r")))]
13798 +  ""
13799 +  "@
13800 +   neg\t%0
13801 +   rsub\t%0, %1, 0"
13802 +  [(set_attr "length" "2,4")
13803 +   (set_attr "cc" "set_vncz")])
13804 +
13805 +(define_insn "negsi2_predicable"
13806 +  [(set (match_operand:SI 0 "register_operand" "+r")
13807 +       (neg:SI (match_dup 0)))]
13808 +  "TARGET_V2_INSNS"
13809 +  "rsub%?\t%0, 0"
13810 +  [(set_attr "length" "4")
13811 +   (set_attr "cc" "cmp_cond_insn")
13812 +   (set_attr "predicable" "yes")])
13813 +
13814 +;;=============================================================================
13815 +;; abs
13816 +;;-----------------------------------------------------------------------------
13817 +;; Store the absolute value of operand 1 into operand 0.
13818 +;;=============================================================================
13819 +(define_insn "abssi2"
13820 +  [(set (match_operand:SI 0 "register_operand" "=r")
13821 +       (abs:SI (match_operand:SI 1 "register_operand" "0")))]
13822 +  ""
13823 +  "abs\t%0"
13824 +  [(set_attr "length" "2")
13825 +   (set_attr "cc" "set_z")])
13826 +
13827 +
13828 +;;=============================================================================
13829 +;; one_cmpl
13830 +;;-----------------------------------------------------------------------------
13831 +;; Store the bitwise-complement of operand 1 into operand 0.
13832 +;;=============================================================================
13833 +
13834 +(define_insn "one_cmplsi2"
13835 +  [(set (match_operand:SI 0 "register_operand" "=r,r")
13836 +       (not:SI (match_operand:SI 1 "register_operand" "0,r")))]
13837 +  ""
13838 +  "@
13839 +   com\t%0
13840 +   rsub\t%0, %1, -1"
13841 +  [(set_attr "length" "2,4")
13842 +   (set_attr "cc" "set_z")])
13843 +
13844 +
13845 +(define_insn "one_cmplsi2_predicable"
13846 +  [(set (match_operand:SI 0 "register_operand" "+r")
13847 +       (not:SI (match_dup 0)))]
13848 +  "TARGET_V2_INSNS"
13849 +  "rsub%?\t%0, -1"
13850 +  [(set_attr "length" "4")
13851 +   (set_attr "cc" "cmp_cond_insn")
13852 +   (set_attr "predicable" "yes")])
13853 +
13854 +
13855 +;;=============================================================================
13856 +;; Bit load
13857 +;;-----------------------------------------------------------------------------
13858 +;; Load a bit into Z and C flags
13859 +;;=============================================================================
13860 +(define_insn "bldsi"
13861 +  [(set (cc0)
13862 +        (and:SI (match_operand:SI 0 "register_operand" "r")
13863 +                (match_operand:SI 1 "one_bit_set_operand" "i")))]
13864 +  ""
13865 +  "bld\t%0, %p1"
13866 +  [(set_attr "length" "4")
13867 +   (set_attr "cc" "bld")]
13868 +  )
13869 +
13870 +
13871 +;;=============================================================================
13872 +;; Compare
13873 +;;-----------------------------------------------------------------------------
13874 +;; Compare reg0 with reg1 or an immediate value.
13875 +;;=============================================================================
13876 +
13877 +(define_expand "cmp<mode>"
13878 +  [(set (cc0)
13879 +       (compare:CMP
13880 +        (match_operand:CMP 0 "register_operand" "")
13881 +        (match_operand:CMP 1 "<CMP:cmp_predicate>"  "")))]
13882 +  ""
13883 +  "{
13884 +   avr32_compare_op0 = operands[0];
13885 +   avr32_compare_op1 = operands[1];
13886 +  }"
13887 +)
13888 +
13889 +(define_insn "cmp<mode>_internal"
13890 +  [(set (cc0)
13891 +        (compare:CMP
13892 +         (match_operand:CMP 0 "register_operand" "r")
13893 +         (match_operand:CMP 1 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>")))]
13894 +  ""
13895 +  {
13896 +switch(GET_MODE(operands[0]))
13897 +  {
13898 +  case QImode:
13899 +       avr32_branch_type = CMP_QI;
13900 +       break;
13901 +  case HImode:
13902 +       avr32_branch_type = CMP_HI;
13903 +       break;
13904 +  case SImode:
13905 +       avr32_branch_type = CMP_SI;
13906 +       break;
13907 +  case DImode:
13908 +       avr32_branch_type = CMP_DI;
13909 +       break;
13910 +  default:
13911 +       abort();
13912 +  }
13913 +   /* Check if the next insn already will output a compare. */
13914 +   if (!next_insn_emits_cmp (insn))  
13915 +     set_next_insn_cond(insn,
13916 +                        avr32_output_cmp(get_next_insn_cond(insn), GET_MODE (operands[0]), operands[0], operands[1]));
13917 +   return "";
13918 +  }
13919 +  [(set_attr "length" "4")
13920 +   (set_attr "cc" "compare")])
13921 +
13922 +(define_expand "cmpsf"
13923 +  [(set (cc0)
13924 +       (compare:SF
13925 +        (match_operand:SF 0 "general_operand" "")
13926 +        (match_operand:SF 1 "general_operand"  "")))]
13927 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
13928 +  "{
13929 +   if ( !REG_P(operands[0]) )
13930 +     operands[0] = force_reg(SFmode, operands[0]);
13931 +
13932 +   if ( !REG_P(operands[1]) )
13933 +     operands[1] = force_reg(SFmode, operands[1]);
13934 +
13935 +   avr32_compare_op0 = operands[0];
13936 +   avr32_compare_op1 = operands[1];
13937 +   emit_insn(gen_cmpsf_internal_uc3fp(operands[0], operands[1]));
13938 +   DONE;
13939 +  }"
13940 +)
13941 +
13942 +;;;=============================================================================
13943 +;; Test if zero
13944 +;;-----------------------------------------------------------------------------
13945 +;; Compare reg against zero and set the condition codes.
13946 +;;=============================================================================
13947 +
13948 +
13949 +(define_expand "tstsi"
13950 +  [(set (cc0)
13951 +       (match_operand:SI 0 "register_operand" ""))]
13952 +  ""
13953 +  {
13954 +   avr32_compare_op0 = operands[0];
13955 +   avr32_compare_op1 = const0_rtx;
13956 +  }
13957 +)
13958 +
13959 +(define_insn "tstsi_internal"
13960 +  [(set (cc0)
13961 +       (match_operand:SI 0 "register_operand" "r"))]
13962 +  ""
13963 +  {
13964 +   /* Check if the next insn already will output a compare. */
13965 +   if (!next_insn_emits_cmp (insn))  
13966 +     set_next_insn_cond(insn,
13967 +                        avr32_output_cmp(get_next_insn_cond(insn), SImode, operands[0], const0_rtx));
13968 +
13969 +   return "";
13970 +  }
13971 +  [(set_attr "length" "2")
13972 +   (set_attr "cc" "compare")])
13973 +
13974 +
13975 +(define_expand "tstdi"
13976 +  [(set (cc0)
13977 +       (match_operand:DI 0 "register_operand" ""))]
13978 +  ""
13979 +  {
13980 +   avr32_compare_op0 = operands[0];
13981 +   avr32_compare_op1 = const0_rtx;
13982 +  }
13983 +)
13984 +
13985 +(define_insn "tstdi_internal"
13986 +  [(set (cc0)
13987 +       (match_operand:DI 0 "register_operand" "r"))]
13988 +  ""
13989 +  {
13990 +   /* Check if the next insn already will output a compare. */
13991 +   if (!next_insn_emits_cmp (insn))  
13992 +     set_next_insn_cond(insn,
13993 +                        avr32_output_cmp(get_next_insn_cond(insn), DImode, operands[0], const0_rtx));
13994 +   return "";
13995 +  }
13996 +  [(set_attr "length" "4")
13997 +   (set_attr "type" "alu2")
13998 +   (set_attr "cc" "compare")])
13999 +
14000 +
14001 +
14002 +;;=============================================================================
14003 +;; Convert operands
14004 +;;-----------------------------------------------------------------------------
14005 +;;
14006 +;;=============================================================================
14007 +(define_insn "truncdisi2"
14008 +  [(set (match_operand:SI 0 "general_operand" "")
14009 +       (truncate:SI (match_operand:DI 1 "general_operand" "")))]
14010 +  ""
14011 +  "truncdisi2")
14012 +
14013 +;;=============================================================================
14014 +;; Extend
14015 +;;-----------------------------------------------------------------------------
14016 +;;
14017 +;;=============================================================================
14018 +
14019 +
14020 +(define_insn "extendhisi2"
14021 +  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
14022 +       (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
14023 +  ""
14024 +  {
14025 +   switch ( which_alternative ){
14026 +     case 0:
14027 +       return    "casts.h\t%0";
14028 +     case 1:
14029 +       return    "bfexts\t%0, %1, 0, 16";
14030 +     case 2:
14031 +     case 3:
14032 +       return    "ld.sh\t%0, %1";
14033 +     default:
14034 +       abort();
14035 +   }
14036 +  }
14037 +  [(set_attr "length" "2,4,2,4")
14038 +   (set_attr "cc" "set_ncz,set_ncz,none,none")
14039 +   (set_attr "type" "alu,alu,load_rm,load_rm")])
14040 +
14041 +(define_insn "extendqisi2"
14042 +  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
14043 +       (sign_extend:SI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))]
14044 +  ""
14045 +  {
14046 +   switch ( which_alternative ){
14047 +     case 0:
14048 +       return    "casts.b\t%0";
14049 +     case 1:
14050 +       return    "bfexts\t%0, %1, 0, 8";
14051 +     case 2:
14052 +     case 3:
14053 +       return    "ld.sb\t%0, %1";
14054 +     default:
14055 +       abort();
14056 +   }
14057 +  }
14058 +  [(set_attr "length" "2,4,2,4")
14059 +   (set_attr "cc" "set_ncz,set_ncz,none,none")
14060 +   (set_attr "type" "alu,alu,load_rm,load_rm")])
14061 +
14062 +(define_insn "extendqihi2"
14063 +  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
14064 +       (sign_extend:HI (match_operand:QI 1 "extendqi_operand" "0,r,RKu00,m")))]
14065 +  ""
14066 +  {
14067 +   switch ( which_alternative ){
14068 +     case 0:
14069 +       return    "casts.b\t%0";
14070 +     case 1:
14071 +       return    "bfexts\t%0, %1, 0, 8";
14072 +     case 2:
14073 +     case 3:
14074 +       return    "ld.sb\t%0, %1";
14075 +     default:
14076 +       abort();
14077 +   }
14078 +  }
14079 +  [(set_attr "length" "2,4,2,4")
14080 +   (set_attr "cc" "set_ncz,set_ncz,none,none")
14081 +   (set_attr "type" "alu,alu,load_rm,load_rm")])
14082 +
14083 +
14084 +;;=============================================================================
14085 +;; Zero-extend
14086 +;;-----------------------------------------------------------------------------
14087 +;;
14088 +;;=============================================================================
14089 +
14090 +(define_insn "zero_extendhisi2"
14091 +  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
14092 +       (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
14093 +  ""
14094 +  {
14095 +   switch ( which_alternative ){
14096 +     case 0:
14097 +       return    "castu.h\t%0";
14098 +     case 1:
14099 +       return    "bfextu\t%0, %1, 0, 16";
14100 +     case 2:
14101 +     case 3:
14102 +       return    "ld.uh\t%0, %1";
14103 +     default:
14104 +       abort();
14105 +   }
14106 +  }
14107 +
14108 +  [(set_attr "length" "2,4,2,4")
14109 +   (set_attr "cc" "set_ncz,set_ncz,none,none")
14110 +   (set_attr "type" "alu,alu,load_rm,load_rm")])
14111 +
14112 +(define_insn "zero_extendqisi2"
14113 +  [(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
14114 +       (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
14115 +  ""
14116 +  {
14117 +   switch ( which_alternative ){
14118 +     case 0:
14119 +       return    "castu.b\t%0";
14120 +     case 1:
14121 +       return    "bfextu\t%0, %1, 0, 8";
14122 +     case 2:
14123 +     case 3:
14124 +       return    "ld.ub\t%0, %1";
14125 +     default:
14126 +       abort();
14127 +   }
14128 +  }
14129 +  [(set_attr "length" "2,4,2,4")
14130 +   (set_attr "cc" "set_ncz, set_ncz, none, none")
14131 +   (set_attr "type" "alu, alu, load_rm, load_rm")])
14132 +
14133 +(define_insn "zero_extendqihi2"
14134 +  [(set (match_operand:HI 0 "register_operand" "=r,r,r,r")
14135 +       (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,r,<RKu00>,m")))]
14136 +  ""
14137 +  {
14138 +   switch ( which_alternative ){
14139 +     case 0:
14140 +       return    "castu.b\t%0";
14141 +     case 1:
14142 +       return    "bfextu\t%0, %1, 0, 8";
14143 +     case 2:
14144 +     case 3:
14145 +       return    "ld.ub\t%0, %1";
14146 +     default:
14147 +       abort();
14148 +   }
14149 +  }
14150 +  [(set_attr "length" "2,4,2,4")
14151 +   (set_attr "cc" "set_ncz, set_ncz, none, none")
14152 +   (set_attr "type" "alu, alu, load_rm, load_rm")])
14153 +
14154 +
14155 +;;=============================================================================
14156 +;; Conditional load and extend insns
14157 +;;=============================================================================
14158 +(define_insn "ldsi<mode>_predicable_se"
14159 +  [(set (match_operand:SI 0 "register_operand" "=r")
14160 +        (sign_extend:SI 
14161 +         (match_operand:INTM 1 "memory_operand" "<INTM:pred_mem_constraint>")))]
14162 +  "TARGET_V2_INSNS"
14163 +  "ld<INTM:load_postfix_s>%?\t%0, %1"
14164 +  [(set_attr "length" "4")
14165 +   (set_attr "cc" "cmp_cond_insn")
14166 +   (set_attr "type" "load")
14167 +   (set_attr "predicable" "yes")]
14168 +)
14169 +
14170 +(define_insn "ldsi<mode>_predicable_ze"
14171 +  [(set (match_operand:SI 0 "register_operand" "=r")
14172 +        (zero_extend:SI 
14173 +         (match_operand:INTM 1 "memory_operand" "<INTM:pred_mem_constraint>")))]
14174 +  "TARGET_V2_INSNS"
14175 +  "ld<INTM:load_postfix_u>%?\t%0, %1"
14176 +  [(set_attr "length" "4")
14177 +   (set_attr "cc" "cmp_cond_insn")
14178 +   (set_attr "type" "load")
14179 +   (set_attr "predicable" "yes")]
14180 +)
14181 +
14182 +(define_insn "ldhi_predicable_ze"
14183 +  [(set (match_operand:HI 0 "register_operand" "=r")
14184 +        (zero_extend:HI 
14185 +         (match_operand:QI 1 "memory_operand" "RKs10")))]
14186 +  "TARGET_V2_INSNS"
14187 +  "ld.ub%?\t%0, %1"
14188 +  [(set_attr "length" "4")
14189 +   (set_attr "cc" "cmp_cond_insn")
14190 +   (set_attr "type" "load")
14191 +   (set_attr "predicable" "yes")]
14192 +)
14193 +
14194 +(define_insn "ldhi_predicable_se"
14195 +  [(set (match_operand:HI 0 "register_operand" "=r")
14196 +        (sign_extend:HI 
14197 +         (match_operand:QI 1 "memory_operand" "RKs10")))]
14198 +  "TARGET_V2_INSNS"
14199 +  "ld.sb%?\t%0, %1"
14200 +  [(set_attr "length" "4")
14201 +   (set_attr "cc" "cmp_cond_insn")
14202 +   (set_attr "type" "load")
14203 +   (set_attr "predicable" "yes")]
14204 +)
14205 +
14206 +;;=============================================================================
14207 +;; Conditional set register
14208 +;; sr{cond4}  rd
14209 +;;-----------------------------------------------------------------------------
14210 +
14211 +;;Because of the same issue as with conditional moves and adds we must
14212 +;;not separate the compare instrcution from the scc instruction as
14213 +;;they might be sheduled "badly".
14214 +
14215 +(define_expand "s<code>"
14216 +  [(set (match_operand:SI 0 "register_operand" "=r")
14217 +       (any_cond:SI (cc0)
14218 +                     (const_int 0)))]
14219 +""
14220 +{
14221 +  if(TARGET_HARD_FLOAT && TARGET_ARCH_FPU)
14222 +    FAIL;
14223 +})
14224 +
14225 +(define_insn "*s<code>"
14226 +  [(set (match_operand:SI 0 "register_operand" "=r")
14227 +       (any_cond:SI (cc0)
14228 +                     (const_int 0)))]
14229 +  ""
14230 +{
14231 +    return "sr<cond>\t%0";
14232 +}
14233 +[(set_attr "length" "2")
14234 +(set_attr "cc" "none")])
14235 +
14236 +(define_insn "seq"
14237 +[(set (match_operand:SI 0 "register_operand" "=r")
14238 +(eq:SI (cc0)
14239 +                                (const_int 0)))]
14240 +  ""
14241 +"sreq\t%0"
14242 +[(set_attr "length" "2")
14243 +(set_attr "cc" "none")])
14244 +
14245 +(define_insn "sne"
14246 +[(set (match_operand:SI 0 "register_operand" "=r")
14247 +(ne:SI (cc0)
14248 +                                (const_int 0)))]
14249 +  ""
14250 +"srne\t%0"
14251 +  [(set_attr "length" "2")
14252 +   (set_attr "cc" "none")])
14253 +
14254 +(define_insn "smi"
14255 +  [(set (match_operand:SI 0 "register_operand" "=r")
14256 +       (unspec:SI [(cc0)
14257 +                    (const_int 0)] UNSPEC_COND_MI))]
14258 +  ""
14259 +  "srmi\t%0"
14260 +  [(set_attr "length" "2")
14261 +   (set_attr "cc" "none")])
14262 +
14263 +(define_insn "spl"
14264 +  [(set (match_operand:SI 0 "register_operand" "=r")
14265 +       (unspec:SI [(cc0)
14266 +                    (const_int 0)] UNSPEC_COND_PL))]
14267 +  ""
14268 +  "srpl\t%0"
14269 +  [(set_attr "length" "2")
14270 +   (set_attr "cc" "none")])
14271 +
14272 +
14273 +;;=============================================================================
14274 +;; Conditional branch
14275 +;;-----------------------------------------------------------------------------
14276 +;; Branch to label if the specified condition codes are set.
14277 +;;=============================================================================
14278 +; branch if negative
14279 +(define_insn "bmi"
14280 +  [(set (pc)
14281 +       (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI)
14282 +                     (label_ref (match_operand 0 "" ""))
14283 +                     (pc)))]
14284 +  ""
14285 +  "brmi    %0"
14286 +  [(set_attr "type" "branch")
14287 +   (set (attr "length")
14288 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14289 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14290 +              (const_int 2)] ; use compact branch
14291 +              (const_int 4))) ; use extended branch
14292 +   (set_attr "cc" "none")])
14293 +
14294 +(define_insn "*bmi-reverse"
14295 +  [(set (pc)
14296 +       (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_MI)
14297 +                     (pc)
14298 +                     (label_ref (match_operand 0 "" ""))))]
14299 +  ""
14300 +  "brpl    %0"
14301 +  [(set_attr "type" "branch")
14302 +   (set (attr "length")
14303 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14304 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14305 +              (const_int 2)] ; use compact branch
14306 +              (const_int 4))) ; use extended branch
14307 +   (set_attr "cc" "none")])
14308 +
14309 +; branch if positive
14310 +(define_insn "bpl"
14311 +  [(set (pc)
14312 +       (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL)
14313 +                     (label_ref (match_operand 0 "" ""))
14314 +                     (pc)))]
14315 +  ""
14316 +  "brpl    %0"
14317 +  [(set_attr "type" "branch")
14318 +   (set (attr "length")
14319 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14320 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14321 +              (const_int 2)] ; use compact branch
14322 +              (const_int 4))) ; use extended branch
14323 +   (set_attr "cc" "none")])
14324 +
14325 +(define_insn "*bpl-reverse"
14326 +  [(set (pc)
14327 +       (if_then_else (unspec:CC [(cc0) (const_int 0)] UNSPEC_COND_PL)
14328 +                     (pc)
14329 +                     (label_ref (match_operand 0 "" ""))))]
14330 +  ""
14331 +  "brmi    %0"
14332 +  [(set_attr "type" "branch")
14333 +   (set (attr "length")
14334 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14335 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14336 +              (const_int 2)] ; use compact branch
14337 +              (const_int 4))) ; use extended branch
14338 +   (set_attr "cc" "none")])
14339 +
14340 +; branch if equal
14341 +(define_insn "b<code>"
14342 +  [(set (pc)
14343 +       (if_then_else (any_cond_b:CC (cc0)
14344 +                         (const_int 0))
14345 +                     (label_ref (match_operand 0 "" ""))
14346 +                     (pc)))]
14347 +  ""
14348 +  {
14349 +    if (TARGET_HARD_FLOAT && TARGET_ARCH_FPU && (avr32_branch_type == CMP_SF))
14350 +       return get_attr_length(insn) == 6 ? "brvs .+6\;br<cond> %0" : "brvs .+8\;br<cond> %0";
14351 +    else
14352 +       return "br<cond> %0";
14353 +  }
14354 +  [(set_attr "type" "branch")
14355 +   (set (attr "length")
14356 +       (if_then_else (eq (const_int 1)(symbol_ref "TARGET_HARD_FLOAT && TARGET_ARCH_FPU"))
14357 +                     (if_then_else 
14358 +                          (and (le (minus (match_dup 0) (pc)) (const_int 254))
14359 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14360 +                                (const_int 6)
14361 +                                (const_int 8))
14362 +                     (if_then_else 
14363 +                          (and (le (minus (match_dup 0) (pc)) (const_int 254))
14364 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14365 +                                   (const_int 2)
14366 +                                   (const_int 4))))
14367 +   (set_attr "cc" "none")])
14368 +
14369 +(define_insn "beq"
14370 +  [(set (pc)
14371 +       (if_then_else (eq:CC (cc0)
14372 +                         (const_int 0))
14373 +                     (label_ref (match_operand 0 "" ""))
14374 +                     (pc)))]
14375 +  ""
14376 +  "breq %0";
14377 +  [(set_attr "type" "branch")
14378 +   (set (attr "length")
14379 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14380 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14381 +              (const_int 2)] ; use compact branch
14382 +              (const_int 4))) ; use extended branch
14383 +   (set_attr "cc" "none")])
14384 +
14385 +(define_insn "bne"
14386 +  [(set (pc)
14387 +       (if_then_else (ne:CC (cc0)
14388 +                         (const_int 0))
14389 +                     (label_ref (match_operand 0 "" ""))
14390 +                     (pc)))]
14391 +  ""
14392 +  "brne %0";
14393 +  [(set_attr "type" "branch")
14394 +   (set (attr "length")
14395 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14396 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14397 +              (const_int 2)] ; use compact branch
14398 +              (const_int 4))) ; use extended branch
14399 +   (set_attr "cc" "none")])
14400 +
14401 +(define_insn "b<code>"
14402 +  [(set (pc)
14403 +       (if_then_else (any_cond4:CC (cc0)
14404 +                         (const_int 0))
14405 +                     (label_ref (match_operand 0 "" ""))
14406 +                     (pc)))]
14407 +  ""
14408 +  {
14409 +       if(TARGET_HARD_FLOAT && TARGET_ARCH_FPU && (avr32_branch_type == CMP_SF))
14410 +               return "brvs .+8\;br<cond> %l0";
14411 +       else
14412 +               return "br<cond> %l0";
14413 +  }
14414 +  [(set_attr "type" "branch")
14415 +   (set (attr "length") 
14416 +    (cond [(eq (const_int 1)(symbol_ref "TARGET_HARD_FLOAT && TARGET_ARCH_FPU"))
14417 +                      (const_int 8)]
14418 +               (const_int 4)))
14419 +   (set_attr "cc" "none")])
14420 +
14421 +(define_insn "*b<code>-reverse"
14422 +  [(set (pc)
14423 +       (if_then_else (any_cond_b:CC (cc0)
14424 +                         (const_int 0))
14425 +                     (pc)
14426 +                     (label_ref (match_operand 0 "" ""))))]
14427 +  ""
14428 +  {
14429 +    if (TARGET_HARD_FLOAT && TARGET_ARCH_FPU && (avr32_branch_type == CMP_SF))
14430 +       return "brvs %0\;br<invcond> %0";
14431 +    else
14432 +       return "br<invcond> %0";
14433 +  }
14434 +  [(set_attr "type" "branch")
14435 +   (set (attr "length")
14436 +       (if_then_else (eq (const_int 1)(symbol_ref "TARGET_HARD_FLOAT && TARGET_ARCH_FPU"))
14437 +                     (if_then_else 
14438 +                          (and (le (minus (match_dup 0) (pc)) (const_int 254))
14439 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14440 +                                (const_int 6)
14441 +                                (const_int 8))
14442 +                     (if_then_else 
14443 +                          (and (le (minus (match_dup 0) (pc)) (const_int 254))
14444 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14445 +                                   (const_int 2)
14446 +                                   (const_int 4))))
14447 +   (set_attr "cc" "none")])
14448 +
14449 +(define_insn "*beq-reverse"
14450 +  [(set (pc)
14451 +       (if_then_else (eq:CC (cc0)
14452 +                         (const_int 0))
14453 +                     (pc)
14454 +                     (label_ref (match_operand 0 "" ""))))]
14455 +  ""
14456 +  "brne %0";
14457 +  [(set_attr "type" "branch")
14458 +   (set (attr "length")
14459 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14460 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14461 +              (const_int 2)] ; use compact branch
14462 +              (const_int 4))) ; use extended branch
14463 +   (set_attr "cc" "none")])
14464 +
14465 +(define_insn "*bne-reverse"
14466 +  [(set (pc)
14467 +       (if_then_else (ne:CC (cc0)
14468 +                         (const_int 0))
14469 +                     (pc)
14470 +                     (label_ref (match_operand 0 "" ""))))]
14471 +  ""
14472 +  "breq %0";
14473 +  [(set_attr "type" "branch")
14474 +   (set (attr "length")
14475 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 254))
14476 +                   (le (minus (pc) (match_dup 0)) (const_int 256)))
14477 +              (const_int 2)] ; use compact branch
14478 +              (const_int 4))) ; use extended branch
14479 +   (set_attr "cc" "none")])
14480 +
14481 +(define_insn "*b<code>-reverse"
14482 +  [(set (pc)
14483 +       (if_then_else (any_cond4:CC (cc0)
14484 +                         (const_int 0))
14485 +                     (pc)
14486 +                     (label_ref (match_operand 0 "" ""))))]
14487 +  ""
14488 +  {
14489 +    if (TARGET_HARD_FLOAT && TARGET_ARCH_FPU && (avr32_branch_type == CMP_SF))
14490 +       return "brvs %l0\;br<invcond> %l0";
14491 +    else
14492 +       return "br<invcond> %0";
14493 +  }
14494 +  [(set_attr "type" "branch")
14495 +   (set (attr "length") 
14496 +    (cond [(eq (const_int 1)(symbol_ref "TARGET_HARD_FLOAT && TARGET_ARCH_FPU"))
14497 +                      (const_int 8)]
14498 +               (const_int 4)))
14499 +   (set_attr "cc" "none")])
14500 +
14501 +;=============================================================================
14502 +; Conditional Add/Subtract
14503 +;-----------------------------------------------------------------------------
14504 +; sub{cond4}  Rd, imm
14505 +;=============================================================================
14506 +
14507 +
14508 +(define_expand "add<mode>cc"
14509 +  [(set (match_operand:ADDCC 0 "register_operand" "")
14510 +        (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" 
14511 +                                            [(match_dup 4)
14512 +                                             (match_dup 5)])
14513 +                            (match_operand:ADDCC 2 "register_operand" "")
14514 +                            (plus:ADDCC 
14515 +                             (match_dup 2)
14516 +                             (match_operand:ADDCC 3 "" ""))))]
14517 +  ""
14518 +  {
14519 +   if ( !(GET_CODE (operands[3]) == CONST_INT
14520 +          || (TARGET_V2_INSNS && REG_P(operands[3]))) ){
14521 +      FAIL;
14522 +   }
14523 +
14524 +   /* Delete compare instruction as it is merged into this instruction */
14525 +   remove_insn (get_last_insn_anywhere ());
14526 +
14527 +   operands[4] = avr32_compare_op0;
14528 +   operands[5] = avr32_compare_op1;
14529 +   
14530 +   if ( TARGET_V2_INSNS 
14531 +        && REG_P(operands[3]) 
14532 +        && REGNO(operands[0]) != REGNO(operands[2]) ){
14533 +       emit_move_insn (operands[0], operands[2]);
14534 +       operands[2] = operands[0];
14535 +   }
14536 +  }
14537 +  )
14538 +
14539 +(define_insn "add<ADDCC:mode>cc_cmp<CMP:mode>_reg"
14540 +  [(set (match_operand:ADDCC 0 "register_operand" "=r")
14541 +        (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" 
14542 +                                            [(match_operand:CMP 4 "register_operand" "r")
14543 +                                             (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>")])
14544 +                            (match_dup 0)
14545 +                            (plus:ADDCC 
14546 +                             (match_operand:ADDCC 2 "register_operand" "r")
14547 +                             (match_operand:ADDCC 3 "register_operand" "r"))))]
14548 +  "TARGET_V2_INSNS"
14549 +  {
14550 +   operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
14551 +   return "add%i1\t%0, %2, %3";
14552 +  }
14553 +  [(set_attr "length" "8")
14554 +   (set_attr "cc" "cmp_cond_insn")])
14555 +
14556 +(define_insn "add<ADDCC:mode>cc_cmp<CMP:mode>"
14557 +  [(set (match_operand:ADDCC 0 "register_operand" "=r")
14558 +        (if_then_else:ADDCC (match_operator 1 "avr32_comparison_operator" 
14559 +                                            [(match_operand:CMP 4 "register_operand" "r")
14560 +                                             (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>")])
14561 +                            (match_operand:ADDCC 2 "register_operand" "0")
14562 +                            (plus:ADDCC 
14563 +                             (match_dup 2)
14564 +                             (match_operand:ADDCC 3 "avr32_cond_immediate_operand" "Is08"))))]
14565 +  ""
14566 +  {
14567 +   operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
14568 +   return "sub%i1\t%0, -%3";
14569 +  }
14570 +  [(set_attr "length" "8")
14571 +   (set_attr "cc" "cmp_cond_insn")])
14572 +
14573 +;=============================================================================
14574 +; Conditional Move
14575 +;-----------------------------------------------------------------------------
14576 +; mov{cond4}  Rd, (Rs/imm)
14577 +;=============================================================================
14578 +(define_expand "mov<mode>cc"
14579 +  [(set (match_operand:MOVCC 0 "register_operand" "")
14580 +        (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator" 
14581 +                                            [(match_dup 4)
14582 +                                             (match_dup 5)])
14583 +                            (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "")
14584 +                            (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "")))]
14585 +  ""
14586 +  {
14587 +   /* Delete compare instruction as it is merged into this instruction */
14588 +   remove_insn (get_last_insn_anywhere ());
14589 +
14590 +   operands[4] = avr32_compare_op0;
14591 +   operands[5] = avr32_compare_op1;
14592 +  }
14593 +  )
14594 +
14595 +
14596 +(define_insn "mov<MOVCC:mode>cc_cmp<CMP:mode>"
14597 +  [(set (match_operand:MOVCC 0 "register_operand" "=r,r,r")
14598 +        (if_then_else:MOVCC (match_operator 1 "avr32_comparison_operator" 
14599 +                                            [(match_operand:CMP 4 "register_operand" "r,r,r")
14600 +                                             (match_operand:CMP 5 "<CMP:cmp_predicate>" "<CMP:cmp_constraint>,<CMP:cmp_constraint>,<CMP:cmp_constraint>")])
14601 +                            (match_operand:MOVCC 2 "avr32_cond_register_immediate_operand" "0, rKs08,rKs08")
14602 +                            (match_operand:MOVCC 3 "avr32_cond_register_immediate_operand" "rKs08,0,rKs08")))]
14603 +  ""
14604 +  {
14605 +   operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
14606 +           
14607 +   switch( which_alternative ){
14608 +    case 0:
14609 +      return "mov%i1    %0, %3";
14610 +    case 1:
14611 +      return "mov%1    %0, %2";
14612 +    case 2:
14613 +      return "mov%1    %0, %2\;mov%i1    %0, %3";
14614 +    default:
14615 +      abort();
14616 +    }
14617 +
14618 +  }
14619 +  [(set_attr "length" "8,8,12")
14620 +   (set_attr "cc" "cmp_cond_insn")])
14621 +
14622 +  
14623 +
14624 +
14625 +;;=============================================================================
14626 +;; jump
14627 +;;-----------------------------------------------------------------------------
14628 +;; Jump inside a function; an unconditional branch to a label.
14629 +;;=============================================================================
14630 +(define_insn "jump"
14631 +  [(set (pc)
14632 +       (label_ref (match_operand 0 "" "")))]
14633 +  ""
14634 +  {
14635 +    if (get_attr_length(insn) > 4)
14636 +      return "Can't jump this far";
14637 +    return (get_attr_length(insn) == 2 ?
14638 +           "rjmp    %0" : "bral    %0");
14639 +  }
14640 +  [(set_attr "type" "branch")
14641 +   (set (attr "length")
14642 +       (cond [(and (le (minus (match_dup 0) (pc)) (const_int 1022))
14643 +                   (le (minus (pc) (match_dup 0)) (const_int 1024)))
14644 +              (const_int 2) ; use rjmp
14645 +              (le (match_dup 0) (const_int 1048575))
14646 +              (const_int 4)] ; use bral
14647 +             (const_int 8))) ; do something else
14648 +   (set_attr "cc" "none")])
14649 +
14650 +;;=============================================================================
14651 +;; call
14652 +;;-----------------------------------------------------------------------------
14653 +;; Subroutine call instruction returning no value.
14654 +;;=============================================================================
14655 +(define_insn "call_internal"
14656 +  [(parallel [(call (mem:SI (match_operand:SI 0 "avr32_call_operand" "r,U,T,W"))
14657 +                    (match_operand 1 "" ""))
14658 +              (clobber (reg:SI LR_REGNUM))])]
14659 +  ""
14660 +  {
14661 +
14662 +    /* Check for a flashvault call. */
14663 +    if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[0])))
14664 +      {
14665 +        /* Assembly is already emitted. */
14666 +        return "";
14667 +      }
14668 +
14669 +    switch (which_alternative) {
14670 +      case 0:
14671 +        return "icall\t%0";
14672 +      case 1:
14673 +        return "rcall\t%0";
14674 +      case 2:
14675 +        return "mcall\t%0";
14676 +      case 3:
14677 +        if (TARGET_HAS_ASM_ADDR_PSEUDOS)
14678 +          return "call\t%0";
14679 +        else
14680 +          return "mcall\tr6[%0@got]";
14681 +      default:
14682 +        abort();
14683 +    }
14684 +  }
14685 +  [(set_attr "type" "call")
14686 +   (set_attr "length" "2,4,4,10")
14687 +   (set_attr "cc" "clobber")])
14688 +
14689 +
14690 +(define_expand "call"
14691 +  [(parallel [(call (match_operand:SI 0 "" "")
14692 +                    (match_operand 1 "" ""))
14693 +              (clobber (reg:SI LR_REGNUM))])]
14694 +  ""
14695 +  {
14696 +    rtx call_address;
14697 +    if ( GET_CODE(operands[0]) != MEM )
14698 +      FAIL;
14699 +
14700 +    call_address = XEXP(operands[0], 0);
14701 +
14702 +   /* If assembler supports call pseudo insn and the call address is a symbol then nothing special needs to be done. */
14703 +    if (TARGET_HAS_ASM_ADDR_PSEUDOS && (GET_CODE(call_address) == SYMBOL_REF) )
14704 +    {
14705 +       /* We must however mark the function as using the GOT if flag_pic is set, since the call insn might turn into a mcall using the GOT ptr register. */
14706 +       if (flag_pic)
14707 +       {
14708 +          crtl->uses_pic_offset_table = 1;
14709 +          emit_call_insn(gen_call_internal(call_address, operands[1]));
14710 +          DONE;
14711 +       }
14712 +    } 
14713 +    else 
14714 +    {
14715 +      if (flag_pic && GET_CODE(call_address) == SYMBOL_REF )
14716 +      {
14717 +        crtl->uses_pic_offset_table = 1;
14718 +        emit_call_insn(gen_call_internal(call_address, operands[1]));
14719 +        DONE;
14720 +      }
14721 +
14722 +      if (!SYMBOL_REF_RCALL_FUNCTION_P(operands[0]) )
14723 +      {
14724 +        if (optimize_size && GET_CODE(call_address) == SYMBOL_REF )
14725 +        {
14726 +          call_address = force_const_mem(SImode, call_address);
14727 +        } 
14728 +        else 
14729 +        {
14730 +          call_address = force_reg(SImode, call_address);
14731 +        }
14732 +      }
14733 +    }
14734 +    emit_call_insn(gen_call_internal(call_address, operands[1]));
14735 +    DONE;
14736 +
14737 +  }
14738 +)
14739 +
14740 +;;=============================================================================
14741 +;; call_value
14742 +;;-----------------------------------------------------------------------------
14743 +;; Subroutine call instruction returning a value.
14744 +;;=============================================================================
14745 +(define_expand "call_value"
14746 +   [(parallel [(set (match_operand:SI 0 "" "")
14747 +                    (call (match_operand:SI 1 "" "")
14748 +                          (match_operand 2 "" "")))
14749 +               (clobber (reg:SI LR_REGNUM))])]
14750 +   ""
14751 +   {
14752 +    rtx call_address;
14753 +    if ( GET_CODE(operands[1]) != MEM )
14754 +      FAIL;
14755 +
14756 +    call_address = XEXP(operands[1], 0);
14757 +
14758 +   /* Check for a flashvault call. 
14759 +   if (GET_CODE (call_address) == SYMBOL_REF 
14760 +       && avr32_flashvault_call (SYMBOL_REF_DECL (call_address)))
14761 +     DONE;  
14762 +     
14763 +    */ 
14764 +
14765 +    /* If assembler supports call pseudo insn and the call
14766 +       address is a symbol then nothing special needs to be done. */
14767 +    if ( TARGET_HAS_ASM_ADDR_PSEUDOS
14768 +         && (GET_CODE(call_address) == SYMBOL_REF) ){
14769 +       /* We must however mark the function as using the GOT if
14770 +          flag_pic is set, since the call insn might turn into
14771 +          a mcall using the GOT ptr register. */
14772 +       if ( flag_pic ) {
14773 +          crtl->uses_pic_offset_table = 1;
14774 +          emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2]));
14775 +          DONE;
14776 +       }
14777 +    } else {
14778 +      if ( flag_pic &&
14779 +           GET_CODE(call_address) == SYMBOL_REF ){
14780 +        crtl->uses_pic_offset_table = 1;
14781 +        emit_call_insn(gen_call_value_internal(operands[0], call_address, operands[2]));
14782 +        DONE;
14783 +      }
14784 +
14785 +      if ( !SYMBOL_REF_RCALL_FUNCTION_P(operands[1]) ){
14786 +        if ( optimize_size &&
14787 +             GET_CODE(call_address) == SYMBOL_REF){
14788 +          call_address = force_const_mem(SImode, call_address);
14789 +        } else {
14790 +          call_address = force_reg(SImode, call_address);
14791 +        }
14792 +      }
14793 +    }
14794 +    emit_call_insn(gen_call_value_internal(operands[0], call_address,
14795 +                                           operands[2]));
14796 +    DONE;
14797 +
14798 +   })
14799 +
14800 +(define_insn "call_value_internal"
14801 +  [(parallel [(set (match_operand 0 "register_operand" "=r,r,r,r")
14802 +                   (call (mem:SI (match_operand:SI 1 "avr32_call_operand" "r,U,T,W"))
14803 +                         (match_operand 2 "" "")))
14804 +              (clobber (reg:SI LR_REGNUM))])]
14805 +  ;; Operand 2 not used on the AVR32.
14806 +  ""
14807 +  {
14808 +    /* Check for a flashvault call. */
14809 +    if (avr32_flashvault_call (SYMBOL_REF_DECL (operands[1])))
14810 +      {
14811 +        /* Assembly is already emitted. */
14812 +        return "";
14813 +      }
14814 +
14815 +
14816 +    switch (which_alternative) {
14817 +      case 0:
14818 +        return "icall\t%1";
14819 +      case 1:
14820 +        return "rcall\t%1";
14821 +      case 2:
14822 +        return "mcall\t%1";
14823 +      case 3:
14824 +        if ( TARGET_HAS_ASM_ADDR_PSEUDOS )
14825 +          return "call\t%1";
14826 +        else
14827 +          return "mcall\tr6[%1@got]";
14828 +      default:
14829 +        abort();
14830 +    }
14831 +  }
14832 +  [(set_attr "type" "call")
14833 +   (set_attr "length" "2,4,4,10")
14834 +   (set_attr "cc" "call_set")])
14835 +
14836 +
14837 +;;=============================================================================
14838 +;; untyped_call
14839 +;;-----------------------------------------------------------------------------
14840 +;; Subrutine call instruction returning a value of any type.
14841 +;; The code is copied from m68k.md (except gen_blockage is removed)
14842 +;; Fixme!
14843 +;;=============================================================================
14844 +(define_expand "untyped_call"
14845 +  [(parallel [(call (match_operand 0 "avr32_call_operand" "")
14846 +                   (const_int 0))
14847 +             (match_operand 1 "" "")
14848 +             (match_operand 2 "" "")])]
14849 +  ""
14850 +  {
14851 +    int i;
14852 +
14853 +    emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx));
14854 +
14855 +    for (i = 0; i < XVECLEN (operands[2], 0); i++) {
14856 +      rtx set = XVECEXP (operands[2], 0, i);
14857 +      emit_move_insn (SET_DEST (set), SET_SRC (set));
14858 +    }
14859 +
14860 +    /* The optimizer does not know that the call sets the function value
14861 +       registers we stored in the result block.  We avoid problems by
14862 +       claiming that all hard registers are used and clobbered at this
14863 +       point.  */
14864 +    emit_insn (gen_blockage ());
14865 +
14866 +    DONE;
14867 +  })
14868 +
14869 +
14870 +;;=============================================================================
14871 +;; return
14872 +;;=============================================================================
14873 +
14874 +(define_insn "return"
14875 +  [(return)]
14876 +  "USE_RETURN_INSN (FALSE)"
14877 +  {
14878 +   avr32_output_return_instruction(TRUE, FALSE, NULL, NULL);
14879 +   return "";
14880 +  }
14881 +  [(set_attr "length" "4")
14882 +   (set_attr "type" "call")]
14883 +  )
14884 +
14885 +
14886 +(define_insn "return_cond"
14887 +  [(set (pc) 
14888 +        (if_then_else (match_operand 0 "avr32_comparison_operand" "")
14889 +                      (return)
14890 +                      (pc)))]
14891 +  "USE_RETURN_INSN (TRUE)"
14892 +  "ret%0\tr12";
14893 +  [(set_attr "type" "call")])
14894 +  
14895 +(define_insn "return_cond_predicable"
14896 +  [(return)]
14897 +  "USE_RETURN_INSN (TRUE)"
14898 +  "ret%?\tr12";
14899 +  [(set_attr "type" "call")
14900 +   (set_attr "predicable" "yes")])
14901 +
14902 +
14903 +(define_insn "return_imm"
14904 +  [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
14905 +              (use (reg RETVAL_REGNUM))
14906 +              (return)])]
14907 +  "USE_RETURN_INSN (FALSE) &&
14908 +   ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
14909 +  {
14910 +   avr32_output_return_instruction(TRUE, FALSE, NULL, operands[0]);
14911 +   return "";
14912 +  }
14913 +  [(set_attr "length" "4")
14914 +   (set_attr "type" "call")]
14915 +  )
14916 +
14917 +(define_insn "return_imm_cond"
14918 +  [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
14919 +              (use (reg RETVAL_REGNUM))
14920 +              (set (pc) 
14921 +                   (if_then_else (match_operand 1 "avr32_comparison_operand" "")
14922 +                                 (return)
14923 +                                 (pc)))])]
14924 +  "USE_RETURN_INSN (TRUE) &&
14925 +   ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
14926 +  "ret%1\t%0";
14927 +  [(set_attr "type" "call")]
14928 +  )
14929 +
14930 +(define_insn "return_imm_predicable"
14931 +  [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
14932 +              (use (reg RETVAL_REGNUM))
14933 +              (return)])]
14934 +  "USE_RETURN_INSN (TRUE) &&
14935 +   ((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
14936 +  "ret%?\t%0";
14937 +  [(set_attr "type" "call")
14938 +   (set_attr "predicable" "yes")])
14939 +
14940 +(define_insn "return_<mode>reg"
14941 +  [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r"))
14942 +   (use (reg RETVAL_REGNUM))
14943 +   (return)]
14944 +  "USE_RETURN_INSN (TRUE)"
14945 +  "ret%?\t%0";
14946 +  [(set_attr "type" "call")
14947 +   (set_attr "predicable" "yes")])
14948 +
14949 +(define_insn "return_<mode>reg_cond"
14950 +  [(set (reg RETVAL_REGNUM) (match_operand:MOVM 0 "register_operand" "r"))
14951 +   (use (reg RETVAL_REGNUM))
14952 +   (set (pc) 
14953 +        (if_then_else (match_operator 1 "avr32_comparison_operator"
14954 +                                      [(cc0) (const_int 0)])
14955 +                      (return)
14956 +                      (pc)))]
14957 +  "USE_RETURN_INSN (TRUE)"
14958 +  "ret%1\t%0";
14959 +  [(set_attr "type" "call")])
14960 +  
14961 +;;=============================================================================
14962 +;; nonlocal_goto_receiver
14963 +;;-----------------------------------------------------------------------------
14964 +;; For targets with a return stack we must make sure to flush the return stack
14965 +;; since it will be corrupt after a nonlocal goto.
14966 +;;=============================================================================
14967 +(define_expand "nonlocal_goto_receiver"
14968 +  [(const_int 0)]
14969 +  "TARGET_RETURN_STACK"
14970 +  "
14971 +   {
14972 +    emit_insn ( gen_frs() );
14973 +    DONE;
14974 +   }
14975 +  "
14976 +  )
14977 +
14978 +
14979 +;;=============================================================================
14980 +;; builtin_setjmp_receiver
14981 +;;-----------------------------------------------------------------------------
14982 +;; For pic code we need to reload the pic register.
14983 +;; For targets with a return stack we must make sure to flush the return stack
14984 +;; since it will probably be corrupted.
14985 +;;=============================================================================
14986 +(define_expand "builtin_setjmp_receiver"
14987 +  [(label_ref (match_operand 0 "" ""))]
14988 +  "flag_pic"
14989 +  "
14990 +   {
14991 +    if ( TARGET_RETURN_STACK ) 
14992 +     emit_insn ( gen_frs() );
14993 +
14994 +    avr32_load_pic_register ();
14995 +    DONE;
14996 +   }
14997 +  "
14998 +)
14999 +
15000 +
15001 +;;=============================================================================
15002 +;; indirect_jump
15003 +;;-----------------------------------------------------------------------------
15004 +;; Jump to an address in reg or memory.
15005 +;;=============================================================================
15006 +(define_expand "indirect_jump"
15007 +  [(set (pc)
15008 +       (match_operand:SI 0 "general_operand" ""))]
15009 +  ""
15010 +  {
15011 +    /* One of the ops has to be in a register.  */
15012 +    if ( (flag_pic || TARGET_HAS_ASM_ADDR_PSEUDOS )
15013 +         && !avr32_legitimate_pic_operand_p(operands[0]) )
15014 +      operands[0] = legitimize_pic_address (operands[0], SImode, 0);
15015 +    else if ( flag_pic && avr32_address_operand(operands[0], GET_MODE(operands[0])) )
15016 +      /* If we have an address operand then this function uses the pic register. */
15017 +      crtl->uses_pic_offset_table = 1;
15018 +  })
15019 +
15020 +
15021 +(define_insn "indirect_jump_internal"
15022 +  [(set (pc)
15023 +       (match_operand:SI 0 "avr32_non_rmw_general_operand" "r,m,W"))]
15024 +  ""
15025 +  {
15026 +    switch( which_alternative ){
15027 +      case 0:
15028 +        return "mov\tpc, %0";
15029 +      case 1:
15030 +        if ( avr32_const_pool_ref_operand(operands[0], GET_MODE(operands[0])) )
15031 +          return "lddpc\tpc, %0";
15032 +        else
15033 +          return "ld.w\tpc, %0";
15034 +      case 2:
15035 +        if ( flag_pic )
15036 +          return "ld.w\tpc, r6[%0@got]";
15037 +        else
15038 +          return "lda.w\tpc, %0";
15039 +      default:
15040 +       abort();
15041 +    }
15042 +   }
15043 +  [(set_attr "length" "2,4,8")
15044 +   (set_attr "type" "call,call,call")
15045 +   (set_attr "cc" "none,none,clobber")])
15046 +
15047 +
15048 +
15049 +;;=============================================================================
15050 +;; casesi and tablejump
15051 +;;=============================================================================
15052 +(define_insn "tablejump_add"
15053 +  [(set (pc)
15054 +       (plus:SI (match_operand:SI 0 "register_operand" "r")
15055 +                 (mult:SI (match_operand:SI 1 "register_operand" "r")
15056 +                          (match_operand:SI 2 "immediate_operand" "Ku04" ))))
15057 +   (use (label_ref (match_operand 3 "" "")))]
15058 +  "flag_pic &&
15059 +   ((INTVAL(operands[2]) == 0) || (INTVAL(operands[2]) == 2) ||
15060 +    (INTVAL(operands[2]) == 4) || (INTVAL(operands[2]) == 8))"
15061 +  "add\tpc, %0, %1 << %p2"
15062 +  [(set_attr "length" "4")
15063 +   (set_attr "cc" "clobber")])
15064 +
15065 +(define_insn "tablejump_insn"
15066 +  [(set (pc) (match_operand:SI 0 "memory_operand" "m"))
15067 +   (use (label_ref (match_operand 1 "" "")))]
15068 +  "!flag_pic"
15069 +  "ld.w\tpc, %0"
15070 +  [(set_attr "length" "4")
15071 +   (set_attr "type" "call")
15072 +   (set_attr "cc" "none")])
15073 +
15074 +(define_expand "casesi"
15075 +  [(match_operand:SI 0 "register_operand" "")  ; index to jump on
15076 +   (match_operand:SI 1 "const_int_operand" "") ; lower bound
15077 +   (match_operand:SI 2 "const_int_operand" "") ; total range
15078 +   (match_operand:SI 3 "" "")                  ; table label
15079 +   (match_operand:SI 4 "" "")]                 ; Out of range label
15080 +  ""
15081 +  "
15082 +  {
15083 +    rtx reg;
15084 +    rtx index = operands[0];
15085 +    rtx low_bound = operands[1];
15086 +    rtx range = operands[2];
15087 +    rtx table_label = operands[3];
15088 +    rtx oor_label = operands[4];
15089 +
15090 +    index = force_reg ( SImode, index );
15091 +    if (low_bound != const0_rtx)
15092 +      {
15093 +        if (!avr32_const_ok_for_constraint_p(INTVAL (low_bound), 'I', \"Is21\")){
15094 +          reg = force_reg(SImode, GEN_INT (INTVAL (low_bound)));
15095 +         emit_insn (gen_subsi3 (reg, index,
15096 +                                reg));
15097 +        } else {
15098 +          reg = gen_reg_rtx (SImode);
15099 +          emit_insn (gen_addsi3 (reg, index,
15100 +                                GEN_INT (-INTVAL (low_bound))));
15101 +        }
15102 +       index = reg;
15103 +      }
15104 +
15105 +    if (!avr32_const_ok_for_constraint_p (INTVAL (range), 'K', \"Ks21\"))
15106 +      range = force_reg (SImode, range);
15107 +
15108 +    emit_cmp_and_jump_insns ( index, range, GTU, NULL_RTX, SImode, 1, oor_label );
15109 +    reg = gen_reg_rtx (SImode);
15110 +    emit_move_insn ( reg, gen_rtx_LABEL_REF (VOIDmode, table_label));
15111 +
15112 +    if ( flag_pic ) 
15113 +       emit_jump_insn ( gen_tablejump_add ( reg, index, GEN_INT(4), table_label));
15114 +    else
15115 +       emit_jump_insn ( 
15116 +           gen_tablejump_insn ( gen_rtx_MEM ( SImode, 
15117 +                                              gen_rtx_PLUS ( SImode, 
15118 +                                                             reg, 
15119 +                                                             gen_rtx_MULT ( SImode, 
15120 +                                                                            index, 
15121 +                                                                            GEN_INT(4)))),
15122 +                                table_label));
15123 +    DONE;
15124 +  }"
15125 +)
15126 +
15127 +
15128 +
15129 +(define_insn "prefetch"
15130 +  [(prefetch (match_operand:SI 0 "avr32_ks16_address_operand" "p")
15131 +            (match_operand 1 "const_int_operand" "")
15132 +            (match_operand 2 "const_int_operand" ""))]
15133 +  ""
15134 +  {
15135 +     return "pref\t%0";
15136 +  }
15137 +
15138 +  [(set_attr "length" "4")
15139 +   (set_attr "type" "load")
15140 +   (set_attr "cc" "none")])
15141 +
15142 +
15143 +
15144 +;;=============================================================================
15145 +;; prologue
15146 +;;-----------------------------------------------------------------------------
15147 +;; This pattern, if defined, emits RTL for entry to a function. The function
15148 +;; entry i responsible for setting up the stack frame, initializing the frame
15149 +;; pointer register, saving callee saved registers, etc.
15150 +;;=============================================================================
15151 +(define_expand "prologue"
15152 +  [(clobber (const_int 0))]
15153 +  ""
15154 +  "
15155 +  avr32_expand_prologue();
15156 +  DONE;
15157 +  "
15158 +  )
15159 +
15160 +;;=============================================================================
15161 +;; eh_return
15162 +;;-----------------------------------------------------------------------------
15163 +;; This pattern, if defined, affects the way __builtin_eh_return, and
15164 +;; thence the call frame exception handling library routines, are
15165 +;; built. It is intended to handle non-trivial actions needed along
15166 +;; the abnormal return path.
15167 +;;
15168 +;; The address of the exception handler to which the function should
15169 +;; return is passed as operand to this pattern. It will normally need
15170 +;; to copied by the pattern to some special register or memory
15171 +;; location. If the pattern needs to determine the location of the
15172 +;; target call frame in order to do so, it may use
15173 +;; EH_RETURN_STACKADJ_RTX, if defined; it will have already been
15174 +;; assigned.
15175 +;;
15176 +;; If this pattern is not defined, the default action will be to
15177 +;; simply copy the return address to EH_RETURN_HANDLER_RTX. Either
15178 +;; that macro or this pattern needs to be defined if call frame
15179 +;; exception handling is to be used.
15180 +
15181 +;; We can't expand this before we know where the link register is stored.
15182 +(define_insn_and_split "eh_return"
15183 +  [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")]
15184 +                   VUNSPEC_EH_RETURN)
15185 +   (clobber (match_scratch:SI 1 "=&r"))]
15186 +  ""
15187 +  "#"
15188 +  "reload_completed"
15189 +  [(const_int 0)]
15190 +  "
15191 +  {
15192 +    avr32_set_return_address (operands[0], operands[1]);
15193 +    DONE;
15194 +  }"
15195 +  )
15196 +
15197 +
15198 +;;=============================================================================
15199 +;; ffssi2
15200 +;;-----------------------------------------------------------------------------
15201 +(define_insn "ffssi2"
15202 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15203 +         (ffs:SI (match_operand:SI 1 "register_operand" "r"))) ]
15204 +  ""
15205 +  "mov    %0, %1
15206 +   brev   %0
15207 +   clz    %0, %0
15208 +   sub    %0, -1
15209 +   cp     %0, 33
15210 +   moveq  %0, 0"
15211 +  [(set_attr "length" "18")
15212 +   (set_attr "cc" "clobber")]
15213 +  )
15214 +
15215 +
15216 +
15217 +;;=============================================================================
15218 +;; swap_h
15219 +;;-----------------------------------------------------------------------------
15220 +(define_insn "*swap_h"
15221 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15222 +         (ior:SI (ashift:SI (match_dup 0) (const_int 16))
15223 +                 (lshiftrt:SI (match_dup 0) (const_int 16))))]
15224 +  ""
15225 +  "swap.h    %0"
15226 +  [(set_attr "length" "2")]
15227 +  )
15228 +
15229 +(define_insn_and_split "bswap_16"
15230 +  [ (set (match_operand:HI 0 "avr32_bswap_operand" "=r,RKs13,r")
15231 +         (ior:HI (and:HI (lshiftrt:HI (match_operand:HI 1 "avr32_bswap_operand" "r,r,RKs13")
15232 +                                      (const_int 8))
15233 +                         (const_int 255))
15234 +                 (ashift:HI (and:HI (match_dup 1)
15235 +                                    (const_int 255))
15236 +                            (const_int 8))))]
15237 +  ""
15238 +  {
15239 +   switch ( which_alternative ){
15240 +     case 0:
15241 +       if ( REGNO(operands[0]) == REGNO(operands[1]))
15242 +         return "swap.bh\t%0";
15243 +       else
15244 +         return "mov\t%0, %1\;swap.bh\t%0";
15245 +     case 1:
15246 +       return "stswp.h\t%0, %1";
15247 +     case 2:
15248 +       return "ldswp.sh\t%0, %1";
15249 +     default:
15250 +       abort();
15251 +     }
15252 +  }
15253 +
15254 +  "(reload_completed &&
15255 +     REG_P(operands[0]) && REG_P(operands[1])
15256 +     && (REGNO(operands[0]) != REGNO(operands[1])))"
15257 +  [(set (match_dup 0) (match_dup 1))
15258 +   (set (match_dup 0)
15259 +        (ior:HI (and:HI (lshiftrt:HI (match_dup 0)
15260 +                                     (const_int 8))
15261 +                        (const_int 255))
15262 +                (ashift:HI (and:HI (match_dup 0)
15263 +                                   (const_int 255))
15264 +                           (const_int 8))))]
15265 +  ""
15266 +
15267 +  [(set_attr "length" "4,4,4")
15268 +   (set_attr "type" "alu,store,load_rm")]
15269 +  )
15270 +
15271 +(define_insn_and_split "bswap_32"
15272 +  [ (set (match_operand:SI 0 "avr32_bswap_operand" "=r,RKs14,r")
15273 +         (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_operand:SI 1 "avr32_bswap_operand" "r,r,RKs14")
15274 +                                              (const_int -16777216))
15275 +                                      (const_int 24))
15276 +                         (lshiftrt:SI (and:SI (match_dup 1)
15277 +                                              (const_int 16711680))
15278 +                                      (const_int 8)))
15279 +                 (ior:SI (ashift:SI (and:SI (match_dup 1)
15280 +                                            (const_int 65280))
15281 +                                    (const_int 8))
15282 +                         (ashift:SI (and:SI (match_dup 1)
15283 +                                            (const_int 255))
15284 +                                    (const_int 24)))))]
15285 +  ""
15286 +  {
15287 +    switch ( which_alternative ){
15288 +     case 0:
15289 +       if ( REGNO(operands[0]) == REGNO(operands[1]))
15290 +         return "swap.b\t%0";
15291 +       else
15292 +         return "#";
15293 +     case 1:
15294 +       return "stswp.w\t%0, %1";
15295 +     case 2:
15296 +       return "ldswp.w\t%0, %1";
15297 +     default:
15298 +       abort();
15299 +    }
15300 +  }
15301 +  "(reload_completed &&
15302 +    REG_P(operands[0]) && REG_P(operands[1])
15303 +    && (REGNO(operands[0]) != REGNO(operands[1])))"
15304 +  [(set (match_dup 0) (match_dup 1))
15305 +   (set (match_dup 0)
15306 +        (ior:SI (ior:SI (lshiftrt:SI (and:SI (match_dup 0)
15307 +                                             (const_int -16777216))
15308 +                                     (const_int 24))
15309 +                        (lshiftrt:SI (and:SI (match_dup 0)
15310 +                                             (const_int 16711680))
15311 +                                     (const_int 8)))
15312 +                (ior:SI (ashift:SI (and:SI (match_dup 0)
15313 +                                           (const_int 65280))
15314 +                                   (const_int 8))
15315 +                        (ashift:SI (and:SI (match_dup 0)
15316 +                                           (const_int 255))
15317 +                                   (const_int 24)))))]
15318 +  ""
15319 +
15320 +  [(set_attr "length" "4,4,4")
15321 +   (set_attr "type" "alu,store,load_rm")]
15322 +  )
15323 +
15324 +
15325 +;;=============================================================================
15326 +;; blockage
15327 +;;-----------------------------------------------------------------------------
15328 +;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15329 +;; all of memory.  This blocks insns from being moved across this point.
15330 +
15331 +(define_insn "blockage"
15332 +  [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
15333 +  ""
15334 +  ""
15335 +  [(set_attr "length" "0")]
15336 +)
15337 +
15338 +;;=============================================================================
15339 +;; clzsi2
15340 +;;-----------------------------------------------------------------------------
15341 +(define_insn "clzsi2"
15342 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15343 +         (clz:SI (match_operand:SI 1 "register_operand" "r"))) ]
15344 +  ""
15345 +  "clz    %0, %1"
15346 +  [(set_attr "length" "4")
15347 +   (set_attr "cc" "set_z")]
15348 +  )
15349 +
15350 +;;=============================================================================
15351 +;; ctzsi2
15352 +;;-----------------------------------------------------------------------------
15353 +(define_insn "ctzsi2"
15354 +  [ (set (match_operand:SI 0 "register_operand" "=r,r")
15355 +         (ctz:SI (match_operand:SI 1 "register_operand" "0,r"))) ]
15356 +  ""
15357 +  "@
15358 +   brev\t%0\;clz\t%0, %0
15359 +   mov\t%0, %1\;brev\t%0\;clz\t%0, %0"
15360 +  [(set_attr "length" "8")
15361 +   (set_attr "cc" "set_z")]
15362 +  )
15363 +
15364 +;;=============================================================================
15365 +;; cache instructions
15366 +;;-----------------------------------------------------------------------------
15367 +(define_insn "cache"
15368 +  [ (unspec_volatile [(match_operand:SI 0 "avr32_ks11_address_operand" "p")
15369 +                      (match_operand:SI 1 "immediate_operand" "Ku05")] VUNSPEC_CACHE)]
15370 +  ""
15371 +  "cache    %0, %1"
15372 +  [(set_attr "length" "4")]
15373 +  )
15374 +
15375 +(define_insn "sync"
15376 +  [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku08")] VUNSPEC_SYNC)]
15377 +  ""
15378 +  "sync    %0"
15379 +  [(set_attr "length" "4")]
15380 +  )
15381 +
15382 +;;=============================================================================
15383 +;; TLB instructions
15384 +;;-----------------------------------------------------------------------------
15385 +(define_insn "tlbr"
15386 +  [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBR)]
15387 +  ""
15388 +  "tlbr"
15389 +  [(set_attr "length" "2")]
15390 +  )
15391 +
15392 +(define_insn "tlbw"
15393 +  [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBW)]
15394 +  ""
15395 +  "tlbw"
15396 +  [(set_attr "length" "2")]
15397 +  )
15398 +
15399 +(define_insn "tlbs"
15400 +  [ (unspec_volatile [(const_int 0)] VUNSPEC_TLBS)]
15401 +  ""
15402 +  "tlbs"
15403 +  [(set_attr "length" "2")]
15404 +  )
15405 +
15406 +;;=============================================================================
15407 +;; Breakpoint instruction
15408 +;;-----------------------------------------------------------------------------
15409 +(define_insn "breakpoint"
15410 +  [ (unspec_volatile [(const_int 0)] VUNSPEC_BREAKPOINT)]
15411 +  ""
15412 +  "breakpoint"
15413 +  [(set_attr "length" "2")]
15414 +  )
15415 +
15416 +
15417 +;;=============================================================================
15418 +;; mtsr/mfsr instruction
15419 +;;-----------------------------------------------------------------------------
15420 +(define_insn "mtsr"
15421 +  [ (unspec_volatile [(match_operand 0 "immediate_operand" "i")
15422 +                      (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTSR)]
15423 +  ""
15424 +  "mtsr\t%0, %1"
15425 +  [(set_attr "length" "4")]
15426 +  )
15427 +
15428 +(define_insn "mfsr"
15429 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15430 +         (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFSR)) ]
15431 +  ""
15432 +  "mfsr\t%0, %1"
15433 +  [(set_attr "length" "4")]
15434 +  )
15435 +
15436 +;;=============================================================================
15437 +;; mtdr/mfdr instruction
15438 +;;-----------------------------------------------------------------------------
15439 +(define_insn "mtdr"
15440 +  [ (unspec_volatile [(match_operand 0 "immediate_operand" "i")
15441 +                      (match_operand:SI 1 "register_operand" "r")] VUNSPEC_MTDR)]
15442 +  ""
15443 +  "mtdr\t%0, %1"
15444 +  [(set_attr "length" "4")]
15445 +  )
15446 +
15447 +(define_insn "mfdr"
15448 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15449 +         (unspec_volatile:SI [(match_operand 1 "immediate_operand" "i")] VUNSPEC_MFDR)) ]
15450 +  ""
15451 +  "mfdr\t%0, %1"
15452 +  [(set_attr "length" "4")]
15453 +  )
15454 +
15455 +;;=============================================================================
15456 +;; musfr
15457 +;;-----------------------------------------------------------------------------
15458 +(define_insn "musfr"
15459 +  [ (unspec_volatile [(match_operand:SI 0 "register_operand" "r")] VUNSPEC_MUSFR)]
15460 +  ""
15461 +  "musfr\t%0"
15462 +  [(set_attr "length" "2")
15463 +   (set_attr "cc" "clobber")]
15464 +  )
15465 +
15466 +(define_insn "mustr"
15467 +  [ (set (match_operand:SI 0 "register_operand" "=r")
15468 +         (unspec_volatile:SI [(const_int 0)] VUNSPEC_MUSTR)) ]
15469 +  ""
15470 +  "mustr\t%0"
15471 +  [(set_attr "length" "2")]
15472 +  )
15473 +
15474 +(define_insn "ssrf"
15475 +  [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku05")] VUNSPEC_SSRF)]
15476 +  ""
15477 +  "ssrf    %0"
15478 +  [(set_attr "length" "2")
15479 +   (set_attr "cc" "clobber")]
15480 +  )
15481 +
15482 +(define_insn "csrf"
15483 +  [ (unspec_volatile [(match_operand:SI 0 "immediate_operand" "Ku05")] VUNSPEC_CSRF)]
15484 +  ""
15485 +  "csrf    %0"
15486 +  [(set_attr "length" "2")
15487 +   (set_attr "cc" "clobber")]
15488 +  )
15489 +
15490 +;;=============================================================================
15491 +;; Flush Return Stack instruction
15492 +;;-----------------------------------------------------------------------------
15493 +(define_insn "frs"
15494 +  [ (unspec_volatile [(const_int 0)] VUNSPEC_FRS)]
15495 +  ""
15496 +  "frs"
15497 +  [(set_attr "length" "2")
15498 +   (set_attr "cc" "none")]
15499 +  )
15500 +
15501 +
15502 +;;=============================================================================
15503 +;; Saturation Round Scale instruction
15504 +;;-----------------------------------------------------------------------------
15505 +(define_insn "sats"
15506 +  [ (set (match_operand:SI 0 "register_operand" "+r")
15507 +         (unspec:SI [(match_dup 0)
15508 +                     (match_operand 1 "immediate_operand" "Ku05")
15509 +                     (match_operand 2 "immediate_operand" "Ku05")]
15510 +                    UNSPEC_SATS)) ]
15511 +  "TARGET_DSP"
15512 +  "sats\t%0 >> %1, %2"
15513 +  [(set_attr "type" "alu_sat")
15514 +   (set_attr "length" "4")]
15515 +  )
15516 +
15517 +(define_insn "satu"
15518 +  [ (set (match_operand:SI 0 "register_operand" "+r")
15519 +         (unspec:SI [(match_dup 0)
15520 +                     (match_operand 1 "immediate_operand" "Ku05")
15521 +                     (match_operand 2 "immediate_operand" "Ku05")]
15522 +                    UNSPEC_SATU)) ]
15523 +  "TARGET_DSP"
15524 +  "satu\t%0 >> %1, %2"
15525 +  [(set_attr "type" "alu_sat")
15526 +   (set_attr "length" "4")]
15527 +  )
15528 +
15529 +(define_insn "satrnds"
15530 +  [ (set (match_operand:SI 0 "register_operand" "+r")
15531 +         (unspec:SI [(match_dup 0)
15532 +                     (match_operand 1 "immediate_operand" "Ku05")
15533 +                     (match_operand 2 "immediate_operand" "Ku05")]
15534 +                    UNSPEC_SATRNDS)) ]
15535 +  "TARGET_DSP"
15536 +  "satrnds\t%0 >> %1, %2"
15537 +  [(set_attr "type" "alu_sat")
15538 +   (set_attr "length" "4")]
15539 +  )
15540 +
15541 +(define_insn "satrndu"
15542 +  [ (set (match_operand:SI 0 "register_operand" "+r")
15543 +         (unspec:SI [(match_dup 0)
15544 +                     (match_operand 1 "immediate_operand" "Ku05")
15545 +                     (match_operand 2 "immediate_operand" "Ku05")]
15546 +                    UNSPEC_SATRNDU)) ]
15547 +  "TARGET_DSP"
15548 +  "sats\t%0 >> %1, %2"
15549 +  [(set_attr "type" "alu_sat")
15550 +   (set_attr "length" "4")]
15551 +  )
15552 +
15553 +(define_insn "sleep"
15554 +  [(unspec_volatile [(const_int 0)] VUNSPEC_SLEEP)
15555 +  (match_operand:SI 0 "const_int_operand" "")]
15556 +  ""
15557 +  "sleep       %0"
15558 +  [(set_attr "length" "1")
15559 +   (set_attr "cc"  "none")
15560 +  ])
15561 +
15562 +(define_expand "delay_cycles"
15563 +  [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")]
15564 +                    VUNSPEC_DELAY_CYCLES)]
15565 +  ""
15566 +  "
15567 +  unsigned int cycles = UINTVAL (operands[0]);
15568 +  if (IN_RANGE(cycles,0x10000 ,0xFFFFFFFF))
15569 +   {
15570 +     unsigned int msb = (cycles & 0xFFFF0000);
15571 +     unsigned int shift = 16;
15572 +     msb = (msb >> shift);
15573 +     unsigned int cycles_used = (msb*0x10000);
15574 +     emit_insn (gen_delay_cycles_2 (gen_int_mode (msb, SImode)));
15575 +     cycles -= cycles_used;
15576 +   }
15577 +  if (IN_RANGE(cycles, 4, 0xFFFF))
15578 +   {
15579 +     unsigned int loop_count = (cycles/ 4);
15580 +     unsigned int cycles_used = (loop_count*4);
15581 +     emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, SImode)));
15582 +     cycles -= cycles_used;
15583 +   }
15584 +  while (cycles >= 3)
15585 +    {
15586 +      emit_insn (gen_nop3 ());
15587 +      cycles -= 3;
15588 +    }
15589 +  if (cycles == 1 || cycles == 2)
15590 +    {
15591 +      while (cycles--)
15592 +        emit_insn (gen_nop ());
15593 +    }
15594 +  DONE;
15595 +  ")
15596 +
15597 +(define_insn "delay_cycles_1"
15598 +[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_1)
15599 +  (match_operand:SI 0 "immediate_operand" "")
15600 +  (clobber (match_scratch:SI 1 "=&r"))]
15601 +  ""
15602 +  "mov\t%1, %0
15603 +    1:  sub\t%1, 1
15604 +        brne\t1b
15605 +        nop"
15606 +)
15607 +
15608 +(define_insn "delay_cycles_2"
15609 +[(unspec_volatile [(const_int 0)] VUNSPEC_DELAY_CYCLES_2)
15610 +  (match_operand:SI 0 "immediate_operand" "")
15611 +  (clobber (match_scratch:SI 1 "=&r"))
15612 +  (clobber (match_scratch:SI 2 "=&r"))]
15613 +  ""
15614 +  "mov\t%1, %0
15615 +    1:  mov\t%2, 16383 
15616 +    2:  sub\t%2, 1     
15617 +        brne\t2b
15618 +        nop
15619 +        sub\t%1, 1
15620 +        brne\t1b
15621 +        nop"
15622 +)
15623 +
15624 +;; CPU instructions
15625 +
15626 +;;=============================================================================
15627 +;; nop
15628 +;;-----------------------------------------------------------------------------
15629 +;; No-op instruction.
15630 +;;=============================================================================
15631 +(define_insn "nop"
15632 +  [(unspec_volatile [(const_int 0)] VUNSPEC_NOP)]
15633 +  ""
15634 +  "nop"
15635 +  [(set_attr "length" "1")
15636 +   (set_attr "type" "alu")
15637 +  (set_attr "cc" "none")])
15638 +
15639 +;; NOP3
15640 +(define_insn "nop3"
15641 +  [(unspec_volatile [(const_int 0)] VUNSPEC_NOP3)]
15642 +  ""
15643 +  "rjmp\t2"
15644 +  [(set_attr "length" "3")
15645 +   (set_attr "type" "alu")
15646 +  (set_attr "cc" "none")])
15647 +
15648 +;; Special patterns for dealing with the constant pool
15649 +
15650 +(define_insn "align_4"
15651 +  [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)]
15652 +  ""
15653 +  {
15654 +   assemble_align (32);
15655 +   return "";
15656 +  }
15657 +  [(set_attr "length" "2")]
15658 +)
15659 +
15660 +
15661 +(define_insn "consttable_start"
15662 +  [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_START)]
15663 +  ""
15664 +  {
15665 +   return ".cpool";
15666 +  }
15667 +  [(set_attr "length" "0")]
15668 +  )
15669 +
15670 +(define_insn "consttable_end"
15671 +  [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)]
15672 +  ""
15673 +  {
15674 +   making_const_table = FALSE;
15675 +   return "";
15676 +  }
15677 +  [(set_attr "length" "0")]
15678 +)
15679 +
15680 +
15681 +(define_insn "consttable_4"
15682 +  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)]
15683 +  ""
15684 +  {
15685 +    making_const_table = TRUE;
15686 +    switch (GET_MODE_CLASS (GET_MODE (operands[0])))
15687 +      {
15688 +      case MODE_FLOAT:
15689 +      {
15690 +        REAL_VALUE_TYPE r;
15691 +        char real_string[1024];
15692 +        REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
15693 +        real_to_decimal(real_string, &r, 1024, 0, 1);
15694 +        asm_fprintf (asm_out_file, "\t.float\t%s\n", real_string);
15695 +        break;
15696 +      }
15697 +      default:
15698 +        assemble_integer (operands[0], 4, 0, 1);
15699 +        break;
15700 +      }
15701 +    return "";
15702 +  }
15703 +  [(set_attr "length" "4")]
15704 +)
15705 +
15706 +(define_insn "consttable_8"
15707 +  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)]
15708 +  ""
15709 +  {
15710 +    making_const_table = TRUE;
15711 +    switch (GET_MODE_CLASS (GET_MODE (operands[0])))
15712 +      {
15713 +       case MODE_FLOAT:
15714 +        {
15715 +         REAL_VALUE_TYPE r; 
15716 +         char real_string[1024];
15717 +         REAL_VALUE_FROM_CONST_DOUBLE (r, operands[0]);
15718 +         real_to_decimal(real_string, &r, 1024, 0, 1);
15719 +         asm_fprintf (asm_out_file, "\t.double\t%s\n", real_string);
15720 +         break;
15721 +        }
15722 +       default:
15723 +         assemble_integer(operands[0], 8, 0, 1);
15724 +        break;
15725 +     }
15726 +    return "";
15727 +  }
15728 +  [(set_attr "length" "8")]
15729 +)
15730 +
15731 +(define_insn "consttable_16"
15732 +  [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)]
15733 +  ""
15734 +  {
15735 +    making_const_table = TRUE;
15736 +    assemble_integer(operands[0], 16, 0, 1);
15737 +    return "";
15738 +  }
15739 +  [(set_attr "length" "16")]
15740 +)
15741 +
15742 +;;=============================================================================
15743 +;; coprocessor instructions
15744 +;;-----------------------------------------------------------------------------
15745 +(define_insn "cop"
15746 +  [ (unspec_volatile [(match_operand 0 "immediate_operand" "Ku03")
15747 +                      (match_operand 1 "immediate_operand" "Ku04")
15748 +                      (match_operand 2 "immediate_operand" "Ku04")
15749 +                      (match_operand 3 "immediate_operand" "Ku04")
15750 +                      (match_operand 4 "immediate_operand" "Ku07")] VUNSPEC_COP)]
15751 +  ""
15752 +  "cop\tcp%0, cr%1, cr%2, cr%3, %4"
15753 +  [(set_attr "length" "4")]
15754 +  )
15755 +
15756 +(define_insn "mvcrsi"
15757 +  [ (set (match_operand:SI 0 "avr32_cop_move_operand" "=r,<,Z")
15758 +         (unspec_volatile:SI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03")
15759 +                              (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")]
15760 +                             VUNSPEC_MVCR)) ]
15761 +  ""
15762 +  "@
15763 +   mvcr.w\tcp%1, %0, cr%2
15764 +   stcm.w\tcp%1, %0, cr%2
15765 +   stc.w\tcp%1, %0, cr%2"
15766 +  [(set_attr "length" "4")]
15767 +  )
15768 +
15769 +(define_insn "mvcrdi"
15770 +  [ (set (match_operand:DI 0 "avr32_cop_move_operand" "=r,<,Z")
15771 +         (unspec_volatile:DI [(match_operand 1 "immediate_operand" "Ku03,Ku03,Ku03")
15772 +                              (match_operand 2 "immediate_operand" "Ku04,Ku04,Ku04")]
15773 +                             VUNSPEC_MVCR)) ]
15774 +  ""
15775 +  "@
15776 +   mvcr.d\tcp%1, %0, cr%2
15777 +   stcm.d\tcp%1, %0, cr%2-cr%i2
15778 +   stc.d\tcp%1, %0, cr%2"
15779 +  [(set_attr "length" "4")]
15780 +  )
15781 +
15782 +(define_insn "mvrcsi"
15783 +  [ (unspec_volatile:SI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03")
15784 +                         (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04")
15785 +                         (match_operand:SI 2 "avr32_cop_move_operand" "r,>,Z")]
15786 +                        VUNSPEC_MVRC)]
15787 +  ""
15788 +  {
15789 +   switch (which_alternative){
15790 +    case 0:
15791 +      return "mvrc.w\tcp%0, cr%1, %2";
15792 +    case 1:
15793 +      return "ldcm.w\tcp%0, %2, cr%1";
15794 +    case 2:
15795 +      return "ldc.w\tcp%0, cr%1, %2";
15796 +    default:
15797 +      abort();
15798 +   }
15799 +  }
15800 +  [(set_attr "length" "4")]
15801 +  )
15802 +
15803 +(define_insn "mvrcdi"
15804 +  [ (unspec_volatile:DI [(match_operand 0 "immediate_operand" "Ku03,Ku03,Ku03")
15805 +                         (match_operand 1 "immediate_operand" "Ku04,Ku04,Ku04")
15806 +                         (match_operand:DI 2 "avr32_cop_move_operand" "r,>,Z")]
15807 +                        VUNSPEC_MVRC)]
15808 +  ""
15809 +  {
15810 +   switch (which_alternative){
15811 +    case 0:
15812 +      return "mvrc.d\tcp%0, cr%1, %2";
15813 +    case 1:
15814 +      return "ldcm.d\tcp%0, %2, cr%1-cr%i1";
15815 +    case 2:
15816 +      return "ldc.d\tcp%0, cr%1, %2";
15817 +    default:
15818 +      abort();
15819 +   }
15820 +  }
15821 +  [(set_attr "length" "4")]
15822 +  )
15823 +
15824 +;;=============================================================================
15825 +;; epilogue
15826 +;;-----------------------------------------------------------------------------
15827 +;; This pattern emits RTL for exit from a function. The function exit is
15828 +;; responsible for deallocating the stack frame, restoring callee saved
15829 +;; registers and emitting the return instruction.
15830 +;; ToDo: using TARGET_ASM_FUNCTION_PROLOGUE instead.
15831 +;;=============================================================================
15832 +(define_expand "epilogue"
15833 +  [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
15834 +  ""
15835 +  "
15836 +  if (USE_RETURN_INSN (FALSE)){
15837 +      emit_jump_insn (gen_return ());
15838 +      DONE;
15839 +  }
15840 +  emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode,
15841 +       gen_rtvec (1,
15842 +               gen_rtx_RETURN (VOIDmode)),
15843 +       VUNSPEC_EPILOGUE));
15844 +  DONE;
15845 +  "
15846 +  )
15847 +
15848 +(define_insn "*epilogue_insns"
15849 +  [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
15850 +  ""
15851 +  {
15852 +    avr32_output_return_instruction (FALSE, FALSE, NULL, NULL);
15853 +    return "";
15854 +  }
15855 +  ; Length is absolute worst case
15856 +  [(set_attr "type" "branch")
15857 +   (set_attr "length" "12")]
15858 +  )
15859 +
15860 +(define_insn "*epilogue_insns_ret_imm"
15861 +  [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
15862 +              (use (reg RETVAL_REGNUM))
15863 +              (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])]
15864 +  "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
15865 +  {
15866 +    avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]);
15867 +    return "";
15868 +  }
15869 +  ; Length is absolute worst case
15870 +  [(set_attr "type" "branch")
15871 +   (set_attr "length" "12")]
15872 +  )
15873 +
15874 +(define_insn "sibcall_epilogue"
15875 +  [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)]
15876 +  ""
15877 +  {
15878 +   avr32_output_return_instruction (FALSE, FALSE,  NULL, NULL);
15879 +   return "";
15880 +  }
15881 +;; Length is absolute worst case
15882 +  [(set_attr "type" "branch")
15883 +   (set_attr "length" "12")]
15884 +  )
15885 +
15886 +(define_insn "*sibcall_epilogue_insns_ret_imm"
15887 +  [(parallel [(set (reg RETVAL_REGNUM) (match_operand 0 "immediate_operand" "i"))
15888 +              (use (reg RETVAL_REGNUM))
15889 +              (unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)])]
15890 +  "((INTVAL(operands[0]) == -1) || (INTVAL(operands[0]) == 0) || (INTVAL(operands[0]) == 1))"
15891 +  {
15892 +    avr32_output_return_instruction (FALSE, FALSE, NULL, operands[0]);
15893 +    return "";
15894 +  }
15895 +  ; Length is absolute worst case
15896 +  [(set_attr "type" "branch")
15897 +   (set_attr "length" "12")]
15898 +  )
15899 +
15900 +(define_insn "ldxi"
15901 +  [(set (match_operand:SI 0 "register_operand" "=r")
15902 +       (mem:SI (plus:SI
15903 +                 (match_operand:SI 1 "register_operand" "r")
15904 +                 (mult:SI (zero_extract:SI (match_operand:SI 2 "register_operand" "r")
15905 +                                           (const_int 8)
15906 +                                           (match_operand:SI 3 "immediate_operand" "Ku05"))
15907 +                          (const_int 4)))))]
15908 +  "(INTVAL(operands[3]) == 24 || INTVAL(operands[3]) == 16 || INTVAL(operands[3]) == 8
15909 +   || INTVAL(operands[3]) == 0)"
15910 +  {
15911 +   switch ( INTVAL(operands[3]) ){
15912 +    case 0:
15913 +         return "ld.w    %0, %1[%2:b << 2]";
15914 +    case 8:
15915 +         return "ld.w    %0, %1[%2:l << 2]";
15916 +    case 16:
15917 +         return "ld.w    %0, %1[%2:u << 2]";
15918 +    case 24:
15919 +         return "ld.w    %0, %1[%2:t << 2]";
15920 +    default:
15921 +         internal_error("illegal operand for ldxi");
15922 +   }
15923 +  }
15924 +  [(set_attr "type" "load")
15925 +   (set_attr "length" "4")
15926 +   (set_attr "cc" "none")])
15927 +
15928 +
15929 +
15930 +
15931 +
15932 +
15933 +;;=============================================================================
15934 +;; Peephole optimizing
15935 +;;-----------------------------------------------------------------------------
15936 +;; Changing
15937 +;;   sub     r8, r7, 8
15938 +;;   st.w    r8[0x0], r12
15939 +;; to
15940 +;;   sub     r8, r7, 8
15941 +;;   st.w    r7[-0x8], r12
15942 +;;=============================================================================
15943 +; (set (reg:SI 9 r8)
15944 +;      (plus:SI (reg/f:SI 6 r7)
15945 +;               (const_int ...)))
15946 +; (set (mem:SI (reg:SI 9 r8))
15947 +;      (reg:SI 12 r12))
15948 +(define_peephole2
15949 +  [(set (match_operand:SI 0 "register_operand" "")
15950 +       (plus:SI (match_operand:SI 1 "register_operand" "")
15951 +                (match_operand:SI 2 "immediate_operand" "")))
15952 +   (set (mem:SI (match_dup 0))
15953 +       (match_operand:SI 3 "register_operand" ""))]
15954 +  "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")"
15955 +  [(set (match_dup 0)
15956 +       (plus:SI (match_dup 1)
15957 +                (match_dup 2)))
15958 +   (set (mem:SI (plus:SI (match_dup 1)
15959 +                        (match_dup 2)))
15960 +       (match_dup 3))]
15961 +  "")
15962 +
15963 +;;=============================================================================
15964 +;; Peephole optimizing
15965 +;;-----------------------------------------------------------------------------
15966 +;; Changing
15967 +;;   sub     r6, r7, 4
15968 +;;   ld.w    r6, r6[0x0]
15969 +;; to
15970 +;;   sub     r6, r7, 4
15971 +;;   ld.w    r6, r7[-0x4]
15972 +;;=============================================================================
15973 +; (set (reg:SI 7 r6)
15974 +;      (plus:SI (reg/f:SI 6 r7)
15975 +;               (const_int -4 [0xfffffffc])))
15976 +; (set (reg:SI 7 r6)
15977 +;      (mem:SI (reg:SI 7 r6)))
15978 +(define_peephole2
15979 +  [(set (match_operand:SI 0 "register_operand" "")
15980 +       (plus:SI (match_operand:SI 1 "register_operand" "")
15981 +                (match_operand:SI 2 "immediate_operand" "")))
15982 +   (set (match_operand:SI 3 "register_operand" "")
15983 +       (mem:SI (match_dup 0)))]
15984 +  "REGNO(operands[0]) != REGNO(operands[1]) && avr32_const_ok_for_constraint_p(INTVAL(operands[2]), 'K', \"Ks16\")"
15985 +  [(set (match_dup 0)
15986 +       (plus:SI (match_dup 1)
15987 +                (match_dup 2)))
15988 +   (set (match_dup 3)
15989 +       (mem:SI (plus:SI (match_dup 1)
15990 +                        (match_dup 2))))]
15991 +  "")
15992 +
15993 +;;=============================================================================
15994 +;; Peephole optimizing
15995 +;;-----------------------------------------------------------------------------
15996 +;; Changing
15997 +;;   ld.sb   r0, r7[-0x6]
15998 +;;   cashs.b r0
15999 +;; to
16000 +;;   ld.sb   r0, r7[-0x6]
16001 +;;=============================================================================
16002 +(define_peephole2
16003 +  [(set (match_operand:QI 0 "register_operand" "")
16004 +       (match_operand:QI 1 "load_sb_memory_operand" ""))
16005 +   (set (match_operand:SI 2 "register_operand" "")
16006 +       (sign_extend:SI (match_dup 0)))]
16007 +  "(REGNO(operands[0]) == REGNO(operands[2]) || peep2_reg_dead_p(2, operands[0]))"
16008 +  [(set (match_dup 2)
16009 +       (sign_extend:SI (match_dup 1)))]
16010 +  "")
16011 +
16012 +;;=============================================================================
16013 +;; Peephole optimizing
16014 +;;-----------------------------------------------------------------------------
16015 +;; Changing
16016 +;;   ld.ub   r0, r7[-0x6]
16017 +;;   cashu.b r0
16018 +;; to
16019 +;;   ld.ub   r0, r7[-0x6]
16020 +;;=============================================================================
16021 +(define_peephole2
16022 +  [(set (match_operand:QI 0 "register_operand" "")
16023 +       (match_operand:QI 1 "memory_operand" ""))
16024 +   (set (match_operand:SI 2 "register_operand" "")
16025 +       (zero_extend:SI (match_dup 0)))]
16026 +  "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
16027 +  [(set (match_dup 2)
16028 +       (zero_extend:SI (match_dup 1)))]
16029 +  "")
16030 +
16031 +;;=============================================================================
16032 +;; Peephole optimizing
16033 +;;-----------------------------------------------------------------------------
16034 +;; Changing
16035 +;;   ld.sh   r0, r7[-0x6]
16036 +;;   casts.h r0
16037 +;; to
16038 +;;   ld.sh   r0, r7[-0x6]
16039 +;;=============================================================================
16040 +(define_peephole2
16041 +  [(set (match_operand:HI 0 "register_operand" "")
16042 +       (match_operand:HI 1 "memory_operand" ""))
16043 +   (set (match_operand:SI 2 "register_operand" "")
16044 +       (sign_extend:SI (match_dup 0)))]
16045 +  "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
16046 +  [(set (match_dup 2)
16047 +       (sign_extend:SI (match_dup 1)))]
16048 +  "")
16049 +
16050 +;;=============================================================================
16051 +;; Peephole optimizing
16052 +;;-----------------------------------------------------------------------------
16053 +;; Changing
16054 +;;   ld.uh   r0, r7[-0x6]
16055 +;;   castu.h r0
16056 +;; to
16057 +;;   ld.uh   r0, r7[-0x6]
16058 +;;=============================================================================
16059 +(define_peephole2
16060 +  [(set (match_operand:HI 0 "register_operand" "")
16061 +       (match_operand:HI 1 "memory_operand" ""))
16062 +   (set (match_operand:SI 2 "register_operand" "")
16063 +       (zero_extend:SI (match_dup 0)))]
16064 +  "(REGNO(operands[0]) == REGNO(operands[2])) || peep2_reg_dead_p(2, operands[0])"
16065 +  [(set (match_dup 2)
16066 +       (zero_extend:SI (match_dup 1)))]
16067 +  "")
16068 +
16069 +;;=============================================================================
16070 +;; Peephole optimizing
16071 +;;-----------------------------------------------------------------------------
16072 +;; Changing
16073 +;;   mul     rd, rx, ry
16074 +;;   add     rd2, rd  
16075 +;; or
16076 +;;   add     rd2, rd, rd2  
16077 +;; to
16078 +;;   mac     rd2, rx, ry
16079 +;;=============================================================================
16080 +(define_peephole2
16081 +  [(set (match_operand:SI 0 "register_operand" "")
16082 +        (mult:SI (match_operand:SI 1 "register_operand" "")
16083 +                (match_operand:SI 2 "register_operand" "")))
16084 +   (set (match_operand:SI 3 "register_operand" "")
16085 +        (plus:SI (match_dup 3)
16086 +                 (match_dup 0)))]
16087 +  "peep2_reg_dead_p(2, operands[0])"
16088 +  [(set (match_dup 3)
16089 +       (plus:SI (mult:SI (match_dup 1)
16090 +                         (match_dup 2))
16091 +                (match_dup 3)))]
16092 +  "")
16093 +
16094 +(define_peephole2
16095 +  [(set (match_operand:SI 0 "register_operand" "")
16096 +        (mult:SI (match_operand:SI 1 "register_operand" "")
16097 +                (match_operand:SI 2 "register_operand" "")))
16098 +   (set (match_operand:SI 3 "register_operand" "")
16099 +        (plus:SI (match_dup 0)
16100 +                 (match_dup 3)))]
16101 +  "peep2_reg_dead_p(2, operands[0])"
16102 +  [(set (match_dup 3)
16103 +       (plus:SI (mult:SI (match_dup 1)
16104 +                         (match_dup 2))
16105 +                (match_dup 3)))]
16106 +  "")
16107 +
16108 +
16109 +;;=============================================================================
16110 +;; Peephole optimizing
16111 +;;-----------------------------------------------------------------------------
16112 +;; Changing
16113 +;;   bfextu  rd, rs, k5, 1 or and(h/l) rd, one_bit_set_mask
16114 +;; to
16115 +;;   bld     rs, k5
16116 +;;
16117 +;; If rd is dead after the operation.
16118 +;;=============================================================================
16119 +(define_peephole2
16120 +  [ (set (match_operand:SI 0 "register_operand" "")
16121 +         (zero_extract:SI (match_operand:SI 1 "register_operand" "")
16122 +                          (const_int 1)
16123 +                          (match_operand:SI 2 "immediate_operand" "")))
16124 +    (set (cc0)
16125 +         (match_dup 0))]
16126 +  "peep2_reg_dead_p(2, operands[0])"
16127 +  [(set (cc0)
16128 +        (and:SI (match_dup 1)
16129 +                (match_dup 2)))]
16130 +  "operands[2] = GEN_INT(1 << INTVAL(operands[2]));")
16131 +
16132 +(define_peephole2
16133 +  [ (set (match_operand:SI 0 "register_operand" "")
16134 +         (and:SI (match_operand:SI 1 "register_operand" "")
16135 +                 (match_operand:SI 2 "one_bit_set_operand" "")))
16136 +    (set (cc0)
16137 +         (match_dup 0))]
16138 +  "peep2_reg_dead_p(2, operands[0])"
16139 +  [(set (cc0)
16140 +        (and:SI (match_dup 1)
16141 +                (match_dup 2)))]
16142 +  "")
16143 +
16144 +;;=============================================================================
16145 +;; Peephole optimizing
16146 +;;-----------------------------------------------------------------------------
16147 +;; Load with extracted index: ld.w  Rd, Rb[Ri:{t/u/b/l} << 2]
16148 +;;
16149 +;;=============================================================================
16150 +
16151 +
16152 +(define_peephole
16153 +  [(set (match_operand:SI 0 "register_operand" "")
16154 +        (zero_extract:SI (match_operand:SI 1 "register_operand" "")
16155 +                         (const_int 8)
16156 +                         (match_operand:SI 2 "avr32_extract_shift_operand" "")))
16157 +   (set (match_operand:SI 3 "register_operand" "")
16158 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16159 +                         (match_operand:SI 4 "register_operand" ""))))]
16160 +
16161 +  "(dead_or_set_p(insn, operands[0]))"
16162 +  {
16163 +   switch ( INTVAL(operands[2]) ){
16164 +    case 0:
16165 +         return "ld.w    %3, %4[%1:b << 2]";
16166 +    case 8:
16167 +         return "ld.w    %3, %4[%1:l << 2]";
16168 +    case 16:
16169 +         return "ld.w    %3, %4[%1:u << 2]";
16170 +    case 24:
16171 +         return "ld.w    %3, %4[%1:t << 2]";
16172 +    default:
16173 +         internal_error("illegal operand for ldxi");
16174 +   }
16175 +  }
16176 +  [(set_attr "type" "load")
16177 +   (set_attr "length" "4")
16178 +   (set_attr "cc" "clobber")]
16179 +  )
16180 +
16181 +
16182 +
16183 +(define_peephole
16184 +  [(set (match_operand:SI 0 "register_operand" "")
16185 +        (and:SI (match_operand:SI 1 "register_operand" "") (const_int 255)))
16186 +   (set (match_operand:SI 2 "register_operand" "")
16187 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16188 +                         (match_operand:SI 3 "register_operand" ""))))]
16189 +
16190 +  "(dead_or_set_p(insn, operands[0]))"
16191 +
16192 +  "ld.w    %2, %3[%1:b << 2]"
16193 +  [(set_attr "type" "load")
16194 +   (set_attr "length" "4")
16195 +   (set_attr "cc" "clobber")]
16196 +  )
16197 +
16198 +
16199 +(define_peephole2
16200 +  [(set (match_operand:SI 0 "register_operand" "")
16201 +        (zero_extract:SI (match_operand:SI 1 "register_operand" "")
16202 +                         (const_int 8)
16203 +                         (match_operand:SI 2 "avr32_extract_shift_operand" "")))
16204 +   (set (match_operand:SI 3 "register_operand" "")
16205 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16206 +                         (match_operand:SI 4 "register_operand" ""))))]
16207 +
16208 +  "(peep2_reg_dead_p(2, operands[0]))
16209 +   || (REGNO(operands[0]) == REGNO(operands[3]))"
16210 +  [(set (match_dup 3)
16211 +       (mem:SI (plus:SI
16212 +                 (match_dup 4)
16213 +                 (mult:SI (zero_extract:SI (match_dup 1)
16214 +                                           (const_int 8)
16215 +                                           (match_dup 2))
16216 +                          (const_int 4)))))]
16217 +  )
16218 +
16219 +(define_peephole2
16220 +  [(set (match_operand:SI 0 "register_operand" "")
16221 +        (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
16222 +   (set (match_operand:SI 2 "register_operand" "")
16223 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16224 +                         (match_operand:SI 3 "register_operand" ""))))]
16225 +
16226 +  "(peep2_reg_dead_p(2, operands[0]))
16227 +   || (REGNO(operands[0]) == REGNO(operands[2]))"
16228 +  [(set (match_dup 2)
16229 +       (mem:SI (plus:SI
16230 +                 (match_dup 3)
16231 +                 (mult:SI (zero_extract:SI (match_dup 1)
16232 +                                           (const_int 8)
16233 +                                           (const_int 0))
16234 +                          (const_int 4)))))]
16235 +  "operands[1] = gen_rtx_REG(SImode, REGNO(operands[1]));"
16236 +  )
16237 +
16238 +
16239 +(define_peephole2
16240 +  [(set (match_operand:SI 0 "register_operand" "")
16241 +        (and:SI (match_operand:SI 1 "register_operand" "")
16242 +                (const_int 255)))
16243 +   (set (match_operand:SI 2 "register_operand" "")
16244 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16245 +                         (match_operand:SI 3 "register_operand" ""))))]
16246 +
16247 +  "(peep2_reg_dead_p(2, operands[0]))
16248 +   || (REGNO(operands[0]) == REGNO(operands[2]))"
16249 +  [(set (match_dup 2)
16250 +       (mem:SI (plus:SI
16251 +                 (match_dup 3)
16252 +                 (mult:SI (zero_extract:SI (match_dup 1)
16253 +                                           (const_int 8)
16254 +                                           (const_int 0))
16255 +                          (const_int 4)))))]
16256 +  ""
16257 +  )
16258 +
16259 +
16260 +
16261 +(define_peephole2
16262 +  [(set (match_operand:SI 0 "register_operand" "")
16263 +        (lshiftrt:SI (match_operand:SI 1 "register_operand" "")
16264 +                     (const_int 24)))
16265 +   (set (match_operand:SI 2 "register_operand" "")
16266 +        (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
16267 +                         (match_operand:SI 3 "register_operand" ""))))]
16268 +
16269 +  "(peep2_reg_dead_p(2, operands[0]))
16270 +   || (REGNO(operands[0]) == REGNO(operands[2]))"
16271 +  [(set (match_dup 2)
16272 +       (mem:SI (plus:SI
16273 +                 (match_dup 3)
16274 +                 (mult:SI (zero_extract:SI (match_dup 1)
16275 +                                           (const_int 8)
16276 +                                           (const_int 24))
16277 +                          (const_int 4)))))]
16278 +  ""
16279 +  )
16280 +
16281 +
16282 +;;************************************************
16283 +;; ANDN
16284 +;;
16285 +;;************************************************
16286 +
16287 +
16288 +(define_peephole2
16289 +  [(set (match_operand:SI 0 "register_operand" "")
16290 +        (not:SI (match_operand:SI 1 "register_operand" "")))
16291 +   (set (match_operand:SI 2 "register_operand" "")
16292 +        (and:SI (match_dup 2)
16293 +                (match_dup 0)))]
16294 +  "peep2_reg_dead_p(2, operands[0])"
16295 +
16296 +  [(set (match_dup 2)
16297 +        (and:SI  (match_dup 2)
16298 +                 (not:SI (match_dup 1))
16299 +                 ))]
16300 +  ""
16301 +)
16302 +
16303 +(define_peephole2
16304 +  [(set (match_operand:SI 0 "register_operand" "")
16305 +        (not:SI (match_operand:SI 1 "register_operand" "")))
16306 +   (set (match_operand:SI 2 "register_operand" "")
16307 +        (and:SI (match_dup 0)
16308 +                (match_dup 2)
16309 +                ))]
16310 +  "peep2_reg_dead_p(2, operands[0])"
16311 +
16312 +  [(set (match_dup 2)
16313 +        (and:SI  (match_dup 2)
16314 +                 (not:SI (match_dup 1))
16315 +                 ))]
16316 +
16317 +  ""
16318 +)
16319 +
16320 +
16321 +;;=================================================================
16322 +;; Addabs peephole
16323 +;;=================================================================
16324 +
16325 +(define_peephole
16326 +  [(set (match_operand:SI 2 "register_operand" "=r")
16327 +       (abs:SI (match_operand:SI 1 "register_operand" "r")))
16328 +   (set (match_operand:SI 0 "register_operand" "=r")
16329 +       (plus:SI (match_operand:SI 3 "register_operand" "r")
16330 +                (match_dup 2)))]
16331 +  "dead_or_set_p(insn, operands[2])"
16332 +  "addabs  %0, %3, %1"
16333 +  [(set_attr "length" "4")
16334 +   (set_attr "cc" "set_z")])
16335 +
16336 +(define_peephole
16337 +  [(set (match_operand:SI 2 "register_operand" "=r")
16338 +       (abs:SI (match_operand:SI 1 "register_operand" "r")))
16339 +   (set (match_operand:SI 0 "register_operand" "=r")
16340 +       (plus:SI (match_dup 2)
16341 +                 (match_operand:SI 3 "register_operand" "r")))]
16342 +  "dead_or_set_p(insn, operands[2])"
16343 +  "addabs  %0, %3, %1"
16344 +  [(set_attr "length" "4")
16345 +   (set_attr "cc" "set_z")])
16346 +
16347 +
16348 +;;=================================================================
16349 +;; Detect roundings
16350 +;;=================================================================
16351 +
16352 +(define_insn "*round"
16353 +  [(set (match_operand:SI 0 "register_operand" "+r")
16354 +        (ashiftrt:SI (plus:SI (match_dup 0)
16355 +                              (match_operand:SI 1 "immediate_operand" "i"))
16356 +                     (match_operand:SI 2 "immediate_operand" "i")))]
16357 +  "avr32_rnd_operands(operands[1], operands[2])"
16358 +
16359 +  "satrnds    %0 >> %2, 31"
16360 +
16361 +  [(set_attr "type" "alu_sat")
16362 +   (set_attr "length" "4")]
16363 +
16364 +  )
16365 +
16366 +
16367 +(define_peephole2
16368 +  [(set (match_operand:SI 0 "register_operand" "")
16369 +       (plus:SI (match_dup 0)
16370 +                 (match_operand:SI 1 "immediate_operand" "")))
16371 +   (set (match_dup 0)
16372 +       (ashiftrt:SI (match_dup 0)
16373 +                     (match_operand:SI 2 "immediate_operand" "")))]
16374 +  "avr32_rnd_operands(operands[1], operands[2])"
16375 +
16376 +  [(set (match_dup 0)
16377 +        (ashiftrt:SI (plus:SI (match_dup 0)
16378 +                              (match_dup 1))
16379 +                     (match_dup 2)))]
16380 +  )
16381 +
16382 +(define_peephole
16383 +  [(set (match_operand:SI 0 "register_operand" "r")
16384 +       (plus:SI (match_dup 0)
16385 +                 (match_operand:SI 1 "immediate_operand" "i")))
16386 +   (set (match_dup 0)
16387 +       (ashiftrt:SI (match_dup 0)
16388 +                     (match_operand:SI 2 "immediate_operand" "i")))]
16389 +  "avr32_rnd_operands(operands[1], operands[2])"
16390 +
16391 +  "satrnds    %0 >> %2, 31"
16392 +
16393 +  [(set_attr "type" "alu_sat")
16394 +   (set_attr "length" "4")
16395 +   (set_attr "cc" "clobber")]
16396 +
16397 +  )
16398 +
16399 +
16400 +;;=================================================================
16401 +;; mcall
16402 +;;=================================================================
16403 +(define_peephole
16404 +  [(set (match_operand:SI 0 "register_operand"        "")
16405 +       (match_operand 1 "avr32_const_pool_ref_operand"  ""))
16406 +   (parallel [(call (mem:SI (match_dup 0))
16407 +                    (match_operand 2 "" ""))
16408 +              (clobber (reg:SI LR_REGNUM))])]
16409 +  "dead_or_set_p(insn, operands[0])"
16410 +  "mcall    %1"
16411 +  [(set_attr "type" "call")
16412 +   (set_attr "length" "4")
16413 +   (set_attr "cc" "clobber")]
16414 +)
16415 +
16416 +(define_peephole
16417 +  [(set (match_operand:SI 2 "register_operand"        "")
16418 +       (match_operand 1 "avr32_const_pool_ref_operand"  ""))
16419 +   (parallel [(set (match_operand 0 "register_operand" "")
16420 +                   (call (mem:SI (match_dup 2))
16421 +                         (match_operand 3 "" "")))
16422 +              (clobber (reg:SI LR_REGNUM))])]
16423 +  "dead_or_set_p(insn, operands[2])"
16424 +  "mcall    %1"
16425 +  [(set_attr "type" "call")
16426 +   (set_attr "length" "4")
16427 +   (set_attr "cc" "call_set")]
16428 +)
16429 +
16430 +
16431 +(define_peephole2
16432 +  [(set (match_operand:SI 0 "register_operand"    "")
16433 +       (match_operand 1 "avr32_const_pool_ref_operand"  ""))
16434 +   (parallel [(call (mem:SI (match_dup 0))
16435 +                    (match_operand 2 "" ""))
16436 +              (clobber (reg:SI LR_REGNUM))])]
16437 +  "peep2_reg_dead_p(2, operands[0])"
16438 +  [(parallel [(call (mem:SI (match_dup 1))
16439 +                    (match_dup 2))
16440 +              (clobber (reg:SI LR_REGNUM))])]
16441 +  ""
16442 +)
16443 +
16444 +(define_peephole2
16445 +  [(set (match_operand:SI 0 "register_operand"        "")
16446 +       (match_operand 1 "avr32_const_pool_ref_operand"  ""))
16447 +   (parallel [(set (match_operand 2 "register_operand" "")
16448 +                   (call (mem:SI (match_dup 0))
16449 +                         (match_operand 3 "" "")))
16450 +              (clobber (reg:SI LR_REGNUM))])]
16451 +  "(peep2_reg_dead_p(2, operands[0]) || (REGNO(operands[2]) == REGNO(operands[0])))"
16452 +  [(parallel [(set (match_dup 2)
16453 +                   (call (mem:SI (match_dup 1))
16454 +                         (match_dup 3)))
16455 +              (clobber (reg:SI LR_REGNUM))])]
16456 +  ""
16457 +)
16458 +
16459 +;;=================================================================
16460 +;; Returning a value
16461 +;;=================================================================
16462 +
16463 +
16464 +(define_peephole
16465 +  [(set (match_operand 0 "register_operand" "")
16466 +        (match_operand 1 "register_operand" ""))
16467 +   (return)]
16468 +  "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM)
16469 +   && (REGNO(operands[1]) != LR_REGNUM)
16470 +   && (REGNO_REG_CLASS(REGNO(operands[1])) == GENERAL_REGS)"
16471 +  "retal    %1"
16472 +  [(set_attr "type" "call")
16473 +   (set_attr "length" "2")]
16474 +  )
16475 +
16476 +
16477 +(define_peephole
16478 +  [(set (match_operand 0 "register_operand" "r")
16479 +        (match_operand 1 "immediate_operand" "i"))
16480 +   (return)]
16481 +  "(USE_RETURN_INSN (FALSE) && (REGNO(operands[0]) == RETVAL_REGNUM) &&
16482 +   ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1)))"
16483 +  {
16484 +    avr32_output_return_instruction (TRUE, FALSE, NULL, operands[1]);
16485 +    return "";
16486 +  }
16487 +  [(set_attr "type" "call")
16488 +   (set_attr "length" "4")]
16489 +  )
16490 +
16491 +(define_peephole
16492 +  [(set (match_operand 0 "register_operand" "r")
16493 +        (match_operand 1 "immediate_operand" "i"))
16494 +   (unspec_volatile [(return)] VUNSPEC_EPILOGUE)]
16495 +  "(REGNO(operands[0]) == RETVAL_REGNUM) &&
16496 +   ((INTVAL(operands[1]) == -1) || (INTVAL(operands[1]) == 0) || (INTVAL(operands[1]) == 1))"
16497 +  {
16498 +    avr32_output_return_instruction (FALSE, FALSE, NULL, operands[1]);
16499 +    return "";
16500 +  }
16501 +  ; Length is absolute worst case
16502 +  [(set_attr "type" "branch")
16503 +   (set_attr "length" "12")]
16504 +  )
16505 +
16506 +(define_peephole
16507 +  [(set (match_operand 0 "register_operand" "=r")
16508 +        (if_then_else (match_operator 1 "avr32_comparison_operator"
16509 +                                      [(match_operand 4 "register_operand" "r")
16510 +                                       (match_operand 5 "register_immediate_operand" "rKs21")])
16511 +                      (match_operand 2 "avr32_cond_register_immediate_operand" "rKs08")
16512 +                      (match_operand 3 "avr32_cond_register_immediate_operand" "rKs08")))
16513 +   (return)]
16514 +  "USE_RETURN_INSN (TRUE) && (REGNO(operands[0]) == RETVAL_REGNUM)"
16515 +  {
16516 +   operands[1] = avr32_output_cmp(operands[1], GET_MODE(operands[4]), operands[4], operands[5]);
16517 +
16518 +   if ( GET_CODE(operands[2]) == REG
16519 +        && GET_CODE(operands[3]) == REG
16520 +        && REGNO(operands[2]) != LR_REGNUM
16521 +        && REGNO(operands[3]) != LR_REGNUM ){
16522 +      return "ret%1    %2\;ret%i1    %3";
16523 +   } else if ( GET_CODE(operands[2]) == REG
16524 +               && GET_CODE(operands[3]) == CONST_INT ){
16525 +      if ( INTVAL(operands[3]) == -1
16526 +           || INTVAL(operands[3]) == 0
16527 +           || INTVAL(operands[3]) == 1 ){
16528 +        return "ret%1    %2\;ret%i1    %d3";
16529 +      } else {
16530 +        return "mov%1    r12, %2\;mov%i1    r12, %3\;retal    r12";
16531 +      }
16532 +   } else if ( GET_CODE(operands[2]) == CONST_INT
16533 +               && GET_CODE(operands[3]) == REG ){
16534 +      if ( INTVAL(operands[2]) == -1
16535 +           || INTVAL(operands[2]) == 0
16536 +           || INTVAL(operands[2]) == 1 ){
16537 +        return "ret%1    %d2\;ret%i1    %3";
16538 +      } else {
16539 +        return "mov%1    r12, %2\;mov%i1    r12, %3\;retal    r12";
16540 +      }
16541 +   } else {
16542 +      if ( (INTVAL(operands[2]) == -1
16543 +            || INTVAL(operands[2]) == 0
16544 +            || INTVAL(operands[2]) == 1 )
16545 +           && (INTVAL(operands[3]) == -1
16546 +               || INTVAL(operands[3]) == 0
16547 +               || INTVAL(operands[3]) == 1 )){
16548 +        return "ret%1    %d2\;ret%i1    %d3";
16549 +      } else {
16550 +        return "mov%1    r12, %2\;mov%i1    r12, %3\;retal    r12";
16551 +      }
16552 +   }
16553 +  }
16554 +
16555 +  [(set_attr "length" "10")
16556 +   (set_attr "cc" "none")
16557 +   (set_attr "type" "call")])
16558 +  
16559 +
16560 +
16561 +;;=================================================================
16562 +;; mulnhh.w
16563 +;;=================================================================
16564 +
16565 +(define_peephole2
16566 +  [(set (match_operand:HI 0 "register_operand" "")
16567 +        (neg:HI (match_operand:HI 1 "register_operand" "")))
16568 +   (set (match_operand:SI 2 "register_operand" "")
16569 +        (mult:SI
16570 +         (sign_extend:SI (match_dup 0))
16571 +         (sign_extend:SI (match_operand:HI 3 "register_operand" ""))))]
16572 +  "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))"
16573 +  [ (set (match_dup 2)
16574 +         (mult:SI
16575 +          (sign_extend:SI (neg:HI (match_dup 1)))
16576 +          (sign_extend:SI (match_dup 3))))]
16577 +  ""
16578 +  )
16579 +
16580 +(define_peephole2
16581 +  [(set (match_operand:HI 0 "register_operand" "")
16582 +        (neg:HI (match_operand:HI 1 "register_operand" "")))
16583 +   (set (match_operand:SI 2 "register_operand" "")
16584 +        (mult:SI
16585 +         (sign_extend:SI (match_operand:HI 3 "register_operand" ""))
16586 +         (sign_extend:SI (match_dup 0))))]
16587 +  "(peep2_reg_dead_p(2, operands[0])) || (REGNO(operands[2]) == REGNO(operands[0]))"
16588 +  [ (set (match_dup 2)
16589 +         (mult:SI
16590 +          (sign_extend:SI (neg:HI (match_dup 1)))
16591 +          (sign_extend:SI (match_dup 3))))]
16592 +  ""
16593 +  )
16594 +
16595 +
16596 +
16597 +;;=================================================================
16598 +;; Vector set and extract operations
16599 +;;=================================================================
16600 +(define_insn "vec_setv2hi_hi"
16601 +  [(set (match_operand:V2HI 0 "register_operand" "=r")
16602 +        (vec_merge:V2HI
16603 +         (match_dup 0)
16604 +         (vec_duplicate:V2HI
16605 +          (match_operand:HI 1 "register_operand" "r"))
16606 +         (const_int 1)))]
16607 +  ""
16608 +  "bfins\t%0, %1, 16, 16"
16609 +  [(set_attr "type" "alu")
16610 +   (set_attr "length" "4")
16611 +   (set_attr "cc" "clobber")])
16612 +
16613 +(define_insn "vec_setv2hi_lo"
16614 +  [(set (match_operand:V2HI 0 "register_operand" "+r")
16615 +        (vec_merge:V2HI
16616 +         (match_dup 0)
16617 +         (vec_duplicate:V2HI
16618 +          (match_operand:HI 1 "register_operand" "r"))
16619 +         (const_int 2)))]
16620 +  ""
16621 +  "bfins\t%0, %1, 0, 16"
16622 +  [(set_attr "type" "alu")
16623 +   (set_attr "length" "4")
16624 +   (set_attr "cc" "clobber")])
16625 +
16626 +(define_expand "vec_setv2hi"
16627 +  [(set (match_operand:V2HI 0 "register_operand" "")
16628 +        (vec_merge:V2HI
16629 +         (match_dup 0)
16630 +         (vec_duplicate:V2HI
16631 +          (match_operand:HI 1 "register_operand" ""))
16632 +         (match_operand 2 "immediate_operand" "")))]
16633 +  ""
16634 +  { operands[2] = GEN_INT(INTVAL(operands[2]) + 1); }
16635 +  )
16636 +
16637 +(define_insn "vec_extractv2hi"
16638 +  [(set (match_operand:HI 0 "register_operand" "=r")
16639 +        (vec_select:HI
16640 +         (match_operand:V2HI 1 "register_operand" "r")
16641 +         (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
16642 +  ""
16643 +  {
16644 +   if ( INTVAL(operands[2]) == 0 )
16645 +      return "bfextu\t%0, %1, 16, 16";
16646 +   else
16647 +      return "bfextu\t%0, %1, 0, 16";
16648 +  }
16649 +  [(set_attr "type" "alu")
16650 +   (set_attr "length" "4")
16651 +   (set_attr "cc" "clobber")])
16652 +
16653 +(define_insn "vec_extractv4qi"
16654 +  [(set (match_operand:QI 0 "register_operand" "=r")
16655 +        (vec_select:QI
16656 +         (match_operand:V4QI 1 "register_operand" "r")
16657 +         (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
16658 +  ""
16659 +  {
16660 +   switch ( INTVAL(operands[2]) ){
16661 +     case 0:
16662 +       return "bfextu\t%0, %1, 24, 8";
16663 +     case 1:
16664 +       return "bfextu\t%0, %1, 16, 8";
16665 +     case 2:
16666 +       return "bfextu\t%0, %1, 8, 8";
16667 +     case 3:
16668 +       return "bfextu\t%0, %1, 0, 8";
16669 +     default:
16670 +       abort();
16671 +   }
16672 +  }
16673 +  [(set_attr "type" "alu")
16674 +   (set_attr "length" "4")
16675 +   (set_attr "cc" "clobber")])
16676 +
16677 +
16678 +(define_insn "concatv2hi"
16679 +  [(set (match_operand:V2HI 0 "register_operand" "=r, r, r")
16680 +        (vec_concat:V2HI
16681 +         (match_operand:HI 1 "register_operand" "r, r, 0")
16682 +         (match_operand:HI 2 "register_operand" "r, 0, r")))]
16683 +  ""
16684 +  "@
16685 +   mov\t%0, %1\;bfins\t%0, %2, 0, 16
16686 +   bfins\t%0, %2, 0, 16
16687 +   bfins\t%0, %1, 16, 16"
16688 +  [(set_attr "length" "6, 4, 4")
16689 +   (set_attr "type" "alu")])
16690 +
16691 +
16692 +;; Load the atomic operation description
16693 +(include "sync.md")
16694 +
16695 +;; Load the SIMD description
16696 +(include "simd.md")
16697 +
16698 +;; Include the FPU for uc3
16699 +(include "uc3fpu.md")
16700 --- /dev/null
16701 +++ b/gcc/config/avr32/avr32-modes.def
16702 @@ -0,0 +1 @@
16703 +VECTOR_MODES (INT, 4);        /*            V4QI V2HI */
16704 --- /dev/null
16705 +++ b/gcc/config/avr32/avr32.opt
16706 @@ -0,0 +1,93 @@
16707 +; Options for the ATMEL AVR32 port of the compiler.
16708 +
16709 +; Copyright 2007 Atmel Corporation.
16710 +;
16711 +; This file is part of GCC.
16712 +;
16713 +; GCC is free software; you can redistribute it and/or modify it under
16714 +; the terms of the GNU General Public License as published by the Free
16715 +; Software Foundation; either version 2, or (at your option) any later
16716 +; version.
16717 +;
16718 +; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
16719 +; WARRANTY; without even the implied warranty of MERCHANTABILITY or
16720 +; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16721 +; for more details.
16722 +;
16723 +; You should have received a copy of the GNU General Public License
16724 +; along with GCC; see the file COPYING.  If not, write to the Free
16725 +; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
16726 +; 02110-1301, USA.
16727 +
16728 +muse-rodata-section
16729 +Target Report Mask(USE_RODATA_SECTION)
16730 +Use section .rodata for read-only data instead of .text.
16731 +
16732 +mhard-float
16733 +Target Report Mask(HARD_FLOAT)
16734 +Use FPU instructions instead of floating point emulation.
16735 +
16736 +msoft-float
16737 +Target Report InverseMask(HARD_FLOAT, SOFT_FLOAT)
16738 +Use floating point emulation for floating point operations.
16739 +
16740 +mforce-double-align
16741 +Target Report RejectNegative Mask(FORCE_DOUBLE_ALIGN)
16742 +Force double-word alignment for double-word memory accesses.
16743 +
16744 +mno-init-got
16745 +Target Report RejectNegative Mask(NO_INIT_GOT)
16746 +Do not initialize GOT register before using it when compiling PIC code.
16747 +
16748 +mrelax
16749 +Target Report Mask(RELAX)
16750 +Let invoked assembler and linker do relaxing (Enabled by default when optimization level is >1).
16751 +
16752 +mmd-reorg-opt
16753 +Target Report Undocumented Mask(MD_REORG_OPTIMIZATION)
16754 +Perform machine dependent optimizations in reorg stage.
16755 +
16756 +masm-addr-pseudos
16757 +Target Report Mask(HAS_ASM_ADDR_PSEUDOS) 
16758 +Use assembler pseudo-instructions lda.w and call for handling direct addresses. (Enabled by default)
16759 +
16760 +mpart=
16761 +Target Report RejectNegative Joined Var(avr32_part_name)
16762 +Specify the AVR32 part name
16763 +
16764 +mcpu=
16765 +Target Report RejectNegative Joined Undocumented Var(avr32_part_name)
16766 +Specify the AVR32 part name (deprecated)
16767 +
16768 +march=
16769 +Target Report RejectNegative Joined Var(avr32_arch_name)
16770 +Specify the AVR32 architecture name
16771 +
16772 +mfast-float
16773 +Target Report Mask(FAST_FLOAT)
16774 +Enable fast floating-point library. Enabled by default if the -funsafe-math-optimizations switch is specified.
16775 +
16776 +mimm-in-const-pool
16777 +Target Report Var(avr32_imm_in_const_pool) Init(-1)
16778 +Put large immediates in constant pool. This is enabled by default for archs with insn-cache.
16779 +
16780 +mno-pic
16781 +Target Report RejectNegative Mask(NO_PIC)
16782 +Do not generate position-independent code. (deprecated, use -fno-pic instead)
16783 +
16784 +mcond-exec-before-reload
16785 +Target Report Undocumented Mask(COND_EXEC_BEFORE_RELOAD) 
16786 +Enable experimental conditional execution preparation before the reload stage. 
16787 +
16788 +mrmw-addressable-data
16789 +Target Report Mask(RMW_ADDRESSABLE_DATA)
16790 +Signal that all data is in range for the Atomic Read-Modify-Write memory instructions, and that
16791 +gcc can safely generate these whenever possible. 
16792 +
16793 +mflashvault
16794 +Target Var(TARGET_FLASHVAULT)
16795 +Generate code for flashvault
16796 +
16797 +mlist-devices
16798 +Target RejectNegative Var(avr32_list_supported_parts)
16799 +Print the list of parts supported while printing --target-help.
16800 --- /dev/null
16801 +++ b/gcc/config/avr32/avr32-protos.h
16802 @@ -0,0 +1,196 @@
16803 +/*
16804 +   Prototypes for exported functions defined in avr32.c
16805 +   Copyright 2003,2004,2005,2006,2007,2008,2009 Atmel Corporation.
16806 +
16807 +   This file is part of GCC.
16808 +
16809 +   This program is free software; you can redistribute it and/or modify
16810 +   it under the terms of the GNU General Public License as published by
16811 +   the Free Software Foundation; either version 2 of the License, or
16812 +   (at your option) any later version.
16813 +
16814 +   This program is distributed in the hope that it will be useful,
16815 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
16816 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16817 +   GNU General Public License for more details.
16818 +
16819 +   You should have received a copy of the GNU General Public License
16820 +   along with this program; if not, write to the Free Software
16821 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
16822 +
16823 +
16824 +#ifndef AVR32_PROTOS_H
16825 +#define AVR32_PROTOS_H
16826 +
16827 +extern const int swap_reg[];
16828 +
16829 +extern int avr32_valid_macmac_bypass (rtx, rtx);
16830 +extern int avr32_valid_mulmac_bypass (rtx, rtx);
16831 +
16832 +extern int avr32_decode_lcomm_symbol_offset (rtx, int *);
16833 +extern void avr32_encode_lcomm_symbol_offset (tree, char *, int);
16834 +
16835 +extern const char *avr32_strip_name_encoding (const char *);
16836 +
16837 +extern rtx avr32_get_note_reg_equiv (rtx insn);
16838 +
16839 +extern int avr32_use_return_insn (int iscond);
16840 +
16841 +extern void avr32_make_reglist16 (int reglist16_vect, char *reglist16_string);
16842 +
16843 +extern void avr32_make_reglist8 (int reglist8_vect, char *reglist8_string);
16844 +extern void avr32_make_fp_reglist_w (int reglist_mask, char *reglist_string);
16845 +extern void avr32_make_fp_reglist_d (int reglist_mask, char *reglist_string);
16846 +
16847 +extern void avr32_output_return_instruction (int single_ret_inst,
16848 +                                            int iscond, rtx cond,
16849 +                                            rtx r12_imm);
16850 +extern void avr32_expand_prologue (void);
16851 +extern void avr32_set_return_address (rtx source, rtx scratch);
16852 +
16853 +extern int avr32_hard_regno_mode_ok (int regno, enum machine_mode mode);
16854 +extern int avr32_extra_constraint_s (rtx value, const int strict);
16855 +extern int avr32_eh_return_data_regno (const int n);
16856 +extern int avr32_initial_elimination_offset (const int from, const int to);
16857 +extern rtx avr32_function_arg (CUMULATIVE_ARGS * cum, enum machine_mode mode,
16858 +                              tree type, int named);
16859 +extern void avr32_init_cumulative_args (CUMULATIVE_ARGS * cum, tree fntype,
16860 +                                       rtx libname, tree fndecl);
16861 +extern void avr32_function_arg_advance (CUMULATIVE_ARGS * cum,
16862 +                                       enum machine_mode mode,
16863 +                                       tree type, int named);
16864 +#ifdef ARGS_SIZE_RTX
16865 +/* expr.h defines ARGS_SIZE_RTX and `enum direction'.  */
16866 +extern enum direction avr32_function_arg_padding (enum machine_mode mode,
16867 +                                                 tree type);
16868 +#endif /* ARGS_SIZE_RTX */
16869 +extern rtx avr32_function_value (tree valtype, tree func, bool outgoing);
16870 +extern rtx avr32_libcall_value (enum machine_mode mode);
16871 +extern int avr32_sched_use_dfa_pipeline_interface (void);
16872 +extern bool avr32_return_in_memory (tree type, tree fntype);
16873 +extern void avr32_regs_to_save (char *operand);
16874 +extern void avr32_target_asm_function_prologue (FILE * file,
16875 +                                               HOST_WIDE_INT size);
16876 +extern void avr32_target_asm_function_epilogue (FILE * file,
16877 +                                               HOST_WIDE_INT size);
16878 +extern void avr32_trampoline_template (FILE * file);
16879 +extern void avr32_initialize_trampoline (rtx addr, rtx fnaddr,
16880 +                                        rtx static_chain);
16881 +extern int avr32_legitimate_address (enum machine_mode mode, rtx x,
16882 +                                    int strict);
16883 +extern int avr32_legitimate_constant_p (rtx x);
16884 +
16885 +extern int avr32_legitimate_pic_operand_p (rtx x);
16886 +
16887 +extern rtx avr32_find_symbol (rtx x);
16888 +extern void avr32_select_section (rtx exp, int reloc, int align);
16889 +extern void avr32_encode_section_info (tree decl, rtx rtl, int first);
16890 +extern void avr32_asm_file_end (FILE * stream);
16891 +extern void avr32_asm_output_ascii (FILE * stream, char *ptr, int len);
16892 +extern void avr32_asm_output_common (FILE * stream, const char *name,
16893 +                                    int size, int rounded);
16894 +extern void avr32_asm_output_label (FILE * stream, const char *name);
16895 +extern void avr32_asm_declare_object_name (FILE * stream, char *name,
16896 +                                          tree decl);
16897 +extern void avr32_asm_globalize_label (FILE * stream, const char *name);
16898 +extern void avr32_asm_weaken_label (FILE * stream, const char *name);
16899 +extern void avr32_asm_output_external (FILE * stream, tree decl,
16900 +                                      const char *name);
16901 +extern void avr32_asm_output_external_libcall (FILE * stream, rtx symref);
16902 +extern void avr32_asm_output_labelref (FILE * stream, const char *name);
16903 +extern void avr32_notice_update_cc (rtx exp, rtx insn);
16904 +extern void avr32_print_operand (FILE * stream, rtx x, int code);
16905 +extern void avr32_print_operand_address (FILE * stream, rtx x);
16906 +
16907 +extern int avr32_symbol (rtx x);
16908 +
16909 +extern void avr32_select_rtx_section (enum machine_mode mode, rtx x,
16910 +                                     unsigned HOST_WIDE_INT align);
16911 +
16912 +extern int avr32_load_multiple_operation (rtx op, enum machine_mode mode);
16913 +extern int avr32_store_multiple_operation (rtx op, enum machine_mode mode);
16914 +
16915 +extern int avr32_const_ok_for_constraint_p (HOST_WIDE_INT value, char c,
16916 +                                           const char *str);
16917 +
16918 +extern bool avr32_cannot_force_const_mem (rtx x);
16919 +
16920 +extern void avr32_init_builtins (void);
16921 +
16922 +extern rtx avr32_expand_builtin (tree exp, rtx target, rtx subtarget,
16923 +                                enum machine_mode mode, int ignore);
16924 +
16925 +extern bool avr32_must_pass_in_stack (enum machine_mode mode, tree type);
16926 +
16927 +extern bool avr32_strict_argument_naming (CUMULATIVE_ARGS * ca);
16928 +
16929 +extern bool avr32_pass_by_reference (CUMULATIVE_ARGS * cum,
16930 +                                    enum machine_mode mode,
16931 +                                    tree type, bool named);
16932 +
16933 +extern rtx avr32_gen_load_multiple (rtx * regs, int count, rtx from,
16934 +                                   int write_back, int in_struct_p,
16935 +                                   int scalar_p);
16936 +extern rtx avr32_gen_store_multiple (rtx * regs, int count, rtx to,
16937 +                                    int in_struct_p, int scalar_p);
16938 +extern int avr32_gen_movmemsi (rtx * operands);
16939 +
16940 +extern int avr32_rnd_operands (rtx add, rtx shift);
16941 +extern int avr32_adjust_insn_length (rtx insn, int length);
16942 +
16943 +extern int symbol_mentioned_p (rtx x);
16944 +extern int label_mentioned_p (rtx x);
16945 +extern rtx legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg);
16946 +extern int avr32_address_register_rtx_p (rtx x, int strict_p);
16947 +extern int avr32_legitimate_index_p (enum machine_mode mode, rtx index,
16948 +                                    int strict_p);
16949 +
16950 +extern int avr32_const_double_immediate (rtx value);
16951 +extern void avr32_init_expanders (void);
16952 +extern rtx avr32_return_addr (int count, rtx frame);
16953 +extern bool avr32_got_mentioned_p (rtx addr);
16954 +
16955 +extern void avr32_final_prescan_insn (rtx insn, rtx * opvec, int noperands);
16956 +
16957 +extern int avr32_expand_movcc (enum machine_mode mode, rtx operands[]);
16958 +extern int avr32_expand_addcc (enum machine_mode mode, rtx operands[]);
16959 +#ifdef RTX_CODE
16960 +extern int avr32_expand_scc (RTX_CODE cond, rtx * operands);
16961 +#endif
16962 +
16963 +extern int avr32_store_bypass (rtx insn_out, rtx insn_in);
16964 +extern int avr32_mul_waw_bypass (rtx insn_out, rtx insn_in);
16965 +extern int avr32_valid_load_double_bypass (rtx insn_out, rtx insn_in);
16966 +extern int avr32_valid_load_quad_bypass (rtx insn_out, rtx insn_in);
16967 +extern rtx avr32_output_cmp (rtx cond, enum machine_mode mode,
16968 +                            rtx op0, rtx op1);
16969 +
16970 +rtx get_next_insn_cond (rtx cur_insn);
16971 +int set_next_insn_cond (rtx cur_insn, rtx cond);
16972 +rtx next_insn_emits_cmp (rtx cur_insn);
16973 +void avr32_override_options (void);
16974 +void avr32_load_pic_register (void);
16975 +#ifdef GCC_BASIC_BLOCK_H
16976 +rtx avr32_ifcvt_modify_insn (ce_if_block_t *ce_info, rtx pattern, rtx insn, 
16977 +                             int *num_true_changes);
16978 +rtx avr32_ifcvt_modify_test (ce_if_block_t *ce_info, rtx test );
16979 +void avr32_ifcvt_modify_cancel ( ce_if_block_t *ce_info, int *num_true_changes);
16980 +#endif
16981 +void avr32_optimization_options (int level, int size);
16982 +int avr32_const_ok_for_move (HOST_WIDE_INT c);
16983 +
16984 +void avr32_split_const_expr (enum machine_mode mode,
16985 +                             enum machine_mode new_mode,
16986 +                             rtx expr, 
16987 +                             rtx *split_expr);
16988 +void avr32_get_intval (enum machine_mode mode,
16989 +                       rtx const_expr, 
16990 +                       HOST_WIDE_INT *val);
16991 +
16992 +int avr32_cond_imm_clobber_splittable (rtx insn, 
16993 +                                       rtx operands[]);
16994 +
16995 +bool avr32_flashvault_call(tree decl);
16996 +extern void avr32_emit_swdivsf (rtx, rtx, rtx);
16997 +
16998 +#endif /* AVR32_PROTOS_H */
16999 --- /dev/null
17000 +++ b/gcc/config/avr32/crti.asm
17001 @@ -0,0 +1,64 @@
17002 +/*
17003 +   Init/fini stuff for AVR32.
17004 +   Copyright 2003-2006 Atmel Corporation.
17005 +
17006 +   Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
17007 +
17008 +   This file is part of GCC.
17009 +
17010 +   This program is free software; you can redistribute it and/or modify
17011 +   it under the terms of the GNU General Public License as published by
17012 +   the Free Software Foundation; either version 2 of the License, or
17013 +   (at your option) any later version.
17014 +
17015 +   This program is distributed in the hope that it will be useful,
17016 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
17017 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17018 +   GNU General Public License for more details.
17019 +
17020 +   You should have received a copy of the GNU General Public License
17021 +   along with this program; if not, write to the Free Software
17022 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17023 +
17024 +       
17025 +/* The code in sections .init and .fini is supposed to be a single
17026 +   regular function.  The function in .init is called directly from
17027 +   start in crt1.asm.  The function in .fini is atexit()ed in crt1.asm
17028 +   too.
17029 +
17030 +   crti.asm contributes the prologue of a function to these sections,
17031 +   and crtn.asm comes up the epilogue.  STARTFILE_SPEC should list
17032 +   crti.o before any other object files that might add code to .init
17033 +   or .fini sections, and ENDFILE_SPEC should list crtn.o after any
17034 +   such object files.  */
17035 +               
17036 +       .file           "crti.asm"
17037 +
17038 +       .section        ".init"
17039 +/* Just load the GOT */
17040 +       .align 2
17041 +       .global _init
17042 +_init:
17043 +       stm     --sp, r6, lr
17044 +       lddpc   r6, 1f          
17045 +0:     
17046 +       rsub    r6, pc
17047 +       rjmp    2f
17048 +       .align  2
17049 +1:     .long   0b - _GLOBAL_OFFSET_TABLE_              
17050 +2:     
17051 +                               
17052 +       .section        ".fini"
17053 +/* Just load the GOT */
17054 +       .align  2
17055 +       .global _fini
17056 +_fini:
17057 +       stm     --sp, r6, lr
17058 +       lddpc   r6, 1f          
17059 +0:     
17060 +       rsub    r6, pc
17061 +       rjmp    2f
17062 +       .align  2
17063 +1:     .long   0b - _GLOBAL_OFFSET_TABLE_              
17064 +2:     
17065 +
17066 --- /dev/null
17067 +++ b/gcc/config/avr32/crtn.asm
17068 @@ -0,0 +1,44 @@
17069 +/*   Copyright (C) 2001 Free Software Foundation, Inc.
17070 +    Written By Nick Clifton
17071 +
17072 +  This file is free software; you can redistribute it and/or modify it
17073 +  under the terms of the GNU General Public License as published by the
17074 +  Free Software Foundation; either version 2, or (at your option) any
17075 +  later version.
17076 +
17077 +  In addition to the permissions in the GNU General Public License, the
17078 +  Free Software Foundation gives you unlimited permission to link the
17079 +  compiled version of this file with other programs, and to distribute
17080 +  those programs without any restriction coming from the use of this
17081 +  file.  (The General Public License restrictions do apply in other
17082 +  respects; for example, they cover modification of the file, and
17083 +  distribution when not linked into another program.)
17084 +
17085 +  This file is distributed in the hope that it will be useful, but
17086 +  WITHOUT ANY WARRANTY; without even the implied warranty of
17087 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17088 +  General Public License for more details.
17089 +
17090 +  You should have received a copy of the GNU General Public License
17091 +  along with this program; see the file COPYING.  If not, write to
17092 +  the Free Software Foundation, 59 Temple Place - Suite 330,
17093 +  Boston, MA 02111-1307, USA.
17094 +
17095 +     As a special exception, if you link this library with files
17096 +     compiled with GCC to produce an executable, this does not cause
17097 +     the resulting executable to be covered by the GNU General Public License.
17098 +     This exception does not however invalidate any other reasons why
17099 +     the executable file might be covered by the GNU General Public License.
17100 +*/
17101 +
17102 +
17103 +
17104 +       
17105 +       .file           "crtn.asm"
17106 +
17107 +       .section        ".init"
17108 +       ldm     sp++, r6, pc
17109 +                       
17110 +       .section        ".fini"
17111 +       ldm     sp++, r6, pc
17112 +               
17113 --- /dev/null
17114 +++ b/gcc/config/avr32/lib1funcs.S
17115 @@ -0,0 +1,2903 @@
17116 +/* Macro for moving immediate value to register. */    
17117 +.macro mov_imm reg, imm
17118 +.if    (((\imm & 0xfffff) == \imm) || ((\imm | 0xfff00000) == \imm))
17119 +       mov     \reg, \imm
17120 +#if __AVR32_UC__ >= 2
17121 +.elseif        ((\imm & 0xffff) == 0)
17122 +       movh    \reg, hi(\imm)
17123 +
17124 +#endif
17125 +.else
17126 +       mov     \reg, lo(\imm)
17127 +       orh     \reg, hi(\imm)
17128 +.endif
17129 +.endm
17130 +       
17131 +       
17132 +        
17133 +/* Adjust the unpacked double number if it is a subnormal number.
17134 +   The exponent and mantissa pair are stored
17135 +   in [mant_hi,mant_lo] and [exp]. A register with the correct sign bit in
17136 +   the MSB is passed in [sign]. Needs two scratch
17137 +   registers [scratch1] and [scratch2]. An adjusted and packed double float
17138 +   is present in [mant_hi,mant_lo] after macro has executed */
17139 +.macro  adjust_subnormal_df     exp, mant_lo, mant_hi, sign, scratch1, scratch2 
17140 +        /* We have an exponent which is <=0 indicating a subnormal number
17141 +           As it should be stored as if the exponent was 1 (although the
17142 +           exponent field is all zeros to indicate a subnormal number)
17143 +           we have to shift down the mantissa to its correct position. */
17144 +        neg     \exp
17145 +        sub     \exp,-1                   /* amount to shift down */
17146 +        cp.w    \exp,54
17147 +        brlo    50f                     /* if more than 53 shift steps, the
17148 +                                           entire mantissa will disappear
17149 +                                           without any rounding to occur */
17150 +        mov     \mant_hi, 0
17151 +        mov     \mant_lo, 0
17152 +        rjmp    52f
17153 +50:     
17154 +        sub     \exp,-10                /* do the shift to position the
17155 +                                           mantissa at the same time
17156 +                                           note! this does not include the
17157 +                                           final 1 step shift to add the sign */
17158
17159 +        /* when shifting, save all shifted out bits in [scratch2]. we may need to
17160 +           look at them to make correct rounding. */
17161
17162 +        rsub    \scratch1,\exp,32       /* get inverted shift count */
17163 +        cp.w    \exp,32                 /* handle shifts >= 32 separately */
17164 +        brhs    51f
17165
17166 +        /* small (<32) shift amount, both words are part of the shift */
17167 +        lsl     \scratch2,\mant_lo,\scratch1               /* save bits to shift out from lsw*/
17168 +        lsl     \scratch1,\mant_hi,\scratch1               /* get bits from msw destined for lsw*/
17169 +        lsr     \mant_lo,\mant_lo,\exp                     /* shift down lsw */
17170 +        lsr     \mant_hi,\mant_hi,\exp                     /* shift down msw */
17171 +        or      \mant_hi,\scratch1                         /* add bits from msw with prepared lsw */
17172 +        rjmp    50f
17173
17174 +        /* large (>=32) shift amount, only lsw will have bits left after shift.
17175 +           note that shift operations will use ((shift count) mod 32) so
17176 +           we do not need to subtract 32 from shift count. */
17177 +51:
17178 +        lsl     \scratch2,\mant_hi,\scratch1               /* save bits to shift out from msw */
17179 +        or      \scratch2,\mant_lo                         /* also save all bits from lsw */
17180 +        mov     \mant_lo,\mant_hi                          /* msw -> lsw (i.e. "shift 32 first") */
17181 +        mov     \mant_hi,0                                 /* clear msw */
17182 +        lsr     \mant_lo,\mant_lo,\exp                     /* make rest of shift inside lsw */
17183
17184 +50:
17185 +        /* result is almost ready to return, except that least significant bit
17186 +           and the part we already shifted out may cause the result to be
17187 +           rounded */
17188 +        bld     \mant_lo,0                   /* get bit to be shifted out */
17189 +        brcc    51f                          /* if bit was 0, no rounding */
17190
17191 +        /* msb of part to remove is 1, so rounding depends on rest of bits */
17192 +        tst     \scratch2,\scratch2                   /* get shifted out tail */
17193 +        brne    50f     /* if rest > 0, do round */
17194 +        bld     \mant_lo,1                   /* we have to look at lsb in result */
17195 +        brcc    51f   /* if lsb is 0, don't round */
17196
17197 +50:
17198 +        /* subnormal result requires rounding
17199 +           rounding may cause subnormal to become smallest normal number
17200 +           luckily, smallest normal number has exactly the representation
17201 +           we got by rippling a one bit up from mantissa into exponent field. */
17202 +        sub     \mant_lo,-1
17203 +        subcc   \mant_hi,-1
17204
17205 +51:
17206 +        /* shift and return packed double with correct sign */
17207 +        rol     \sign
17208 +        ror     \mant_hi
17209 +        ror     \mant_lo        
17210 +52:     
17211 +.endm
17212
17213
17214 +/* Adjust subnormal single float number with exponent [exp]
17215 +   and mantissa [mant] and round.    */
17216 +.macro  adjust_subnormal_sf     sf, exp, mant, sign, scratch
17217 +        /* subnormal number */
17218 +        rsub    \exp,\exp, 1            /* shift amount */
17219 +        cp.w    \exp, 25
17220 +        movhs   \mant, 0                
17221 +        brhs    90f                     /* Return zero */
17222 +        rsub    \scratch, \exp, 32
17223 +        lsl     \scratch, \mant,\scratch/* Check if there are any bits set
17224 +                                           in the bits discarded in the mantissa */
17225 +        srne    \scratch                /* If so set the lsb of the shifted mantissa */ 
17226 +        lsr     \mant,\mant,\exp        /* Shift the mantissa */
17227 +        or      \mant, \scratch         /* Round lsb if any bits were shifted out  */
17228 +        /* Rounding :   For explaination, see round_sf. */
17229 +        mov     \scratch, 0x7f          /* Set rounding constant */
17230 +        bld     \mant, 8                
17231 +        subeq   \scratch, -1            /* For odd numbers use rounding constant 0x80 */
17232 +        add     \mant, \scratch         /* Add rounding constant to mantissa */
17233 +        /* We can't overflow because mantissa is at least shifted one position
17234 +           to the right so the implicit bit is zero. We can however get the implicit
17235 +           bit set after rounding which means that we have the lowest normal number
17236 +           but this is ok since this bit has the same position as the LSB of the
17237 +           exponent */
17238 +        lsr     \sf, \mant, 7
17239 +        /* Rotate in sign */
17240 +        lsl     \sign, 1
17241 +        ror     \sf
17242 +90:     
17243 +.endm
17244
17245
17246 +/* Round the unpacked df number with exponent [exp] and
17247 +   mantissa [mant_hi, mant_lo]. Uses scratch register
17248 +   [scratch] */
17249 +.macro  round_df        exp, mant_lo, mant_hi, scratch
17250 +        mov     \scratch, 0x3ff         /* Rounding constant */
17251 +        bld     \mant_lo,11             /* Check if lsb in the final result is  
17252 +                                           set */
17253 +        subeq   \scratch, -1            /* Adjust rounding constant to 0x400
17254 +                                           if rounding 0.5 upwards */   
17255 +        add     \mant_lo, \scratch      /* Round */
17256 +        acr     \mant_hi                /* If overflowing we know that
17257 +                                           we have all zeros in the bits not
17258 +                                           scaled out so we can leave them
17259 +                                           but we must increase the exponent with
17260 +                                           two since we had an implicit bit
17261 +                                           which is lost + the extra overflow bit */
17262 +        subcs   \exp, -2                /* Update exponent */
17263 +.endm           
17264
17265 +/* Round single float number stored in [mant] and [exp] */
17266 +.macro  round_sf        exp, mant, scratch
17267 +        /* Round:       
17268 +                For 0.5 we round to nearest even integer
17269 +                for all other cases we round to nearest integer.
17270 +                This means that if the digit left of the "point" (.)
17271 +                is 1 we can add 0x80 to the mantissa since the
17272 +                corner case 0x180 will round up to 0x200. If the
17273 +                digit left of the "point" is 0 we will have to
17274 +                add 0x7f since this will give 0xff and hence a
17275 +                truncation/rounding downwards for the corner
17276 +                case when the 9 lowest bits are 0x080 */
17277 +        mov     \scratch, 0x7f  /* Set rounding constant */
17278 +        /* Check if the mantissa is even or odd */
17279 +        bld     \mant, 8
17280 +        subeq   \scratch, -1    /* Rounding constant should be 0x80 */
17281 +        add     \mant, \scratch
17282 +        subcs   \exp, -2        /* Adjust exponent if we overflowed */          
17283 +.endm
17284
17285 +                 
17286
17287 +/* Pack a single float number stored in [mant] and [exp]
17288 +   into a single float number in [sf]  */
17289 +.macro  pack_sf sf, exp, mant
17290 +        bld     \mant,31                  /* implicit bit to z */
17291 +        subne   \exp,1                   /* if subnormal (implicit bit 0)
17292 +                                          adjust exponent to storage format */
17293 +        
17294 +        lsr     \sf, \mant, 7
17295 +        bfins   \sf, \exp, 24, 8
17296 +.endm   
17297
17298 +/* Pack exponent [exp] and mantissa [mant_hi, mant_lo]
17299 +   into [df_hi, df_lo].  [df_hi] is shifted
17300 +   one bit up so the sign bit can be shifted into it */
17301 +        
17302 +.macro  pack_df         exp, mant_lo, mant_hi, df_lo, df_hi
17303 +        bld     \mant_hi,31                  /* implicit bit to z */
17304 +        subne   \exp,1                   /* if subnormal (implicit bit 0)
17305 +                                          adjust exponent to storage format */
17306
17307 +        lsr     \mant_lo,11                  /* shift back lsw */
17308 +        or      \df_lo,\mant_lo,\mant_hi<<21          /* combine with low bits from msw */
17309 +        lsl     \mant_hi,1                   /* get rid of implicit bit */
17310 +        lsr     \mant_hi,11                  /* shift back msw except for one step*/
17311 +        or      \df_hi,\mant_hi,\exp<<21          /* combine msw with exponent */
17312 +.endm
17313
17314 +/* Normalize single float number stored in [mant] and [exp]
17315 +   using scratch register [scratch] */
17316 +.macro  normalize_sf    exp, mant, scratch
17317 +        /* Adjust exponent and mantissa */
17318 +        clz     \scratch, \mant
17319 +        sub     \exp, \scratch
17320 +        lsl     \mant, \mant, \scratch
17321 +.endm
17322
17323 +/* Normalize the exponent and mantissa pair stored
17324 +   in [mant_hi,mant_lo] and [exp]. Needs two scratch
17325 +   registers [scratch1] and [scratch2]. */
17326 +.macro  normalize_df            exp, mant_lo, mant_hi, scratch1, scratch2
17327 +        clz     \scratch1,\mant_hi     /* Check if we have zeros in high bits */
17328 +        breq    80f                     /* No need for scaling if no zeros in high bits */
17329 +        brcs    81f                     /* Check for all zeros */           
17330
17331 +        /* shift amount is smaller than 32, and involves both msw and lsw*/
17332 +        rsub    \scratch2,\scratch1,32  /* shift mantissa */
17333 +        lsl     \mant_hi,\mant_hi,\scratch1
17334 +        lsr     \scratch2,\mant_lo,\scratch2
17335 +        or      \mant_hi,\scratch2
17336 +        lsl     \mant_lo,\mant_lo,\scratch1
17337 +        sub     \exp,\scratch1          /* adjust exponent */
17338 +        rjmp    80f                     /* Finished */  
17339 +81:
17340 +        /* shift amount is greater than 32 */
17341 +        clz     \scratch1,\mant_lo      /* shift mantissa */
17342 +        movcs   \scratch1, 0
17343 +        subcc   \scratch1,-32
17344 +        lsl     \mant_hi,\mant_lo,\scratch1
17345 +        mov     \mant_lo,0
17346 +        sub     \exp,\scratch1          /* adjust exponent */
17347 +80:     
17348 +.endm
17349 +        
17350
17351 +/* Fast but approximate multiply of two 64-bit numbers to give a 64 bit result.
17352 +   The multiplication of [al]x[bl] is discarded.
17353 +   Operands in [ah], [al], [bh], [bl].
17354 +   Scratch registers in [sh], [sl].
17355 +   Returns results in registers [rh], [rl].*/
17356 +.macro  mul_approx_df   ah, al, bh, bl, rh, rl, sh, sl
17357 +        mulu.d  \sl, \ah, \bl
17358 +        macu.d  \sl, \al, \bh
17359 +        mulu.d  \rl, \ah, \bh
17360 +        add     \rl, \sh
17361 +        acr     \rh
17362 +.endm           
17363
17364
17365 +        
17366 +#if defined(L_avr32_f64_mul) || defined(L_avr32_f64_mul_fast)
17367 +        .align  2
17368 +#if defined(L_avr32_f64_mul)
17369 +        .global __avr32_f64_mul
17370 +        .type  __avr32_f64_mul,@function
17371 +__avr32_f64_mul:
17372 +#else 
17373 +        .global __avr32_f64_mul_fast
17374 +        .type  __avr32_f64_mul_fast,@function
17375 +__avr32_f64_mul_fast:
17376 +#endif                
17377 +        or      r12, r10, r11 << 1 
17378 +        breq   __avr32_f64_mul_op1_zero        
17379 +
17380 +#if defined(L_avr32_f64_mul)
17381 +       pushm   r4-r7, lr
17382 +#else
17383 +        stm     --sp, r5,r6,r7,lr       
17384 +#endif
17385 +
17386 +#define AVR32_F64_MUL_OP1_INT_BITS 1
17387 +#define AVR32_F64_MUL_OP2_INT_BITS 10
17388 +#define AVR32_F64_MUL_RES_INT_BITS 11
17389 +       
17390 +        /* op1 in {r11,r10}*/
17391 +        /* op2 in {r9,r8}*/
17392 +        eor     lr, r11, r9             /* MSB(lr) = Sign(op1) ^ Sign(op2) */
17393
17394 +        /* Unpack op1 to 1.63 format*/        
17395 +        /* exp: r7 */
17396 +        /* sf:  r11, r10 */
17397 +       bfextu  r7, r11, 20, 11 /* Extract exponent */
17398 +
17399 +       mov     r5, 1
17400 +
17401 +        /* Check if normalization is needed */
17402 +        breq    __avr32_f64_mul_op1_subnormal /*If number is subnormal, normalize it */ 
17403 +
17404 +        lsl     r11, (12-AVR32_F64_MUL_OP1_INT_BITS-1) /* Extract mantissa, leave room for implicit bit */ 
17405 +        or      r11, r11, r10>>(32-(12-AVR32_F64_MUL_OP1_INT_BITS-1))
17406 +        lsl     r10, (12-AVR32_F64_MUL_OP1_INT_BITS-1)
17407 +       bfins   r11, r5, 32 - (1 + AVR32_F64_MUL_OP1_INT_BITS), 1 + AVR32_F64_MUL_OP1_INT_BITS /* Insert implicit bit */
17408 +
17409 +
17410 +22:     
17411 +        /* Unpack op2 to 10.54 format */
17412 +        /* exp: r6 */
17413 +        /* sf:  r9, r8 */
17414 +       bfextu  r6, r9, 20, 11 /* Extract exponent */
17415 +
17416 +        /* Check if normalization is needed */
17417 +        breq    __avr32_f64_mul_op2_subnormal /*If number is subnormal, normalize it */ 
17418 +
17419 +       lsl     r8, 1 /* Extract mantissa, leave room for implicit bit */
17420 +       rol     r9      
17421 +       bfins   r9, r5, 32 - (1 + AVR32_F64_MUL_OP2_INT_BITS), 1 + AVR32_F64_MUL_OP2_INT_BITS /* Insert implicit bit */
17422 +
17423 +23:     
17424
17425 +        /* Check if any operands are NaN or INF */
17426 +        cp      r7, 0x7ff
17427 +        breq    __avr32_f64_mul_op_nan_or_inf /* Check op1 for NaN or Inf */
17428 +        cp      r6, 0x7ff
17429 +        breq    __avr32_f64_mul_op_nan_or_inf  /* Check op2 for NaN or Inf */
17430
17431
17432 +        /* Calculate new exponent in r12*/
17433 +        add     r12, r7, r6
17434 +        sub     r12, (1023-1)
17435
17436 +#if defined(L_avr32_f64_mul)
17437 +       /* Do the multiplication.
17438 +           Place result in [r11, r10, r7, r6]. The result is in 11.117 format.  */
17439 +        mulu.d  r4, r11, r8
17440 +        macu.d  r4, r10, r9
17441 +        mulu.d  r6, r10, r8
17442 +        mulu.d  r10, r11, r9
17443 +       add     r7, r4
17444 +       adc     r10, r10, r5    
17445 +       acr     r11
17446 +#else
17447 +       /* Do the multiplication using approximate calculation. discard the al x bl
17448 +          calculation.
17449 +           Place result in [r11, r10, r7]. The result is in 11.85 format.  */
17450 +
17451 +        /* Do the multiplication using approximate calculation.
17452 +         Place result in r11, r10. Use r7, r6 as scratch registers */
17453 +        mulu.d  r6, r11, r8
17454 +        macu.d  r6, r10, r9
17455 +        mulu.d  r10, r11, r9
17456 +        add     r10, r7
17457 +        acr     r11
17458 +#endif 
17459 +        /* Adjust exponent and mantissa */
17460 +        /* [r12]:exp, [r11, r10]:mant [r7, r6]:sticky bits */
17461 +        /* Mantissa may be of the format 00000000000.0xxx or 00000000000.1xxx. */
17462 +        /* In the first case, shift one pos to left.*/
17463 +        bld     r11, 32-AVR32_F64_MUL_RES_INT_BITS-1
17464 +       breq    0f      
17465 +       lsl     r7, 1
17466 +       rol     r10
17467 +       rol     r11
17468 +       sub     r12, 1
17469 +0:     
17470 +        cp      r12, 0  
17471 +        brle    __avr32_f64_mul_res_subnormal /*Result was subnormal.*/
17472
17473 +        /* Check for Inf. */
17474 +        cp.w    r12, 0x7ff
17475 +        brge    __avr32_f64_mul_res_inf
17476 +
17477 +       /* Insert exponent. */
17478 +       bfins   r11, r12, 20, 11  
17479 +
17480 +        /* Result was not subnormal. Perform rounding. */
17481 +        /* For the fast version we discard the sticky bits and always round
17482 +          the halfwaycase up. */
17483 +24:    
17484 +#if defined(L_avr32_f64_mul)
17485 +       or      r6, r6, r10 << 31 /* Or in parity bit into stickybits */
17486 +       or      r7, r7, r6 >> 1   /* Or together sticky and still make the msb 
17487 +                                    of r7 represent the halfway bit. */
17488 +       eorh    r7, 0x8000        /* Toggle halfway bit. */
17489 +       /* We should now round up by adding one for the following cases:
17490 +
17491 +               halfway   sticky|parity  round-up
17492 +                  0            x           no
17493 +                  1            0           no
17494 +                  1            1           yes
17495 +
17496 +          Since we have inverted the halfway bit we can use the satu instruction
17497 +           by saturating to 1 bit to implement this. 
17498 +       */ 
17499 +       satu    r7 >> 0, 1
17500 +#else
17501 +       lsr     r7, 31
17502 +#endif 
17503 +       add     r10, r7
17504 +       acr     r11     
17505 +        
17506 +        /* Insert sign bit*/
17507 +        bld     lr, 31
17508 +        bst     r11, 31
17509 +        
17510 +        /* Return result in [r11,r10] */
17511 +#if defined(L_avr32_f64_mul)
17512 +       popm    r4-r7, pc
17513 +#else
17514 +        ldm     sp++, r5, r6, r7,pc
17515 +#endif
17516
17517
17518 +__avr32_f64_mul_op1_subnormal:
17519 +       andh    r11, 0x000f /* Remove sign bit and exponent */
17520 +        clz     r12, r10    /* Count leading zeros in lsw */
17521 +        clz     r6, r11     /* Count leading zeros in msw */
17522 +        subcs  r12, -32 + AVR32_F64_MUL_OP1_INT_BITS 
17523 +       movcs   r6, r12
17524 +       subcc   r6, AVR32_F64_MUL_OP1_INT_BITS
17525 +       cp.w    r6, 32
17526 +       brge    0f
17527 +               
17528 +        /* shifting involves both msw and lsw*/
17529 +        rsub    r12, r6, 32  /* shift mantissa */
17530 +        lsl     r11, r11, r6
17531 +        lsr     r12, r10, r12
17532 +        or      r11, r12
17533 +        lsl     r10, r10, r6
17534 +       sub     r6, 12-AVR32_F64_MUL_OP1_INT_BITS
17535 +        sub     r7, r6          /* adjust exponent */
17536 +        rjmp    22b             /* Finished */  
17537 +0:
17538 +        /* msw is zero so only need to consider lsw */
17539 +        lsl     r11, r10, r6
17540 +       breq    __avr32_f64_mul_res_zero
17541 +        mov     r10, 0
17542 +       sub     r6, 12-AVR32_F64_MUL_OP1_INT_BITS
17543 +        sub     r7, r6            /* adjust exponent */
17544 +        rjmp    22b
17545 +
17546
17547 +__avr32_f64_mul_op2_subnormal:
17548 +       andh    r9, 0x000f  /* Remove sign bit and exponent */
17549 +        clz     r12, r8    /* Count leading zeros in lsw */
17550 +        clz     r5, r9     /* Count leading zeros in msw */
17551 +        subcs  r12, -32 + AVR32_F64_MUL_OP2_INT_BITS 
17552 +       movcs   r5, r12
17553 +       subcc   r5, AVR32_F64_MUL_OP2_INT_BITS
17554 +       cp.w    r5, 32
17555 +       brge    0f
17556 +               
17557 +        /* shifting involves both msw and lsw*/
17558 +        rsub    r12, r5, 32  /* shift mantissa */
17559 +        lsl     r9, r9, r5
17560 +        lsr     r12, r8, r12
17561 +        or      r9, r12
17562 +        lsl     r8, r8, r5
17563 +       sub     r5, 12 - AVR32_F64_MUL_OP2_INT_BITS
17564 +        sub     r6, r5          /* adjust exponent */
17565 +        rjmp    23b             /* Finished */  
17566 +0:
17567 +        /* msw is zero so only need to consider lsw */
17568 +        lsl     r9, r8, r5
17569 +       breq    __avr32_f64_mul_res_zero
17570 +        mov     r8, 0
17571 +       sub     r5, 12 - AVR32_F64_MUL_OP2_INT_BITS
17572 +        sub     r6, r5            /* adjust exponent */
17573 +        rjmp    23b
17574 +                
17575
17576 +__avr32_f64_mul_op_nan_or_inf:
17577 +        /* Same code for OP1 and OP2*/
17578 +        /* Since we are here, at least one of the OPs were NaN or INF*/
17579 +       andh    r9, 0x000f  /* Remove sign bit and exponent */
17580 +       andh    r11, 0x000f  /* Remove sign bit and exponent */
17581 +        /* Merge the regs in each operand to check for zero*/
17582 +        or      r11, r10 /* op1 */
17583 +        or      r9, r8 /* op2 */
17584 +        /* Check if op1 is NaN or INF */
17585 +        cp      r7, 0x7ff
17586 +        brne    __avr32_f64_mul_op1_not_naninf
17587 +        /* op1 was NaN or INF.*/
17588 +        cp      r11, 0
17589 +        brne    __avr32_f64_mul_res_nan /* op1 was NaN. Result will be NaN*/
17590 +        /*op1 was INF. check if op2 is NaN or INF*/
17591 +        cp      r6, 0x7ff
17592 +        brne    __avr32_f64_mul_res_inf /*op1 was INF, op2 was neither NaN nor INF*/
17593 +        /* op1 is INF, op2 is either NaN or INF*/
17594 +        cp      r9, 0
17595 +        breq    __avr32_f64_mul_res_inf /*op2 was also INF*/
17596 +        rjmp    __avr32_f64_mul_res_nan /*op2 was NaN*/
17597
17598 +__avr32_f64_mul_op1_not_naninf:
17599 +        /* op1 was not NaN nor INF. Then op2 must be NaN or INF*/
17600 +        cp      r9, 0
17601 +        breq    __avr32_f64_mul_res_inf /*op2 was INF, return INF*/
17602 +        rjmp   __avr32_f64_mul_res_nan /*else return NaN*/
17603 +        
17604 +__avr32_f64_mul_res_subnormal:/* Multiply result was subnormal. */
17605 +#if defined(L_avr32_f64_mul)
17606 +       /* Check how much we must scale down the mantissa. */
17607 +       neg     r12
17608 +       sub     r12, -1     /* We do no longer have an implicit bit. */
17609 +       satu    r12 >> 0, 6 /* Saturate shift amount to max 63. */
17610 +       cp.w    r12, 32
17611 +       brge    0f
17612 +       /* Shift amount <32 */
17613 +       rsub    r8, r12, 32
17614 +       or      r6, r7 
17615 +       lsr     r7, r7, r12
17616 +       lsl     r9, r10, r8
17617 +       or      r7, r9
17618 +       lsr     r10, r10, r12
17619 +       lsl     r9, r11, r8
17620 +       or      r10, r9
17621 +       lsr     r11, r11, r12
17622 +       rjmp    24b
17623 +0:
17624 +       /* Shift amount >=32 */
17625 +       rsub    r8, r12, 32
17626 +       moveq   r9, 0
17627 +       breq    0f
17628 +       lsl     r9, r11, r8
17629 +0:     
17630 +       or      r6, r7
17631 +       or      r6, r6, r10 << 1 
17632 +       lsr     r10, r10, r12
17633 +       or      r7, r9, r10
17634 +       lsr     r10, r11, r12
17635 +       mov     r11, 0  
17636 +       rjmp    24b                             
17637 +#else
17638 +       /* Flush to zero for the fast version. */
17639 +        mov     r11, lr /*Get correct sign*/
17640 +        andh    r11, 0x8000, COH
17641 +        mov     r10, 0
17642 +        ldm     sp++, r5, r6, r7,pc
17643 +#endif
17644 +
17645 +__avr32_f64_mul_res_zero:/* Multiply result is zero. */
17646 +        mov     r11, lr /*Get correct sign*/
17647 +        andh    r11, 0x8000, COH
17648 +        mov     r10, 0
17649 +#if defined(L_avr32_f64_mul)
17650 +       popm    r4-r7, pc
17651 +#else
17652 +        ldm     sp++, r5, r6, r7,pc
17653 +#endif
17654
17655 +__avr32_f64_mul_res_nan:        /* Return NaN. */
17656 +        mov     r11, -1
17657 +        mov     r10, -1
17658 +#if defined(L_avr32_f64_mul)
17659 +       popm    r4-r7, pc
17660 +#else
17661 +        ldm     sp++, r5, r6, r7,pc
17662 +#endif
17663 +        
17664 +__avr32_f64_mul_res_inf:        /* Return INF. */
17665 +       mov     r11, 0xfff00000
17666 +        bld     lr, 31
17667 +        bst     r11, 31
17668 +        mov     r10, 0
17669 +#if defined(L_avr32_f64_mul)
17670 +       popm    r4-r7, pc
17671 +#else
17672 +        ldm     sp++, r5, r6, r7,pc
17673 +#endif
17674 +
17675 +__avr32_f64_mul_op1_zero:
17676 +        /* Get sign */
17677 +        eor     r11, r11, r9
17678 +        andh    r11, 0x8000, COH  
17679 +        /* Check if op2 is Inf or NaN. */
17680 +        bfextu  r12, r9, 20, 11
17681 +        cp.w    r12, 0x7ff
17682 +        retne   r12     /* Return 0.0 */
17683 +        /* Return NaN */
17684 +        mov     r10, -1
17685 +        mov     r11, -1
17686 +        ret     r12
17687 +         
17688 +
17689
17690 +#endif
17691 +                
17692
17693 +#if  defined(L_avr32_f64_addsub) || defined(L_avr32_f64_addsub_fast)
17694 +        .align  2
17695 +
17696 +__avr32_f64_sub_from_add:
17697 +        /* Switch sign on op2 */
17698 +        eorh    r9, 0x8000
17699 +
17700 +#if  defined(L_avr32_f64_addsub_fast)
17701 +        .global __avr32_f64_sub_fast
17702 +        .type  __avr32_f64_sub_fast,@function
17703 +__avr32_f64_sub_fast:
17704 +#else  
17705 +        .global __avr32_f64_sub
17706 +        .type  __avr32_f64_sub,@function
17707 +__avr32_f64_sub:
17708 +#endif
17709 +        
17710 +        /* op1 in {r11,r10}*/
17711 +        /* op2 in {r9,r8}*/
17712 +
17713 +#if  defined(L_avr32_f64_addsub_fast)
17714 +        /* If op2 is zero just return op1 */
17715 +        or      r12, r8, r9 << 1
17716 +        reteq   r12 
17717 +#endif
17718
17719 +        /* Check signs */
17720 +        eor     r12, r11, r9
17721 +        /* Different signs, use addition. */
17722 +        brmi    __avr32_f64_add_from_sub
17723
17724 +        stm     --sp, r5, r6, r7, lr
17725
17726 +        /* Get sign of op1 into r12 */
17727 +        mov     r12, r11
17728 +        andh    r12, 0x8000, COH                
17729
17730 +        /* Remove sign from operands */
17731 +        cbr     r11, 31
17732 +        cbr     r9, 31
17733
17734 +        /* Put the largest number in [r11, r10]
17735 +           and the smallest number in [r9, r8] */
17736 +        cp      r10, r8
17737 +        cpc     r11, r9
17738 +        brhs    1f /* Skip swap if operands already correctly ordered*/
17739 +        /* Operands were not correctly ordered, swap them*/
17740 +        mov     r7, r11
17741 +        mov     r11, r9
17742 +        mov     r9, r7
17743 +        mov     r7, r10
17744 +        mov     r10, r8
17745 +        mov     r8, r7
17746 +        eorh    r12, 0x8000 /* Invert sign in r12*/
17747 +1:      
17748 +        /* Unpack largest operand - opH */      
17749 +        /* exp: r7 */
17750 +        /* sf:  r11, r10 */
17751 +        lsr     r7, r11, 20 /* Extract exponent */
17752 +        lsl     r11, 11 /* Extract mantissa, leave room for implicit bit */ 
17753 +        or      r11, r11, r10>>21
17754 +        lsl     r10, 11
17755 +        sbr     r11, 31 /* Insert implicit bit */
17756
17757 +        
17758 +        /* Unpack smallest operand - opL */
17759 +        /* exp: r6 */
17760 +        /* sf:  r9, r8 */
17761 +        lsr     r6, r9, 20 /* Extract exponent */
17762 +        breq    __avr32_f64_sub_opL_subnormal /* If either zero or subnormal */
17763 +        lsl     r9, 11 /* Extract mantissa, leave room for implicit bit */ 
17764 +        or      r9, r9, r8>>21
17765 +        lsl     r8, 11
17766 +        sbr     r9, 31 /* Insert implicit bit */
17767
17768 +
17769 +__avr32_f64_sub_opL_subnormal_done:     
17770 +        /* opH is NaN or Inf. */
17771 +        cp.w    r7, 0x7ff
17772 +        breq    __avr32_f64_sub_opH_nan_or_inf
17773 +
17774 +        /* Get shift amount to scale mantissa of op2. */
17775 +        rsub    r6, r7
17776 +        breq    __avr32_f64_sub_shift_done /* No need to shift, exponents are equal*/
17777
17778 +        /* Scale mantissa [r9, r8] with amount [r6].
17779 +        Uses scratch registers [r5] and [lr].
17780 +        In IEEE mode:Must not forget the sticky bits we intend to shift out. */
17781
17782 +        rsub    r5,r6,32 /* get (32 - shift count)
17783 +                            (if shift count > 32 we get a
17784 +                            negative value, but that will
17785 +                            work as well in the code below.) */
17786
17787 +        cp.w    r6,32       /* handle shifts >= 32 separately */
17788 +        brhs    __avr32_f64_sub_longshift
17789
17790 +        /* small (<32) shift amount, both words are part of the shift
17791 +           first remember whether part that is lost contains any 1 bits ... */
17792 +        lsl     lr,r8,r5  /* shift away bits that are part of
17793 +                             final mantissa. only part that goes
17794 +                             to lr are bits that will be lost */
17795
17796 +        /* ... and now to the actual shift */
17797 +        lsl     r5,r9,r5  /* get bits from msw destined for lsw*/
17798 +        lsr     r8,r8,r6  /* shift down lsw of mantissa */
17799 +        lsr     r9,r9,r6  /* shift down msw of mantissa */
17800 +        or      r8,r5     /* combine these bits with prepared lsw*/
17801 +#if  defined(L_avr32_f64_addsub)
17802 +        cp.w    lr,0      /* if any '1' bit in part we lost ...*/
17803 +        srne    lr
17804 +        or      r8, lr     /* ... we need to set sticky bit*/
17805 +#endif
17806 +        
17807 +__avr32_f64_sub_shift_done:     
17808 +        /* Now subtract the mantissas. */
17809 +        sub     r10, r8
17810 +        sbc     r11, r11, r9
17811
17812 +        /* Normalize the exponent and mantissa pair stored in
17813 +        [r11,r10] and exponent in [r7]. Needs two scratch registers [r6] and [lr]. */
17814 +        clz     r6,r11     /* Check if we have zeros in high bits */
17815 +        breq    __avr32_f64_sub_longnormalize_done  /* No need for scaling if no zeros in high bits */
17816 +        brcs    __avr32_f64_sub_longnormalize
17817
17818 +       
17819 +        /* shift amount is smaller than 32, and involves both msw and lsw*/
17820 +        rsub    lr,r6,32  /* shift mantissa */
17821 +        lsl     r11,r11,r6
17822 +        lsr     lr,r10,lr
17823 +        or      r11,lr
17824 +        lsl     r10,r10,r6
17825
17826 +        sub     r7,r6    /* adjust exponent */
17827 +        brle    __avr32_f64_sub_subnormal_result
17828 +__avr32_f64_sub_longnormalize_done:     
17829 +        
17830 +#if defined(L_avr32_f64_addsub)
17831 +        /* Insert the bits we will remove from the mantissa r9[31:21] */
17832 +        lsl     r9, r10, (32 - 11)
17833 +#else
17834 +        /* Keep the last bit shifted out. */
17835 +        bfextu  r9, r10, 10, 1
17836 +#endif
17837
17838 +        /* Pack final result*/
17839 +        /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */
17840 +        /* Result in [r11,r10] */
17841 +        /* Insert mantissa */
17842 +        lsr     r10, 11
17843 +        or      r10, r10, r11<<21
17844 +        lsr     r11, 11
17845 +        /* Insert exponent and sign bit*/
17846 +       bfins   r11, r7, 20, 11
17847 +        or      r11, r12
17848 +        
17849 +        /* Round */     
17850 +__avr32_f64_sub_round:
17851 +#if defined(L_avr32_f64_addsub)
17852 +       mov_imm r7, 0x80000000
17853 +        bld     r10, 0
17854 +        subne   r7, -1  
17855
17856 +        cp.w    r9, r7
17857 +        srhs    r9
17858 +#endif
17859 +        add     r10, r9
17860 +        acr     r11
17861 +        
17862 +        /* Return result in [r11,r10] */
17863 +        ldm     sp++, r5, r6, r7,pc
17864
17865
17866
17867 +__avr32_f64_sub_opL_subnormal:
17868 +        /* Extract the of mantissa */
17869 +        lsl     r9, 11 /* Extract mantissa, leave room for implicit bit */ 
17870 +        or      r9, r9, r8>>21
17871 +        lsl     r8, 11
17872
17873 +        /* Set exponent to 1 if we do not have a zero. */
17874 +        or      lr, r9, r8
17875 +        movne   r6,1
17876 +       
17877 +        /* Check if opH is also subnormal. If so, clear implicit bit in r11*/
17878 +        rsub    lr, r7, 0
17879 +        moveq   r7,1
17880 +        bst     r11, 31
17881 +       
17882 +        /* Check if op1 is zero, if so set exponent to 0. */
17883 +        or      lr, r11, r10
17884 +        moveq   r7,0
17885 +                        
17886 +        rjmp    __avr32_f64_sub_opL_subnormal_done
17887
17888 +__avr32_f64_sub_opH_nan_or_inf: 
17889 +        /* Check if opH is NaN, if so return NaN */
17890 +        cbr     r11, 31
17891 +        or      lr, r11, r10
17892 +        brne    __avr32_f64_sub_return_nan
17893
17894 +        /* opH is Inf. */
17895 +        /* Check if opL is Inf. or NaN */
17896 +        cp.w    r6, 0x7ff
17897 +        breq    __avr32_f64_sub_return_nan
17898 +       /* Return infinity with correct sign. */        
17899 +       or      r11, r12, r7 << 20
17900 +        ldm     sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */
17901 +__avr32_f64_sub_return_nan:     
17902 +        mov     r10, -1 /* Generate NaN in r11, r10 */
17903 +        mov     r11, -1
17904 +        ldm     sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */
17905
17906
17907 +__avr32_f64_sub_subnormal_result:
17908 +#if defined(L_avr32_f64_addsub)
17909 +       /* Check how much we must scale down the mantissa. */
17910 +       neg     r7
17911 +       sub     r7, -1     /* We do no longer have an implicit bit. */
17912 +       satu    r7 >> 0, 6 /* Saturate shift amount to max 63. */
17913 +       cp.w    r7, 32
17914 +       brge    0f
17915 +       /* Shift amount <32 */
17916 +       rsub    r8, r7, 32
17917 +       lsl     r9, r10, r8
17918 +       srne    r6
17919 +       lsr     r10, r10, r7
17920 +       or      r10, r6         /* Sticky bit from the
17921 +                                  part that was shifted out. */
17922 +       lsl     r9, r11, r8
17923 +       or      r10, r10, r9
17924 +       lsr     r11, r10, r7
17925 +       /* Set exponent */
17926 +       mov     r7, 0
17927 +       rjmp    __avr32_f64_sub_longnormalize_done
17928 +0:
17929 +       /* Shift amount >=32 */
17930 +       rsub    r8, r7, 64
17931 +       lsl     r9, r11, r8
17932 +       or      r9, r10
17933 +       srne    r6
17934 +       lsr     r10, r11, r7
17935 +       or      r10, r6         /* Sticky bit from the
17936 +                                  part that was shifted out. */
17937 +       mov     r11, 0
17938 +       /* Set exponent */
17939 +       mov     r7, 0
17940 +       rjmp    __avr32_f64_sub_longnormalize_done
17941 +#else
17942 +        /* Just flush subnormals to zero. */
17943 +        mov     r10, 0
17944 +        mov     r11, 0
17945 +#endif
17946 +        ldm     sp++, r5, r6, r7, pc
17947
17948 +__avr32_f64_sub_longshift:
17949 +        /* large (>=32) shift amount, only lsw will have bits left after shift.
17950 +           note that shift operations will use ((shift count=r6) mod 32) so
17951 +           we do not need to subtract 32 from shift count. */
17952 +        /* Saturate the shift amount to 63. If the amount
17953 +           is any larger op2 is insignificant. */
17954 +        satu    r6 >> 0, 6
17955 +       
17956 +#if defined(L_avr32_f64_addsub)
17957 +        /* first remember whether part that is lost contains any 1 bits ... */
17958 +       moveq   lr, r8     /* If shift amount is 32, no bits from msw are lost. */
17959 +       breq    0f
17960 +        lsl     lr,r9,r5   /* save all lost bits from msw */
17961 +        or      lr,r8      /* also save lost bits (all) from lsw
17962 +                              now lr != 0 if we lose any bits */
17963 +#endif  
17964 +0:     
17965 +        /* ... and now to the actual shift */
17966 +        lsr     r8,r9,r6   /* Move msw to lsw and shift. */
17967 +        mov     r9,0       /* clear msw */
17968 +#if defined(L_avr32_f64_addsub)
17969 +        cp.w    lr,0       /* if any '1' bit in part we lost ...*/
17970 +        srne    lr
17971 +        or      r8, lr      /* ... we need to set sticky bit*/
17972 +#endif
17973 +        rjmp    __avr32_f64_sub_shift_done
17974
17975 +__avr32_f64_sub_longnormalize:
17976 +        /* shift amount is greater than 32 */
17977 +        clz     r6,r10      /* shift mantissa */
17978 +        /* If the resulting mantissa is zero the result is 
17979 +           zero so force exponent to zero. */
17980 +        movcs   r7, 0
17981 +        movcs   r6, 0
17982 +        movcs   r12, 0  /* Also clear sign bit. A zero result from subtraction
17983 +                          always is +0.0 */
17984 +        subcc   r6,-32
17985 +        lsl     r11,r10,r6
17986 +        mov     r10,0
17987 +        sub     r7,r6          /* adjust exponent */
17988 +        brle    __avr32_f64_sub_subnormal_result
17989 +        rjmp    __avr32_f64_sub_longnormalize_done
17990 +        
17991
17992 +        
17993 +        .align  2
17994 +__avr32_f64_add_from_sub:
17995 +        /* Switch sign on op2 */
17996 +        eorh    r9, 0x8000
17997 +
17998 +#if defined(L_avr32_f64_addsub_fast)
17999 +        .global __avr32_f64_add_fast
18000 +        .type  __avr32_f64_add_fast,@function
18001 +__avr32_f64_add_fast:
18002 +#else  
18003 +        .global __avr32_f64_add
18004 +        .type  __avr32_f64_add,@function
18005 +__avr32_f64_add:
18006 +#endif
18007 +        
18008 +        /* op1 in {r11,r10}*/
18009 +        /* op2 in {r9,r8}*/
18010
18011 +#if defined(L_avr32_f64_addsub_fast)
18012 +        /* If op2 is zero just return op1 */
18013 +        or      r12, r8, r9 << 1
18014 +        reteq   r12 
18015 +#endif
18016 +
18017 +        /* Check signs */
18018 +        eor     r12, r11, r9
18019 +        /* Different signs, use subtraction. */
18020 +        brmi    __avr32_f64_sub_from_add
18021
18022 +        stm     --sp, r5, r6, r7, lr
18023
18024 +        /* Get sign of op1 into r12 */
18025 +        mov     r12, r11
18026 +        andh    r12, 0x8000, COH                
18027
18028 +        /* Remove sign from operands */
18029 +        cbr     r11, 31
18030 +        cbr     r9, 31
18031
18032 +        /* Put the number with the largest exponent in [r11, r10]
18033 +           and the number with the smallest exponent in [r9, r8] */
18034 +        cp      r11, r9
18035 +        brhs    1f /* Skip swap if operands already correctly ordered */
18036 +        /* Operands were not correctly ordered, swap them */
18037 +        mov     r7, r11
18038 +        mov     r11, r9
18039 +        mov     r9, r7
18040 +        mov     r7, r10
18041 +        mov     r10, r8
18042 +        mov     r8, r7
18043 +1:      
18044 +       mov     lr, 0 /* Set sticky bits to zero */
18045 +        /* Unpack largest operand - opH */      
18046 +        /* exp: r7 */
18047 +        /* sf:  r11, r10 */
18048 +       bfextu  R7, R11, 20, 11 /* Extract exponent */
18049 +       bfextu  r11, r11, 0, 20 /* Extract mantissa */
18050 +        sbr     r11, 20 /* Insert implicit bit */
18051
18052 +        /* Unpack smallest operand - opL */
18053 +        /* exp: r6 */
18054 +        /* sf:  r9, r8 */
18055 +       bfextu  R6, R9, 20, 11  /* Extract exponent */
18056 +       breq    __avr32_f64_add_op2_subnormal
18057 +       bfextu  r9, r9, 0, 20   /* Extract mantissa */
18058 +        sbr     r9, 20         /* Insert implicit bit */
18059 +
18060 +2:              
18061 +        /* opH is NaN or Inf. */
18062 +        cp.w    r7, 0x7ff
18063 +        breq    __avr32_f64_add_opH_nan_or_inf
18064 +
18065 +        /* Get shift amount to scale mantissa of op2. */
18066 +        rsub    r6, r7
18067 +        breq    __avr32_f64_add_shift_done /* No need to shift, exponents are equal*/
18068
18069 +        /* Scale mantissa [r9, r8] with amount [r6].
18070 +        Uses scratch registers [r5] and [lr].
18071 +        In IEEE mode:Must not forget the sticky bits we intend to shift out. */
18072 +        rsub    r5,r6,32 /* get (32 - shift count)
18073 +                            (if shift count > 32 we get a
18074 +                            negative value, but that will
18075 +                            work as well in the code below.) */
18076
18077 +        cp.w    r6,32       /* handle shifts >= 32 separately */
18078 +        brhs    __avr32_f64_add_longshift
18079
18080 +        /* small (<32) shift amount, both words are part of the shift
18081 +           first remember whether part that is lost contains any 1 bits ... */
18082 +        lsl     lr,r8,r5  /* shift away bits that are part of
18083 +                             final mantissa. only part that goes
18084 +                             to lr are bits that will be lost */
18085
18086 +        /* ... and now to the actual shift */
18087 +        lsl     r5,r9,r5  /* get bits from msw destined for lsw*/
18088 +        lsr     r8,r8,r6  /* shift down lsw of mantissa */
18089 +        lsr     r9,r9,r6  /* shift down msw of mantissa */
18090 +        or      r8,r5     /* combine these bits with prepared lsw*/
18091 +        
18092 +__avr32_f64_add_shift_done:     
18093 +        /* Now add the mantissas. */
18094 +        add     r10, r8
18095 +        adc     r11, r11, r9
18096 +
18097 +        /* Check if we overflowed. */
18098 +       bld     r11, 21 
18099 +        breq   __avr32_f64_add_res_of:
18100 +
18101 +__avr32_f64_add_res_of_done:    
18102 +        
18103 +        /* Pack final result*/
18104 +        /* Input: [r7]:exp, [r11, r10]:mant, [r12]:sign in MSB */
18105 +        /* Result in [r11,r10] */
18106 +        /* Insert exponent and sign bit*/
18107 +       bfins   r11, r7, 20, 11
18108 +       or      r11, r12
18109 +        
18110 +        /* Round */     
18111 +__avr32_f64_add_round:
18112 +#if defined(L_avr32_f64_addsub)
18113 +       bfextu  r12, r10, 0, 1 /* Extract parity bit.*/
18114 +       or      lr, r12        /* or it together with the sticky bits. */       
18115 +       eorh    lr, 0x8000     /* Toggle round bit. */  
18116 +       /* We should now round up by adding one for the following cases:
18117 +
18118 +               halfway   sticky|parity  round-up
18119 +                  0            x           no
18120 +                  1            0           no
18121 +                  1            1           yes
18122 +
18123 +          Since we have inverted the halfway bit we can use the satu instruction
18124 +           by saturating to 1 bit to implement this. 
18125 +       */ 
18126 +       satu    lr >> 0, 1
18127 +#else
18128 +       lsr     lr, 31
18129 +#endif
18130 +        add     r10, lr
18131 +        acr     r11
18132 +        
18133 +        /* Return result in [r11,r10] */
18134 +        ldm     sp++, r5, r6, r7,pc
18135
18136 +  
18137 +__avr32_f64_add_opH_nan_or_inf: 
18138 +        /* Check if opH is NaN, if so return NaN */
18139 +        cbr     r11, 20
18140 +        or      lr, r11, r10
18141 +        brne    __avr32_f64_add_return_nan
18142
18143 +        /* opH is Inf. */
18144 +        /* Check if opL is Inf. or NaN */
18145 +        cp.w    r6, 0x7ff
18146 +        breq    __avr32_f64_add_opL_nan_or_inf
18147 +        ldm     sp++, r5, r6, r7, pc/* opL not Inf or NaN, return opH */
18148 +__avr32_f64_add_opL_nan_or_inf:
18149 +        cbr     r9, 20
18150 +        or      lr, r9, r8
18151 +        brne    __avr32_f64_add_return_nan
18152 +        mov     r10, 0  /* Generate Inf in r11, r10 */
18153 +       mov_imm r11, 0x7ff00000
18154 +        or      r11, r12 /* Put sign bit back */
18155 +        ldm     sp++, r5, r6, r7, pc/* opL Inf, return Inf */
18156 +__avr32_f64_add_return_nan:     
18157 +        mov     r10, -1 /* Generate NaN in r11, r10 */
18158 +        mov     r11, -1
18159 +        ldm     sp++, r5, r6, r7, pc/* opL Inf or NaN, return NaN */
18160
18161
18162 +__avr32_f64_add_longshift:
18163 +        /* large (>=32) shift amount, only lsw will have bits left after shift.
18164 +           note that shift operations will use ((shift count=r6) mod 32) so
18165 +           we do not need to subtract 32 from shift count. */
18166 +        /* Saturate the shift amount to 63. If the amount
18167 +           is any larger op2 is insignificant. */
18168 +        satu    r6 >> 0, 6
18169 +       /* If shift amount is 32 there are no bits from the msw that are lost. */
18170 +       moveq   lr, r8
18171 +       breq    0f      
18172 +        /* first remember whether part that is lost contains any 1 bits ... */
18173 +        lsl     lr,r9,r5   /* save all lost bits from msw */
18174 +#if defined(L_avr32_f64_addsub)
18175 +       cp.w    r8, 0
18176 +       srne    r8      
18177 +        or      lr,r8      /* also save lost bits (all) from lsw
18178 +                              now lr != 0 if we lose any bits */
18179 +#endif  
18180 +0:     
18181 +        /* ... and now to the actual shift */
18182 +        lsr     r8,r9,r6   /* msw -> lsw and make rest of shift inside lsw*/
18183 +        mov     r9,0       /* clear msw */
18184 +        rjmp    __avr32_f64_add_shift_done
18185
18186 +__avr32_f64_add_res_of:
18187 +       /* We overflowed. Scale down mantissa by shifting right one position. */
18188 +       or      lr, lr, lr << 1 /* Remember stickybits*/
18189 +       lsr     r11, 1
18190 +       ror     r10
18191 +       ror     lr
18192 +       sub     r7, -1  /* Increment exponent */
18193
18194 +        /* Clear mantissa to set result to Inf if the exponent is 255. */
18195 +        cp.w    r7, 0x7ff
18196 +        moveq   r10, 0
18197 +        moveq   r11, 0
18198 +        moveq   lr, 0
18199 +        rjmp    __avr32_f64_add_res_of_done
18200 +        
18201 +__avr32_f64_add_op2_subnormal: 
18202 +       /* Set epxponent to 1 */
18203 +       mov     r6, 1
18204 +
18205 +       /* Check if op2 is also subnormal. */
18206 +       cp.w    r7, 0
18207 +       brne    2b
18208 +
18209 +       cbr     r11, 20
18210 +       /* Both operands are subnormal. Just addd the mantissas
18211 +          and the exponent will automatically be set to 1 if
18212 +          we overflow into a normal number. */
18213 +       add     r10, r8
18214 +       adc     r11, r11, r9
18215 +
18216 +       /* Add sign bit */
18217 +       or      r11, r12
18218 +       
18219 +        /* Return result in [r11,r10] */
18220 +        ldm     sp++, r5, r6, r7,pc
18221 +       
18222 +                       
18223 +        
18224 +#endif
18225
18226 +#ifdef L_avr32_f64_to_u32
18227 +        /* This goes into L_fixdfsi */
18228 +#endif
18229 +        
18230
18231 +#ifdef L_avr32_f64_to_s32
18232 +        .global __avr32_f64_to_u32
18233 +        .type  __avr32_f64_to_u32,@function
18234 +__avr32_f64_to_u32:
18235 +        cp.w    r11, 0
18236 +        retmi   0       /* Negative returns 0 */
18237
18238 +        /* Fallthrough to df to signed si conversion */ 
18239 +        .global __avr32_f64_to_s32
18240 +        .type  __avr32_f64_to_s32,@function
18241 +__avr32_f64_to_s32:
18242 +        lsl     r12,r11,1
18243 +        lsr     r12,21                  /* extract exponent*/
18244 +        sub     r12,1023                /* convert to unbiased exponent.*/
18245 +        retlo   0                       /* too small exponent implies zero. */
18246
18247 +1:      
18248 +        rsub    r12,r12,31              /* shift count = 31 - exponent */
18249 +        mov     r9,r11                  /* save sign for later...*/
18250 +        lsl     r11,11                  /* remove exponent and sign*/
18251 +        sbr     r11,31                  /* add implicit bit*/
18252 +        or      r11,r11,r10>>21         /* get rest of bits from lsw of double */
18253 +        lsr     r11,r11,r12             /* shift down mantissa to final place */
18254 +        lsl     r9,1                    /* sign -> carry */
18255 +        retcc   r11                     /* if positive, we are done */
18256 +        neg     r11                     /* if negative float, negate result */
18257 +        ret     r11
18258
18259 +#endif  /* L_fixdfsi*/
18260
18261 +#ifdef L_avr32_f64_to_u64
18262 +        /* Actual function is in L_fixdfdi */
18263 +#endif
18264 +        
18265 +#ifdef L_avr32_f64_to_s64
18266 +        .global __avr32_f64_to_u64
18267 +        .type  __avr32_f64_to_u64,@function
18268 +__avr32_f64_to_u64:
18269 +        cp.w    r11,0
18270 +        /* Negative numbers return zero */
18271 +        movmi   r10, 0
18272 +        movmi   r11, 0
18273 +        retmi   r11
18274
18275 +        
18276
18277 +        /* Fallthrough */
18278 +        .global __avr32_f64_to_s64
18279 +        .type  __avr32_f64_to_s64,@function
18280 +__avr32_f64_to_s64:
18281 +        lsl     r9,r11,1
18282 +        lsr     r9,21                   /* get exponent*/
18283 +        sub     r9,1023                 /* convert to correct range*/
18284 +        /* Return zero if exponent to small */
18285 +        movlo   r10, 0
18286 +        movlo   r11, 0
18287 +        retlo   r11
18288
18289 +        mov     r8,r11                  /* save sign for later...*/
18290 +1:      
18291 +        lsl     r11,11                  /* remove exponent */
18292 +        sbr     r11,31                  /* add implicit bit*/
18293 +        or      r11,r11,r10>>21         /* get rest of bits from lsw of double*/
18294 +        lsl     r10,11                  /* align lsw correctly as well */
18295 +        rsub    r9,r9,63                /* shift count = 63 - exponent */
18296 +        breq    1f
18297
18298 +        cp.w    r9,32                   /* is shift count more than one reg? */
18299 +        brhs    0f
18300
18301 +        mov     r12,r11                 /* save msw */
18302 +        lsr     r10,r10,r9              /* small shift count, shift down lsw */
18303 +        lsr     r11,r11,r9              /* small shift count, shift down msw */
18304 +        rsub    r9,r9,32                /* get 32-size of shifted out tail */
18305 +        lsl     r12,r12,r9              /* align part to move from msw to lsw */
18306 +        or      r10,r12                 /* combine to get new lsw */
18307 +        rjmp    1f
18308
18309 +0:
18310 +        lsr     r10,r11,r9              /* large shift count,only lsw get bits
18311 +                                           note that shift count is modulo 32*/
18312 +        mov     r11,0                   /* msw will be 0 */
18313
18314 +1:
18315 +        lsl     r8,1                    /* sign -> carry */
18316 +        retcc   r11                     /* if positive, we are done */
18317
18318 +        neg     r11                     /* if negative float, negate result */
18319 +        neg     r10
18320 +        scr     r11
18321 +        ret     r11 
18322
18323 +#endif
18324
18325 +#ifdef L_avr32_u32_to_f64
18326 +        /* Code located in L_floatsidf */
18327 +#endif
18328 +        
18329 +#ifdef L_avr32_s32_to_f64
18330 +        .global __avr32_u32_to_f64
18331 +        .type  __avr32_u32_to_f64,@function
18332 +__avr32_u32_to_f64:
18333 +        sub     r11, r12, 0 /* Move to r11 and force Z flag to be updated */
18334 +        mov     r12, 0      /* always positive */
18335 +        rjmp    0f          /* Jump to common code for floatsidf */
18336 +        
18337 +        .global __avr32_s32_to_f64
18338 +        .type  __avr32_s32_to_f64,@function
18339 +__avr32_s32_to_f64:
18340 +        mov     r11, r12        /* Keep original value in r12 for sign */
18341 +        abs     r11             /* Absolute value if r12 */
18342 +0:      
18343 +        mov     r10,0           /* let remaining bits be zero */
18344 +        reteq   r11             /* zero long will return zero float */
18345
18346 +        pushm   lr
18347 +        mov     r9,31+1023              /* set exponent */
18348 +                
18349 +        normalize_df    r9 /*exp*/, r10, r11 /* mantissa */, r8, lr /* scratch */
18350
18351 +        /* Check if a subnormal result was created */
18352 +        cp.w    r9, 0
18353 +        brgt    0f
18354 +        
18355 +        adjust_subnormal_df     r9 /* exp */, r10, r11 /* Mantissa */, r12 /*sign*/, r8, lr /* scratch */
18356 +        popm    pc
18357 +0:
18358 +        
18359 +        /* Round result */
18360 +        round_df        r9 /*exp*/, r10, r11 /* Mantissa */, r8 /*scratch*/
18361 +        cp.w    r9,0x7ff
18362 +        brlt    0f
18363 +        /*Return infinity */
18364 +        mov     r10, 0
18365 +       mov_imm r11, 0xffe00000
18366 +        rjmp    __floatsidf_return_op1
18367 +        
18368 +0:
18369
18370 +        /* Pack */
18371 +        pack_df r9 /*exp*/, r10, r11 /* mantissa */, r10, r11 /* Output df number*/
18372 +__floatsidf_return_op1: 
18373 +        lsl     r12,1                  /* shift in sign bit */
18374 +        ror     r11
18375
18376 +        popm    pc
18377 +#endif
18378
18379
18380 +#ifdef L_avr32_f32_cmp_eq
18381 +        .global __avr32_f32_cmp_eq
18382 +        .type  __avr32_f32_cmp_eq,@function
18383 +__avr32_f32_cmp_eq:     
18384 +        cp.w    r12, r11
18385 +        breq    0f      
18386 +        /* If not equal check for +/-0 */
18387 +        /* Or together the two values and shift out the sign bit.
18388 +           If the result is zero, then the two values are both zero. */
18389 +        or      r12, r11
18390 +        lsl     r12, 1
18391 +        reteq   1
18392 +        ret     0
18393 +0:                      
18394 +        /* Numbers were equal. Check for NaN or Inf */
18395 +       mov_imm r11, 0xff000000
18396 +        lsl     r12, 1
18397 +        cp.w    r12, r11
18398 +        retls   1     /* 0 if NaN, 1 otherwise */
18399 +        ret     0     
18400 +#endif
18401 +        
18402 +#if defined(L_avr32_f32_cmp_ge) || defined(L_avr32_f32_cmp_lt)
18403 +#ifdef L_avr32_f32_cmp_ge
18404 +        .global __avr32_f32_cmp_ge
18405 +        .type  __avr32_f32_cmp_ge,@function
18406 +__avr32_f32_cmp_ge:
18407 +#endif  
18408 +#ifdef L_avr32_f32_cmp_lt
18409 +        .global __avr32_f32_cmp_lt
18410 +        .type  __avr32_f32_cmp_lt,@function
18411 +__avr32_f32_cmp_lt:
18412 +#endif  
18413 +        lsl     r10, r12, 1     /* Remove sign bits */
18414 +        lsl     r9, r11, 1
18415 +       subfeq  r10, 0
18416 +#ifdef L_avr32_f32_cmp_ge
18417 +       reteq   1               /* Both number are zero. Return true. */
18418 +#endif 
18419 +#ifdef L_avr32_f32_cmp_lt
18420 +       reteq   0               /* Both number are zero. Return false. */
18421 +#endif 
18422 +       mov_imm r8, 0xff000000
18423 +        cp.w    r10, r8
18424 +        rethi   0               /* Op0 is NaN */                
18425 +        cp.w    r9, r8
18426 +        rethi   0               /* Op1 is Nan */
18427
18428 +        eor     r8, r11, r12
18429 +        bld     r12, 31
18430 +#ifdef L_avr32_f32_cmp_ge
18431 +        srcc    r8      /* Set result to true if op0 is positive*/
18432 +#endif
18433 +#ifdef L_avr32_f32_cmp_lt
18434 +        srcs    r8      /* Set result to true if op0 is negative*/
18435 +#endif
18436 +        retmi   r8      /* Return if signs are different */
18437 +        brcs    0f      /* Both signs negative? */
18438
18439 +        /* Both signs positive */
18440 +        cp.w    r12, r11
18441 +#ifdef L_avr32_f32_cmp_ge
18442 +        reths    1
18443 +        retlo    0
18444 +#endif
18445 +#ifdef L_avr32_f32_cmp_lt
18446 +        reths    0
18447 +        retlo    1
18448 +#endif
18449 +0:
18450 +        /* Both signs negative */
18451 +        cp.w    r11, r12
18452 +#ifdef L_avr32_f32_cmp_ge
18453 +        reths    1
18454 +        retlo    0
18455 +#endif
18456 +#ifdef L_avr32_f32_cmp_lt
18457 +        reths    0
18458 +        retlo    1
18459 +#endif
18460 +#endif
18461 +        
18462
18463 +#ifdef L_avr32_f64_cmp_eq
18464 +        .global __avr32_f64_cmp_eq
18465 +        .type  __avr32_f64_cmp_eq,@function
18466 +__avr32_f64_cmp_eq:     
18467 +        cp.w    r10,r8
18468 +        cpc     r11,r9
18469 +        breq    0f
18470 +        
18471 +        /* Args were not equal*/
18472 +        /* Both args could be zero with different sign bits */
18473 +        lsl     r11,1                   /* get rid of sign bits */
18474 +        lsl     r9,1
18475 +        or      r11,r10                 /* Check if all bits are zero */
18476 +        or      r11,r9
18477 +        or      r11,r8
18478 +        reteq   1                       /* If all zeros the arguments are equal
18479 +                                           so return 1 else return 0 */
18480 +        ret     0
18481 +0:      
18482 +        /* check for NaN */
18483 +        lsl     r11,1
18484 +       mov_imm r12, 0xffe00000
18485 +        cp.w    r10,0
18486 +        cpc     r11,r12                 /* check if nan or inf */
18487 +        retls   1                       /* If Arg is NaN return 0 else 1*/
18488 +        ret     0                       /* Return  */
18489
18490 +#endif
18491
18492
18493 +#if   defined(L_avr32_f64_cmp_ge) || defined(L_avr32_f64_cmp_lt)
18494
18495 +#ifdef L_avr32_f64_cmp_ge
18496 +        .global __avr32_f64_cmp_ge
18497 +        .type  __avr32_f64_cmp_ge,@function
18498 +__avr32_f64_cmp_ge:
18499 +#endif  
18500 +#ifdef L_avr32_f64_cmp_lt
18501 +        .global __avr32_f64_cmp_lt
18502 +        .type  __avr32_f64_cmp_lt,@function
18503 +__avr32_f64_cmp_lt:
18504 +#endif  
18505
18506 +        /* compare magnitude of op1 and op2 */
18507 +        st.w    --sp, lr
18508 +        st.w    --sp, r7
18509 +        lsl     r11,1                   /* Remove sign bit of op1 */
18510 +        srcs    r12                     /* Sign op1 to lsb of r12*/
18511 +        lsl     r9,1                    /* Remove sign bit of op2 */
18512 +        srcs    r7
18513 +        rol     r12                     /* Sign op2 to lsb of lr, sign bit op1 bit 1 of r12*/
18514 +       
18515
18516 +        /* Check for Nan */
18517 +        mov_imm lr, 0xffe00000
18518 +        cp.w    r10,0
18519 +        cpc     r11,lr
18520 +        brhi    0f      /* We have NaN */
18521 +        cp.w    r8,0
18522 +        cpc     r9,lr
18523 +        brhi    0f      /* We have NaN */
18524 +
18525 +        cp.w    r11, 0
18526 +        subfeq  r10, 0
18527 +        breq    3f                     /* op1 zero */
18528 +        ld.w    r7, sp++
18529 +        ld.w    lr, sp++
18530 +
18531 +        cp.w    r12,3                   /* both operands negative ?*/    
18532 +        breq    1f
18533
18534 +        cp.w    r12,1                   /* both operands positive? */
18535 +        brlo    2f
18536
18537 +        /* Different signs. If sign of op1 is negative the difference
18538 +           between op1 and op2 will always be negative, and if op1 is
18539 +           positive the difference will always be positive */           
18540 +#ifdef L_avr32_f64_cmp_ge
18541 +       reteq   1
18542 +       retne   0
18543 +#endif
18544 +#ifdef L_avr32_f64_cmp_lt
18545 +       reteq   0
18546 +       retne   1
18547 +#endif
18548 +  
18549 +2:
18550 +        /* Both operands positive. Just compute the difference */
18551 +        cp.w    r10,r8
18552 +        cpc     r11,r9
18553 +#ifdef L_avr32_f64_cmp_ge
18554 +       reths   1
18555 +       retlo   0
18556 +#endif
18557 +#ifdef L_avr32_f64_cmp_lt
18558 +       reths   0
18559 +       retlo   1
18560 +#endif
18561 +                
18562 +1:
18563 +        /* Both operands negative. Compute the difference with operands switched */
18564 +        cp     r8,r10
18565 +        cpc    r9,r11
18566 +#ifdef L_avr32_f64_cmp_ge
18567 +       reths   1
18568 +       retlo   0
18569 +#endif
18570 +#ifdef L_avr32_f64_cmp_lt
18571 +       reths   0
18572 +       retlo   1
18573 +#endif
18574 +
18575 +0:      
18576 +        ld.w    r7, sp++
18577 +        popm    pc, r12=0
18578 +#endif
18579
18580 +3:
18581 +        cp.w    r7, 1          /* Check sign bit from r9 */
18582 +#ifdef L_avr32_f64_cmp_ge
18583 +        sreq    r12                   /* If op2 is negative then op1 >= op2. */        
18584 +#endif
18585 +#ifdef L_avr32_f64_cmp_lt
18586 +        srne    r12                   /* If op2 is positve then op1 <= op2. */
18587 +#endif
18588 +        cp.w    r9, 0
18589 +        subfeq  r8, 0
18590 +        ld.w    r7, sp++
18591 +        ld.w    lr, sp++
18592 +#ifdef L_avr32_f64_cmp_ge
18593 +       reteq   1                      /* Both operands are zero. Return true. */
18594 +#endif
18595 +#ifdef L_avr32_f64_cmp_lt
18596 +       reteq   0                      /* Both operands are zero. Return false. */
18597 +#endif
18598 +       ret     r12
18599 +                                       
18600
18601 +#if defined(L_avr32_f64_div) || defined(L_avr32_f64_div_fast)
18602 +        .align  2
18603 +
18604 +#if defined(L_avr32_f64_div_fast)
18605 +        .global __avr32_f64_div_fast
18606 +        .type  __avr32_f64_div_fast,@function
18607 +__avr32_f64_div_fast:
18608 +#else
18609 +        .global __avr32_f64_div
18610 +        .type  __avr32_f64_div,@function
18611 +__avr32_f64_div:
18612 +#endif
18613 +        stm     --sp, r0, r1, r2, r3, r4, r5, r6, r7,lr 
18614 +        /* op1 in {r11,r10}*/
18615 +        /* op2 in {r9,r8}*/
18616 +        eor     lr, r11, r9             /* MSB(lr) = Sign(op1) ^ Sign(op2) */
18617
18618 +        
18619 +        /* Unpack op1 to 2.62 format*/  
18620 +        /* exp: r7 */
18621 +        /* sf:  r11, r10 */
18622 +        lsr     r7, r11, 20 /* Extract exponent */
18623 +                
18624 +        lsl     r11, 9 /* Extract mantissa, leave room for implicit bit */ 
18625 +        or      r11, r11, r10>>23
18626 +        lsl     r10, 9
18627 +        sbr     r11, 29 /* Insert implicit bit */
18628 +        andh    r11, 0x3fff /*Mask last part of exponent since we use 2.62 format*/
18629
18630 +        cbr     r7, 11       /* Clear sign bit */
18631 +        /* Check if normalization is needed */
18632 +        breq    11f /*If number is subnormal, normalize it */
18633 +22:     
18634 +        cp      r7, 0x7ff
18635 +        brge    2f  /* Check op1 for NaN or Inf */
18636 +
18637 +        /* Unpack op2 to 2.62 format*/
18638 +        /* exp: r6 */
18639 +        /* sf:  r9, r8 */
18640 +        lsr     r6, r9, 20 /* Extract exponent */
18641 +                
18642 +        lsl     r9, 9 /* Extract mantissa, leave room for implicit bit */ 
18643 +        or      r9, r9, r8>>23
18644 +        lsl     r8, 9
18645 +        sbr     r9, 29 /* Insert implicit bit */
18646 +        andh    r9, 0x3fff /*Mask last part of exponent since we use 2.62 format*/
18647
18648 +        cbr     r6, 11       /* Clear sign bit */
18649 +        /* Check if normalization is needed */
18650 +        breq    13f /*If number is subnormal, normalize it */
18651 +23:             
18652 +        cp      r6, 0x7ff
18653 +        brge    3f  /* Check op2 for NaN or Inf */
18654 +
18655 +        /* Calculate new exponent */
18656 +        sub     r7, r6
18657 +        sub     r7,-1023
18658
18659 +        /* Divide */
18660 +        /* Approximating 1/d with the following recurrence: */
18661 +        /* R[j+1] = R[j]*(2-R[j]*d) */
18662 +        /* Using 2.62 format */
18663 +        /* TWO:  r12 */
18664 +        /* d = op2 = divisor (2.62 format): r9,r8 */
18665 +        /* Multiply result :     r5, r4 */
18666 +        /* Initial guess :       r3, r2 */
18667 +        /* New approximations :  r3, r2 */
18668 +        /* op1 = Dividend (2.62 format) : r11, r10 */
18669
18670 +       mov_imm r12, 0x80000000
18671 +         
18672 +        /* Load initial guess, using look-up table */
18673 +        /* Initial guess is of format 01.XY, where XY is constructed as follows: */
18674 +        /* Let d be of following format: 00.1xy....., then XY=~xy */
18675 +        /* For d=00.100 = 0,5   -> initial guess=01.11 = 1,75 */
18676 +        /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5  */
18677 +        /* For d=00.110 = 0,75  -> initial guess=01.11 = 1,25 */
18678 +        /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0  */
18679 +        /* r2 is also part of the reg pair forming initial guess, but it*/
18680 +        /* is kept uninitialized to save one cycle since it has so low significance*/
18681
18682 +        lsr     r3, r12, 1
18683 +        bfextu  r4, r9, 27, 2
18684 +        com     r4
18685 +        bfins   r3, r4, 28, 2
18686
18687 +        /* First approximation */
18688 +        /* Approximating to 32 bits */
18689 +        /* r5 = R[j]*d */
18690 +        mulu.d  r4, r3, r9
18691 +        /* r5 = 2-R[j]*d */
18692 +        sub    r5, r12, r5<<2
18693 +        /* r3 = R[j]*(2-R[j]*d) */
18694 +        mulu.d  r4, r3, r5
18695 +        lsl     r3, r5, 2
18696 +         
18697 +        /* Second approximation */
18698 +        /* Approximating to 32 bits */
18699 +        /* r5 = R[j]*d */
18700 +        mulu.d  r4, r3, r9
18701 +        /* r5 = 2-R[j]*d */
18702 +        sub    r5, r12, r5<<2
18703 +        /* r3 = R[j]*(2-R[j]*d) */
18704 +        mulu.d  r4, r3, r5
18705 +        lsl     r3, r5, 2
18706 +         
18707 +        /* Third approximation */
18708 +        /* Approximating to 32 bits */
18709 +        /* r5 = R[j]*d */
18710 +        mulu.d  r4, r3, r9
18711 +        /* r5 = 2-R[j]*d */
18712 +        sub    r5, r12, r5<<2
18713 +        /* r3 = R[j]*(2-R[j]*d) */
18714 +        mulu.d  r4, r3, r5
18715 +        lsl     r3, r5, 2
18716
18717 +        /* Fourth approximation */
18718 +        /* Approximating to 64 bits */
18719 +        /* r5,r4 = R[j]*d */
18720 +        mul_approx_df        r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
18721 +        lsl    r5, 2
18722 +        or     r5, r5, r4>>30
18723 +        lsl    r4, 2
18724 +        /* r5,r4 = 2-R[j]*d */
18725 +        neg    r4
18726 +        sbc    r5, r12, r5
18727 +        /* r3,r2 = R[j]*(2-R[j]*d) */
18728 +        mul_approx_df        r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
18729 +        lsl    r3, r5, 2
18730 +        or     r3, r3, r4>>30
18731 +        lsl    r2, r4, 2
18732
18733
18734 +        /* Fifth approximation */
18735 +        /* Approximating to 64 bits */
18736 +        /* r5,r4 = R[j]*d */
18737 +        mul_approx_df        r3 /*ah*/, r2 /*al*/, r9 /*bh*/, r8 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
18738 +        lsl    r5, 2
18739 +        or     r5, r5, r4>>30
18740 +        lsl    r4, 2
18741 +        /* r5,r4 = 2-R[j]*d */
18742 +        neg    r4
18743 +        sbc    r5, r12, r5
18744 +        /* r3,r2 = R[j]*(2-R[j]*d) */
18745 +        mul_approx_df        r3 /*ah*/, r2 /*al*/, r5 /*bh*/, r4 /*bl*/, r5 /*rh*/, r4 /*rl*/, r1 /*sh*/, r0 /*sl*/
18746 +        lsl    r3, r5, 2
18747 +        or     r3, r3, r4>>30
18748 +        lsl    r2, r4, 2
18749
18750
18751 +        /* Multiply with dividend to get quotient */
18752 +        mul_approx_df        r3 /*ah*/, r2 /*al*/, r11 /*bh*/, r10 /*bl*/, r3 /*rh*/, r2 /*rl*/, r1 /*sh*/, r0 /*sl*/
18753
18754
18755 +        /* To increase speed, this result is not corrected before final rounding.*/
18756 +        /* This may give a difference to IEEE compliant code of 1 ULP.*/
18757 +               
18758
18759 +        /* Adjust exponent and mantissa */
18760 +        /* r7:exp, [r3, r2]:mant, [r5, r4]:scratch*/
18761 +        /* Mantissa may be of the format 0.xxxx or 1.xxxx. */
18762 +        /* In the first case, shift one pos to left.*/
18763 +        bld     r3, 31-3
18764 +       breq    0f
18765 +       lsl     r2, 1
18766 +       rol     r3
18767 +       sub     r7, 1
18768 +#if defined(L_avr32_f64_div)
18769 +       /* We must scale down the dividend to 5.59 format. */
18770 +       lsr     r10, 3
18771 +       or      r10, r10, r11 << 29
18772 +       lsr     r11, 3
18773 +       rjmp    1f
18774 +#endif 
18775 +0:     
18776 +#if defined(L_avr32_f64_div)
18777 +       /* We must scale down the dividend to 6.58 format. */
18778 +       lsr     r10, 4
18779 +       or      r10, r10, r11 << 28
18780 +       lsr     r11, 4
18781 +1:     
18782 +#endif
18783 +        cp      r7, 0   
18784 +        brle    __avr32_f64_div_res_subnormal /* Result was subnormal. */
18785
18786
18787 +#if defined(L_avr32_f64_div)
18788 +       /* In order to round correctly we calculate the remainder:      
18789 +          Remainder = dividend[11:r10] - divisor[r9:r8]*quotient[r3:r2] 
18790 +          for the case when the quotient is halfway between the round-up
18791 +          value and the round down value. If the remainder then is negative
18792 +          it means that the quotient was to big and that it should not be
18793 +           rounded up, if the remainder is positive the quotient was to small
18794 +          and we need to round up. If the remainder is zero it means that the
18795 +          quotient is exact but since we need to remove the guard bit we should
18796 +          round to even. */
18797 +
18798 +       /* Truncate and add guard bit. */
18799 +       andl    r2, 0xff00
18800 +       orl     r2, 0x0080      
18801 +       
18802 +
18803 +       /* Now do the multiplication. The quotient has the format 4.60
18804 +          while the divisor has the format 2.62 which gives a result
18805 +          of 6.58 */
18806 +        mulu.d  r0, r3, r8
18807 +        macu.d  r0, r2, r9
18808 +        mulu.d  r4, r2, r8
18809 +        mulu.d  r8, r3, r9
18810 +       add     r5, r0
18811 +       adc     r8, r8, r1      
18812 +       acr     r9
18813 +
18814 +
18815 +       /* Check if remainder is positive, negative or equal. */
18816 +       bfextu  r12, r2, 8, 1  /* Get parity bit into bit 0 of r0 */ 
18817 +       cp      r4, 0
18818 +       cpc     r5
18819 +__avr32_f64_div_round_subnormal:       
18820 +       cpc     r8, r10
18821 +       cpc     r9, r11
18822 +       srlo    r6      /* Remainder positive:   we need to round up.*/
18823 +       moveq   r6, r12  /* Remainder zero:      round up if mantissa odd. */
18824 +#else
18825 +       bfextu  r6, r2, 7, 1  /* Get guard bit */       
18826 +#endif
18827 +       /* Final packing, scale down mantissa. */
18828 +       lsr     r10, r2, 8
18829 +        or      r10, r10, r3<<24
18830 +        lsr     r11, r3, 8
18831 +       /* Insert exponent and sign bit*/
18832 +       bfins   r11, r7, 20, 11
18833 +        bld     lr, 31
18834 +        bst     r11, 31
18835 +
18836 +       /* Final rounding */
18837 +       add     r10, r6
18838 +       acr     r11             
18839 +               
18840 +        /* Return result in [r11,r10] */
18841 +        ldm     sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
18842
18843 +                
18844 +2:
18845 +        /* Op1 is NaN or inf */
18846 +        andh    r11, 0x000f /* Extract mantissa */
18847 +        or      r11, r10
18848 +        brne    16f     /* Return NaN if op1 is NaN */
18849 +        /* Op1 is inf check op2 */
18850 +        lsr     r6, r9, 20 /* Extract exponent */
18851 +        cbr     r6, 11      /* Clear sign bit */
18852 +        cp      r6, 0x7ff
18853 +        brne    17f     /* Inf/number gives inf, return inf */
18854 +        rjmp    16f     /* The rest gives NaN*/
18855 +        
18856 +3:      
18857 +        /* Op1 is a valid number. Op 2 is NaN or inf */
18858 +        andh    r9, 0x000f /* Extract mantissa */
18859 +        or      r9, r8
18860 +        brne    16f     /* Return NaN if op2 is NaN */
18861 +        rjmp    15f     /* Op2 was inf, return zero*/
18862 +                
18863 +11:     /* Op1 was denormal. Fix it. */
18864 +        lsl     r11, 3
18865 +        or      r11, r11, r10 >> 29
18866 +        lsl     r10, 3
18867 +        /* Check if op1 is zero. */
18868 +        or      r4, r10, r11
18869 +        breq    __avr32_f64_div_op1_zero
18870 +        normalize_df    r7 /*exp*/, r10, r11 /*Mantissa*/, r4, r5 /*scratch*/
18871 +        lsr     r10, 2
18872 +        or      r10, r10, r11 << 30
18873 +        lsr     r11, 2
18874 +        rjmp    22b
18875
18876
18877 +13:     /* Op2 was denormal. Fix it */
18878 +        lsl     r9, 3
18879 +        or      r9, r9, r8 >> 29
18880 +        lsl     r8, 3
18881 +        /* Check if op2 is zero. */
18882 +        or      r4, r9, r8
18883 +        breq    17f     /* Divisor is zero -> return Inf */
18884 +        normalize_df    r6 /*exp*/, r8, r9 /*Mantissa*/, r4, r5 /*scratch*/     
18885 +        lsr     r8, 2
18886 +        or      r8, r8, r9 << 30
18887 +        lsr     r9, 2
18888 +        rjmp    23b
18889 +        
18890
18891 +__avr32_f64_div_res_subnormal:/* Divide result was subnormal. */
18892 +#if defined(L_avr32_f64_div)
18893 +       /* Check how much we must scale down the mantissa. */
18894 +       neg     r7
18895 +       sub     r7, -1     /* We do no longer have an implicit bit. */
18896 +       satu    r7 >> 0, 6 /* Saturate shift amount to max 63. */
18897 +       cp.w    r7, 32
18898 +       brge    0f
18899 +       /* Shift amount <32 */
18900 +       /* Scale down quotient */
18901 +       rsub    r6, r7, 32
18902 +       lsr     r2, r2, r7
18903 +       lsl     r12, r3, r6
18904 +       or      r2, r12
18905 +       lsr     r3, r3, r7
18906 +       /* Scale down the dividend to match the scaling of the quotient. */
18907 +       lsl     r1, r10, r6
18908 +       lsr     r10, r10, r7
18909 +       lsl     r12, r11, r6
18910 +       or      r10, r12
18911 +       lsr     r11, r11, r7
18912 +       mov     r0, 0
18913 +       rjmp    1f
18914 +0:
18915 +       /* Shift amount >=32 */
18916 +       rsub    r6, r7, 32
18917 +       moveq   r0, 0
18918 +       moveq   r12, 0
18919 +       breq    0f
18920 +       lsl     r0, r10, r6
18921 +       lsl     r12, r11, r6
18922 +0:     
18923 +       lsr     r2, r3, r7
18924 +       mov     r3, 0
18925 +       /* Scale down the dividend to match the scaling of the quotient. */
18926 +       lsr     r1, r10, r7
18927 +       or      r1, r12
18928 +       lsr     r10, r11, r7
18929 +       mov     r11, 0
18930 +1:     
18931 +       /* Start performing the same rounding as done for normal numbers
18932 +          but this time we have scaled the quotient and dividend and hence
18933 +          need a little different comparison. */
18934 +       /* Truncate and add guard bit. */
18935 +       andl    r2, 0xff00
18936 +       orl     r2, 0x0080      
18937 +       
18938 +       /* Now do the multiplication. */
18939 +        mulu.d  r6, r3, r8
18940 +        macu.d  r6, r2, r9
18941 +        mulu.d  r4, r2, r8
18942 +        mulu.d  r8, r3, r9
18943 +       add     r5, r6
18944 +       adc     r8, r8, r7      
18945 +       acr     r9
18946 +
18947 +       /* Set exponent to 0 */
18948 +       mov     r7, 0   
18949 +
18950 +       /* Check if remainder is positive, negative or equal. */
18951 +       bfextu  r12, r2, 8, 1  /* Get parity bit into bit 0 of r0 */ 
18952 +       cp      r4, r0
18953 +       cpc     r5, r1
18954 +       /* Now the rest of the rounding is the same as for normals. */
18955 +       rjmp    __avr32_f64_div_round_subnormal
18956 +       
18957 +#endif
18958 +15:    
18959 +       /* Flush to zero for the fast version. */
18960 +        mov     r11, lr /*Get correct sign*/
18961 +        andh    r11, 0x8000, COH
18962 +        mov     r10, 0
18963 +        ldm     sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
18964 +        
18965 +16:     /* Return NaN. */
18966 +        mov     r11, -1
18967 +        mov     r10, 0
18968 +        ldm     sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
18969 +        
18970 +17:     
18971 +        /* Check if op1 is zero. */
18972 +        or      r4, r10, r11
18973 +        breq    __avr32_f64_div_op1_zero
18974 +        /* Return INF. */
18975 +        mov     r11, lr /*Get correct sign*/
18976 +        andh    r11, 0x8000, COH
18977 +        orh     r11, 0x7ff0
18978 +        mov     r10, 0
18979 +        ldm     sp++, r0, r1, r2, r3, r4, r5, r6, r7,pc
18980 +
18981 +__avr32_f64_div_op1_zero:
18982 +        or      r5, r8, r9 << 1
18983 +        breq    16b             /* 0.0/0.0 -> NaN */
18984 +        bfextu  r4, r9, 20, 11
18985 +        cp      r4, 0x7ff
18986 +        brne    15b             /* Return zero */
18987 +        /* Check if divisor is Inf or NaN */
18988 +        or      r5, r8, r9 << 12
18989 +        breq    15b             /* Divisor is inf -> return zero */
18990 +        rjmp    16b             /* Return NaN */                
18991 +        
18992 +        
18993 +        
18994 +
18995 +#endif  
18996 +                
18997 +#if defined(L_avr32_f32_addsub) || defined(L_avr32_f32_addsub_fast)
18998 +
18999 +        .align  2
19000 +__avr32_f32_sub_from_add:
19001 +        /* Switch sign on op2 */
19002 +        eorh    r11, 0x8000
19003 +
19004 +#if defined(L_avr32_f32_addsub_fast)
19005 +        .global __avr32_f32_sub_fast
19006 +        .type  __avr32_f32_sub_fast,@function
19007 +__avr32_f32_sub_fast:
19008 +#else
19009 +        .global __avr32_f32_sub
19010 +        .type  __avr32_f32_sub,@function
19011 +__avr32_f32_sub:
19012 +#endif 
19013
19014 +        /* Check signs */
19015 +        eor     r8, r11, r12
19016 +        /* Different signs, use subtraction. */
19017 +        brmi    __avr32_f32_add_from_sub
19018
19019 +        /* Get sign of op1 */
19020 +        mov     r8, r12
19021 +        andh    r12, 0x8000, COH                
19022
19023 +        /* Remove sign from operands */
19024 +        cbr     r11, 31
19025 +#if defined(L_avr32_f32_addsub_fast)
19026 +        reteq   r8      /* If op2 is zero return op1 */
19027 +#endif
19028 +        cbr     r8, 31
19029
19030 +        /* Put the number with the largest exponent in r10
19031 +           and the number with the smallest exponent in r9 */
19032 +        max     r10, r8, r11
19033 +        min     r9, r8, r11
19034 +        cp      r10, r8 /*If largest operand (in R10) is not equal to op1*/
19035 +        subne   r12, 1 /* Subtract 1 from sign, which will invert MSB of r12*/
19036 +        andh    r12, 0x8000, COH /*Mask all but MSB*/
19037
19038 +        /* Unpack exponent and mantissa of op1 */
19039 +        lsl     r8, r10, 8
19040 +        sbr     r8, 31  /* Set implicit bit. */
19041 +        lsr     r10, 23 
19042 +                
19043 +        /* op1 is NaN or Inf. */
19044 +        cp.w    r10, 0xff
19045 +        breq    __avr32_f32_sub_op1_nan_or_inf
19046 +        
19047 +        /* Unpack exponent and mantissa of op2 */
19048 +        lsl     r11, r9, 8
19049 +        sbr     r11, 31  /* Set implicit bit. */
19050 +        lsr     r9, 23  
19051
19052 +#if defined(L_avr32_f32_addsub)
19053 +        /* Keep sticky bit for correct IEEE rounding */
19054 +        st.w    --sp, r12
19055
19056 +        /* op2 is either zero or subnormal. */
19057 +        breq    __avr32_f32_sub_op2_subnormal
19058 +0:      
19059 +        /* Get shift amount to scale mantissa of op2. */
19060 +        sub     r12, r10, r9                 
19061 +
19062 +       breq    __avr32_f32_sub_shift_done
19063
19064 +        /* Saturate the shift amount to 31. If the amount
19065 +           is any larger op2 is insignificant. */
19066 +        satu    r12 >> 0, 5      
19067 +
19068 +        /* Put the remaining bits into r9.*/
19069 +        rsub    r9, r12, 32
19070 +        lsl     r9, r11, r9
19071 +       
19072 +       /* If the remaining bits are non-zero then we must subtract one
19073 +          more from opL.  */
19074 +       subne   r8, 1
19075 +       srne    r9      /* LSB of r9 represents sticky bits. */
19076 +
19077 +        /* Shift mantissa of op2 to same decimal point as the mantissa
19078 +           of op1. */
19079 +        lsr     r11, r11, r12
19080
19081 +
19082 +__avr32_f32_sub_shift_done:    
19083 +        /* Now subtract the mantissas. */
19084 +        sub     r8, r11
19085
19086 +        ld.w    r12, sp++
19087
19088 +        /* Normalize resulting mantissa. */
19089 +        clz     r11, r8
19090 +
19091 +       retcs   0
19092 +        lsl     r8, r8, r11
19093 +        sub     r10, r11
19094 +        brle    __avr32_f32_sub_subnormal_result
19095 +
19096 +        /* Insert the bits we will remove from the mantissa into r9[31:24] */
19097 +       or      r9, r9, r8 << 24
19098 +#else
19099 +        /* Ignore sticky bit to simplify and speed up rounding */
19100 +        /* op2 is either zero or subnormal. */
19101 +        breq    __avr32_f32_sub_op2_subnormal
19102 +0:      
19103 +        /* Get shift amount to scale mantissa of op2. */
19104 +        rsub    r9, r10                 
19105
19106 +        /* Saturate the shift amount to 31. If the amount
19107 +           is any larger op2 is insignificant. */
19108 +        satu    r9 >> 0, 5      
19109
19110 +        /* Shift mantissa of op2 to same decimal point as the mantissa
19111 +           of op1. */
19112 +        lsr     r11, r11, r9
19113
19114 +        /* Now subtract the mantissas. */
19115 +        sub     r8, r11
19116
19117 +        /* Normalize resulting mantissa. */
19118 +        clz     r9, r8
19119 +       retcs   0
19120 +        lsl     r8, r8, r9
19121 +        sub     r10, r9
19122 +        brle    __avr32_f32_sub_subnormal_result        
19123 +#endif
19124 +        
19125 +        /* Pack result. */
19126 +        or      r12, r12, r8 >> 8
19127 +        bfins   r12, r10, 23, 8         
19128
19129 +        /* Round */     
19130 +__avr32_f32_sub_round:
19131 +#if defined(L_avr32_f32_addsub)
19132 +       mov_imm r10, 0x80000000
19133 +        bld     r12, 0
19134 +        subne   r10, -1 
19135 +        cp.w    r9, r10
19136 +        subhs   r12, -1
19137 +#else
19138 +        bld     r8, 7 
19139 +        acr     r12
19140 +#endif  
19141 +        
19142 +        ret     r12     
19143
19144
19145 +__avr32_f32_sub_op2_subnormal:
19146 +        /* Fix implicit bit and adjust exponent of subnormals. */
19147 +        cbr     r11, 31
19148 +        /* Set exponent to 1 if we do not have a zero. */
19149 +        movne   r9,1
19150
19151 +        /* Check if op1 is also subnormal. */
19152 +        cp.w    r10, 0
19153 +        brne    0b
19154
19155 +        cbr     r8, 31
19156 +         /* If op1 is not zero set exponent to 1. */
19157 +        movne   r10,1
19158 +                
19159 +        rjmp    0b
19160
19161 +__avr32_f32_sub_op1_nan_or_inf: 
19162 +        /* Check if op1 is NaN, if so return NaN */
19163 +        lsl     r11, r8, 1
19164 +        retne   -1
19165
19166 +        /* op1 is Inf. */
19167 +        bfins   r12, r10, 23, 8 /* Generate Inf in r12 */
19168
19169 +        /* Check if op2 is Inf. or NaN */
19170 +        lsr     r11, r9, 23
19171 +        cp.w    r11, 0xff
19172 +        retne   r12             /* op2 not Inf or NaN, return op1 */
19173
19174 +        ret     -1              /* op2 Inf or NaN, return NaN */
19175
19176 +__avr32_f32_sub_subnormal_result:
19177 +        /* Check if the number is so small that
19178 +           it will be represented with zero. */
19179 +        rsub    r10, r10, 9
19180 +        rsub    r11, r10, 32
19181 +        retcs   0
19182
19183 +        /* Shift the mantissa into the correct position.*/
19184 +        lsr     r10, r8, r10
19185 +        /* Add sign bit. */
19186 +        or      r12, r10
19187 +
19188 +        /* Put the shifted out bits in the most significant part
19189 +           of r8. */
19190 +        lsl     r8, r8, r11
19191
19192 +#if defined(L_avr32_f32_addsub)
19193 +        /* Add all the remainder bits used for rounding into r9 */
19194 +        or      r9, r8
19195 +#else
19196 +        lsr     r8, 24 
19197 +#endif
19198 +        rjmp    __avr32_f32_sub_round
19199
19200 +                                
19201 +        .align  2
19202 +
19203 +__avr32_f32_add_from_sub:
19204 +        /* Switch sign on op2 */
19205 +        eorh    r11, 0x8000
19206 +
19207 +#if defined(L_avr32_f32_addsub_fast)
19208 +        .global __avr32_f32_add_fast
19209 +        .type  __avr32_f32_add_fast,@function
19210 +__avr32_f32_add_fast:
19211 +#else
19212 +        .global __avr32_f32_add
19213 +        .type  __avr32_f32_add,@function
19214 +__avr32_f32_add:
19215 +#endif 
19216 +       
19217 +        /* Check signs */
19218 +        eor     r8, r11, r12
19219 +        /* Different signs, use subtraction. */
19220 +        brmi    __avr32_f32_sub_from_add
19221
19222 +        /* Get sign of op1 */
19223 +        mov     r8, r12
19224 +        andh    r12, 0x8000, COH                
19225
19226 +        /* Remove sign from operands */
19227 +        cbr     r11, 31
19228 +#if defined(L_avr32_f32_addsub_fast)
19229 +        reteq   r8      /* If op2 is zero return op1 */
19230 +#endif
19231 +        cbr     r8, 31
19232
19233 +        /* Put the number with the largest exponent in r10
19234 +           and the number with the smallest exponent in r9 */
19235 +        max     r10, r8, r11
19236 +        min     r9, r8, r11
19237
19238 +        /* Unpack exponent and mantissa of op1 */
19239 +        lsl     r8, r10, 8
19240 +        sbr     r8, 31  /* Set implicit bit. */
19241 +        lsr     r10, 23 
19242 +                
19243 +        /* op1 is NaN or Inf. */
19244 +        cp.w    r10, 0xff
19245 +        breq    __avr32_f32_add_op1_nan_or_inf
19246 +        
19247 +        /* Unpack exponent and mantissa of op2 */
19248 +        lsl     r11, r9, 8
19249 +        sbr     r11, 31  /* Set implicit bit. */
19250 +        lsr     r9, 23  
19251
19252 +#if defined(L_avr32_f32_addsub)
19253 +        /* op2 is either zero or subnormal. */
19254 +        breq    __avr32_f32_add_op2_subnormal
19255 +0:      
19256 +        /* Keep sticky bit for correct IEEE rounding */
19257 +        st.w    --sp, r12
19258
19259 +        /* Get shift amount to scale mantissa of op2. */
19260 +        rsub    r9, r10                 
19261
19262 +        /* Saturate the shift amount to 31. If the amount
19263 +           is any larger op2 is insignificant. */
19264 +        satu    r9 >> 0, 5      
19265
19266 +        /* Shift mantissa of op2 to same decimal point as the mantissa
19267 +           of op1. */
19268 +        lsr     r12, r11, r9
19269
19270 +        /* Put the remainding bits into r11[23:..].*/
19271 +        rsub    r9, r9, (32-8)
19272 +        lsl     r11, r11, r9
19273 +        /* Insert the bits we will remove from the mantissa into r11[31:24] */
19274 +        bfins   r11, r12, 24, 8
19275
19276 +        /* Now add the mantissas. */
19277 +        add     r8, r12
19278
19279 +        ld.w    r12, sp++
19280 +#else
19281 +        /* Ignore sticky bit to simplify and speed up rounding */
19282 +        /* op2 is either zero or subnormal. */
19283 +        breq    __avr32_f32_add_op2_subnormal
19284 +0:      
19285 +        /* Get shift amount to scale mantissa of op2. */
19286 +        rsub    r9, r10                 
19287
19288 +        /* Saturate the shift amount to 31. If the amount
19289 +           is any larger op2 is insignificant. */
19290 +        satu    r9 >> 0, 5      
19291
19292 +        /* Shift mantissa of op2 to same decimal point as the mantissa
19293 +           of op1. */
19294 +        lsr     r11, r11, r9
19295
19296 +        /* Now add the mantissas. */
19297 +        add     r8, r11
19298 +        
19299 +#endif
19300 +        /* Check if we overflowed. */
19301 +        brcs    __avr32_f32_add_res_of
19302 +1:      
19303 +        /* Pack result. */
19304 +        or      r12, r12, r8 >> 8
19305 +        bfins   r12, r10, 23, 8         
19306
19307 +        /* Round */     
19308 +#if defined(L_avr32_f32_addsub)
19309 +       mov_imm r10, 0x80000000
19310 +        bld     r12, 0
19311 +        subne   r10, -1 
19312 +        cp.w    r11, r10
19313 +        subhs   r12, -1
19314 +#else
19315 +        bld     r8, 7 
19316 +        acr     r12
19317 +#endif  
19318 +
19319 +        ret     r12     
19320
19321 +__avr32_f32_add_op2_subnormal:
19322 +        /* Fix implicit bit and adjust exponent of subnormals. */
19323 +        cbr     r11, 31
19324 +        /* Set exponent to 1 if we do not have a zero. */
19325 +        movne   r9,1
19326
19327 +        /* Check if op1 is also subnormal. */
19328 +        cp.w    r10, 0
19329 +        brne    0b
19330 +       /* Both operands subnormal, just add the mantissas and 
19331 +          pack. If the addition of the subnormal numbers results
19332 +          in a normal number then the exponent will automatically
19333 +          be set to 1 by the addition. */
19334 +        cbr     r8, 31
19335 +       add     r11, r8
19336 +       or      r12, r12, r11 >> 8
19337 +       ret     r12
19338
19339 +__avr32_f32_add_op1_nan_or_inf: 
19340 +        /* Check if op1 is NaN, if so return NaN */
19341 +        lsl     r11, r8, 1
19342 +        retne   -1
19343
19344 +        /* op1 is Inf. */
19345 +        bfins   r12, r10, 23, 8 /* Generate Inf in r12 */
19346
19347 +        /* Check if op2 is Inf. or NaN */
19348 +        lsr     r11, r9, 23
19349 +        cp.w    r11, 0xff
19350 +        retne   r12             /* op2 not Inf or NaN, return op1 */
19351
19352 +        lsl     r9, 9
19353 +        reteq   r12             /* op2 Inf return op1 */
19354 +        ret     -1              /* op2 is NaN, return NaN */ 
19355
19356 +__avr32_f32_add_res_of:
19357 +        /* We overflowed. Increase exponent and shift mantissa.*/
19358 +        lsr     r8, 1
19359 +        sub     r10, -1
19360
19361 +        /* Clear mantissa to set result to Inf if the exponent is 255. */
19362 +        cp.w    r10, 255
19363 +        moveq   r8, 0
19364 +        moveq   r11, 0
19365 +        rjmp    1b      
19366 +        
19367 +        
19368 +#endif
19369 +
19370 +       
19371 +#if defined(L_avr32_f32_div) || defined(L_avr32_f32_div_fast)
19372 +       .align  2
19373 +
19374 +#if defined(L_avr32_f32_div_fast)
19375 +        .global __avr32_f32_div_fast
19376 +        .type  __avr32_f32_div_fast,@function
19377 +__avr32_f32_div_fast:
19378 +#else
19379 +        .global __avr32_f32_div
19380 +        .type  __avr32_f32_div,@function
19381 +__avr32_f32_div:
19382 +#endif
19383 +        
19384 +        eor     r8, r11, r12            /* MSB(r8) = Sign(op1) ^ Sign(op2) */
19385
19386 +        /* Unpack */
19387 +        lsl     r12,1
19388 +        lsl     r11,1
19389 +        breq    4f                      /* Check op2 for zero */
19390 +
19391 +        tst     r12, r12
19392 +        moveq   r9, 0
19393 +        breq    12f
19394 +
19395 +        /* Unpack op1*/ 
19396 +        /* exp: r9 */
19397 +        /* sf:  r12 */
19398 +        lsr     r9, r12, 24
19399 +        breq    11f /*If number is subnormal*/
19400 +        cp      r9, 0xff
19401 +        brhs    2f  /* Check op1 for NaN or Inf */      
19402 +        lsl     r12, 7
19403 +        sbr     r12, 31 /*Implicit bit*/
19404 +12:                     
19405
19406 +        /* Unpack op2*/
19407 +        /* exp: r10 */
19408 +        /* sf:  r11 */
19409 +        lsr     r10, r11, 24
19410 +        breq    13f /*If number is subnormal*/
19411 +        cp      r10, 0xff
19412 +        brhs    3f  /* Check op2 for NaN or Inf */      
19413 +        lsl     r11,7
19414 +        sbr     r11, 31 /*Implicit bit*/
19415 +
19416 +        cp.w    r9, 0
19417 +        subfeq  r12, 0
19418 +        reteq   0                       /* op1 is zero and op2 is not zero */
19419 +                                        /* or NaN so return zero */
19420 +
19421 +14:     
19422
19423 +        /* For UC3, store with predecrement is faster than stm */
19424 +        st.w    --sp, r5
19425 +        st.d    --sp, r6
19426
19427 +        /* Calculate new exponent */
19428 +        sub     r9, r10
19429 +        sub     r9,-127
19430
19431 +        /* Divide */
19432 +        /* Approximating 1/d with the following recurrence: */
19433 +        /* R[j+1] = R[j]*(2-R[j]*d) */
19434 +        /* Using 2.30 format */
19435 +        /* TWO:  r10 */
19436 +        /* d:    r5 */
19437 +        /* Multiply result :     r6, r7 */
19438 +        /* Initial guess :       r11 */
19439 +        /* New approximations :  r11 */
19440 +        /* Dividend :            r12 */
19441 +
19442 +       /* Load TWO */
19443 +       mov_imm r10, 0x80000000 
19444 +         
19445 +        lsr     r12, 2     /* Get significand of Op1 in 2.30 format */
19446 +        lsr     r5, r11, 2 /* Get significand of Op2 (=d) in 2.30 format */
19447
19448 +        /* Load initial guess, using look-up table */
19449 +        /* Initial guess is of format 01.XY, where XY is constructed as follows: */
19450 +        /* Let d be of following format: 00.1xy....., then XY=~xy */
19451 +        /* For d=00.100 = 0,5   -> initial guess=01.11 = 1,75 */
19452 +        /* For d=00.101 = 0,625 -> initial guess=01.11 = 1,5  */
19453 +        /* For d=00.110 = 0,75  -> initial guess=01.11 = 1,25 */
19454 +        /* For d=00.111 = 0,875 -> initial guess=01.11 = 1,0  */
19455
19456 +        lsr     r11, r10, 1
19457 +        bfextu  r6, r5, 27, 2
19458 +        com     r6
19459 +        bfins   r11, r6, 28, 2
19460
19461 +        /* First approximation */
19462 +        /* r7 = R[j]*d */
19463 +        mulu.d  r6, r11, r5
19464 +        /* r7 = 2-R[j]*d */
19465 +        sub    r7, r10, r7<<2
19466 +        /* r11 = R[j]*(2-R[j]*d) */
19467 +        mulu.d  r6, r11, r7
19468 +        lsl     r11, r7, 2
19469 +         
19470 +        /* Second approximation */
19471 +        /* r7 = R[j]*d */
19472 +        mulu.d  r6, r11, r5
19473 +        /* r7 = 2-R[j]*d */
19474 +        sub    r7, r10, r7<<2
19475 +        /* r11 = R[j]*(2-R[j]*d) */
19476 +        mulu.d  r6, r11, r7
19477 +        lsl     r11, r7, 2
19478 +         
19479 +        /* Third approximation */
19480 +        /* r7 = R[j]*d */
19481 +        mulu.d  r6, r11, r5
19482 +        /* r7 = 2-R[j]*d */
19483 +        sub    r7, r10, r7<<2
19484 +        /* r11 = R[j]*(2-R[j]*d) */
19485 +        mulu.d  r6, r11, r7
19486 +        lsl     r11, r7, 2
19487
19488 +        /* Fourth approximation */
19489 +        /* r7 = R[j]*d */
19490 +        mulu.d  r6, r11, r5
19491 +        /* r7 = 2-R[j]*d */
19492 +        sub    r7, r10, r7<<2
19493 +        /* r11 = R[j]*(2-R[j]*d) */
19494 +        mulu.d  r6, r11, r7
19495 +        lsl     r11, r7, 2
19496
19497
19498 +        /* Multiply with dividend to get quotient, r7 = sf(op1)/sf(op2) */
19499 +        mulu.d  r6, r11, r12
19500
19501 +        /* Shift by 3 to get result in 1.31 format, as required by the exponent. */
19502 +        /* Note that 1.31 format is already used by the exponent in r9, since */
19503 +        /* a bias of 127 was added to the result exponent, even though the implicit */
19504 +        /* bit was inserted. This gives the exponent an additional bias of 1, which */
19505 +        /* supports 1.31 format. */
19506 +       //lsl     r10, r7, 3
19507 +
19508 +       /* Adjust exponent and mantissa in case the result is of format
19509 +          0000.1xxx to 0001.xxx*/      
19510 +#if defined(L_avr32_f32_div)
19511 +       lsr     r12, 4  /* Scale dividend to 6.26 format to match the
19512 +                          result of the multiplication of the divisor and 
19513 +                          quotient to get the remainder. */
19514 +#endif
19515 +       bld     r7, 31-3
19516 +       breq    0f
19517 +       lsl     r7, 1   
19518 +       sub     r9, 1
19519 +#if defined(L_avr32_f32_div)
19520 +       lsl     r12, 1  /* Scale dividend to 5.27 format to match the
19521 +                          result of the multiplication of the divisor and 
19522 +                          quotient to get the remainder. */
19523 +#endif
19524 +0:             
19525 +        cp      r9, 0   
19526 +        brle    __avr32_f32_div_res_subnormal /* Result was subnormal. */
19527 +
19528 +               
19529 +#if defined(L_avr32_f32_div)
19530 +       /* In order to round correctly we calculate the remainder:      
19531 +          Remainder = dividend[r12] - divisor[r5]*quotient[r7] 
19532 +          for the case when the quotient is halfway between the round-up
19533 +          value and the round down value. If the remainder then is negative
19534 +          it means that the quotient was to big and that it should not be
19535 +           rounded up, if the remainder is positive the quotient was to small
19536 +          and we need to round up. If the remainder is zero it means that the
19537 +          quotient is exact but since we need to remove the guard bit we should
19538 +          round to even. */
19539 +       andl    r7, 0xffe0
19540 +       orl     r7, 0x0010
19541 +
19542 +       /* Now do the multiplication. The quotient has the format 4.28
19543 +          while the divisor has the format 2.30 which gives a result
19544 +          of 6.26 */
19545 +       mulu.d  r10, r5, r7
19546 +
19547 +       /* Check if remainder is positive, negative or equal. */
19548 +       bfextu  r5, r7, 5, 1  /* Get parity bit into bit 0 of r5 */ 
19549 +       cp      r10, 0
19550 +__avr32_f32_div_round_subnormal:       
19551 +       cpc     r11, r12
19552 +       srlo    r11     /* Remainder positive:   we need to round up.*/
19553 +       moveq   r11, r5  /* Remainder zero:      round up if mantissa odd. */
19554 +#else
19555 +       bfextu  r11, r7, 4, 1  /* Get guard bit */      
19556 +#endif
19557 +                               
19558 +        /* Pack final result*/
19559 +        lsr     r12, r7, 5
19560 +        bfins   r12, r9, 23, 8
19561 +        /* For UC3, load with postincrement is faster than ldm */
19562 +        ld.d    r6, sp++
19563 +        ld.w    r5, sp++
19564 +        bld     r8, 31
19565 +        bst     r12, 31
19566 +       /* Rounding add. */
19567 +       add     r12, r11
19568 +        ret     r12
19569 +
19570 +__divsf_return_op1:     
19571 +        lsl     r8, 1
19572 +        ror     r12
19573 +        ret     r12
19574
19575
19576 +2:
19577 +        /* Op1 is NaN or inf */
19578 +        retne   -1      /* Return NaN if op1 is NaN */
19579 +        /* Op1 is inf check op2 */
19580 +       mov_imm r9, 0xff000000
19581 +        cp      r11, r9
19582 +        brlo    __divsf_return_op1 /* inf/number gives inf */
19583 +        ret     -1      /* The rest gives NaN*/
19584 +3:      
19585 +        /* Op2 is NaN or inf */
19586 +        reteq   0       /* Return zero if number/inf*/
19587 +        ret     -1      /* Return NaN*/
19588 +4:
19589 +        /* Op1 is zero ? */
19590 +        tst     r12,r12
19591 +        reteq   -1      /* 0.0/0.0 is NaN */
19592 +        /* Op1 is Nan? */
19593 +        lsr     r9, r12, 24
19594 +        breq    11f /*If number is subnormal*/
19595 +        cp      r9, 0xff
19596 +        brhs    2b  /* Check op1 for NaN or Inf */
19597 +        /* Nonzero/0.0 is Inf. Sign bit will be shifted in before returning*/
19598 +       mov_imm r12, 0xff000000
19599 +        rjmp    __divsf_return_op1
19600 +                
19601 +11:     /* Op1 was denormal. Fix it. */
19602 +        lsl     r12,7
19603 +        clz     r9,r12
19604 +        lsl     r12,r12,r9
19605 +        rsub    r9,r9,1
19606 +        rjmp    12b
19607
19608 +13:     /* Op2 was denormal. Fix it. */ 
19609 +        lsl     r11,7
19610 +        clz     r10,r11
19611 +        lsl     r11,r11,r10
19612 +        rsub    r10,r10,1
19613 +        rjmp    14b
19614 +        
19615
19616 +__avr32_f32_div_res_subnormal:     /* Divide result was subnormal */
19617 +#if defined(L_avr32_f32_div)
19618 +       /* Check how much we must scale down the mantissa. */
19619 +       neg     r9
19620 +       sub     r9, -1     /* We do no longer have an implicit bit. */
19621 +       satu    r9 >> 0, 5 /* Saturate shift amount to max 32. */
19622 +       /* Scale down quotient */
19623 +       rsub    r10, r9, 32
19624 +       lsr     r7, r7, r9
19625 +       /* Scale down the dividend to match the scaling of the quotient. */
19626 +       lsl     r6, r12, r10    /* Make the divident 64-bit and put the lsw in r6 */
19627 +       lsr     r12, r12, r9
19628 +
19629 +       /* Start performing the same rounding as done for normal numbers
19630 +          but this time we have scaled the quotient and dividend and hence
19631 +          need a little different comparison. */
19632 +       andl    r7, 0xffe0
19633 +       orl     r7, 0x0010
19634 +
19635 +       /* Now do the multiplication. The quotient has the format 4.28
19636 +          while the divisor has the format 2.30 which gives a result
19637 +          of 6.26 */
19638 +       mulu.d  r10, r5, r7
19639 +
19640 +       /* Set exponent to 0 */
19641 +       mov     r9, 0   
19642 +
19643 +       /* Check if remainder is positive, negative or equal. */
19644 +       bfextu  r5, r7, 5, 1  /* Get parity bit into bit 0 of r5 */ 
19645 +       cp      r10, r6
19646 +       rjmp    __avr32_f32_div_round_subnormal
19647 +
19648 +#else
19649 +        ld.d    r6, sp++
19650 +        ld.w    r5, sp++
19651 +        /*Flush to zero*/
19652 +       ret     0
19653 +#endif
19654 +#endif
19655
19656 +#ifdef L_avr32_f32_mul
19657 +        .global __avr32_f32_mul
19658 +        .type  __avr32_f32_mul,@function
19659
19660 +                
19661 +__avr32_f32_mul:
19662 +        mov     r8, r12
19663 +        eor     r12, r11                /* MSB(r8) = Sign(op1) ^ Sign(op2) */
19664 +        andh    r12, 0x8000, COH
19665 +        
19666 +        /* arrange operands so that that op1 >= op2 */
19667 +        cbr     r8, 31
19668 +        breq    __avr32_f32_mul_op1_zero
19669 +        cbr     r11, 31
19670
19671 +        /* Put the number with the largest exponent in r10
19672 +           and the number with the smallest exponent in r9 */
19673 +        max     r10, r8, r11
19674 +        min     r9, r8, r11
19675
19676 +        /* Unpack exponent and mantissa of op1 */
19677 +        lsl     r8, r10, 8
19678 +        sbr     r8, 31  /* Set implicit bit. */
19679 +        lsr     r10, 23 
19680 +                
19681 +        /* op1 is NaN or Inf. */
19682 +        cp.w    r10, 0xff
19683 +        breq    __avr32_f32_mul_op1_nan_or_inf
19684 +        
19685 +        /* Unpack exponent and mantissa of op2 */
19686 +        lsl     r11, r9, 8
19687 +        sbr     r11, 31  /* Set implicit bit. */
19688 +        lsr     r9, 23  
19689
19690 +        /* op2 is either zero or subnormal. */
19691 +        breq    __avr32_f32_mul_op2_subnormal
19692 +0:      
19693 +        /* Calculate new exponent */
19694 +        add     r9,r10
19695
19696 +        /* Do the multiplication */
19697 +        mulu.d  r10,r8,r11
19698
19699 +        /* We might need to scale up by two if the MSB of the result is
19700 +           zero. */
19701 +        lsl     r8, r11, 1
19702 +        movcc   r11, r8
19703 +        subcc   r9, 1
19704
19705 +        /* Put the shifted out bits of the mantissa into r10 */
19706 +        lsr     r10, 8
19707 +        bfins   r10, r11, 24, 8
19708 +                
19709 +        sub     r9,(127-1)              /* remove extra exponent bias */
19710 +        brle    __avr32_f32_mul_res_subnormal
19711
19712 +        /* Check for Inf. */
19713 +        cp.w    r9, 0xff
19714 +        brge    1f
19715
19716 +        /* Pack result. */
19717 +        or      r12, r12, r11 >> 8
19718 +        bfins   r12, r9, 23, 8          
19719
19720 +        /* Round */     
19721 +__avr32_f32_mul_round:
19722 +       mov_imm r8, 0x80000000
19723 +        bld     r12, 0
19724 +        subne   r8, -1  
19725
19726 +        cp.w    r10, r8
19727 +        subhs   r12, -1
19728 +        
19729 +        ret     r12     
19730
19731 +1:      
19732 +        /* Return Inf */        
19733 +        orh     r12, 0x7f80
19734 +        ret     r12
19735
19736 +__avr32_f32_mul_op2_subnormal:
19737 +        cbr     r11, 31
19738 +        clz     r9, r11
19739 +        retcs   0       /* op2 is zero. Return 0 */
19740 +        sub     r9, 8
19741 +        lsl     r11, r11, r9
19742 +        rsub    r9, r9, 1
19743 +                
19744 +        /* Check if op2 is subnormal. */
19745 +        tst     r10, r10
19746 +        brne    0b
19747
19748 +        /* op2 is subnormal */  
19749 +        cbr     r8, 31
19750 +        clz     r10, r11
19751 +        retcs   0       /* op1 is zero. Return 0 */
19752 +        lsl     r8, r8, r10
19753 +        rsub    r10, r10, 1
19754 +                        
19755 +        rjmp    0b
19756 +                
19757
19758 +__avr32_f32_mul_op1_nan_or_inf:
19759 +        /* Check if op1 is NaN, if so return NaN */
19760 +        lsl     r11, r8, 1
19761 +        retne   -1
19762
19763 +        /* op1 is Inf. */
19764 +        tst     r9, r9
19765 +        reteq   -1      /* Inf * 0 -> NaN */
19766
19767 +        bfins   r12, r10, 23, 8 /* Generate Inf in r12 */
19768
19769 +        /* Check if op2 is Inf. or NaN */
19770 +        lsr     r11, r9, 23
19771 +        cp.w    r11, 0xff
19772 +        retne   r12             /* op2 not Inf or NaN, return Info */
19773
19774 +        lsl     r9, 9
19775 +        reteq   r12             /* op2 Inf return Inf */
19776 +        ret     -1              /* op2 is NaN, return NaN */ 
19777 +        
19778 +__avr32_f32_mul_res_subnormal:
19779 +        /* Check if the number is so small that
19780 +           it will be represented with zero. */
19781 +        rsub    r9, r9, 9
19782 +        rsub    r8, r9, 32
19783 +        retcs   0
19784
19785 +        /* Shift the mantissa into the correct position.*/
19786 +        lsr     r9, r11, r9
19787 +        /* Add sign bit. */
19788 +        or      r12, r9
19789 +        /* Put the shifted out bits in the most significant part
19790 +           of r8. */
19791 +        lsl     r11, r11, r8
19792
19793 +        /* Add all the remainder bits used for rounding into r11 */
19794 +        andh    r10, 0x00FF     
19795 +        or      r10, r11
19796 +        rjmp    __avr32_f32_mul_round
19797 +
19798 +__avr32_f32_mul_op1_zero:
19799 +        bfextu  r10, r11, 23, 8
19800 +        cp.w    r10, 0xff
19801 +        retne   r12
19802 +        reteq   -1        
19803
19804 +#endif  
19805
19806 +        
19807 +#ifdef L_avr32_s32_to_f32
19808 +        .global __avr32_s32_to_f32
19809 +        .type  __avr32_s32_to_f32,@function
19810 +__avr32_s32_to_f32:
19811 +        cp      r12, 0
19812 +        reteq   r12     /* If zero then return zero float */
19813 +        mov     r11, r12 /* Keep the sign */
19814 +        abs     r12     /* Compute the absolute value */
19815 +        mov     r10, 31 + 127   /* Set the correct exponent */
19816 +        
19817 +        /* Normalize */
19818 +        normalize_sf    r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/       
19819
19820 +        /* Check for subnormal result */
19821 +        cp.w    r10, 0
19822 +        brle    __avr32_s32_to_f32_subnormal
19823
19824 +        round_sf        r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/       
19825 +        pack_sf         r12 /*sf*/, r10 /*exp*/, r12 /*mant*/
19826 +        lsl     r11, 1
19827 +        ror     r12
19828 +        ret     r12             
19829
19830 +__avr32_s32_to_f32_subnormal:
19831 +        /* Adjust a subnormal result */
19832 +        adjust_subnormal_sf     r12/*sf*/, r10 /*exp*/, r12 /*mant*/, r11/*sign*/, r9 /*scratch*/
19833 +        ret     r12
19834 +        
19835 +#endif
19836
19837 +#ifdef L_avr32_u32_to_f32
19838 +        .global __avr32_u32_to_f32
19839 +        .type  __avr32_u32_to_f32,@function
19840 +__avr32_u32_to_f32:
19841 +        cp      r12, 0
19842 +        reteq   r12     /* If zero then return zero float */
19843 +        mov     r10, 31 + 127   /* Set the correct exponent */
19844 +        
19845 +        /* Normalize */
19846 +        normalize_sf    r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/       
19847
19848 +        /* Check for subnormal result */
19849 +        cp.w    r10, 0
19850 +        brle    __avr32_u32_to_f32_subnormal
19851
19852 +        round_sf        r10 /*exp*/, r12 /*mant*/, r9 /*scratch*/       
19853 +        pack_sf         r12 /*sf*/, r10 /*exp*/, r12 /*mant*/
19854 +        lsr     r12,1   /* Sign bit is 0 for unsigned int */
19855 +        ret     r12             
19856
19857 +__avr32_u32_to_f32_subnormal:
19858 +        /* Adjust a subnormal result */
19859 +        mov     r8, 0
19860 +        adjust_subnormal_sf     r12/*sf*/,r10 /*exp*/, r12 /*mant*/,r8/*sign*/, r9 /*scratch*/
19861 +        ret     r12
19862 +        
19863 +        
19864 +#endif
19865 +        
19866
19867 +#ifdef L_avr32_f32_to_s32
19868 +        .global __avr32_f32_to_s32
19869 +        .type  __avr32_f32_to_s32,@function
19870 +__avr32_f32_to_s32:
19871 +        bfextu  r11, r12, 23, 8
19872 +        sub     r11,127                 /* Fix bias */
19873 +        retlo   0                       /* Negative exponent yields zero integer */
19874
19875 +        /* Shift mantissa into correct position */
19876 +        rsub    r11,r11,31      /* Shift amount */
19877 +        lsl     r10,r12,8       /* Get mantissa */
19878 +        sbr     r10,31          /* Add implicit bit */
19879 +        lsr     r10,r10,r11     /* Perform shift */
19880 +        lsl     r12,1           /* Check sign */
19881 +        retcc   r10             /* if positive, we are done */
19882 +        neg     r10             /* if negative float, negate result */
19883 +        ret     r10
19884
19885 +#endif  
19886 +        
19887 +#ifdef L_avr32_f32_to_u32
19888 +        .global __avr32_f32_to_u32
19889 +        .type  __avr32_f32_to_u32,@function
19890 +__avr32_f32_to_u32:
19891 +        cp      r12,0
19892 +        retmi   0                       /* Negative numbers gives 0 */
19893 +        bfextu  r11, r12, 23, 8         /* Extract exponent */
19894 +        sub     r11,127                 /* Fix bias */
19895 +        retlo   0                       /* Negative exponent yields zero integer */
19896
19897 +        /* Shift mantissa into correct position */
19898 +        rsub    r11,r11,31      /* Shift amount */
19899 +        lsl     r12,8           /* Get mantissa */
19900 +        sbr     r12,31          /* Add implicit bit */
19901 +        lsr     r12,r12,r11     /* Perform shift */
19902 +        ret     r12
19903
19904 +#endif  
19905
19906 +#ifdef L_avr32_f32_to_f64
19907 +        .global __avr32_f32_to_f64
19908 +        .type  __avr32_f32_to_f64,@function
19909
19910 +__avr32_f32_to_f64:
19911 +        lsl     r11,r12,1               /* Remove sign bit, keep original value in r12*/
19912 +        moveq   r10, 0
19913 +        reteq   r11                     /* Return zero if input is zero */
19914
19915 +        bfextu  r9,r11,24,8              /* Get exponent */
19916 +        cp.w    r9,0xff                 /* check for NaN or inf */
19917 +        breq    0f
19918
19919 +        lsl     r11,7                   /* Convert sf mantissa to df format */
19920 +        mov     r10,0
19921
19922 +        /* Check if implicit bit should be set */
19923 +        cp.w    r9, 0
19924 +        subeq   r9,-1                    /* Adjust exponent if it was 0 */
19925 +        srne    r8
19926 +        or      r11, r11, r8 << 31      /* Set implicit bit if needed */
19927 +        sub     r9,(127-0x3ff)          /* Convert exponent to df format exponent */
19928
19929 +        /*We know that low register of mantissa is 0, and will be unaffected by normalization.*/
19930 +        /*We can therefore use the faster normalize_sf function instead of normalize_df.*/
19931 +        normalize_sf    r9 /*exp*/, r11 /*mantissa*/, r8 /*scratch*/
19932 +        pack_df         r9 /*exp*/, r10, r11 /*mantissa*/, r10, r11 /*df*/
19933
19934 +__extendsfdf_return_op1:        
19935 +        /* Rotate in sign bit */
19936 +        lsl     r12, 1
19937 +        ror     r11
19938 +        ret     r11
19939 +                        
19940 +0:
19941 +        /* Inf or NaN*/
19942 +       mov_imm r10, 0xffe00000
19943 +        lsl     r11,8                   /* check mantissa */
19944 +        movne   r11, -1                 /* Return NaN */
19945 +        moveq   r11, r10                /* Return inf */
19946 +        mov     r10, 0
19947 +        rjmp    __extendsfdf_return_op1
19948 +#endif                  
19949
19950
19951 +#ifdef L_avr32_f64_to_f32
19952 +        .global __avr32_f64_to_f32
19953 +        .type  __avr32_f64_to_f32,@function
19954
19955 +__avr32_f64_to_f32:
19956 +        /* Unpack */
19957 +        lsl     r9,r11,1                /* Unpack exponent */
19958 +        lsr     r9,21
19959
19960 +        reteq   0                       /* If exponent is 0 the number is so small
19961 +                                           that the conversion to single float gives
19962 +                                           zero */
19963
19964 +        lsl     r8,r11,10                  /* Adjust mantissa */
19965 +        or      r12,r8,r10>>22
19966
19967 +        lsl     r10,10                  /* Check if there are any remaining bits
19968 +                                           in the low part of the mantissa.*/
19969 +        neg     r10
19970 +        rol     r12                     /* If there were remaining bits then set lsb
19971 +                                           of mantissa to 1 */
19972
19973 +        cp      r9,0x7ff
19974 +        breq    2f                      /* Check for NaN or inf */
19975
19976 +        sub     r9,(0x3ff-127)          /* Adjust bias of exponent */
19977 +        sbr     r12,31                  /* set the implicit bit.*/
19978
19979 +        cp.w    r9, 0                   /* Check for subnormal number */
19980 +        brle    3f
19981
19982 +        round_sf        r9 /*exp*/, r12 /*mant*/, r10 /*scratch*/       
19983 +        pack_sf         r12 /*sf*/, r9 /*exp*/, r12 /*mant*/
19984 +__truncdfsf_return_op1: 
19985 +        /* Rotate in sign bit */
19986 +        lsl     r11, 1
19987 +        ror     r12
19988 +        ret     r12             
19989 +        
19990 +2:
19991 +        /* NaN or inf */
19992 +        cbr     r12,31                  /* clear implicit bit */
19993 +        retne   -1                      /* Return NaN if mantissa not zero */
19994 +       mov_imm r12, 0x7f800000
19995 +        ret     r12                     /* Return inf */
19996
19997 +3:      /* Result is subnormal. Adjust it.*/
19998 +        adjust_subnormal_sf     r12/*sf*/,r9 /*exp*/, r12 /*mant*/, r11/*sign*/, r10 /*scratch*/
19999 +        ret     r12
20000 +        
20001 +                
20002 +#endif
20003
20004 +#if defined(L_mulsi3) && defined(__AVR32_NO_MUL__)
20005 +       .global __mulsi3
20006 +       .type __mulsi3,@function
20007 +
20008 +__mulsi3:
20009 +       mov r9, 0
20010 +0:
20011 +       lsr r11, 1
20012 +       addcs r9, r9, r12
20013 +       breq 1f
20014 +       lsl r12, 1
20015 +       rjmp 0b
20016 +1:
20017 +       ret r9
20018 +#endif
20019 --- /dev/null
20020 +++ b/gcc/config/avr32/lib2funcs.S
20021 @@ -0,0 +1,21 @@
20022 +       .align  4
20023 +       .global __nonlocal_goto
20024 +       .type  __nonlocal_goto,@function
20025 +
20026 +/* __nonlocal_goto:    This function handles nonlocal_goto's in gcc.
20027 +
20028 +       parameter 0 (r12) = New Frame Pointer
20029 +       parameter 1 (r11) = Address to goto
20030 +       parameter 2 (r10) = New Stack Pointer
20031 +
20032 +       This function invalidates the return stack, since it returns from a
20033 +       function without using a return instruction.
20034 +*/
20035 +__nonlocal_goto:
20036 +       mov     r7, r12
20037 +       mov     sp, r10
20038 +       frs                     # Flush return stack
20039 +       mov     pc, r11
20040 +
20041 +
20042 +               
20043 --- /dev/null
20044 +++ b/gcc/config/avr32/linux-elf.h
20045 @@ -0,0 +1,151 @@
20046 +/*
20047 +   Linux/Elf specific definitions.
20048 +   Copyright 2003-2006 Atmel Corporation.
20049 +
20050 +   Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
20051 +   and H�vard Skinnemoen, Atmel Norway, <hskinnemoen@atmel.com>
20052 +
20053 +   This file is part of GCC.
20054 +
20055 +   This program is free software; you can redistribute it and/or modify
20056 +   it under the terms of the GNU General Public License as published by
20057 +   the Free Software Foundation; either version 2 of the License, or
20058 +   (at your option) any later version.
20059 +
20060 +   This program is distributed in the hope that it will be useful,
20061 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
20062 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20063 +   GNU General Public License for more details.
20064 +
20065 +   You should have received a copy of the GNU General Public License
20066 +   along with this program; if not, write to the Free Software
20067 +   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
20068 +
20069 +
20070 +
20071 +/* elfos.h should have already been included.  Now just override
20072 +   any conflicting definitions and add any extras.  */
20073 +
20074 +/* Run-time Target Specification.  */
20075 +#undef  TARGET_VERSION
20076 +#define TARGET_VERSION  fputs (" (AVR32 GNU/Linux with ELF)", stderr);
20077 +
20078 +/* Do not assume anything about header files.  */
20079 +#define NO_IMPLICIT_EXTERN_C
20080 +
20081 +/* The GNU C++ standard library requires that these macros be defined.  */
20082 +#undef CPLUSPLUS_CPP_SPEC
20083 +#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
20084 +
20085 +/* Now we define the strings used to build the spec file.  */
20086 +#undef  LIB_SPEC
20087 +#define LIB_SPEC \
20088 +  "%{pthread:-lpthread} \
20089 +   %{shared:-lc} \
20090 +   %{!shared:%{profile:-lc_p}%{!profile:-lc}}"
20091 +
20092 +/* Provide a STARTFILE_SPEC appropriate for GNU/Linux.  Here we add
20093 +   the GNU/Linux magical crtbegin.o file (see crtstuff.c) which
20094 +   provides part of the support for getting C++ file-scope static
20095 +   object constructed before entering `main'.  */
20096 +
20097 +#undef  STARTFILE_SPEC
20098 +#define STARTFILE_SPEC \
20099 +  "%{!shared: \
20100 +     %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s} \
20101 +                      %{!p:%{profile:gcrt1.o%s} \
20102 +                        %{!profile:crt1.o%s}}}} \
20103 +   crti.o%s %{!shared:crtbegin.o%s} %{shared:crtbeginS.o%s}"
20104 +
20105 +/* Provide a ENDFILE_SPEC appropriate for GNU/Linux.  Here we tack on
20106 +   the GNU/Linux magical crtend.o file (see crtstuff.c) which
20107 +   provides part of the support for getting C++ file-scope static
20108 +   object constructed before entering `main', followed by a normal
20109 +   GNU/Linux "finalizer" file, `crtn.o'.  */
20110 +
20111 +#undef  ENDFILE_SPEC
20112 +#define ENDFILE_SPEC \
20113 +  "%{!shared:crtend.o%s} %{shared:crtendS.o%s} crtn.o%s"
20114 +
20115 +#undef ASM_SPEC
20116 +#define ASM_SPEC "%{!mno-pic:%{!fno-pic:--pic}} %{mrelax|O*:%{mno-relax|O0|O1: ;:--linkrelax}} %{mcpu=*:-mcpu=%*}"
20117
20118 +#undef  LINK_SPEC
20119 +#define LINK_SPEC "%{version:-v} \
20120 +   %{static:-Bstatic} \
20121 +   %{shared:-shared} \
20122 +   %{symbolic:-Bsymbolic} \
20123 +   %{rdynamic:-export-dynamic} \
20124 +   %{!dynamic-linker:-dynamic-linker /lib/ld-uClibc.so.0} \
20125 +   %{mrelax|O*:%{mno-relax|O0|O1: ;:--relax}}"
20126 +
20127 +#define TARGET_OS_CPP_BUILTINS() LINUX_TARGET_OS_CPP_BUILTINS()
20128 +
20129 +/* This is how we tell the assembler that two symbols have the same value.  */
20130 +#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
20131 +  do                                      \
20132 +    {                                     \
20133 +      assemble_name (FILE, NAME1);        \
20134 +      fputs (" = ", FILE);                \
20135 +      assemble_name (FILE, NAME2);        \
20136 +      fputc ('\n', FILE);                 \
20137 +    }                                     \
20138 +  while (0)
20139 +
20140 +
20141 +
20142 +#undef  CC1_SPEC
20143 +#define CC1_SPEC "%{profile:-p}"
20144 +
20145 +/* Target CPU builtins.  */
20146 +#define TARGET_CPU_CPP_BUILTINS()                              \
20147 +  do                                                           \
20148 +    {                                                          \
20149 +      builtin_define ("__avr32__");                            \
20150 +      builtin_define ("__AVR32__");                            \
20151 +      builtin_define ("__AVR32_LINUX__");                      \
20152 +      builtin_define (avr32_part->macro);                      \
20153 +      builtin_define (avr32_arch->macro);                      \
20154 +      if (avr32_arch->uarch_type == UARCH_TYPE_AVR32A)         \
20155 +       builtin_define ("__AVR32_AVR32A__");                    \
20156 +      else                                                     \
20157 +       builtin_define ("__AVR32_AVR32B__");                    \
20158 +      if (TARGET_UNALIGNED_WORD)                               \
20159 +       builtin_define ("__AVR32_HAS_UNALIGNED_WORD__");        \
20160 +      if (TARGET_SIMD)                                         \
20161 +       builtin_define ("__AVR32_HAS_SIMD__");                  \
20162 +      if (TARGET_DSP)                                          \
20163 +       builtin_define ("__AVR32_HAS_DSP__");                   \
20164 +      if (TARGET_RMW)                                          \
20165 +       builtin_define ("__AVR32_HAS_RMW__");                   \
20166 +      if (TARGET_BRANCH_PRED)                                  \
20167 +       builtin_define ("__AVR32_HAS_BRANCH_PRED__");           \
20168 +      if (TARGET_FAST_FLOAT)                                    \
20169 +        builtin_define ("__AVR32_FAST_FLOAT__");                \
20170 +    }                                                          \
20171 +  while (0)
20172 +
20173 +
20174 +
20175 +/* Call the function profiler with a given profile label.  */
20176 +#undef  FUNCTION_PROFILER
20177 +#define FUNCTION_PROFILER(STREAM, LABELNO)                             \
20178 +  do                                                                   \
20179 +    {                                                                  \
20180 +      fprintf (STREAM, "\tmov\tlr, lo(mcount)\n\torh\tlr, hi(mcount)\n"); \
20181 +      fprintf (STREAM, "\ticall lr\n");                                        \
20182 +    }                                                                  \
20183 +  while (0)
20184 +
20185 +#define NO_PROFILE_COUNTERS 1
20186 +
20187 +/* For dynamic libraries to work */
20188 +/* #define PLT_REG_CALL_CLOBBERED 1 */
20189 +#define AVR32_ALWAYS_PIC 1
20190 +
20191 +/* uclibc does not implement sinf, cosf etc. */
20192 +#undef TARGET_C99_FUNCTIONS
20193 +#define TARGET_C99_FUNCTIONS 0
20194 +
20195 +#define LINK_GCC_C_SEQUENCE_SPEC \
20196 +  "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}"
20197 --- /dev/null
20198 +++ b/gcc/config/avr32/predicates.md
20199 @@ -0,0 +1,422 @@
20200 +;;   AVR32 predicates file.
20201 +;;   Copyright 2003-2006 Atmel Corporation.
20202 +;;
20203 +;;   Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
20204 +;;
20205 +;;   This file is part of GCC.
20206 +;;
20207 +;;   This program is free software; you can redistribute it and/or modify
20208 +;;   it under the terms of the GNU General Public License as published by
20209 +;;   the Free Software Foundation; either version 2 of the License, or
20210 +;;   (at your option) any later version.
20211 +;;
20212 +;;   This program is distributed in the hope that it will be useful,
20213 +;;   but WITHOUT ANY WARRANTY; without even the implied warranty of
20214 +;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20215 +;;   GNU General Public License for more details.
20216 +;;
20217 +;;   You should have received a copy of the GNU General Public License
20218 +;;   along with this program; if not, write to the Free Software
20219 +;;   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20220 +
20221 +
20222 +;; True if the operand is a memory reference which contains an
20223 +;; Address consisting of a single pointer register
20224 +(define_predicate "avr32_indirect_register_operand"
20225 +  (and (match_code "mem")
20226 +       (match_test "register_operand(XEXP(op, 0), SImode)")))
20227 +
20228 +
20229 +
20230 +;; Address expression with a base pointer offset with
20231 +;; a register displacement
20232 +(define_predicate "avr32_indexed_memory_operand"
20233 +  (and (match_code "mem")
20234 +       (match_test "GET_CODE(XEXP(op, 0)) == PLUS"))
20235 +  {
20236 +
20237 +   rtx op0 = XEXP(XEXP(op, 0), 0);
20238 +   rtx op1 = XEXP(XEXP(op, 0), 1);
20239 +
20240 +   return ((avr32_address_register_rtx_p (op0, 0)
20241 +            && avr32_legitimate_index_p (GET_MODE(op), op1, 0))
20242 +          || (avr32_address_register_rtx_p (op1, 0)
20243 +            && avr32_legitimate_index_p (GET_MODE(op), op0, 0)));
20244 +
20245 + })
20246 +
20247 +;; Operand suitable for the ld.sb instruction
20248 +(define_predicate "load_sb_memory_operand"
20249 +  (ior (match_operand 0 "avr32_indirect_register_operand")
20250 +       (match_operand 0 "avr32_indexed_memory_operand")))
20251 +
20252 +
20253 +;; Operand suitable as operand to insns sign extending QI values
20254 +(define_predicate "extendqi_operand"
20255 +  (ior (match_operand 0 "load_sb_memory_operand")
20256 +       (match_operand 0 "register_operand")))
20257 +
20258 +(define_predicate "post_inc_memory_operand"
20259 +  (and (match_code "mem")
20260 +       (match_test "(GET_CODE(XEXP(op, 0)) == POST_INC)
20261 +                     && REG_P(XEXP(XEXP(op, 0), 0))")))
20262 +
20263 +(define_predicate "pre_dec_memory_operand"
20264 +  (and (match_code "mem")
20265 +       (match_test "(GET_CODE(XEXP(op, 0)) == PRE_DEC)
20266 +                     && REG_P(XEXP(XEXP(op, 0), 0))")))
20267 +
20268 +;; Operand suitable for add instructions
20269 +(define_predicate "avr32_add_operand"
20270 +  (ior (match_operand 0 "register_operand")
20271 +       (and (match_operand 0 "immediate_operand")
20272 +            (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is21\")"))))
20273 +
20274 +;; Operand is a power of two immediate
20275 +(define_predicate "power_of_two_operand"
20276 +  (match_code "const_int")
20277 +{
20278 +  HOST_WIDE_INT value = INTVAL (op);
20279 +
20280 +  return value != 0 && (value & (value - 1)) == 0;
20281 +})
20282 +
20283 +;; Operand is a multiple of 8 immediate
20284 +(define_predicate "multiple_of_8_operand"
20285 +  (match_code "const_int")
20286 +{
20287 +  HOST_WIDE_INT value = INTVAL (op);
20288 +
20289 +  return (value & 0x7) == 0 ;
20290 +})
20291 +
20292 +;; Operand is a multiple of 16 immediate
20293 +(define_predicate "multiple_of_16_operand"
20294 +  (match_code "const_int")
20295 +{
20296 +  HOST_WIDE_INT value = INTVAL (op);
20297 +
20298 +  return (value & 0xf) == 0 ;
20299 +})
20300 +
20301 +;; Operand is a mask used for masking away upper bits of a reg
20302 +(define_predicate "avr32_mask_upper_bits_operand"
20303 +  (match_code "const_int")
20304 +{
20305 +  HOST_WIDE_INT value = INTVAL (op) + 1;
20306 +
20307 +  return value != 1 && value != 0 && (value & (value - 1)) == 0;
20308 +})
20309 +
20310 +
20311 +;; Operand suitable for mul instructions
20312 +(define_predicate "avr32_mul_operand"
20313 +  (ior (match_operand 0 "register_operand")
20314 +       (and (match_operand 0 "immediate_operand")
20315 +            (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")"))))
20316 +
20317 +;; True for logical binary operators.
20318 +(define_predicate "logical_binary_operator"
20319 +  (match_code "ior,xor,and"))
20320 +
20321 +;; True for logical shift operators
20322 +(define_predicate "logical_shift_operator"
20323 +  (match_code "ashift,lshiftrt"))
20324 +
20325 +;; True for shift operand for logical and, or and eor insns
20326 +(define_predicate "avr32_logical_shift_operand"
20327 +  (and (match_code "ashift,lshiftrt")
20328 +       (ior (and (match_test "GET_CODE(XEXP(op, 1)) == CONST_INT")
20329 +                 (match_test "register_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))"))
20330 +            (and (match_test "GET_CODE(XEXP(op, 0)) == CONST_INT")
20331 +                 (match_test "register_operand(XEXP(op, 1), GET_MODE(XEXP(op, 1)))"))))
20332 +  )
20333 +
20334 +
20335 +;; Predicate for second operand to and, ior and xor insn patterns
20336 +(define_predicate "avr32_logical_insn_operand"
20337 +  (ior (match_operand 0 "register_operand")
20338 +       (match_operand 0 "avr32_logical_shift_operand"))
20339 +)
20340 +
20341 +
20342 +;; True for avr32 comparison operators
20343 +(define_predicate "avr32_comparison_operator"
20344 +  (ior (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu")
20345 +       (and (match_code "unspec")
20346 +            (match_test "(XINT(op, 1) == UNSPEC_COND_MI)
20347 +                         || (XINT(op, 1) == UNSPEC_COND_PL)"))))
20348 +
20349 +(define_predicate "avr32_cond3_comparison_operator"
20350 +  (ior (match_code "eq, ne, ge, lt, geu, ltu")
20351 +       (and (match_code "unspec")
20352 +            (match_test "(XINT(op, 1) == UNSPEC_COND_MI)
20353 +                         || (XINT(op, 1) == UNSPEC_COND_PL)"))))
20354 +
20355 +;; True for avr32 comparison operand
20356 +(define_predicate "avr32_comparison_operand"
20357 +  (ior (and (match_code "eq, ne, gt, ge, lt, le, gtu, geu, ltu, leu")
20358 +            (match_test "(CC0_P (XEXP(op,0)) && rtx_equal_p (XEXP(op,1), const0_rtx))"))
20359 +       (and (match_code "unspec")
20360 +            (match_test "(XINT(op, 1) == UNSPEC_COND_MI)
20361 +                         || (XINT(op, 1) == UNSPEC_COND_PL)"))))
20362 +
20363 +;; True if this is a const_int with one bit set
20364 +(define_predicate "one_bit_set_operand"
20365 +  (match_code "const_int")
20366 +  {
20367 +   int i;
20368 +   int value;
20369 +   int ones = 0;
20370 +
20371 +   value = INTVAL(op);
20372 +   for ( i = 0 ; i < 32; i++ ){
20373 +     if ( value & ( 1 << i ) ){
20374 +        ones++;
20375 +      }
20376 +   }
20377 +
20378 +   return ( ones == 1 );
20379 +  })
20380 +
20381 +
20382 +;; True if this is a const_int with one bit cleared
20383 +(define_predicate "one_bit_cleared_operand"
20384 +  (match_code "const_int")
20385 +  {
20386 +   int i;
20387 +   int value;
20388 +   int zeroes = 0;
20389 +
20390 +   value = INTVAL(op);
20391 +   for ( i = 0 ; i < 32; i++ ){
20392 +     if ( !(value & ( 1 << i )) ){
20393 +        zeroes++;
20394 +      }
20395 +   }
20396 +
20397 +   return ( zeroes == 1 );
20398 +  })
20399 +
20400 +
20401 +;; Immediate all the low 16-bits cleared
20402 +(define_predicate "avr32_hi16_immediate_operand"
20403 +  (match_code "const_int")
20404 +  {
20405 +   /* If the low 16-bits are zero then this
20406 +      is a hi16 immediate. */
20407 +   return ((INTVAL(op) & 0xffff) == 0);
20408 +   }
20409 +)
20410 +
20411 +;; True if this is a register or immediate operand
20412 +(define_predicate "register_immediate_operand"
20413 +  (ior (match_operand 0 "register_operand")
20414 +       (match_operand 0 "immediate_operand")))
20415 +
20416 +;; True if this is a register or const_int operand
20417 +(define_predicate "register_const_int_operand"
20418 +  (ior (match_operand 0 "register_operand")
20419 +       (and (match_operand 0 "const_int_operand")
20420 +            (match_operand 0 "immediate_operand"))))
20421 +
20422 +;; True if this is a register or const_double operand
20423 +(define_predicate "register_const_double_operand"
20424 +  (ior (match_operand 0 "register_operand")
20425 +       (match_operand 0 "const_double_operand")))
20426 +
20427 +;; True if this is an operand containing a label_ref.
20428 +(define_predicate "avr32_label_ref_operand"
20429 +  (and (match_code "mem")
20430 +       (match_test "avr32_find_symbol(op)
20431 +                    && (GET_CODE(avr32_find_symbol(op)) == LABEL_REF)")))
20432 +
20433 +;; True if this is a valid symbol pointing to the constant pool.
20434 +(define_predicate "avr32_const_pool_operand"
20435 +  (and (match_code "symbol_ref")
20436 +       (match_test "CONSTANT_POOL_ADDRESS_P(op)"))
20437 +  {
20438 +        return (flag_pic ? (!(symbol_mentioned_p (get_pool_constant (op))
20439 +                        || label_mentioned_p (get_pool_constant (op)))
20440 +                       || avr32_got_mentioned_p(get_pool_constant (op)))
20441 +                    : true);
20442 +  }
20443 +)
20444 +
20445 +;; True if this is a memory reference to the constant or mini pool.
20446 +(define_predicate "avr32_const_pool_ref_operand"
20447 +  (ior (match_operand 0 "avr32_label_ref_operand")
20448 +       (and (match_code "mem")
20449 +            (match_test "avr32_const_pool_operand(XEXP(op,0), GET_MODE(XEXP(op,0)))"))))
20450 +
20451 +
20452 +;; Legal source operand for movti insns
20453 +(define_predicate "avr32_movti_src_operand"
20454 +  (ior (match_operand 0 "avr32_const_pool_ref_operand")
20455 +       (ior (ior (match_operand 0 "register_immediate_operand")
20456 +                 (match_operand 0 "avr32_indirect_register_operand"))
20457 +            (match_operand 0 "post_inc_memory_operand"))))
20458 +  
20459 +;; Legal destination operand for movti insns
20460 +(define_predicate "avr32_movti_dst_operand"
20461 +  (ior (ior (match_operand 0 "register_operand")
20462 +            (match_operand 0 "avr32_indirect_register_operand"))
20463 +       (match_operand 0 "pre_dec_memory_operand")))
20464 +
20465 +
20466 +;; True if this is a k12 offseted memory operand.
20467 +(define_predicate "avr32_k12_memory_operand"
20468 +  (and (match_code "mem")
20469 +       (ior (match_test "REG_P(XEXP(op, 0))")
20470 +            (match_test "GET_CODE(XEXP(op, 0)) == PLUS
20471 +                         && REG_P(XEXP(XEXP(op, 0), 0))
20472 +                         && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)
20473 +                         && (CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)),
20474 +                                'K', (mode == SImode) ? \"Ks14\" : ((mode == HImode) ? \"Ks13\" : \"Ks12\")))"))))
20475 +
20476 +;; True if this is a memory operand with an immediate displacement.
20477 +(define_predicate "avr32_imm_disp_memory_operand"
20478 +  (and (match_code "mem")
20479 +       (match_test "GET_CODE(XEXP(op, 0)) == PLUS
20480 +                    && REG_P(XEXP(XEXP(op, 0), 0))
20481 +                    && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)")))
20482 +
20483 +;; True if this is a bswap operand.
20484 +(define_predicate "avr32_bswap_operand"
20485 +  (ior (match_operand 0 "avr32_k12_memory_operand")
20486 +       (match_operand 0 "register_operand")))
20487 +
20488 +;; True if this is a valid coprocessor insn memory operand.
20489 +(define_predicate "avr32_cop_memory_operand"
20490 +  (and (match_operand 0 "memory_operand")
20491 +       (not (match_test "GET_CODE(XEXP(op, 0)) == PLUS
20492 +                         && REG_P(XEXP(XEXP(op, 0), 0))
20493 +                         && (GET_CODE(XEXP(XEXP(op, 0), 1)) == CONST_INT)
20494 +                         && !(CONST_OK_FOR_CONSTRAINT_P(INTVAL(XEXP(XEXP(op, 0), 0)), 'K', \"Ku10\"))"))))
20495 +
20496 +;; True if this is a valid source/destination operand.
20497 +;; for moving values to/from a coprocessor
20498 +(define_predicate "avr32_cop_move_operand"
20499 +  (ior (match_operand 0 "register_operand")
20500 +       (match_operand 0 "avr32_cop_memory_operand")))
20501 +
20502 +
20503 +;; True if this is a valid extract byte offset for use in
20504 +;; load extracted index insns.
20505 +(define_predicate "avr32_extract_shift_operand"
20506 +  (and (match_operand 0 "const_int_operand")
20507 +       (match_test "(INTVAL(op) == 0) || (INTVAL(op) == 8)
20508 +                    || (INTVAL(op) == 16) || (INTVAL(op) == 24)")))
20509 +
20510 +;; True if this is a valid avr32 symbol operand.
20511 +(define_predicate "avr32_symbol_operand"
20512 +   (and (match_code "label_ref, symbol_ref, const")
20513 +        (match_test "avr32_find_symbol(op)")))
20514 +
20515 +;; True if this is a valid operand for the lda.w and call pseudo insns.
20516 +(define_predicate "avr32_address_operand"
20517 +   (and (and (match_code "label_ref, symbol_ref")
20518 +             (match_test "avr32_find_symbol(op)"))
20519 +       (ior (match_test "TARGET_HAS_ASM_ADDR_PSEUDOS")
20520 +            (match_test "flag_pic")) ))
20521 +
20522 +;; An immediate k16 address operand
20523 +(define_predicate "avr32_ks16_address_operand"
20524 +  (and (match_operand 0 "address_operand")
20525 +       (ior (match_test "REG_P(op)")
20526 +            (match_test "GET_CODE(op) == PLUS
20527 +                         && ((GET_CODE(XEXP(op,0)) == CONST_INT)
20528 +                             || (GET_CODE(XEXP(op,1)) == CONST_INT))")) ))
20529 +
20530 +;; An offset k16 memory operand
20531 +(define_predicate "avr32_ks16_memory_operand"
20532 +  (and (match_code "mem")
20533 +       (match_test "avr32_ks16_address_operand (XEXP (op, 0), GET_MODE (XEXP (op, 0)))")))
20534 +
20535 +;; An immediate k11 address operand
20536 +(define_predicate "avr32_ks11_address_operand"
20537 +  (and (match_operand 0 "address_operand")
20538 +       (ior (match_test "REG_P(op)")
20539 +            (match_test "GET_CODE(op) == PLUS
20540 +                         && (((GET_CODE(XEXP(op,0)) == CONST_INT)
20541 +                              && avr32_const_ok_for_constraint_p(INTVAL(XEXP(op,0)), 'K', \"Ks11\"))
20542 +                             || ((GET_CODE(XEXP(op,1)) == CONST_INT)
20543 +                                 && avr32_const_ok_for_constraint_p(INTVAL(XEXP(op,1)), 'K', \"Ks11\")))")) ))
20544 +
20545 +;; True if this is a avr32 call operand
20546 +(define_predicate "avr32_call_operand"
20547 +  (ior (ior (match_operand 0 "register_operand")
20548 +            (ior (match_operand 0 "avr32_const_pool_ref_operand")
20549 +                 (match_operand 0 "avr32_address_operand")))
20550 +       (match_test "SYMBOL_REF_RCALL_FUNCTION_P(op)")))
20551 +
20552 +;; Return true for operators performing ALU operations
20553 +
20554 +(define_predicate "alu_operator"
20555 +  (match_code "ior, xor, and, plus, minus, ashift, lshiftrt, ashiftrt"))
20556 +
20557 +(define_predicate "avr32_add_shift_immediate_operand"
20558 +  (and (match_operand 0 "immediate_operand")
20559 +       (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ku02\")")))
20560 +
20561 +(define_predicate "avr32_cond_register_immediate_operand"
20562 +  (ior (match_operand 0 "register_operand")
20563 +       (and (match_operand 0 "immediate_operand")
20564 +            (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")"))))
20565 +
20566 +(define_predicate "avr32_cond_immediate_operand"
20567 +  (and (match_operand 0 "immediate_operand")
20568 +       (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'I', \"Is08\")")))
20569 +
20570 +
20571 +(define_predicate "avr32_cond_move_operand"
20572 +  (ior (ior (match_operand 0 "register_operand")
20573 +            (and (match_operand 0 "immediate_operand")
20574 +                 (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks08\")")))
20575 +       (and (match_test "TARGET_V2_INSNS")
20576 +            (match_operand 0 "memory_operand"))))
20577 +
20578 +(define_predicate "avr32_mov_immediate_operand"
20579 +  (and (match_operand 0 "immediate_operand")
20580 +       (match_test "avr32_const_ok_for_move(INTVAL(op))")))
20581 +
20582 +
20583 +(define_predicate "avr32_rmw_address_operand"
20584 +  (ior (and (match_code "symbol_ref") 
20585 +            (match_test "({rtx symbol = avr32_find_symbol(op); \
20586 +                               symbol && (GET_CODE (symbol) == SYMBOL_REF) && SYMBOL_REF_RMW_ADDR(symbol);})"))
20587 +       (and (match_operand 0 "immediate_operand")
20588 +            (match_test "CONST_OK_FOR_CONSTRAINT_P(INTVAL(op), 'K', \"Ks17\")")))
20589 +  {
20590 +     return TARGET_RMW && !flag_pic;
20591 +  }
20592 +)
20593
20594 +(define_predicate "avr32_rmw_memory_operand"
20595 +  (and (match_code "mem") 
20596 +       (match_test "!volatile_refs_p(op) && (GET_MODE(op) == SImode) && 
20597 +                    avr32_rmw_address_operand(XEXP(op, 0), GET_MODE(XEXP(op, 0)))")))
20598 +
20599 +(define_predicate "avr32_rmw_memory_or_register_operand"
20600 +  (ior (match_operand 0 "avr32_rmw_memory_operand")
20601 +       (match_operand 0 "register_operand")))
20602 +
20603 +(define_predicate "avr32_non_rmw_memory_operand"
20604 +  (and (not (match_operand 0 "avr32_rmw_memory_operand"))
20605 +       (match_operand 0 "memory_operand")))
20606 +
20607 +(define_predicate "avr32_non_rmw_general_operand"
20608 +  (and (not (match_operand 0 "avr32_rmw_memory_operand"))
20609 +       (match_operand 0 "general_operand")))
20610 +
20611 +(define_predicate "avr32_non_rmw_nonimmediate_operand"
20612 +  (and (not (match_operand 0 "avr32_rmw_memory_operand"))
20613 +       (match_operand 0 "nonimmediate_operand")))
20614 +
20615 +;; Return true if the operand is the 1.0f constant.
20616 +
20617 +(define_predicate "const_1f_operand"
20618 +  (match_code "const_int,const_double")
20619 +{
20620 +  return (op == CONST1_RTX (SFmode));
20621 +})
20622 --- /dev/null
20623 +++ b/gcc/config/avr32/simd.md
20624 @@ -0,0 +1,145 @@
20625 +;;   AVR32 machine description file for SIMD instructions.
20626 +;;   Copyright 2003-2006 Atmel Corporation.
20627 +;;
20628 +;;   Written by Ronny Pedersen, Atmel Norway, <rpedersen@atmel.com>
20629 +;;
20630 +;;   This file is part of GCC.
20631 +;;
20632 +;;   This program is free software; you can redistribute it and/or modify
20633 +;;   it under the terms of the GNU General Public License as published by
20634 +;;   the Free Software Foundation; either version 2 of the License, or
20635 +;;   (at your option) any later version.
20636 +;;
20637 +;;   This program is distributed in the hope that it will be useful,
20638 +;;   but WITHOUT ANY WARRANTY; without even the implied warranty of
20639 +;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20640 +;;   GNU General Public License for more details.
20641 +;;
20642 +;;   You should have received a copy of the GNU General Public License
20643 +;;   along with this program; if not, write to the Free Software
20644 +;;   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20645 +
20646 +;; -*- Mode: Scheme -*-
20647 +
20648 +
20649 +;; Vector modes
20650 +(define_mode_iterator VECM [V2HI V4QI])
20651 +(define_mode_attr  size [(V2HI "h") (V4QI "b")])
20652 +
20653 +(define_insn "add<mode>3"
20654 +  [(set (match_operand:VECM 0 "register_operand" "=r")
20655 +       (plus:VECM (match_operand:VECM 1 "register_operand" "r")
20656 +                   (match_operand:VECM 2 "register_operand" "r")))]
20657 +  "TARGET_SIMD"
20658 +  "padd.<size>\t%0, %1, %2"
20659 +  [(set_attr "length" "4")
20660 +   (set_attr "type" "alu")])
20661 +
20662 +
20663 +(define_insn "sub<mode>3"
20664 +  [(set (match_operand:VECM 0 "register_operand" "=r")
20665 +       (minus:VECM (match_operand:VECM 1 "register_operand" "r")
20666 +                    (match_operand:VECM 2 "register_operand" "r")))]
20667 +  "TARGET_SIMD"
20668 +  "psub.<size>\t%0, %1, %2"
20669 +  [(set_attr "length" "4")
20670 +   (set_attr "type" "alu")])
20671 +
20672 +
20673 +(define_insn "abs<mode>2"
20674 +  [(set (match_operand:VECM 0 "register_operand" "=r")
20675 +       (abs:VECM (match_operand:VECM 1 "register_operand" "r")))]
20676 +  "TARGET_SIMD"
20677 +  "pabs.s<size>\t%0, %1"
20678 +  [(set_attr "length" "4")
20679 +   (set_attr "type" "alu")])
20680 +
20681 +(define_insn "ashl<mode>3"
20682 +  [(set (match_operand:VECM 0 "register_operand"           "=r")
20683 +       (ashift:VECM (match_operand:VECM 1 "register_operand" "r")
20684 +                     (match_operand:SI 2 "immediate_operand" "Ku04")))]
20685 +  "TARGET_SIMD"
20686 +  "plsl.<size>\t%0, %1, %2"
20687 +  [(set_attr "length" "4")
20688 +   (set_attr "type" "alu")])
20689 +
20690 +(define_insn "ashr<mode>3"
20691 +  [(set (match_operand:VECM 0 "register_operand"           "=r")
20692 +       (ashiftrt:VECM (match_operand:VECM 1 "register_operand" "r")
20693 +                       (match_operand:SI 2 "immediate_operand" "Ku04")))]
20694 +  "TARGET_SIMD"
20695 +  "pasr.<size>\t%0, %1, %2"
20696 +  [(set_attr "length" "4")
20697 +   (set_attr "type" "alu")])
20698 +
20699 +(define_insn "lshr<mode>3"
20700 +  [(set (match_operand:VECM 0 "register_operand"           "=r")
20701 +       (lshiftrt:VECM (match_operand:VECM 1 "register_operand" "r")
20702 +                       (match_operand:SI 2 "immediate_operand" "Ku04")))]
20703 +  "TARGET_SIMD"
20704 +  "plsr.<size>\t%0, %1, %2"
20705 +  [(set_attr "length" "4")
20706 +   (set_attr "type" "alu")])
20707 +
20708 +(define_insn "smaxv2hi3"
20709 +  [(set (match_operand:V2HI 0 "register_operand" "=r")
20710 +       (smax:V2HI (match_operand:V2HI 1 "register_operand" "r")
20711 +                        (match_operand:V2HI 2 "register_operand" "r")))]
20712 +
20713 +  "TARGET_SIMD"
20714 +  "pmax.sh\t%0, %1, %2"
20715 +  [(set_attr "length" "4")
20716 +   (set_attr "type" "alu")])
20717 +
20718 +(define_insn "sminv2hi3"
20719 +  [(set (match_operand:V2HI 0 "register_operand" "=r")
20720 +       (smin:V2HI (match_operand:V2HI 1 "register_operand" "r")
20721 +                        (match_operand:V2HI 2 "register_operand" "r")))]
20722 +
20723 +  "TARGET_SIMD"
20724 +  "pmin.sh\t%0, %1, %2"
20725 +  [(set_attr "length" "4")
20726 +   (set_attr "type" "alu")])
20727 +
20728 +(define_insn "umaxv4qi3"
20729 +  [(set (match_operand:V4QI 0 "register_operand" "=r")
20730 +       (umax:V4QI (match_operand:V4QI 1 "register_operand" "r")
20731 +                   (match_operand:V4QI 2 "register_operand" "r")))]
20732 +
20733 +  "TARGET_SIMD"
20734 +  "pmax.ub\t%0, %1, %2"
20735 +  [(set_attr "length" "4")
20736 +   (set_attr "type" "alu")])
20737 +
20738 +(define_insn "uminv4qi3"
20739 +  [(set (match_operand:V4QI 0 "register_operand" "=r")
20740 +       (umin:V4QI (match_operand:V4QI 1 "register_operand" "r")
20741 +                   (match_operand:V4QI 2 "register_operand" "r")))]
20742 +
20743 +  "TARGET_SIMD"
20744 +  "pmin.ub\t%0, %1, %2"
20745 +  [(set_attr "length" "4")
20746 +   (set_attr "type" "alu")])
20747 +
20748 +
20749 +(define_insn "addsubv2hi"
20750 +  [(set (match_operand:V2HI 0 "register_operand" "=r")
20751 +        (vec_concat:V2HI
20752 +         (plus:HI (match_operand:HI 1 "register_operand" "r")
20753 +                  (match_operand:HI 2 "register_operand" "r"))
20754 +         (minus:HI (match_dup 1) (match_dup 2))))]
20755 +  "TARGET_SIMD"
20756 +  "paddsub.h\t%0, %1:b, %2:b"
20757 +  [(set_attr "length" "4")
20758 +   (set_attr "type" "alu")])
20759 +
20760 +(define_insn "subaddv2hi"
20761 +  [(set (match_operand:V2HI 0 "register_operand" "=r")
20762 +        (vec_concat:V2HI
20763 +         (minus:HI (match_operand:HI 1 "register_operand" "r")
20764 +                  (match_operand:HI 2 "register_operand" "r"))
20765 +         (plus:HI (match_dup 1) (match_dup 2))))]
20766 +  "TARGET_SIMD"
20767 +  "psubadd.h\t%0, %1:b, %2:b"
20768 +  [(set_attr "length" "4")
20769 +   (set_attr "type" "alu")])
20770 --- /dev/null
20771 +++ b/gcc/config/avr32/sync.md
20772 @@ -0,0 +1,244 @@
20773 +;;=================================================================
20774 +;; Atomic operations
20775 +;;=================================================================
20776 +
20777 +
20778 +(define_insn "sync_compare_and_swapsi"
20779 +  [(set (match_operand:SI 0 "register_operand" "=&r,&r")
20780 +       (match_operand:SI 1 "memory_operand" "+RKs16,+RKs16"))
20781 +   (set (match_dup 1)
20782 +       (unspec_volatile:SI
20783 +         [(match_dup 1)
20784 +          (match_operand:SI 2 "register_immediate_operand" "r,Ks21")
20785 +          (match_operand:SI 3 "register_operand" "r,r")]
20786 +         VUNSPEC_SYNC_CMPXCHG))   ]
20787 +  ""
20788 +  "0:
20789 +   ssrf\t5
20790 +   ld.w\t%0,%1
20791 +   cp.w\t%0,%2
20792 +   brne\t0f
20793 +   stcond\t%1, %3
20794 +   brne\t0b
20795 +   0:
20796 +  "
20797 +  [(set_attr "length" "16,18")
20798 +   (set_attr "cc" "clobber")]
20799 +  )
20800
20801 +
20802 +(define_code_iterator atomic_op [plus minus and ior xor])
20803 +(define_code_attr  atomic_asm_insn [(plus "add") (minus "sub") (and "and") (ior "or") (xor "eor")])
20804 +(define_code_attr  atomic_insn [(plus "add") (minus "sub") (and "and") (ior "ior") (xor "xor")])
20805 +
20806 +(define_insn "sync_loadsi"
20807 +  ; NB! Put an early clobber on the destination operand to 
20808 +  ; avoid gcc using the same register in the source and 
20809 +  ; destination. This is done in order to avoid gcc to 
20810 +  ; clobber the source operand since these instructions
20811 +  ; are actually inside a "loop".
20812 +  [(set (match_operand:SI 0 "register_operand" "=&r")
20813 +       (unspec_volatile:SI
20814 +         [(match_operand:SI 1 "avr32_ks16_memory_operand" "RKs16")
20815 +          (label_ref (match_operand 2 "" ""))]
20816 +         VUNSPEC_SYNC_SET_LOCK_AND_LOAD) )]
20817 +  ""
20818 +  "%2:
20819 +   ssrf\t5
20820 +   ld.w\t%0,%1"
20821 +  [(set_attr "length" "6")
20822 +   (set_attr "cc" "clobber")]
20823 +  )
20824 +  
20825 +(define_insn "sync_store_if_lock"
20826 +  [(set (match_operand:SI 0 "avr32_ks16_memory_operand" "=RKs16")
20827 +        (unspec_volatile:SI
20828 +         [(match_operand:SI 1 "register_operand" "r")
20829 +          (label_ref (match_operand 2 "" ""))]
20830 +         VUNSPEC_SYNC_STORE_IF_LOCK) )]
20831 +  ""
20832 +  "stcond\t%0, %1
20833 +   brne\t%2"
20834 +  [(set_attr "length" "6")
20835 +   (set_attr "cc" "clobber")]
20836 +  )
20837 +
20838 +
20839 +(define_expand "sync_<atomic_insn>si"
20840 +  [(set (match_dup 2)
20841 +       (unspec_volatile:SI
20842 +         [(match_operand:SI 0 "avr32_ks16_memory_operand" "")
20843 +          (match_dup 3)]
20844 +         VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
20845 +   (set (match_dup 2) 
20846 +        (atomic_op:SI (match_dup 2)
20847 +                      (match_operand:SI 1 "register_immediate_operand" "")))
20848 +   (set (match_dup 0)
20849 +        (unspec_volatile:SI
20850 +         [(match_dup 2)
20851 +          (match_dup 3)]
20852 +         VUNSPEC_SYNC_STORE_IF_LOCK) )
20853 +   (use (match_dup 1))
20854 +   (use (match_dup 4))]
20855 +  ""
20856 +  {
20857 +   rtx *mem_expr = &operands[0];
20858 +   rtx ptr_reg;
20859 +   if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) )
20860 +    {
20861 +      ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0));
20862 +      XEXP (*mem_expr, 0) = ptr_reg;
20863 +    } 
20864 +   else 
20865 +    {
20866 +      rtx address = XEXP (*mem_expr, 0);
20867 +      if ( REG_P (address) )
20868 +         ptr_reg = address;
20869 +      else if ( REG_P (XEXP (address, 0)) ) 
20870 +         ptr_reg = XEXP (address, 0);
20871 +      else 
20872 +         ptr_reg = XEXP (address, 1);
20873 +    }
20874 +
20875 +   operands[2] = gen_reg_rtx (SImode);
20876 +   operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
20877 +   operands[4] = ptr_reg;   
20878 +
20879 +  }
20880 +  )
20881 +
20882 +
20883 +
20884 +(define_expand "sync_old_<atomic_insn>si"
20885 +  [(set (match_operand:SI 0 "register_operand" "")
20886 +       (unspec_volatile:SI
20887 +         [(match_operand:SI 1 "avr32_ks16_memory_operand" "")
20888 +          (match_dup 4)]
20889 +         VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
20890 +   (set (match_dup 3) 
20891 +        (atomic_op:SI (match_dup 0)
20892 +                      (match_operand:SI 2 "register_immediate_operand" "")))
20893 +   (set (match_dup 1)
20894 +        (unspec_volatile:SI
20895 +         [(match_dup 3)
20896 +          (match_dup 4)]
20897 +         VUNSPEC_SYNC_STORE_IF_LOCK) )
20898 +   (use (match_dup 2))
20899 +   (use (match_dup 5))]
20900 +  ""
20901 +  {
20902 +   rtx *mem_expr = &operands[1];
20903 +   rtx ptr_reg;
20904 +   if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) )
20905 +    {
20906 +      ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0));
20907 +      XEXP (*mem_expr, 0) = ptr_reg;
20908 +    } 
20909 +   else 
20910 +    {
20911 +      rtx address = XEXP (*mem_expr, 0);
20912 +      if ( REG_P (address) )
20913 +         ptr_reg = address;
20914 +      else if ( REG_P (XEXP (address, 0)) ) 
20915 +         ptr_reg = XEXP (address, 0);
20916 +      else 
20917 +         ptr_reg = XEXP (address, 1);
20918 +    }
20919 +
20920 +   operands[3] = gen_reg_rtx (SImode);
20921 +   operands[4] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
20922 +   operands[5] = ptr_reg;
20923 +  }
20924 +  )
20925 +
20926 +(define_expand "sync_new_<atomic_insn>si"
20927 +  [(set (match_operand:SI 0 "register_operand" "")
20928 +       (unspec_volatile:SI
20929 +         [(match_operand:SI 1 "avr32_ks16_memory_operand" "")
20930 +          (match_dup 3)]
20931 +         VUNSPEC_SYNC_SET_LOCK_AND_LOAD))
20932 +   (set (match_dup 0) 
20933 +        (atomic_op:SI (match_dup 0)
20934 +                      (match_operand:SI 2 "register_immediate_operand" "")))
20935 +   (set (match_dup 1)
20936 +        (unspec_volatile:SI
20937 +         [(match_dup 0)
20938 +          (match_dup 3)]
20939 +         VUNSPEC_SYNC_STORE_IF_LOCK) )
20940 +   (use (match_dup 2))
20941 +   (use (match_dup 4))]
20942 +  ""
20943 +  {
20944 +   rtx *mem_expr = &operands[1];
20945 +   rtx ptr_reg;
20946 +   if ( !avr32_ks16_memory_operand (*mem_expr, GET_MODE (*mem_expr)) )
20947 +    {
20948 +      ptr_reg = force_reg (Pmode, XEXP (*mem_expr, 0));
20949 +      XEXP (*mem_expr, 0) = ptr_reg;
20950 +    } 
20951 +   else 
20952 +    {
20953 +      rtx address = XEXP (*mem_expr, 0);
20954 +      if ( REG_P (address) )
20955 +         ptr_reg = address;
20956 +      else if ( REG_P (XEXP (address, 0)) ) 
20957 +         ptr_reg = XEXP (address, 0);
20958 +      else 
20959 +         ptr_reg = XEXP (address, 1);
20960 +    }
20961 +
20962 +   operands[3] = gen_rtx_LABEL_REF(Pmode, gen_label_rtx ());
20963 +   operands[4] = ptr_reg;
20964 +  }
20965 +  )
20966 +
20967 +
20968 +;(define_insn "sync_<atomic_insn>si"
20969 +;  [(set (match_operand:SI 0 "memory_operand" "+RKs16")
20970 +;      (unspec_volatile:SI
20971 +;         [(atomic_op:SI (match_dup 0)
20972 +;                        (match_operand:SI 1 "register_operand" "r"))]
20973 +;         VUNSPEC_SYNC_CMPXCHG))
20974 +;   (clobber (match_scratch:SI 2 "=&r"))]
20975 +;  ""
20976 +;  "0:
20977 +;   ssrf\t5
20978 +;   ld.w\t%2,%0
20979 +;   <atomic_asm_insn>\t%2,%1
20980 +;   stcond\t%0, %2
20981 +;   brne\t0b
20982 +;  "
20983 +;  [(set_attr "length" "14")
20984 +;   (set_attr "cc" "clobber")]
20985 +;  )
20986 +;
20987 +;(define_insn "sync_new_<atomic_insn>si"
20988 +;  [(set (match_operand:SI 1 "memory_operand" "+RKs16")
20989 +;      (unspec_volatile:SI
20990 +;         [(atomic_op:SI (match_dup 1)
20991 +;                        (match_operand:SI 2 "register_operand" "r"))]
20992 +;         VUNSPEC_SYNC_CMPXCHG))
20993 +;   (set (match_operand:SI 0 "register_operand" "=&r")
20994 +;      (atomic_op:SI (match_dup 1)
20995 +;                      (match_dup 2)))]
20996 +;  ""
20997 +;  "0:
20998 +;   ssrf\t5
20999 +;   ld.w\t%0,%1
21000 +;   <atomic_asm_insn>\t%0,%2
21001 +;   stcond\t%1, %0
21002 +;   brne\t0b
21003 +;  "
21004 +;  [(set_attr "length" "14")
21005 +;   (set_attr "cc" "clobber")]
21006 +;  )
21007 +
21008 +(define_insn "sync_lock_test_and_setsi"
21009 +  [ (set (match_operand:SI 0 "register_operand" "=&r")
21010 +         (match_operand:SI 1 "memory_operand" "+RKu00"))
21011 +    (set (match_dup 1)
21012 +         (match_operand:SI 2 "register_operand" "r")) ]
21013 +  ""
21014 +  "xchg\t%0, %p1, %2"
21015 +  [(set_attr "length" "4")]
21016 +  )
21017 --- /dev/null
21018 +++ b/gcc/config/avr32/t-avr32
21019 @@ -0,0 +1,118 @@
21020 +
21021 +MD_INCLUDES=   $(srcdir)/config/avr32/avr32.md \
21022 +               $(srcdir)/config/avr32/sync.md \
21023 +               $(srcdir)/config/avr32/simd.md \
21024 +        $(srcdir)/config/avr32/predicates.md
21025 +
21026 +s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
21027 +       s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
21028 +
21029 +# We want fine grained libraries, so use the new code
21030 +# to build the floating point emulation libraries.
21031 +FPBIT = fp-bit.c
21032 +DPBIT = dp-bit.c
21033 +
21034 +LIB1ASMSRC = avr32/lib1funcs.S
21035 +LIB1ASMFUNCS =  _avr32_f64_mul _avr32_f64_mul_fast _avr32_f64_addsub _avr32_f64_addsub_fast  _avr32_f64_to_u32 \
21036 +                _avr32_f64_to_s32 _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 \
21037 +                _avr32_s32_to_f64 _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \
21038 +                _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt _avr32_f64_div _avr32_f64_div_fast \
21039 +                _avr32_f32_div _avr32_f32_div_fast _avr32_f32_addsub _avr32_f32_addsub_fast \
21040 +                _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \
21041 +                _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32 _mulsi3
21042 +
21043 +#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S
21044 +
21045 +MULTILIB_OPTIONS     = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp
21046 +MULTILIB_DIRNAMES    = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp
21047 +MULTILIB_EXCEPTIONS  =
21048 +MULTILIB_MATCHES     += march?ap=mpart?ap7000
21049 +MULTILIB_MATCHES     += march?ap=mpart?ap7001
21050 +MULTILIB_MATCHES     += march?ap=mpart?ap7002
21051 +MULTILIB_MATCHES     += march?ap=mpart?ap7200
21052 +MULTILIB_MATCHES     += march?ucr1=march?uc
21053 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3a0512es
21054 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0128
21055 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0256
21056 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0512
21057 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1128
21058 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1256
21059 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3a1512es
21060 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1512
21061 +MULTILIB_MATCHES     += march?ucr2nomul=mpart?uc3a3revd
21062 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a364
21063 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a364s
21064 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3128
21065 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3128s
21066 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3256
21067 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3256s
21068 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a464
21069 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a464s
21070 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4128
21071 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4128s
21072 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4256
21073 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4256s
21074 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b064
21075 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0128
21076 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0256es
21077 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0256
21078 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b0512
21079 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b0512revc
21080 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b164
21081 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1128
21082 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1256es
21083 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1256
21084 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b1512
21085 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b1512revc
21086 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64d3
21087 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128d3
21088 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64d4
21089 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128d4
21090 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c0512crevc
21091 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c1512crevc
21092 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c2512crevc
21093 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l0256
21094 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l0128
21095 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l064
21096 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l032
21097 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l016
21098 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l064revb
21099 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64l3u
21100 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128l3u
21101 +MULTILIB_MATCHES     += march?ucr3=mpart?uc256l3u
21102 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64l4u
21103 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128l4u
21104 +MULTILIB_MATCHES     += march?ucr3=mpart?uc256l4u
21105 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c064c
21106 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0128c
21107 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0256c
21108 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0512c
21109 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c164c
21110 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1128c
21111 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1256c
21112 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1512c
21113 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c264c
21114 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2128c
21115 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2256c
21116 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2512c
21117 +MULTILIB_MATCHES     += march?ucr3=mpart?mxt768e
21118 +
21119 +
21120 +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o
21121 +
21122 +CRTSTUFF_T_CFLAGS = -mrelax
21123 +CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC
21124 +TARGET_LIBGCC2_CFLAGS += -mrelax
21125 +
21126 +LIBGCC = stmp-multilib
21127 +INSTALL_LIBGCC = install-multilib
21128 +
21129 +fp-bit.c: $(srcdir)/config/fp-bit.c
21130 +       echo '#define FLOAT' > fp-bit.c
21131 +       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
21132 +
21133 +dp-bit.c: $(srcdir)/config/fp-bit.c
21134 +       cat $(srcdir)/config/fp-bit.c > dp-bit.c
21135 +
21136 +
21137 +
21138 --- /dev/null
21139 +++ b/gcc/config/avr32/t-avr32-linux
21140 @@ -0,0 +1,118 @@
21141 +
21142 +MD_INCLUDES=   $(srcdir)/config/avr32/avr32.md \
21143 +               $(srcdir)/config/avr32/sync.md \
21144 +               $(srcdir)/config/avr32/simd.md \
21145 +               $(srcdir)/config/avr32/predicates.md
21146 +
21147 +s-config s-conditions s-flags s-codes s-constants s-emit s-recog s-preds \
21148 +       s-opinit s-extract s-peep s-attr s-attrtab s-output: $(MD_INCLUDES)
21149 +
21150 +# We want fine grained libraries, so use the new code
21151 +# to build the floating point emulation libraries.
21152 +FPBIT = fp-bit.c
21153 +DPBIT = dp-bit.c
21154 +
21155 +LIB1ASMSRC = avr32/lib1funcs.S
21156 +LIB1ASMFUNCS =  _avr32_f64_mul _avr32_f64_mul_fast _avr32_f64_addsub _avr32_f64_addsub_fast  _avr32_f64_to_u32 \
21157 +                _avr32_f64_to_s32 _avr32_f64_to_u64 _avr32_f64_to_s64 _avr32_u32_to_f64 \
21158 +                _avr32_s32_to_f64 _avr32_f64_cmp_eq _avr32_f64_cmp_ge _avr32_f64_cmp_lt \
21159 +                _avr32_f32_cmp_eq _avr32_f32_cmp_ge _avr32_f32_cmp_lt _avr32_f64_div _avr32_f64_div_fast \
21160 +                _avr32_f32_div _avr32_f32_div_fast _avr32_f32_addsub _avr32_f32_addsub_fast \
21161 +                _avr32_f32_mul _avr32_s32_to_f32 _avr32_u32_to_f32 _avr32_f32_to_s32 \
21162 +                _avr32_f32_to_u32 _avr32_f32_to_f64 _avr32_f64_to_f32 _mulsi3
21163 +
21164 +#LIB2FUNCS_EXTRA += $(srcdir)/config/avr32/lib2funcs.S
21165 +
21166 +MULTILIB_OPTIONS     = march=ap/march=ucr1/march=ucr2/march=ucr2nomul/march=ucr3/march=ucr3fp
21167 +MULTILIB_DIRNAMES    = ap ucr1 ucr2 ucr2nomul ucr3 ucr3fp
21168 +MULTILIB_EXCEPTIONS  =
21169 +MULTILIB_MATCHES     += march?ap=mpart?ap7000
21170 +MULTILIB_MATCHES     += march?ap=mpart?ap7001
21171 +MULTILIB_MATCHES     += march?ap=mpart?ap7002
21172 +MULTILIB_MATCHES     += march?ap=mpart?ap7200
21173 +MULTILIB_MATCHES     += march?ucr1=march?uc
21174 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3a0512es
21175 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0128
21176 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0256
21177 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a0512
21178 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1128
21179 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1256
21180 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3a1512es
21181 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a1512
21182 +MULTILIB_MATCHES     += march?ucr2nomul=mpart?uc3a3revd
21183 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a364
21184 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a364s
21185 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3128
21186 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3128s
21187 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3256
21188 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a3256s
21189 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a464
21190 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a464s
21191 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4128
21192 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4128s
21193 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4256
21194 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3a4256s
21195 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b064
21196 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0128
21197 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0256es
21198 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b0256
21199 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b0512
21200 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b0512revc
21201 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b164
21202 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1128
21203 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1256es
21204 +MULTILIB_MATCHES     += march?ucr1=mpart?uc3b1256
21205 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b1512
21206 +MULTILIB_MATCHES     += march?ucr2=mpart?uc3b1512revc
21207 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64d3
21208 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128d3
21209 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64d4
21210 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128d4
21211 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c0512crevc
21212 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c1512crevc
21213 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3c2512crevc
21214 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l0256
21215 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l0128
21216 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l064
21217 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l032
21218 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l016
21219 +MULTILIB_MATCHES     += march?ucr3=mpart?uc3l064revb
21220 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64l3u
21221 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128l3u
21222 +MULTILIB_MATCHES     += march?ucr3=mpart?uc256l3u
21223 +MULTILIB_MATCHES     += march?ucr3=mpart?uc64l4u
21224 +MULTILIB_MATCHES     += march?ucr3=mpart?uc128l4u
21225 +MULTILIB_MATCHES     += march?ucr3=mpart?uc256l4u
21226 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c064c
21227 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0128c
21228 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0256c
21229 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c0512c
21230 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c164c
21231 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1128c
21232 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1256c
21233 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c1512c
21234 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c264c
21235 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2128c
21236 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2256c
21237 +MULTILIB_MATCHES     += march?ucr3fp=mpart?uc3c2512c
21238 +MULTILIB_MATCHES     += march?ucr3=mpart?mxt768e
21239 +
21240 +
21241 +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o
21242 +
21243 +CRTSTUFF_T_CFLAGS = -mrelax
21244 +CRTSTUFF_T_CFLAGS_S = -mrelax -fPIC
21245 +TARGET_LIBGCC2_CFLAGS += -mrelax
21246 +
21247 +LIBGCC = stmp-multilib
21248 +INSTALL_LIBGCC = install-multilib
21249 +
21250 +fp-bit.c: $(srcdir)/config/fp-bit.c
21251 +       echo '#define FLOAT' > fp-bit.c
21252 +       cat $(srcdir)/config/fp-bit.c >> fp-bit.c
21253 +
21254 +dp-bit.c: $(srcdir)/config/fp-bit.c
21255 +       cat $(srcdir)/config/fp-bit.c > dp-bit.c
21256 +
21257 +
21258 +
21259 --- /dev/null
21260 +++ b/gcc/config/avr32/t-elf
21261 @@ -0,0 +1,16 @@
21262 +
21263 +# Assemble startup files.
21264 +$(T)crti.o: $(srcdir)/config/avr32/crti.asm $(GCC_PASSES)
21265 +       $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \
21266 +       -c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/avr32/crti.asm
21267 +
21268 +$(T)crtn.o: $(srcdir)/config/avr32/crtn.asm $(GCC_PASSES)
21269 +       $(GCC_FOR_TARGET) $(CRTSTUFF_CFLAGS) $(CRTSTUFF_T_CFLAGS) $(INCLUDES) \
21270 +       -c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/avr32/crtn.asm
21271 +
21272 +
21273 +# Build the libraries for both hard and soft floating point
21274 +EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o
21275 +
21276 +LIBGCC = stmp-multilib
21277 +INSTALL_LIBGCC = install-multilib
21278 --- /dev/null
21279 +++ b/gcc/config/avr32/uc3fpu.md
21280 @@ -0,0 +1,199 @@
21281 +;;   AVR32 machine description file for Floating-Point instructions.
21282 +;;   Copyright 2003-2006 Atmel Corporation.
21283 +;;
21284 +;;
21285 +;;   This file is part of GCC.
21286 +;;
21287 +;;   This program is free software; you can redistribute it and/or modify
21288 +;;   it under the terms of the GNU General Public License as published by
21289 +;;   the Free Software Foundation; either version 2 of the License, or
21290 +;;   (at your option) any later version.
21291 +;;
21292 +;;   This program is distributed in the hope that it will be useful,
21293 +;;   but WITHOUT ANY WARRANTY; without even the implied warranty of
21294 +;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21295 +;;   GNU General Public License for more details.
21296 +;;
21297 +;;   You should have received a copy of the GNU General Public License
21298 +;;   along with this program; if not, write to the Free Software
21299 +;;   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21300 +
21301 +(define_insn "*movsf_uc3fp"
21302 +  [(set (match_operand:SF 0 "nonimmediate_operand"     "=r,r,r,m")
21303 +       (match_operand:SF 1 "general_operand"          "r,G,m,r"))]
21304 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21305 +  "@
21306 +   mov\t%0, %1
21307 +   mov\t%0, %1
21308 +   ld.w\t%0, %1
21309 +   st.w\t%0, %1"
21310 +  [(set_attr "length" "2,4,4,4")
21311 +   (set_attr "type" "alu,alu,load,store")])
21312 +
21313 +(define_insn "mulsf3"
21314 +  [(set (match_operand:SF          0 "register_operand" "=r")
21315 +       (mult:SF (match_operand:SF 1 "register_operand" "r")
21316 +                (match_operand:SF 2 "register_operand" "r")))]
21317 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21318 +  "fmul.s\t%0, %1, %2"
21319 +  [(set_attr "length" "4")
21320 +   (set_attr "type" "fmul")])
21321 +
21322 +(define_insn "nmulsf3"
21323 +  [(set (match_operand:SF          0 "register_operand" "=r")
21324 +       (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "%r")
21325 +                         (match_operand:SF 2 "register_operand" "r"))))]
21326 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21327 +  "fnmul.s\t%0, %1, %2"
21328 +  [(set_attr "length" "4")
21329 +   (set_attr "type" "fmul")])
21330 +
21331 +(define_insn "macsf3"
21332 +  [(set (match_operand:SF          0 "register_operand" "=r")
21333 +       (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "r")
21334 +                          (match_operand:SF 2 "register_operand" "r"))
21335 +                 (match_operand:SF 3 "register_operand" "r")))]
21336 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21337 +  "fmac.s\t%0, %3, %1, %2"
21338 +  [(set_attr "length" "4")
21339 +   (set_attr "type" "fmul")])
21340 +
21341 +;(define_insn "nmacsf3"
21342 +;  [(set (match_operand:SF          0 "register_operand" "=r")
21343 +;      (plus:SF  (neg:SF (match_operand:SF 1 "register_operand" "r"))
21344 +;                            (mult:SF(match_operand:SF 2 "register_operand" "r")
21345 +;                                    (match_operand:SF 3 "register_operand" "r"))))]
21346 +;  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21347 +;  "fnmac.s\t%0, %1, %2, %3"
21348 +;  [(set_attr "length" "4")
21349 +;   (set_attr "type" "fmul")])
21350 +
21351 +(define_insn "nmacsf3"
21352 +  [(set (match_operand:SF          0 "register_operand" "=r")
21353 +       (minus:SF  (mult:SF (match_operand:SF 2 "register_operand" "r")
21354 +                        (match_operand:SF 3 "register_operand" "r"))
21355 +                           (match_operand:SF 1 "register_operand" "r")))]
21356 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21357 +  "fnmac.s\t%0, %1, %2, %3"
21358 +  [(set_attr "length" "4")
21359 +   (set_attr "type" "fmul")])
21360 +
21361 +(define_insn "msubacsf3"
21362 +  [(set (match_operand:SF          0 "register_operand" "=r")
21363 +       (minus:SF (match_operand:SF 3 "register_operand" "r")
21364 +                 (mult:SF (match_operand:SF 1 "register_operand" "r")
21365 +                       (match_operand:SF 2 "register_operand" "r"))))]
21366 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21367 +  "fmsc.s\t%0, %3, %1, %2"
21368 +  [(set_attr "length" "4")
21369 +   (set_attr "type" "fmul")])
21370 +
21371 +(define_insn "nmsubacsf3"
21372 +  [(set (match_operand:SF          0 "register_operand" "=r")
21373 +       (minus:SF  (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "r")
21374 +                                    (match_operand:SF 2 "register_operand" "r")))
21375 +                   (match_operand:SF 3 "register_operand" "r")))]
21376 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21377 +  "fnmsc.s\t%0, %3, %1, %2"
21378 +  [(set_attr "length" "4")
21379 +   (set_attr "type" "fmul")])
21380 +
21381 +(define_insn "addsf3"
21382 +  [(set (match_operand:SF 0 "register_operand" "=r")
21383 +       (plus:SF (match_operand:SF 1 "register_operand" "%r")
21384 +                   (match_operand:SF 2 "register_operand" "r")))]
21385 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21386 +  "fadd.s\t%0, %1, %2"
21387 +  [(set_attr "length" "4")
21388 +   (set_attr "type" "fmul")])
21389 +
21390 +(define_insn "subsf3"
21391 +  [(set (match_operand:SF          0 "register_operand" "=r")
21392 +       (minus:SF (match_operand:SF 1 "register_operand" "r")
21393 +                  (match_operand:SF 2 "register_operand" "r")))]
21394 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21395 +  "fsub.s\t%0, %1, %2"
21396 +  [(set_attr "length" "4")
21397 +   (set_attr "type" "fmul")])
21398 +
21399 +(define_insn "fixuns_truncsfsi2"
21400 +  [(set (match_operand:SI 0 "register_operand" "=r")
21401 +       (unsigned_fix:SI (match_operand:SF 1 "register_operand" "r")))]
21402 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21403 +  "fcastrs.uw\t%0, %1"
21404 +  [(set_attr "length" "4")])
21405 +
21406 +(define_insn "fix_truncsfsi2"
21407 +  [(set (match_operand:SI 0 "register_operand" "=r")
21408 +       (fix:SI (match_operand:SF 1 "register_operand" "r")))]
21409 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21410 +  "fcastrs.sw\t%0, %1"
21411 +  [(set_attr "length" "4")])
21412 +
21413 +(define_insn "floatunssisf2"
21414 +  [(set (match_operand:SF 0 "register_operand" "=r")
21415 +        (unsigned_float:SF (match_operand:SI 1 "register_operand" "r")))]
21416 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21417 +  "fcastuw.s\t%0, %1"
21418 +  [(set_attr "length" "4")])
21419 +
21420 +(define_insn "floatsisf2"
21421 +  [(set (match_operand:SF 0 "register_operand" "=r")
21422 +        (float:SF (match_operand:SI 1 "register_operand" "r")))]
21423 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21424 +  "fcastsw.s\t%0, %1"
21425 +  [(set_attr "length" "4")])
21426 +
21427 +(define_insn "cmpsf_internal_uc3fp"
21428 +  [(set (cc0)
21429 +        (compare:CC
21430 +         (match_operand:SF 0 "register_operand" "r")
21431 +         (match_operand:SF 1 "register_operand" "r")))]
21432 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21433 +  {
21434 +        avr32_branch_type = CMP_SF;
21435 +   if (!rtx_equal_p(cc_prev_status.mdep.value, SET_SRC(PATTERN (insn))) )
21436 +      return "fcmp.s\t%0, %1";
21437 +   return "";
21438 +  }
21439 +  [(set_attr "length" "4")
21440 +   (set_attr "cc" "compare")])
21441 +
21442 +(define_expand "divsf3"
21443 +  [(set (match_operand:SF 0 "register_operand" "=r")
21444 +       (div:SF (match_operand:SF 1 "register_operand" "r")
21445 +                (match_operand:SF 2 "register_operand" "r")))]
21446 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
21447 +  "{
21448 +    emit_insn(gen_frcpa_internal(operands[0],operands[2]));
21449 +    emit_insn(gen_mulsf3(operands[0],operands[0],operands[1]));
21450 +    DONE;
21451 +  }"  
21452 +)
21453 +
21454 +(define_insn "frcpa_internal"
21455 +  [(set (match_operand:SF 0 "register_operand" "=r")
21456 +       (unspec:SF [(match_operand:SF 1 "register_operand" "r")] UNSPEC_FRCPA))]
21457 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21458 +  "frcpa.s %0,%1"
21459 +  [(set_attr "length" "4")])
21460 +
21461 +(define_expand "sqrtsf2"
21462 +  [(set (match_operand:SF 0 "register_operand" "")
21463 +       (sqrt:SF (match_operand:SF 1 "register_operand" "")))]
21464 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT && flag_unsafe_math_optimizations"
21465 +  "
21466 +{
21467 +  rtx scratch = gen_reg_rtx (SFmode);
21468 +  emit_insn (gen_rsqrtsf2 (scratch, operands[1], CONST1_RTX (SFmode)));
21469 +  emit_insn (gen_divsf3(operands[0], force_reg (SFmode, CONST1_RTX (SFmode)),
21470 +                        scratch));
21471 +  DONE;
21472 +}")
21473 +
21474 +(define_insn "rsqrtsf2"
21475 +  [(set (match_operand:SF 0 "register_operand" "=r")
21476 +       (div:SF (match_operand:SF 2 "const_1f_operand" "F")
21477 +               (sqrt:SF (match_operand:SF 1 "register_operand" "?r"))))]
21478 +  "TARGET_ARCH_FPU && TARGET_HARD_FLOAT"
21479 +  "frsqrta.s %1, %0")
21480 --- /dev/null
21481 +++ b/gcc/config/avr32/uclinux-elf.h
21482 @@ -0,0 +1,20 @@
21483 +
21484 +/* Run-time Target Specification.  */
21485 +#undef  TARGET_VERSION
21486 +#define TARGET_VERSION  fputs (" (AVR32 uClinux with ELF)", stderr)
21487 +
21488 +/* We don't want a .jcr section on uClinux. As if this makes a difference... */
21489 +#define TARGET_USE_JCR_SECTION 0
21490 +
21491 +/* Here we go. Drop the crtbegin/crtend stuff completely. */
21492 +#undef STARTFILE_SPEC
21493 +#define STARTFILE_SPEC                                                 \
21494 +  "%{!shared: %{pg:gcrt1.o%s} %{!pg:%{p:gcrt1.o%s}"                    \
21495 +  " %{!p:%{profile:gcrt1.o%s}"                                         \
21496 +  " %{!profile:crt1.o%s}}}} crti.o%s"
21497 +
21498 +#undef ENDFILE_SPEC
21499 +#define ENDFILE_SPEC "crtn.o%s"
21500 +
21501 +#undef TARGET_DEFAULT
21502 +#define TARGET_DEFAULT (AVR32_FLAG_NO_INIT_GOT)
21503 --- a/gcc/config/host-linux.c
21504 +++ b/gcc/config/host-linux.c
21505 @@ -25,6 +25,9 @@
21506  #include "hosthooks.h"
21507  #include "hosthooks-def.h"
21508  
21509 +#ifndef SSIZE_MAX
21510 +#define SSIZE_MAX LONG_MAX
21511 +#endif
21512  
21513  /* Linux has a feature called exec-shield-randomize that perturbs the
21514     address of non-fixed mapped segments by a (relatively) small amount.
21515 --- a/gcc/config.gcc
21516 +++ b/gcc/config.gcc
21517 @@ -810,6 +810,24 @@ avr-*-rtems*)
21518  avr-*-*)
21519         tm_file="avr/avr.h dbxelf.h"
21520         ;;
21521 +avr32*-*-linux*)
21522 +       tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/avr32.h "
21523 +       tmake_file="t-linux avr32/t-avr32-linux"
21524 +       extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
21525 +       extra_modes=avr32/avr32-modes.def
21526 +       gnu_ld=yes
21527 +       ;;
21528 +avr32*-*-uclinux*)
21529 +       tm_file="dbxelf.h elfos.h linux.h avr32/linux-elf.h avr32/uclinux-elf.h avr32/avr32.h"
21530 +       tmake_file="t-linux avr32/t-avr32-linux"
21531 +       extra_modes=avr32/avr32-modes.def
21532 +       gnu_ld=yes
21533 +       ;;
21534 +avr32-*-*)
21535 +       tm_file="dbxelf.h elfos.h avr32/avr32.h avr32/avr32-elf.h"
21536 +       tmake_file="avr32/t-avr32 avr32/t-elf"
21537 +       extra_modes=avr32/avr32-modes.def
21538 +       ;;
21539  bfin*-elf*)
21540         tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h"
21541         tmake_file=bfin/t-bfin-elf
21542 @@ -2764,6 +2782,32 @@ case "${target}" in
21543                 fi
21544                 ;;
21545  
21546 +       avr32*-*-*)
21547 +               supported_defaults="part arch"
21548 +
21549 +               case "$with_part" in
21550 +               "" \
21551 +               | "ap7000" | "ap7010" | "ap7020" | "uc3a0256" | "uc3a0512" | "uc3a1128" | "uc3a1256" | "uc3a1512" )
21552 +                       # OK
21553 +                       ;;
21554 +               *)
21555 +                       echo "Unknown part used in --with-part=$with_part" 1>&2
21556 +                       exit 1
21557 +                       ;;
21558 +               esac
21559 +
21560 +               case "$with_arch" in
21561 +               "" \
21562 +               | "ap" | "uc")
21563 +                       # OK
21564 +                       ;;
21565 +               *)
21566 +                       echo "Unknown arch used in --with-arch=$with_arch" 1>&2
21567 +                       exit 1
21568 +                       ;;
21569 +               esac
21570 +                ;;
21571 +
21572         fr*-*-*linux*)
21573                 supported_defaults=cpu
21574                 case "$with_cpu" in
21575 --- a/gcc/configure.ac
21576 +++ b/gcc/configure.ac
21577 @@ -2240,10 +2240,9 @@ L2:],
21578    as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
21579    if echo "$as_ver" | grep GNU > /dev/null; then
21580  changequote(,)dnl
21581 -    as_vers=`echo $as_ver | sed -n \
21582 -       -e 's,^.*[       ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
21583 -    as_major=`expr "$as_vers" : '\([0-9]*\)'`
21584 -    as_minor=`expr "$as_vers" : '[0-9]*\.\([0-9]*\)'`
21585 +    as_ver=`echo $as_ver | sed -e 's/GNU assembler\( (GNU Binutils)\)\? \([0-9.][0-9.]*\).*/\2/'`
21586 +    as_major=`echo $as_ver | sed 's/\..*//'`
21587 +    as_minor=`echo $as_ver | sed 's/[^.]*\.\([0-9]*\).*/\1/'`
21588  changequote([,])dnl
21589      if test $as_major -eq 2 && test $as_minor -lt 11
21590      then :
21591 @@ -3308,7 +3307,7 @@ case "$target" in
21592    i?86*-*-* | mips*-*-* | alpha*-*-* | powerpc*-*-* | sparc*-*-* | m68*-*-* \
21593    | x86_64*-*-* | hppa*-*-* | arm*-*-* \
21594    | xstormy16*-*-* | cris-*-* | crisv32-*-* | xtensa*-*-* | bfin-*-* | score*-*-* \
21595 -  | spu-*-* | fido*-*-* | m32c-*-*)
21596 +  | spu-*-* | fido*-*-* | m32c-*-* | avr32-*-*)
21597      insn="nop"
21598      ;;
21599    ia64*-*-* | s390*-*-*)
21600 --- a/gcc/doc/extend.texi
21601 +++ b/gcc/doc/extend.texi
21602 @@ -2397,7 +2397,7 @@ This attribute is ignored for R8C target
21603  
21604  @item interrupt
21605  @cindex interrupt handler functions
21606 -Use this attribute on the ARM, AVR, CRX, M32C, M32R/D, m68k,
21607 +Use this attribute on the ARM, AVR, AVR32, CRX, M32C, M32R/D, m68k,
21608  and Xstormy16 ports to indicate that the specified function is an
21609  interrupt handler.  The compiler will generate function entry and exit
21610  sequences suitable for use in an interrupt handler when this attribute
21611 @@ -2417,6 +2417,15 @@ void f () __attribute__ ((interrupt ("IR
21612  
21613  Permissible values for this parameter are: IRQ, FIQ, SWI, ABORT and UNDEF@.
21614  
21615 +Note, for the AVR32, you can specify which banking scheme is used for
21616 +the interrupt mode this interrupt handler is used in like this:
21617 +
21618 +@smallexample
21619 +void f () __attribute__ ((interrupt ("FULL")));
21620 +@end smallexample
21621 +
21622 +Permissible values for this parameter are: FULL, HALF, NONE and UNDEF.
21623 +
21624  On ARMv7-M the interrupt type is ignored, and the attribute means the function
21625  may be called with a word aligned stack pointer.
21626  
21627 @@ -4188,6 +4197,23 @@ placed in either the @code{.bss_below100
21628  
21629  @end table
21630  
21631 +@subsection AVR32 Variable Attributes
21632 +
21633 +One attribute is currently defined for AVR32 configurations:
21634 +@code{rmw_addressable}
21635 +
21636 +@table @code
21637 +@item rmw_addressable
21638 +@cindex @code{rmw_addressable} attribute
21639 +
21640 +This attribute can be used to signal that a variable can be accessed 
21641 +with the addressing mode of the AVR32 Atomic Read-Modify-Write memory
21642 +instructions and hence make it possible for gcc to generate these 
21643 +instructions without using built-in functions or inline assembly statements. 
21644 +Variables used within the AVR32 Atomic Read-Modify-Write built-in
21645 +functions will automatically get the @code{rmw_addressable} attribute.
21646 +@end table
21647 +
21648  @subsection AVR Variable Attributes
21649  
21650  @table @code
21651 @@ -7042,6 +7068,7 @@ instructions, but allow the compiler to
21652  * Alpha Built-in Functions::
21653  * ARM iWMMXt Built-in Functions::
21654  * ARM NEON Intrinsics::
21655 +* AVR32 Built-in Functions::
21656  * Blackfin Built-in Functions::
21657  * FR-V Built-in Functions::
21658  * X86 Built-in Functions::
21659 @@ -7284,6 +7311,7 @@ long long __builtin_arm_wxor (long long,
21660  long long __builtin_arm_wzero ()
21661  @end smallexample
21662  
21663 +
21664  @node ARM NEON Intrinsics
21665  @subsection ARM NEON Intrinsics
21666  
21667 @@ -7292,6 +7320,74 @@ when the @option{-mfpu=neon} switch is u
21668  
21669  @include arm-neon-intrinsics.texi
21670  
21671 +@node AVR32 Built-in Functions
21672 +@subsection AVR32 Built-in Functions
21673 +
21674 +Built-in functions for atomic memory (RMW) instructions. Note that these
21675 +built-ins will fail for targets where the RMW instructions are not
21676 +implemented. Also note that these instructions only that a Ks15 << 2
21677 +memory address and will therefor not work with any runtime computed 
21678 +memory addresses. The user is responsible for making sure that any
21679 +pointers used within these functions points to a valid memory address.
21680
21681 +@smallexample
21682 +void __builtin_mems(int */*ptr*/, int /*bit*/)
21683 +void __builtin_memc(int */*ptr*/, int /*bit*/)
21684 +void __builtin_memt(int */*ptr*/, int /*bit*/)
21685 +@end smallexample
21686 +
21687 +Built-in functions for DSP instructions. Note that these built-ins will
21688 +fail for targets where the DSP instructions are not implemented.
21689 +
21690 +@smallexample
21691 +int __builtin_sats (int /*Rd*/,int /*sa*/, int /*bn*/)
21692 +int __builtin_satu (int /*Rd*/,int /*sa*/, int /*bn*/)
21693 +int __builtin_satrnds (int /*Rd*/,int /*sa*/, int /*bn*/)
21694 +int __builtin_satrndu (int /*Rd*/,int /*sa*/, int /*bn*/)
21695 +short __builtin_mulsathh_h (short, short)
21696 +int __builtin_mulsathh_w (short, short)
21697 +short __builtin_mulsatrndhh_h (short, short)
21698 +int __builtin_mulsatrndwh_w (int, short)
21699 +int __builtin_mulsatwh_w (int, short)
21700 +int __builtin_macsathh_w (int, short, short)
21701 +short __builtin_satadd_h (short, short)
21702 +short __builtin_satsub_h (short, short)
21703 +int __builtin_satadd_w (int, int)
21704 +int __builtin_satsub_w (int, int)
21705 +long long __builtin_mulwh_d(int, short)
21706 +long long __builtin_mulnwh_d(int, short)
21707 +long long __builtin_macwh_d(long long, int, short)
21708 +long long __builtin_machh_d(long long, short, short)
21709 +@end smallexample
21710 +
21711 +Other built-in functions for instructions that cannot easily be
21712 +generated by the compiler. 
21713 +
21714 +@smallexample
21715 +void __builtin_ssrf(int);
21716 +void __builtin_csrf(int);
21717 +void __builtin_musfr(int);
21718 +int __builtin_mustr(void);
21719 +int __builtin_mfsr(int /*Status Register Address*/)
21720 +void __builtin_mtsr(int /*Status Register Address*/, int /*Value*/)
21721 +int __builtin_mfdr(int /*Debug Register Address*/)
21722 +void __builtin_mtdr(int /*Debug Register Address*/, int /*Value*/)
21723 +void __builtin_cache(void * /*Address*/, int /*Cache Operation*/)
21724 +void __builtin_sync(int /*Sync Operation*/)
21725 +void __builtin_tlbr(void)
21726 +void __builtin_tlbs(void)
21727 +void __builtin_tlbw(void)
21728 +void __builtin_breakpoint(void)
21729 +int __builtin_xchg(void * /*Address*/, int /*Value*/ )
21730 +short __builtin_bswap_16(short)
21731 +int __builtin_bswap_32(int)
21732 +void __builtin_cop(int/*cpnr*/, int/*crd*/, int/*crx*/, int/*cry*/, int/*op*/)
21733 +int __builtin_mvcr_w(int/*cpnr*/, int/*crs*/)
21734 +void __builtin_mvrc_w(int/*cpnr*/, int/*crd*/, int/*value*/)
21735 +long long __builtin_mvcr_d(int/*cpnr*/, int/*crs*/)
21736 +void __builtin_mvrc_d(int/*cpnr*/, int/*crd*/, long long/*value*/)
21737 +@end smallexample
21738 +
21739  @node Blackfin Built-in Functions
21740  @subsection Blackfin Built-in Functions
21741  
21742 --- a/gcc/doc/invoke.texi
21743 +++ b/gcc/doc/invoke.texi
21744 @@ -195,7 +195,7 @@ in the following sections.
21745  -fvisibility-ms-compat @gol
21746  -Wabi  -Wctor-dtor-privacy @gol
21747  -Wnon-virtual-dtor  -Wreorder @gol
21748 --Weffc++  -Wstrict-null-sentinel @gol
21749 +-Weffc++  -Wno-deprecated @gol
21750  -Wno-non-template-friend  -Wold-style-cast @gol
21751  -Woverloaded-virtual  -Wno-pmf-conversions @gol
21752  -Wsign-promo}
21753 @@ -641,6 +641,12 @@ Objective-C and Objective-C++ Dialects}.
21754  -mauto-incdec  -minmax  -mlong-calls  -mshort @gol
21755  -msoft-reg-count=@var{count}}
21756  
21757 +@emph{AVR32 Options}
21758 +@gccoptlist{-muse-rodata-section -mhard-float -msoft-float -mrelax @gol
21759 +-mforce-double-align -mno-init-got -mrelax -mmd-reorg-opt -masm-addr-pseudos @gol
21760 +-mpart=@var{part} -mcpu=@var{cpu} -march=@var{arch} @gol  
21761 +-mfast-float -mimm-in-const-pool}
21762 +
21763  @emph{MCore Options}
21764  @gccoptlist{-mhardlit  -mno-hardlit  -mdiv  -mno-div  -mrelax-immediates @gol
21765  -mno-relax-immediates  -mwide-bitfields  -mno-wide-bitfields @gol
21766 @@ -3256,13 +3262,11 @@ appears in a class without constructors.
21767  If you want to warn about code which uses the uninitialized value of the
21768  variable in its own initializer, use the @option{-Winit-self} option.
21769  
21770 -These warnings occur for individual uninitialized or clobbered
21771 -elements of structure, union or array variables as well as for
21772 -variables which are uninitialized or clobbered as a whole.  They do
21773 -not occur for variables or elements declared @code{volatile}.  Because
21774 -these warnings depend on optimization, the exact variables or elements
21775 -for which there are warnings will depend on the precise optimization
21776 -options and version of GCC used.
21777 +These warnings occur only for variables that are candidates for
21778 +register allocation.  Therefore, they do not occur for a variable that
21779 +is declared @code{volatile}, or whose address is taken, or whose size
21780 +is other than 1, 2, 4 or 8 bytes.  Also, they do not occur for
21781 +structures, unions or arrays, even when they are in registers.
21782  
21783  Note that there may be no warning about a variable that is used only
21784  to compute a value that itself is never used, because such
21785 @@ -7461,10 +7465,6 @@ If number of candidates in the set is sm
21786  we always try to remove unnecessary ivs from the set during its
21787  optimization when a new iv is added to the set.
21788  
21789 -@item scev-max-expr-size
21790 -Bound on size of expressions used in the scalar evolutions analyzer.
21791 -Large expressions slow the analyzer.
21792 -
21793  @item omega-max-vars
21794  The maximum number of variables in an Omega constraint system.
21795  The default value is 128.
21796 @@ -8860,6 +8860,7 @@ platform.
21797  * ARC Options::
21798  * ARM Options::
21799  * AVR Options::
21800 +* AVR32 Options::
21801  * Blackfin Options::
21802  * CRIS Options::
21803  * CRX Options::
21804 @@ -9348,6 +9349,145 @@ comply to the C standards, but it will p
21805  size.
21806  @end table
21807  
21808 +@node AVR32 Options
21809 +@subsection AVR32 Options
21810 +@cindex AVR32 Options
21811 +
21812 +These options are defined for AVR32 implementations:
21813 +
21814 +@table @gcctabopt
21815 +@item -muse-rodata-section
21816 +@opindex muse-rodata-section
21817 +Use section @samp{.rodata} for read-only data instead of @samp{.text}.
21818 +
21819 +@item -mhard-float
21820 +@opindex mhard-float
21821 +Use floating point coprocessor instructions.
21822 +
21823 +@item -msoft-float
21824 +@opindex msoft-float
21825 +Use software floating-point library for floating-point operations.
21826 +
21827 +@item -mforce-double-align
21828 +@opindex mforce-double-align
21829 +Force double-word alignment for double-word memory accesses.
21830 +
21831 +@item -masm-addr-pseudos
21832 +@opindex masm-addr-pseudos
21833 +Use assembler pseudo-instructions lda.w and call for handling direct
21834 +addresses. (Enabled by default)
21835 +
21836 +@item -mno-init-got
21837 +@opindex mno-init-got
21838 +Do not initialize the GOT register before using it when compiling PIC
21839 +code.
21840 +
21841 +@item -mrelax
21842 +@opindex mrelax
21843 +Let invoked assembler and linker do relaxing 
21844 +(Enabled by default when optimization level is >1).
21845 +This means that when the address of symbols are known at link time,
21846 +the linker can optimize @samp{icall} and @samp{mcall}
21847 +instructions into a @samp{rcall} instruction if possible. 
21848 +Loading the address of a symbol can also be optimized.  
21849 +
21850 +@item -mmd-reorg-opt
21851 +@opindex mmd-reorg-opt
21852 +Perform machine dependent optimizations in reorg stage.
21853 +
21854 +@item -mpart=@var{part}
21855 +@opindex mpart
21856 +Generate code for the specified part. Permissible parts are: 
21857 +@samp{ap7000},
21858 +@samp{ap7001},
21859 +@samp{ap7002},
21860 +@samp{ap7200},
21861 +@samp{uc3a0128},
21862 +@samp{uc3a0256},
21863 +@samp{uc3a0512},
21864 +@samp{uc3a0512es},
21865 +@samp{uc3a1128},
21866 +@samp{uc3a1256},
21867 +@samp{uc3a1512},
21868 +@samp{uc3a1512es},
21869 +@samp{uc3a3revd},
21870 +@samp{uc3a364},
21871 +@samp{uc3a364s},
21872 +@samp{uc3a3128},
21873 +@samp{uc3a3128s},
21874 +@samp{uc3a3256},
21875 +@samp{uc3a3256s},
21876 +@samp{uc3a464},
21877 +@samp{uc3a464s},
21878 +@samp{uc3a4128},
21879 +@samp{uc3a4128s},
21880 +@samp{uc3a4256},
21881 +@samp{uc3a4256s},
21882 +@samp{uc3b064},
21883 +@samp{uc3b0128},
21884 +@samp{uc3b0256},
21885 +@samp{uc3b0256es},
21886 +@samp{uc3b0512},
21887 +@samp{uc3b0512revc},
21888 +@samp{uc3b164},
21889 +@samp{uc3b1128},
21890 +@samp{uc3b1256},
21891 +@samp{uc3b1256es},
21892 +@samp{uc3b1512},
21893 +@samp{uc3b1512revc}
21894 +@samp{uc64d3},
21895 +@samp{uc128d3},
21896 +@samp{uc64d4},
21897 +@samp{uc128d4},
21898 +@samp{uc3c0512crevc},
21899 +@samp{uc3c1512crevc},
21900 +@samp{uc3c2512crevc},
21901 +@samp{uc3l0256},
21902 +@samp{uc3l0128},
21903 +@samp{uc3l064},
21904 +@samp{uc3l032},
21905 +@samp{uc3l016},
21906 +@samp{uc3l064revb},
21907 +@samp{uc64l3u},
21908 +@samp{uc128l3u},
21909 +@samp{uc256l3u},
21910 +@samp{uc64l4u},
21911 +@samp{uc128l4u},
21912 +@samp{uc256l4u},
21913 +@samp{uc3c064c},
21914 +@samp{uc3c0128c},
21915 +@samp{uc3c0256c},
21916 +@samp{uc3c0512c},
21917 +@samp{uc3c164c},
21918 +@samp{uc3c1128c},
21919 +@samp{uc3c1256c},
21920 +@samp{uc3c1512c},
21921 +@samp{uc3c264c},
21922 +@samp{uc3c2128c},
21923 +@samp{uc3c2256c},
21924 +@samp{uc3c2512c},
21925 +@samp{mxt768e}.
21926 +
21927 +@item -mcpu=@var{cpu-type}
21928 +@opindex mcpu
21929 +Same as -mpart. Obsolete.
21930 +
21931 +@item -march=@var{arch}
21932 +@opindex march
21933 +Generate code for the specified architecture. Permissible architectures are:
21934 +@samp{ap}, @samp{uc} and @samp{ucr2}. 
21935 +
21936 +@item -mfast-float
21937 +@opindex mfast-float
21938 +Enable fast floating-point library that does not conform to IEEE-754 but is still good enough
21939 +for most applications. The fast floating-point library does not round to the nearest even
21940 +but away from zero. Enabled by default if the -funsafe-math-optimizations switch is specified. 
21941 +
21942 +@item -mimm-in-const-pool
21943 +@opindex mimm-in-const-pool
21944 +Put large immediates in constant pool. This is enabled by default for archs with insn-cache.
21945 +@end table
21946 +
21947  @node Blackfin Options
21948  @subsection Blackfin Options
21949  @cindex Blackfin Options
21950 @@ -9403,29 +9543,12 @@ When enabled, the compiler will ensure t
21951  contain speculative loads after jump instructions. If this option is used,
21952  @code{__WORKAROUND_SPECULATIVE_LOADS} is defined.
21953  
21954 -@item -mno-specld-anomaly
21955 -@opindex mno-specld-anomaly
21956 -Don't generate extra code to prevent speculative loads from occurring.
21957 -
21958  @item -mcsync-anomaly
21959  @opindex mcsync-anomaly
21960  When enabled, the compiler will ensure that the generated code does not
21961  contain CSYNC or SSYNC instructions too soon after conditional branches.
21962  If this option is used, @code{__WORKAROUND_SPECULATIVE_SYNCS} is defined.
21963  
21964 -@item -mno-csync-anomaly
21965 -@opindex mno-csync-anomaly
21966 -Don't generate extra code to prevent CSYNC or SSYNC instructions from
21967 -occurring too soon after a conditional branch.
21968 -
21969 -@item -mlow-64k
21970 -@opindex mlow-64k
21971 -When enabled, the compiler is free to take advantage of the knowledge that
21972 -the entire program fits into the low 64k of memory.
21973 -
21974 -@item -mno-low-64k
21975 -@opindex mno-low-64k
21976 -Assume that the program is arbitrarily large.  This is the default.
21977  
21978  @item -mstack-check-l1
21979  @opindex mstack-check-l1
21980 @@ -9439,11 +9562,6 @@ This allows for execute in place and sha
21981  without virtual memory management.  This option implies @option{-fPIC}.
21982  With a @samp{bfin-elf} target, this option implies @option{-msim}.
21983  
21984 -@item -mno-id-shared-library
21985 -@opindex mno-id-shared-library
21986 -Generate code that doesn't assume ID based shared libraries are being used.
21987 -This is the default.
21988 -
21989  @item -mleaf-id-shared-library
21990  @opindex mleaf-id-shared-library
21991  Generate code that supports shared libraries via the library ID method,
21992 @@ -9485,11 +9603,6 @@ call on this register.  This switch is n
21993  will lie outside of the 24 bit addressing range of the offset based
21994  version of subroutine call instruction.
21995  
21996 -This feature is not enabled by default.  Specifying
21997 -@option{-mno-long-calls} will restore the default behavior.  Note these
21998 -switches have no effect on how the compiler generates code to handle
21999 -function calls via function pointers.
22000 -
22001  @item -mfast-fp
22002  @opindex mfast-fp
22003  Link with the fast floating-point library. This library relaxes some of
22004 --- a/gcc/doc/md.texi
22005 +++ b/gcc/doc/md.texi
22006 @@ -4,6 +4,7 @@
22007  @c This is part of the GCC manual.
22008  @c For copying conditions, see the file gcc.texi.
22009  
22010 +
22011  @ifset INTERNALS
22012  @node Machine Desc
22013  @chapter Machine Descriptions
22014 @@ -1685,6 +1686,58 @@ A memory reference suitable for iWMMXt l
22015  A memory reference suitable for the ARMv4 ldrsb instruction.
22016  @end table
22017  
22018 +@item AVR32 family---@file{avr32.h}
22019 +@table @code
22020 +@item f
22021 +Floating-point registers (f0 to f15)
22022 +
22023 +@item Ku@var{bits}
22024 +Unsigned constant representable with @var{bits} number of bits (Must be
22025 +two digits). I.e: An unsigned 8-bit constant is written as @samp{Ku08}  
22026
22027 +@item Ks@var{bits}
22028 +Signed constant representable with @var{bits} number of bits (Must be
22029 +two digits). I.e: A signed 12-bit constant is written as @samp{Ks12}  
22030 +
22031 +@item Is@var{bits}
22032 +The negated range of a signed constant representable with  @var{bits} 
22033 +number of bits. The same as @samp{Ks@var{bits}} with a negated range. 
22034 +This means that the constant must be in the range @math{-2^{bits-1}-1} to @math{2^{bits-1}}
22035 +
22036 +@item G
22037 +A single/double precision floating-point immediate or 64-bit integer 
22038 +immediate where the least and most significant words both can be
22039 +loaded with a move instruction. That is the the integer form of the 
22040 +values in the least and most significant words both are in the range 
22041 +@math{-2^{20}} to @math{2^{20}-1}.
22042 +         
22043 +@item RKs@var{bits}
22044 +A memory reference where the address consists of a base register
22045 +plus a signed immediate displacement with range given by @samp{Ks@var{bits}}
22046 +which has the same format as for the signed immediate integer constraint
22047 +given above.  
22048 +
22049 +@item RKu@var{bits}
22050 +A memory reference where the address consists of a base register
22051 +plus an unsigned immediate displacement with range given by @samp{Ku@var{bits}}
22052 +which has the same format as for the unsigned immediate integer constraint
22053 +given above.  
22054 +
22055 +@item S
22056 +A memory reference with an immediate or register offset
22057 +
22058 +@item T
22059 +A memory reference to a constant pool entry
22060 +
22061 +@item W
22062 +A valid operand for use in the @samp{lda.w} instruction macro when
22063 +relaxing is enabled
22064 +
22065 +@item Z
22066 +A memory reference valid for coprocessor memory instructions
22067 +
22068 +@end table
22069 +
22070  @item AVR family---@file{config/avr/constraints.md}
22071  @table @code
22072  @item l
22073 --- a/gcc/expmed.c
22074 +++ b/gcc/expmed.c
22075 @@ -472,9 +472,9 @@ store_bit_field_1 (rtx str_rtx, unsigned
22076           ? ((GET_MODE_SIZE (fieldmode) >= UNITS_PER_WORD
22077              || GET_MODE_SIZE (GET_MODE (op0)) == GET_MODE_SIZE (fieldmode))
22078              && byte_offset % GET_MODE_SIZE (fieldmode) == 0)
22079 -         : (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
22080 +          : ( (! SLOW_UNALIGNED_ACCESS (fieldmode, MEM_ALIGN (op0))
22081              || (offset * BITS_PER_UNIT % bitsize == 0
22082 -                && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0))))
22083 +                     && MEM_ALIGN (op0) % GET_MODE_BITSIZE (fieldmode) == 0)))))
22084      {
22085        if (MEM_P (op0))
22086         op0 = adjust_address (op0, fieldmode, offset);
22087 --- a/gcc/expr.c
22088 +++ b/gcc/expr.c
22089 @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.
22090  #include "tree-flow.h"
22091  #include "target.h"
22092  #include "timevar.h"
22093 +#include "c-common.h"
22094  #include "df.h"
22095  #include "diagnostic.h"
22096  
22097 @@ -3647,16 +3648,17 @@ emit_single_push_insn (enum machine_mode
22098      }
22099    else
22100      {
22101 +      emit_move_insn (stack_pointer_rtx,
22102 +                     expand_binop (Pmode,
22103  #ifdef STACK_GROWS_DOWNWARD
22104 -      /* ??? This seems wrong if STACK_PUSH_CODE == POST_DEC.  */
22105 -      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
22106 -                               GEN_INT (-(HOST_WIDE_INT) rounded_size));
22107 +                                   sub_optab,
22108  #else
22109 -      /* ??? This seems wrong if STACK_PUSH_CODE == POST_INC.  */
22110 -      dest_addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
22111 -                               GEN_INT (rounded_size));
22112 +                                   add_optab,
22113  #endif
22114 -      dest_addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, dest_addr);
22115 +                                   stack_pointer_rtx,
22116 +                                   GEN_INT (rounded_size),
22117 +                                   NULL_RTX, 0, OPTAB_LIB_WIDEN));
22118 +      dest_addr = stack_pointer_rtx;
22119      }
22120  
22121    dest = gen_rtx_MEM (mode, dest_addr);
22122 @@ -5775,7 +5777,8 @@ store_field (rtx target, HOST_WIDE_INT b
22123       is a bit field, we cannot use addressing to access it.
22124       Use bit-field techniques or SUBREG to store in it.  */
22125  
22126 -  if (mode == VOIDmode
22127 +  if (
22128 +      mode == VOIDmode
22129        || (mode != BLKmode && ! direct_store[(int) mode]
22130           && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
22131           && GET_MODE_CLASS (mode) != MODE_COMPLEX_FLOAT)
22132 @@ -5932,7 +5935,18 @@ get_inner_reference (tree exp, HOST_WIDE
22133      {
22134        tree field = TREE_OPERAND (exp, 1);
22135        size_tree = DECL_SIZE (field);
22136 -      if (!DECL_BIT_FIELD (field))
22137 +      if (!DECL_BIT_FIELD (field)
22138 +          /* Added for AVR32:
22139 +             Bitfields with a size equal to a target storage
22140 +             type might not cause DECL_BIT_FIELD to return
22141 +             true since it can be optimized into a normal array
22142 +             access operation. But for volatile bitfields we do
22143 +             not allow this when targetm.narrow_volatile_bitfield ()
22144 +             is false. We can use DECL_C_BIT_FIELD to check if this
22145 +             really is a c-bitfield. */ 
22146 +          && !(TREE_THIS_VOLATILE (exp)
22147 +               && !targetm.narrow_volatile_bitfield ()
22148 +               && DECL_C_BIT_FIELD (field)) )
22149         mode = DECL_MODE (field);
22150        else if (DECL_MODE (field) == BLKmode)
22151         blkmode_bitfield = true;
22152 @@ -7915,7 +7929,8 @@ expand_expr_real_1 (tree exp, rtx target
22153            by doing the extract into an object as wide as the field
22154            (which we know to be the width of a basic mode), then
22155            storing into memory, and changing the mode to BLKmode.  */
22156 -       if (mode1 == VOIDmode
22157 +       if (      
22158 +            mode1 == VOIDmode
22159             || REG_P (op0) || GET_CODE (op0) == SUBREG
22160             || (mode1 != BLKmode && ! direct_load[(int) mode1]
22161                 && GET_MODE_CLASS (mode) != MODE_COMPLEX_INT
22162 --- a/gcc/function.c
22163 +++ b/gcc/function.c
22164 @@ -2810,7 +2810,11 @@ assign_parm_setup_reg (struct assign_par
22165    assign_parm_remove_parallels (data);
22166  
22167    /* Copy the value into the register.  */
22168 -  if (data->nominal_mode != data->passed_mode
22169 +  if ( (data->nominal_mode != data->passed_mode
22170 +        /* Added for AVR32: If passed_mode is equal
22171 +           to promoted nominal mode why should be convert?
22172 +           The conversion should make no difference. */
22173 +        && data->passed_mode != promoted_nominal_mode)
22174        || promoted_nominal_mode != data->promoted_mode)
22175      {
22176        int save_tree_used;
22177 --- a/gcc/genemit.c
22178 +++ b/gcc/genemit.c
22179 @@ -121,6 +121,24 @@ max_operand_vec (rtx insn, int arg)
22180  }
22181  \f
22182  static void
22183 +gen_vararg_prologue(int operands)
22184 +{
22185 +  int i;
22186 +
22187 +  if (operands > 1)
22188 +    {
22189 +      for (i = 1; i < operands; i++)
22190 +       printf("  rtx operand%d ATTRIBUTE_UNUSED;\n", i);
22191 +
22192 +      printf("  va_list args;\n\n");
22193 +      printf("  va_start(args, operand0);\n");
22194 +      for (i = 1; i < operands; i++)
22195 +       printf("  operand%d = va_arg(args, rtx);\n", i);
22196 +      printf("  va_end(args);\n\n");
22197 +    }
22198 +}
22199 +
22200 +static void
22201  print_code (RTX_CODE code)
22202  {
22203    const char *p1;
22204 @@ -406,18 +424,16 @@ gen_insn (rtx insn, int lineno)
22205      fatal ("match_dup operand number has no match_operand");
22206  
22207    /* Output the function name and argument declarations.  */
22208 -  printf ("rtx\ngen_%s (", XSTR (insn, 0));
22209 +  printf ("rtx\ngen_%s ", XSTR (insn, 0));
22210 +
22211    if (operands)
22212 -    for (i = 0; i < operands; i++)
22213 -      if (i)
22214 -       printf (",\n\trtx operand%d ATTRIBUTE_UNUSED", i);
22215 +    printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
22216        else
22217 -       printf ("rtx operand%d ATTRIBUTE_UNUSED", i);
22218 -  else
22219 -    printf ("void");
22220 -  printf (")\n");
22221 +    printf("(void)\n");
22222    printf ("{\n");
22223  
22224 +  gen_vararg_prologue(operands);
22225 +
22226    /* Output code to construct and return the rtl for the instruction body.  */
22227  
22228    if (XVECLEN (insn, 1) == 1)
22229 @@ -461,16 +477,12 @@ gen_expand (rtx expand)
22230    operands = max_operand_vec (expand, 1);
22231  
22232    /* Output the function name and argument declarations.  */
22233 -  printf ("rtx\ngen_%s (", XSTR (expand, 0));
22234 +  printf ("rtx\ngen_%s ", XSTR (expand, 0));
22235    if (operands)
22236 -    for (i = 0; i < operands; i++)
22237 -      if (i)
22238 -       printf (",\n\trtx operand%d", i);
22239 -      else
22240 -       printf ("rtx operand%d", i);
22241 +    printf("(rtx operand0 ATTRIBUTE_UNUSED, ...)\n");
22242    else
22243 -    printf ("void");
22244 -  printf (")\n");
22245 +    printf("(void)\n");
22246 +
22247    printf ("{\n");
22248  
22249    /* If we don't have any C code to write, only one insn is being written,
22250 @@ -480,6 +492,8 @@ gen_expand (rtx expand)
22251        && operands > max_dup_opno
22252        && XVECLEN (expand, 1) == 1)
22253      {
22254 +      gen_vararg_prologue(operands);
22255 +
22256        printf ("  return ");
22257        gen_exp (XVECEXP (expand, 1, 0), DEFINE_EXPAND, NULL);
22258        printf (";\n}\n\n");
22259 @@ -493,6 +507,7 @@ gen_expand (rtx expand)
22260    for (; i <= max_scratch_opno; i++)
22261      printf ("  rtx operand%d ATTRIBUTE_UNUSED;\n", i);
22262    printf ("  rtx _val = 0;\n");
22263 +  gen_vararg_prologue(operands);
22264    printf ("  start_sequence ();\n");
22265  
22266    /* The fourth operand of DEFINE_EXPAND is some code to be executed
22267 --- a/gcc/genflags.c
22268 +++ b/gcc/genflags.c
22269 @@ -127,7 +127,6 @@ static void
22270  gen_proto (rtx insn)
22271  {
22272    int num = num_operands (insn);
22273 -  int i;
22274    const char *name = XSTR (insn, 0);
22275    int truth = maybe_eval_c_test (XSTR (insn, 2));
22276  
22277 @@ -158,12 +157,7 @@ gen_proto (rtx insn)
22278    if (num == 0)
22279      fputs ("void", stdout);
22280    else
22281 -    {
22282 -      for (i = 1; i < num; i++)
22283 -       fputs ("rtx, ", stdout);
22284 -
22285 -      fputs ("rtx", stdout);
22286 -    }
22287 +    fputs("rtx, ...", stdout);
22288  
22289    puts (");");
22290  
22291 @@ -173,12 +167,7 @@ gen_proto (rtx insn)
22292      {
22293        printf ("static inline rtx\ngen_%s", name);
22294        if (num > 0)
22295 -       {
22296 -         putchar ('(');
22297 -         for (i = 0; i < num-1; i++)
22298 -           printf ("rtx ARG_UNUSED (%c), ", 'a' + i);
22299 -         printf ("rtx ARG_UNUSED (%c))\n", 'a' + i);
22300 -       }
22301 +       puts("(rtx ARG_UNUSED(a), ...)");
22302        else
22303         puts ("(void)");
22304        puts ("{\n  return 0;\n}");
22305 --- a/gcc/genoutput.c
22306 +++ b/gcc/genoutput.c
22307 @@ -386,7 +386,7 @@ output_insn_data (void)
22308         }
22309  
22310        if (d->name && d->name[0] != '*')
22311 -       printf ("    (insn_gen_fn) gen_%s,\n", d->name);
22312 +       printf ("    gen_%s,\n", d->name);
22313        else
22314         printf ("    0,\n");
22315  
22316 --- a/gcc/ifcvt.c
22317 +++ b/gcc/ifcvt.c
22318 @@ -84,7 +84,7 @@ static int num_possible_if_blocks;
22319  static int num_updated_if_blocks;
22320  
22321  /* # of changes made.  */
22322 -static int num_true_changes;
22323 +int num_true_changes;
22324  
22325  /* Whether conditional execution changes were made.  */
22326  static int cond_exec_changed_p;
22327 @@ -290,6 +290,9 @@ cond_exec_process_insns (ce_if_block_t *
22328        if (must_be_last)
22329         return FALSE;
22330  
22331 +#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN       
22332 +      if ( !IFCVT_ALLOW_MODIFY_TEST_IN_INSN )
22333 +#endif
22334        if (modified_in_p (test, insn))
22335         {
22336           if (!mod_ok)
22337 @@ -570,15 +573,18 @@ cond_exec_process_if_block (ce_if_block_
22338    IFCVT_MODIFY_FINAL (ce_info);
22339  #endif
22340  
22341 +  /* Merge the blocks!  */
22342 +  if ( reload_completed ){
22343    /* Conversion succeeded.  */
22344    if (dump_file)
22345      fprintf (dump_file, "%d insn%s converted to conditional execution.\n",
22346              n_insns, (n_insns == 1) ? " was" : "s were");
22347  
22348 -  /* Merge the blocks!  */
22349    merge_if_block (ce_info);
22350    cond_exec_changed_p = TRUE;
22351    return TRUE;
22352 +  }
22353 +  return FALSE;
22354  
22355   fail:
22356  #ifdef IFCVT_MODIFY_CANCEL
22357 @@ -1087,7 +1093,11 @@ noce_try_addcc (struct noce_if_info *if_
22358           != UNKNOWN))
22359      {
22360        rtx cond = if_info->cond;
22361 -      enum rtx_code code = reversed_comparison_code (cond, if_info->jump);
22362 +      /* This generates wrong code for AVR32. The cond code need not be reversed
22363 +         since the addmodecc patterns add if the condition is NOT met. */
22364 +      /*   enum rtx_code code = reversed_comparison_code (cond, if_info->jump);*/
22365 +      enum rtx_code code = GET_CODE(cond);
22366 +
22367  
22368        /* First try to use addcc pattern.  */
22369        if (general_operand (XEXP (cond, 0), VOIDmode)
22370 @@ -3039,7 +3049,12 @@ find_if_header (basic_block test_bb, int
22371        && noce_find_if_block (test_bb, then_edge, else_edge, pass))
22372      goto success;
22373  
22374 -  if (HAVE_conditional_execution && reload_completed
22375 +  if (HAVE_conditional_execution && 
22376 +#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD
22377 +      (reload_completed || IFCVT_COND_EXEC_BEFORE_RELOAD)
22378 +#else
22379 +      reload_completed
22380 +#endif
22381        && cond_exec_find_if_block (&ce_info))
22382      goto success;
22383  
22384 @@ -3154,7 +3169,11 @@ cond_exec_find_if_block (struct ce_if_bl
22385  
22386    /* We only ever should get here after reload,
22387       and only if we have conditional execution.  */
22388 +#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD
22389 +  gcc_assert (HAVE_conditional_execution && (reload_completed||IFCVT_COND_EXEC_BEFORE_RELOAD));
22390 +#else
22391    gcc_assert (HAVE_conditional_execution && reload_completed);
22392 +#endif
22393  
22394    /* Discover if any fall through predecessors of the current test basic block
22395       were && tests (which jump to the else block) or || tests (which jump to
22396 @@ -4259,6 +4278,14 @@ gate_handle_if_after_reload (void)
22397  static unsigned int
22398  rest_of_handle_if_after_reload (void)
22399  {
22400 +  /* Hack for the AVR32 experimental ifcvt processing before reload.
22401 +     The AVR32 specific ifcvt code needs to know when ifcvt after reload 
22402 +     has begun. */
22403 +#ifdef IFCVT_COND_EXEC_BEFORE_RELOAD
22404 +  if ( IFCVT_COND_EXEC_BEFORE_RELOAD )
22405 +    cfun->machine->ifcvt_after_reload = 1;
22406 +#endif
22407 +  
22408    if_convert ();
22409    return 0;
22410  }
22411 --- a/gcc/longlong.h
22412 +++ b/gcc/longlong.h
22413 @@ -250,6 +250,41 @@ UDItype __umulsidi3 (USItype, USItype);
22414  #define COUNT_LEADING_ZEROS_0 32
22415  #endif
22416  
22417 +#if defined (__avr32__) && W_TYPE_SIZE == 32
22418 +#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
22419 +  __asm__ ("add\t%1, %4, %5\n\tadc\t%0, %2, %3"                \
22420 +          : "=r" ((USItype) (sh)),                                     \
22421 +            "=&r" ((USItype) (sl))                                     \
22422 +          : "r" ((USItype) (ah)),                                      \
22423 +            "r" ((USItype) (bh)),                                      \
22424 +            "r" ((USItype) (al)),                                      \
22425 +            "r" ((USItype) (bl)) __CLOBBER_CC)
22426 +#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
22427 +  __asm__ ("sub\t%1, %4, %5\n\tsbc\t%0, %2, %3"                \
22428 +          : "=r" ((USItype) (sh)),                                     \
22429 +            "=&r" ((USItype) (sl))                                     \
22430 +          : "r" ((USItype) (ah)),                                      \
22431 +            "r" ((USItype) (bh)),                                      \
22432 +            "r" ((USItype) (al)),                                      \
22433 +            "r" ((USItype) (bl)) __CLOBBER_CC)
22434 +
22435 +#if !defined (__AVR32_NO_MUL__)
22436 +#define __umulsidi3(a,b) ((UDItype)(a) * (UDItype)(b))
22437 +
22438 +#define umul_ppmm(w1, w0, u, v) \
22439 +{                                                                      \
22440 +  DWunion __w;                                                         \
22441 +  __w.ll = __umulsidi3 (u, v);                                         \
22442 +  w1 = __w.s.high;                                                     \
22443 +  w0 = __w.s.low;                                                      \
22444 +}
22445 +#endif
22446 +
22447 +#define count_leading_zeros(COUNT,X)   ((COUNT) = __builtin_clz (X))
22448 +#define count_trailing_zeros(COUNT,X)  ((COUNT) = __builtin_ctz (X))
22449 +#define COUNT_LEADING_ZEROS_0 32
22450 +#endif
22451 +
22452  #if defined (__CRIS__) && __CRIS_arch_version >= 3
22453  #define count_leading_zeros(COUNT, X) ((COUNT) = __builtin_clz (X))
22454  #if __CRIS_arch_version >= 8
22455 --- a/gcc/optabs.h
22456 +++ b/gcc/optabs.h
22457 @@ -603,7 +603,7 @@ extern enum insn_code reload_out_optab[N
22458  extern optab code_to_optab[NUM_RTX_CODE + 1];
22459  
22460  \f
22461 -typedef rtx (*rtxfun) (rtx);
22462 +typedef rtx (*rtxfun) (rtx, ...);
22463  
22464  /* Indexed by the rtx-code for a conditional (e.g. EQ, LT,...)
22465     gives the gen_function to make a branch to test that condition.  */
22466 --- a/gcc/regrename.c
22467 +++ b/gcc/regrename.c
22468 @@ -1582,6 +1582,9 @@ copyprop_hardreg_forward_1 (basic_block
22469    bool changed = false;
22470    rtx insn;
22471  
22472 +  rtx prev_pred_test;
22473 +  int prev_pred_insn_skipped = 0;
22474 +
22475    for (insn = BB_HEAD (bb); ; insn = NEXT_INSN (insn))
22476      {
22477        int n_ops, i, alt, predicated;
22478 @@ -1621,6 +1624,58 @@ copyprop_hardreg_forward_1 (basic_block
22479             recog_data.operand_type[i] = OP_INOUT;
22480         }
22481  
22482 +
22483 +      /* Added for targets (AVR32) which supports test operands to be modified
22484 +         in cond_exec instruction. For these targets we cannot make a change to
22485 +         the test operands if one of the test operands is an output operand This beacuse
22486 +         changing the test operands might cause the need for inserting a new test
22487 +         insns in the middle of a sequence of cond_exec insns and if the test operands
22488 +         are modified these tests will fail.
22489 +      */
22490 +      if ( IFCVT_ALLOW_MODIFY_TEST_IN_INSN
22491 +           && predicated )
22492 +        { 
22493 +          int insn_skipped = 0;
22494 +          rtx test = COND_EXEC_TEST (PATTERN (insn));
22495 +
22496 +          /* Check if the previous insn was a skipped predicated insn with the same
22497 +             test as this predicated insns. If so we cannot do any modification to
22498 +             this insn either since we cannot emit the test insn because the operands
22499 +             are clobbered. */
22500 +          if ( prev_pred_insn_skipped 
22501 +               && (rtx_equal_p (test, prev_pred_test) 
22502 +                   || rtx_equal_p (test, reversed_condition (prev_pred_test))) )
22503 +            { 
22504 +              insn_skipped = 1;
22505 +            }
22506 +          else
22507 +            {
22508 +              /* Check if the output operand is used in the test expression. */
22509 +              for (i = 0; i < n_ops; ++i)
22510 +                if ( recog_data.operand_type[i] == OP_INOUT 
22511 +                     && reg_mentioned_p (recog_data.operand[i], test) )
22512 +                  {
22513 +                    insn_skipped = 1;
22514 +                    break;
22515 +                  }
22516 +              
22517 +            }
22518 +          
22519 +          prev_pred_test = test;
22520 +          prev_pred_insn_skipped = insn_skipped;
22521 +          if ( insn_skipped )
22522 +            {
22523 +              if (insn == BB_END (bb))
22524 +                break;
22525 +              else
22526 +                continue;
22527 +            }
22528 +        } 
22529 +      else 
22530 +        {
22531 +          prev_pred_insn_skipped = 0;
22532 +        }
22533 +      
22534        /* For each earlyclobber operand, zap the value data.  */
22535        for (i = 0; i < n_ops; i++)
22536         if (recog_op_alt[i][alt].earlyclobber)
22537 --- a/gcc/sched-deps.c
22538 +++ b/gcc/sched-deps.c
22539 @@ -1473,7 +1473,14 @@ fixup_sched_groups (rtx insn)
22540  
22541    prev_nonnote = prev_nonnote_insn (insn);
22542    if (BLOCK_FOR_INSN (insn) == BLOCK_FOR_INSN (prev_nonnote)
22543 -      && ! sched_insns_conditions_mutex_p (insn, prev_nonnote))
22544 +      /* Modification for AVR32 by RP: Why is this here, this will
22545 +         cause instruction to be without any dependencies which might
22546 +         cause it to be moved anywhere. For the AVR32 we try to keep
22547 +         a group of conditionals together even if they are mutual exclusive.
22548 +      */
22549 +      && (! sched_insns_conditions_mutex_p (insn, prev_nonnote)
22550 +          || GET_CODE (PATTERN (insn)) == COND_EXEC )
22551 +      )
22552      add_dependence (insn, prev_nonnote, REG_DEP_ANTI);
22553  }
22554  \f
22555 @@ -2230,8 +2237,29 @@ sched_analyze_insn (struct deps *deps, r
22556  
22557    if (code == COND_EXEC)
22558      {
22559 +#ifdef IFCVT_ALLOW_MODIFY_TEST_IN_INSN
22560 +      if (IFCVT_ALLOW_MODIFY_TEST_IN_INSN)
22561 +        {
22562 +          /* Check if we have a group og conditional instructions with the same test. 
22563 +             If so we must make sure that they are not scheduled apart in order to
22564 +             avoid unnecesarry tests and if one of the registers in the test is modified
22565 +             in the instruction this is needed to ensure correct code. */
22566 +          if ( prev_nonnote_insn (insn)
22567 +               && INSN_P (prev_nonnote_insn (insn))
22568 +               && GET_CODE (PATTERN (prev_nonnote_insn (insn))) == COND_EXEC 
22569 +               && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 0), XEXP (COND_EXEC_TEST (x), 0))
22570 +               && rtx_equal_p (XEXP(COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn))), 1), XEXP (COND_EXEC_TEST (x), 1))
22571 +               && ( GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == GET_CODE (COND_EXEC_TEST (x))
22572 +                    || GET_CODE (COND_EXEC_TEST (PATTERN (prev_nonnote_insn (insn)))) == reversed_comparison_code (COND_EXEC_TEST (x), insn)))
22573 +            {
22574 +              SCHED_GROUP_P (insn) = 1;
22575 +              //CANT_MOVE (prev_nonnote_insn (insn)) = 1;
22576 +            }
22577 +        }
22578 +#endif      
22579        sched_analyze_2 (deps, COND_EXEC_TEST (x), insn);
22580  
22581 +
22582        /* ??? Should be recording conditions so we reduce the number of
22583          false dependencies.  */
22584        x = COND_EXEC_CODE (x);
22585 --- a/gcc/testsuite/gcc.dg/sibcall-3.c
22586 +++ b/gcc/testsuite/gcc.dg/sibcall-3.c
22587 @@ -5,7 +5,7 @@
22588     Copyright (C) 2002 Free Software Foundation Inc.
22589     Contributed by Hans-Peter Nilsson  <hp@bitrange.com>  */
22590  
22591 -/* { dg-do run { xfail { { arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
22592 +/* { dg-do run { xfail { { arc-*-* avr-*-* avr32-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
22593  /* -mlongcall disables sibcall patterns.  */
22594  /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
22595  /* { dg-options "-O2 -foptimize-sibling-calls" } */
22596 --- a/gcc/testsuite/gcc.dg/sibcall-4.c
22597 +++ b/gcc/testsuite/gcc.dg/sibcall-4.c
22598 @@ -5,7 +5,7 @@
22599     Copyright (C) 2002 Free Software Foundation Inc.
22600     Contributed by Hans-Peter Nilsson  <hp@bitrange.com>  */
22601  
22602 -/* { dg-do run { xfail { { arc-*-* avr-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
22603 +/* { dg-do run { xfail { { arc-*-* avr-*-* avr32-*-* cris-*-* crisv32-*-* h8300-*-* hppa*64*-*-* m32r-*-* m68hc1?-*-* mcore-*-* mn10300-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */
22604  /* -mlongcall disables sibcall patterns.  */
22605  /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */
22606  /* { dg-options "-O2 -foptimize-sibling-calls" } */
22607 --- a/gcc/testsuite/gcc.dg/trampoline-1.c
22608 +++ b/gcc/testsuite/gcc.dg/trampoline-1.c
22609 @@ -47,6 +47,8 @@ void foo (void)
22610  
22611  int main (void)
22612  {
22613 +#ifndef NO_TRAMPOLINES
22614    foo ();
22615 +#endif
22616    return 0;
22617  }
22618 --- a/libgcc/config.host
22619 +++ b/libgcc/config.host
22620 @@ -218,6 +218,13 @@ arm*-wince-pe*)
22621         ;;
22622  arm-*-pe*)
22623         ;;
22624 +avr32-*-linux*)
22625 +       # No need to build crtbeginT.o on uClibc systems. Should probably be
22626 +       # moved to the OS specific section above.
22627 +       extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o"
22628 +       ;;
22629 +avr32-*-*)
22630 +       ;;
22631  avr-*-rtems*)
22632         ;;
22633  avr-*-*)
22634 --- a/libstdc++-v3/config/os/gnu-linux/ctype_base.h
22635 +++ b/libstdc++-v3/config/os/gnu-linux/ctype_base.h
22636 @@ -26,6 +26,8 @@
22637  //
22638  // ISO C++ 14882: 22.1  Locales
22639  //
22640 +#include <features.h>
22641 +#include <ctype.h>
22642    
22643  /** @file ctype_base.h
22644   *  This is an internal header file, included by other library headers.
22645 @@ -40,7 +42,11 @@ _GLIBCXX_BEGIN_NAMESPACE(std)
22646    struct ctype_base
22647    {
22648      // Non-standard typedefs.
22649 +#ifdef __UCLIBC__
22650 +    typedef const __ctype_touplow_t*   __to_type;
22651 +#else
22652      typedef const int*                 __to_type;
22653 +#endif
22654  
22655      // NB: Offsets into ctype<char>::_M_table force a particular size
22656      // on the mask type. Because of this, we don't use an enum.
22657 --- a/libstdc++-v3/include/Makefile.in
22658 +++ b/libstdc++-v3/include/Makefile.in
22659 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22660  build_triplet = @build@
22661  host_triplet = @host@
22662  target_triplet = @target@
22663 +LIBOBJDIR =
22664  DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22665         $(top_srcdir)/fragment.am
22666  subdir = include
22667 --- a/libstdc++-v3/libsupc++/Makefile.in
22668 +++ b/libstdc++-v3/libsupc++/Makefile.in
22669 @@ -38,6 +38,7 @@ POST_UNINSTALL = :
22670  build_triplet = @build@
22671  host_triplet = @host@
22672  target_triplet = @target@
22673 +LIBOBJDIR =
22674  DIST_COMMON = $(glibcxxinstall_HEADERS) $(srcdir)/Makefile.am \
22675         $(srcdir)/Makefile.in $(top_srcdir)/fragment.am
22676  subdir = libsupc++
22677 --- a/libstdc++-v3/Makefile.in
22678 +++ b/libstdc++-v3/Makefile.in
22679 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22680  build_triplet = @build@
22681  host_triplet = @host@
22682  target_triplet = @target@
22683 +LIBOBJDIR =
22684  DIST_COMMON = $(top_srcdir)/fragment.am $(srcdir)/../config.guess \
22685         $(srcdir)/../config.sub README ChangeLog $(srcdir)/Makefile.in \
22686         $(srcdir)/Makefile.am $(top_srcdir)/configure \
22687 --- a/libstdc++-v3/po/Makefile.in
22688 +++ b/libstdc++-v3/po/Makefile.in
22689 @@ -36,6 +36,7 @@ POST_UNINSTALL = :
22690  build_triplet = @build@
22691  host_triplet = @host@
22692  target_triplet = @target@
22693 +LIBOBJDIR =
22694  DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22695         $(top_srcdir)/fragment.am
22696  subdir = po
22697 --- a/libstdc++-v3/src/Makefile.in
22698 +++ b/libstdc++-v3/src/Makefile.in
22699 @@ -37,6 +37,7 @@ POST_UNINSTALL = :
22700  build_triplet = @build@
22701  host_triplet = @host@
22702  target_triplet = @target@
22703 +LIBOBJDIR =
22704  DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
22705         $(top_srcdir)/fragment.am
22706  subdir = src