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