OSDN Git Service

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