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