OSDN Git Service

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