OSDN Git Service

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