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