OSDN Git Service

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