OSDN Git Service

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