OSDN Git Service

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