OSDN Git Service

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