OSDN Git Service

* config/avr/avr.c (avr_mcu_t): Add atmega8c1, atmega16c1 and
[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    2009 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 "params.h"
47 #include "df.h"
48
49 /* Maximal allowed offset for an address in the LD command */
50 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
51
52 static int avr_naked_function_p (tree);
53 static int interrupt_function_p (tree);
54 static int signal_function_p (tree);
55 static int avr_OS_task_function_p (tree);
56 static int avr_OS_main_function_p (tree);
57 static int avr_regs_to_save (HARD_REG_SET *);
58 static int get_sequence_length (rtx insns);
59 static int sequent_regs_live (void);
60 static const char *ptrreg_to_str (int);
61 static const char *cond_string (enum rtx_code);
62 static int avr_num_arg_regs (enum machine_mode, tree);
63
64 static RTX_CODE compare_condition (rtx insn);
65 static int compare_sign_p (rtx insn);
66 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
67 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
68 static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
69 const struct attribute_spec avr_attribute_table[];
70 static bool avr_assemble_integer (rtx, unsigned int, int);
71 static void avr_file_start (void);
72 static void avr_file_end (void);
73 static void avr_asm_function_end_prologue (FILE *);
74 static void avr_asm_function_begin_epilogue (FILE *);
75 static rtx avr_function_value (const_tree, const_tree, bool);
76 static void avr_insert_attributes (tree, tree *);
77 static void avr_asm_init_sections (void);
78 static unsigned int avr_section_type_flags (tree, const char *, int);
79
80 static void avr_reorg (void);
81 static void avr_asm_out_ctor (rtx, int);
82 static void avr_asm_out_dtor (rtx, int);
83 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code, bool);
84 static bool avr_rtx_costs (rtx, int, int, int *, bool);
85 static int avr_address_cost (rtx, bool);
86 static bool avr_return_in_memory (const_tree, const_tree);
87 static struct machine_function * avr_init_machine_status (void);
88 static rtx avr_builtin_setjmp_frame_value (void);
89 static bool avr_hard_regno_scratch_ok (unsigned int);
90
91 /* Allocate registers from r25 to r8 for parameters for function calls.  */
92 #define FIRST_CUM_REG 26
93
94 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
95 static GTY(()) rtx tmp_reg_rtx;
96
97 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
98 static GTY(()) rtx zero_reg_rtx;
99
100 /* AVR register names {"r0", "r1", ..., "r31"} */
101 static const char *const avr_regnames[] = REGISTER_NAMES;
102
103 /* This holds the last insn address.  */
104 static int last_insn_address = 0;
105
106 /* Preprocessor macros to define depending on MCU type.  */
107 const char *avr_extra_arch_macro;
108
109 /* Current architecture.  */
110 const struct base_arch_s *avr_current_arch;
111
112 section *progmem_section;
113
114 static const struct base_arch_s avr_arch_types[] = {
115   { 1, 0, 0, 0, 0, 0, 0, 0, NULL },  /* unknown device specified */
116   { 1, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=1"   },
117   { 0, 0, 0, 0, 0, 0, 0, 0, "__AVR_ARCH__=2"   },
118   { 0, 0, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=25"  },
119   { 0, 0, 1, 0, 0, 0, 0, 0, "__AVR_ARCH__=3"   },
120   { 0, 0, 1, 0, 1, 0, 0, 0, "__AVR_ARCH__=31"  },
121   { 0, 0, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=35"  },
122   { 0, 1, 0, 1, 0, 0, 0, 0, "__AVR_ARCH__=4"   },
123   { 0, 1, 1, 1, 0, 0, 0, 0, "__AVR_ARCH__=5"   },
124   { 0, 1, 1, 1, 1, 1, 0, 0, "__AVR_ARCH__=51"  },
125   { 0, 1, 1, 1, 1, 1, 1, 0, "__AVR_ARCH__=6"   }
126 };
127
128 /* These names are used as the index into the avr_arch_types[] table 
129    above.  */
130
131 enum avr_arch
132 {
133   ARCH_UNKNOWN,
134   ARCH_AVR1,
135   ARCH_AVR2,
136   ARCH_AVR25,
137   ARCH_AVR3,
138   ARCH_AVR31,
139   ARCH_AVR35,
140   ARCH_AVR4,
141   ARCH_AVR5,
142   ARCH_AVR51,
143   ARCH_AVR6
144 };
145
146 struct mcu_type_s {
147   const char *const name;
148   int arch;  /* index in avr_arch_types[] */
149   /* Must lie outside user's namespace.  NULL == no macro.  */
150   const char *const macro;
151 };
152
153 /* List of all known AVR MCU types - if updated, it has to be kept
154    in sync in several places (FIXME: is there a better way?):
155     - here
156     - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
157     - t-avr (MULTILIB_MATCHES)
158     - gas/config/tc-avr.c
159     - avr-libc  */
160
161 static const struct mcu_type_s avr_mcu_types[] = {
162     /* Classic, <= 8K.  */
163   { "avr2",         ARCH_AVR2, NULL },
164   { "at90s2313",    ARCH_AVR2, "__AVR_AT90S2313__" },
165   { "at90s2323",    ARCH_AVR2, "__AVR_AT90S2323__" },
166   { "at90s2333",    ARCH_AVR2, "__AVR_AT90S2333__" },
167   { "at90s2343",    ARCH_AVR2, "__AVR_AT90S2343__" },
168   { "attiny22",     ARCH_AVR2, "__AVR_ATtiny22__" },
169   { "attiny26",     ARCH_AVR2, "__AVR_ATtiny26__" },
170   { "at90s4414",    ARCH_AVR2, "__AVR_AT90S4414__" },
171   { "at90s4433",    ARCH_AVR2, "__AVR_AT90S4433__" },
172   { "at90s4434",    ARCH_AVR2, "__AVR_AT90S4434__" },
173   { "at90s8515",    ARCH_AVR2, "__AVR_AT90S8515__" },
174   { "at90c8534",    ARCH_AVR2, "__AVR_AT90C8534__" },
175   { "at90s8535",    ARCH_AVR2, "__AVR_AT90S8535__" },
176     /* Classic + MOVW, <= 8K.  */
177   { "avr25",        ARCH_AVR25, NULL },
178   { "ata6289",      ARCH_AVR25, "__AVR_ATA6289__" },
179   { "attiny13",     ARCH_AVR25, "__AVR_ATtiny13__" },
180   { "attiny13a",    ARCH_AVR25, "__AVR_ATtiny13A__" },
181   { "attiny2313",   ARCH_AVR25, "__AVR_ATtiny2313__" },
182   { "attiny24",     ARCH_AVR25, "__AVR_ATtiny24__" },
183   { "attiny44",     ARCH_AVR25, "__AVR_ATtiny44__" },
184   { "attiny84",     ARCH_AVR25, "__AVR_ATtiny84__" },
185   { "attiny25",     ARCH_AVR25, "__AVR_ATtiny25__" },
186   { "attiny45",     ARCH_AVR25, "__AVR_ATtiny45__" },
187   { "attiny85",     ARCH_AVR25, "__AVR_ATtiny85__" },
188   { "attiny261",    ARCH_AVR25, "__AVR_ATtiny261__" },
189   { "attiny461",    ARCH_AVR25, "__AVR_ATtiny461__" },
190   { "attiny861",    ARCH_AVR25, "__AVR_ATtiny861__" },
191   { "attiny43u",    ARCH_AVR25, "__AVR_ATtiny43U__" },
192   { "attiny87",     ARCH_AVR25, "__AVR_ATtiny87__" },
193   { "attiny48",     ARCH_AVR25, "__AVR_ATtiny48__" },
194   { "attiny88",     ARCH_AVR25, "__AVR_ATtiny88__" },
195   { "at86rf401",    ARCH_AVR25, "__AVR_AT86RF401__" },
196     /* Classic, > 8K, <= 64K.  */
197   { "avr3",         ARCH_AVR3, NULL },
198   { "at43usb355",   ARCH_AVR3, "__AVR_AT43USB355__" },
199   { "at76c711",     ARCH_AVR3, "__AVR_AT76C711__" },
200     /* Classic, == 128K.  */
201   { "avr31",        ARCH_AVR31, NULL },
202   { "atmega103",    ARCH_AVR31, "__AVR_ATmega103__" },
203   { "at43usb320",   ARCH_AVR31, "__AVR_AT43USB320__" },
204     /* Classic + MOVW + JMP/CALL.  */
205   { "avr35",        ARCH_AVR35, NULL },
206   { "at90usb82",    ARCH_AVR35, "__AVR_AT90USB82__" },
207   { "at90usb162",   ARCH_AVR35, "__AVR_AT90USB162__" },
208   { "attiny167",    ARCH_AVR35, "__AVR_ATtiny167__" },
209   { "attiny327",    ARCH_AVR35, "__AVR_ATtiny327__" },
210     /* Enhanced, <= 8K.  */
211   { "avr4",         ARCH_AVR4, NULL },
212   { "atmega8",      ARCH_AVR4, "__AVR_ATmega8__" },
213   { "atmega48",     ARCH_AVR4, "__AVR_ATmega48__" },
214   { "atmega48p",    ARCH_AVR4, "__AVR_ATmega48P__" },
215   { "atmega88",     ARCH_AVR4, "__AVR_ATmega88__" },
216   { "atmega88p",    ARCH_AVR4, "__AVR_ATmega88P__" },
217   { "atmega8515",   ARCH_AVR4, "__AVR_ATmega8515__" },
218   { "atmega8535",   ARCH_AVR4, "__AVR_ATmega8535__" },
219   { "atmega8hva",   ARCH_AVR4, "__AVR_ATmega8HVA__" },
220   { "atmega4hvd",   ARCH_AVR4, "__AVR_ATmega4HVD__" },
221   { "atmega8hvd",   ARCH_AVR4, "__AVR_ATmega8HVD__" },
222   { "atmega8c1",    ARCH_AVR4, "__AVR_ATmega8C1__" },
223   { "atmega8m1",    ARCH_AVR4, "__AVR_ATmega8M1__" },
224   { "at90pwm1",     ARCH_AVR4, "__AVR_AT90PWM1__" },
225   { "at90pwm2",     ARCH_AVR4, "__AVR_AT90PWM2__" },
226   { "at90pwm2b",    ARCH_AVR4, "__AVR_AT90PWM2B__" },
227   { "at90pwm3",     ARCH_AVR4, "__AVR_AT90PWM3__" },
228   { "at90pwm3b",    ARCH_AVR4, "__AVR_AT90PWM3B__" },
229   { "at90pwm81",    ARCH_AVR4, "__AVR_AT90PWM81__" },
230     /* Enhanced, > 8K, <= 64K.  */
231   { "avr5",         ARCH_AVR5, NULL },
232   { "atmega16",     ARCH_AVR5, "__AVR_ATmega16__" },
233   { "atmega161",    ARCH_AVR5, "__AVR_ATmega161__" },
234   { "atmega162",    ARCH_AVR5, "__AVR_ATmega162__" },
235   { "atmega163",    ARCH_AVR5, "__AVR_ATmega163__" },
236   { "atmega164p",   ARCH_AVR5, "__AVR_ATmega164P__" },
237   { "atmega165",    ARCH_AVR5, "__AVR_ATmega165__" },
238   { "atmega165p",   ARCH_AVR5, "__AVR_ATmega165P__" },
239   { "atmega168",    ARCH_AVR5, "__AVR_ATmega168__" },
240   { "atmega168p",   ARCH_AVR5, "__AVR_ATmega168P__" },
241   { "atmega169",    ARCH_AVR5, "__AVR_ATmega169__" },
242   { "atmega169p",   ARCH_AVR5, "__AVR_ATmega169P__" },
243   { "atmega32",     ARCH_AVR5, "__AVR_ATmega32__" },
244   { "atmega323",    ARCH_AVR5, "__AVR_ATmega323__" },
245   { "atmega324p",   ARCH_AVR5, "__AVR_ATmega324P__" },
246   { "atmega325",    ARCH_AVR5, "__AVR_ATmega325__" },
247   { "atmega325p",   ARCH_AVR5, "__AVR_ATmega325P__" },
248   { "atmega3250",   ARCH_AVR5, "__AVR_ATmega3250__" },
249   { "atmega3250p",  ARCH_AVR5, "__AVR_ATmega3250P__" },
250   { "atmega328p",   ARCH_AVR5, "__AVR_ATmega328P__" },
251   { "atmega329",    ARCH_AVR5, "__AVR_ATmega329__" },
252   { "atmega329p",   ARCH_AVR5, "__AVR_ATmega329P__" },
253   { "atmega3290",   ARCH_AVR5, "__AVR_ATmega3290__" },
254   { "atmega3290p",  ARCH_AVR5, "__AVR_ATmega3290P__" },
255   { "atmega406",    ARCH_AVR5, "__AVR_ATmega406__" },
256   { "atmega64",     ARCH_AVR5, "__AVR_ATmega64__" },
257   { "atmega640",    ARCH_AVR5, "__AVR_ATmega640__" },
258   { "atmega644",    ARCH_AVR5, "__AVR_ATmega644__" },
259   { "atmega644p",   ARCH_AVR5, "__AVR_ATmega644P__" },
260   { "atmega645",    ARCH_AVR5, "__AVR_ATmega645__" },
261   { "atmega6450",   ARCH_AVR5, "__AVR_ATmega6450__" },
262   { "atmega649",    ARCH_AVR5, "__AVR_ATmega649__" },
263   { "atmega6490",   ARCH_AVR5, "__AVR_ATmega6490__" },
264   { "atmega16hva",  ARCH_AVR5, "__AVR_ATmega16HVA__" },
265   { "atmega16hvb",  ARCH_AVR5, "__AVR_ATmega16HVB__" },
266   { "atmega32hvb",  ARCH_AVR5, "__AVR_ATmega32HVB__" },
267   { "at90can32",    ARCH_AVR5, "__AVR_AT90CAN32__" },
268   { "at90can64",    ARCH_AVR5, "__AVR_AT90CAN64__" },
269   { "at90pwm216",   ARCH_AVR5, "__AVR_AT90PWM216__" },
270   { "at90pwm316",   ARCH_AVR5, "__AVR_AT90PWM316__" },
271   { "atmega16c1",   ARCH_AVR5, "__AVR_ATmega16C1__" },
272   { "atmega32c1",   ARCH_AVR5, "__AVR_ATmega32C1__" },
273   { "atmega64c1",   ARCH_AVR5, "__AVR_ATmega64C1__" },
274   { "atmega16m1",   ARCH_AVR5, "__AVR_ATmega16M1__" },
275   { "atmega32m1",   ARCH_AVR5, "__AVR_ATmega32M1__" },
276   { "atmega64m1",   ARCH_AVR5, "__AVR_ATmega64M1__" },
277   { "atmega16u4",   ARCH_AVR5, "__AVR_ATmega16U4__" },
278   { "atmega32u4",   ARCH_AVR5, "__AVR_ATmega32U4__" },
279   { "atmega32u6",   ARCH_AVR5, "__AVR_ATmega32U6__" },
280   { "at90scr100",   ARCH_AVR5, "__AVR_AT90SCR100__" },
281   { "at90usb646",   ARCH_AVR5, "__AVR_AT90USB646__" },
282   { "at90usb647",   ARCH_AVR5, "__AVR_AT90USB647__" },
283   { "at94k",        ARCH_AVR5, "__AVR_AT94K__" },
284     /* Enhanced, == 128K.  */
285   { "avr51",        ARCH_AVR51, NULL },
286   { "atmega128",    ARCH_AVR51, "__AVR_ATmega128__" },
287   { "atmega1280",   ARCH_AVR51, "__AVR_ATmega1280__" },
288   { "atmega1281",   ARCH_AVR51, "__AVR_ATmega1281__" },
289   { "atmega1284p",  ARCH_AVR51, "__AVR_ATmega1284P__" },
290   { "atmega128rfa1",  ARCH_AVR51, "__AVR_ATmega128RFA1__" },
291   { "at90can128",   ARCH_AVR51, "__AVR_AT90CAN128__" },
292   { "at90usb1286",  ARCH_AVR51, "__AVR_AT90USB1286__" },
293   { "at90usb1287",  ARCH_AVR51, "__AVR_AT90USB1287__" },
294   { "m3000f",       ARCH_AVR51, "__AVR_M3000F__" },
295   { "m3000s",       ARCH_AVR51, "__AVR_M3000S__" },
296   { "m3001b",       ARCH_AVR51, "__AVR_M3001B__" },
297     /* 3-Byte PC.  */
298   { "avr6",         ARCH_AVR6, NULL },
299   { "atmega2560",   ARCH_AVR6, "__AVR_ATmega2560__" },
300   { "atmega2561",   ARCH_AVR6, "__AVR_ATmega2561__" },
301     /* Assembler only.  */
302   { "avr1",         ARCH_AVR1, NULL },
303   { "at90s1200",    ARCH_AVR1, "__AVR_AT90S1200__" },
304   { "attiny11",     ARCH_AVR1, "__AVR_ATtiny11__" },
305   { "attiny12",     ARCH_AVR1, "__AVR_ATtiny12__" },
306   { "attiny15",     ARCH_AVR1, "__AVR_ATtiny15__" },
307   { "attiny28",     ARCH_AVR1, "__AVR_ATtiny28__" },
308   { NULL,           ARCH_UNKNOWN, NULL }
309 };
310
311 int avr_case_values_threshold = 30000;
312 \f
313 /* Initialize the GCC target structure.  */
314 #undef TARGET_ASM_ALIGNED_HI_OP
315 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
316 #undef TARGET_ASM_ALIGNED_SI_OP
317 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
318 #undef TARGET_ASM_UNALIGNED_HI_OP
319 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
320 #undef TARGET_ASM_UNALIGNED_SI_OP
321 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
322 #undef TARGET_ASM_INTEGER
323 #define TARGET_ASM_INTEGER avr_assemble_integer
324 #undef TARGET_ASM_FILE_START
325 #define TARGET_ASM_FILE_START avr_file_start
326 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
327 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
328 #undef TARGET_ASM_FILE_END
329 #define TARGET_ASM_FILE_END avr_file_end
330
331 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
332 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
333 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
334 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
335 #undef TARGET_FUNCTION_VALUE
336 #define TARGET_FUNCTION_VALUE avr_function_value
337 #undef TARGET_ATTRIBUTE_TABLE
338 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
339 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
340 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
341 #undef TARGET_INSERT_ATTRIBUTES
342 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
343 #undef TARGET_SECTION_TYPE_FLAGS
344 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
345 #undef TARGET_RTX_COSTS
346 #define TARGET_RTX_COSTS avr_rtx_costs
347 #undef TARGET_ADDRESS_COST
348 #define TARGET_ADDRESS_COST avr_address_cost
349 #undef TARGET_MACHINE_DEPENDENT_REORG
350 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
351
352 #undef TARGET_RETURN_IN_MEMORY
353 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
354
355 #undef TARGET_STRICT_ARGUMENT_NAMING
356 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
357
358 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
359 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
360
361 #undef TARGET_HARD_REGNO_SCRATCH_OK
362 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
363
364 struct gcc_target targetm = TARGET_INITIALIZER;
365 \f
366 void
367 avr_override_options (void)
368 {
369   const struct mcu_type_s *t;
370
371   flag_delete_null_pointer_checks = 0;
372
373   if (!PARAM_SET_P (PARAM_INLINE_CALL_COST))
374     set_param_value ("inline-call-cost", 5);
375
376   for (t = avr_mcu_types; t->name; t++)
377     if (strcmp (t->name, avr_mcu_name) == 0)
378       break;
379
380   if (!t->name)
381     {
382       fprintf (stderr, "unknown MCU '%s' specified\nKnown MCU names:\n",
383                avr_mcu_name);
384       for (t = avr_mcu_types; t->name; t++)
385         fprintf (stderr,"   %s\n", t->name);
386     }
387
388   avr_current_arch = &avr_arch_types[t->arch];
389   avr_extra_arch_macro = t->macro;
390
391   if (optimize && !TARGET_NO_TABLEJUMP)
392     avr_case_values_threshold = 
393       (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
394
395   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
396   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
397
398   init_machine_status = avr_init_machine_status;
399 }
400
401 /*  return register class from register number.  */
402
403 static const int reg_class_tab[]={
404   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
405   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
406   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
407   GENERAL_REGS, /* r0 - r15 */
408   LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
409   LD_REGS,                      /* r16 - 23 */
410   ADDW_REGS,ADDW_REGS,          /* r24,r25 */
411   POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
412   POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
413   POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
414   STACK_REG,STACK_REG           /* SPL,SPH */
415 };
416
417 /* Function to set up the backend function structure.  */
418
419 static struct machine_function *
420 avr_init_machine_status (void)
421 {
422   return ((struct machine_function *) 
423           ggc_alloc_cleared (sizeof (struct machine_function)));
424 }
425
426 /* Return register class for register R.  */
427
428 enum reg_class
429 avr_regno_reg_class (int r)
430 {
431   if (r <= 33)
432     return reg_class_tab[r];
433   return ALL_REGS;
434 }
435
436 /* Return nonzero if FUNC is a naked function.  */
437
438 static int
439 avr_naked_function_p (tree func)
440 {
441   tree a;
442
443   gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
444   
445   a = lookup_attribute ("naked", TYPE_ATTRIBUTES (TREE_TYPE (func)));
446   return a != NULL_TREE;
447 }
448
449 /* Return nonzero if FUNC is an interrupt function as specified
450    by the "interrupt" attribute.  */
451
452 static int
453 interrupt_function_p (tree func)
454 {
455   tree a;
456
457   if (TREE_CODE (func) != FUNCTION_DECL)
458     return 0;
459
460   a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
461   return a != NULL_TREE;
462 }
463
464 /* Return nonzero if FUNC is a signal function as specified
465    by the "signal" attribute.  */
466
467 static int
468 signal_function_p (tree func)
469 {
470   tree a;
471
472   if (TREE_CODE (func) != FUNCTION_DECL)
473     return 0;
474
475   a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
476   return a != NULL_TREE;
477 }
478
479 /* Return nonzero if FUNC is a OS_task function.  */
480
481 static int
482 avr_OS_task_function_p (tree func)
483 {
484   tree a;
485
486   gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
487   
488   a = lookup_attribute ("OS_task", TYPE_ATTRIBUTES (TREE_TYPE (func)));
489   return a != NULL_TREE;
490 }
491
492 /* Return nonzero if FUNC is a OS_main function.  */
493
494 static int
495 avr_OS_main_function_p (tree func)
496 {
497   tree a;
498
499   gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
500   
501   a = lookup_attribute ("OS_main", TYPE_ATTRIBUTES (TREE_TYPE (func)));
502   return a != NULL_TREE;
503 }
504
505 /* Return the number of hard registers to push/pop in the prologue/epilogue
506    of the current function, and optionally store these registers in SET.  */
507
508 static int
509 avr_regs_to_save (HARD_REG_SET *set)
510 {
511   int reg, count;
512   int int_or_sig_p = (interrupt_function_p (current_function_decl)
513                       || signal_function_p (current_function_decl));
514
515   if (!reload_completed)
516     cfun->machine->is_leaf = leaf_function_p ();
517
518   if (set)
519     CLEAR_HARD_REG_SET (*set);
520   count = 0;
521
522   /* No need to save any registers if the function never returns or 
523      is have "OS_task" or "OS_main" attribute.  */
524   if (TREE_THIS_VOLATILE (current_function_decl)
525       || cfun->machine->is_OS_task
526       || cfun->machine->is_OS_main)
527     return 0;
528
529   for (reg = 0; reg < 32; reg++)
530     {
531       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
532          any global register variables.  */
533       if (fixed_regs[reg])
534         continue;
535
536       if ((int_or_sig_p && !cfun->machine->is_leaf && call_used_regs[reg])
537           || (df_regs_ever_live_p (reg)
538               && (int_or_sig_p || !call_used_regs[reg])
539               && !(frame_pointer_needed
540                    && (reg == REG_Y || reg == (REG_Y+1)))))
541         {
542           if (set)
543             SET_HARD_REG_BIT (*set, reg);
544           count++;
545         }
546     }
547   return count;
548 }
549
550 /* Compute offset between arg_pointer and frame_pointer.  */
551
552 int
553 initial_elimination_offset (int from, int to)
554 {
555   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
556     return 0;
557   else
558     {
559       int offset = frame_pointer_needed ? 2 : 0;
560       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
561
562       offset += avr_regs_to_save (NULL);
563       return get_frame_size () + (avr_pc_size) + 1 + offset;
564     }
565 }
566
567 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
568    frame pointer by +STARTING_FRAME_OFFSET.
569    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
570    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
571
572 rtx avr_builtin_setjmp_frame_value (void)
573 {
574   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
575                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
576 }
577
578 /* Return 1 if the function epilogue is just a single "ret".  */
579
580 int
581 avr_simple_epilogue (void)
582 {
583   return (! frame_pointer_needed
584           && get_frame_size () == 0
585           && avr_regs_to_save (NULL) == 0
586           && ! interrupt_function_p (current_function_decl)
587           && ! signal_function_p (current_function_decl)
588           && ! avr_naked_function_p (current_function_decl)
589           && ! TREE_THIS_VOLATILE (current_function_decl));
590 }
591
592 /* This function checks sequence of live registers.  */
593
594 static int
595 sequent_regs_live (void)
596 {
597   int reg;
598   int live_seq=0;
599   int cur_seq=0;
600
601   for (reg = 0; reg < 18; ++reg)
602     {
603       if (!call_used_regs[reg])
604         {
605           if (df_regs_ever_live_p (reg))
606             {
607               ++live_seq;
608               ++cur_seq;
609             }
610           else
611             cur_seq = 0;
612         }
613     }
614
615   if (!frame_pointer_needed)
616     {
617       if (df_regs_ever_live_p (REG_Y))
618         {
619           ++live_seq;
620           ++cur_seq;
621         }
622       else
623         cur_seq = 0;
624
625       if (df_regs_ever_live_p (REG_Y+1))
626         {
627           ++live_seq;
628           ++cur_seq;
629         }
630       else
631         cur_seq = 0;
632     }
633   else
634     {
635       cur_seq += 2;
636       live_seq += 2;
637     }
638   return (cur_seq == live_seq) ? live_seq : 0;
639 }
640
641 /* Obtain the length sequence of insns.  */
642
643 int
644 get_sequence_length (rtx insns)
645 {
646   rtx insn;
647   int length;
648   
649   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
650     length += get_attr_length (insn);
651                 
652   return length;
653 }
654
655 /*  Output function prologue.  */
656
657 void
658 expand_prologue (void)
659 {
660   int live_seq;
661   HARD_REG_SET set;
662   int minimize;
663   HOST_WIDE_INT size = get_frame_size();
664   /* Define templates for push instructions.  */
665   rtx pushbyte = gen_rtx_MEM (QImode,
666                   gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
667   rtx pushword = gen_rtx_MEM (HImode,
668                   gen_rtx_POST_DEC (HImode, stack_pointer_rtx));
669   rtx insn;
670
671   last_insn_address = 0;
672   
673   /* Init cfun->machine.  */
674   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
675   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
676   cfun->machine->is_signal = signal_function_p (current_function_decl);
677   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
678   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
679   
680   /* Prologue: naked.  */
681   if (cfun->machine->is_naked)
682     {
683       return;
684     }
685
686   avr_regs_to_save (&set);
687   live_seq = sequent_regs_live ();
688   minimize = (TARGET_CALL_PROLOGUES
689               && !cfun->machine->is_interrupt
690               && !cfun->machine->is_signal
691               && !cfun->machine->is_OS_task
692               && !cfun->machine->is_OS_main
693               && live_seq);
694
695   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
696     {
697       if (cfun->machine->is_interrupt)
698         {
699           /* Enable interrupts.  */
700           insn = emit_insn (gen_enable_interrupt ());
701           RTX_FRAME_RELATED_P (insn) = 1;
702         }
703         
704       /* Push zero reg.  */
705       insn = emit_move_insn (pushbyte, zero_reg_rtx);
706       RTX_FRAME_RELATED_P (insn) = 1;
707
708       /* Push tmp reg.  */
709       insn = emit_move_insn (pushbyte, tmp_reg_rtx);
710       RTX_FRAME_RELATED_P (insn) = 1;
711
712       /* Push SREG.  */
713       insn = emit_move_insn (tmp_reg_rtx, 
714                              gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
715       RTX_FRAME_RELATED_P (insn) = 1;
716       insn = emit_move_insn (pushbyte, tmp_reg_rtx);
717       RTX_FRAME_RELATED_P (insn) = 1;
718
719       /* Push RAMPZ.  */
720       if(AVR_HAVE_RAMPZ 
721          && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
722         {
723           insn = emit_move_insn (tmp_reg_rtx, 
724                                  gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
725           RTX_FRAME_RELATED_P (insn) = 1;
726           insn = emit_move_insn (pushbyte, tmp_reg_rtx);
727           RTX_FRAME_RELATED_P (insn) = 1;
728         }
729         
730       /* Clear zero reg.  */
731       insn = emit_move_insn (zero_reg_rtx, const0_rtx);
732       RTX_FRAME_RELATED_P (insn) = 1;
733
734       /* Prevent any attempt to delete the setting of ZERO_REG!  */
735       emit_use (zero_reg_rtx);
736     }
737   if (minimize && (frame_pointer_needed 
738                    || (AVR_2_BYTE_PC && live_seq > 6)
739                    || live_seq > 7)) 
740     {
741       insn = emit_move_insn (gen_rtx_REG (HImode, REG_X), 
742                              gen_int_mode (size, HImode));
743       RTX_FRAME_RELATED_P (insn) = 1;
744
745       insn = 
746         emit_insn (gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
747                                             gen_int_mode (size + live_seq, HImode)));
748       RTX_FRAME_RELATED_P (insn) = 1;
749     }
750   else
751     {
752       int reg;
753       for (reg = 0; reg < 32; ++reg)
754         {
755           if (TEST_HARD_REG_BIT (set, reg))
756             {
757               /* Emit push of register to save.  */
758               insn=emit_move_insn (pushbyte, gen_rtx_REG (QImode, reg));
759               RTX_FRAME_RELATED_P (insn) = 1;
760             }
761         }
762       if (frame_pointer_needed)
763         {
764           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
765             {
766               /* Push frame pointer.  */
767               insn = emit_move_insn (pushword, frame_pointer_rtx);
768               RTX_FRAME_RELATED_P (insn) = 1;
769             }
770
771           if (!size)
772             {
773               insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
774               RTX_FRAME_RELATED_P (insn) = 1;
775             }
776           else
777             {
778               /*  Creating a frame can be done by direct manipulation of the
779                   stack or via the frame pointer. These two methods are:
780                     fp=sp
781                     fp-=size
782                     sp=fp
783                 OR
784                     sp-=size
785                     fp=sp
786               the optimum method depends on function type, stack and frame size.
787               To avoid a complex logic, both methods are tested and shortest
788               is selected.  */
789               rtx myfp;
790               rtx fp_plus_insns; 
791               rtx sp_plus_insns = NULL_RTX;
792
793               if (TARGET_TINY_STACK)
794                 {
795                   /* The high byte (r29) doesn't change - prefer 'subi' (1 cycle)
796                      over 'sbiw' (2 cycles, same size).  */
797                   myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
798                 }
799               else 
800                 {
801                   /*  Normal sized addition.  */
802                   myfp = frame_pointer_rtx;
803                 }
804
805               /* Method 1-Adjust frame pointer.  */
806               start_sequence ();
807
808               insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
809               RTX_FRAME_RELATED_P (insn) = 1;
810
811               insn = 
812                 emit_move_insn (myfp,
813                                 gen_rtx_PLUS (GET_MODE(myfp), myfp, 
814                                               gen_int_mode (-size, 
815                                                             GET_MODE(myfp))));
816               RTX_FRAME_RELATED_P (insn) = 1;
817
818               /* Copy to stack pointer.  */
819               if (TARGET_TINY_STACK)
820                 {
821                   insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
822                   RTX_FRAME_RELATED_P (insn) = 1;
823                 }
824               else if (TARGET_NO_INTERRUPTS 
825                        || cfun->machine->is_signal
826                        || cfun->machine->is_OS_main)
827                 {
828                   insn = 
829                     emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
830                                                        frame_pointer_rtx));
831                   RTX_FRAME_RELATED_P (insn) = 1;               
832                 }
833               else if (cfun->machine->is_interrupt)
834                 {
835                   insn = emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
836                                                            frame_pointer_rtx));
837                   RTX_FRAME_RELATED_P (insn) = 1;
838                 }
839               else
840                 {
841                   insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
842                   RTX_FRAME_RELATED_P (insn) = 1;
843                 }
844
845               fp_plus_insns = get_insns ();
846               end_sequence ();
847
848               /* Method 2-Adjust Stack pointer.  */
849               if (size <= 6)
850                 {
851                   start_sequence ();
852
853                   insn = 
854                     emit_move_insn (stack_pointer_rtx,
855                                     gen_rtx_PLUS (HImode, 
856                                                   stack_pointer_rtx, 
857                                                   gen_int_mode (-size, 
858                                                                 HImode)));
859                   RTX_FRAME_RELATED_P (insn) = 1;
860                   
861                   insn = 
862                     emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
863                   RTX_FRAME_RELATED_P (insn) = 1;
864
865                   sp_plus_insns = get_insns ();
866                   end_sequence ();
867                 }
868
869               /* Use shortest method.  */
870               if (size <= 6 && (get_sequence_length (sp_plus_insns) 
871                                  < get_sequence_length (fp_plus_insns)))
872                 emit_insn (sp_plus_insns);
873               else
874                 emit_insn (fp_plus_insns);
875             }
876         }
877     }
878 }
879
880 /* Output summary at end of function prologue.  */
881
882 static void
883 avr_asm_function_end_prologue (FILE *file)
884 {
885   if (cfun->machine->is_naked)
886     {
887       fputs ("/* prologue: naked */\n", file);
888     }
889   else
890     {
891       if (cfun->machine->is_interrupt)
892         {
893           fputs ("/* prologue: Interrupt */\n", file);
894         }
895       else if (cfun->machine->is_signal)
896         {
897           fputs ("/* prologue: Signal */\n", file);
898         }
899       else
900         fputs ("/* prologue: function */\n", file);
901     }
902   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
903                  get_frame_size());
904 }
905
906
907 /* Implement EPILOGUE_USES.  */
908
909 int
910 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
911 {
912   if (reload_completed 
913       && cfun->machine
914       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
915     return 1;
916   return 0;
917 }
918
919 /*  Output RTL epilogue.  */
920
921 void
922 expand_epilogue (void)
923 {
924   int reg;
925   int live_seq;
926   HARD_REG_SET set;      
927   int minimize;
928   HOST_WIDE_INT size = get_frame_size();
929   
930   /* epilogue: naked  */
931   if (cfun->machine->is_naked)
932     {
933       emit_jump_insn (gen_return ());
934       return;
935     }
936
937   avr_regs_to_save (&set);
938   live_seq = sequent_regs_live ();
939   minimize = (TARGET_CALL_PROLOGUES
940               && !cfun->machine->is_interrupt
941               && !cfun->machine->is_signal
942               && !cfun->machine->is_OS_task
943               && !cfun->machine->is_OS_main
944               && live_seq);
945   
946   if (minimize && (frame_pointer_needed || live_seq > 4))
947     {
948       if (frame_pointer_needed)
949         {
950           /*  Get rid of frame.  */
951           emit_move_insn(frame_pointer_rtx,
952                          gen_rtx_PLUS (HImode, frame_pointer_rtx,
953                                        gen_int_mode (size, HImode)));
954         }
955       else
956         {
957           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
958         }
959         
960       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
961     }
962   else
963     {
964       if (frame_pointer_needed)
965         {
966           if (size)
967             {
968               /* Try two methods to adjust stack and select shortest.  */
969               rtx myfp;
970               rtx fp_plus_insns;
971               rtx sp_plus_insns = NULL_RTX;
972               
973               if (TARGET_TINY_STACK)
974                 {
975                   /* The high byte (r29) doesn't change - prefer 'subi' 
976                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
977                   myfp = gen_rtx_REG (QImode, REGNO (frame_pointer_rtx));
978                 }
979               else 
980                 {
981                   /* Normal sized addition.  */
982                   myfp = frame_pointer_rtx;
983                 }
984               
985               /* Method 1-Adjust frame pointer.  */
986               start_sequence ();
987
988               emit_move_insn (myfp,
989                               gen_rtx_PLUS (HImode, myfp,
990                                             gen_int_mode (size, 
991                                                           GET_MODE(myfp))));
992
993               /* Copy to stack pointer.  */
994               if (TARGET_TINY_STACK)
995                 {
996                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
997                 }
998               else if (TARGET_NO_INTERRUPTS 
999                        || cfun->machine->is_signal)
1000                 {
1001                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
1002                                                      frame_pointer_rtx));
1003                 }
1004               else if (cfun->machine->is_interrupt)
1005                 {
1006                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
1007                                                     frame_pointer_rtx));
1008                 }
1009               else
1010                 {
1011                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1012                 }
1013
1014               fp_plus_insns = get_insns ();
1015               end_sequence ();        
1016
1017               /* Method 2-Adjust Stack pointer.  */
1018               if (size <= 5)
1019                 {
1020                   start_sequence ();
1021
1022                   emit_move_insn (stack_pointer_rtx,
1023                                   gen_rtx_PLUS (HImode, stack_pointer_rtx,
1024                                                 gen_int_mode (size, 
1025                                                               HImode)));
1026
1027                   sp_plus_insns = get_insns ();
1028                   end_sequence ();
1029                 }
1030
1031               /* Use shortest method.  */
1032               if (size <= 5 && (get_sequence_length (sp_plus_insns) 
1033                                  < get_sequence_length (fp_plus_insns)))
1034                 emit_insn (sp_plus_insns);
1035               else
1036                 emit_insn (fp_plus_insns);
1037             }
1038           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1039             {
1040               /* Restore previous frame_pointer.  */
1041               emit_insn (gen_pophi (frame_pointer_rtx));
1042             }
1043         }
1044       /* Restore used registers.  */
1045       for (reg = 31; reg >= 0; --reg)
1046         {
1047           if (TEST_HARD_REG_BIT (set, reg))
1048               emit_insn (gen_popqi (gen_rtx_REG (QImode, reg)));
1049         }
1050       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1051         {
1052           /* Restore RAMPZ using tmp reg as scratch.  */
1053           if(AVR_HAVE_RAMPZ 
1054              && (TEST_HARD_REG_BIT (set, REG_Z) && TEST_HARD_REG_BIT (set, REG_Z + 1)))
1055             {
1056               emit_insn (gen_popqi (tmp_reg_rtx));
1057               emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(RAMPZ_ADDR)), 
1058                               tmp_reg_rtx);
1059             }
1060
1061           /* Restore SREG using tmp reg as scratch.  */
1062           emit_insn (gen_popqi (tmp_reg_rtx));
1063       
1064           emit_move_insn (gen_rtx_MEM(QImode, GEN_INT(SREG_ADDR)), 
1065                           tmp_reg_rtx);
1066
1067           /* Restore tmp REG.  */
1068           emit_insn (gen_popqi (tmp_reg_rtx));
1069
1070           /* Restore zero REG.  */
1071           emit_insn (gen_popqi (zero_reg_rtx));
1072         }
1073
1074       emit_jump_insn (gen_return ());
1075     }
1076 }
1077
1078 /* Output summary messages at beginning of function epilogue.  */
1079
1080 static void
1081 avr_asm_function_begin_epilogue (FILE *file)
1082 {
1083   fprintf (file, "/* epilogue start */\n");
1084 }
1085
1086 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1087    machine for a memory operand of mode MODE.  */
1088
1089 int
1090 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
1091 {
1092   enum reg_class r = NO_REGS;
1093   
1094   if (TARGET_ALL_DEBUG)
1095     {
1096       fprintf (stderr, "mode: (%s) %s %s %s %s:",
1097                GET_MODE_NAME(mode),
1098                strict ? "(strict)": "",
1099                reload_completed ? "(reload_completed)": "",
1100                reload_in_progress ? "(reload_in_progress)": "",
1101                reg_renumber ? "(reg_renumber)" : "");
1102       if (GET_CODE (x) == PLUS
1103           && REG_P (XEXP (x, 0))
1104           && GET_CODE (XEXP (x, 1)) == CONST_INT
1105           && INTVAL (XEXP (x, 1)) >= 0
1106           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
1107           && reg_renumber
1108           )
1109         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1110                  true_regnum (XEXP (x, 0)));
1111       debug_rtx (x);
1112     }
1113   if (!strict && GET_CODE (x) == SUBREG)
1114         x = SUBREG_REG (x);
1115   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
1116                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
1117     r = POINTER_REGS;
1118   else if (CONSTANT_ADDRESS_P (x))
1119     r = ALL_REGS;
1120   else if (GET_CODE (x) == PLUS
1121            && REG_P (XEXP (x, 0))
1122            && GET_CODE (XEXP (x, 1)) == CONST_INT
1123            && INTVAL (XEXP (x, 1)) >= 0)
1124     {
1125       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1126       if (fit)
1127         {
1128           if (! strict
1129               || REGNO (XEXP (x,0)) == REG_X
1130               || REGNO (XEXP (x,0)) == REG_Y
1131               || REGNO (XEXP (x,0)) == REG_Z)
1132             r = BASE_POINTER_REGS;
1133           if (XEXP (x,0) == frame_pointer_rtx
1134               || XEXP (x,0) == arg_pointer_rtx)
1135             r = BASE_POINTER_REGS;
1136         }
1137       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
1138         r = POINTER_Y_REGS;
1139     }
1140   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1141            && REG_P (XEXP (x, 0))
1142            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
1143                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
1144     {
1145       r = POINTER_REGS;
1146     }
1147   if (TARGET_ALL_DEBUG)
1148     {
1149       fprintf (stderr, "   ret = %c\n", r + '0');
1150     }
1151   return r == NO_REGS ? 0 : (int)r;
1152 }
1153
1154 /* Attempts to replace X with a valid
1155    memory address for an operand of mode MODE  */
1156
1157 rtx
1158 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1159 {
1160   x = oldx;
1161   if (TARGET_ALL_DEBUG)
1162     {
1163       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1164       debug_rtx (oldx);
1165     }
1166   
1167   if (GET_CODE (oldx) == PLUS
1168       && REG_P (XEXP (oldx,0)))
1169     {
1170       if (REG_P (XEXP (oldx,1)))
1171         x = force_reg (GET_MODE (oldx), oldx);
1172       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1173         {
1174           int offs = INTVAL (XEXP (oldx,1));
1175           if (frame_pointer_rtx != XEXP (oldx,0))
1176             if (offs > MAX_LD_OFFSET (mode))
1177               {
1178                 if (TARGET_ALL_DEBUG)
1179                   fprintf (stderr, "force_reg (big offset)\n");
1180                 x = force_reg (GET_MODE (oldx), oldx);
1181               }
1182         }
1183     }
1184   return x;
1185 }
1186
1187
1188 /* Return a pointer register name as a string.  */
1189
1190 static const char *
1191 ptrreg_to_str (int regno)
1192 {
1193   switch (regno)
1194     {
1195     case REG_X: return "X";
1196     case REG_Y: return "Y";
1197     case REG_Z: return "Z";
1198     default:
1199       output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1200     }
1201   return NULL;
1202 }
1203
1204 /* Return the condition name as a string.
1205    Used in conditional jump constructing  */
1206
1207 static const char *
1208 cond_string (enum rtx_code code)
1209 {
1210   switch (code)
1211     {
1212     case NE:
1213       return "ne";
1214     case EQ:
1215       return "eq";
1216     case GE:
1217       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1218         return "pl";
1219       else
1220         return "ge";
1221     case LT:
1222       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1223         return "mi";
1224       else
1225         return "lt";
1226     case GEU:
1227       return "sh";
1228     case LTU:
1229       return "lo";
1230     default:
1231       gcc_unreachable ();
1232     }
1233 }
1234
1235 /* Output ADDR to FILE as address.  */
1236
1237 void
1238 print_operand_address (FILE *file, rtx addr)
1239 {
1240   switch (GET_CODE (addr))
1241     {
1242     case REG:
1243       fprintf (file, ptrreg_to_str (REGNO (addr)));
1244       break;
1245
1246     case PRE_DEC:
1247       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1248       break;
1249
1250     case POST_INC:
1251       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1252       break;
1253
1254     default:
1255       if (CONSTANT_ADDRESS_P (addr)
1256           && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1257               || GET_CODE (addr) == LABEL_REF))
1258         {
1259           fprintf (file, "gs(");
1260           output_addr_const (file,addr);
1261           fprintf (file ,")");
1262         }
1263       else
1264         output_addr_const (file, addr);
1265     }
1266 }
1267
1268
1269 /* Output X as assembler operand to file FILE.  */
1270      
1271 void
1272 print_operand (FILE *file, rtx x, int code)
1273 {
1274   int abcd = 0;
1275
1276   if (code >= 'A' && code <= 'D')
1277     abcd = code - 'A';
1278
1279   if (code == '~')
1280     {
1281       if (!AVR_HAVE_JMP_CALL)
1282         fputc ('r', file);
1283     }
1284   else if (code == '!')
1285     {
1286       if (AVR_HAVE_EIJMP_EICALL)
1287         fputc ('e', file);
1288     }
1289   else if (REG_P (x))
1290     {
1291       if (x == zero_reg_rtx)
1292         fprintf (file, "__zero_reg__");
1293       else
1294         fprintf (file, reg_names[true_regnum (x) + abcd]);
1295     }
1296   else if (GET_CODE (x) == CONST_INT)
1297     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1298   else if (GET_CODE (x) == MEM)
1299     {
1300       rtx addr = XEXP (x,0);
1301
1302       if (CONSTANT_P (addr) && abcd)
1303         {
1304           fputc ('(', file);
1305           output_address (addr);
1306           fprintf (file, ")+%d", abcd);
1307         }
1308       else if (code == 'o')
1309         {
1310           if (GET_CODE (addr) != PLUS)
1311             fatal_insn ("bad address, not (reg+disp):", addr);
1312
1313           print_operand (file, XEXP (addr, 1), 0);
1314         }
1315       else if (code == 'p' || code == 'r')
1316         {
1317           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1318             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1319           
1320           if (code == 'p')
1321             print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1322           else
1323             print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1324         }
1325       else if (GET_CODE (addr) == PLUS)
1326         {
1327           print_operand_address (file, XEXP (addr,0));
1328           if (REGNO (XEXP (addr, 0)) == REG_X)
1329             fatal_insn ("internal compiler error.  Bad address:"
1330                         ,addr);
1331           fputc ('+', file);
1332           print_operand (file, XEXP (addr,1), code);
1333         }
1334       else
1335         print_operand_address (file, addr);
1336     }
1337   else if (GET_CODE (x) == CONST_DOUBLE)
1338     {
1339       long val;
1340       REAL_VALUE_TYPE rv;
1341       if (GET_MODE (x) != SFmode)
1342         fatal_insn ("internal compiler error.  Unknown mode:", x);
1343       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1344       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1345       fprintf (file, "0x%lx", val);
1346     }
1347   else if (code == 'j')
1348     fputs (cond_string (GET_CODE (x)), file);
1349   else if (code == 'k')
1350     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1351   else
1352     print_operand_address (file, x);
1353 }
1354
1355 /* Update the condition code in the INSN.  */
1356
1357 void
1358 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1359 {
1360   rtx set;
1361   
1362   switch (get_attr_cc (insn))
1363     {
1364     case CC_NONE:
1365       /* Insn does not affect CC at all.  */
1366       break;
1367
1368     case CC_SET_N:
1369       CC_STATUS_INIT;
1370       break;
1371
1372     case CC_SET_ZN:
1373       set = single_set (insn);
1374       CC_STATUS_INIT;
1375       if (set)
1376         {
1377           cc_status.flags |= CC_NO_OVERFLOW;
1378           cc_status.value1 = SET_DEST (set);
1379         }
1380       break;
1381
1382     case CC_SET_CZN:
1383       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1384          The V flag may or may not be known but that's ok because
1385          alter_cond will change tests to use EQ/NE.  */
1386       set = single_set (insn);
1387       CC_STATUS_INIT;
1388       if (set)
1389         {
1390           cc_status.value1 = SET_DEST (set);
1391           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1392         }
1393       break;
1394
1395     case CC_COMPARE:
1396       set = single_set (insn);
1397       CC_STATUS_INIT;
1398       if (set)
1399         cc_status.value1 = SET_SRC (set);
1400       break;
1401       
1402     case CC_CLOBBER:
1403       /* Insn doesn't leave CC in a usable state.  */
1404       CC_STATUS_INIT;
1405
1406       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1407       set = single_set (insn);
1408       if (set)
1409         {
1410           rtx src = SET_SRC (set);
1411           
1412           if (GET_CODE (src) == ASHIFTRT
1413               && GET_MODE (src) == QImode)
1414             {
1415               rtx x = XEXP (src, 1);
1416
1417               if (GET_CODE (x) == CONST_INT
1418                   && INTVAL (x) > 0
1419                   && INTVAL (x) != 6)
1420                 {
1421                   cc_status.value1 = SET_DEST (set);
1422                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1423                 }
1424             }
1425         }
1426       break;
1427     }
1428 }
1429
1430 /* Return maximum number of consecutive registers of
1431    class CLASS needed to hold a value of mode MODE.  */
1432
1433 int
1434 class_max_nregs (enum reg_class rclass ATTRIBUTE_UNUSED,enum machine_mode mode)
1435 {
1436   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1437 }
1438
1439 /* Choose mode for jump insn:
1440    1 - relative jump in range -63 <= x <= 62 ;
1441    2 - relative jump in range -2046 <= x <= 2045 ;
1442    3 - absolute jump (only for ATmega[16]03).  */
1443
1444 int
1445 avr_jump_mode (rtx x, rtx insn)
1446 {
1447   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1448                                             ? XEXP (x, 0) : x));
1449   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1450   int jump_distance = cur_addr - dest_addr;
1451   
1452   if (-63 <= jump_distance && jump_distance <= 62)
1453     return 1;
1454   else if (-2046 <= jump_distance && jump_distance <= 2045)
1455     return 2;
1456   else if (AVR_HAVE_JMP_CALL)
1457     return 3;
1458   
1459   return 2;
1460 }
1461
1462 /* return an AVR condition jump commands.
1463    X is a comparison RTX.
1464    LEN is a number returned by avr_jump_mode function.
1465    if REVERSE nonzero then condition code in X must be reversed.  */
1466
1467 const char *
1468 ret_cond_branch (rtx x, int len, int reverse)
1469 {
1470   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1471   
1472   switch (cond)
1473     {
1474     case GT:
1475       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1476         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1477                             AS1 (brpl,%0)) :
1478                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1479                             AS1 (brmi,.+2) CR_TAB
1480                             AS1 (rjmp,%0)) :
1481                 (AS1 (breq,.+6) CR_TAB
1482                  AS1 (brmi,.+4) CR_TAB
1483                  AS1 (jmp,%0)));
1484           
1485       else
1486         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1487                             AS1 (brge,%0)) :
1488                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1489                             AS1 (brlt,.+2) CR_TAB
1490                             AS1 (rjmp,%0)) :
1491                 (AS1 (breq,.+6) CR_TAB
1492                  AS1 (brlt,.+4) CR_TAB
1493                  AS1 (jmp,%0)));
1494     case GTU:
1495       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1496                           AS1 (brsh,%0)) :
1497               len == 2 ? (AS1 (breq,.+4) CR_TAB
1498                           AS1 (brlo,.+2) CR_TAB
1499                           AS1 (rjmp,%0)) :
1500               (AS1 (breq,.+6) CR_TAB
1501                AS1 (brlo,.+4) CR_TAB
1502                AS1 (jmp,%0)));
1503     case LE:
1504       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1505         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1506                             AS1 (brmi,%0)) :
1507                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1508                             AS1 (brpl,.+2) CR_TAB
1509                             AS1 (rjmp,%0)) :
1510                 (AS1 (breq,.+2) CR_TAB
1511                  AS1 (brpl,.+4) CR_TAB
1512                  AS1 (jmp,%0)));
1513       else
1514         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1515                             AS1 (brlt,%0)) :
1516                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1517                             AS1 (brge,.+2) CR_TAB
1518                             AS1 (rjmp,%0)) :
1519                 (AS1 (breq,.+2) CR_TAB
1520                  AS1 (brge,.+4) CR_TAB
1521                  AS1 (jmp,%0)));
1522     case LEU:
1523       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1524                           AS1 (brlo,%0)) :
1525               len == 2 ? (AS1 (breq,.+2) CR_TAB
1526                           AS1 (brsh,.+2) CR_TAB
1527                           AS1 (rjmp,%0)) :
1528               (AS1 (breq,.+2) CR_TAB
1529                AS1 (brsh,.+4) CR_TAB
1530                AS1 (jmp,%0)));
1531     default:
1532       if (reverse)
1533         {
1534           switch (len)
1535             {
1536             case 1:
1537               return AS1 (br%k1,%0);
1538             case 2:
1539               return (AS1 (br%j1,.+2) CR_TAB
1540                       AS1 (rjmp,%0));
1541             default:
1542               return (AS1 (br%j1,.+4) CR_TAB
1543                       AS1 (jmp,%0));
1544             }
1545         }
1546         else
1547           {
1548             switch (len)
1549               {
1550               case 1:
1551                 return AS1 (br%j1,%0);
1552               case 2:
1553                 return (AS1 (br%k1,.+2) CR_TAB
1554                         AS1 (rjmp,%0));
1555               default:
1556                 return (AS1 (br%k1,.+4) CR_TAB
1557                         AS1 (jmp,%0));
1558               }
1559           }
1560     }
1561   return "";
1562 }
1563
1564 /* Predicate function for immediate operand which fits to byte (8bit) */
1565
1566 int
1567 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1568 {
1569   return (GET_CODE (op) == CONST_INT
1570           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1571 }
1572
1573 /* Output all insn addresses and their sizes into the assembly language
1574    output file.  This is helpful for debugging whether the length attributes
1575    in the md file are correct.
1576    Output insn cost for next insn.  */
1577
1578 void
1579 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1580                     int num_operands ATTRIBUTE_UNUSED)
1581 {
1582   int uid = INSN_UID (insn);
1583
1584   if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1585     {
1586       fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1587                INSN_ADDRESSES (uid),
1588                INSN_ADDRESSES (uid) - last_insn_address,
1589                rtx_cost (PATTERN (insn), INSN, !optimize_size));
1590     }
1591   last_insn_address = INSN_ADDRESSES (uid);
1592 }
1593
1594 /* Return 0 if undefined, 1 if always true or always false.  */
1595
1596 int
1597 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1598 {
1599   unsigned int max = (mode == QImode ? 0xff :
1600                       mode == HImode ? 0xffff :
1601                       mode == SImode ? 0xffffffff : 0);
1602   if (max && op && GET_CODE (x) == CONST_INT)
1603     {
1604       if (unsigned_condition (op) != op)
1605         max >>= 1;
1606
1607       if (max != (INTVAL (x) & max)
1608           && INTVAL (x) != 0xff)
1609         return 1;
1610     }
1611   return 0;
1612 }
1613
1614
1615 /* Returns nonzero if REGNO is the number of a hard
1616    register in which function arguments are sometimes passed.  */
1617
1618 int
1619 function_arg_regno_p(int r)
1620 {
1621   return (r >= 8 && r <= 25);
1622 }
1623
1624 /* Initializing the variable cum for the state at the beginning
1625    of the argument list.  */
1626
1627 void
1628 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1629                       tree fndecl ATTRIBUTE_UNUSED)
1630 {
1631   cum->nregs = 18;
1632   cum->regno = FIRST_CUM_REG;
1633   if (!libname && fntype)
1634     {
1635       int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1636                     && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1637                         != void_type_node));
1638       if (stdarg)
1639         cum->nregs = 0;
1640     }
1641 }
1642
1643 /* Returns the number of registers to allocate for a function argument.  */
1644
1645 static int
1646 avr_num_arg_regs (enum machine_mode mode, tree type)
1647 {
1648   int size;
1649
1650   if (mode == BLKmode)
1651     size = int_size_in_bytes (type);
1652   else
1653     size = GET_MODE_SIZE (mode);
1654
1655   /* Align all function arguments to start in even-numbered registers.
1656      Odd-sized arguments leave holes above them.  */
1657
1658   return (size + 1) & ~1;
1659 }
1660
1661 /* Controls whether a function argument is passed
1662    in a register, and which register.  */
1663
1664 rtx
1665 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1666               int named ATTRIBUTE_UNUSED)
1667 {
1668   int bytes = avr_num_arg_regs (mode, type);
1669
1670   if (cum->nregs && bytes <= cum->nregs)
1671     return gen_rtx_REG (mode, cum->regno - bytes);
1672
1673   return NULL_RTX;
1674 }
1675
1676 /* Update the summarizer variable CUM to advance past an argument
1677    in the argument list.  */
1678    
1679 void
1680 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1681                       int named ATTRIBUTE_UNUSED)
1682 {
1683   int bytes = avr_num_arg_regs (mode, type);
1684
1685   cum->nregs -= bytes;
1686   cum->regno -= bytes;
1687
1688   if (cum->nregs <= 0)
1689     {
1690       cum->nregs = 0;
1691       cum->regno = FIRST_CUM_REG;
1692     }
1693 }
1694
1695 /***********************************************************************
1696   Functions for outputting various mov's for a various modes
1697 ************************************************************************/
1698 const char *
1699 output_movqi (rtx insn, rtx operands[], int *l)
1700 {
1701   int dummy;
1702   rtx dest = operands[0];
1703   rtx src = operands[1];
1704   int *real_l = l;
1705   
1706   if (!l)
1707     l = &dummy;
1708
1709   *l = 1;
1710   
1711   if (register_operand (dest, QImode))
1712     {
1713       if (register_operand (src, QImode)) /* mov r,r */
1714         {
1715           if (test_hard_reg_class (STACK_REG, dest))
1716             return AS2 (out,%0,%1);
1717           else if (test_hard_reg_class (STACK_REG, src))
1718             return AS2 (in,%0,%1);
1719           
1720           return AS2 (mov,%0,%1);
1721         }
1722       else if (CONSTANT_P (src))
1723         {
1724           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1725             return AS2 (ldi,%0,lo8(%1));
1726           
1727           if (GET_CODE (src) == CONST_INT)
1728             {
1729               if (src == const0_rtx) /* mov r,L */
1730                 return AS1 (clr,%0);
1731               else if (src == const1_rtx)
1732                 {
1733                   *l = 2;
1734                   return (AS1 (clr,%0) CR_TAB
1735                           AS1 (inc,%0));
1736                 }
1737               else if (src == constm1_rtx)
1738                 {
1739                   /* Immediate constants -1 to any register */
1740                   *l = 2;
1741                   return (AS1 (clr,%0) CR_TAB
1742                           AS1 (dec,%0));
1743                 }
1744               else
1745                 {
1746                   int bit_nr = exact_log2 (INTVAL (src));
1747
1748                   if (bit_nr >= 0)
1749                     {
1750                       *l = 3;
1751                       if (!real_l)
1752                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1753                                           "set"), operands);
1754                       if (!real_l)
1755                         avr_output_bld (operands, bit_nr);
1756
1757                       return "";
1758                     }
1759                 }
1760             }
1761           
1762           /* Last resort, larger than loading from memory.  */
1763           *l = 4;
1764           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1765                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1766                   AS2 (mov,%0,r31)          CR_TAB
1767                   AS2 (mov,r31,__tmp_reg__));
1768         }
1769       else if (GET_CODE (src) == MEM)
1770         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1771     }
1772   else if (GET_CODE (dest) == MEM)
1773     {
1774       const char *templ;
1775
1776       if (src == const0_rtx)
1777         operands[1] = zero_reg_rtx;
1778
1779       templ = out_movqi_mr_r (insn, operands, real_l);
1780
1781       if (!real_l)
1782         output_asm_insn (templ, operands);
1783
1784       operands[1] = src;
1785     }
1786   return "";
1787 }
1788
1789
1790 const char *
1791 output_movhi (rtx insn, rtx operands[], int *l)
1792 {
1793   int dummy;
1794   rtx dest = operands[0];
1795   rtx src = operands[1];
1796   int *real_l = l;
1797   
1798   if (!l)
1799     l = &dummy;
1800   
1801   if (register_operand (dest, HImode))
1802     {
1803       if (register_operand (src, HImode)) /* mov r,r */
1804         {
1805           if (test_hard_reg_class (STACK_REG, dest))
1806             {
1807               if (TARGET_TINY_STACK)
1808                 return *l = 1, AS2 (out,__SP_L__,%A1);
1809               /* Use simple load of stack pointer if no interrupts are 
1810                  used.  */
1811               else if (TARGET_NO_INTERRUPTS)
1812                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
1813                                 AS2 (out,__SP_L__,%A1));
1814               *l = 5;
1815               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
1816                       "cli"                          CR_TAB
1817                       AS2 (out,__SP_H__,%B1)         CR_TAB
1818                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1819                       AS2 (out,__SP_L__,%A1));
1820             }
1821           else if (test_hard_reg_class (STACK_REG, src))
1822             {
1823               *l = 2;   
1824               return (AS2 (in,%A0,__SP_L__) CR_TAB
1825                       AS2 (in,%B0,__SP_H__));
1826             }
1827
1828           if (AVR_HAVE_MOVW)
1829             {
1830               *l = 1;
1831               return (AS2 (movw,%0,%1));
1832             }
1833           else
1834             {
1835               *l = 2;
1836               return (AS2 (mov,%A0,%A1) CR_TAB
1837                       AS2 (mov,%B0,%B1));
1838             }
1839         }
1840       else if (CONSTANT_P (src))
1841         {
1842           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1843             {
1844               *l = 2;
1845               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1846                       AS2 (ldi,%B0,hi8(%1)));
1847             }
1848           
1849           if (GET_CODE (src) == CONST_INT)
1850             {
1851               if (src == const0_rtx) /* mov r,L */
1852                 {
1853                   *l = 2;
1854                   return (AS1 (clr,%A0) CR_TAB
1855                           AS1 (clr,%B0));
1856                 }
1857               else if (src == const1_rtx)
1858                 {
1859                   *l = 3;
1860                   return (AS1 (clr,%A0) CR_TAB
1861                           AS1 (clr,%B0) CR_TAB
1862                           AS1 (inc,%A0));
1863                 }
1864               else if (src == constm1_rtx)
1865                 {
1866                   /* Immediate constants -1 to any register */
1867                   *l = 3;
1868                   return (AS1 (clr,%0)  CR_TAB
1869                           AS1 (dec,%A0) CR_TAB
1870                           AS2 (mov,%B0,%A0));
1871                 }
1872               else
1873                 {
1874                   int bit_nr = exact_log2 (INTVAL (src));
1875
1876                   if (bit_nr >= 0)
1877                     {
1878                       *l = 4;
1879                       if (!real_l)
1880                         output_asm_insn ((AS1 (clr,%A0) CR_TAB
1881                                           AS1 (clr,%B0) CR_TAB
1882                                           "set"), operands);
1883                       if (!real_l)
1884                         avr_output_bld (operands, bit_nr);
1885
1886                       return "";
1887                     }
1888                 }
1889
1890               if ((INTVAL (src) & 0xff) == 0)
1891                 {
1892                   *l = 5;
1893                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1894                           AS1 (clr,%A0)             CR_TAB
1895                           AS2 (ldi,r31,hi8(%1))     CR_TAB
1896                           AS2 (mov,%B0,r31)         CR_TAB
1897                           AS2 (mov,r31,__tmp_reg__));
1898                 }
1899               else if ((INTVAL (src) & 0xff00) == 0)
1900                 {
1901                   *l = 5;
1902                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1903                           AS2 (ldi,r31,lo8(%1))     CR_TAB
1904                           AS2 (mov,%A0,r31)         CR_TAB
1905                           AS1 (clr,%B0)             CR_TAB
1906                           AS2 (mov,r31,__tmp_reg__));
1907                 }
1908             }
1909           
1910           /* Last resort, equal to loading from memory.  */
1911           *l = 6;
1912           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1913                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1914                   AS2 (mov,%A0,r31)         CR_TAB
1915                   AS2 (ldi,r31,hi8(%1))     CR_TAB
1916                   AS2 (mov,%B0,r31)         CR_TAB
1917                   AS2 (mov,r31,__tmp_reg__));
1918         }
1919       else if (GET_CODE (src) == MEM)
1920         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1921     }
1922   else if (GET_CODE (dest) == MEM)
1923     {
1924       const char *templ;
1925
1926       if (src == const0_rtx)
1927         operands[1] = zero_reg_rtx;
1928
1929       templ = out_movhi_mr_r (insn, operands, real_l);
1930
1931       if (!real_l)
1932         output_asm_insn (templ, operands);
1933
1934       operands[1] = src;
1935       return "";
1936     }
1937   fatal_insn ("invalid insn:", insn);
1938   return "";
1939 }
1940
1941 const char *
1942 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1943 {
1944   rtx dest = op[0];
1945   rtx src = op[1];
1946   rtx x = XEXP (src, 0);
1947   int dummy;
1948   
1949   if (!l)
1950     l = &dummy;
1951   
1952   if (CONSTANT_ADDRESS_P (x))
1953     {
1954       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
1955         {
1956           *l = 1;
1957           return AS2 (in,%0,__SREG__);
1958         }
1959       if (optimize > 0 && io_address_operand (x, QImode))
1960         {
1961           *l = 1;
1962           return AS2 (in,%0,%1-0x20);
1963         }
1964       *l = 2;
1965       return AS2 (lds,%0,%1);
1966     }
1967   /* memory access by reg+disp */
1968   else if (GET_CODE (x) == PLUS
1969       && REG_P (XEXP (x,0))
1970       && GET_CODE (XEXP (x,1)) == CONST_INT)
1971     {
1972       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1973         {
1974           int disp = INTVAL (XEXP (x,1));
1975           if (REGNO (XEXP (x,0)) != REG_Y)
1976             fatal_insn ("incorrect insn:",insn);
1977
1978           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1979             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1980                             AS2 (ldd,%0,Y+63)     CR_TAB
1981                             AS2 (sbiw,r28,%o1-63));
1982
1983           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1984                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1985                           AS2 (ld,%0,Y)            CR_TAB
1986                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1987                           AS2 (sbci,r29,hi8(%o1)));
1988         }
1989       else if (REGNO (XEXP (x,0)) == REG_X)
1990         {
1991           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1992              it but I have this situation with extremal optimizing options.  */
1993           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1994               || reg_unused_after (insn, XEXP (x,0)))
1995             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1996                             AS2 (ld,%0,X));
1997
1998           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1999                           AS2 (ld,%0,X)      CR_TAB
2000                           AS2 (sbiw,r26,%o1));
2001         }
2002       *l = 1;
2003       return AS2 (ldd,%0,%1);
2004     }
2005   *l = 1;
2006   return AS2 (ld,%0,%1);
2007 }
2008
2009 const char *
2010 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2011 {
2012   rtx dest = op[0];
2013   rtx src = op[1];
2014   rtx base = XEXP (src, 0);
2015   int reg_dest = true_regnum (dest);
2016   int reg_base = true_regnum (base);
2017   /* "volatile" forces reading low byte first, even if less efficient,
2018      for correct operation with 16-bit I/O registers.  */
2019   int mem_volatile_p = MEM_VOLATILE_P (src);
2020   int tmp;
2021
2022   if (!l)
2023     l = &tmp;
2024
2025   if (reg_base > 0)
2026     {
2027       if (reg_dest == reg_base)         /* R = (R) */
2028         {
2029           *l = 3;
2030           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2031                   AS2 (ld,%B0,%1) CR_TAB
2032                   AS2 (mov,%A0,__tmp_reg__));
2033         }
2034       else if (reg_base == REG_X)        /* (R26) */
2035         {
2036           if (reg_unused_after (insn, base))
2037             {
2038               *l = 2;
2039               return (AS2 (ld,%A0,X+) CR_TAB
2040                       AS2 (ld,%B0,X));
2041             }
2042           *l  = 3;
2043           return (AS2 (ld,%A0,X+) CR_TAB
2044                   AS2 (ld,%B0,X) CR_TAB
2045                   AS2 (sbiw,r26,1));
2046         }
2047       else                      /* (R)  */
2048         {
2049           *l = 2;
2050           return (AS2 (ld,%A0,%1)    CR_TAB
2051                   AS2 (ldd,%B0,%1+1));
2052         }
2053     }
2054   else if (GET_CODE (base) == PLUS) /* (R + i) */
2055     {
2056       int disp = INTVAL (XEXP (base, 1));
2057       int reg_base = true_regnum (XEXP (base, 0));
2058       
2059       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2060         {
2061           if (REGNO (XEXP (base, 0)) != REG_Y)
2062             fatal_insn ("incorrect insn:",insn);
2063           
2064           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2065             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2066                             AS2 (ldd,%A0,Y+62)    CR_TAB
2067                             AS2 (ldd,%B0,Y+63)    CR_TAB
2068                             AS2 (sbiw,r28,%o1-62));
2069
2070           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2071                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2072                           AS2 (ld,%A0,Y)           CR_TAB
2073                           AS2 (ldd,%B0,Y+1)        CR_TAB
2074                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2075                           AS2 (sbci,r29,hi8(%o1)));
2076         }
2077       if (reg_base == REG_X)
2078         {
2079           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2080              it but I have this situation with extremal
2081              optimization options.  */
2082           
2083           *l = 4;
2084           if (reg_base == reg_dest)
2085             return (AS2 (adiw,r26,%o1)      CR_TAB
2086                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2087                     AS2 (ld,%B0,X)          CR_TAB
2088                     AS2 (mov,%A0,__tmp_reg__));
2089
2090           return (AS2 (adiw,r26,%o1) CR_TAB
2091                   AS2 (ld,%A0,X+)    CR_TAB
2092                   AS2 (ld,%B0,X)     CR_TAB
2093                   AS2 (sbiw,r26,%o1+1));
2094         }
2095
2096       if (reg_base == reg_dest)
2097         {
2098           *l = 3;
2099           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2100                   AS2 (ldd,%B0,%B1)         CR_TAB
2101                   AS2 (mov,%A0,__tmp_reg__));
2102         }
2103       
2104       *l = 2;
2105       return (AS2 (ldd,%A0,%A1) CR_TAB
2106               AS2 (ldd,%B0,%B1));
2107     }
2108   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2109     {
2110       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2111         fatal_insn ("incorrect insn:", insn);
2112
2113       if (mem_volatile_p)
2114         {
2115           if (REGNO (XEXP (base, 0)) == REG_X)
2116             {
2117               *l = 4;
2118               return (AS2 (sbiw,r26,2)  CR_TAB
2119                       AS2 (ld,%A0,X+)   CR_TAB
2120                       AS2 (ld,%B0,X)    CR_TAB
2121                       AS2 (sbiw,r26,1));
2122             }
2123           else
2124             {
2125               *l = 3;
2126               return (AS2 (sbiw,%r1,2)   CR_TAB
2127                       AS2 (ld,%A0,%p1)  CR_TAB
2128                       AS2 (ldd,%B0,%p1+1));
2129             }
2130         }
2131
2132       *l = 2;
2133       return (AS2 (ld,%B0,%1) CR_TAB
2134               AS2 (ld,%A0,%1));
2135     }
2136   else if (GET_CODE (base) == POST_INC) /* (R++) */
2137     {
2138       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2139         fatal_insn ("incorrect insn:", insn);
2140
2141       *l = 2;
2142       return (AS2 (ld,%A0,%1)  CR_TAB
2143               AS2 (ld,%B0,%1));
2144     }
2145   else if (CONSTANT_ADDRESS_P (base))
2146     {
2147       if (optimize > 0 && io_address_operand (base, HImode))
2148         {
2149           *l = 2;
2150           return (AS2 (in,%A0,%A1-0x20) CR_TAB
2151                   AS2 (in,%B0,%B1-0x20));
2152         }
2153       *l = 4;
2154       return (AS2 (lds,%A0,%A1) CR_TAB
2155               AS2 (lds,%B0,%B1));
2156     }
2157   
2158   fatal_insn ("unknown move insn:",insn);
2159   return "";
2160 }
2161
2162 const char *
2163 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2164 {
2165   rtx dest = op[0];
2166   rtx src = op[1];
2167   rtx base = XEXP (src, 0);
2168   int reg_dest = true_regnum (dest);
2169   int reg_base = true_regnum (base);
2170   int tmp;
2171
2172   if (!l)
2173     l = &tmp;
2174   
2175   if (reg_base > 0)
2176     {
2177       if (reg_base == REG_X)        /* (R26) */
2178         {
2179           if (reg_dest == REG_X)
2180             /* "ld r26,-X" is undefined */
2181             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2182                           AS2 (ld,r29,X)          CR_TAB
2183                           AS2 (ld,r28,-X)         CR_TAB
2184                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2185                           AS2 (sbiw,r26,1)        CR_TAB
2186                           AS2 (ld,r26,X)          CR_TAB
2187                           AS2 (mov,r27,__tmp_reg__));
2188           else if (reg_dest == REG_X - 2)
2189             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2190                           AS2 (ld,%B0,X+) CR_TAB
2191                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2192                           AS2 (ld,%D0,X)  CR_TAB
2193                           AS2 (mov,%C0,__tmp_reg__));
2194           else if (reg_unused_after (insn, base))
2195             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2196                            AS2 (ld,%B0,X+) CR_TAB
2197                            AS2 (ld,%C0,X+) CR_TAB
2198                            AS2 (ld,%D0,X));
2199           else
2200             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2201                            AS2 (ld,%B0,X+) CR_TAB
2202                            AS2 (ld,%C0,X+) CR_TAB
2203                            AS2 (ld,%D0,X)  CR_TAB
2204                            AS2 (sbiw,r26,3));
2205         }
2206       else
2207         {
2208           if (reg_dest == reg_base)
2209             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2210                           AS2 (ldd,%C0,%1+2) CR_TAB
2211                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2212                           AS2 (ld,%A0,%1)  CR_TAB
2213                           AS2 (mov,%B0,__tmp_reg__));
2214           else if (reg_base == reg_dest + 2)
2215             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2216                           AS2 (ldd,%B0,%1+1) CR_TAB
2217                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2218                           AS2 (ldd,%D0,%1+3) CR_TAB
2219                           AS2 (mov,%C0,__tmp_reg__));
2220           else
2221             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2222                           AS2 (ldd,%B0,%1+1) CR_TAB
2223                           AS2 (ldd,%C0,%1+2) CR_TAB
2224                           AS2 (ldd,%D0,%1+3));
2225         }
2226     }
2227   else if (GET_CODE (base) == PLUS) /* (R + i) */
2228     {
2229       int disp = INTVAL (XEXP (base, 1));
2230       
2231       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2232         {
2233           if (REGNO (XEXP (base, 0)) != REG_Y)
2234             fatal_insn ("incorrect insn:",insn);
2235
2236           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2237             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2238                             AS2 (ldd,%A0,Y+60)    CR_TAB
2239                             AS2 (ldd,%B0,Y+61)    CR_TAB
2240                             AS2 (ldd,%C0,Y+62)    CR_TAB
2241                             AS2 (ldd,%D0,Y+63)    CR_TAB
2242                             AS2 (sbiw,r28,%o1-60));
2243
2244           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2245                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2246                           AS2 (ld,%A0,Y)           CR_TAB
2247                           AS2 (ldd,%B0,Y+1)        CR_TAB
2248                           AS2 (ldd,%C0,Y+2)        CR_TAB
2249                           AS2 (ldd,%D0,Y+3)        CR_TAB
2250                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2251                           AS2 (sbci,r29,hi8(%o1)));
2252         }
2253
2254       reg_base = true_regnum (XEXP (base, 0));
2255       if (reg_base == REG_X)
2256         {
2257           /* R = (X + d) */
2258           if (reg_dest == REG_X)
2259             {
2260               *l = 7;
2261               /* "ld r26,-X" is undefined */
2262               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2263                       AS2 (ld,r29,X)          CR_TAB
2264                       AS2 (ld,r28,-X)         CR_TAB
2265                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2266                       AS2 (sbiw,r26,1)        CR_TAB
2267                       AS2 (ld,r26,X)          CR_TAB
2268                       AS2 (mov,r27,__tmp_reg__));
2269             }
2270           *l = 6;
2271           if (reg_dest == REG_X - 2)
2272             return (AS2 (adiw,r26,%o1)      CR_TAB
2273                     AS2 (ld,r24,X+)         CR_TAB
2274                     AS2 (ld,r25,X+)         CR_TAB
2275                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2276                     AS2 (ld,r27,X)          CR_TAB
2277                     AS2 (mov,r26,__tmp_reg__));
2278
2279           return (AS2 (adiw,r26,%o1) CR_TAB
2280                   AS2 (ld,%A0,X+)    CR_TAB
2281                   AS2 (ld,%B0,X+)    CR_TAB
2282                   AS2 (ld,%C0,X+)    CR_TAB
2283                   AS2 (ld,%D0,X)     CR_TAB
2284                   AS2 (sbiw,r26,%o1+3));
2285         }
2286       if (reg_dest == reg_base)
2287         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2288                       AS2 (ldd,%C0,%C1) CR_TAB
2289                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2290                       AS2 (ldd,%A0,%A1) CR_TAB
2291                       AS2 (mov,%B0,__tmp_reg__));
2292       else if (reg_dest == reg_base - 2)
2293         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2294                       AS2 (ldd,%B0,%B1) CR_TAB
2295                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2296                       AS2 (ldd,%D0,%D1) CR_TAB
2297                       AS2 (mov,%C0,__tmp_reg__));
2298       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2299                     AS2 (ldd,%B0,%B1) CR_TAB
2300                     AS2 (ldd,%C0,%C1) CR_TAB
2301                     AS2 (ldd,%D0,%D1));
2302     }
2303   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2304     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2305                   AS2 (ld,%C0,%1) CR_TAB
2306                   AS2 (ld,%B0,%1) CR_TAB
2307                   AS2 (ld,%A0,%1));
2308   else if (GET_CODE (base) == POST_INC) /* (R++) */
2309     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2310                   AS2 (ld,%B0,%1) CR_TAB
2311                   AS2 (ld,%C0,%1) CR_TAB
2312                   AS2 (ld,%D0,%1));
2313   else if (CONSTANT_ADDRESS_P (base))
2314       return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2315                     AS2 (lds,%B0,%B1) CR_TAB
2316                     AS2 (lds,%C0,%C1) CR_TAB
2317                     AS2 (lds,%D0,%D1));
2318     
2319   fatal_insn ("unknown move insn:",insn);
2320   return "";
2321 }
2322
2323 const char *
2324 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2325 {
2326   rtx dest = op[0];
2327   rtx src = op[1];
2328   rtx base = XEXP (dest, 0);
2329   int reg_base = true_regnum (base);
2330   int reg_src = true_regnum (src);
2331   int tmp;
2332   
2333   if (!l)
2334     l = &tmp;
2335   
2336   if (CONSTANT_ADDRESS_P (base))
2337     return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2338                  AS2 (sts,%B0,%B1) CR_TAB
2339                  AS2 (sts,%C0,%C1) CR_TAB
2340                  AS2 (sts,%D0,%D1));
2341   if (reg_base > 0)                 /* (r) */
2342     {
2343       if (reg_base == REG_X)                /* (R26) */
2344         {
2345           if (reg_src == REG_X)
2346             {
2347               /* "st X+,r26" is undefined */
2348               if (reg_unused_after (insn, base))
2349                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2350                               AS2 (st,X,r26)            CR_TAB
2351                               AS2 (adiw,r26,1)          CR_TAB
2352                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2353                               AS2 (st,X+,r28)           CR_TAB
2354                               AS2 (st,X,r29));
2355               else
2356                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2357                               AS2 (st,X,r26)            CR_TAB
2358                               AS2 (adiw,r26,1)          CR_TAB
2359                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2360                               AS2 (st,X+,r28)           CR_TAB
2361                               AS2 (st,X,r29)            CR_TAB
2362                               AS2 (sbiw,r26,3));
2363             }
2364           else if (reg_base == reg_src + 2)
2365             {
2366               if (reg_unused_after (insn, base))
2367                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2368                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2369                               AS2 (st,%0+,%A1) CR_TAB
2370                               AS2 (st,%0+,%B1) CR_TAB
2371                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2372                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2373                               AS1 (clr,__zero_reg__));
2374               else
2375                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2376                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2377                               AS2 (st,%0+,%A1) CR_TAB
2378                               AS2 (st,%0+,%B1) CR_TAB
2379                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2380                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2381                               AS1 (clr,__zero_reg__)     CR_TAB
2382                               AS2 (sbiw,r26,3));
2383             }
2384           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2385                         AS2 (st,%0+,%B1) CR_TAB
2386                         AS2 (st,%0+,%C1) CR_TAB
2387                         AS2 (st,%0,%D1)  CR_TAB
2388                         AS2 (sbiw,r26,3));
2389         }
2390       else
2391         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2392                       AS2 (std,%0+1,%B1) CR_TAB
2393                       AS2 (std,%0+2,%C1) CR_TAB
2394                       AS2 (std,%0+3,%D1));
2395     }
2396   else if (GET_CODE (base) == PLUS) /* (R + i) */
2397     {
2398       int disp = INTVAL (XEXP (base, 1));
2399       reg_base = REGNO (XEXP (base, 0));
2400       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2401         {
2402           if (reg_base != REG_Y)
2403             fatal_insn ("incorrect insn:",insn);
2404
2405           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2406             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2407                             AS2 (std,Y+60,%A1)    CR_TAB
2408                             AS2 (std,Y+61,%B1)    CR_TAB
2409                             AS2 (std,Y+62,%C1)    CR_TAB
2410                             AS2 (std,Y+63,%D1)    CR_TAB
2411                             AS2 (sbiw,r28,%o0-60));
2412
2413           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2414                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2415                           AS2 (st,Y,%A1)           CR_TAB
2416                           AS2 (std,Y+1,%B1)        CR_TAB
2417                           AS2 (std,Y+2,%C1)        CR_TAB
2418                           AS2 (std,Y+3,%D1)        CR_TAB
2419                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2420                           AS2 (sbci,r29,hi8(%o0)));
2421         }
2422       if (reg_base == REG_X)
2423         {
2424           /* (X + d) = R */
2425           if (reg_src == REG_X)
2426             {
2427               *l = 9;
2428               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2429                       AS2 (mov,__zero_reg__,r27) CR_TAB
2430                       AS2 (adiw,r26,%o0)         CR_TAB
2431                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2432                       AS2 (st,X+,__zero_reg__)   CR_TAB
2433                       AS2 (st,X+,r28)            CR_TAB
2434                       AS2 (st,X,r29)             CR_TAB
2435                       AS1 (clr,__zero_reg__)     CR_TAB
2436                       AS2 (sbiw,r26,%o0+3));
2437             }
2438           else if (reg_src == REG_X - 2)
2439             {
2440               *l = 9;
2441               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2442                       AS2 (mov,__zero_reg__,r27) CR_TAB
2443                       AS2 (adiw,r26,%o0)         CR_TAB
2444                       AS2 (st,X+,r24)            CR_TAB
2445                       AS2 (st,X+,r25)            CR_TAB
2446                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2447                       AS2 (st,X,__zero_reg__)    CR_TAB
2448                       AS1 (clr,__zero_reg__)     CR_TAB
2449                       AS2 (sbiw,r26,%o0+3));
2450             }
2451           *l = 6;
2452           return (AS2 (adiw,r26,%o0) CR_TAB
2453                   AS2 (st,X+,%A1)    CR_TAB
2454                   AS2 (st,X+,%B1)    CR_TAB
2455                   AS2 (st,X+,%C1)    CR_TAB
2456                   AS2 (st,X,%D1)     CR_TAB
2457                   AS2 (sbiw,r26,%o0+3));
2458         }
2459       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2460                     AS2 (std,%B0,%B1) CR_TAB
2461                     AS2 (std,%C0,%C1) CR_TAB
2462                     AS2 (std,%D0,%D1));
2463     }
2464   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2465     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2466                   AS2 (st,%0,%C1) CR_TAB
2467                   AS2 (st,%0,%B1) CR_TAB
2468                   AS2 (st,%0,%A1));
2469   else if (GET_CODE (base) == POST_INC) /* (R++) */
2470     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2471                   AS2 (st,%0,%B1) CR_TAB
2472                   AS2 (st,%0,%C1) CR_TAB
2473                   AS2 (st,%0,%D1));
2474   fatal_insn ("unknown move insn:",insn);
2475   return "";
2476 }
2477
2478 const char *
2479 output_movsisf(rtx insn, rtx operands[], int *l)
2480 {
2481   int dummy;
2482   rtx dest = operands[0];
2483   rtx src = operands[1];
2484   int *real_l = l;
2485   
2486   if (!l)
2487     l = &dummy;
2488   
2489   if (register_operand (dest, VOIDmode))
2490     {
2491       if (register_operand (src, VOIDmode)) /* mov r,r */
2492         {
2493           if (true_regnum (dest) > true_regnum (src))
2494             {
2495               if (AVR_HAVE_MOVW)
2496                 {
2497                   *l = 2;
2498                   return (AS2 (movw,%C0,%C1) CR_TAB
2499                           AS2 (movw,%A0,%A1));
2500                 }
2501               *l = 4;
2502               return (AS2 (mov,%D0,%D1) CR_TAB
2503                       AS2 (mov,%C0,%C1) CR_TAB
2504                       AS2 (mov,%B0,%B1) CR_TAB
2505                       AS2 (mov,%A0,%A1));
2506             }
2507           else
2508             {
2509               if (AVR_HAVE_MOVW)
2510                 {
2511                   *l = 2;
2512                   return (AS2 (movw,%A0,%A1) CR_TAB
2513                           AS2 (movw,%C0,%C1));
2514                 }
2515               *l = 4;
2516               return (AS2 (mov,%A0,%A1) CR_TAB
2517                       AS2 (mov,%B0,%B1) CR_TAB
2518                       AS2 (mov,%C0,%C1) CR_TAB
2519                       AS2 (mov,%D0,%D1));
2520             }
2521         }
2522       else if (CONSTANT_P (src))
2523         {
2524           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2525             {
2526               *l = 4;
2527               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2528                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2529                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2530                       AS2 (ldi,%D0,hhi8(%1)));
2531             }
2532           
2533           if (GET_CODE (src) == CONST_INT)
2534             {
2535               const char *const clr_op0 =
2536                 AVR_HAVE_MOVW ? (AS1 (clr,%A0) CR_TAB
2537                                 AS1 (clr,%B0) CR_TAB
2538                                 AS2 (movw,%C0,%A0))
2539                              : (AS1 (clr,%A0) CR_TAB
2540                                 AS1 (clr,%B0) CR_TAB
2541                                 AS1 (clr,%C0) CR_TAB
2542                                 AS1 (clr,%D0));
2543
2544               if (src == const0_rtx) /* mov r,L */
2545                 {
2546                   *l = AVR_HAVE_MOVW ? 3 : 4;
2547                   return clr_op0;
2548                 }
2549               else if (src == const1_rtx)
2550                 {
2551                   if (!real_l)
2552                     output_asm_insn (clr_op0, operands);
2553                   *l = AVR_HAVE_MOVW ? 4 : 5;
2554                   return AS1 (inc,%A0);
2555                 }
2556               else if (src == constm1_rtx)
2557                 {
2558                   /* Immediate constants -1 to any register */
2559                   if (AVR_HAVE_MOVW)
2560                     {
2561                       *l = 4;
2562                       return (AS1 (clr,%A0)     CR_TAB
2563                               AS1 (dec,%A0)     CR_TAB
2564                               AS2 (mov,%B0,%A0) CR_TAB
2565                               AS2 (movw,%C0,%A0));
2566                     }
2567                   *l = 5;
2568                   return (AS1 (clr,%A0)     CR_TAB
2569                           AS1 (dec,%A0)     CR_TAB
2570                           AS2 (mov,%B0,%A0) CR_TAB
2571                           AS2 (mov,%C0,%A0) CR_TAB
2572                           AS2 (mov,%D0,%A0));
2573                 }
2574               else
2575                 {
2576                   int bit_nr = exact_log2 (INTVAL (src));
2577
2578                   if (bit_nr >= 0)
2579                     {
2580                       *l = AVR_HAVE_MOVW ? 5 : 6;
2581                       if (!real_l)
2582                         {
2583                           output_asm_insn (clr_op0, operands);
2584                           output_asm_insn ("set", operands);
2585                         }
2586                       if (!real_l)
2587                         avr_output_bld (operands, bit_nr);
2588
2589                       return "";
2590                     }
2591                 }
2592             }
2593           
2594           /* Last resort, better than loading from memory.  */
2595           *l = 10;
2596           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2597                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2598                   AS2 (mov,%A0,r31)         CR_TAB
2599                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2600                   AS2 (mov,%B0,r31)         CR_TAB
2601                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2602                   AS2 (mov,%C0,r31)         CR_TAB
2603                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2604                   AS2 (mov,%D0,r31)         CR_TAB
2605                   AS2 (mov,r31,__tmp_reg__));
2606         }
2607       else if (GET_CODE (src) == MEM)
2608         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2609     }
2610   else if (GET_CODE (dest) == MEM)
2611     {
2612       const char *templ;
2613
2614       if (src == const0_rtx)
2615           operands[1] = zero_reg_rtx;
2616
2617       templ = out_movsi_mr_r (insn, operands, real_l);
2618
2619       if (!real_l)
2620         output_asm_insn (templ, operands);
2621
2622       operands[1] = src;
2623       return "";
2624     }
2625   fatal_insn ("invalid insn:", insn);
2626   return "";
2627 }
2628
2629 const char *
2630 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2631 {
2632   rtx dest = op[0];
2633   rtx src = op[1];
2634   rtx x = XEXP (dest, 0);
2635   int dummy;
2636
2637   if (!l)
2638     l = &dummy;
2639   
2640   if (CONSTANT_ADDRESS_P (x))
2641     {
2642       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2643         {
2644           *l = 1;
2645           return AS2 (out,__SREG__,%1);
2646         }
2647       if (optimize > 0 && io_address_operand (x, QImode))
2648         {
2649           *l = 1;
2650           return AS2 (out,%0-0x20,%1);
2651         }
2652       *l = 2;
2653       return AS2 (sts,%0,%1);
2654     }
2655   /* memory access by reg+disp */
2656   else if (GET_CODE (x) == PLUS 
2657       && REG_P (XEXP (x,0))
2658       && GET_CODE (XEXP (x,1)) == CONST_INT)
2659     {
2660       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2661         {
2662           int disp = INTVAL (XEXP (x,1));
2663           if (REGNO (XEXP (x,0)) != REG_Y)
2664             fatal_insn ("incorrect insn:",insn);
2665
2666           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2667             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2668                             AS2 (std,Y+63,%1)     CR_TAB
2669                             AS2 (sbiw,r28,%o0-63));
2670
2671           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2672                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2673                           AS2 (st,Y,%1)            CR_TAB
2674                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2675                           AS2 (sbci,r29,hi8(%o0)));
2676         }
2677       else if (REGNO (XEXP (x,0)) == REG_X)
2678         {
2679           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2680             {
2681               if (reg_unused_after (insn, XEXP (x,0)))
2682                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2683                                 AS2 (adiw,r26,%o0)       CR_TAB
2684                                 AS2 (st,X,__tmp_reg__));
2685
2686               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2687                               AS2 (adiw,r26,%o0)       CR_TAB
2688                               AS2 (st,X,__tmp_reg__)   CR_TAB
2689                               AS2 (sbiw,r26,%o0));
2690             }
2691           else
2692             {
2693               if (reg_unused_after (insn, XEXP (x,0)))
2694                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2695                                 AS2 (st,X,%1));
2696
2697               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2698                               AS2 (st,X,%1)      CR_TAB
2699                               AS2 (sbiw,r26,%o0));
2700             }
2701         }
2702       *l = 1;
2703       return AS2 (std,%0,%1);
2704     }
2705   *l = 1;
2706   return AS2 (st,%0,%1);
2707 }
2708
2709 const char *
2710 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2711 {
2712   rtx dest = op[0];
2713   rtx src = op[1];
2714   rtx base = XEXP (dest, 0);
2715   int reg_base = true_regnum (base);
2716   int reg_src = true_regnum (src);
2717   /* "volatile" forces writing high byte first, even if less efficient,
2718      for correct operation with 16-bit I/O registers.  */
2719   int mem_volatile_p = MEM_VOLATILE_P (dest);
2720   int tmp;
2721
2722   if (!l)
2723     l = &tmp;
2724   if (CONSTANT_ADDRESS_P (base))
2725     {
2726       if (optimize > 0 && io_address_operand (base, HImode))
2727         {
2728           *l = 2;
2729           return (AS2 (out,%B0-0x20,%B1) CR_TAB
2730                   AS2 (out,%A0-0x20,%A1));
2731         }
2732       return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2733                       AS2 (sts,%A0,%A1));
2734     }
2735   if (reg_base > 0)
2736     {
2737       if (reg_base == REG_X)
2738         {
2739           if (reg_src == REG_X)
2740             {
2741               /* "st X+,r26" and "st -X,r26" are undefined.  */
2742               if (!mem_volatile_p && reg_unused_after (insn, src))
2743                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2744                               AS2 (st,X,r26)            CR_TAB
2745                               AS2 (adiw,r26,1)          CR_TAB
2746                               AS2 (st,X,__tmp_reg__));
2747               else
2748                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2749                               AS2 (adiw,r26,1)          CR_TAB
2750                               AS2 (st,X,__tmp_reg__)    CR_TAB
2751                               AS2 (sbiw,r26,1)          CR_TAB
2752                               AS2 (st,X,r26));
2753             }
2754           else
2755             {
2756               if (!mem_volatile_p && reg_unused_after (insn, base))
2757                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2758                               AS2 (st,X,%B1));
2759               else
2760                 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2761                               AS2 (st,X,%B1)   CR_TAB
2762                               AS2 (st,-X,%A1));
2763             }
2764         }
2765       else
2766         return  *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2767                        AS2 (st,%0,%A1));
2768     }
2769   else if (GET_CODE (base) == PLUS)
2770     {
2771       int disp = INTVAL (XEXP (base, 1));
2772       reg_base = REGNO (XEXP (base, 0));
2773       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2774         {
2775           if (reg_base != REG_Y)
2776             fatal_insn ("incorrect insn:",insn);
2777
2778           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2779             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2780                             AS2 (std,Y+63,%B1)    CR_TAB
2781                             AS2 (std,Y+62,%A1)    CR_TAB
2782                             AS2 (sbiw,r28,%o0-62));
2783
2784           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2785                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2786                           AS2 (std,Y+1,%B1)        CR_TAB
2787                           AS2 (st,Y,%A1)           CR_TAB
2788                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2789                           AS2 (sbci,r29,hi8(%o0)));
2790         }
2791       if (reg_base == REG_X)
2792         {
2793           /* (X + d) = R */
2794           if (reg_src == REG_X)
2795             {
2796               *l = 7;
2797               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2798                       AS2 (mov,__zero_reg__,r27) CR_TAB
2799                       AS2 (adiw,r26,%o0+1)       CR_TAB
2800                       AS2 (st,X,__zero_reg__)    CR_TAB
2801                       AS2 (st,-X,__tmp_reg__)    CR_TAB
2802                       AS1 (clr,__zero_reg__)     CR_TAB
2803                       AS2 (sbiw,r26,%o0));
2804             }
2805           *l = 4;
2806           return (AS2 (adiw,r26,%o0+1) CR_TAB
2807                   AS2 (st,X,%B1)       CR_TAB
2808                   AS2 (st,-X,%A1)      CR_TAB
2809                   AS2 (sbiw,r26,%o0));
2810         }
2811       return *l=2, (AS2 (std,%B0,%B1)    CR_TAB
2812                     AS2 (std,%A0,%A1));
2813     }
2814   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2815     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2816                   AS2 (st,%0,%A1));
2817   else if (GET_CODE (base) == POST_INC) /* (R++) */
2818     {
2819       if (mem_volatile_p)
2820         {
2821           if (REGNO (XEXP (base, 0)) == REG_X)
2822             {
2823               *l = 4;
2824               return (AS2 (adiw,r26,1)  CR_TAB
2825                       AS2 (st,X,%B1)    CR_TAB
2826                       AS2 (st,-X,%A1)   CR_TAB
2827                       AS2 (adiw,r26,2));
2828             }
2829           else
2830             {
2831               *l = 3;
2832               return (AS2 (std,%p0+1,%B1) CR_TAB
2833                       AS2 (st,%p0,%A1)    CR_TAB
2834                       AS2 (adiw,%r0,2));
2835             }
2836         }
2837
2838       *l = 2;
2839       return (AS2 (st,%0,%A1)  CR_TAB
2840             AS2 (st,%0,%B1));
2841     }
2842   fatal_insn ("unknown move insn:",insn);
2843   return "";
2844 }
2845
2846 /* Return 1 if frame pointer for current function required.  */
2847
2848 int
2849 frame_pointer_required_p (void)
2850 {
2851   return (cfun->calls_alloca
2852           || crtl->args.info.nregs == 0
2853           || get_frame_size () > 0);
2854 }
2855
2856 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2857
2858 static RTX_CODE
2859 compare_condition (rtx insn)
2860 {
2861   rtx next = next_real_insn (insn);
2862   RTX_CODE cond = UNKNOWN;
2863   if (next && GET_CODE (next) == JUMP_INSN)
2864     {
2865       rtx pat = PATTERN (next);
2866       rtx src = SET_SRC (pat);
2867       rtx t = XEXP (src, 0);
2868       cond = GET_CODE (t);
2869     }
2870   return cond;
2871 }
2872
2873 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
2874
2875 static int
2876 compare_sign_p (rtx insn)
2877 {
2878   RTX_CODE cond = compare_condition (insn);
2879   return (cond == GE || cond == LT);
2880 }
2881
2882 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2883    that needs to be swapped (GT, GTU, LE, LEU).  */
2884
2885 int
2886 compare_diff_p (rtx insn)
2887 {
2888   RTX_CODE cond = compare_condition (insn);
2889   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2890 }
2891
2892 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
2893
2894 int
2895 compare_eq_p (rtx insn)
2896 {
2897   RTX_CODE cond = compare_condition (insn);
2898   return (cond == EQ || cond == NE);
2899 }
2900
2901
2902 /* Output test instruction for HImode.  */
2903
2904 const char *
2905 out_tsthi (rtx insn, int *l)
2906 {
2907   if (compare_sign_p (insn))
2908     {
2909       if (l) *l = 1;
2910       return AS1 (tst,%B0);
2911     }
2912   if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2913       && compare_eq_p (insn))
2914     {
2915       /* Faster than sbiw if we can clobber the operand.  */
2916       if (l) *l = 1;
2917       return AS2 (or,%A0,%B0);
2918     }
2919   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2920     {
2921       if (l) *l = 1;
2922       return AS2 (sbiw,%0,0);
2923     }
2924   if (l) *l = 2;
2925   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2926           AS2 (cpc,%B0,__zero_reg__));
2927 }
2928
2929
2930 /* Output test instruction for SImode.  */
2931
2932 const char *
2933 out_tstsi (rtx insn, int *l)
2934 {
2935   if (compare_sign_p (insn))
2936     {
2937       if (l) *l = 1;
2938       return AS1 (tst,%D0);
2939     }
2940   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2941     {
2942       if (l) *l = 3;
2943       return (AS2 (sbiw,%A0,0) CR_TAB
2944               AS2 (cpc,%C0,__zero_reg__) CR_TAB
2945               AS2 (cpc,%D0,__zero_reg__));
2946     }
2947   if (l) *l = 4;
2948   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2949           AS2 (cpc,%B0,__zero_reg__) CR_TAB
2950           AS2 (cpc,%C0,__zero_reg__) CR_TAB
2951           AS2 (cpc,%D0,__zero_reg__));
2952 }
2953
2954
2955 /* Generate asm equivalent for various shifts.
2956    Shift count is a CONST_INT, MEM or REG.
2957    This only handles cases that are not already
2958    carefully hand-optimized in ?sh??i3_out.  */
2959
2960 void
2961 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
2962                     int *len, int t_len)
2963 {
2964   rtx op[10];
2965   char str[500];
2966   int second_label = 1;
2967   int saved_in_tmp = 0;
2968   int use_zero_reg = 0;
2969
2970   op[0] = operands[0];
2971   op[1] = operands[1];
2972   op[2] = operands[2];
2973   op[3] = operands[3];
2974   str[0] = 0;
2975
2976   if (len)
2977     *len = 1;
2978
2979   if (GET_CODE (operands[2]) == CONST_INT)
2980     {
2981       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2982       int count = INTVAL (operands[2]);
2983       int max_len = 10;  /* If larger than this, always use a loop.  */
2984
2985       if (count <= 0)
2986         {
2987           if (len)
2988             *len = 0;
2989           return;
2990         }
2991
2992       if (count < 8 && !scratch)
2993         use_zero_reg = 1;
2994
2995       if (optimize_size)
2996         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2997
2998       if (t_len * count <= max_len)
2999         {
3000           /* Output shifts inline with no loop - faster.  */
3001           if (len)
3002             *len = t_len * count;
3003           else
3004             {
3005               while (count-- > 0)
3006                 output_asm_insn (templ, op);
3007             }
3008
3009           return;
3010         }
3011
3012       if (scratch)
3013         {
3014           if (!len)
3015             strcat (str, AS2 (ldi,%3,%2));
3016         }
3017       else if (use_zero_reg)
3018         {
3019           /* Hack to save one word: use __zero_reg__ as loop counter.
3020              Set one bit, then shift in a loop until it is 0 again.  */
3021
3022           op[3] = zero_reg_rtx;
3023           if (len)
3024             *len = 2;
3025           else
3026             strcat (str, ("set" CR_TAB
3027                           AS2 (bld,%3,%2-1)));
3028         }
3029       else
3030         {
3031           /* No scratch register available, use one from LD_REGS (saved in
3032              __tmp_reg__) that doesn't overlap with registers to shift.  */
3033
3034           op[3] = gen_rtx_REG (QImode,
3035                            ((true_regnum (operands[0]) - 1) & 15) + 16);
3036           op[4] = tmp_reg_rtx;
3037           saved_in_tmp = 1;
3038
3039           if (len)
3040             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
3041           else
3042             strcat (str, (AS2 (mov,%4,%3) CR_TAB
3043                           AS2 (ldi,%3,%2)));
3044         }
3045
3046       second_label = 0;
3047     }
3048   else if (GET_CODE (operands[2]) == MEM)
3049     {
3050       rtx op_mov[10];
3051       
3052       op[3] = op_mov[0] = tmp_reg_rtx;
3053       op_mov[1] = op[2];
3054
3055       if (len)
3056         out_movqi_r_mr (insn, op_mov, len);
3057       else
3058         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3059     }
3060   else if (register_operand (operands[2], QImode))
3061     {
3062       if (reg_unused_after (insn, operands[2]))
3063         op[3] = op[2];
3064       else
3065         {
3066           op[3] = tmp_reg_rtx;
3067           if (!len)
3068             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3069         }
3070     }
3071   else
3072     fatal_insn ("bad shift insn:", insn);
3073
3074   if (second_label)
3075     {
3076       if (len)
3077         ++*len;
3078       else
3079         strcat (str, AS1 (rjmp,2f));
3080     }
3081
3082   if (len)
3083     *len += t_len + 2;  /* template + dec + brXX */
3084   else
3085     {
3086       strcat (str, "\n1:\t");
3087       strcat (str, templ);
3088       strcat (str, second_label ? "\n2:\t" : "\n\t");
3089       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3090       strcat (str, CR_TAB);
3091       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3092       if (saved_in_tmp)
3093         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3094       output_asm_insn (str, op);
3095     }
3096 }
3097
3098
3099 /* 8bit shift left ((char)x << i)   */
3100
3101 const char *
3102 ashlqi3_out (rtx insn, rtx operands[], int *len)
3103 {
3104   if (GET_CODE (operands[2]) == CONST_INT)
3105     {
3106       int k;
3107
3108       if (!len)
3109         len = &k;
3110
3111       switch (INTVAL (operands[2]))
3112         {
3113         default:
3114           if (INTVAL (operands[2]) < 8)
3115             break;
3116
3117           *len = 1;
3118           return AS1 (clr,%0);
3119           
3120         case 1:
3121           *len = 1;
3122           return AS1 (lsl,%0);
3123           
3124         case 2:
3125           *len = 2;
3126           return (AS1 (lsl,%0) CR_TAB
3127                   AS1 (lsl,%0));
3128
3129         case 3:
3130           *len = 3;
3131           return (AS1 (lsl,%0) CR_TAB
3132                   AS1 (lsl,%0) CR_TAB
3133                   AS1 (lsl,%0));
3134
3135         case 4:
3136           if (test_hard_reg_class (LD_REGS, operands[0]))
3137             {
3138               *len = 2;
3139               return (AS1 (swap,%0) CR_TAB
3140                       AS2 (andi,%0,0xf0));
3141             }
3142           *len = 4;
3143           return (AS1 (lsl,%0) CR_TAB
3144                   AS1 (lsl,%0) CR_TAB
3145                   AS1 (lsl,%0) CR_TAB
3146                   AS1 (lsl,%0));
3147
3148         case 5:
3149           if (test_hard_reg_class (LD_REGS, operands[0]))
3150             {
3151               *len = 3;
3152               return (AS1 (swap,%0) CR_TAB
3153                       AS1 (lsl,%0)  CR_TAB
3154                       AS2 (andi,%0,0xe0));
3155             }
3156           *len = 5;
3157           return (AS1 (lsl,%0) CR_TAB
3158                   AS1 (lsl,%0) CR_TAB
3159                   AS1 (lsl,%0) CR_TAB
3160                   AS1 (lsl,%0) CR_TAB
3161                   AS1 (lsl,%0));
3162
3163         case 6:
3164           if (test_hard_reg_class (LD_REGS, operands[0]))
3165             {
3166               *len = 4;
3167               return (AS1 (swap,%0) CR_TAB
3168                       AS1 (lsl,%0)  CR_TAB
3169                       AS1 (lsl,%0)  CR_TAB
3170                       AS2 (andi,%0,0xc0));
3171             }
3172           *len = 6;
3173           return (AS1 (lsl,%0) CR_TAB
3174                   AS1 (lsl,%0) CR_TAB
3175                   AS1 (lsl,%0) CR_TAB
3176                   AS1 (lsl,%0) CR_TAB
3177                   AS1 (lsl,%0) CR_TAB
3178                   AS1 (lsl,%0));
3179
3180         case 7:
3181           *len = 3;
3182           return (AS1 (ror,%0) CR_TAB
3183                   AS1 (clr,%0) CR_TAB
3184                   AS1 (ror,%0));
3185         }
3186     }
3187   else if (CONSTANT_P (operands[2]))
3188     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3189
3190   out_shift_with_cnt (AS1 (lsl,%0),
3191                       insn, operands, len, 1);
3192   return "";
3193 }
3194
3195
3196 /* 16bit shift left ((short)x << i)   */
3197
3198 const char *
3199 ashlhi3_out (rtx insn, rtx operands[], int *len)
3200 {
3201   if (GET_CODE (operands[2]) == CONST_INT)
3202     {
3203       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3204       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3205       int k;
3206       int *t = len;
3207
3208       if (!len)
3209         len = &k;
3210       
3211       switch (INTVAL (operands[2]))
3212         {
3213         default:
3214           if (INTVAL (operands[2]) < 16)
3215             break;
3216
3217           *len = 2;
3218           return (AS1 (clr,%B0) CR_TAB
3219                   AS1 (clr,%A0));
3220
3221         case 4:
3222           if (optimize_size && scratch)
3223             break;  /* 5 */
3224           if (ldi_ok)
3225             {
3226               *len = 6;
3227               return (AS1 (swap,%A0)      CR_TAB
3228                       AS1 (swap,%B0)      CR_TAB
3229                       AS2 (andi,%B0,0xf0) CR_TAB
3230                       AS2 (eor,%B0,%A0)   CR_TAB
3231                       AS2 (andi,%A0,0xf0) CR_TAB
3232                       AS2 (eor,%B0,%A0));
3233             }
3234           if (scratch)
3235             {
3236               *len = 7;
3237               return (AS1 (swap,%A0)    CR_TAB
3238                       AS1 (swap,%B0)    CR_TAB
3239                       AS2 (ldi,%3,0xf0) CR_TAB
3240                       AS2 (and,%B0,%3)  CR_TAB
3241                       AS2 (eor,%B0,%A0) CR_TAB
3242                       AS2 (and,%A0,%3)  CR_TAB
3243                       AS2 (eor,%B0,%A0));
3244             }
3245           break;  /* optimize_size ? 6 : 8 */
3246
3247         case 5:
3248           if (optimize_size)
3249             break;  /* scratch ? 5 : 6 */
3250           if (ldi_ok)
3251             {
3252               *len = 8;
3253               return (AS1 (lsl,%A0)       CR_TAB
3254                       AS1 (rol,%B0)       CR_TAB
3255                       AS1 (swap,%A0)      CR_TAB
3256                       AS1 (swap,%B0)      CR_TAB
3257                       AS2 (andi,%B0,0xf0) CR_TAB
3258                       AS2 (eor,%B0,%A0)   CR_TAB
3259                       AS2 (andi,%A0,0xf0) CR_TAB
3260                       AS2 (eor,%B0,%A0));
3261             }
3262           if (scratch)
3263             {
3264               *len = 9;
3265               return (AS1 (lsl,%A0)     CR_TAB
3266                       AS1 (rol,%B0)     CR_TAB
3267                       AS1 (swap,%A0)    CR_TAB
3268                       AS1 (swap,%B0)    CR_TAB
3269                       AS2 (ldi,%3,0xf0) CR_TAB
3270                       AS2 (and,%B0,%3)  CR_TAB
3271                       AS2 (eor,%B0,%A0) CR_TAB
3272                       AS2 (and,%A0,%3)  CR_TAB
3273                       AS2 (eor,%B0,%A0));
3274             }
3275           break;  /* 10 */
3276
3277         case 6:
3278           if (optimize_size)
3279             break;  /* scratch ? 5 : 6 */
3280           *len = 9;
3281           return (AS1 (clr,__tmp_reg__) CR_TAB
3282                   AS1 (lsr,%B0)         CR_TAB
3283                   AS1 (ror,%A0)         CR_TAB
3284                   AS1 (ror,__tmp_reg__) CR_TAB
3285                   AS1 (lsr,%B0)         CR_TAB
3286                   AS1 (ror,%A0)         CR_TAB
3287                   AS1 (ror,__tmp_reg__) CR_TAB
3288                   AS2 (mov,%B0,%A0)     CR_TAB
3289                   AS2 (mov,%A0,__tmp_reg__));
3290
3291         case 7:
3292           *len = 5;
3293           return (AS1 (lsr,%B0)     CR_TAB
3294                   AS2 (mov,%B0,%A0) CR_TAB
3295                   AS1 (clr,%A0)     CR_TAB
3296                   AS1 (ror,%B0)     CR_TAB
3297                   AS1 (ror,%A0));
3298
3299         case 8:
3300           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3301                             AS1 (clr,%A0));
3302
3303         case 9:
3304           *len = 3;
3305           return (AS2 (mov,%B0,%A0) CR_TAB
3306                   AS1 (clr,%A0)     CR_TAB
3307                   AS1 (lsl,%B0));
3308
3309         case 10:
3310           *len = 4;
3311           return (AS2 (mov,%B0,%A0) CR_TAB
3312                   AS1 (clr,%A0)     CR_TAB
3313                   AS1 (lsl,%B0)     CR_TAB
3314                   AS1 (lsl,%B0));
3315
3316         case 11:
3317           *len = 5;
3318           return (AS2 (mov,%B0,%A0) CR_TAB
3319                   AS1 (clr,%A0)     CR_TAB
3320                   AS1 (lsl,%B0)     CR_TAB
3321                   AS1 (lsl,%B0)     CR_TAB
3322                   AS1 (lsl,%B0));
3323
3324         case 12:
3325           if (ldi_ok)