OSDN Git Service

PR target/14047
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
3    Free Software Foundation, Inc.
4    Contributed by Denis Chertykov (denisc@overta.ru)
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2, or (at your option)
11    any later version.
12    
13    GCC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING.  If not, write to
20    the Free Software Foundation, 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-attr.h"
34 #include "flags.h"
35 #include "reload.h"
36 #include "tree.h"
37 #include "output.h"
38 #include "expr.h"
39 #include "toplev.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "ggc.h"
44 #include "tm_p.h"
45 #include "target.h"
46 #include "target-def.h"
47
48 /* Maximal allowed offset for an address in the LD command */
49 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
50
51 static int avr_naked_function_p (tree);
52 static int interrupt_function_p (tree);
53 static int signal_function_p (tree);
54 static int avr_regs_to_save (HARD_REG_SET *);
55 static int sequent_regs_live (void);
56 static const char *ptrreg_to_str (int);
57 static const char *cond_string (enum rtx_code);
58 static int avr_num_arg_regs (enum machine_mode, tree);
59 static int out_adj_frame_ptr (FILE *, int);
60 static int out_set_stack_ptr (FILE *, int, int);
61 static RTX_CODE compare_condition (rtx insn);
62 static int compare_sign_p (rtx insn);
63 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
64 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
65 const struct attribute_spec avr_attribute_table[];
66 static bool avr_assemble_integer (rtx, unsigned int, int);
67 static void avr_file_start (void);
68 static void avr_file_end (void);
69 static void avr_output_function_prologue (FILE *, HOST_WIDE_INT);
70 static void avr_output_function_epilogue (FILE *, HOST_WIDE_INT);
71 static void avr_unique_section (tree, int);
72 static void avr_insert_attributes (tree, tree *);
73 static unsigned int avr_section_type_flags (tree, const char *, int);
74
75 static void avr_reorg (void);
76 static void avr_asm_out_ctor (rtx, int);
77 static void avr_asm_out_dtor (rtx, int);
78 static int default_rtx_costs (rtx, enum rtx_code, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
82
83 /* Allocate registers from r25 to r8 for parameters for function calls.  */
84 #define FIRST_CUM_REG 26
85
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
88
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
91
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
94
95 /* This holds the last insn address.  */
96 static int last_insn_address = 0;
97
98 /* Commands count in the compiled file */
99 static int commands_in_file;
100
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
103
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
106
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
110
111 /* Size of all jump tables in the current function, in words.  */
112 static int jump_tables_size;
113
114 /* Initial stack value specified by the `-minit-stack=' option */
115 const char *avr_init_stack = "__stack";
116
117 /* Default MCU name */
118 const char *avr_mcu_name = "avr2";
119
120 /* Preprocessor macros to define depending on MCU type.  */
121 const char *avr_base_arch_macro;
122 const char *avr_extra_arch_macro;
123
124 /* More than 8K of program memory: use "call" and "jmp".  */
125 int avr_mega_p = 0;
126
127 /* Enhanced core: use "movw", "mul", ...  */
128 int avr_enhanced_p = 0;
129
130 /* Assembler only.  */
131 int avr_asm_only_p = 0;
132
133 struct base_arch_s {
134   int asm_only;
135   int enhanced;
136   int mega;
137   const char *const macro;
138 };
139
140 static const struct base_arch_s avr_arch_types[] = {
141   { 1, 0, 0, NULL },  /* unknown device specified */
142   { 1, 0, 0, "__AVR_ARCH__=1" },
143   { 0, 0, 0, "__AVR_ARCH__=2" },
144   { 0, 0, 1, "__AVR_ARCH__=3" },
145   { 0, 1, 0, "__AVR_ARCH__=4" },
146   { 0, 1, 1, "__AVR_ARCH__=5" }
147 };
148
149 struct mcu_type_s {
150   const char *const name;
151   int arch;  /* index in avr_arch_types[] */
152   /* Must lie outside user's namespace.  NULL == no macro.  */
153   const char *const macro;
154 };
155
156 /* List of all known AVR MCU types - if updated, it has to be kept
157    in sync in several places (FIXME: is there a better way?):
158     - here
159     - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
160     - t-avr (MULTILIB_MATCHES)
161     - gas/config/tc-avr.c
162     - avr-libc  */
163
164 static const struct mcu_type_s avr_mcu_types[] = {
165     /* Classic, <= 8K.  */
166   { "avr2",      2, NULL },
167   { "at90s2313", 2, "__AVR_AT90S2313__" },
168   { "at90s2323", 2, "__AVR_AT90S2323__" },
169   { "at90s2333", 2, "__AVR_AT90S2333__" },
170   { "at90s2343", 2, "__AVR_AT90S2343__" },
171   { "attiny22",  2, "__AVR_ATtiny22__" },
172   { "attiny26",  2, "__AVR_ATtiny26__" },
173   { "at90s4414", 2, "__AVR_AT90S4414__" },
174   { "at90s4433", 2, "__AVR_AT90S4433__" },
175   { "at90s4434", 2, "__AVR_AT90S4434__" },
176   { "at90s8515", 2, "__AVR_AT90S8515__" },
177   { "at90c8534", 2, "__AVR_AT90C8534__" },
178   { "at90s8535", 2, "__AVR_AT90S8535__" },
179   { "at86rf401", 2, "__AVR_AT86RF401__" },
180     /* Classic, > 8K.  */
181   { "avr3",      3, NULL },
182   { "atmega103", 3, "__AVR_ATmega103__" },
183   { "atmega603", 3, "__AVR_ATmega603__" },
184   { "at43usb320", 3, "__AVR_AT43USB320__" },
185   { "at43usb355", 3, "__AVR_AT43USB355__" },
186   { "at76c711",  3, "__AVR_AT76C711__" },
187     /* Enhanced, <= 8K.  */
188   { "avr4",      4, NULL },
189   { "atmega8",   4, "__AVR_ATmega8__" },
190   { "atmega8515", 4, "__AVR_ATmega8515__" },
191   { "atmega8535", 4, "__AVR_ATmega8535__" },
192     /* Enhanced, > 8K.  */
193   { "avr5",      5, NULL },
194   { "atmega16",  5, "__AVR_ATmega16__" },
195   { "atmega161", 5, "__AVR_ATmega161__" },
196   { "atmega162", 5, "__AVR_ATmega162__" },
197   { "atmega163", 5, "__AVR_ATmega163__" },
198   { "atmega169", 5, "__AVR_ATmega169__" },
199   { "atmega32",  5, "__AVR_ATmega32__" },
200   { "atmega323", 5, "__AVR_ATmega323__" },
201   { "atmega64",  5, "__AVR_ATmega64__" },
202   { "atmega128", 5, "__AVR_ATmega128__" },
203   { "at94k",     5, "__AVR_AT94K__" },
204     /* Assembler only.  */
205   { "avr1",      1, NULL },
206   { "at90s1200", 1, "__AVR_AT90S1200__" },
207   { "attiny11",  1, "__AVR_ATtiny11__" },
208   { "attiny12",  1, "__AVR_ATtiny12__" },
209   { "attiny15",  1, "__AVR_ATtiny15__" },
210   { "attiny28",  1, "__AVR_ATtiny28__" },
211   { NULL,        0, NULL }
212 };
213
214 int avr_case_values_threshold = 30000;
215 \f
216 /* Initialize the GCC target structure.  */
217 #undef TARGET_ASM_ALIGNED_HI_OP
218 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
219 #undef TARGET_ASM_INTEGER
220 #define TARGET_ASM_INTEGER avr_assemble_integer
221 #undef TARGET_ASM_FILE_START
222 #define TARGET_ASM_FILE_START avr_file_start
223 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
224 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
225 #undef TARGET_ASM_FILE_END
226 #define TARGET_ASM_FILE_END avr_file_end
227
228 #undef TARGET_ASM_FUNCTION_PROLOGUE
229 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
230 #undef TARGET_ASM_FUNCTION_EPILOGUE
231 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
232 #undef TARGET_ATTRIBUTE_TABLE
233 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
234 #undef TARGET_ASM_UNIQUE_SECTION
235 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
236 #undef TARGET_INSERT_ATTRIBUTES
237 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
238 #undef TARGET_SECTION_TYPE_FLAGS
239 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
240 #undef TARGET_RTX_COSTS
241 #define TARGET_RTX_COSTS avr_rtx_costs
242 #undef TARGET_ADDRESS_COST
243 #define TARGET_ADDRESS_COST avr_address_cost
244 #undef TARGET_MACHINE_DEPENDENT_REORG
245 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
246
247 #undef TARGET_RETURN_IN_MEMORY
248 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
249
250 #undef TARGET_STRICT_ARGUMENT_NAMING
251 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
252
253 struct gcc_target targetm = TARGET_INITIALIZER;
254 \f
255 void
256 avr_override_options (void)
257 {
258   const struct mcu_type_s *t;
259   const struct base_arch_s *base;
260
261   for (t = avr_mcu_types; t->name; t++)
262     if (strcmp (t->name, avr_mcu_name) == 0)
263       break;
264
265   if (!t->name)
266     {
267       fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
268                avr_mcu_name);
269       for (t = avr_mcu_types; t->name; t++)
270         fprintf (stderr,"   %s\n", t->name);
271     }
272
273   base = &avr_arch_types[t->arch];
274   avr_asm_only_p = base->asm_only;
275   avr_enhanced_p = base->enhanced;
276   avr_mega_p = base->mega;
277   avr_base_arch_macro = base->macro;
278   avr_extra_arch_macro = t->macro;
279
280   if (optimize && !TARGET_NO_TABLEJUMP)
281     avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
282
283   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
284   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
285 }
286
287 /*  return register class from register number.  */
288
289 static const int reg_class_tab[]={
290   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
291   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
292   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
293   GENERAL_REGS, /* r0 - r15 */
294   LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
295   LD_REGS,                      /* r16 - 23 */
296   ADDW_REGS,ADDW_REGS,          /* r24,r25 */
297   POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
298   POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
299   POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
300   STACK_REG,STACK_REG           /* SPL,SPH */
301 };
302
303 /* Return register class for register R.  */
304
305 enum reg_class
306 avr_regno_reg_class (int r)
307 {
308   if (r <= 33)
309     return reg_class_tab[r];
310   return ALL_REGS;
311 }
312
313
314 /* A C expression which defines the machine-dependent operand
315    constraint letters for register classes.  If C is such a
316    letter, the value should be the register class corresponding to
317    it.  Otherwise, the value should be `NO_REGS'.  The register
318    letter `r', corresponding to class `GENERAL_REGS', will not be
319    passed to this macro; you do not need to handle it.  */
320
321 enum reg_class
322 avr_reg_class_from_letter  (int c)
323 {
324   switch (c)
325     {
326     case 't' : return R0_REG;
327     case 'b' : return BASE_POINTER_REGS;
328     case 'e' : return POINTER_REGS;
329     case 'w' : return ADDW_REGS;
330     case 'd' : return LD_REGS;
331     case 'l' : return NO_LD_REGS;
332     case 'a' : return SIMPLE_LD_REGS;
333     case 'x' : return POINTER_X_REGS;
334     case 'y' : return POINTER_Y_REGS;
335     case 'z' : return POINTER_Z_REGS;
336     case 'q' : return STACK_REG;
337     default: break;
338     }
339   return NO_REGS;
340 }
341
342 /* Return nonzero if FUNC is a naked function.  */
343
344 static int
345 avr_naked_function_p (tree func)
346 {
347   tree a;
348
349   if (TREE_CODE (func) != FUNCTION_DECL)
350     abort ();
351   
352   a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
353   return a != NULL_TREE;
354 }
355
356 /* Return nonzero if FUNC is an interrupt function as specified
357    by the "interrupt" attribute.  */
358
359 static int
360 interrupt_function_p (tree func)
361 {
362   tree a;
363
364   if (TREE_CODE (func) != FUNCTION_DECL)
365     return 0;
366
367   a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
368   return a != NULL_TREE;
369 }
370
371 /* Return nonzero if FUNC is a signal function as specified
372    by the "signal" attribute.  */
373
374 static int
375 signal_function_p (tree func)
376 {
377   tree a;
378
379   if (TREE_CODE (func) != FUNCTION_DECL)
380     return 0;
381
382   a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
383   return a != NULL_TREE;
384 }
385
386 /* Return the number of hard registers to push/pop in the prologue/epilogue
387    of the current function, and optionally store these registers in SET.  */
388
389 static int
390 avr_regs_to_save (HARD_REG_SET *set)
391 {
392   int reg, count;
393   int int_or_sig_p = (interrupt_function_p (current_function_decl)
394                       || signal_function_p (current_function_decl));
395   int leaf_func_p = leaf_function_p ();
396
397   if (set)
398     CLEAR_HARD_REG_SET (*set);
399   count = 0;
400
401   /* No need to save any registers if the function never returns.  */
402   if (TREE_THIS_VOLATILE (current_function_decl))
403     return 0;
404
405   for (reg = 0; reg < 32; reg++)
406     {
407       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
408          any global register variables.  */
409       if (fixed_regs[reg])
410         continue;
411
412       if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
413           || (regs_ever_live[reg]
414               && (int_or_sig_p || !call_used_regs[reg])
415               && !(frame_pointer_needed
416                    && (reg == REG_Y || reg == (REG_Y+1)))))
417         {
418           if (set)
419             SET_HARD_REG_BIT (*set, reg);
420           count++;
421         }
422     }
423   return count;
424 }
425
426 /* Compute offset between arg_pointer and frame_pointer.  */
427
428 int
429 initial_elimination_offset (int from, int to)
430 {
431   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
432     return 0;
433   else
434     {
435       int offset = frame_pointer_needed ? 2 : 0;
436
437       offset += avr_regs_to_save (NULL);
438       return get_frame_size () + 2 + 1 + offset;
439     }
440 }
441
442 /* Return 1 if the function epilogue is just a single "ret".  */
443
444 int
445 avr_simple_epilogue (void)
446 {
447   return (! frame_pointer_needed
448           && get_frame_size () == 0
449           && avr_regs_to_save (NULL) == 0
450           && ! interrupt_function_p (current_function_decl)
451           && ! signal_function_p (current_function_decl)
452           && ! avr_naked_function_p (current_function_decl)
453           && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
454           && ! TREE_THIS_VOLATILE (current_function_decl));
455 }
456
457 /* This function checks sequence of live registers.  */
458
459 static int
460 sequent_regs_live (void)
461 {
462   int reg;
463   int live_seq=0;
464   int cur_seq=0;
465
466   for (reg = 0; reg < 18; ++reg)
467     {
468       if (!call_used_regs[reg])
469         {
470           if (regs_ever_live[reg])
471             {
472               ++live_seq;
473               ++cur_seq;
474             }
475           else
476             cur_seq = 0;
477         }
478     }
479
480   if (!frame_pointer_needed)
481     {
482       if (regs_ever_live[REG_Y])
483         {
484           ++live_seq;
485           ++cur_seq;
486         }
487       else
488         cur_seq = 0;
489
490       if (regs_ever_live[REG_Y+1])
491         {
492           ++live_seq;
493           ++cur_seq;
494         }
495       else
496         cur_seq = 0;
497     }
498   else
499     {
500       cur_seq += 2;
501       live_seq += 2;
502     }
503   return (cur_seq == live_seq) ? live_seq : 0;
504 }
505
506
507 /* Output to FILE the asm instructions to adjust the frame pointer by
508    ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
509    (epilogue).  Returns the number of instructions generated.  */
510
511 static int
512 out_adj_frame_ptr (FILE *file, int adj)
513 {
514   int size = 0;
515
516   if (adj)
517     {
518       if (TARGET_TINY_STACK)
519         {
520           if (adj < -63 || adj > 63)
521             warning ("large frame pointer change (%d) with -mtiny-stack", adj);
522
523           /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
524              over "sbiw" (2 cycles, same size).  */
525
526           fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
527           size++;
528         }
529       else if (adj < -63 || adj > 63)
530         {
531           fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
532                           AS2 (sbci, r29, hi8(%d)) CR_TAB),
533                    adj, adj);
534           size += 2;
535         }
536       else if (adj < 0)
537         {
538           fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
539           size++;
540         }
541       else
542         {
543           fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
544           size++;
545         }
546     }
547   return size;
548 }
549
550
551 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
552    handling various cases of interrupt enable flag state BEFORE and AFTER
553    (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
554    Returns the number of instructions generated.  */
555
556 static int
557 out_set_stack_ptr (FILE *file, int before, int after)
558 {
559   int do_sph, do_cli, do_save, do_sei, lock_sph, size;
560
561   /* The logic here is so that -mno-interrupts actually means
562      "it is safe to write SPH in one instruction, then SPL in the
563      next instruction, without disabling interrupts first".
564      The after != -1 case (interrupt/signal) is not affected.  */
565
566   do_sph = !TARGET_TINY_STACK;
567   lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
568   do_cli = (before != 0 && (after == 0 || lock_sph));
569   do_save = (do_cli && before == -1 && after == -1);
570   do_sei = ((do_cli || before != 1) && after == 1);
571   size = 1;
572
573   if (do_save)
574     {
575       fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
576       size++;
577     }
578
579   if (do_cli)
580     {
581       fprintf (file, "cli" CR_TAB);
582       size++;
583     }
584
585   /* Do SPH first - maybe this will disable interrupts for one instruction
586      someday (a suggestion has been sent to avr@atmel.com for consideration
587      in future devices - that would make -mno-interrupts always safe).  */
588   if (do_sph)
589     {
590       fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
591       size++;
592     }
593
594   /* Set/restore the I flag now - interrupts will be really enabled only
595      after the next instruction.  This is not clearly documented, but
596      believed to be true for all AVR devices.  */
597   if (do_save)
598     {
599       fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
600       size++;
601     }
602   else if (do_sei)
603     {
604       fprintf (file, "sei" CR_TAB);
605       size++;
606     }
607
608   fprintf (file, AS2 (out, __SP_L__, r28) "\n");
609
610   return size;
611 }
612
613
614 /* Output function prologue.  */
615
616 static void
617 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
618 {
619   int reg;
620   int interrupt_func_p;
621   int signal_func_p;
622   int main_p;
623   int live_seq;
624   int minimize;
625
626   last_insn_address = 0;
627   jump_tables_size = 0;
628   prologue_size = 0;
629   fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
630            size);
631
632   if (avr_naked_function_p (current_function_decl))
633     {
634       fputs ("/* prologue: naked */\n", file);
635       goto out;
636     }
637
638   interrupt_func_p = interrupt_function_p (current_function_decl);
639   signal_func_p = signal_function_p (current_function_decl);
640   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
641   live_seq = sequent_regs_live ();
642   minimize = (TARGET_CALL_PROLOGUES
643               && !interrupt_func_p && !signal_func_p && live_seq);
644
645   if (interrupt_func_p)
646     {
647       fprintf (file,"\tsei\n");
648       ++prologue_size;
649     }
650   if (interrupt_func_p || signal_func_p)
651     {
652       fprintf (file, "\t"
653                AS1 (push,__zero_reg__)   CR_TAB
654                AS1 (push,__tmp_reg__)    CR_TAB
655                AS2 (in,__tmp_reg__,__SREG__) CR_TAB
656                AS1 (push,__tmp_reg__)    CR_TAB
657                AS1 (clr,__zero_reg__)    "\n");
658       prologue_size += 5;
659     }
660   if (main_p)
661     {
662       fprintf (file, ("\t" 
663                       AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
664                       AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
665                       AS2 (out,__SP_H__,r29)     CR_TAB
666                       AS2 (out,__SP_L__,r28) "\n"),
667                avr_init_stack, size, avr_init_stack, size);
668       
669       prologue_size += 4;
670     }
671   else if (minimize && (frame_pointer_needed || live_seq > 6)) 
672     {
673       const char *cfun_name = current_function_name ();
674       fprintf (file, ("\t"
675                       AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
676                       AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
677
678       fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
679                       AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB),
680                cfun_name, cfun_name);
681       
682       prologue_size += 4;
683       
684       if (AVR_MEGA)
685         {
686           fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
687                    (18 - live_seq) * 2);
688           prologue_size += 2;
689         }
690       else
691         {
692           fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
693                    (18 - live_seq) * 2);
694           ++prologue_size;
695         }
696       fprintf (file, ".L_%s_body:\n", cfun_name);
697     }
698   else
699     {
700       HARD_REG_SET set;
701
702       prologue_size += avr_regs_to_save (&set);
703       for (reg = 0; reg < 32; ++reg)
704         {
705           if (TEST_HARD_REG_BIT (set, reg))
706             {
707               fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
708             }
709         }
710       if (frame_pointer_needed)
711         {
712           fprintf (file, "\t"
713                    AS1 (push,r28) CR_TAB
714                    AS1 (push,r29) CR_TAB
715                    AS2 (in,r28,__SP_L__) CR_TAB
716                    AS2 (in,r29,__SP_H__) "\n");
717           prologue_size += 4;
718           if (size)
719             {
720               fputs ("\t", file);
721               prologue_size += out_adj_frame_ptr (file, size);
722
723               if (interrupt_func_p)
724                 {
725                   prologue_size += out_set_stack_ptr (file, 1, 1);
726                 }
727               else if (signal_func_p)
728                 {
729                   prologue_size += out_set_stack_ptr (file, 0, 0);
730                 }
731               else
732                 {
733                   prologue_size += out_set_stack_ptr (file, -1, -1);
734                 }
735             }
736         }
737     }
738
739  out:
740   fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
741 }
742
743 /* Output function epilogue.  */
744
745 static void
746 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
747 {
748   int reg;
749   int interrupt_func_p;
750   int signal_func_p;
751   int main_p;
752   int function_size;
753   int live_seq;
754   int minimize;
755   rtx last = get_last_nonnote_insn ();
756
757   function_size = jump_tables_size;
758   if (last)
759     {
760       rtx first = get_first_nonnote_insn ();
761       function_size += (INSN_ADDRESSES (INSN_UID (last)) -
762                         INSN_ADDRESSES (INSN_UID (first)));
763       function_size += get_attr_length (last);
764     }
765
766   fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
767   epilogue_size = 0;
768
769   if (avr_naked_function_p (current_function_decl))
770     {
771       fputs ("/* epilogue: naked */\n", file);
772       goto out;
773     }
774
775   if (last && GET_CODE (last) == BARRIER)
776     {
777       fputs ("/* epilogue: noreturn */\n", file);
778       goto out;
779     }
780
781   interrupt_func_p = interrupt_function_p (current_function_decl);
782   signal_func_p = signal_function_p (current_function_decl);
783   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
784   live_seq = sequent_regs_live ();
785   minimize = (TARGET_CALL_PROLOGUES
786               && !interrupt_func_p && !signal_func_p && live_seq);
787   
788   if (main_p)
789     {
790       /* Return value from main() is already in the correct registers
791          (r25:r24) as the exit() argument.  */
792       if (AVR_MEGA)
793         {
794           fputs ("\t" AS1 (jmp,exit) "\n", file);
795           epilogue_size += 2;
796         }
797       else
798         {
799           fputs ("\t" AS1 (rjmp,exit) "\n", file);
800           ++epilogue_size;
801         }
802     }
803   else if (minimize && (frame_pointer_needed || live_seq > 4))
804     {
805       fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
806       ++epilogue_size;
807       if (frame_pointer_needed)
808         {
809           epilogue_size += out_adj_frame_ptr (file, -size);
810         }
811       else
812         {
813           fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
814                           AS2 (in , r29, __SP_H__) CR_TAB));
815           epilogue_size += 2;
816         }
817       
818       if (AVR_MEGA)
819         {
820           fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
821                    (18 - live_seq) * 2);
822           epilogue_size += 2;
823         }
824       else
825         {
826           fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
827                    (18 - live_seq) * 2);
828           ++epilogue_size;
829         }
830     }
831   else
832     {
833       HARD_REG_SET set;
834
835       if (frame_pointer_needed)
836         {
837           if (size)
838             {
839               fputs ("\t", file);
840               epilogue_size += out_adj_frame_ptr (file, -size);
841
842               if (interrupt_func_p || signal_func_p)
843                 {
844                   epilogue_size += out_set_stack_ptr (file, -1, 0);
845                 }
846               else
847                 {
848                   epilogue_size += out_set_stack_ptr (file, -1, -1);
849                 }
850             }
851           fprintf (file, "\t"
852                    AS1 (pop,r29) CR_TAB
853                    AS1 (pop,r28) "\n");
854           epilogue_size += 2;
855         }
856
857       epilogue_size += avr_regs_to_save (&set);
858       for (reg = 31; reg >= 0; --reg)
859         {
860           if (TEST_HARD_REG_BIT (set, reg))
861             {
862               fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
863             }
864         }
865
866       if (interrupt_func_p || signal_func_p)
867         {
868           fprintf (file, "\t"
869                    AS1 (pop,__tmp_reg__)      CR_TAB
870                    AS2 (out,__SREG__,__tmp_reg__) CR_TAB
871                    AS1 (pop,__tmp_reg__)      CR_TAB
872                    AS1 (pop,__zero_reg__)     "\n");
873           epilogue_size += 4;
874           fprintf (file, "\treti\n");
875         }
876       else
877         fprintf (file, "\tret\n");
878       ++epilogue_size;
879     }
880
881  out:
882   fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
883   fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
884            prologue_size + function_size + epilogue_size, function_size);
885   commands_in_file += prologue_size + function_size + epilogue_size;
886   commands_in_prologues += prologue_size;
887   commands_in_epilogues += epilogue_size;
888 }
889
890
891 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
892    machine for a memory operand of mode MODE.  */
893
894 int
895 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
896 {
897   enum reg_class r = NO_REGS;
898   
899   if (TARGET_ALL_DEBUG)
900     {
901       fprintf (stderr, "mode: (%s) %s %s %s %s:",
902                GET_MODE_NAME(mode),
903                strict ? "(strict)": "",
904                reload_completed ? "(reload_completed)": "",
905                reload_in_progress ? "(reload_in_progress)": "",
906                reg_renumber ? "(reg_renumber)" : "");
907       if (GET_CODE (x) == PLUS
908           && REG_P (XEXP (x, 0))
909           && GET_CODE (XEXP (x, 1)) == CONST_INT
910           && INTVAL (XEXP (x, 1)) >= 0
911           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
912           && reg_renumber
913           )
914         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
915                  true_regnum (XEXP (x, 0)));
916       debug_rtx (x);
917     }
918   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
919                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
920     r = POINTER_REGS;
921   else if (CONSTANT_ADDRESS_P (x))
922     r = ALL_REGS;
923   else if (GET_CODE (x) == PLUS
924            && REG_P (XEXP (x, 0))
925            && GET_CODE (XEXP (x, 1)) == CONST_INT
926            && INTVAL (XEXP (x, 1)) >= 0)
927     {
928       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
929       if (fit)
930         {
931           if (! strict
932               || REGNO (XEXP (x,0)) == REG_Y
933               || REGNO (XEXP (x,0)) == REG_Z)
934             r = BASE_POINTER_REGS;
935           if (XEXP (x,0) == frame_pointer_rtx
936               || XEXP (x,0) == arg_pointer_rtx)
937             r = BASE_POINTER_REGS;
938         }
939       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
940         r = POINTER_Y_REGS;
941     }
942   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
943            && REG_P (XEXP (x, 0))
944            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
945                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
946     {
947       r = POINTER_REGS;
948     }
949   if (TARGET_ALL_DEBUG)
950     {
951       fprintf (stderr, "   ret = %c\n", r);
952     }
953   return r == NO_REGS ? 0 : (int)r;
954 }
955
956 /* Attempts to replace X with a valid
957    memory address for an operand of mode MODE  */
958
959 rtx
960 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
961 {
962   x = oldx;
963   if (TARGET_ALL_DEBUG)
964     {
965       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
966       debug_rtx (oldx);
967     }
968   
969   if (GET_CODE (oldx) == PLUS
970       && REG_P (XEXP (oldx,0)))
971     {
972       if (REG_P (XEXP (oldx,1)))
973         x = force_reg (GET_MODE (oldx), oldx);
974       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
975         {
976           int offs = INTVAL (XEXP (oldx,1));
977           if (frame_pointer_rtx != XEXP (oldx,0))
978             if (offs > MAX_LD_OFFSET (mode))
979               {
980                 if (TARGET_ALL_DEBUG)
981                   fprintf (stderr, "force_reg (big offset)\n");
982                 x = force_reg (GET_MODE (oldx), oldx);
983               }
984         }
985     }
986   return x;
987 }
988
989
990 /* Return a pointer register name as a string.  */
991
992 static const char *
993 ptrreg_to_str (int regno)
994 {
995   switch (regno)
996     {
997     case REG_X: return "X";
998     case REG_Y: return "Y";
999     case REG_Z: return "Z";
1000     default:
1001       abort ();
1002     }
1003   return NULL;
1004 }
1005
1006 /* Return the condition name as a string.
1007    Used in conditional jump constructing  */
1008
1009 static const char *
1010 cond_string (enum rtx_code code)
1011 {
1012   switch (code)
1013     {
1014     case NE:
1015       return "ne";
1016     case EQ:
1017       return "eq";
1018     case GE:
1019       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1020         return "pl";
1021       else
1022         return "ge";
1023     case LT:
1024       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1025         return "mi";
1026       else
1027         return "lt";
1028     case GEU:
1029       return "sh";
1030     case LTU:
1031       return "lo";
1032     default:
1033       abort ();
1034     }
1035 }
1036
1037 /* Output ADDR to FILE as address.  */
1038
1039 void
1040 print_operand_address (FILE *file, rtx addr)
1041 {
1042   switch (GET_CODE (addr))
1043     {
1044     case REG:
1045       fprintf (file, ptrreg_to_str (REGNO (addr)));
1046       break;
1047
1048     case PRE_DEC:
1049       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1050       break;
1051
1052     case POST_INC:
1053       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1054       break;
1055
1056     default:
1057       if (CONSTANT_ADDRESS_P (addr)
1058           && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1059               || GET_CODE (addr) == LABEL_REF))
1060         {
1061           fprintf (file, "pm(");
1062           output_addr_const (file,addr);
1063           fprintf (file ,")");
1064         }
1065       else
1066         output_addr_const (file, addr);
1067     }
1068 }
1069
1070
1071 /* Output X as assembler operand to file FILE.  */
1072      
1073 void
1074 print_operand (FILE *file, rtx x, int code)
1075 {
1076   int abcd = 0;
1077
1078   if (code >= 'A' && code <= 'D')
1079     abcd = code - 'A';
1080
1081   if (code == '~')
1082     {
1083       if (!AVR_MEGA)
1084         fputc ('r', file);
1085     }
1086   else if (REG_P (x))
1087     {
1088       if (x == zero_reg_rtx)
1089         fprintf (file, "__zero_reg__");
1090       else
1091         fprintf (file, reg_names[true_regnum (x) + abcd]);
1092     }
1093   else if (GET_CODE (x) == CONST_INT)
1094     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1095   else if (GET_CODE (x) == MEM)
1096     {
1097       rtx addr = XEXP (x,0);
1098
1099       if (CONSTANT_P (addr) && abcd)
1100         {
1101           fputc ('(', file);
1102           output_address (addr);
1103           fprintf (file, ")+%d", abcd);
1104         }
1105       else if (code == 'o')
1106         {
1107           if (GET_CODE (addr) != PLUS)
1108             fatal_insn ("bad address, not (reg+disp):", addr);
1109
1110           print_operand (file, XEXP (addr, 1), 0);
1111         }
1112       else if (GET_CODE (addr) == PLUS)
1113         {
1114           print_operand_address (file, XEXP (addr,0));
1115           if (REGNO (XEXP (addr, 0)) == REG_X)
1116             fatal_insn ("internal compiler error.  Bad address:"
1117                         ,addr);
1118           fputc ('+', file);
1119           print_operand (file, XEXP (addr,1), code);
1120         }
1121       else
1122         print_operand_address (file, addr);
1123     }
1124   else if (GET_CODE (x) == CONST_DOUBLE)
1125     {
1126       long val;
1127       REAL_VALUE_TYPE rv;
1128       if (GET_MODE (x) != SFmode)
1129         fatal_insn ("internal compiler error.  Unknown mode:", x);
1130       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1131       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1132       fprintf (file, "0x%lx", val);
1133     }
1134   else if (code == 'j')
1135     fputs (cond_string (GET_CODE (x)), file);
1136   else if (code == 'k')
1137     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1138   else
1139     print_operand_address (file, x);
1140 }
1141
1142 /* Recognize operand OP of mode MODE used in call instructions.  */
1143
1144 int
1145 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1146 {
1147   if (GET_CODE (op) == MEM)
1148     {
1149       rtx inside = XEXP (op, 0);
1150       if (register_operand (inside, Pmode))
1151         return 1;
1152       if (CONSTANT_ADDRESS_P (inside))
1153         return 1;
1154     }
1155   return 0;
1156 }
1157
1158 /* Update the condition code in the INSN.  */
1159
1160 void
1161 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1162 {
1163   rtx set;
1164   
1165   switch (get_attr_cc (insn))
1166     {
1167     case CC_NONE:
1168       /* Insn does not affect CC at all.  */
1169       break;
1170
1171     case CC_SET_N:
1172       CC_STATUS_INIT;
1173       break;
1174
1175     case CC_SET_ZN:
1176       set = single_set (insn);
1177       CC_STATUS_INIT;
1178       if (set)
1179         {
1180           cc_status.flags |= CC_NO_OVERFLOW;
1181           cc_status.value1 = SET_DEST (set);
1182         }
1183       break;
1184
1185     case CC_SET_CZN:
1186       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1187          The V flag may or may not be known but that's ok because
1188          alter_cond will change tests to use EQ/NE.  */
1189       set = single_set (insn);
1190       CC_STATUS_INIT;
1191       if (set)
1192         {
1193           cc_status.value1 = SET_DEST (set);
1194           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1195         }
1196       break;
1197
1198     case CC_COMPARE:
1199       set = single_set (insn);
1200       CC_STATUS_INIT;
1201       if (set)
1202         cc_status.value1 = SET_SRC (set);
1203       break;
1204       
1205     case CC_CLOBBER:
1206       /* Insn doesn't leave CC in a usable state.  */
1207       CC_STATUS_INIT;
1208
1209       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1210       set = single_set (insn);
1211       if (set)
1212         {
1213           rtx src = SET_SRC (set);
1214           
1215           if (GET_CODE (src) == ASHIFTRT
1216               && GET_MODE (src) == QImode)
1217             {
1218               rtx x = XEXP (src, 1);
1219
1220               if (GET_CODE (x) == CONST_INT
1221                   && INTVAL (x) != 6)
1222                 {
1223                   cc_status.value1 = SET_DEST (set);
1224                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1225                 }
1226             }
1227         }
1228       break;
1229     }
1230 }
1231
1232 /* Return maximum number of consecutive registers of
1233    class CLASS needed to hold a value of mode MODE.  */
1234
1235 int
1236 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1237 {
1238   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1239 }
1240
1241 /* Choose mode for jump insn:
1242    1 - relative jump in range -63 <= x <= 62 ;
1243    2 - relative jump in range -2046 <= x <= 2045 ;
1244    3 - absolute jump (only for ATmega[16]03).  */
1245
1246 int
1247 avr_jump_mode (rtx x, rtx insn)
1248 {
1249   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1250                                             ? XEXP (x, 0) : x));
1251   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1252   int jump_distance = cur_addr - dest_addr;
1253   
1254   if (-63 <= jump_distance && jump_distance <= 62)
1255     return 1;
1256   else if (-2046 <= jump_distance && jump_distance <= 2045)
1257     return 2;
1258   else if (AVR_MEGA)
1259     return 3;
1260   
1261   return 2;
1262 }
1263
1264 /* return an AVR condition jump commands.
1265    X is a comparison RTX.
1266    LEN is a number returned by avr_jump_mode function.
1267    if REVERSE nonzero then condition code in X must be reversed.  */
1268
1269 const char *
1270 ret_cond_branch (rtx x, int len, int reverse)
1271 {
1272   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1273   
1274   switch (cond)
1275     {
1276     case GT:
1277       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1278         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1279                             AS1 (brpl,%0)) :
1280                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1281                             AS1 (brmi,.+2) CR_TAB
1282                             AS1 (rjmp,%0)) :
1283                 (AS1 (breq,.+6) CR_TAB
1284                  AS1 (brmi,.+4) CR_TAB
1285                  AS1 (jmp,%0)));
1286           
1287       else
1288         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1289                             AS1 (brge,%0)) :
1290                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1291                             AS1 (brlt,.+2) CR_TAB
1292                             AS1 (rjmp,%0)) :
1293                 (AS1 (breq,.+6) CR_TAB
1294                  AS1 (brlt,.+4) CR_TAB
1295                  AS1 (jmp,%0)));
1296     case GTU:
1297       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1298                           AS1 (brsh,%0)) :
1299               len == 2 ? (AS1 (breq,.+4) CR_TAB
1300                           AS1 (brlo,.+2) CR_TAB
1301                           AS1 (rjmp,%0)) :
1302               (AS1 (breq,.+6) CR_TAB
1303                AS1 (brlo,.+4) CR_TAB
1304                AS1 (jmp,%0)));
1305     case LE:
1306       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1307         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1308                             AS1 (brmi,%0)) :
1309                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1310                             AS1 (brpl,.+2) CR_TAB
1311                             AS1 (rjmp,%0)) :
1312                 (AS1 (breq,.+2) CR_TAB
1313                  AS1 (brpl,.+4) CR_TAB
1314                  AS1 (jmp,%0)));
1315       else
1316         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1317                             AS1 (brlt,%0)) :
1318                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1319                             AS1 (brge,.+2) CR_TAB
1320                             AS1 (rjmp,%0)) :
1321                 (AS1 (breq,.+2) CR_TAB
1322                  AS1 (brge,.+4) CR_TAB
1323                  AS1 (jmp,%0)));
1324     case LEU:
1325       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1326                           AS1 (brlo,%0)) :
1327               len == 2 ? (AS1 (breq,.+2) CR_TAB
1328                           AS1 (brsh,.+2) CR_TAB
1329                           AS1 (rjmp,%0)) :
1330               (AS1 (breq,.+2) CR_TAB
1331                AS1 (brsh,.+4) CR_TAB
1332                AS1 (jmp,%0)));
1333     default:
1334       if (reverse)
1335         {
1336           switch (len)
1337             {
1338             case 1:
1339               return AS1 (br%k1,%0);
1340             case 2:
1341               return (AS1 (br%j1,.+2) CR_TAB
1342                       AS1 (rjmp,%0));
1343             default:
1344               return (AS1 (br%j1,.+4) CR_TAB
1345                       AS1 (jmp,%0));
1346             }
1347         }
1348         else
1349           {
1350             switch (len)
1351               {
1352               case 1:
1353                 return AS1 (br%j1,%0);
1354               case 2:
1355                 return (AS1 (br%k1,.+2) CR_TAB
1356                         AS1 (rjmp,%0));
1357               default:
1358                 return (AS1 (br%k1,.+4) CR_TAB
1359                         AS1 (jmp,%0));
1360               }
1361           }
1362     }
1363   return "";
1364 }
1365
1366 /* Predicate function for immediate operand which fits to byte (8bit) */
1367
1368 int
1369 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1370 {
1371   return (GET_CODE (op) == CONST_INT
1372           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1373 }
1374
1375 /* Output all insn addresses and their sizes into the assembly language
1376    output file.  This is helpful for debugging whether the length attributes
1377    in the md file are correct.
1378    Output insn cost for next insn.  */
1379
1380 void
1381 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1382                     int num_operands ATTRIBUTE_UNUSED)
1383 {
1384   int uid = INSN_UID (insn);
1385
1386   if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1387     {
1388       fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1389                INSN_ADDRESSES (uid),
1390                INSN_ADDRESSES (uid) - last_insn_address,
1391                rtx_cost (PATTERN (insn), INSN));
1392     }
1393   last_insn_address = INSN_ADDRESSES (uid);
1394 }
1395
1396 /* Return 0 if undefined, 1 if always true or always false.  */
1397
1398 int
1399 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1400 {
1401   unsigned int max = (mode == QImode ? 0xff :
1402                       mode == HImode ? 0xffff :
1403                       mode == SImode ? 0xffffffff : 0);
1404   if (max && operator && GET_CODE (x) == CONST_INT)
1405     {
1406       if (unsigned_condition (operator) != operator)
1407         max >>= 1;
1408
1409       if (max != (INTVAL (x) & max)
1410           && INTVAL (x) != 0xff)
1411         return 1;
1412     }
1413   return 0;
1414 }
1415
1416
1417 /* Returns nonzero if REGNO is the number of a hard
1418    register in which function arguments are sometimes passed.  */
1419
1420 int
1421 function_arg_regno_p(int r)
1422 {
1423   return (r >= 8 && r <= 25);
1424 }
1425
1426 /* Initializing the variable cum for the state at the beginning
1427    of the argument list.  */
1428
1429 void
1430 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1431                       tree fndecl ATTRIBUTE_UNUSED)
1432 {
1433   cum->nregs = 18;
1434   cum->regno = FIRST_CUM_REG;
1435   if (!libname && fntype)
1436     {
1437       int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1438                     && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1439                         != void_type_node));
1440       if (stdarg)
1441         cum->nregs = 0;
1442     }
1443 }
1444
1445 /* Returns the number of registers to allocate for a function argument.  */
1446
1447 static int
1448 avr_num_arg_regs (enum machine_mode mode, tree type)
1449 {
1450   int size;
1451
1452   if (mode == BLKmode)
1453     size = int_size_in_bytes (type);
1454   else
1455     size = GET_MODE_SIZE (mode);
1456
1457   /* Align all function arguments to start in even-numbered registers.
1458      Odd-sized arguments leave holes above them.  */
1459
1460   return (size + 1) & ~1;
1461 }
1462
1463 /* Controls whether a function argument is passed
1464    in a register, and which register.  */
1465
1466 rtx
1467 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1468               int named ATTRIBUTE_UNUSED)
1469 {
1470   int bytes = avr_num_arg_regs (mode, type);
1471
1472   if (cum->nregs && bytes <= cum->nregs)
1473     return gen_rtx_REG (mode, cum->regno - bytes);
1474
1475   return NULL_RTX;
1476 }
1477
1478 /* Update the summarizer variable CUM to advance past an argument
1479    in the argument list.  */
1480    
1481 void
1482 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1483                       int named ATTRIBUTE_UNUSED)
1484 {
1485   int bytes = avr_num_arg_regs (mode, type);
1486
1487   cum->nregs -= bytes;
1488   cum->regno -= bytes;
1489
1490   if (cum->nregs <= 0)
1491     {
1492       cum->nregs = 0;
1493       cum->regno = FIRST_CUM_REG;
1494     }
1495 }
1496
1497 /***********************************************************************
1498   Functions for outputting various mov's for a various modes
1499 ************************************************************************/
1500 const char *
1501 output_movqi (rtx insn, rtx operands[], int *l)
1502 {
1503   int dummy;
1504   rtx dest = operands[0];
1505   rtx src = operands[1];
1506   int *real_l = l;
1507   
1508   if (!l)
1509     l = &dummy;
1510
1511   *l = 1;
1512   
1513   if (register_operand (dest, QImode))
1514     {
1515       if (register_operand (src, QImode)) /* mov r,r */
1516         {
1517           if (test_hard_reg_class (STACK_REG, dest))
1518             return AS2 (out,%0,%1);
1519           else if (test_hard_reg_class (STACK_REG, src))
1520             return AS2 (in,%0,%1);
1521           
1522           return AS2 (mov,%0,%1);
1523         }
1524       else if (CONSTANT_P (src))
1525         {
1526           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1527             return AS2 (ldi,%0,lo8(%1));
1528           
1529           if (GET_CODE (src) == CONST_INT)
1530             {
1531               if (src == const0_rtx) /* mov r,L */
1532                 return AS1 (clr,%0);
1533               else if (src == const1_rtx)
1534                 {
1535                   *l = 2;
1536                   return (AS1 (clr,%0) CR_TAB
1537                           AS1 (inc,%0));
1538                 }
1539               else if (src == constm1_rtx)
1540                 {
1541                   /* Immediate constants -1 to any register */
1542                   *l = 2;
1543                   return (AS1 (clr,%0) CR_TAB
1544                           AS1 (dec,%0));
1545                 }
1546               else
1547                 {
1548                   int bit_nr = exact_log2 (INTVAL (src));
1549
1550                   if (bit_nr >= 0)
1551                     {
1552                       *l = 3;
1553                       if (!real_l)
1554                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1555                                           "set"), operands);
1556                       if (!real_l)
1557                         avr_output_bld (operands, bit_nr);
1558
1559                       return "";
1560                     }
1561                 }
1562             }
1563           
1564           /* Last resort, larger than loading from memory.  */
1565           *l = 4;
1566           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1567                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1568                   AS2 (mov,%0,r31)          CR_TAB
1569                   AS2 (mov,r31,__tmp_reg__));
1570         }
1571       else if (GET_CODE (src) == MEM)
1572         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1573     }
1574   else if (GET_CODE (dest) == MEM)
1575     {
1576       const char *template;
1577
1578       if (src == const0_rtx)
1579         operands[1] = zero_reg_rtx;
1580
1581       template = out_movqi_mr_r (insn, operands, real_l);
1582
1583       if (!real_l)
1584         output_asm_insn (template, operands);
1585
1586       operands[1] = src;
1587     }
1588   return "";
1589 }
1590
1591
1592 const char *
1593 output_movhi (rtx insn, rtx operands[], int *l)
1594 {
1595   int dummy;
1596   rtx dest = operands[0];
1597   rtx src = operands[1];
1598   int *real_l = l;
1599   
1600   if (!l)
1601     l = &dummy;
1602   
1603   if (register_operand (dest, HImode))
1604     {
1605       if (register_operand (src, HImode)) /* mov r,r */
1606         {
1607           if (test_hard_reg_class (STACK_REG, dest))
1608             {
1609               if (TARGET_TINY_STACK)
1610                 {
1611                   *l = 1;
1612                   return AS2 (out,__SP_L__,%A1);
1613                 }
1614               else if (TARGET_NO_INTERRUPTS)
1615                 {
1616                   *l = 2;
1617                   return (AS2 (out,__SP_H__,%B1) CR_TAB
1618                           AS2 (out,__SP_L__,%A1));
1619                 }
1620
1621               *l = 5;
1622               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
1623                       "cli"                          CR_TAB
1624                       AS2 (out,__SP_H__,%B1)         CR_TAB
1625                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1626                       AS2 (out,__SP_L__,%A1));
1627             }
1628           else if (test_hard_reg_class (STACK_REG, src))
1629             {
1630               *l = 2;   
1631               return (AS2 (in,%A0,__SP_L__) CR_TAB
1632                       AS2 (in,%B0,__SP_H__));
1633             }
1634
1635           if (AVR_ENHANCED)
1636             {
1637               *l = 1;
1638               return (AS2 (movw,%0,%1));
1639             }
1640
1641           if (true_regnum (dest) > true_regnum (src))
1642             {
1643               *l = 2;
1644               return (AS2 (mov,%B0,%B1) CR_TAB
1645                       AS2 (mov,%A0,%A1));
1646             }
1647           else
1648             {
1649               *l = 2;
1650               return (AS2 (mov,%A0,%A1) CR_TAB
1651                       AS2 (mov,%B0,%B1));
1652             }
1653         }
1654       else if (CONSTANT_P (src))
1655         {
1656           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1657             {
1658               *l = 2;
1659               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1660                       AS2 (ldi,%B0,hi8(%1)));
1661             }
1662           
1663           if (GET_CODE (src) == CONST_INT)
1664             {
1665               if (src == const0_rtx) /* mov r,L */
1666                 {
1667                   *l = 2;
1668                   return (AS1 (clr,%A0) CR_TAB
1669                           AS1 (clr,%B0));
1670                 }
1671               else if (src == const1_rtx)
1672                 {
1673                   *l = 3;
1674                   return (AS1 (clr,%A0) CR_TAB
1675                           AS1 (clr,%B0) CR_TAB
1676                           AS1 (inc,%A0));
1677                 }
1678               else if (src == constm1_rtx)
1679                 {
1680                   /* Immediate constants -1 to any register */
1681                   *l = 3;
1682                   return (AS1 (clr,%0)  CR_TAB
1683                           AS1 (dec,%A0) CR_TAB
1684                           AS2 (mov,%B0,%A0));
1685                 }
1686               else
1687                 {
1688                   int bit_nr = exact_log2 (INTVAL (src));
1689
1690                   if (bit_nr >= 0)
1691                     {
1692                       *l = 4;
1693                       if (!real_l)
1694                         output_asm_insn ((AS1 (clr,%A0) CR_TAB
1695                                           AS1 (clr,%B0) CR_TAB
1696                                           "set"), operands);
1697                       if (!real_l)
1698                         avr_output_bld (operands, bit_nr);
1699
1700                       return "";
1701                     }
1702                 }
1703
1704               if ((INTVAL (src) & 0xff) == 0)
1705                 {
1706                   *l = 5;
1707                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1708                           AS1 (clr,%A0)             CR_TAB
1709                           AS2 (ldi,r31,hi8(%1))     CR_TAB
1710                           AS2 (mov,%B0,r31)         CR_TAB
1711                           AS2 (mov,r31,__tmp_reg__));
1712                 }
1713               else if ((INTVAL (src) & 0xff00) == 0)
1714                 {
1715                   *l = 5;
1716                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1717                           AS2 (ldi,r31,lo8(%1))     CR_TAB
1718                           AS2 (mov,%A0,r31)         CR_TAB
1719                           AS1 (clr,%B0)             CR_TAB
1720                           AS2 (mov,r31,__tmp_reg__));
1721                 }
1722             }
1723           
1724           /* Last resort, equal to loading from memory.  */
1725           *l = 6;
1726           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1727                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1728                   AS2 (mov,%A0,r31)         CR_TAB
1729                   AS2 (ldi,r31,hi8(%1))     CR_TAB
1730                   AS2 (mov,%B0,r31)         CR_TAB
1731                   AS2 (mov,r31,__tmp_reg__));
1732         }
1733       else if (GET_CODE (src) == MEM)
1734         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1735     }
1736   else if (GET_CODE (dest) == MEM)
1737     {
1738       const char *template;
1739
1740       if (src == const0_rtx)
1741         operands[1] = zero_reg_rtx;
1742
1743       template = out_movhi_mr_r (insn, operands, real_l);
1744
1745       if (!real_l)
1746         output_asm_insn (template, operands);
1747
1748       operands[1] = src;
1749       return "";
1750     }
1751   fatal_insn ("invalid insn:", insn);
1752   return "";
1753 }
1754
1755 const char *
1756 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1757 {
1758   rtx dest = op[0];
1759   rtx src = op[1];
1760   rtx x = XEXP (src, 0);
1761   int dummy;
1762   
1763   if (!l)
1764     l = &dummy;
1765   
1766   if (CONSTANT_ADDRESS_P (x))
1767     {
1768       if (avr_io_address_p (x, 1))
1769         {
1770           *l = 1;
1771           return AS2 (in,%0,%1-0x20);
1772         }
1773       *l = 2;
1774       return AS2 (lds,%0,%1);
1775     }
1776   /* memory access by reg+disp */
1777   else if (GET_CODE (x) == PLUS
1778       && REG_P (XEXP (x,0))
1779       && GET_CODE (XEXP (x,1)) == CONST_INT)
1780     {
1781       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1782         {
1783           int disp = INTVAL (XEXP (x,1));
1784           if (REGNO (XEXP (x,0)) != REG_Y)
1785             fatal_insn ("incorrect insn:",insn);
1786
1787           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1788             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1789                             AS2 (ldd,%0,Y+63)     CR_TAB
1790                             AS2 (sbiw,r28,%o1-63));
1791
1792           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1793                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1794                           AS2 (ld,%0,Y)            CR_TAB
1795                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1796                           AS2 (sbci,r29,hi8(%o1)));
1797         }
1798       else if (REGNO (XEXP (x,0)) == REG_X)
1799         {
1800           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1801              it but I have this situation with extremal optimizing options.  */
1802           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1803               || reg_unused_after (insn, XEXP (x,0)))
1804             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1805                             AS2 (ld,%0,X));
1806
1807           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1808                           AS2 (ld,%0,X)      CR_TAB
1809                           AS2 (sbiw,r26,%o1));
1810         }
1811       *l = 1;
1812       return AS2 (ldd,%0,%1);
1813     }
1814   *l = 1;
1815   return AS2 (ld,%0,%1);
1816 }
1817
1818 const char *
1819 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1820 {
1821   rtx dest = op[0];
1822   rtx src = op[1];
1823   rtx base = XEXP (src, 0);
1824   int reg_dest = true_regnum (dest);
1825   int reg_base = true_regnum (base);
1826   int tmp;
1827
1828   if (!l)
1829     l = &tmp;
1830
1831   if (reg_base > 0)
1832     {
1833       if (reg_dest == reg_base)         /* R = (R) */
1834         {
1835           *l = 3;
1836           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1837                   AS2 (ld,%B0,%1) CR_TAB
1838                   AS2 (mov,%A0,__tmp_reg__));
1839         }
1840       else if (reg_base == REG_X)        /* (R26) */
1841         {
1842           if (reg_unused_after (insn, base))
1843             {
1844               *l = 2;
1845               return (AS2 (ld,%A0,X+) CR_TAB
1846                       AS2 (ld,%B0,X));
1847             }
1848           *l  = 3;
1849           return (AS2 (ld,%A0,X+) CR_TAB
1850                   AS2 (ld,%B0,X) CR_TAB
1851                   AS2 (sbiw,r26,1));
1852         }
1853       else                      /* (R)  */
1854         {
1855           *l = 2;
1856           return (AS2 (ld,%A0,%1)    CR_TAB
1857                   AS2 (ldd,%B0,%1+1));
1858         }
1859     }
1860   else if (GET_CODE (base) == PLUS) /* (R + i) */
1861     {
1862       int disp = INTVAL (XEXP (base, 1));
1863       int reg_base = true_regnum (XEXP (base, 0));
1864       
1865       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1866         {
1867           if (REGNO (XEXP (base, 0)) != REG_Y)
1868             fatal_insn ("incorrect insn:",insn);
1869           
1870           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1871             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1872                             AS2 (ldd,%A0,Y+62)    CR_TAB
1873                             AS2 (ldd,%B0,Y+63)    CR_TAB
1874                             AS2 (sbiw,r28,%o1-62));
1875
1876           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1877                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1878                           AS2 (ld,%A0,Y)           CR_TAB
1879                           AS2 (ldd,%B0,Y+1)        CR_TAB
1880                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1881                           AS2 (sbci,r29,hi8(%o1)));
1882         }
1883       if (reg_base == REG_X)
1884         {
1885           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1886              it but I have this situation with extremal
1887              optimization options.  */
1888           
1889           *l = 4;
1890           if (reg_base == reg_dest)
1891             return (AS2 (adiw,r26,%o1)      CR_TAB
1892                     AS2 (ld,__tmp_reg__,X+) CR_TAB
1893                     AS2 (ld,%B0,X)          CR_TAB
1894                     AS2 (mov,%A0,__tmp_reg__));
1895
1896           return (AS2 (adiw,r26,%o1) CR_TAB
1897                   AS2 (ld,%A0,X+)    CR_TAB
1898                   AS2 (ld,%B0,X)     CR_TAB
1899                   AS2 (sbiw,r26,%o1+1));
1900         }
1901
1902       if (reg_base == reg_dest)
1903         {
1904           *l = 3;
1905           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1906                   AS2 (ldd,%B0,%B1)         CR_TAB
1907                   AS2 (mov,%A0,__tmp_reg__));
1908         }
1909       
1910       *l = 2;
1911       return (AS2 (ldd,%A0,%A1) CR_TAB
1912               AS2 (ldd,%B0,%B1));
1913     }
1914   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1915     {
1916       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1917         fatal_insn ("incorrect insn:", insn);
1918
1919       *l = 2;
1920       return (AS2 (ld,%B0,%1) CR_TAB
1921               AS2 (ld,%A0,%1));
1922     }
1923   else if (GET_CODE (base) == POST_INC) /* (R++) */
1924     {
1925       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1926         fatal_insn ("incorrect insn:", insn);
1927
1928       *l = 2;
1929       return (AS2 (ld,%A0,%1)  CR_TAB
1930               AS2 (ld,%B0,%1));
1931     }
1932   else if (CONSTANT_ADDRESS_P (base))
1933     {
1934       if (avr_io_address_p (base, 2))
1935         {
1936           *l = 2;
1937           return (AS2 (in,%A0,%A1-0x20) CR_TAB
1938                   AS2 (in,%B0,%B1-0x20));
1939         }
1940       *l = 4;
1941       return (AS2 (lds,%A0,%A1) CR_TAB
1942               AS2 (lds,%B0,%B1));
1943     }
1944   
1945   fatal_insn ("unknown move insn:",insn);
1946   return "";
1947 }
1948
1949 const char *
1950 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1951 {
1952   rtx dest = op[0];
1953   rtx src = op[1];
1954   rtx base = XEXP (src, 0);
1955   int reg_dest = true_regnum (dest);
1956   int reg_base = true_regnum (base);
1957   int tmp;
1958
1959   if (!l)
1960     l = &tmp;
1961   
1962   if (reg_base > 0)
1963     {
1964       if (reg_base == REG_X)        /* (R26) */
1965         {
1966           if (reg_dest == REG_X)
1967             /* "ld r26,-X" is undefined */
1968             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
1969                           AS2 (ld,r29,X)          CR_TAB
1970                           AS2 (ld,r28,-X)         CR_TAB
1971                           AS2 (ld,__tmp_reg__,-X) CR_TAB
1972                           AS2 (sbiw,r26,1)        CR_TAB
1973                           AS2 (ld,r26,X)          CR_TAB
1974                           AS2 (mov,r27,__tmp_reg__));
1975           else if (reg_dest == REG_X - 2)
1976             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
1977                           AS2 (ld,%B0,X+) CR_TAB
1978                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
1979                           AS2 (ld,%D0,X)  CR_TAB
1980                           AS2 (mov,%C0,__tmp_reg__));
1981           else if (reg_unused_after (insn, base))
1982             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
1983                            AS2 (ld,%B0,X+) CR_TAB
1984                            AS2 (ld,%C0,X+) CR_TAB
1985                            AS2 (ld,%D0,X));
1986           else
1987             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
1988                            AS2 (ld,%B0,X+) CR_TAB
1989                            AS2 (ld,%C0,X+) CR_TAB
1990                            AS2 (ld,%D0,X)  CR_TAB
1991                            AS2 (sbiw,r26,3));
1992         }
1993       else
1994         {
1995           if (reg_dest == reg_base)
1996             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1997                           AS2 (ldd,%C0,%1+2) CR_TAB
1998                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
1999                           AS2 (ld,%A0,%1)  CR_TAB
2000                           AS2 (mov,%B0,__tmp_reg__));
2001           else if (reg_base == reg_dest + 2)
2002             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2003                           AS2 (ldd,%B0,%1+1) CR_TAB
2004                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2005                           AS2 (ldd,%D0,%1+3) CR_TAB
2006                           AS2 (mov,%C0,__tmp_reg__));
2007           else
2008             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2009                           AS2 (ldd,%B0,%1+1) CR_TAB
2010                           AS2 (ldd,%C0,%1+2) CR_TAB
2011                           AS2 (ldd,%D0,%1+3));
2012         }
2013     }
2014   else if (GET_CODE (base) == PLUS) /* (R + i) */
2015     {
2016       int disp = INTVAL (XEXP (base, 1));
2017       
2018       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2019         {
2020           if (REGNO (XEXP (base, 0)) != REG_Y)
2021             fatal_insn ("incorrect insn:",insn);
2022
2023           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2024             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2025                             AS2 (ldd,%A0,Y+60)    CR_TAB
2026                             AS2 (ldd,%B0,Y+61)    CR_TAB
2027                             AS2 (ldd,%C0,Y+62)    CR_TAB
2028                             AS2 (ldd,%D0,Y+63)    CR_TAB
2029                             AS2 (sbiw,r28,%o1-60));
2030
2031           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2032                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2033                           AS2 (ld,%A0,Y)           CR_TAB
2034                           AS2 (ldd,%B0,Y+1)        CR_TAB
2035                           AS2 (ldd,%C0,Y+2)        CR_TAB
2036                           AS2 (ldd,%D0,Y+3)        CR_TAB
2037                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2038                           AS2 (sbci,r29,hi8(%o1)));
2039         }
2040
2041       reg_base = true_regnum (XEXP (base, 0));
2042       if (reg_base == REG_X)
2043         {
2044           /* R = (X + d) */
2045           if (reg_dest == REG_X)
2046             {
2047               *l = 7;
2048               /* "ld r26,-X" is undefined */
2049               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2050                       AS2 (ld,r29,X)          CR_TAB
2051                       AS2 (ld,r28,-X)         CR_TAB
2052                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2053                       AS2 (sbiw,r26,1)        CR_TAB
2054                       AS2 (ld,r26,X)          CR_TAB
2055                       AS2 (mov,r27,__tmp_reg__));
2056             }
2057           *l = 6;
2058           if (reg_dest == REG_X - 2)
2059             return (AS2 (adiw,r26,%o1)      CR_TAB
2060                     AS2 (ld,r24,X+)         CR_TAB
2061                     AS2 (ld,r25,X+)         CR_TAB
2062                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2063                     AS2 (ld,r27,X)          CR_TAB
2064                     AS2 (mov,r26,__tmp_reg__));
2065
2066           return (AS2 (adiw,r26,%o1) CR_TAB
2067                   AS2 (ld,%A0,X+)    CR_TAB
2068                   AS2 (ld,%B0,X+)    CR_TAB
2069                   AS2 (ld,%C0,X+)    CR_TAB
2070                   AS2 (ld,%D0,X)     CR_TAB
2071                   AS2 (sbiw,r26,%o1+3));
2072         }
2073       if (reg_dest == reg_base)
2074         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2075                       AS2 (ldd,%C0,%C1) CR_TAB
2076                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2077                       AS2 (ldd,%A0,%A1) CR_TAB
2078                       AS2 (mov,%B0,__tmp_reg__));
2079       else if (reg_dest == reg_base - 2)
2080         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2081                       AS2 (ldd,%B0,%B1) CR_TAB
2082                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2083                       AS2 (ldd,%D0,%D1) CR_TAB
2084                       AS2 (mov,%C0,__tmp_reg__));
2085       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2086                     AS2 (ldd,%B0,%B1) CR_TAB
2087                     AS2 (ldd,%C0,%C1) CR_TAB
2088                     AS2 (ldd,%D0,%D1));
2089     }
2090   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2091     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2092                   AS2 (ld,%C0,%1) CR_TAB
2093                   AS2 (ld,%B0,%1) CR_TAB
2094                   AS2 (ld,%A0,%1));
2095   else if (GET_CODE (base) == POST_INC) /* (R++) */
2096     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2097                   AS2 (ld,%B0,%1) CR_TAB
2098                   AS2 (ld,%C0,%1) CR_TAB
2099                   AS2 (ld,%D0,%1));
2100   else if (CONSTANT_ADDRESS_P (base))
2101       return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2102                     AS2 (lds,%B0,%B1) CR_TAB
2103                     AS2 (lds,%C0,%C1) CR_TAB
2104                     AS2 (lds,%D0,%D1));
2105     
2106   fatal_insn ("unknown move insn:",insn);
2107   return "";
2108 }
2109
2110 const char *
2111 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2112 {
2113   rtx dest = op[0];
2114   rtx src = op[1];
2115   rtx base = XEXP (dest, 0);
2116   int reg_base = true_regnum (base);
2117   int reg_src = true_regnum (src);
2118   int tmp;
2119   
2120   if (!l)
2121     l = &tmp;
2122   
2123   if (CONSTANT_ADDRESS_P (base))
2124     return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2125                  AS2 (sts,%B0,%B1) CR_TAB
2126                  AS2 (sts,%C0,%C1) CR_TAB
2127                  AS2 (sts,%D0,%D1));
2128   if (reg_base > 0)                 /* (r) */
2129     {
2130       if (reg_base == REG_X)                /* (R26) */
2131         {
2132           if (reg_src == REG_X)
2133             {
2134               /* "st X+,r26" is undefined */
2135               if (reg_unused_after (insn, base))
2136                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2137                               AS2 (st,X,r26)            CR_TAB
2138                               AS2 (adiw,r26,1)          CR_TAB
2139                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2140                               AS2 (st,X+,r28)           CR_TAB
2141                               AS2 (st,X,r29));
2142               else
2143                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2144                               AS2 (st,X,r26)            CR_TAB
2145                               AS2 (adiw,r26,1)          CR_TAB
2146                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2147                               AS2 (st,X+,r28)           CR_TAB
2148                               AS2 (st,X,r29)            CR_TAB
2149                               AS2 (sbiw,r26,3));
2150             }
2151           else if (reg_base == reg_src + 2)
2152             {
2153               if (reg_unused_after (insn, base))
2154                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2155                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2156                               AS2 (st,%0+,%A1) CR_TAB
2157                               AS2 (st,%0+,%B1) CR_TAB
2158                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2159                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2160                               AS1 (clr,__zero_reg__));
2161               else
2162                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2163                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2164                               AS2 (st,%0+,%A1) CR_TAB
2165                               AS2 (st,%0+,%B1) CR_TAB
2166                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2167                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2168                               AS1 (clr,__zero_reg__)     CR_TAB
2169                               AS2 (sbiw,r26,3));
2170             }
2171           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2172                         AS2 (st,%0+,%B1) CR_TAB
2173                         AS2 (st,%0+,%C1) CR_TAB
2174                         AS2 (st,%0,%D1)  CR_TAB
2175                         AS2 (sbiw,r26,3));
2176         }
2177       else
2178         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2179                       AS2 (std,%0+1,%B1) CR_TAB
2180                       AS2 (std,%0+2,%C1) CR_TAB
2181                       AS2 (std,%0+3,%D1));
2182     }
2183   else if (GET_CODE (base) == PLUS) /* (R + i) */
2184     {
2185       int disp = INTVAL (XEXP (base, 1));
2186       reg_base = REGNO (XEXP (base, 0));
2187       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2188         {
2189           if (reg_base != REG_Y)
2190             fatal_insn ("incorrect insn:",insn);
2191
2192           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2193             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2194                             AS2 (std,Y+60,%A1)    CR_TAB
2195                             AS2 (std,Y+61,%B1)    CR_TAB
2196                             AS2 (std,Y+62,%C1)    CR_TAB
2197                             AS2 (std,Y+63,%D1)    CR_TAB
2198                             AS2 (sbiw,r28,%o0-60));
2199
2200           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2201                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2202                           AS2 (st,Y,%A1)           CR_TAB
2203                           AS2 (std,Y+1,%B1)        CR_TAB
2204                           AS2 (std,Y+2,%C1)        CR_TAB
2205                           AS2 (std,Y+3,%D1)        CR_TAB
2206                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2207                           AS2 (sbci,r29,hi8(%o0)));
2208         }
2209       if (reg_base == REG_X)
2210         {
2211           /* (X + d) = R */
2212           if (reg_src == REG_X)
2213             {
2214               *l = 9;
2215               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2216                       AS2 (mov,__zero_reg__,r27) CR_TAB
2217                       AS2 (adiw,r26,%o0)         CR_TAB
2218                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2219                       AS2 (st,X+,__zero_reg__)   CR_TAB
2220                       AS2 (st,X+,r28)            CR_TAB
2221                       AS2 (st,X,r29)             CR_TAB
2222                       AS1 (clr,__zero_reg__)     CR_TAB
2223                       AS2 (sbiw,r26,%o0+3));
2224             }
2225           else if (reg_src == REG_X - 2)
2226             {
2227               *l = 9;
2228               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2229                       AS2 (mov,__zero_reg__,r27) CR_TAB
2230                       AS2 (adiw,r26,%o0)         CR_TAB
2231                       AS2 (st,X+,r24)            CR_TAB
2232                       AS2 (st,X+,r25)            CR_TAB
2233                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2234                       AS2 (st,X,__zero_reg__)    CR_TAB
2235                       AS1 (clr,__zero_reg__)     CR_TAB
2236                       AS2 (sbiw,r26,%o0+3));
2237             }
2238           *l = 6;
2239           return (AS2 (adiw,r26,%o0) CR_TAB
2240                   AS2 (st,X+,%A1)    CR_TAB
2241                   AS2 (st,X+,%B1)    CR_TAB
2242                   AS2 (st,X+,%C1)    CR_TAB
2243                   AS2 (st,X,%D1)     CR_TAB
2244                   AS2 (sbiw,r26,%o0+3));
2245         }
2246       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2247                     AS2 (std,%B0,%B1) CR_TAB
2248                     AS2 (std,%C0,%C1) CR_TAB
2249                     AS2 (std,%D0,%D1));
2250     }
2251   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2252     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2253                   AS2 (st,%0,%C1) CR_TAB
2254                   AS2 (st,%0,%B1) CR_TAB
2255                   AS2 (st,%0,%A1));
2256   else if (GET_CODE (base) == POST_INC) /* (R++) */
2257     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2258                   AS2 (st,%0,%B1) CR_TAB
2259                   AS2 (st,%0,%C1) CR_TAB
2260                   AS2 (st,%0,%D1));
2261   fatal_insn ("unknown move insn:",insn);
2262   return "";
2263 }
2264
2265 const char *
2266 output_movsisf(rtx insn, rtx operands[], int *l)
2267 {
2268   int dummy;
2269   rtx dest = operands[0];
2270   rtx src = operands[1];
2271   int *real_l = l;
2272   
2273   if (!l)
2274     l = &dummy;
2275   
2276   if (register_operand (dest, VOIDmode))
2277     {
2278       if (register_operand (src, VOIDmode)) /* mov r,r */
2279         {
2280           if (true_regnum (dest) > true_regnum (src))
2281             {
2282               if (AVR_ENHANCED)
2283                 {
2284                   *l = 2;
2285                   return (AS2 (movw,%C0,%C1) CR_TAB
2286                           AS2 (movw,%A0,%A1));
2287                 }
2288               *l = 4;
2289               return (AS2 (mov,%D0,%D1) CR_TAB
2290                       AS2 (mov,%C0,%C1) CR_TAB
2291                       AS2 (mov,%B0,%B1) CR_TAB
2292                       AS2 (mov,%A0,%A1));
2293             }
2294           else
2295             {
2296               if (AVR_ENHANCED)
2297                 {
2298                   *l = 2;
2299                   return (AS2 (movw,%A0,%A1) CR_TAB
2300                           AS2 (movw,%C0,%C1));
2301                 }
2302               *l = 4;
2303               return (AS2 (mov,%A0,%A1) CR_TAB
2304                       AS2 (mov,%B0,%B1) CR_TAB
2305                       AS2 (mov,%C0,%C1) CR_TAB
2306                       AS2 (mov,%D0,%D1));
2307             }
2308         }
2309       else if (CONSTANT_P (src))
2310         {
2311           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2312             {
2313               *l = 4;
2314               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2315                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2316                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2317                       AS2 (ldi,%D0,hhi8(%1)));
2318             }
2319           
2320           if (GET_CODE (src) == CONST_INT)
2321             {
2322               const char *const clr_op0 =
2323                 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2324                                 AS1 (clr,%B0) CR_TAB
2325                                 AS2 (movw,%C0,%A0))
2326                              : (AS1 (clr,%A0) CR_TAB
2327                                 AS1 (clr,%B0) CR_TAB
2328                                 AS1 (clr,%C0) CR_TAB
2329                                 AS1 (clr,%D0));
2330
2331               if (src == const0_rtx) /* mov r,L */
2332                 {
2333                   *l = AVR_ENHANCED ? 3 : 4;
2334                   return clr_op0;
2335                 }
2336               else if (src == const1_rtx)
2337                 {
2338                   if (!real_l)
2339                     output_asm_insn (clr_op0, operands);
2340                   *l = AVR_ENHANCED ? 4 : 5;
2341                   return AS1 (inc,%A0);
2342                 }
2343               else if (src == constm1_rtx)
2344                 {
2345                   /* Immediate constants -1 to any register */
2346                   if (AVR_ENHANCED)
2347                     {
2348                       *l = 4;
2349                       return (AS1 (clr,%A0)     CR_TAB
2350                               AS1 (dec,%A0)     CR_TAB
2351                               AS2 (mov,%B0,%A0) CR_TAB
2352                               AS2 (movw,%C0,%A0));
2353                     }
2354                   *l = 5;
2355                   return (AS1 (clr,%A0)     CR_TAB
2356                           AS1 (dec,%A0)     CR_TAB
2357                           AS2 (mov,%B0,%A0) CR_TAB
2358                           AS2 (mov,%C0,%A0) CR_TAB
2359                           AS2 (mov,%D0,%A0));
2360                 }
2361               else
2362                 {
2363                   int bit_nr = exact_log2 (INTVAL (src));
2364
2365                   if (bit_nr >= 0)
2366                     {
2367                       *l = AVR_ENHANCED ? 5 : 6;
2368                       if (!real_l)
2369                         {
2370                           output_asm_insn (clr_op0, operands);
2371                           output_asm_insn ("set", operands);
2372                         }
2373                       if (!real_l)
2374                         avr_output_bld (operands, bit_nr);
2375
2376                       return "";
2377                     }
2378                 }
2379             }
2380           
2381           /* Last resort, better than loading from memory.  */
2382           *l = 10;
2383           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2384                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2385                   AS2 (mov,%A0,r31)         CR_TAB
2386                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2387                   AS2 (mov,%B0,r31)         CR_TAB
2388                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2389                   AS2 (mov,%C0,r31)         CR_TAB
2390                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2391                   AS2 (mov,%D0,r31)         CR_TAB
2392                   AS2 (mov,r31,__tmp_reg__));
2393         }
2394       else if (GET_CODE (src) == MEM)
2395         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2396     }
2397   else if (GET_CODE (dest) == MEM)
2398     {
2399       const char *template;
2400
2401       if (src == const0_rtx)
2402           operands[1] = zero_reg_rtx;
2403
2404       template = out_movsi_mr_r (insn, operands, real_l);
2405
2406       if (!real_l)
2407         output_asm_insn (template, operands);
2408
2409       operands[1] = src;
2410       return "";
2411     }
2412   fatal_insn ("invalid insn:", insn);
2413   return "";
2414 }
2415
2416 const char *
2417 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2418 {
2419   rtx dest = op[0];
2420   rtx src = op[1];
2421   rtx x = XEXP (dest, 0);
2422   int dummy;
2423
2424   if (!l)
2425     l = &dummy;
2426   
2427   if (CONSTANT_ADDRESS_P (x))
2428     {
2429       if (avr_io_address_p (x, 1))
2430         {
2431           *l = 1;
2432           return AS2 (out,%0-0x20,%1);
2433         }
2434       *l = 2;
2435       return AS2 (sts,%0,%1);
2436     }
2437   /* memory access by reg+disp */
2438   else if (GET_CODE (x) == PLUS 
2439       && REG_P (XEXP (x,0))
2440       && GET_CODE (XEXP (x,1)) == CONST_INT)
2441     {
2442       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2443         {
2444           int disp = INTVAL (XEXP (x,1));
2445           if (REGNO (XEXP (x,0)) != REG_Y)
2446             fatal_insn ("incorrect insn:",insn);
2447
2448           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2449             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2450                             AS2 (std,Y+63,%1)     CR_TAB
2451                             AS2 (sbiw,r28,%o0-63));
2452
2453           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2454                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2455                           AS2 (st,Y,%1)            CR_TAB
2456                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2457                           AS2 (sbci,r29,hi8(%o0)));
2458         }
2459       else if (REGNO (XEXP (x,0)) == REG_X)
2460         {
2461           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2462             {
2463               if (reg_unused_after (insn, XEXP (x,0)))
2464                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2465                                 AS2 (adiw,r26,%o0)       CR_TAB
2466                                 AS2 (st,X,__tmp_reg__));
2467
2468               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2469                               AS2 (adiw,r26,%o0)       CR_TAB
2470                               AS2 (st,X,__tmp_reg__)   CR_TAB
2471                               AS2 (sbiw,r26,%o0));
2472             }
2473           else
2474             {
2475               if (reg_unused_after (insn, XEXP (x,0)))
2476                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2477                                 AS2 (st,X,%1));
2478
2479               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2480                               AS2 (st,X,%1)      CR_TAB
2481                               AS2 (sbiw,r26,%o0));
2482             }
2483         }
2484       *l = 1;
2485       return AS2 (std,%0,%1);
2486     }
2487   *l = 1;
2488   return AS2 (st,%0,%1);
2489 }
2490
2491 const char *
2492 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2493 {
2494   rtx dest = op[0];
2495   rtx src = op[1];
2496   rtx base = XEXP (dest, 0);
2497   int reg_base = true_regnum (base);
2498   int reg_src = true_regnum (src);
2499   int tmp;
2500   if (!l)
2501     l = &tmp;
2502   if (CONSTANT_ADDRESS_P (base))
2503     {
2504       if (avr_io_address_p (base, 2))
2505         {
2506           *l = 2;
2507           return (AS2 (out,%B0-0x20,%B1) CR_TAB
2508                   AS2 (out,%A0-0x20,%A1));
2509         }
2510       return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2511                       AS2 (sts,%A0,%A1));
2512     }
2513   if (reg_base > 0)
2514     {
2515       if (reg_base == REG_X)
2516         {
2517           if (reg_src == REG_X)
2518             {
2519               /* "st X+,r26" is undefined */
2520               if (reg_unused_after (insn, src))
2521                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2522                               AS2 (st,X,r26)            CR_TAB
2523                               AS2 (adiw,r26,1)          CR_TAB
2524                               AS2 (st,X,__tmp_reg__));
2525               else
2526                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2527                               AS2 (st,X,r26)            CR_TAB
2528                               AS2 (adiw,r26,1)          CR_TAB
2529                               AS2 (st,X,__tmp_reg__)    CR_TAB
2530                               AS2 (sbiw,r26,1));
2531             }
2532           else
2533             {
2534               if (reg_unused_after (insn, base))
2535                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2536                               AS2 (st,X,%B1));
2537               else
2538                 return *l=3, (AS2 (st  ,X+,%A1) CR_TAB
2539                               AS2 (st  ,X,%B1) CR_TAB
2540                               AS2 (sbiw,r26,1));
2541             }
2542         }
2543       else
2544         return  *l=2, (AS2 (st ,%0,%A1)    CR_TAB
2545                        AS2 (std,%0+1,%B1));
2546     }
2547   else if (GET_CODE (base) == PLUS)
2548     {
2549       int disp = INTVAL (XEXP (base, 1));
2550       reg_base = REGNO (XEXP (base, 0));
2551       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2552         {
2553           if (reg_base != REG_Y)
2554             fatal_insn ("incorrect insn:",insn);
2555
2556           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2557             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2558                             AS2 (std,Y+62,%A1)    CR_TAB
2559                             AS2 (std,Y+63,%B1)    CR_TAB
2560                             AS2 (sbiw,r28,%o0-62));
2561
2562           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2563                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2564                           AS2 (st,Y,%A1)           CR_TAB
2565                           AS2 (std,Y+1,%B1)        CR_TAB
2566                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2567                           AS2 (sbci,r29,hi8(%o0)));
2568         }
2569       if (reg_base == REG_X)
2570         {
2571           /* (X + d) = R */
2572           if (reg_src == REG_X)
2573             {
2574               *l = 7;
2575               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2576                       AS2 (mov,__zero_reg__,r27) CR_TAB
2577                       AS2 (adiw,r26,%o0)         CR_TAB
2578                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2579                       AS2 (st,X,__zero_reg__)    CR_TAB
2580                       AS1 (clr,__zero_reg__)     CR_TAB
2581                       AS2 (sbiw,r26,%o0+1));
2582             }
2583           *l = 4;
2584           return (AS2 (adiw,r26,%o0) CR_TAB
2585                   AS2 (st,X+,%A1)    CR_TAB
2586                   AS2 (st,X,%B1)     CR_TAB
2587                   AS2 (sbiw,r26,%o0+1));
2588         }
2589       return *l=2, (AS2 (std,%A0,%A1)    CR_TAB
2590                     AS2 (std,%B0,%B1));
2591     }
2592   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2593     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2594                   AS2 (st,%0,%A1));
2595   else if (GET_CODE (base) == POST_INC) /* (R++) */
2596     return *l=2, (AS2 (st,%0,%A1)  CR_TAB
2597                   AS2 (st,%0,%B1));
2598   fatal_insn ("unknown move insn:",insn);
2599   return "";
2600 }
2601
2602 /* Return 1 if frame pointer for current function required.  */
2603
2604 int
2605 frame_pointer_required_p (void)
2606 {
2607   return (current_function_calls_alloca
2608           || current_function_args_info.nregs == 0
2609           || get_frame_size () > 0);
2610 }
2611
2612 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2613
2614 static RTX_CODE
2615 compare_condition (rtx insn)
2616 {
2617   rtx next = next_real_insn (insn);
2618   RTX_CODE cond = UNKNOWN;
2619   if (next && GET_CODE (next) == JUMP_INSN)
2620     {
2621       rtx pat = PATTERN (next);
2622       rtx src = SET_SRC (pat);
2623       rtx t = XEXP (src, 0);
2624       cond = GET_CODE (t);
2625     }
2626   return cond;
2627 }
2628
2629 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
2630
2631 static int
2632 compare_sign_p (rtx insn)
2633 {
2634   RTX_CODE cond = compare_condition (insn);
2635   return (cond == GE || cond == LT);
2636 }
2637
2638 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2639    that needs to be swapped (GT, GTU, LE, LEU).  */
2640
2641 int
2642 compare_diff_p (rtx insn)
2643 {
2644   RTX_CODE cond = compare_condition (insn);
2645   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2646 }
2647
2648 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
2649
2650 int
2651 compare_eq_p (rtx insn)
2652 {
2653   RTX_CODE cond = compare_condition (insn);
2654   return (cond == EQ || cond == NE);
2655 }
2656
2657
2658 /* Output test instruction for HImode.  */
2659
2660 const char *
2661 out_tsthi (rtx insn, int *l)
2662 {
2663   if (compare_sign_p (insn))
2664     {
2665       if (l) *l = 1;
2666       return AS1 (tst,%B0);
2667     }
2668   if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2669       && compare_eq_p (insn))
2670     {
2671       /* Faster than sbiw if we can clobber the operand.  */
2672       if (l) *l = 1;
2673       return AS2 (or,%A0,%B0);
2674     }
2675   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2676     {
2677       if (l) *l = 1;
2678       return AS2 (sbiw,%0,0);
2679     }
2680   if (l) *l = 2;
2681   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2682           AS2 (cpc,%B0,__zero_reg__));
2683 }
2684
2685
2686 /* Output test instruction for SImode.  */
2687
2688 const char *
2689 out_tstsi (rtx insn, int *l)
2690 {
2691   if (compare_sign_p (insn))
2692     {
2693       if (l) *l = 1;
2694       return AS1 (tst,%D0);
2695     }
2696   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2697     {
2698       if (l) *l = 3;
2699       return (AS2 (sbiw,%A0,0) CR_TAB
2700               AS2 (cpc,%C0,__zero_reg__) CR_TAB
2701               AS2 (cpc,%D0,__zero_reg__));
2702     }
2703   if (l) *l = 4;
2704   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2705           AS2 (cpc,%B0,__zero_reg__) CR_TAB
2706           AS2 (cpc,%C0,__zero_reg__) CR_TAB
2707           AS2 (cpc,%D0,__zero_reg__));
2708 }
2709
2710
2711 /* Generate asm equivalent for various shifts.
2712    Shift count is a CONST_INT, MEM or REG.
2713    This only handles cases that are not already
2714    carefully hand-optimized in ?sh??i3_out.  */
2715
2716 void
2717 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2718                     int *len, int t_len)
2719 {
2720   rtx op[10];
2721   char str[500];
2722   int second_label = 1;
2723   int saved_in_tmp = 0;
2724   int use_zero_reg = 0;
2725
2726   op[0] = operands[0];
2727   op[1] = operands[1];
2728   op[2] = operands[2];
2729   op[3] = operands[3];
2730   str[0] = 0;
2731
2732   if (len)
2733     *len = 1;
2734
2735   if (GET_CODE (operands[2]) == CONST_INT)
2736     {
2737       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2738       int count = INTVAL (operands[2]);
2739       int max_len = 10;  /* If larger than this, always use a loop.  */
2740
2741       if (count < 8 && !scratch)
2742         use_zero_reg = 1;
2743
2744       if (optimize_size)
2745         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2746
2747       if (t_len * count <= max_len)
2748         {
2749           /* Output shifts inline with no loop - faster.  */
2750           if (len)
2751             *len = t_len * count;
2752           else
2753             {
2754               while (count-- > 0)
2755                 output_asm_insn (template, op);
2756             }
2757
2758           return;
2759         }
2760
2761       if (scratch)
2762         {
2763           if (!len)
2764             strcat (str, AS2 (ldi,%3,%2));
2765         }
2766       else if (use_zero_reg)
2767         {
2768           /* Hack to save one word: use __zero_reg__ as loop counter.
2769              Set one bit, then shift in a loop until it is 0 again.  */
2770
2771           op[3] = zero_reg_rtx;
2772           if (len)
2773             *len = 2;
2774           else
2775             strcat (str, ("set" CR_TAB
2776                           AS2 (bld,%3,%2-1)));
2777         }
2778       else
2779         {
2780           /* No scratch register available, use one from LD_REGS (saved in
2781              __tmp_reg__) that doesn't overlap with registers to shift.  */
2782
2783           op[3] = gen_rtx_REG (QImode,
2784                            ((true_regnum (operands[0]) - 1) & 15) + 16);
2785           op[4] = tmp_reg_rtx;
2786           saved_in_tmp = 1;
2787
2788           if (len)
2789             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
2790           else
2791             strcat (str, (AS2 (mov,%4,%3) CR_TAB
2792                           AS2 (ldi,%3,%2)));
2793         }
2794
2795       second_label = 0;
2796     }
2797   else if (GET_CODE (operands[2]) == MEM)
2798     {
2799       rtx op_mov[10];
2800       
2801       op[3] = op_mov[0] = tmp_reg_rtx;
2802       op_mov[1] = op[2];
2803
2804       if (len)
2805         out_movqi_r_mr (insn, op_mov, len);
2806       else
2807         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2808     }
2809   else if (register_operand (operands[2], QImode))
2810     {
2811       if (reg_unused_after (insn, operands[2]))
2812         op[3] = op[2];
2813       else
2814         {
2815           op[3] = tmp_reg_rtx;
2816           if (!len)
2817             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2818         }
2819     }
2820   else
2821     fatal_insn ("bad shift insn:", insn);
2822
2823   if (second_label)
2824     {
2825       if (len)
2826         ++*len;
2827       else
2828         strcat (str, AS1 (rjmp,2f));
2829     }
2830
2831   if (len)
2832     *len += t_len + 2;  /* template + dec + brXX */
2833   else
2834     {
2835       strcat (str, "\n1:\t");
2836       strcat (str, template);
2837       strcat (str, second_label ? "\n2:\t" : "\n\t");
2838       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2839       strcat (str, CR_TAB);
2840       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2841       if (saved_in_tmp)
2842         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2843       output_asm_insn (str, op);
2844     }
2845 }
2846
2847
2848 /* 8bit shift left ((char)x << i)   */
2849
2850 const char *
2851 ashlqi3_out (rtx insn, rtx operands[], int *len)
2852 {
2853   if (GET_CODE (operands[2]) == CONST_INT)
2854     {
2855       int k;
2856
2857       if (!len)
2858         len = &k;
2859
2860       switch (INTVAL (operands[2]))
2861         {
2862         default:
2863           *len = 1;
2864           return AS1 (clr,%0);
2865           
2866         case 1:
2867           *len = 1;
2868           return AS1 (lsl,%0);
2869           
2870         case 2:
2871           *len = 2;
2872           return (AS1 (lsl,%0) CR_TAB
2873                   AS1 (lsl,%0));
2874
2875         case 3:
2876           *len = 3;
2877           return (AS1 (lsl,%0) CR_TAB
2878                   AS1 (lsl,%0) CR_TAB
2879                   AS1 (lsl,%0));
2880
2881         case 4:
2882           if (test_hard_reg_class (LD_REGS, operands[0]))
2883             {
2884               *len = 2;
2885               return (AS1 (swap,%0) CR_TAB
2886                       AS2 (andi,%0,0xf0));
2887             }
2888           *len = 4;
2889           return (AS1 (lsl,%0) CR_TAB
2890                   AS1 (lsl,%0) CR_TAB
2891                   AS1 (lsl,%0) CR_TAB
2892                   AS1 (lsl,%0));
2893
2894         case 5:
2895           if (test_hard_reg_class (LD_REGS, operands[0]))
2896             {
2897               *len = 3;
2898               return (AS1 (swap,%0) CR_TAB
2899                       AS1 (lsl,%0)  CR_TAB
2900                       AS2 (andi,%0,0xe0));
2901             }
2902           *len = 5;
2903           return (AS1 (lsl,%0) CR_TAB
2904                   AS1 (lsl,%0) CR_TAB
2905                   AS1 (lsl,%0) CR_TAB
2906                   AS1 (lsl,%0) CR_TAB
2907                   AS1 (lsl,%0));
2908
2909         case 6:
2910           if (test_hard_reg_class (LD_REGS, operands[0]))
2911             {
2912               *len = 4;
2913               return (AS1 (swap,%0) CR_TAB
2914                       AS1 (lsl,%0)  CR_TAB
2915                       AS1 (lsl,%0)  CR_TAB
2916                       AS2 (andi,%0,0xc0));
2917             }
2918           *len = 6;
2919           return (AS1 (lsl,%0) CR_TAB
2920                   AS1 (lsl,%0) CR_TAB
2921                   AS1 (lsl,%0) CR_TAB
2922                   AS1 (lsl,%0) CR_TAB
2923                   AS1 (lsl,%0) CR_TAB
2924                   AS1 (lsl,%0));
2925
2926         case 7:
2927           *len = 3;
2928           return (AS1 (ror,%0) CR_TAB
2929                   AS1 (clr,%0) CR_TAB
2930                   AS1 (ror,%0));
2931         }
2932     }
2933   else if (CONSTANT_P (operands[2]))
2934     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
2935
2936   out_shift_with_cnt (AS1 (lsl,%0),
2937                       insn, operands, len, 1);
2938   return "";
2939 }
2940
2941
2942 /* 16bit shift left ((short)x << i)   */
2943
2944 const char *
2945 ashlhi3_out (rtx insn, rtx operands[], int *len)
2946 {
2947   if (GET_CODE (operands[2]) == CONST_INT)
2948     {
2949       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2950       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2951       int k;
2952       int *t = len;
2953
2954       if (!len)
2955         len = &k;
2956       
2957       switch (INTVAL (operands[2]))
2958         {
2959         case 4:
2960           if (optimize_size && scratch)
2961             break;  /* 5 */
2962           if (ldi_ok)
2963             {
2964               *len = 6;
2965               return (AS1 (swap,%A0)      CR_TAB
2966                       AS1 (swap,%B0)      CR_TAB
2967                       AS2 (andi,%B0,0xf0) CR_TAB
2968                       AS2 (eor,%B0,%A0)   CR_TAB
2969                       AS2 (andi,%A0,0xf0) CR_TAB
2970                       AS2 (eor,%B0,%A0));
2971             }
2972           if (scratch)
2973             {
2974               *len = 7;
2975               return (AS1 (swap,%A0)    CR_TAB
2976                       AS1 (swap,%B0)    CR_TAB
2977                       AS2 (ldi,%3,0xf0) CR_TAB
2978                       AS2 (and,%B0,%3)  CR_TAB
2979                       AS2 (eor,%B0,%A0) CR_TAB
2980                       AS2 (and,%A0,%3)  CR_TAB
2981                       AS2 (eor,%B0,%A0));
2982             }
2983           break;  /* optimize_size ? 6 : 8 */
2984
2985         case 5:
2986           if (optimize_size)
2987             break;  /* scratch ? 5 : 6 */
2988           if (ldi_ok)
2989             {
2990               *len = 8;
2991               return (AS1 (lsl,%A0)       CR_TAB
2992                       AS1 (rol,%B0)       CR_TAB
2993                       AS1 (swap,%A0)      CR_TAB
2994                       AS1 (swap,%B0)      CR_TAB
2995                       AS2 (andi,%B0,0xf0) CR_TAB
2996                       AS2 (eor,%B0,%A0)   CR_TAB
2997                       AS2 (andi,%A0,0xf0) CR_TAB
2998                       AS2 (eor,%B0,%A0));
2999             }
3000           if (scratch)
3001             {
3002               *len = 9;
3003               return (AS1 (lsl,%A0)     CR_TAB
3004                       AS1 (rol,%B0)     CR_TAB
3005                       AS1 (swap,%A0)    CR_TAB
3006                       AS1 (swap,%B0)    CR_TAB
3007                       AS2 (ldi,%3,0xf0) CR_TAB
3008                       AS2 (and,%B0,%3)  CR_TAB
3009                       AS2 (eor,%B0,%A0) CR_TAB
3010                       AS2 (and,%A0,%3)  CR_TAB
3011                       AS2 (eor,%B0,%A0));
3012             }
3013           break;  /* 10 */
3014
3015         case 6:
3016           if (optimize_size)
3017             break;  /* scratch ? 5 : 6 */
3018           *len = 9;
3019           return (AS1 (clr,__tmp_reg__) CR_TAB
3020                   AS1 (lsr,%B0)         CR_TAB
3021                   AS1 (ror,%A0)         CR_TAB
3022                   AS1 (ror,__tmp_reg__) CR_TAB
3023                   AS1 (lsr,%B0)         CR_TAB
3024                   AS1 (ror,%A0)         CR_TAB
3025                   AS1 (ror,__tmp_reg__) CR_TAB
3026                   AS2 (mov,%B0,%A0)     CR_TAB
3027                   AS2 (mov,%A0,__tmp_reg__));
3028
3029         case 7:
3030           *len = 5;
3031           return (AS1 (lsr,%B0)     CR_TAB
3032                   AS2 (mov,%B0,%A0) CR_TAB
3033                   AS1 (clr,%A0)     CR_TAB
3034                   AS1 (ror,%B0)     CR_TAB
3035                   AS1 (ror,%A0));
3036
3037         case 8:
3038           if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3039             return *len = 1, AS1 (clr,%A0);
3040           else
3041             return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3042                               AS1 (clr,%A0));
3043
3044         case 9:
3045           *len = 3;
3046           return (AS2 (mov,%B0,%A0) CR_TAB
3047                   AS1 (clr,%A0)     CR_TAB
3048                   AS1 (lsl,%B0));
3049
3050         case 10:
3051           *len = 4;
3052           return (AS2 (mov,%B0,%A0) CR_TAB
3053                   AS1 (clr,%A0)     CR_TAB
3054                   AS1 (lsl,%B0)     CR_TAB
3055                   AS1 (lsl,%B0));
3056
3057         case 11:
3058           *len = 5;
3059           return (AS2 (mov,%B0,%A0) CR_TAB
3060                   AS1 (clr,%A0)     CR_TAB
3061                   AS1 (lsl,%B0)     CR_TAB
3062                   AS1 (lsl,%B0)     CR_TAB
3063                   AS1 (lsl,%B0));
3064
3065         case 12:
3066           if (ldi_ok)
3067             {
3068               *len = 4;
3069               return (AS2 (mov,%B0,%A0) CR_TAB
3070                       AS1 (clr,%A0)     CR_TAB
3071                       AS1 (swap,%B0)    CR_TAB
3072                       AS2 (andi,%B0,0xf0));
3073             }
3074           if (scratch)
3075             {
3076               *len = 5;
3077               return (AS2 (mov,%B0,%A0) CR_TAB
3078                       AS1 (clr,%A0)     CR_TAB
3079                       AS1 (swap,%B0)    CR_TAB
3080                       AS2 (ldi,%3,0xf0) CR_TAB
3081                       AS2 (and,%B0,%3));
3082             }
3083           *len = 6;
3084           return (AS2 (mov,%B0,%A0) CR_TAB
3085                   AS1 (clr,%A0)     CR_TAB
3086                   AS1 (lsl,%B0)     CR_TAB
3087                   AS1 (lsl,%B0)     CR_TAB
3088                   AS1 (lsl,%B0)     CR_TAB
3089                   AS1 (lsl,%B0));
3090
3091         case 13:
3092           if (ldi_ok)
3093             {
3094               *len = 5;
3095               return (AS2 (mov,%B0,%A0) CR_TAB
3096                       AS1 (clr,%A0)     CR_TAB
3097                       AS1 (swap,%B0)    CR_TAB
3098                       AS1 (lsl,%B0)     CR_TAB
3099                       AS2 (andi,%B0,0xe0));
3100             }
3101           if (AVR_ENHANCED && scratch)
3102             {
3103               *len = 5;
3104               return (AS2 (ldi,%3,0x20) CR_TAB
3105                       AS2 (mul,%A0,%3)  CR_TAB
3106                       AS2 (mov,%B0,r0)  CR_TAB
3107                       AS1 (clr,%A0)     CR_TAB
3108                       AS1 (clr,__zero_reg__));
3109             }
3110           if (optimize_size && scratch)
3111             break;  /* 5 */
3112           if (scratch)
3113             {
3114               *len = 6;
3115               return (AS2 (mov,%B0,%A0) CR_TAB
3116                       AS1 (clr,%A0)     CR_TAB
3117                       AS1 (swap,%B0)    CR_TAB
3118                       AS1 (lsl,%B0)     CR_TAB
3119                       AS2 (ldi,%3,0xe0) CR_TAB
3120                       AS2 (and,%B0,%3));
3121             }
3122           if (AVR_ENHANCED)
3123             {
3124               *len = 6;
3125               return ("set"            CR_TAB
3126                       AS2 (bld,r1,5)   CR_TAB
3127                       AS2 (mul,%A0,r1) CR_TAB
3128                       AS2 (mov,%B0,r0) CR_TAB
3129                       AS1 (clr,%A0)    CR_TAB
3130                       AS1 (clr,__zero_reg__));
3131             }
3132           *len = 7;
3133           return (AS2 (mov,%B0,%A0) CR_TAB
3134                   AS1 (clr,%A0)     CR_TAB
3135                   AS1 (lsl,%B0)     CR_TAB
3136                   AS1 (lsl,%B0)     CR_TAB
3137                   AS1 (lsl,%B0)     CR_TAB
3138                   AS1 (lsl,%B0)     CR_TAB
3139                   AS1 (lsl,%B0));
3140
3141         case 14:
3142           if (AVR_ENHANCED && ldi_ok)
3143             {
3144               *len = 5;
3145               return (AS2 (ldi,%B0,0x40) CR_TAB
3146                       AS2 (mul,%A0,%B0)  CR_TAB
3147                       AS2 (mov,%B0,r0)   CR_TAB
3148                       AS1 (clr,%A0)      CR_TAB
3149                       AS1 (clr,__zero_reg__));
3150             }
3151           if (AVR_ENHANCED && scratch)
3152             {
3153               *len = 5;
3154               return (AS2 (ldi,%3,0x40) CR_TAB
3155                       AS2 (mul,%A0,%3)  CR_TAB
3156                       AS2 (mov,%B0,r0)  CR_TAB
3157                       AS1 (clr,%A0)     CR_TAB
3158                       AS1 (clr,__zero_reg__));
3159             }
3160           if (optimize_size && ldi_ok)
3161             {
3162               *len = 5;
3163               return (AS2 (mov,%B0,%A0) CR_TAB
3164                       AS2 (ldi,%A0,6) "\n1:\t"
3165                       AS1 (lsl,%B0)     CR_TAB
3166                       AS1 (dec,%A0)     CR_TAB
3167                       AS1 (brne,1b));
3168             }
3169           if (optimize_size && scratch)
3170             break;  /* 5 */
3171           *len = 6;
3172           return (AS1 (clr,%B0) CR_TAB
3173                   AS1 (lsr,%A0) CR_TAB
3174                   AS1 (ror,%B0) CR_TAB
3175                   AS1 (lsr,%A0) CR_TAB
3176                   AS1 (ror,%B0) CR_TAB
3177                   AS1 (clr,%A0));
3178
3179         case 15:
3180           *len = 4;
3181           return (AS1 (clr,%B0) CR_TAB
3182                   AS1 (lsr,%A0) CR_TAB
3183                   AS1 (ror,%B0) CR_TAB
3184                   AS1 (clr,%A0));
3185         }
3186       len = t;
3187     }
3188   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3189                        AS1 (rol,%B0)),
3190                        insn, operands, len, 2);
3191   return "";
3192 }
3193
3194
3195 /* 32bit shift left ((long)x << i)   */
3196
3197 const char *
3198 ashlsi3_out (rtx insn, rtx operands[], int *len)
3199 {
3200   if (GET_CODE (operands[2]) == CONST_INT)
3201     {
3202       int k;
3203       int *t = len;
3204       
3205       if (!len)
3206         len = &k;
3207       
3208       switch (INTVAL (operands[2]))
3209         {
3210         case 8:
3211           {
3212             int reg0 = true_regnum (operands[0]);
3213             int reg1 = true_regnum (operands[1]);
3214             *len = 4;
3215             if (reg0 >= reg1)
3216               return (AS2 (mov,%D0,%C1)  CR_TAB
3217                       AS2 (mov,%C0,%B1)  CR_TAB
3218                       AS2 (mov,%B0,%A1)  CR_TAB
3219                       AS1 (clr,%A0));
3220             else if (reg0 + 1 == reg1)
3221               {
3222                 *len = 1;
3223                 return AS1 (clr,%A0);
3224               }
3225             else
3226               return (AS1 (clr,%A0)      CR_TAB
3227                       AS2 (mov,%B0,%A1)  CR_TAB
3228                       AS2 (mov,%C0,%B1)  CR_TAB
3229                       AS2 (mov,%D0,%C1));
3230           }
3231
3232         case 16:
3233           {
3234             int reg0 = true_regnum (operands[0]);
3235             int reg1 = true_regnum (operands[1]);
3236             *len = 4;
3237             if (AVR_ENHANCED && (reg0 + 2 != reg1))
3238               {
3239                 *len = 3;
3240                 return (AS2 (movw,%C0,%A1) CR_TAB
3241                         AS1 (clr,%B0)      CR_TAB
3242                         AS1 (clr,%A0));
3243               }
3244             if (reg0 + 1 >= reg1)
3245               return (AS2 (mov,%D0,%B1)  CR_TAB
3246                       AS2 (mov,%C0,%A1)  CR_TAB
3247                       AS1 (clr,%B0)      CR_TAB
3248                       AS1 (clr,%A0));
3249             if (reg0 + 2 == reg1)
3250               {
3251                 *len = 2;
3252                 return (AS1 (clr,%B0)      CR_TAB
3253                         AS1 (clr,%A0));
3254               }
3255             else
3256               return (AS2 (mov,%C0,%A1)  CR_TAB
3257                       AS2 (mov,%D0,%B1)  CR_TAB
3258                       AS1 (clr,%B0)      CR_TAB
3259                       AS1 (clr,%A0));
3260           }
3261
3262         case 24:
3263           *len = 4;
3264           if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3265             return (AS2 (mov,%D0,%A1)  CR_TAB
3266                     AS1 (clr,%C0)      CR_TAB
3267                     AS1 (clr,%B0)      CR_TAB
3268                     AS1 (clr,%A0));
3269           else
3270             {
3271               *len = 3;
3272               return (AS1 (clr,%C0)      CR_TAB
3273                       AS1 (clr,%B0)      CR_TAB
3274                       AS1 (clr,%A0));
3275             }
3276
3277         case 31:
3278           *len = 6;
3279           return (AS1 (clr,%D0) CR_TAB
3280                   AS1 (lsr,%A0) CR_TAB
3281                   AS1 (ror,%D0) CR_TAB
3282                   AS1 (clr,%C0) CR_TAB
3283                   AS1 (clr,%B0) CR_TAB
3284                   AS1 (clr,%A0));
3285         }
3286       len = t;
3287     }
3288   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3289                        AS1 (rol,%B0) CR_TAB
3290                        AS1 (rol,%C0) CR_TAB
3291                        AS1 (rol,%D0)),
3292                        insn, operands, len, 4);
3293   return "";
3294 }
3295
3296 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3297
3298 const char *
3299 ashrqi3_out (rtx insn, rtx operands[], int *len)
3300 {
3301   if (GET_CODE (operands[2]) == CONST_INT)
3302     {
3303       int k;
3304
3305       if (!len)
3306         len = &k;
3307
3308       switch (INTVAL (operands[2]))
3309         {
3310         case 1:
3311           *len = 1;
3312           return AS1 (asr,%0);
3313
3314         case 2:
3315           *len = 2;
3316           return (AS1 (asr,%0) CR_TAB
3317                   AS1 (asr,%0));
3318
3319         case 3:
3320           *len = 3;
3321           return (AS1 (asr,%0) CR_TAB
3322                   AS1 (asr,%0) CR_TAB
3323                   AS1 (asr,%0));
3324
3325         case 4:
3326           *len = 4;
3327           return (AS1 (asr,%0) CR_TAB
3328                   AS1 (asr,%0) CR_TAB
3329                   AS1 (asr,%0) CR_TAB
3330                   AS1 (asr,%0));
3331
3332         case 5:
3333           *len = 5;
3334           return (AS1 (asr,%0) CR_TAB
3335                   AS1 (asr,%0) CR_TAB
3336                   AS1 (asr,%0) CR_TAB
3337                   AS1 (asr,%0) CR_TAB
3338                   AS1 (asr,%0));
3339
3340         case 6:
3341           *len = 4;
3342           return (AS2 (bst,%0,6)  CR_TAB
3343                   AS1 (lsl,%0)    CR_TAB
3344                   AS2 (sbc,%0,%0) CR_TAB
3345                   AS2 (bld,%0,0));
3346
3347         default:
3348         case 7:
3349           *len = 2;
3350           return (AS1 (lsl,%0) CR_TAB
3351                   AS2 (sbc,%0,%0));
3352         }
3353     }
3354   else if (CONSTANT_P (operands[2]))
3355     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3356
3357   out_shift_with_cnt (AS1 (asr,%0),
3358                       insn, operands, len, 1);
3359   return "";
3360 }
3361
3362
3363 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3364
3365 const char *
3366 ashrhi3_out (rtx insn, rtx operands[], int *len)
3367 {
3368   if (GET_CODE (operands[2]) == CONST_INT)
3369     {
3370       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3371       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3372       int k;
3373       int *t = len;
3374       
3375       if (!len)
3376         len = &k;
3377
3378       switch (INTVAL (operands[2]))
3379         {
3380         case 4:
3381         case 5:
3382           /* XXX try to optimize this too? */
3383           break;
3384
3385         case 6:
3386           if (optimize_size)
3387             break;  /* scratch ? 5 : 6 */
3388           *len = 8;
3389           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3390                   AS2 (mov,%A0,%B0)         CR_TAB
3391                   AS1 (lsl,__tmp_reg__)     CR_TAB
3392                   AS1 (rol,%A0)             CR_TAB
3393                   AS2 (sbc,%B0,%B0)         CR_TAB
3394                   AS1 (lsl,__tmp_reg__)     CR_TAB
3395                   AS1 (rol,%A0)             CR_TAB
3396                   AS1 (rol,%B0));
3397
3398         case 7:
3399           *len = 4;
3400           return (AS1 (lsl,%A0)     CR_TAB
3401                   AS2 (mov,%A0,%B0) CR_TAB
3402                   AS1 (rol,%A0)     CR_TAB
3403                   AS2 (sbc,%B0,%B0));
3404
3405         case 8:
3406           {
3407             int reg0 = true_regnum (operands[0]);
3408             int reg1 = true_regnum (operands[1]);
3409
3410             if (reg0 == reg1)
3411               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3412                                 AS1 (lsl,%B0)     CR_TAB
3413                                 AS2 (sbc,%B0,%B0));
3414             else if (reg0 == reg1 + 1)
3415               return *len = 3, (AS1 (clr,%B0)    CR_TAB
3416                                 AS2 (sbrc,%A0,7) CR_TAB
3417                                 AS1 (dec,%B0));
3418
3419             return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3420                               AS1 (clr,%B0)     CR_TAB
3421                               AS2 (sbrc,%A0,7)  CR_TAB
3422                               AS1 (dec,%B0));
3423           }
3424
3425         case 9:
3426           *len = 4;
3427           return (AS2 (mov,%A0,%B0) CR_TAB
3428                   AS1 (lsl,%B0)      CR_TAB
3429                   AS2 (sbc,%B0,%B0) CR_TAB
3430                   AS1 (asr,%A0));
3431
3432         case 10:
3433           *len = 5;
3434           return (AS2 (mov,%A0,%B0) CR_TAB
3435                   AS1 (lsl,%B0)     CR_TAB
3436                   AS2 (sbc,%B0,%B0) CR_TAB
3437                   AS1 (asr,%A0)     CR_TAB
3438                   AS1 (asr,%A0));
3439
3440         case 11:
3441           if (AVR_ENHANCED && ldi_ok)
3442             {
3443               *len = 5;
3444               return (AS2 (ldi,%A0,0x20) CR_TAB
3445                       AS2 (muls,%B0,%A0) CR_TAB
3446                       AS2 (mov,%A0,r1)   CR_TAB
3447                       AS2 (sbc,%B0,%B0)  CR_TAB
3448                       AS1 (clr,__zero_reg__));
3449             }
3450           if (optimize_size && scratch)
3451             break;  /* 5 */
3452           *len = 6;
3453           return (AS2 (mov,%A0,%B0) CR_TAB
3454                   AS1 (lsl,%B0)     CR_TAB
3455                   AS2 (sbc,%B0,%B0) CR_TAB
3456                   AS1 (asr,%A0)     CR_TAB
3457                   AS1 (asr,%A0)     CR_TAB
3458                   AS1 (asr,%A0));
3459
3460         case 12:
3461           if (AVR_ENHANCED && ldi_ok)
3462             {
3463               *len = 5;
3464               return (AS2 (ldi,%A0,0x10) CR_TAB
3465                       AS2 (muls,%B0,%A0) CR_TAB
3466                       AS2 (mov,%A0,r1)   CR_TAB
3467                       AS2 (sbc,%B0,%B0)  CR_TAB
3468                       AS1 (clr,__zero_reg__));
3469             }
3470           if (optimize_size && scratch)
3471             break;  /* 5 */
3472           *len = 7;
3473           return (AS2 (mov,%A0,%B0) CR_TAB
3474                   AS1 (lsl,%B0)     CR_TAB
3475                   AS2 (sbc,%B0,%B0) CR_TAB
3476                   AS1 (asr,%A0)     CR_TAB
3477                   AS1 (asr,%A0)     CR_TAB
3478                   AS1 (asr,%A0)     CR_TAB
3479                   AS1 (asr,%A0));
3480
3481         case 13:
3482           if (AVR_ENHANCED && ldi_ok)
3483             {
3484               *len = 5;
3485               return (AS2 (ldi,%A0,0x08) CR_TAB
3486                       AS2 (muls,%B0,%A0) CR_TAB
3487                       AS2 (mov,%A0,r1)   CR_TAB
3488                       AS2 (sbc,%B0,%B0)  CR_TAB
3489                       AS1 (clr,__zero_reg__));
3490             }
3491           if (optimize_size)
3492             break;  /* scratch ? 5 : 7 */
3493           *len = 8;
3494           return (AS2 (mov,%A0,%B0) CR_TAB
3495                   AS1 (lsl,%B0)     CR_TAB
3496                   AS2 (sbc,%B0,%B0) CR_TAB
3497                   AS1 (asr,%A0)     CR_TAB
3498                   AS1 (asr,%A0)     CR_TAB
3499                   AS1 (asr,%A0)     CR_TAB
3500                   AS1 (asr,%A0)     CR_TAB
3501                   AS1 (asr,%A0));
3502
3503         case 14:
3504           *len = 5;
3505           return (AS1 (lsl,%B0)     CR_TAB
3506                   AS2 (sbc,%A0,%A0) CR_TAB
3507                   AS1 (lsl,%B0)     CR_TAB
3508                   AS2 (mov,%B0,%A0) CR_TAB
3509                   AS1 (rol,%A0));
3510
3511         case 15:
3512           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
3513                             AS2 (sbc,%A0,%A0) CR_TAB
3514                             AS2 (mov,%B0,%A0));
3515         }
3516       len = t;
3517     }
3518   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3519                        AS1 (ror,%A0)),
3520                        insn, operands, len, 2);
3521   return "";
3522 }
3523
3524
3525 /* 32bit arithmetic shift right  ((signed long)x >> i) */
3526
3527 const char *
3528 ashrsi3_out (rtx insn, rtx operands[], int *len)
3529 {
3530   if (GET_CODE (operands[2]) == CONST_INT)
3531     {
3532       int k;
3533       int *t = len;
3534       
3535       if (!len)
3536         len = &k;
3537       
3538       switch (INTVAL (operands[2]))
3539         {
3540         case 8:
3541           {
3542             int reg0 = true_regnum (operands[0]);
3543             int reg1 = true_regnum (operands[1]);
3544             *len=6;
3545             if (reg0 <= reg1)
3546               return (AS2 (mov,%A0,%B1) CR_TAB
3547                       AS2 (mov,%B0,%C1) CR_TAB
3548                       AS2 (mov,%C0,%D1) CR_TAB
3549                       AS1 (clr,%D0)     CR_TAB
3550                       AS2 (sbrc,%C0,7)  CR_TAB
3551                       AS1 (dec,%D0));
3552             else if (reg0 == reg1 + 1)
3553               {
3554                 *len = 3;
3555                 return (AS1 (clr,%D0)     CR_TAB
3556                         AS2 (sbrc,%C0,7)  CR_TAB
3557                         AS1 (dec,%D0));
3558               }
3559             else
3560               return (AS1 (clr,%D0)     CR_TAB
3561                       AS2 (sbrc,%D1,7)  CR_TAB
3562                       AS1 (dec,%D0)     CR_TAB
3563                       AS2 (mov,%C0,%D1) CR_TAB
3564                       AS2 (mov,%B0,%C1) CR_TAB
3565                       AS2 (mov,%A0,%B1));
3566           }
3567           
3568         case 16:
3569           {
3570             int reg0 = true_regnum (operands[0]);
3571             int reg1 = true_regnum (operands[1]);
3572             *len=6;
3573             if (AVR_ENHANCED && (reg0 != reg1 + 2))
3574               {
3575                 *len = 5;
3576                 return (AS2 (movw,%A0,%C1) CR_TAB
3577                         AS1 (clr,%D0)      CR_TAB
3578                         AS2 (sbrc,%B0,7)   CR_TAB
3579                         AS1 (com,%D0)      CR_TAB
3580                         AS2 (mov,%C0,%D0));
3581               }
3582             if (reg0 <= reg1 + 1)
3583               return (AS2 (mov,%A0,%C1) CR_TAB
3584                       AS2 (mov,%B0,%D1) CR_TAB
3585                       AS1 (clr,%D0)     CR_TAB
3586                       AS2 (sbrc,%B0,7)  CR_TAB
3587                       AS1 (com,%D0)     CR_TAB
3588                       AS2 (mov,%C0,%D0));
3589             else if (reg0 == reg1 + 2)
3590               return *len = 4, (AS1 (clr,%D0)     CR_TAB
3591                                 AS2 (sbrc,%B0,7)  CR_TAB
3592                                 AS1 (com,%D0)     CR_TAB
3593                                 AS2 (mov,%C0,%D0));
3594             else
3595               return (AS2 (mov,%B0,%D1) CR_TAB
3596                       AS2 (mov,%A0,%C1) CR_TAB
3597                       AS1 (clr,%D0)     CR_TAB
3598                       AS2 (sbrc,%B0,7)  CR_TAB
3599                       AS1 (com,%D0)     CR_TAB
3600                       AS2 (mov,%C0,%D0));
3601           }
3602
3603         case 24:
3604           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3605             return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3606                               AS1 (clr,%D0)     CR_TAB
3607                               AS2 (sbrc,%A0,7)  CR_TAB
3608                               AS1 (com,%D0)     CR_TAB
3609                               AS2 (mov,%B0,%D0) CR_TAB
3610                               AS2 (mov,%C0,%D0));
3611           else
3612             return *len = 5, (AS1 (clr,%D0)     CR_TAB
3613                               AS2 (sbrc,%A0,7)  CR_TAB
3614                               AS1 (com,%D0)     CR_TAB
3615                               AS2 (mov,%B0,%D0) CR_TAB
3616                               AS2 (mov,%C0,%D0));
3617
3618         case 31:
3619           if (AVR_ENHANCED)
3620             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
3621                               AS2 (sbc,%A0,%A0) CR_TAB
3622                               AS2 (mov,%B0,%A0) CR_TAB
3623                               AS2 (movw,%C0,%A0));
3624           else
3625             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
3626                               AS2 (sbc,%A0,%A0) CR_TAB
3627                               AS2 (mov,%B0,%A0) CR_TAB
3628                               AS2 (mov,%C0,%A0) CR_TAB
3629                               AS2 (mov,%D0,%A0));
3630         }
3631       len = t;
3632     }
3633   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3634                        AS1 (ror,%C0) CR_TAB
3635                        AS1 (ror,%B0) CR_TAB
3636                        AS1 (ror,%A0)),
3637                        insn, operands, len, 4);
3638   return "";
3639 }
3640
3641 /* 8bit logic shift right ((unsigned char)x >> i) */
3642
3643 const char *
3644 lshrqi3_out (rtx insn, rtx operands[], int *len)
3645 {
3646   if (GET_CODE (operands[2]) == CONST_INT)
3647     {
3648       int k;
3649
3650       if (!len)
3651         len = &k;
3652       
3653       switch (INTVAL (operands[2]))
3654         {
3655         default:
3656           *len = 1;
3657           return AS1 (clr,%0);
3658
3659         case 1:
3660           *len = 1;
3661           return AS1 (lsr,%0);
3662
3663         case 2:
3664           *len = 2;
3665           return (AS1 (lsr,%0) CR_TAB
3666                   AS1 (lsr,%0));
3667         case 3:
3668           *len = 3;
3669           return (AS1 (lsr,%0) CR_TAB
3670                   AS1 (lsr,%0) CR_TAB
3671                   AS1 (lsr,%0));
3672           
3673         case 4:
3674           if (test_hard_reg_class (LD_REGS, operands[0]))
3675             {
3676               *len=2;
3677               return (AS1 (swap,%0) CR_TAB
3678                       AS2 (andi,%0,0x0f));
3679             }
3680           *len = 4;
3681           return (AS1 (lsr,%0) CR_TAB
3682                   AS1 (lsr,%0) CR_TAB
3683                   AS1 (lsr,%0) CR_TAB
3684                   AS1 (lsr,%0));
3685           
3686         case 5:
3687           if (test_hard_reg_class (LD_REGS, operands[0]))
3688             {
3689               *len = 3;
3690               return (AS1 (swap,%0) CR_TAB
3691                       AS1 (lsr,%0)  CR_TAB
3692                       AS2 (andi,%0,0x7));
3693             }
3694           *len = 5;
3695           return (AS1 (lsr,%0) CR_TAB
3696                   AS1 (lsr,%0) CR_TAB
3697                   AS1 (lsr,%0) CR_TAB
3698                   AS1 (lsr,%0) CR_TAB
3699                   AS1 (lsr,%0));
3700           
3701         case 6:
3702           if (test_hard_reg_class (LD_REGS, operands[0]))
3703             {
3704               *len = 4;
3705               return (AS1 (swap,%0) CR_TAB
3706                       AS1 (lsr,%0)  CR_TAB
3707                       AS1 (lsr,%0)  CR_TAB
3708                       AS2 (andi,%0,0x3));
3709             }
3710           *len = 6;
3711           return (AS1 (lsr,%0) CR_TAB
3712                   AS1 (lsr,%0) CR_TAB
3713                   AS1 (lsr,%0) CR_TAB
3714                   AS1 (lsr,%0) CR_TAB
3715                   AS1 (lsr,%0) CR_TAB
3716                   AS1 (lsr,%0));
3717           
3718         case 7:
3719           *len = 3;
3720           return (AS1 (rol,%0) CR_TAB
3721                   AS1 (clr,%0) CR_TAB
3722                   AS1 (rol,%0));
3723         }
3724     }
3725   else if (CONSTANT_P (operands[2]))
3726     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3727   
3728   out_shift_with_cnt (AS1 (lsr,%0),
3729                       insn, operands, len, 1);
3730   return "";
3731 }
3732
3733 /* 16bit logic shift right ((unsigned short)x >> i) */
3734
3735 const char *
3736 lshrhi3_out (rtx insn, rtx operands[], int *len)
3737 {
3738   if (GET_CODE (operands[2]) == CONST_INT)
3739     {
3740       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3741       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3742       int k;
3743       int *t = len;
3744
3745       if (!len)
3746         len = &k;
3747       
3748       switch (INTVAL (operands[2]))
3749         {
3750         case 4:
3751           if (optimize_size && scratch)
3752             break;  /* 5 */
3753           if (ldi_ok)
3754             {
3755               *len = 6;
3756               return (AS1 (swap,%B0)      CR_TAB
3757                       AS1 (swap,%A0)      CR_TAB
3758                       AS2 (andi,%A0,0x0f) CR_TAB
3759                       AS2 (eor,%A0,%B0)   CR_TAB
3760                       AS2 (andi,%B0,0x0f) CR_TAB
3761                       AS2 (eor,%A0,%B0));
3762             }
3763           if (scratch)
3764             {
3765               *len = 7;
3766               return (AS1 (swap,%B0)    CR_TAB
3767                       AS1 (swap,%A0)    CR_TAB
3768                       AS2 (ldi,%3,0x0f) CR_TAB
3769                       AS2 (and,%A0,%3)  CR_TAB
3770                       AS2 (eor,%A0,%B0) CR_TAB
3771                       AS2 (and,%B0,%3)  CR_TAB
3772                       AS2 (eor,%A0,%B0));
3773             }
3774           break;  /* optimize_size ? 6 : 8 */
3775
3776         case 5:
3777           if (optimize_size)
3778             break;  /* scratch ? 5 : 6 */
3779           if (ldi_ok)
3780             {
3781               *len = 8;
3782               return (AS1 (lsr,%B0)       CR_TAB
3783                       AS1 (ror,%A0)       CR_TAB
3784                       AS1 (swap,%B0)      CR_TAB
3785                       AS1 (swap,%A0)      CR_TAB
3786                       AS2 (andi,%A0,0x0f) CR_TAB
3787                       AS2 (eor,%A0,%B0)   CR_TAB
3788                       AS2 (andi,%B0,0x0f) CR_TAB
3789                       AS2 (eor,%A0,%B0));
3790             }
3791           if (scratch)
3792             {
3793               *len = 9;
3794               return (AS1 (lsr,%B0)     CR_TAB
3795                       AS1 (ror,%A0)     CR_TAB
3796                       AS1 (swap,%B0)    CR_TAB
3797                       AS1 (swap,%A0)    CR_TAB
3798                       AS2 (ldi,%3,0x0f) CR_TAB
3799                       AS2 (and,%A0,%3)  CR_TAB
3800                       AS2 (eor,%A0,%B0) CR_TAB
3801                       AS2 (and,%B0,%3)  CR_TAB
3802                       AS2 (eor,%A0,%B0));
3803             }
3804           break;  /* 10 */
3805
3806         case 6:
3807           if (optimize_size)
3808             break;  /* scratch ? 5 : 6 */
3809           *len = 9;
3810           return (AS1 (clr,__tmp_reg__) CR_TAB
3811                   AS1 (lsl,%A0)         CR_TAB
3812                   AS1 (rol,%B0)         CR_TAB
3813                   AS1 (rol,__tmp_reg__) CR_TAB
3814                   AS1 (lsl,%A0)         CR_TAB
3815                   AS1 (rol,%B0)         CR_TAB
3816                   AS1 (rol,__tmp_reg__) CR_TAB
3817                   AS2 (mov,%A0,%B0)     CR_TAB
3818                   AS2 (mov,%B0,__tmp_reg__));
3819
3820         case 7:
3821           *len = 5;
3822           return (AS1 (lsl,%A0)     CR_TAB
3823                   AS2 (mov,%A0,%B0) CR_TAB
3824                   AS1 (rol,%A0)     CR_TAB
3825                   AS2 (sbc,%B0,%B0) CR_TAB
3826                   AS1 (neg,%B0));
3827
3828         case 8:
3829           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3830             return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3831                               AS1 (clr,%B0));
3832           else
3833             return *len = 1, AS1 (clr,%B0);
3834
3835         case 9:
3836           *len = 3;
3837           return (AS2 (mov,%A0,%B0) CR_TAB
3838                   AS1 (clr,%B0)     CR_TAB
3839                   AS1 (lsr,%A0));
3840
3841         case 10:
3842           *len = 4;
3843           return (AS2 (mov,%A0,%B0) CR_TAB
3844                   AS1 (clr,%B0)     CR_TAB
3845                   AS1 (lsr,%A0)     CR_TAB
3846                   AS1 (lsr,%A0));
3847
3848         case 11:
3849           *len = 5;
3850           return (AS2 (mov,%A0,%B0) CR_TAB
3851                   AS1 (clr,%B0)     CR_TAB
3852                   AS1 (lsr,%A0)     CR_TAB
3853                   AS1 (lsr,%A0)     CR_TAB
3854                   AS1 (lsr,%A0));
3855
3856         case 12:
3857           if (ldi_ok)
3858             {
3859               *len = 4;
3860               return (AS2 (mov,%A0,%B0) CR_TAB
3861                       AS1 (clr,%B0)     CR_TAB
3862                       AS1 (swap,%A0)    CR_TAB
3863                       AS2 (andi,%A0,0x0f));
3864             }
3865           if (scratch)
3866             {
3867               *len = 5;
3868               return (AS2 (mov,%A0,%B0) CR_TAB
3869                       AS1 (clr,%B0)     CR_TAB
3870                       AS1 (swap,%A0)    CR_TAB
3871                       AS2 (ldi,%3,0x0f) CR_TAB
3872                       AS2 (and,%A0,%3));
3873             }
3874           *len = 6;
3875           return (AS2 (mov,%A0,%B0) CR_TAB
3876                   AS1 (clr,%B0)     CR_TAB
3877                   AS1 (lsr,%A0)     CR_TAB
3878                   AS1 (lsr,%A0)     CR_TAB
3879                   AS1 (lsr,%A0)     CR_TAB
3880                   AS1 (lsr,%A0));
3881
3882         case 13:
3883           if (ldi_ok)
3884             {
3885               *len = 5;
3886               return (AS2 (mov,%A0,%B0) CR_TAB
3887                       AS1 (clr,%B0)     CR_TAB
3888                       AS1 (swap,%A0)    CR_TAB
3889                       AS1 (lsr,%A0)     CR_TAB
3890                       AS2 (andi,%A0,0x07));
3891             }
3892           if (AVR_ENHANCED && scratch)
3893             {
3894               *len = 5;
3895               return (AS2 (ldi,%3,0x08) CR_TAB
3896                       AS2 (mul,%B0,%3)  CR_TAB
3897                       AS2 (mov,%A0,r1)  CR_TAB
3898                       AS1 (clr,%B0)     CR_TAB
3899                       AS1 (clr,__zero_reg__));
3900             }
3901           if (optimize_size && scratch)
3902             break;  /* 5 */
3903           if (scratch)
3904             {
3905               *len = 6;
3906               return (AS2 (mov,%A0,%B0) CR_TAB
3907                       AS1 (clr,%B0)     CR_TAB
3908                       AS1 (swap,%A0)    CR_TAB
3909                       AS1 (lsr,%A0)     CR_TAB
3910                       AS2 (ldi,%3,0x07) CR_TAB
3911                       AS2 (and,%A0,%3));
3912             }
3913           if (AVR_ENHANCED)
3914             {
3915               *len = 6;
3916               return ("set"            CR_TAB
3917                       AS2 (bld,r1,3)   CR_TAB
3918                       AS2 (mul,%B0,r1) CR_TAB
3919                       AS2 (mov,%A0,r1) CR_TAB
3920                       AS1 (clr,%B0)    CR_TAB
3921                       AS1 (clr,__zero_reg__));
3922             }
3923           *len = 7;
3924           return (AS2 (mov,%A0,%B0) CR_TAB
3925                   AS1 (clr,%B0)     CR_TAB
3926                   AS1 (lsr,%A0)     CR_TAB
3927                   AS1 (lsr,%A0)     CR_TAB
3928                   AS1 (lsr,%A0)     CR_TAB
3929                   AS1 (lsr,%A0)     CR_TAB
3930                   AS1 (lsr,%A0));
3931
3932         case 14:
3933           if (AVR_ENHANCED && ldi_ok)
3934             {
3935               *len = 5;
3936               return (AS2 (ldi,%A0,0x04) CR_TAB
3937                       AS2 (mul,%B0,%A0)  CR_TAB
3938                       AS2 (mov,%A0,r1)   CR_TAB
3939                       AS1 (clr,%B0)      CR_TAB
3940                       AS1 (clr,__zero_reg__));
3941             }
3942           if (AVR_ENHANCED && scratch)
3943             {
3944               *len = 5;
3945               return (AS2 (ldi,%3,0x04) CR_TAB
3946                       AS2 (mul,%B0,%3)  CR_TAB
3947                       AS2 (mov,%A0,r1)  CR_TAB
3948                       AS1 (clr,%B0)     CR_TAB
3949                       AS1 (clr,__zero_reg__));
3950             }
3951           if (optimize_size && ldi_ok)
3952             {
3953               *len = 5;
3954               return (AS2 (mov,%A0,%B0) CR_TAB
3955                       AS2 (ldi,%B0,6) "\n1:\t"
3956                       AS1 (lsr,%A0)     CR_TAB
3957                       AS1 (dec,%B0)     CR_TAB
3958                       AS1 (brne,1b));
3959             }
3960           if (optimize_size && scratch)
3961             break;  /* 5 */
3962           *len = 6;
3963           return (AS1 (clr,%A0) CR_TAB
3964                   AS1 (lsl,%B0) CR_TAB
3965                   AS1 (rol,%A0) CR_TAB
3966                   AS1 (lsl,%B0) CR_TAB
3967                   AS1 (rol,%A0) CR_TAB
3968                   AS1 (clr,%B0));
3969
3970         case 15:
3971           *len = 4;
3972           return (AS1 (clr,%A0) CR_TAB
3973                   AS1 (lsl,%B0) CR_TAB
3974                   AS1 (rol,%A0) CR_TAB
3975                   AS1 (clr,%B0));
3976         }
3977       len = t;
3978     }
3979   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
3980                        AS1 (ror,%A0)),
3981                        insn, operands, len, 2);
3982   return "";
3983 }
3984
3985 /* 32bit logic shift right ((unsigned int)x >> i) */
3986
3987 const char *
3988 lshrsi3_out (rtx insn, rtx operands[], int *len)
3989 {
3990   if (GET_CODE (operands[2]) == CONST_INT)
3991     {
3992       int k;
3993       int *t = len;
3994       
3995       if (!len)
3996         len = &k;
3997       
3998       switch (INTVAL (operands[2]))
3999         {
4000         case 8:
4001           {
4002             int reg0 = true_regnum (operands[0]);
4003             int reg1 = true_regnum (operands[1]);
4004             *len = 4;
4005             if (reg0 <= reg1)
4006               return (AS2 (mov,%A0,%B1) CR_TAB
4007                       AS2 (mov,%B0,%C1) CR_TAB
4008                       AS2 (mov,%C0,%D1) CR_TAB
4009                       AS1 (clr,%D0));
4010             else if (reg0 == reg1 + 1)
4011               return *len = 1, AS1 (clr,%D0);
4012             else
4013               return (AS1 (clr,%D0)     CR_TAB
4014                       AS2 (mov,%C0,%D1) CR_TAB
4015                       AS2 (mov,%B0,%C1) CR_TAB
4016                       AS2 (mov,%A0,%B1)); 
4017           }
4018           
4019         case 16:
4020           {
4021             int reg0 = true_regnum (operands[0]);
4022             int reg1 = true_regnum (operands[1]);
4023             *len = 4;
4024             if (AVR_ENHANCED && (reg0 != reg1 + 2))
4025               {
4026                 *len = 3;
4027                 return (AS2 (movw,%A0,%C1) CR_TAB
4028                         AS1 (clr,%C0)      CR_TAB
4029                         AS1 (clr,%D0));
4030               }
4031             if (reg0 <= reg1 + 1)
4032               return (AS2 (mov,%A0,%C1) CR_TAB
4033                       AS2 (mov,%B0,%D1) CR_TAB
4034                       AS1 (clr,%C0)     CR_TAB
4035                       AS1 (clr,%D0));
4036             else if (reg0 == reg1 + 2)
4037               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4038                                 AS1 (clr,%D0));
4039             else
4040               return (AS2 (mov,%B0,%D1) CR_TAB
4041                       AS2 (mov,%A0,%C1) CR_TAB
4042                       AS1 (clr,%C0)     CR_TAB
4043                       AS1 (clr,%D0));
4044           }
4045           
4046         case 24:
4047           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
4048             return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4049                               AS1 (clr,%B0)     CR_TAB
4050                               AS1 (clr,%C0)     CR_TAB
4051                               AS1 (clr,%D0));
4052           else
4053             return *len = 3, (AS1 (clr,%B0)     CR_TAB
4054                               AS1 (clr,%C0)     CR_TAB
4055                               AS1 (clr,%D0));
4056
4057         case 31:
4058           *len = 6;
4059           return (AS1 (clr,%A0)    CR_TAB
4060                   AS2 (sbrc,%D0,7) CR_TAB
4061                   AS1 (inc,%A0)    CR_TAB
4062                   AS1 (clr,%B0)    CR_TAB
4063                   AS1 (clr,%C0)    CR_TAB
4064                   AS1 (clr,%D0));
4065         }
4066       len = t;
4067     }
4068   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4069                        AS1 (ror,%C0) CR_TAB
4070                        AS1 (ror,%B0) CR_TAB
4071                        AS1 (ror,%A0)),
4072                       insn, operands, len, 4);
4073   return "";
4074 }
4075
4076 /* Modifies the length assigned to instruction INSN
4077  LEN is the initially computed length of the insn.  */
4078
4079 int
4080 adjust_insn_length (rtx insn, int len)
4081 {
4082   rtx patt = PATTERN (insn);
4083   rtx set;
4084
4085   if (GET_CODE (patt) == SET)
4086     {
4087       rtx op[10];
4088       op[1] = SET_SRC (patt);
4089       op[0] = SET_DEST (patt);
4090       if (general_operand (op[1], VOIDmode)
4091           && general_operand (op[0], VOIDmode))
4092         {
4093           switch (GET_MODE (op[0]))
4094             {
4095             case QImode:
4096               output_movqi (insn, op, &len);
4097               break;
4098             case HImode:
4099               output_movhi (insn, op, &len);
4100               break;
4101             case SImode:
4102             case SFmode:
4103               output_movsisf (insn, op, &len);
4104               break;
4105             default:
4106               break;
4107             }
4108         }
4109       else if (op[0] == cc0_rtx && REG_P (op[1]))
4110         {
4111           switch (GET_MODE (op[1]))
4112             {
4113             case HImode: out_tsthi (insn,&len); break;
4114             case SImode: out_tstsi (insn,&len); break;
4115             default: break;
4116             }
4117         }
4118       else if (GET_CODE (op[1]) == AND)
4119         {
4120           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4121             {
4122               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4123               if (GET_MODE (op[1]) == SImode)
4124                 len = (((mask & 0xff) != 0xff)
4125                        + ((mask & 0xff00) != 0xff00)
4126                        + ((mask & 0xff0000L) != 0xff0000L)
4127                        + ((mask & 0xff000000L) != 0xff000000L));
4128               else if (GET_MODE (op[1]) == HImode)
4129                 len = (((mask & 0xff) != 0xff)
4130                        + ((mask & 0xff00) != 0xff00));
4131             }
4132         }
4133       else if (GET_CODE (op[1]) == IOR)
4134         {
4135           if (GET_CODE (XEXP (op[1],1)) == CONST_INT)
4136             {
4137               HOST_WIDE_INT mask = INTVAL (XEXP (op[1],1));
4138               if (GET_MODE (op[1]) == SImode)
4139                 len = (((mask & 0xff) != 0)
4140                        + ((mask & 0xff00) != 0)
4141                        + ((mask & 0xff0000L) != 0)
4142                        + ((mask & 0xff000000L) != 0));
4143               else if (GET_MODE (op[1]) == HImode)
4144                 len = (((mask & 0xff) != 0)
4145                        + ((mask & 0xff00) != 0));
4146             }
4147         }
4148     }
4149   set = single_set (insn);
4150   if (set)
4151     {
4152       rtx op[10];
4153
4154       op[1] = SET_SRC (set);
4155       op[0] = SET_DEST (set);
4156
4157       if (GET_CODE (patt) == PARALLEL
4158           && general_operand (op[1], VOIDmode)
4159           && general_operand (op[0], VOIDmode))
4160         {
4161           if (XVECLEN (patt, 0) == 2)
4162             op[2] = XVECEXP (patt, 0, 1);
4163
4164           switch (GET_MODE (op[0]))
4165             {
4166             case QImode:
4167               len = 2;
4168               break;
4169             case HImode:
4170               output_reload_inhi (insn, op, &len);
4171               break;
4172             case SImode:
4173             case SFmode:
4174               output_reload_insisf (insn, op, &len);
4175               break;
4176             default:
4177               break;
4178             }
4179         }
4180       else if (GET_CODE (op[1]) == ASHIFT
4181           || GET_CODE (op[1]) == ASHIFTRT
4182           || GET_CODE (op[1]) == LSHIFTRT)
4183         {
4184           rtx ops[10];
4185           ops[0] = op[0];
4186           ops[1] = XEXP (op[1],0);
4187           ops[2] = XEXP (op[1],1);
4188           switch (GET_CODE (op[1]))
4189             {
4190             case ASHIFT:
4191               switch (GET_MODE (op[0]))
4192                 {
4193                 case QImode: ashlqi3_out (insn,ops,&len); break;
4194                 case HImode: ashlhi3_out (insn,ops,&len); break;
4195                 case SImode: ashlsi3_out (insn,ops,&len); break;
4196                 default: break;
4197                 }
4198               break;
4199             case ASHIFTRT:
4200               switch (GET_MODE (op[0]))
4201                 {
4202                 case QImode: ashrqi3_out (insn,ops,&len); break;
4203                 case HImode: ashrhi3_out (insn,ops,&len); break;
4204                 case SImode: ashrsi3_out (insn,ops,&len); break;
4205                 default: break;
4206                 }
4207               break;
4208             case LSHIFTRT:
4209               switch (GET_MODE (op[0]))
4210                 {
4211                 case QImode: lshrqi3_out (insn,ops,&len); break;
4212                 case HImode: lshrhi3_out (insn,ops,&len); break;
4213                 case SImode: lshrsi3_out (insn,ops,&len); break;
4214                 default: break;
4215                 }
4216               break;
4217             default:
4218               break;
4219             }
4220         }
4221     }
4222   return len;
4223 }
4224
4225 /* Return nonzero if register REG dead after INSN.  */
4226
4227 int
4228 reg_unused_after (rtx insn, rtx reg)
4229 {
4230   return (dead_or_set_p (insn, reg)
4231           || (REG_P(reg) && _reg_unused_after (insn, reg)));
4232 }
4233
4234 /* Return nonzero if REG is not used after INSN.
4235    We assume REG is a reload reg, and therefore does
4236    not live past labels.  It may live past calls or jumps though.  */
4237
4238 int
4239 _reg_unused_after (rtx insn, rtx reg)
4240 {
4241   enum rtx_code code;
4242   rtx set;
4243
4244   /* If the reg is set by this instruction, then it is safe for our
4245      case.  Disregard the case where this is a store to memory, since
4246      we are checking a register used in the store address.  */
4247   set = single_set (insn);
4248   if (set && GET_CODE (SET_DEST (set)) != MEM
4249       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4250     return 1;
4251
4252   while ((insn = NEXT_INSN (insn)))
4253     {
4254       rtx set;
4255       code = GET_CODE (insn);
4256
4257 #if 0
4258       /* If this is a label that existed before reload, then the register
4259          if dead here.  However, if this is a label added by reorg, then
4260          the register may still be live here.  We can't tell the difference,
4261          so we just ignore labels completely.  */
4262       if (code == CODE_LABEL)
4263         return 1;
4264       /* else */
4265 #endif
4266
4267       if (!INSN_P (insn))
4268         continue;
4269
4270       if (code == JUMP_INSN)
4271         return 0;
4272
4273       /* If this is a sequence, we must handle them all at once.
4274          We could have for instance a call that sets the target register,
4275          and an insn in a delay slot that uses the register.  In this case,
4276          we must return 0.  */
4277       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
4278         {
4279           int i;
4280           int retval = 0;
4281
4282           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
4283             {
4284               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
4285               rtx set = single_set (this_insn);
4286
4287               if (GET_CODE (this_insn) == CALL_INSN)
4288                 code = CALL_INSN;
4289               else if (GET_CODE (this_insn) == JUMP_INSN)
4290                 {
4291                   if (INSN_ANNULLED_BRANCH_P (this_insn))
4292                     return 0;
4293                   code = JUMP_INSN;
4294                 }
4295
4296               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4297                 return 0;
4298               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4299                 {
4300                   if (GET_CODE (SET_DEST (set)) != MEM)
4301                     retval = 1;
4302                   else
4303                     return 0;
4304                 }
4305               if (set == 0
4306                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
4307                 return 0;
4308             }
4309           if (retval == 1)
4310             return 1;
4311           else if (code == JUMP_INSN)
4312             return 0;
4313         }
4314
4315       if (code == CALL_INSN)
4316         {
4317           rtx tem;
4318           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
4319             if (GET_CODE (XEXP (tem, 0)) == USE
4320                 && REG_P (XEXP (XEXP (tem, 0), 0))
4321                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
4322               return 0;
4323           if (call_used_regs[REGNO (reg)]) 
4324             return 1;
4325         }
4326
4327       set = single_set (insn);
4328
4329       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
4330         return 0;
4331       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
4332         return GET_CODE (SET_DEST (set)) != MEM;
4333       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
4334         return 0;
4335     }
4336   return 1;
4337 }
4338
4339 /* Target hook for assembling integer objects.  The AVR version needs
4340    special handling for references to certain labels.  */
4341
4342 static bool
4343 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
4344 {
4345   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
4346       && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
4347           || GET_CODE (x) == LABEL_REF))
4348     {
4349       fputs ("\t.word\tpm(", asm_out_file);
4350       output_addr_const (asm_out_file, x);
4351       fputs (")\n", asm_out_file);
4352       return true;
4353     }
4354   return default_assemble_integer (x, size, aligned_p);
4355 }
4356
4357 /* Sets section name for declaration DECL.  */
4358   
4359 static void
4360 avr_unique_section (tree decl, int reloc ATTRIBUTE_UNUSED)
4361 {
4362   int len;
4363   const char *name, *prefix;
4364   char *string;
4365
4366   name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
4367   name = (* targetm.strip_name_encoding) (name);
4368
4369   if (TREE_CODE (decl) == FUNCTION_DECL)
4370     {
4371       if (flag_function_sections)
4372         prefix = ".text.";
4373       else
4374         prefix = ".text";
4375     }
4376   else 
4377     abort ();
4378
4379   if (flag_function_sections)
4380     {
4381       len = strlen (name) + strlen (prefix);
4382       string = alloca (len + 1);
4383       sprintf (string, "%s%s", prefix, name);
4384       DECL_SECTION_NAME (decl) = build_string (len, string);
4385     }
4386 }
4387
4388
4389 /* The routine used to output NUL terminated strings.  We use a special
4390    version of this for most svr4 targets because doing so makes the
4391    generated assembly code more compact (and thus faster to assemble)
4392    as well as more readable, especially for targets like the i386
4393    (where the only alternative is to output character sequences as
4394    comma separated lists of numbers).  */
4395
4396 void
4397 gas_output_limited_string(FILE *file, const char *str)
4398 {
4399   const unsigned char *_limited_str = (unsigned char *) str;
4400   unsigned ch;
4401   fprintf (file, "%s\"", STRING_ASM_OP);
4402   for (; (ch = *_limited_str); _limited_str++)
4403     {
4404       int escape;
4405       switch (escape = ESCAPES[ch])
4406         {
4407         case 0:
4408           putc (ch, file);
4409           break;
4410         case 1:
4411           fprintf (file, "\\%03o", ch);
4412           break;
4413         default:
4414           putc ('\\', file);
4415           putc (escape, file);
4416           break;
4417         }
4418     }
4419   fprintf (file, "\"\n");
4420 }
4421
4422 /* The routine used to output sequences of byte values.  We use a special
4423    version of this for most svr4 targets because doing so makes the
4424    generated assembly code more compact (and thus faster to assemble)
4425    as well as more readable.  Note that if we find subparts of the
4426    character sequence which end with NUL (and which are shorter than
4427    STRING_LIMIT) we output those using ASM_OUTPUT_LIMITED_STRING.  */
4428
4429 void
4430 gas_output_ascii(FILE *file, const char *str, size_t length)
4431 {
4432   const unsigned char *_ascii_bytes = (const unsigned char *) str;
4433   const unsigned char *limit = _ascii_bytes + length;
4434   unsigned bytes_in_chunk = 0;
4435   for (; _ascii_bytes < limit; _ascii_bytes++)
4436     {
4437       const unsigned char *p;
4438       if (bytes_in_chunk >= 60)
4439         {
4440           fprintf (file, "\"\n");
4441           bytes_in_chunk = 0;
4442         }
4443       for (p = _ascii_bytes; p < limit && *p != '\0'; p++)
4444         continue;
4445       if (p < limit && (p - _ascii_bytes) <= (signed)STRING_LIMIT)
4446         {
4447           if (bytes_in_chunk > 0)
4448             {
4449               fprintf (file, "\"\n");
4450               bytes_in_chunk = 0;
4451             }
4452           gas_output_limited_string (file, (char*)_ascii_bytes);
4453           _ascii_bytes = p;
4454         }
4455       else
4456         {
4457           int escape;
4458           unsigned ch;
4459           if (bytes_in_chunk == 0)
4460             fprintf (file, "\t.ascii\t\"");
4461           switch (escape = ESCAPES[ch = *_ascii_bytes])
4462             {
4463             case 0:
4464               putc (ch, file);
4465               bytes_in_chunk++;
4466               break;
4467             case 1:
4468               fprintf (file, "\\%03o", ch);
4469               bytes_in_chunk += 4;
4470               break;
4471             default:
4472               putc ('\\', file);
4473               putc (escape, file);
4474               bytes_in_chunk += 2;
4475               break;
4476             }
4477         }
4478     }
4479   if (bytes_in_chunk > 0)
4480     fprintf (file, "\"\n");
4481 }
4482
4483 /* Return value is nonzero if pseudos that have been
4484    assigned to registers of class CLASS would likely be spilled
4485    because registers of CLASS are needed for spill registers.  */
4486
4487 enum reg_class
4488 class_likely_spilled_p (int c)
4489 {
4490   return (c != ALL_REGS && c != ADDW_REGS);
4491 }
4492
4493 /* Valid attributes:
4494    progmem - put data to program memory;
4495    signal - make a function to be hardware interrupt. After function
4496    prologue interrupts are disabled;
4497    interrupt - make a function to be hardware interrupt. After function
4498    prologue interrupts are enabled;
4499    naked     - don't generate function prologue/epilogue and `ret' command.
4500
4501    Only `progmem' attribute valid for type.  */
4502
4503 const struct attribute_spec avr_attribute_table[] =
4504 {
4505   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
4506   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute },
4507   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute },
4508   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute },
4509   { "naked",     0, 0, true,  false, false,  avr_handle_fndecl_attribute },
4510   { NULL,        0, 0, false, false, false, NULL }
4511 };
4512
4513 /* Handle a "progmem" attribute; arguments as in
4514    struct attribute_spec.handler.  */
4515 static tree
4516 avr_handle_progmem_attribute (tree *node, tree name,
4517                               tree args ATTRIBUTE_UNUSED,
4518                               int flags ATTRIBUTE_UNUSED,
4519                               bool *no_add_attrs)
4520 {
4521   if (DECL_P (*node))
4522     {
4523       if (TREE_CODE (*node) == TYPE_DECL)
4524         {
4525           /* This is really a decl attribute, not a type attribute,
4526              but try to handle it for GCC 3.0 backwards compatibility.  */
4527
4528           tree type = TREE_TYPE (*node);
4529           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
4530           tree newtype = build_type_attribute_variant (type, attr);
4531
4532           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
4533           TREE_TYPE (*node) = newtype;
4534           *no_add_attrs = true;
4535         }
4536       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
4537         {
4538           if (DECL_INITIAL (*node) == NULL_TREE && !DECL_EXTERNAL (*node))
4539             {
4540               warning ("only initialized variables can be placed into "
4541                        "program memory area");
4542               *no_add_attrs = true;
4543             }
4544         }
4545       else
4546         {
4547           warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
4548           *no_add_attrs = true;
4549         }
4550     }
4551
4552   return NULL_TREE;
4553 }
4554
4555 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
4556    struct attribute_spec.handler.  */
4557
4558 static tree
4559 avr_handle_fndecl_attribute (tree *node, tree name,
4560                              tree args ATTRIBUTE_UNUSED,
4561                              int flags ATTRIBUTE_UNUSED,
4562                              bool *no_add_attrs)
4563 {
4564   if (TREE_CODE (*node) != FUNCTION_DECL)
4565     {
4566       warning ("`%s' attribute only applies to functions",
4567                IDENTIFIER_POINTER (name));
4568       *no_add_attrs = true;
4569     }
4570
4571   return NULL_TREE;
4572 }
4573
4574 /* Look for attribute `progmem' in DECL
4575    if found return 1, otherwise 0.  */
4576
4577 int
4578 avr_progmem_p (tree decl, tree attributes)
4579 {
4580   tree a;
4581
4582   if (TREE_CODE (decl) != VAR_DECL)
4583     return 0;
4584
4585   if (NULL_TREE
4586       != lookup_attribute ("progmem", attributes))
4587     return 1;
4588
4589   a=decl;
4590   do
4591     a = TREE_TYPE(a);
4592   while (TREE_CODE (a) == ARRAY_TYPE);
4593
4594   if (a == error_mark_node)
4595     return 0;
4596
4597   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
4598     return 1;
4599   
4600   return 0;
4601 }
4602
4603 /* Add the section attribute if the variable is in progmem.  */
4604
4605 static void
4606 avr_insert_attributes (tree node, tree *attributes)
4607 {
4608   if (TREE_CODE (node) == VAR_DECL
4609       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
4610       && avr_progmem_p (node, *attributes))
4611     {
4612       static const char dsec[] = ".progmem.data";
4613       *attributes = tree_cons (get_identifier ("section"),
4614                 build_tree_list (NULL, build_string (strlen (dsec), dsec)),
4615                 *attributes);
4616
4617       /* ??? This seems sketchy.  Why can't the user declare the
4618          thing const in the first place?  */
4619       TREE_READONLY (node) = 1;
4620     }
4621 }
4622
4623 static unsigned int
4624 avr_section_type_flags (tree decl, const char *name, int reloc)
4625 {
4626   unsigned int flags = default_section_type_flags (decl, name, reloc);
4627
4628   if (strncmp (name, ".noinit", 7) == 0)
4629     {
4630       if (decl && TREE_CODE (decl) == VAR_DECL
4631           && DECL_INITIAL (decl) == NULL_TREE)
4632         flags |= SECTION_BSS;  /* @nobits */
4633       else
4634         warning ("only uninitialized variables can be placed in the "
4635                  ".noinit section");
4636     }
4637
4638   return flags;
4639 }
4640
4641 /* Outputs some appropriate text to go at the start of an assembler
4642    file.  */
4643
4644 static void
4645 avr_file_start (void)
4646 {
4647   if (avr_asm_only_p)
4648     error ("MCU `%s' supported for assembler only", avr_mcu_name);
4649
4650   default_file_start ();
4651
4652   fprintf (asm_out_file, "\t.arch %s\n", avr_mcu_name);
4653   fputs ("__SREG__ = 0x3f\n"
4654          "__SP_H__ = 0x3e\n"
4655          "__SP_L__ = 0x3d\n", asm_out_file);
4656   
4657   fputs ("__tmp_reg__ = 0\n" 
4658          "__zero_reg__ = 1\n", asm_out_file);
4659
4660   /* FIXME: output these only if there is anything in the .data / .bss
4661      sections - some code size could be saved by not linking in the
4662      initialization code from libgcc if one or both sections are empty.  */
4663   fputs ("\t.global __do_copy_data\n", asm_out_file);
4664   fputs ("\t.global __do_clear_bss\n", asm_out_file);
4665
4666   commands_in_file = 0;
4667   commands_in_prologues = 0;
4668   commands_in_epilogues = 0;
4669 }
4670
4671 /* Outputs to the stdio stream FILE some
4672    appropriate text to go at the end of an assembler file.  */
4673
4674 static void
4675 avr_file_end (void)
4676 {
4677   fputs ("/* File ", asm_out_file);
4678   output_quoted_string (asm_out_file, main_input_filename);
4679   fprintf (asm_out_file,
4680            ": code %4d = 0x%04x (%4d), prologues %3d, epilogues %3d */\n",
4681            commands_in_file,
4682            commands_in_file,
4683            commands_in_file - commands_in_prologues - commands_in_epilogues,
4684            commands_in_prologues, commands_in_epilogues);
4685 }
4686
4687 /* Choose the order in which to allocate hard registers for
4688    pseudo-registers local to a basic block.
4689
4690    Store the desired register order in the array `reg_alloc_order'.
4691    Element 0 should be the register to allocate first; element 1, the
4692    next register; and so on.  */
4693
4694 void
4695 order_regs_for_local_alloc (void)
4696 {
4697   unsigned int i;
4698   static const int order_0[] = {
4699     24,25,
4700     18,19,
4701     20,21,
4702     22,23,
4703     30,31,
4704     26,27,
4705     28,29,
4706     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4707     0,1,
4708     32,33,34,35
4709   };
4710   static const int order_1[] = {
4711     18,19,
4712     20,21,
4713     22,23,
4714     24,25,
4715     30,31,
4716     26,27,
4717     28,29,
4718     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4719     0,1,
4720     32,33,34,35
4721   };
4722   static const int order_2[] = {
4723     25,24,
4724     23,22,
4725     21,20,
4726     19,18,
4727     30,31,
4728     26,27,
4729     28,29,
4730     17,16,
4731     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
4732     1,0,
4733     32,33,34,35
4734   };
4735   
4736   const int *order = (TARGET_ORDER_1 ? order_1 :
4737                       TARGET_ORDER_2 ? order_2 :
4738                       order_0);
4739   for (i=0; i < ARRAY_SIZE (order_0); ++i)
4740       reg_alloc_order[i] = order[i];
4741 }
4742
4743 /* Calculate the cost of X code of the expression in which it is contained,
4744    found in OUTER_CODE */
4745
4746 static int
4747 default_rtx_costs (rtx X, enum rtx_code code, enum rtx_code outer_code)
4748 {
4749   int cost=0;
4750   switch (code)
4751     {
4752     case SYMBOL_REF:
4753     case LABEL_REF:
4754       cost = 2 * GET_MODE_SIZE (GET_MODE (X));
4755       break;
4756     case MEM:
4757       if (outer_code != SET)
4758         cost = 1;
4759       if (GET_CODE (XEXP (X,0)) == SYMBOL_REF)
4760         cost += 2 * GET_MODE_SIZE (GET_MODE (X));
4761       else
4762         cost += GET_MODE_SIZE (GET_MODE (X));
4763       break;
4764     case CONST_INT:
4765       cost = 0;
4766       break;
4767     case SIGN_EXTEND:
4768       if (outer_code == SET)
4769         cost = GET_MODE_SIZE (GET_MODE (X));
4770       else
4771         cost = -GET_MODE_SIZE (GET_MODE (X));
4772       break;
4773     case ZERO_EXTEND:
4774       if (outer_code == SET)
4775         cost = GET_MODE_SIZE (GET_MODE (X));
4776       else
4777         cost = -1;
4778       break;
4779     case PLUS:
4780     case MINUS:
4781       if (outer_code == SET)
4782         {
4783           if (X == stack_pointer_rtx)
4784             cost = -10;
4785           else if (GET_CODE (XEXP (X,1)) == CONST_INT)
4786             cost = (INTVAL (XEXP (X,1)) <= 63 ? 1 :
4787                      GET_MODE_SIZE (GET_MODE (X)));
4788           else
4789             cost = GET_MODE_SIZE (GET_MODE (X));
4790         }
4791       break;
4792     case COMPARE:
4793       if (GET_CODE (XEXP (X,1)) == CONST_INT)
4794         cost = GET_MODE_SIZE (GET_MODE (XEXP (X,0)));
4795       break;
4796     default:
4797       break;
4798     }
4799   return cost;
4800 }
4801
4802 static bool
4803 avr_rtx_costs (rtx x, int code, int outer_code, int *total)
4804 {
4805   int cst;
4806
4807   switch (code)
4808     {
4809     case CONST_INT:
4810       if (outer_code == PLUS
4811           || outer_code == IOR
4812           || outer_code == AND
4813           || outer_code == MINUS
4814           || outer_code == SET
4815           || INTVAL (x) == 0)
4816         {
4817           *total = 2;
4818           return true;
4819         }
4820       if (outer_code == COMPARE
4821           && INTVAL (x) >= 0
4822           && INTVAL (x) <= 255)
4823         {
4824           *total = 2;
4825           return true;
4826         }
4827       /* FALLTHRU */
4828
4829     case CONST:
4830     case LABEL_REF:
4831     case SYMBOL_REF:
4832     case CONST_DOUBLE:
4833       *total = 4;
4834       return true;
4835
4836     default:
4837       cst = default_rtx_costs (x, code, outer_code);
4838       if (cst > 0)
4839         {
4840           *total = cst;
4841           return true;
4842         }
4843       else if (cst < 0)
4844         *total += -cst;
4845       return false;
4846     }
4847 }
4848
4849 /* Calculate the cost of a memory address.  */
4850
4851 static int
4852 avr_address_cost (rtx x)
4853 {
4854   if (GET_CODE (x) == PLUS
4855       && GET_CODE (XEXP (x,1)) == CONST_INT
4856       && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
4857       && INTVAL (XEXP (x,1)) >= 61)
4858     return 18;
4859   if (CONSTANT_ADDRESS_P (x))
4860     {
4861       if (avr_io_address_p (x, 1))
4862         return 2;
4863       return 4;
4864     }
4865   return 4;
4866 }
4867
4868 /*  EXTRA_CONSTRAINT helper */
4869
4870 int
4871 extra_constraint (rtx x, int c)
4872 {
4873   if (c == 'Q'
4874       && GET_CODE (x) == MEM
4875       && GET_CODE (XEXP (x,0)) == PLUS)
4876     {
4877           if (TARGET_ALL_DEBUG)
4878             {
4879               fprintf (stderr, ("extra_constraint:\n"
4880                                 "reload_completed: %d\n"
4881                                 "reload_in_progress: %d\n"),
4882                        reload_completed, reload_in_progress);
4883               debug_rtx (x);
4884             }
4885       if (GET_CODE (x) == MEM
4886           && GET_CODE (XEXP (x,0)) == PLUS
4887           && REG_P (XEXP (XEXP (x,0), 0))
4888           && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
4889           && (INTVAL (XEXP (XEXP (x,0), 1))
4890               <= MAX_LD_OFFSET (GET_MODE (x))))
4891         {
4892           rtx xx = XEXP (XEXP (x,0), 0);
4893           int regno = REGNO (xx);
4894           if (TARGET_ALL_DEBUG)
4895             {
4896               fprintf (stderr, ("extra_constraint:\n"
4897                                 "reload_completed: %d\n"
4898                                 "reload_in_progress: %d\n"),
4899                        reload_completed, reload_in_progress);
4900               debug_rtx (x);
4901             }
4902           if (regno >= FIRST_PSEUDO_REGISTER)
4903             return 1;           /* allocate pseudos */
4904           else if (regno == REG_Z || regno == REG_Y)
4905             return 1;           /* strictly check */
4906           else if (xx == frame_pointer_rtx
4907                    || xx == arg_pointer_rtx)
4908             return 1;           /* XXX frame & arg pointer checks */
4909         }
4910     }
4911   return 0;
4912 }
4913
4914 /* Convert condition code CONDITION to the valid AVR condition code.  */
4915
4916 RTX_CODE
4917 avr_normalize_condition (RTX_CODE condition)
4918 {
4919   switch (condition)
4920     {
4921     case GT:
4922       return GE;
4923     case GTU:
4924       return GEU;
4925     case LE:
4926       return LT;
4927     case LEU:
4928       return LTU;
4929     default:
4930       abort ();
4931     }
4932 }
4933
4934 /* This function optimizes conditional jumps.  */
4935
4936 static void
4937 avr_reorg (void)
4938 {
4939   rtx insn, pattern;
4940   
4941   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
4942     {
4943       if (! (GET_CODE (insn) == INSN
4944              || GET_CODE (insn) == CALL_INSN
4945              || GET_CODE (insn) == JUMP_INSN)
4946           || !single_set (insn))
4947         continue;
4948
4949       pattern = PATTERN (insn);
4950
4951       if (GET_CODE (pattern) == PARALLEL)
4952         pattern = XVECEXP (pattern, 0, 0);
4953       if (GET_CODE (pattern) == SET
4954           && SET_DEST (pattern) == cc0_rtx
4955           && compare_diff_p (insn))
4956         {
4957           if (GET_CODE (SET_SRC (pattern)) == COMPARE)
4958             {
4959               /* Now we work under compare insn.  */
4960               
4961               pattern = SET_SRC (pattern);
4962               if (true_regnum (XEXP (pattern,0)) >= 0
4963                   && true_regnum (XEXP (pattern,1)) >= 0 )
4964                 {
4965                   rtx x = XEXP (pattern,0);
4966                   rtx next = next_real_insn (insn);
4967                   rtx pat = PATTERN (next);
4968                   rtx src = SET_SRC (pat);
4969                   rtx t = XEXP (src,0);
4970                   PUT_CODE (t, swap_condition (GET_CODE (t)));
4971                   XEXP (pattern,0) = XEXP (pattern,1);
4972                   XEXP (pattern,1) = x;
4973                   INSN_CODE (next) = -1;
4974                 }
4975               else if (true_regnum (XEXP (pattern,0)) >= 0
4976                        && GET_CODE (XEXP (pattern,1)) == CONST_INT)
4977                 {
4978                   rtx x = XEXP (pattern,1);
4979                   rtx next = next_real_insn (insn);
4980                   rtx pat = PATTERN (next);
4981                   rtx src = SET_SRC (pat);
4982                   rtx t = XEXP (src,0);
4983                   enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
4984
4985                   if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
4986                     {
4987                       XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
4988                       PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
4989                       INSN_CODE (next) = -1;
4990                       INSN_CODE (insn) = -1;
4991                     }
4992                 }
4993             }
4994           else if (true_regnum (SET_SRC (pattern)) >= 0)
4995             {
4996               /* This is a tst insn */
4997               rtx next = next_real_insn (insn);
4998               rtx pat = PATTERN (next);
4999               rtx src = SET_SRC (pat);
5000               rtx t = XEXP (src,0);
5001
5002               PUT_CODE (t, swap_condition (GET_CODE (t)));
5003               SET_SRC (pattern) = gen_rtx_NEG (GET_MODE (SET_SRC (pattern)),
5004                                                SET_SRC (pattern));
5005               INSN_CODE (next) = -1;
5006               INSN_CODE (insn) = -1;
5007             }
5008         }
5009     }
5010 }
5011
5012 /* Returns register number for function return value.*/
5013
5014 int
5015 avr_ret_register (void)
5016 {
5017   return 24;
5018 }
5019
5020 /* Ceate an RTX representing the place where a
5021    library function returns a value of mode MODE.  */
5022
5023 rtx
5024 avr_libcall_value (enum machine_mode mode)
5025 {
5026   int offs = GET_MODE_SIZE (mode);
5027   if (offs < 2)
5028     offs = 2;
5029   return gen_rtx_REG (mode, RET_REGISTER + 2 - offs);
5030 }
5031
5032 /* Create an RTX representing the place where a
5033    function returns a value of data type VALTYPE.  */
5034
5035 rtx
5036 avr_function_value (tree type, tree func ATTRIBUTE_UNUSED)
5037 {
5038   unsigned int offs;
5039   
5040   if (TYPE_MODE (type) != BLKmode)
5041     return avr_libcall_value (TYPE_MODE (type));
5042   
5043   offs = int_size_in_bytes (type);
5044   if (offs < 2)
5045     offs = 2;
5046   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
5047     offs = GET_MODE_SIZE (SImode);
5048   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
5049     offs = GET_MODE_SIZE (DImode);
5050   
5051   return gen_rtx_REG (BLKmode, RET_REGISTER + 2 - offs);
5052 }
5053
5054 /* Returns nonzero if the number MASK has only one bit set.  */
5055
5056 int
5057 mask_one_bit_p (HOST_WIDE_INT mask)
5058 {
5059   int i;
5060   unsigned HOST_WIDE_INT n=mask;
5061   for (i = 0; i < 32; ++i)
5062     {
5063       if (n & 0x80000000L)
5064         {
5065           if (n & 0x7fffffffL)
5066             return 0;
5067           else
5068             return 32-i;
5069         }
5070       n<<=1;
5071     }
5072   return 0; 
5073 }
5074
5075
5076 /* Places additional restrictions on the register class to
5077    use when it is necessary to copy value X into a register
5078    in class CLASS.  */
5079
5080 enum reg_class
5081 preferred_reload_class (rtx x ATTRIBUTE_UNUSED, enum reg_class class)
5082 {
5083   return class;
5084 }
5085
5086 int
5087 test_hard_reg_class (enum reg_class class, rtx x)
5088 {
5089   int regno = true_regnum (x);
5090   if (regno < 0)
5091     return 0;
5092
5093   if (TEST_HARD_REG_CLASS (class, regno))
5094     return 1;
5095
5096   return 0;
5097 }
5098
5099
5100 int
5101 jump_over_one_insn_p (rtx insn, rtx dest)
5102 {
5103   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
5104                       ? XEXP (dest, 0)
5105                       : dest);
5106   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
5107   int dest_addr = INSN_ADDRESSES (uid);
5108   return dest_addr - jump_addr == get_attr_length (insn) + 1;
5109 }
5110
5111 /* Returns 1 if a value of mode MODE can be stored starting with hard
5112    register number REGNO.  On the enhanced core, anything larger than
5113    1 byte must start in even numbered register for "movw" to work
5114    (this way we don't have to check for odd registers everywhere).  */
5115
5116 int
5117 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
5118 {
5119   /* Bug workaround: recog.c (peep2_find_free_register) and probably
5120      a few other places assume that the frame pointer is a single hard
5121      register, so r29 may be allocated and overwrite the high byte of
5122      the frame pointer.  Do not allow any value to start in r29.  */
5123   if (regno == REG_Y + 1)
5124     return 0;
5125
5126   if (mode == QImode)
5127     return 1;
5128   /*  if (regno < 24 && !AVR_ENHANCED)
5129       return 1;*/
5130   return !(regno & 1);
5131 }
5132
5133 /* Returns 1 if X is a valid address for an I/O register of size SIZE
5134    (1 or 2).  Used for lds/sts -> in/out optimization.  Add 0x20 to SIZE
5135    to check for the lower half of I/O space (for cbi/sbi/sbic/sbis).  */
5136
5137 int
5138 avr_io_address_p (rtx x, int size)
5139 {
5140   return (optimize > 0 && GET_CODE (x) == CONST_INT
5141           && INTVAL (x) >= 0x20 && INTVAL (x) <= 0x60 - size);
5142 }
5143
5144 /* Returns nonzero (bit number + 1) if X, or -X, is a constant power of 2.  */
5145
5146 int
5147 const_int_pow2_p (rtx x)
5148 {
5149   if (GET_CODE (x) == CONST_INT)
5150     {
5151       HOST_WIDE_INT d = INTVAL (x);
5152       HOST_WIDE_INT abs_d = (d >= 0) ? d : -d;
5153       return exact_log2 (abs_d) + 1;
5154     }
5155   return 0;
5156 }
5157
5158 const char *
5159 output_reload_inhi (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5160 {
5161   int tmp;
5162   if (!len)
5163     len = &tmp;
5164       
5165   if (GET_CODE (operands[1]) == CONST_INT)
5166     {
5167       int val = INTVAL (operands[1]);
5168       if ((val & 0xff) == 0)
5169         {
5170           *len = 3;
5171           return (AS2 (mov,%A0,__zero_reg__) CR_TAB
5172                   AS2 (ldi,%2,hi8(%1))       CR_TAB
5173                   AS2 (mov,%B0,%2));
5174         }
5175       else if ((val & 0xff00) == 0)
5176         {
5177           *len = 3;
5178           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5179                   AS2 (mov,%A0,%2)     CR_TAB
5180                   AS2 (mov,%B0,__zero_reg__));
5181         }
5182       else if ((val & 0xff) == ((val & 0xff00) >> 8))
5183         {
5184           *len = 3;
5185           return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5186                   AS2 (mov,%A0,%2)     CR_TAB
5187                   AS2 (mov,%B0,%2));
5188         }
5189     }
5190   *len = 4;
5191   return (AS2 (ldi,%2,lo8(%1)) CR_TAB
5192           AS2 (mov,%A0,%2)     CR_TAB
5193           AS2 (ldi,%2,hi8(%1)) CR_TAB
5194           AS2 (mov,%B0,%2));
5195 }
5196
5197
5198 const char *
5199 output_reload_insisf (rtx insn ATTRIBUTE_UNUSED, rtx *operands, int *len)
5200 {
5201   rtx src = operands[1];
5202   int cnst = (GET_CODE (src) == CONST_INT);
5203
5204   if (len)
5205     {
5206       if (cnst)
5207         *len = 4 + ((INTVAL (src) & 0xff) != 0)
5208                 + ((INTVAL (src) & 0xff00) != 0)
5209                 + ((INTVAL (src) & 0xff0000) != 0)
5210                 + ((INTVAL (src) & 0xff000000) != 0);
5211       else
5212         *len = 8;
5213
5214       return "";
5215     }
5216
5217   if (cnst && ((INTVAL (src) & 0xff) == 0))
5218     output_asm_insn (AS2 (mov, %A0, __zero_reg__), operands);
5219   else
5220     {
5221       output_asm_insn (AS2 (ldi, %2, lo8(%1)), operands);
5222       output_asm_insn (AS2 (mov, %A0, %2), operands);
5223     }
5224   if (cnst && ((INTVAL (src) & 0xff00) == 0))
5225     output_asm_insn (AS2 (mov, %B0, __zero_reg__), operands);
5226   else
5227     {
5228       output_asm_insn (AS2 (ldi, %2, hi8(%1)), operands);
5229       output_asm_insn (AS2 (mov, %B0, %2), operands);
5230     }
5231   if (cnst && ((INTVAL (src) & 0xff0000) == 0))
5232     output_asm_insn (AS2 (mov, %C0, __zero_reg__), operands);
5233   else
5234     {
5235       output_asm_insn (AS2 (ldi, %2, hlo8(%1)), operands);
5236       output_asm_insn (AS2 (mov, %C0, %2), operands);
5237     }
5238   if (cnst && ((INTVAL (src) & 0xff000000) == 0))
5239     output_asm_insn (AS2 (mov, %D0, __zero_reg__), operands);
5240   else
5241     {
5242       output_asm_insn (AS2 (ldi, %2, hhi8(%1)), operands);
5243       output_asm_insn (AS2 (mov, %D0, %2), operands);
5244     }
5245   return "";
5246 }
5247
5248 void
5249 avr_output_bld (rtx operands[], int bit_nr)
5250 {
5251   static char s[] = "bld %A0,0";
5252
5253   s[5] = 'A' + (bit_nr >> 3);
5254   s[8] = '0' + (bit_nr & 7);
5255   output_asm_insn (s, operands);
5256 }
5257
5258 void
5259 avr_output_addr_vec_elt (FILE *stream, int value)
5260 {
5261   if (AVR_MEGA)
5262     fprintf (stream, "\t.word pm(.L%d)\n", value);
5263   else
5264     fprintf (stream, "\trjmp .L%d\n", value);
5265
5266   jump_tables_size++;
5267 }
5268
5269 /* Returns 1 if SCRATCH are safe to be allocated as a scratch
5270    registers (for a define_peephole2) in the current function.  */
5271
5272 int
5273 avr_peep2_scratch_safe (rtx scratch)
5274 {
5275   if ((interrupt_function_p (current_function_decl)
5276        || signal_function_p (current_function_decl))
5277       && leaf_function_p ())
5278     {
5279       int first_reg = true_regnum (scratch);
5280       int last_reg = first_reg + GET_MODE_SIZE (GET_MODE (scratch)) - 1;
5281       int reg;
5282
5283       for (reg = first_reg; reg <= last_reg; reg++)
5284         {
5285           if (!regs_ever_live[reg])
5286             return 0;
5287         }
5288     }
5289   return 1;
5290 }
5291
5292 /* Output a branch that tests a single bit of a register (QI, HI or SImode)
5293    or memory location in the I/O space (QImode only).
5294
5295    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
5296    Operand 1: register operand to test, or CONST_INT memory address.
5297    Operand 2: bit number (for QImode operand) or mask (HImode, SImode).
5298    Operand 3: label to jump to if the test is true.  */
5299
5300 const char *
5301 avr_out_sbxx_branch (rtx insn, rtx operands[])
5302 {
5303   enum rtx_code comp = GET_CODE (operands[0]);
5304   int long_jump = (get_attr_length (insn) >= 4);
5305   int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
5306
5307   if (comp == GE)
5308     comp = EQ;
5309   else if (comp == LT)
5310     comp = NE;
5311
5312   if (reverse)
5313     comp = reverse_condition (comp);
5314
5315   if (GET_CODE (operands[1]) == CONST_INT)
5316     {
5317       if (INTVAL (operands[1]) < 0x40)
5318         {
5319           if (comp == EQ)
5320             output_asm_insn (AS2 (sbis,%1-0x20,%2), operands);
5321           else
5322             output_asm_insn (AS2 (sbic,%1-0x20,%2), operands);
5323         }
5324       else
5325         {
5326           output_asm_insn (AS2 (in,__tmp_reg__,%1-0x20), operands);
5327           if (comp == EQ)
5328             output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
5329           else
5330             output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
5331         }
5332     }
5333   else  /* GET_CODE (operands[1]) == REG */
5334     {
5335       if (GET_MODE (operands[1]) == QImode)
5336         {
5337           if (comp == EQ)
5338             output_asm_insn (AS2 (sbrs,%1,%2), operands);
5339           else
5340             output_asm_insn (AS2 (sbrc,%1,%2), operands);
5341         }
5342       else  /* HImode or SImode */
5343         {
5344           static char buf[] = "sbrc %A1,0";
5345           int bit_nr = exact_log2 (INTVAL (operands[2])
5346                                    & GET_MODE_MASK (GET_MODE (operands[1])));
5347
5348           buf[3] = (comp == EQ) ? 's' : 'c';
5349           buf[6] = 'A' + (bit_nr >> 3);
5350           buf[9] = '0' + (bit_nr & 7);
5351           output_asm_insn (buf, operands);
5352         }
5353     }
5354
5355   if (long_jump)
5356     return (AS1 (rjmp,.+4) CR_TAB
5357             AS1 (jmp,%3));
5358   if (!reverse)
5359     return AS1 (rjmp,%3);
5360   return "";
5361 }
5362
5363 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
5364
5365 static void
5366 avr_asm_out_ctor (rtx symbol, int priority)
5367 {
5368   fputs ("\t.global __do_global_ctors\n", asm_out_file);
5369   default_ctor_section_asm_out_constructor (symbol, priority);
5370 }
5371
5372 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
5373
5374 static void
5375 avr_asm_out_dtor (rtx symbol, int priority)
5376 {
5377   fputs ("\t.global __do_global_dtors\n", asm_out_file);
5378   default_dtor_section_asm_out_destructor (symbol, priority);
5379 }
5380
5381 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
5382
5383 static bool
5384 avr_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
5385 {
5386   if (TYPE_MODE (type) == BLKmode)
5387     {
5388       HOST_WIDE_INT size = int_size_in_bytes (type);
5389       return (size == -1 || size > 8);
5390     }
5391   else
5392     return false;
5393 }
5394
5395 #include "gt-avr.h"