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