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