OSDN Git Service

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