OSDN Git Service

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