OSDN Git Service

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