OSDN Git Service

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