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