OSDN Git Service

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