OSDN Git Service

509980559c46e5a81f6e24975a4631cb14ac225f
[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_unique_section (tree, int);
72 static void avr_insert_attributes (tree, tree *);
73 static unsigned int avr_section_type_flags (tree, const char *, int);
74
75 static void avr_reorg (void);
76 static void avr_asm_out_ctor (rtx, int);
77 static void avr_asm_out_dtor (rtx, int);
78 static int default_rtx_costs (rtx, enum rtx_code, enum rtx_code);
79 static bool avr_rtx_costs (rtx, int, int, int *);
80 static int avr_address_cost (rtx);
81 static bool avr_return_in_memory (tree, tree);
82
83 /* Allocate registers from r25 to r8 for parameters for function calls.  */
84 #define FIRST_CUM_REG 26
85
86 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
87 static GTY(()) rtx tmp_reg_rtx;
88
89 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
90 static GTY(()) rtx zero_reg_rtx;
91
92 /* AVR register names {"r0", "r1", ..., "r31"} */
93 static const char *const avr_regnames[] = REGISTER_NAMES;
94
95 /* This holds the last insn address.  */
96 static int last_insn_address = 0;
97
98 /* Commands count in the compiled file */
99 static int commands_in_file;
100
101 /* Commands in the functions prologues in the compiled file */
102 static int commands_in_prologues;
103
104 /* Commands in the functions epilogues in the compiled file */
105 static int commands_in_epilogues;
106
107 /* Prologue/Epilogue size in words */
108 static int prologue_size;
109 static int epilogue_size;
110
111 /* Size of all jump tables in the current function, in words.  */
112 static int jump_tables_size;
113
114 /* Initial stack value specified by the `-minit-stack=' option */
115 const char *avr_init_stack = "__stack";
116
117 /* Default MCU name */
118 const char *avr_mcu_name = "avr2";
119
120 /* Preprocessor macros to define depending on MCU type.  */
121 const char *avr_base_arch_macro;
122 const char *avr_extra_arch_macro;
123
124 /* More than 8K of program memory: use "call" and "jmp".  */
125 int avr_mega_p = 0;
126
127 /* Enhanced core: use "movw", "mul", ...  */
128 int avr_enhanced_p = 0;
129
130 /* Assembler only.  */
131 int avr_asm_only_p = 0;
132
133 struct base_arch_s {
134   int asm_only;
135   int enhanced;
136   int mega;
137   const char *const macro;
138 };
139
140 static const struct base_arch_s avr_arch_types[] = {
141   { 1, 0, 0, NULL },  /* unknown device specified */
142   { 1, 0, 0, "__AVR_ARCH__=1" },
143   { 0, 0, 0, "__AVR_ARCH__=2" },
144   { 0, 0, 1, "__AVR_ARCH__=3" },
145   { 0, 1, 0, "__AVR_ARCH__=4" },
146   { 0, 1, 1, "__AVR_ARCH__=5" }
147 };
148
149 struct mcu_type_s {
150   const char *const name;
151   int arch;  /* index in avr_arch_types[] */
152   /* Must lie outside user's namespace.  NULL == no macro.  */
153   const char *const macro;
154 };
155
156 /* List of all known AVR MCU types - if updated, it has to be kept
157    in sync in several places (FIXME: is there a better way?):
158     - here
159     - avr.h (CPP_SPEC, LINK_SPEC, CRT_BINUTILS_SPECS)
160     - t-avr (MULTILIB_MATCHES)
161     - gas/config/tc-avr.c
162     - avr-libc  */
163
164 static const struct mcu_type_s avr_mcu_types[] = {
165     /* Classic, <= 8K.  */
166   { "avr2",      2, NULL },
167   { "at90s2313", 2, "__AVR_AT90S2313__" },
168   { "at90s2323", 2, "__AVR_AT90S2323__" },
169   { "at90s2333", 2, "__AVR_AT90S2333__" },
170   { "at90s2343", 2, "__AVR_AT90S2343__" },
171   { "attiny22",  2, "__AVR_ATtiny22__" },
172   { "attiny26",  2, "__AVR_ATtiny26__" },
173   { "at90s4414", 2, "__AVR_AT90S4414__" },
174   { "at90s4433", 2, "__AVR_AT90S4433__" },
175   { "at90s4434", 2, "__AVR_AT90S4434__" },
176   { "at90s8515", 2, "__AVR_AT90S8515__" },
177   { "at90c8534", 2, "__AVR_AT90C8534__" },
178   { "at90s8535", 2, "__AVR_AT90S8535__" },
179   { "at86rf401", 2, "__AVR_AT86RF401__" },
180     /* Classic, > 8K.  */
181   { "avr3",      3, NULL },
182   { "atmega103", 3, "__AVR_ATmega103__" },
183   { "atmega603", 3, "__AVR_ATmega603__" },
184   { "at43usb320", 3, "__AVR_AT43USB320__" },
185   { "at43usb355", 3, "__AVR_AT43USB355__" },
186   { "at76c711",  3, "__AVR_AT76C711__" },
187     /* Enhanced, <= 8K.  */
188   { "avr4",      4, NULL },
189   { "atmega8",   4, "__AVR_ATmega8__" },
190   { "atmega8515", 4, "__AVR_ATmega8515__" },
191   { "atmega8535", 4, "__AVR_ATmega8535__" },
192     /* Enhanced, > 8K.  */
193   { "avr5",      5, NULL },
194   { "atmega16",  5, "__AVR_ATmega16__" },
195   { "atmega161", 5, "__AVR_ATmega161__" },
196   { "atmega162", 5, "__AVR_ATmega162__" },
197   { "atmega163", 5, "__AVR_ATmega163__" },
198   { "atmega169", 5, "__AVR_ATmega169__" },
199   { "atmega32",  5, "__AVR_ATmega32__" },
200   { "atmega323", 5, "__AVR_ATmega323__" },
201   { "atmega64",  5, "__AVR_ATmega64__" },
202   { "atmega128", 5, "__AVR_ATmega128__" },
203   { "at94k",     5, "__AVR_AT94K__" },
204     /* Assembler only.  */
205   { "avr1",      1, NULL },
206   { "at90s1200", 1, "__AVR_AT90S1200__" },
207   { "attiny11",  1, "__AVR_ATtiny11__" },
208   { "attiny12",  1, "__AVR_ATtiny12__" },
209   { "attiny15",  1, "__AVR_ATtiny15__" },
210   { "attiny28",  1, "__AVR_ATtiny28__" },
211   { NULL,        0, NULL }
212 };
213
214 int avr_case_values_threshold = 30000;
215 \f
216 /* Initialize the GCC target structure.  */
217 #undef TARGET_ASM_ALIGNED_HI_OP
218 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
219 #undef TARGET_ASM_INTEGER
220 #define TARGET_ASM_INTEGER avr_assemble_integer
221 #undef TARGET_ASM_FILE_START
222 #define TARGET_ASM_FILE_START avr_file_start
223 #undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
224 #define TARGET_ASM_FILE_START_FILE_DIRECTIVE true
225 #undef TARGET_ASM_FILE_END
226 #define TARGET_ASM_FILE_END avr_file_end
227
228 #undef TARGET_ASM_FUNCTION_PROLOGUE
229 #define TARGET_ASM_FUNCTION_PROLOGUE avr_output_function_prologue
230 #undef TARGET_ASM_FUNCTION_EPILOGUE
231 #define TARGET_ASM_FUNCTION_EPILOGUE avr_output_function_epilogue
232 #undef TARGET_ATTRIBUTE_TABLE
233 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
234 #undef TARGET_ASM_UNIQUE_SECTION
235 #define TARGET_ASM_UNIQUE_SECTION avr_unique_section
236 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
237 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
238 #undef TARGET_INSERT_ATTRIBUTES
239 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
240 #undef TARGET_SECTION_TYPE_FLAGS
241 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
242 #undef TARGET_RTX_COSTS
243 #define TARGET_RTX_COSTS avr_rtx_costs
244 #undef TARGET_ADDRESS_COST
245 #define TARGET_ADDRESS_COST avr_address_cost
246 #undef TARGET_MACHINE_DEPENDENT_REORG
247 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
248
249 #undef TARGET_RETURN_IN_MEMORY
250 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
251
252 #undef TARGET_STRICT_ARGUMENT_NAMING
253 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
254
255 struct gcc_target targetm = TARGET_INITIALIZER;
256 \f
257 void
258 avr_override_options (void)
259 {
260   const struct mcu_type_s *t;
261   const struct base_arch_s *base;
262
263   for (t = avr_mcu_types; t->name; t++)
264     if (strcmp (t->name, avr_mcu_name) == 0)
265       break;
266
267   if (!t->name)
268     {
269       fprintf (stderr, "unknown MCU `%s' specified\nKnown MCU names:\n",
270                avr_mcu_name);
271       for (t = avr_mcu_types; t->name; t++)
272         fprintf (stderr,"   %s\n", t->name);
273     }
274
275   base = &avr_arch_types[t->arch];
276   avr_asm_only_p = base->asm_only;
277   avr_enhanced_p = base->enhanced;
278   avr_mega_p = base->mega;
279   avr_base_arch_macro = base->macro;
280   avr_extra_arch_macro = t->macro;
281
282   if (optimize && !TARGET_NO_TABLEJUMP)
283     avr_case_values_threshold = (!AVR_MEGA || TARGET_CALL_PROLOGUES) ? 8 : 17;
284
285   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
286   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
287 }
288
289 /*  return register class from register number.  */
290
291 static const int reg_class_tab[]={
292   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
293   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
294   GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,GENERAL_REGS,
295   GENERAL_REGS, /* r0 - r15 */
296   LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,LD_REGS,
297   LD_REGS,                      /* r16 - 23 */
298   ADDW_REGS,ADDW_REGS,          /* r24,r25 */
299   POINTER_X_REGS,POINTER_X_REGS, /* r26,27 */
300   POINTER_Y_REGS,POINTER_Y_REGS, /* r28,r29 */
301   POINTER_Z_REGS,POINTER_Z_REGS, /* r30,r31 */
302   STACK_REG,STACK_REG           /* SPL,SPH */
303 };
304
305 /* Return register class for register R.  */
306
307 enum reg_class
308 avr_regno_reg_class (int r)
309 {
310   if (r <= 33)
311     return reg_class_tab[r];
312   return ALL_REGS;
313 }
314
315
316 /* A C expression which defines the machine-dependent operand
317    constraint letters for register classes.  If C is such a
318    letter, the value should be the register class corresponding to
319    it.  Otherwise, the value should be `NO_REGS'.  The register
320    letter `r', corresponding to class `GENERAL_REGS', will not be
321    passed to this macro; you do not need to handle it.  */
322
323 enum reg_class
324 avr_reg_class_from_letter  (int c)
325 {
326   switch (c)
327     {
328     case 't' : return R0_REG;
329     case 'b' : return BASE_POINTER_REGS;
330     case 'e' : return POINTER_REGS;
331     case 'w' : return ADDW_REGS;
332     case 'd' : return LD_REGS;
333     case 'l' : return NO_LD_REGS;
334     case 'a' : return SIMPLE_LD_REGS;
335     case 'x' : return POINTER_X_REGS;
336     case 'y' : return POINTER_Y_REGS;
337     case 'z' : return POINTER_Z_REGS;
338     case 'q' : return STACK_REG;
339     default: break;
340     }
341   return NO_REGS;
342 }
343
344 /* Return nonzero if FUNC is a naked function.  */
345
346 static int
347 avr_naked_function_p (tree func)
348 {
349   tree a;
350
351   if (TREE_CODE (func) != FUNCTION_DECL)
352     abort ();
353   
354   a = lookup_attribute ("naked", DECL_ATTRIBUTES (func));
355   return a != NULL_TREE;
356 }
357
358 /* Return nonzero if FUNC is an interrupt function as specified
359    by the "interrupt" attribute.  */
360
361 static int
362 interrupt_function_p (tree func)
363 {
364   tree a;
365
366   if (TREE_CODE (func) != FUNCTION_DECL)
367     return 0;
368
369   a = lookup_attribute ("interrupt", DECL_ATTRIBUTES (func));
370   return a != NULL_TREE;
371 }
372
373 /* Return nonzero if FUNC is a signal function as specified
374    by the "signal" attribute.  */
375
376 static int
377 signal_function_p (tree func)
378 {
379   tree a;
380
381   if (TREE_CODE (func) != FUNCTION_DECL)
382     return 0;
383
384   a = lookup_attribute ("signal", DECL_ATTRIBUTES (func));
385   return a != NULL_TREE;
386 }
387
388 /* Return the number of hard registers to push/pop in the prologue/epilogue
389    of the current function, and optionally store these registers in SET.  */
390
391 static int
392 avr_regs_to_save (HARD_REG_SET *set)
393 {
394   int reg, count;
395   int int_or_sig_p = (interrupt_function_p (current_function_decl)
396                       || signal_function_p (current_function_decl));
397   int leaf_func_p = leaf_function_p ();
398
399   if (set)
400     CLEAR_HARD_REG_SET (*set);
401   count = 0;
402
403   /* No need to save any registers if the function never returns.  */
404   if (TREE_THIS_VOLATILE (current_function_decl))
405     return 0;
406
407   for (reg = 0; reg < 32; reg++)
408     {
409       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
410          any global register variables.  */
411       if (fixed_regs[reg])
412         continue;
413
414       if ((int_or_sig_p && !leaf_func_p && call_used_regs[reg])
415           || (regs_ever_live[reg]
416               && (int_or_sig_p || !call_used_regs[reg])
417               && !(frame_pointer_needed
418                    && (reg == REG_Y || reg == (REG_Y+1)))))
419         {
420           if (set)
421             SET_HARD_REG_BIT (*set, reg);
422           count++;
423         }
424     }
425   return count;
426 }
427
428 /* Compute offset between arg_pointer and frame_pointer.  */
429
430 int
431 initial_elimination_offset (int from, int to)
432 {
433   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
434     return 0;
435   else
436     {
437       int offset = frame_pointer_needed ? 2 : 0;
438
439       offset += avr_regs_to_save (NULL);
440       return get_frame_size () + 2 + 1 + offset;
441     }
442 }
443
444 /* Return 1 if the function epilogue is just a single "ret".  */
445
446 int
447 avr_simple_epilogue (void)
448 {
449   return (! frame_pointer_needed
450           && get_frame_size () == 0
451           && avr_regs_to_save (NULL) == 0
452           && ! interrupt_function_p (current_function_decl)
453           && ! signal_function_p (current_function_decl)
454           && ! avr_naked_function_p (current_function_decl)
455           && ! MAIN_NAME_P (DECL_NAME (current_function_decl))
456           && ! TREE_THIS_VOLATILE (current_function_decl));
457 }
458
459 /* This function checks sequence of live registers.  */
460
461 static int
462 sequent_regs_live (void)
463 {
464   int reg;
465   int live_seq=0;
466   int cur_seq=0;
467
468   for (reg = 0; reg < 18; ++reg)
469     {
470       if (!call_used_regs[reg])
471         {
472           if (regs_ever_live[reg])
473             {
474               ++live_seq;
475               ++cur_seq;
476             }
477           else
478             cur_seq = 0;
479         }
480     }
481
482   if (!frame_pointer_needed)
483     {
484       if (regs_ever_live[REG_Y])
485         {
486           ++live_seq;
487           ++cur_seq;
488         }
489       else
490         cur_seq = 0;
491
492       if (regs_ever_live[REG_Y+1])
493         {
494           ++live_seq;
495           ++cur_seq;
496         }
497       else
498         cur_seq = 0;
499     }
500   else
501     {
502       cur_seq += 2;
503       live_seq += 2;
504     }
505   return (cur_seq == live_seq) ? live_seq : 0;
506 }
507
508
509 /* Output to FILE the asm instructions to adjust the frame pointer by
510    ADJ (r29:r28 -= ADJ;) which can be positive (prologue) or negative
511    (epilogue).  Returns the number of instructions generated.  */
512
513 static int
514 out_adj_frame_ptr (FILE *file, int adj)
515 {
516   int size = 0;
517
518   if (adj)
519     {
520       if (TARGET_TINY_STACK)
521         {
522           if (adj < -63 || adj > 63)
523             warning ("large frame pointer change (%d) with -mtiny-stack", adj);
524
525           /* The high byte (r29) doesn't change - prefer "subi" (1 cycle)
526              over "sbiw" (2 cycles, same size).  */
527
528           fprintf (file, (AS2 (subi, r28, %d) CR_TAB), adj);
529           size++;
530         }
531       else if (adj < -63 || adj > 63)
532         {
533           fprintf (file, (AS2 (subi, r28, lo8(%d)) CR_TAB
534                           AS2 (sbci, r29, hi8(%d)) CR_TAB),
535                    adj, adj);
536           size += 2;
537         }
538       else if (adj < 0)
539         {
540           fprintf (file, (AS2 (adiw, r28, %d) CR_TAB), -adj);
541           size++;
542         }
543       else
544         {
545           fprintf (file, (AS2 (sbiw, r28, %d) CR_TAB), adj);
546           size++;
547         }
548     }
549   return size;
550 }
551
552
553 /* Output to FILE the asm instructions to copy r29:r28 to SPH:SPL,
554    handling various cases of interrupt enable flag state BEFORE and AFTER
555    (0=disabled, 1=enabled, -1=unknown/unchanged) and target_flags.
556    Returns the number of instructions generated.  */
557
558 static int
559 out_set_stack_ptr (FILE *file, int before, int after)
560 {
561   int do_sph, do_cli, do_save, do_sei, lock_sph, size;
562
563   /* The logic here is so that -mno-interrupts actually means
564      "it is safe to write SPH in one instruction, then SPL in the
565      next instruction, without disabling interrupts first".
566      The after != -1 case (interrupt/signal) is not affected.  */
567
568   do_sph = !TARGET_TINY_STACK;
569   lock_sph = do_sph && !TARGET_NO_INTERRUPTS;
570   do_cli = (before != 0 && (after == 0 || lock_sph));
571   do_save = (do_cli && before == -1 && after == -1);
572   do_sei = ((do_cli || before != 1) && after == 1);
573   size = 1;
574
575   if (do_save)
576     {
577       fprintf (file, AS2 (in, __tmp_reg__, __SREG__) CR_TAB);
578       size++;
579     }
580
581   if (do_cli)
582     {
583       fprintf (file, "cli" CR_TAB);
584       size++;
585     }
586
587   /* Do SPH first - maybe this will disable interrupts for one instruction
588      someday (a suggestion has been sent to avr@atmel.com for consideration
589      in future devices - that would make -mno-interrupts always safe).  */
590   if (do_sph)
591     {
592       fprintf (file, AS2 (out, __SP_H__, r29) CR_TAB);
593       size++;
594     }
595
596   /* Set/restore the I flag now - interrupts will be really enabled only
597      after the next instruction.  This is not clearly documented, but
598      believed to be true for all AVR devices.  */
599   if (do_save)
600     {
601       fprintf (file, AS2 (out, __SREG__, __tmp_reg__) CR_TAB);
602       size++;
603     }
604   else if (do_sei)
605     {
606       fprintf (file, "sei" CR_TAB);
607       size++;
608     }
609
610   fprintf (file, AS2 (out, __SP_L__, r28) "\n");
611
612   return size;
613 }
614
615
616 /* Output function prologue.  */
617
618 static void
619 avr_output_function_prologue (FILE *file, HOST_WIDE_INT size)
620 {
621   int reg;
622   int interrupt_func_p;
623   int signal_func_p;
624   int main_p;
625   int live_seq;
626   int minimize;
627
628   last_insn_address = 0;
629   jump_tables_size = 0;
630   prologue_size = 0;
631   fprintf (file, "/* prologue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n",
632            size);
633
634   if (avr_naked_function_p (current_function_decl))
635     {
636       fputs ("/* prologue: naked */\n", file);
637       goto out;
638     }
639
640   interrupt_func_p = interrupt_function_p (current_function_decl);
641   signal_func_p = signal_function_p (current_function_decl);
642   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
643   live_seq = sequent_regs_live ();
644   minimize = (TARGET_CALL_PROLOGUES
645               && !interrupt_func_p && !signal_func_p && live_seq);
646
647   if (interrupt_func_p)
648     {
649       fprintf (file,"\tsei\n");
650       ++prologue_size;
651     }
652   if (interrupt_func_p || signal_func_p)
653     {
654       fprintf (file, "\t"
655                AS1 (push,__zero_reg__)   CR_TAB
656                AS1 (push,__tmp_reg__)    CR_TAB
657                AS2 (in,__tmp_reg__,__SREG__) CR_TAB
658                AS1 (push,__tmp_reg__)    CR_TAB
659                AS1 (clr,__zero_reg__)    "\n");
660       prologue_size += 5;
661     }
662   if (main_p)
663     {
664       fprintf (file, ("\t" 
665                       AS1 (ldi,r28) ",lo8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
666                       AS1 (ldi,r29) ",hi8(%s - " HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
667                       AS2 (out,__SP_H__,r29)     CR_TAB
668                       AS2 (out,__SP_L__,r28) "\n"),
669                avr_init_stack, size, avr_init_stack, size);
670       
671       prologue_size += 4;
672     }
673   else if (minimize && (frame_pointer_needed || live_seq > 6)) 
674     {
675       const char *cfun_name = current_function_name ();
676       fprintf (file, ("\t"
677                       AS1 (ldi, r26) ",lo8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB
678                       AS1 (ldi, r27) ",hi8(" HOST_WIDE_INT_PRINT_DEC ")" CR_TAB), size, size);
679
680       fprintf (file, (AS2 (ldi, r30, pm_lo8(.L_%s_body)) CR_TAB
681                       AS2 (ldi, r31, pm_hi8(.L_%s_body)) CR_TAB),
682                cfun_name, cfun_name);
683       
684       prologue_size += 4;
685       
686       if (AVR_MEGA)
687         {
688           fprintf (file, AS1 (jmp,__prologue_saves__+%d) "\n",
689                    (18 - live_seq) * 2);
690           prologue_size += 2;
691         }
692       else
693         {
694           fprintf (file, AS1 (rjmp,__prologue_saves__+%d) "\n",
695                    (18 - live_seq) * 2);
696           ++prologue_size;
697         }
698       fprintf (file, ".L_%s_body:\n", cfun_name);
699     }
700   else
701     {
702       HARD_REG_SET set;
703
704       prologue_size += avr_regs_to_save (&set);
705       for (reg = 0; reg < 32; ++reg)
706         {
707           if (TEST_HARD_REG_BIT (set, reg))
708             {
709               fprintf (file, "\t" AS1 (push,%s) "\n", avr_regnames[reg]);
710             }
711         }
712       if (frame_pointer_needed)
713         {
714           fprintf (file, "\t"
715                    AS1 (push,r28) CR_TAB
716                    AS1 (push,r29) CR_TAB
717                    AS2 (in,r28,__SP_L__) CR_TAB
718                    AS2 (in,r29,__SP_H__) "\n");
719           prologue_size += 4;
720           if (size)
721             {
722               fputs ("\t", file);
723               prologue_size += out_adj_frame_ptr (file, size);
724
725               if (interrupt_func_p)
726                 {
727                   prologue_size += out_set_stack_ptr (file, 1, 1);
728                 }
729               else if (signal_func_p)
730                 {
731                   prologue_size += out_set_stack_ptr (file, 0, 0);
732                 }
733               else
734                 {
735                   prologue_size += out_set_stack_ptr (file, -1, -1);
736                 }
737             }
738         }
739     }
740
741  out:
742   fprintf (file, "/* prologue end (size=%d) */\n", prologue_size);
743 }
744
745 /* Output function epilogue.  */
746
747 static void
748 avr_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
749 {
750   int reg;
751   int interrupt_func_p;
752   int signal_func_p;
753   int main_p;
754   int function_size;
755   int live_seq;
756   int minimize;
757   rtx last = get_last_nonnote_insn ();
758
759   function_size = jump_tables_size;
760   if (last)
761     {
762       rtx first = get_first_nonnote_insn ();
763       function_size += (INSN_ADDRESSES (INSN_UID (last)) -
764                         INSN_ADDRESSES (INSN_UID (first)));
765       function_size += get_attr_length (last);
766     }
767
768   fprintf (file, "/* epilogue: frame size=" HOST_WIDE_INT_PRINT_DEC " */\n", size);
769   epilogue_size = 0;
770
771   if (avr_naked_function_p (current_function_decl))
772     {
773       fputs ("/* epilogue: naked */\n", file);
774       goto out;
775     }
776
777   if (last && GET_CODE (last) == BARRIER)
778     {
779       fputs ("/* epilogue: noreturn */\n", file);
780       goto out;
781     }
782
783   interrupt_func_p = interrupt_function_p (current_function_decl);
784   signal_func_p = signal_function_p (current_function_decl);
785   main_p = MAIN_NAME_P (DECL_NAME (current_function_decl));
786   live_seq = sequent_regs_live ();
787   minimize = (TARGET_CALL_PROLOGUES
788               && !interrupt_func_p && !signal_func_p && live_seq);
789   
790   if (main_p)
791     {
792       /* Return value from main() is already in the correct registers
793          (r25:r24) as the exit() argument.  */
794       if (AVR_MEGA)
795         {
796           fputs ("\t" AS1 (jmp,exit) "\n", file);
797           epilogue_size += 2;
798         }
799       else
800         {
801           fputs ("\t" AS1 (rjmp,exit) "\n", file);
802           ++epilogue_size;
803         }
804     }
805   else if (minimize && (frame_pointer_needed || live_seq > 4))
806     {
807       fprintf (file, ("\t" AS2 (ldi, r30, %d) CR_TAB), live_seq);
808       ++epilogue_size;
809       if (frame_pointer_needed)
810         {
811           epilogue_size += out_adj_frame_ptr (file, -size);
812         }
813       else
814         {
815           fprintf (file, (AS2 (in , r28, __SP_L__) CR_TAB
816                           AS2 (in , r29, __SP_H__) CR_TAB));
817           epilogue_size += 2;
818         }
819       
820       if (AVR_MEGA)
821         {
822           fprintf (file, AS1 (jmp,__epilogue_restores__+%d) "\n",
823                    (18 - live_seq) * 2);
824           epilogue_size += 2;
825         }
826       else
827         {
828           fprintf (file, AS1 (rjmp,__epilogue_restores__+%d) "\n",
829                    (18 - live_seq) * 2);
830           ++epilogue_size;
831         }
832     }
833   else
834     {
835       HARD_REG_SET set;
836
837       if (frame_pointer_needed)
838         {
839           if (size)
840             {
841               fputs ("\t", file);
842               epilogue_size += out_adj_frame_ptr (file, -size);
843
844               if (interrupt_func_p || signal_func_p)
845                 {
846                   epilogue_size += out_set_stack_ptr (file, -1, 0);
847                 }
848               else
849                 {
850                   epilogue_size += out_set_stack_ptr (file, -1, -1);
851                 }
852             }
853           fprintf (file, "\t"
854                    AS1 (pop,r29) CR_TAB
855                    AS1 (pop,r28) "\n");
856           epilogue_size += 2;
857         }
858
859       epilogue_size += avr_regs_to_save (&set);
860       for (reg = 31; reg >= 0; --reg)
861         {
862           if (TEST_HARD_REG_BIT (set, reg))
863             {
864               fprintf (file, "\t" AS1 (pop,%s) "\n", avr_regnames[reg]);
865             }
866         }
867
868       if (interrupt_func_p || signal_func_p)
869         {
870           fprintf (file, "\t"
871                    AS1 (pop,__tmp_reg__)      CR_TAB
872                    AS2 (out,__SREG__,__tmp_reg__) CR_TAB
873                    AS1 (pop,__tmp_reg__)      CR_TAB
874                    AS1 (pop,__zero_reg__)     "\n");
875           epilogue_size += 4;
876           fprintf (file, "\treti\n");
877         }
878       else
879         fprintf (file, "\tret\n");
880       ++epilogue_size;
881     }
882
883  out:
884   fprintf (file, "/* epilogue end (size=%d) */\n", epilogue_size);
885   fprintf (file, "/* function %s size %d (%d) */\n", current_function_name (),
886            prologue_size + function_size + epilogue_size, function_size);
887   commands_in_file += prologue_size + function_size + epilogue_size;
888   commands_in_prologues += prologue_size;
889   commands_in_epilogues += epilogue_size;
890 }
891
892
893 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
894    machine for a memory operand of mode MODE.  */
895
896 int
897 legitimate_address_p (enum machine_mode mode, rtx x, int strict)
898 {
899   enum reg_class r = NO_REGS;
900   
901   if (TARGET_ALL_DEBUG)
902     {
903       fprintf (stderr, "mode: (%s) %s %s %s %s:",
904                GET_MODE_NAME(mode),
905                strict ? "(strict)": "",
906                reload_completed ? "(reload_completed)": "",
907                reload_in_progress ? "(reload_in_progress)": "",
908                reg_renumber ? "(reg_renumber)" : "");
909       if (GET_CODE (x) == PLUS
910           && REG_P (XEXP (x, 0))
911           && GET_CODE (XEXP (x, 1)) == CONST_INT
912           && INTVAL (XEXP (x, 1)) >= 0
913           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
914           && reg_renumber
915           )
916         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
917                  true_regnum (XEXP (x, 0)));
918       debug_rtx (x);
919     }
920   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
921                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
922     r = POINTER_REGS;
923   else if (CONSTANT_ADDRESS_P (x))
924     r = ALL_REGS;
925   else if (GET_CODE (x) == PLUS
926            && REG_P (XEXP (x, 0))
927            && GET_CODE (XEXP (x, 1)) == CONST_INT
928            && INTVAL (XEXP (x, 1)) >= 0)
929     {
930       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
931       if (fit)
932         {
933           if (! strict
934               || REGNO (XEXP (x,0)) == REG_Y
935               || REGNO (XEXP (x,0)) == REG_Z)
936             r = BASE_POINTER_REGS;
937           if (XEXP (x,0) == frame_pointer_rtx
938               || XEXP (x,0) == arg_pointer_rtx)
939             r = BASE_POINTER_REGS;
940         }
941       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
942         r = POINTER_Y_REGS;
943     }
944   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
945            && REG_P (XEXP (x, 0))
946            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
947                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
948     {
949       r = POINTER_REGS;
950     }
951   if (TARGET_ALL_DEBUG)
952     {
953       fprintf (stderr, "   ret = %c\n", r);
954     }
955   return r == NO_REGS ? 0 : (int)r;
956 }
957
958 /* Attempts to replace X with a valid
959    memory address for an operand of mode MODE  */
960
961 rtx
962 legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
963 {
964   x = oldx;
965   if (TARGET_ALL_DEBUG)
966     {
967       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
968       debug_rtx (oldx);
969     }
970   
971   if (GET_CODE (oldx) == PLUS
972       && REG_P (XEXP (oldx,0)))
973     {
974       if (REG_P (XEXP (oldx,1)))
975         x = force_reg (GET_MODE (oldx), oldx);
976       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
977         {
978           int offs = INTVAL (XEXP (oldx,1));
979           if (frame_pointer_rtx != XEXP (oldx,0))
980             if (offs > MAX_LD_OFFSET (mode))
981               {
982                 if (TARGET_ALL_DEBUG)
983                   fprintf (stderr, "force_reg (big offset)\n");
984                 x = force_reg (GET_MODE (oldx), oldx);
985               }
986         }
987     }
988   return x;
989 }
990
991
992 /* Return a pointer register name as a string.  */
993
994 static const char *
995 ptrreg_to_str (int regno)
996 {
997   switch (regno)
998     {
999     case REG_X: return "X";
1000     case REG_Y: return "Y";
1001     case REG_Z: return "Z";
1002     default:
1003       abort ();
1004     }
1005   return NULL;
1006 }
1007
1008 /* Return the condition name as a string.
1009    Used in conditional jump constructing  */
1010
1011 static const char *
1012 cond_string (enum rtx_code code)
1013 {
1014   switch (code)
1015     {
1016     case NE:
1017       return "ne";
1018     case EQ:
1019       return "eq";
1020     case GE:
1021       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1022         return "pl";
1023       else
1024         return "ge";
1025     case LT:
1026       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1027         return "mi";
1028       else
1029         return "lt";
1030     case GEU:
1031       return "sh";
1032     case LTU:
1033       return "lo";
1034     default:
1035       abort ();
1036     }
1037 }
1038
1039 /* Output ADDR to FILE as address.  */
1040
1041 void
1042 print_operand_address (FILE *file, rtx addr)
1043 {
1044   switch (GET_CODE (addr))
1045     {
1046     case REG:
1047       fprintf (file, ptrreg_to_str (REGNO (addr)));
1048       break;
1049
1050     case PRE_DEC:
1051       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1052       break;
1053
1054     case POST_INC:
1055       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1056       break;
1057
1058     default:
1059       if (CONSTANT_ADDRESS_P (addr)
1060           && ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (addr))
1061               || GET_CODE (addr) == LABEL_REF))
1062         {
1063           fprintf (file, "pm(");
1064           output_addr_const (file,addr);
1065           fprintf (file ,")");
1066         }
1067       else
1068         output_addr_const (file, addr);
1069     }
1070 }
1071
1072
1073 /* Output X as assembler operand to file FILE.  */
1074      
1075 void
1076 print_operand (FILE *file, rtx x, int code)
1077 {
1078   int abcd = 0;
1079
1080   if (code >= 'A' && code <= 'D')
1081     abcd = code - 'A';
1082
1083   if (code == '~')
1084     {
1085       if (!AVR_MEGA)
1086         fputc ('r', file);
1087     }
1088   else if (REG_P (x))
1089     {
1090       if (x == zero_reg_rtx)
1091         fprintf (file, "__zero_reg__");
1092       else
1093         fprintf (file, reg_names[true_regnum (x) + abcd]);
1094     }
1095   else if (GET_CODE (x) == CONST_INT)
1096     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1097   else if (GET_CODE (x) == MEM)
1098     {
1099       rtx addr = XEXP (x,0);
1100
1101       if (CONSTANT_P (addr) && abcd)
1102         {
1103           fputc ('(', file);
1104           output_address (addr);
1105           fprintf (file, ")+%d", abcd);
1106         }
1107       else if (code == 'o')
1108         {
1109           if (GET_CODE (addr) != PLUS)
1110             fatal_insn ("bad address, not (reg+disp):", addr);
1111
1112           print_operand (file, XEXP (addr, 1), 0);
1113         }
1114       else if (GET_CODE (addr) == PLUS)
1115         {
1116           print_operand_address (file, XEXP (addr,0));
1117           if (REGNO (XEXP (addr, 0)) == REG_X)
1118             fatal_insn ("internal compiler error.  Bad address:"
1119                         ,addr);
1120           fputc ('+', file);
1121           print_operand (file, XEXP (addr,1), code);
1122         }
1123       else
1124         print_operand_address (file, addr);
1125     }
1126   else if (GET_CODE (x) == CONST_DOUBLE)
1127     {
1128       long val;
1129       REAL_VALUE_TYPE rv;
1130       if (GET_MODE (x) != SFmode)
1131         fatal_insn ("internal compiler error.  Unknown mode:", x);
1132       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1133       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1134       fprintf (file, "0x%lx", val);
1135     }
1136   else if (code == 'j')
1137     fputs (cond_string (GET_CODE (x)), file);
1138   else if (code == 'k')
1139     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1140   else
1141     print_operand_address (file, x);
1142 }
1143
1144 /* Recognize operand OP of mode MODE used in call instructions.  */
1145
1146 int
1147 call_insn_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1148 {
1149   if (GET_CODE (op) == MEM)
1150     {
1151       rtx inside = XEXP (op, 0);
1152       if (register_operand (inside, Pmode))
1153         return 1;
1154       if (CONSTANT_ADDRESS_P (inside))
1155         return 1;
1156     }
1157   return 0;
1158 }
1159
1160 /* Update the condition code in the INSN.  */
1161
1162 void
1163 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1164 {
1165   rtx set;
1166   
1167   switch (get_attr_cc (insn))
1168     {
1169     case CC_NONE:
1170       /* Insn does not affect CC at all.  */
1171       break;
1172
1173     case CC_SET_N:
1174       CC_STATUS_INIT;
1175       break;
1176
1177     case CC_SET_ZN:
1178       set = single_set (insn);
1179       CC_STATUS_INIT;
1180       if (set)
1181         {
1182           cc_status.flags |= CC_NO_OVERFLOW;
1183           cc_status.value1 = SET_DEST (set);
1184         }
1185       break;
1186
1187     case CC_SET_CZN:
1188       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1189          The V flag may or may not be known but that's ok because
1190          alter_cond will change tests to use EQ/NE.  */
1191       set = single_set (insn);
1192       CC_STATUS_INIT;
1193       if (set)
1194         {
1195           cc_status.value1 = SET_DEST (set);
1196           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1197         }
1198       break;
1199
1200     case CC_COMPARE:
1201       set = single_set (insn);
1202       CC_STATUS_INIT;
1203       if (set)
1204         cc_status.value1 = SET_SRC (set);
1205       break;
1206       
1207     case CC_CLOBBER:
1208       /* Insn doesn't leave CC in a usable state.  */
1209       CC_STATUS_INIT;
1210
1211       /* Correct CC for the ashrqi3 with the shift count as CONST_INT != 6 */
1212       set = single_set (insn);
1213       if (set)
1214         {
1215           rtx src = SET_SRC (set);
1216           
1217           if (GET_CODE (src) == ASHIFTRT
1218               && GET_MODE (src) == QImode)
1219             {
1220               rtx x = XEXP (src, 1);
1221
1222               if (GET_CODE (x) == CONST_INT
1223                   && INTVAL (x) != 6)
1224                 {
1225                   cc_status.value1 = SET_DEST (set);
1226                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1227                 }
1228             }
1229         }
1230       break;
1231     }
1232 }
1233
1234 /* Return maximum number of consecutive registers of
1235    class CLASS needed to hold a value of mode MODE.  */
1236
1237 int
1238 class_max_nregs (enum reg_class class ATTRIBUTE_UNUSED,enum machine_mode mode)
1239 {
1240   return ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD);
1241 }
1242
1243 /* Choose mode for jump insn:
1244    1 - relative jump in range -63 <= x <= 62 ;
1245    2 - relative jump in range -2046 <= x <= 2045 ;
1246    3 - absolute jump (only for ATmega[16]03).  */
1247
1248 int
1249 avr_jump_mode (rtx x, rtx insn)
1250 {
1251   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_MODE (x) == LABEL_REF
1252                                             ? XEXP (x, 0) : x));
1253   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1254   int jump_distance = cur_addr - dest_addr;
1255   
1256   if (-63 <= jump_distance && jump_distance <= 62)
1257     return 1;
1258   else if (-2046 <= jump_distance && jump_distance <= 2045)
1259     return 2;
1260   else if (AVR_MEGA)
1261     return 3;
1262   
1263   return 2;
1264 }
1265
1266 /* return an AVR condition jump commands.
1267    X is a comparison RTX.
1268    LEN is a number returned by avr_jump_mode function.
1269    if REVERSE nonzero then condition code in X must be reversed.  */
1270
1271 const char *
1272 ret_cond_branch (rtx x, int len, int reverse)
1273 {
1274   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1275   
1276   switch (cond)
1277     {
1278     case GT:
1279       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1280         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1281                             AS1 (brpl,%0)) :
1282                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1283                             AS1 (brmi,.+2) CR_TAB
1284                             AS1 (rjmp,%0)) :
1285                 (AS1 (breq,.+6) CR_TAB
1286                  AS1 (brmi,.+4) CR_TAB
1287                  AS1 (jmp,%0)));
1288           
1289       else
1290         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1291                             AS1 (brge,%0)) :
1292                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1293                             AS1 (brlt,.+2) CR_TAB
1294                             AS1 (rjmp,%0)) :
1295                 (AS1 (breq,.+6) CR_TAB
1296                  AS1 (brlt,.+4) CR_TAB
1297                  AS1 (jmp,%0)));
1298     case GTU:
1299       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1300                           AS1 (brsh,%0)) :
1301               len == 2 ? (AS1 (breq,.+4) CR_TAB
1302                           AS1 (brlo,.+2) CR_TAB
1303                           AS1 (rjmp,%0)) :
1304               (AS1 (breq,.+6) CR_TAB
1305                AS1 (brlo,.+4) CR_TAB
1306                AS1 (jmp,%0)));
1307     case LE:
1308       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1309         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1310                             AS1 (brmi,%0)) :
1311                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1312                             AS1 (brpl,.+2) CR_TAB
1313                             AS1 (rjmp,%0)) :
1314                 (AS1 (breq,.+2) CR_TAB
1315                  AS1 (brpl,.+4) CR_TAB
1316                  AS1 (jmp,%0)));
1317       else
1318         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1319                             AS1 (brlt,%0)) :
1320                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1321                             AS1 (brge,.+2) CR_TAB
1322                             AS1 (rjmp,%0)) :
1323                 (AS1 (breq,.+2) CR_TAB
1324                  AS1 (brge,.+4) CR_TAB
1325                  AS1 (jmp,%0)));
1326     case LEU:
1327       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1328                           AS1 (brlo,%0)) :
1329               len == 2 ? (AS1 (breq,.+2) CR_TAB
1330                           AS1 (brsh,.+2) CR_TAB
1331                           AS1 (rjmp,%0)) :
1332               (AS1 (breq,.+2) CR_TAB
1333                AS1 (brsh,.+4) CR_TAB
1334                AS1 (jmp,%0)));
1335     default:
1336       if (reverse)
1337         {
1338           switch (len)
1339             {
1340             case 1:
1341               return AS1 (br%k1,%0);
1342             case 2:
1343               return (AS1 (br%j1,.+2) CR_TAB
1344                       AS1 (rjmp,%0));
1345             default:
1346               return (AS1 (br%j1,.+4) CR_TAB
1347                       AS1 (jmp,%0));
1348             }
1349         }
1350         else
1351           {
1352             switch (len)
1353               {
1354               case 1:
1355                 return AS1 (br%j1,%0);
1356               case 2:
1357                 return (AS1 (br%k1,.+2) CR_TAB
1358                         AS1 (rjmp,%0));
1359               default:
1360                 return (AS1 (br%k1,.+4) CR_TAB
1361                         AS1 (jmp,%0));
1362               }
1363           }
1364     }
1365   return "";
1366 }
1367
1368 /* Predicate function for immediate operand which fits to byte (8bit) */
1369
1370 int
1371 byte_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1372 {
1373   return (GET_CODE (op) == CONST_INT
1374           && INTVAL (op) <= 0xff && INTVAL (op) >= 0);
1375 }
1376
1377 /* Output all insn addresses and their sizes into the assembly language
1378    output file.  This is helpful for debugging whether the length attributes
1379    in the md file are correct.
1380    Output insn cost for next insn.  */
1381
1382 void
1383 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1384                     int num_operands ATTRIBUTE_UNUSED)
1385 {
1386   int uid = INSN_UID (insn);
1387
1388   if (TARGET_INSN_SIZE_DUMP || TARGET_ALL_DEBUG)
1389     {
1390       fprintf (asm_out_file, "/*DEBUG: 0x%x\t\t%d\t%d */\n",
1391                INSN_ADDRESSES (uid),
1392                INSN_ADDRESSES (uid) - last_insn_address,
1393                rtx_cost (PATTERN (insn), INSN));
1394     }
1395   last_insn_address = INSN_ADDRESSES (uid);
1396 }
1397
1398 /* Return 0 if undefined, 1 if always true or always false.  */
1399
1400 int
1401 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE operator, rtx x)
1402 {
1403   unsigned int max = (mode == QImode ? 0xff :
1404                       mode == HImode ? 0xffff :
1405                       mode == SImode ? 0xffffffff : 0);
1406   if (max && operator && GET_CODE (x) == CONST_INT)
1407     {
1408       if (unsigned_condition (operator) != operator)
1409         max >>= 1;
1410
1411       if (max != (INTVAL (x) & max)
1412           && INTVAL (x) != 0xff)
1413         return 1;
1414     }
1415   return 0;
1416 }
1417
1418
1419 /* Returns nonzero if REGNO is the number of a hard
1420    register in which function arguments are sometimes passed.  */
1421
1422 int
1423 function_arg_regno_p(int r)
1424 {
1425   return (r >= 8 && r <= 25);
1426 }
1427
1428 /* Initializing the variable cum for the state at the beginning
1429    of the argument list.  */
1430
1431 void
1432 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1433                       tree fndecl ATTRIBUTE_UNUSED)
1434 {
1435   cum->nregs = 18;
1436   cum->regno = FIRST_CUM_REG;
1437   if (!libname && fntype)
1438     {
1439       int stdarg = (TYPE_ARG_TYPES (fntype) != 0
1440                     && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
1441                         != void_type_node));
1442       if (stdarg)
1443         cum->nregs = 0;
1444     }
1445 }
1446
1447 /* Returns the number of registers to allocate for a function argument.  */
1448
1449 static int
1450 avr_num_arg_regs (enum machine_mode mode, tree type)
1451 {
1452   int size;
1453
1454   if (mode == BLKmode)
1455     size = int_size_in_bytes (type);
1456   else
1457     size = GET_MODE_SIZE (mode);
1458
1459   /* Align all function arguments to start in even-numbered registers.
1460      Odd-sized arguments leave holes above them.  */
1461
1462   return (size + 1) & ~1;
1463 }
1464
1465 /* Controls whether a function argument is passed
1466    in a register, and which register.  */
1467
1468 rtx
1469 function_arg (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1470               int named ATTRIBUTE_UNUSED)
1471 {
1472   int bytes = avr_num_arg_regs (mode, type);
1473
1474   if (cum->nregs && bytes <= cum->nregs)
1475     return gen_rtx_REG (mode, cum->regno - bytes);
1476
1477   return NULL_RTX;
1478 }
1479
1480 /* Update the summarizer variable CUM to advance past an argument
1481    in the argument list.  */
1482    
1483 void
1484 function_arg_advance (CUMULATIVE_ARGS *cum, enum machine_mode mode, tree type,
1485                       int named ATTRIBUTE_UNUSED)
1486 {
1487   int bytes = avr_num_arg_regs (mode, type);
1488
1489   cum->nregs -= bytes;
1490   cum->regno -= bytes;
1491
1492   if (cum->nregs <= 0)
1493     {
1494       cum->nregs = 0;
1495       cum->regno = FIRST_CUM_REG;
1496     }
1497 }
1498
1499 /***********************************************************************
1500   Functions for outputting various mov's for a various modes
1501 ************************************************************************/
1502 const char *
1503 output_movqi (rtx insn, rtx operands[], int *l)
1504 {
1505   int dummy;
1506   rtx dest = operands[0];
1507   rtx src = operands[1];
1508   int *real_l = l;
1509   
1510   if (!l)
1511     l = &dummy;
1512
1513   *l = 1;
1514   
1515   if (register_operand (dest, QImode))
1516     {
1517       if (register_operand (src, QImode)) /* mov r,r */
1518         {
1519           if (test_hard_reg_class (STACK_REG, dest))
1520             return AS2 (out,%0,%1);
1521           else if (test_hard_reg_class (STACK_REG, src))
1522             return AS2 (in,%0,%1);
1523           
1524           return AS2 (mov,%0,%1);
1525         }
1526       else if (CONSTANT_P (src))
1527         {
1528           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1529             return AS2 (ldi,%0,lo8(%1));
1530           
1531           if (GET_CODE (src) == CONST_INT)
1532             {
1533               if (src == const0_rtx) /* mov r,L */
1534                 return AS1 (clr,%0);
1535               else if (src == const1_rtx)
1536                 {
1537                   *l = 2;
1538                   return (AS1 (clr,%0) CR_TAB
1539                           AS1 (inc,%0));
1540                 }
1541               else if (src == constm1_rtx)
1542                 {
1543                   /* Immediate constants -1 to any register */
1544                   *l = 2;
1545                   return (AS1 (clr,%0) CR_TAB
1546                           AS1 (dec,%0));
1547                 }
1548               else
1549                 {
1550                   int bit_nr = exact_log2 (INTVAL (src));
1551
1552                   if (bit_nr >= 0)
1553                     {
1554                       *l = 3;
1555                       if (!real_l)
1556                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1557                                           "set"), operands);
1558                       if (!real_l)
1559                         avr_output_bld (operands, bit_nr);
1560
1561                       return "";
1562                     }
1563                 }
1564             }
1565           
1566           /* Last resort, larger than loading from memory.  */
1567           *l = 4;
1568           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1569                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1570                   AS2 (mov,%0,r31)          CR_TAB
1571                   AS2 (mov,r31,__tmp_reg__));
1572         }
1573       else if (GET_CODE (src) == MEM)
1574         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
1575     }
1576   else if (GET_CODE (dest) == MEM)
1577     {
1578       const char *template;
1579
1580       if (src == const0_rtx)
1581         operands[1] = zero_reg_rtx;
1582
1583       template = out_movqi_mr_r (insn, operands, real_l);
1584
1585       if (!real_l)
1586         output_asm_insn (template, operands);
1587
1588       operands[1] = src;
1589     }
1590   return "";
1591 }
1592
1593
1594 const char *
1595 output_movhi (rtx insn, rtx operands[], int *l)
1596 {
1597   int dummy;
1598   rtx dest = operands[0];
1599   rtx src = operands[1];
1600   int *real_l = l;
1601   
1602   if (!l)
1603     l = &dummy;
1604   
1605   if (register_operand (dest, HImode))
1606     {
1607       if (register_operand (src, HImode)) /* mov r,r */
1608         {
1609           if (test_hard_reg_class (STACK_REG, dest))
1610             {
1611               if (TARGET_TINY_STACK)
1612                 {
1613                   *l = 1;
1614                   return AS2 (out,__SP_L__,%A1);
1615                 }
1616               else if (TARGET_NO_INTERRUPTS)
1617                 {
1618                   *l = 2;
1619                   return (AS2 (out,__SP_H__,%B1) CR_TAB
1620                           AS2 (out,__SP_L__,%A1));
1621                 }
1622
1623               *l = 5;
1624               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
1625                       "cli"                          CR_TAB
1626                       AS2 (out,__SP_H__,%B1)         CR_TAB
1627                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
1628                       AS2 (out,__SP_L__,%A1));
1629             }
1630           else if (test_hard_reg_class (STACK_REG, src))
1631             {
1632               *l = 2;   
1633               return (AS2 (in,%A0,__SP_L__) CR_TAB
1634                       AS2 (in,%B0,__SP_H__));
1635             }
1636
1637           if (AVR_ENHANCED)
1638             {
1639               *l = 1;
1640               return (AS2 (movw,%0,%1));
1641             }
1642
1643           if (true_regnum (dest) > true_regnum (src))
1644             {
1645               *l = 2;
1646               return (AS2 (mov,%B0,%B1) CR_TAB
1647                       AS2 (mov,%A0,%A1));
1648             }
1649           else
1650             {
1651               *l = 2;
1652               return (AS2 (mov,%A0,%A1) CR_TAB
1653                       AS2 (mov,%B0,%B1));
1654             }
1655         }
1656       else if (CONSTANT_P (src))
1657         {
1658           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1659             {
1660               *l = 2;
1661               return (AS2 (ldi,%A0,lo8(%1)) CR_TAB
1662                       AS2 (ldi,%B0,hi8(%1)));
1663             }
1664           
1665           if (GET_CODE (src) == CONST_INT)
1666             {
1667               if (src == const0_rtx) /* mov r,L */
1668                 {
1669                   *l = 2;
1670                   return (AS1 (clr,%A0) CR_TAB
1671                           AS1 (clr,%B0));
1672                 }
1673               else if (src == const1_rtx)
1674                 {
1675                   *l = 3;
1676                   return (AS1 (clr,%A0) CR_TAB
1677                           AS1 (clr,%B0) CR_TAB
1678                           AS1 (inc,%A0));
1679                 }
1680               else if (src == constm1_rtx)
1681                 {
1682                   /* Immediate constants -1 to any register */
1683                   *l = 3;
1684                   return (AS1 (clr,%0)  CR_TAB
1685                           AS1 (dec,%A0) CR_TAB
1686                           AS2 (mov,%B0,%A0));
1687                 }
1688               else
1689                 {
1690                   int bit_nr = exact_log2 (INTVAL (src));
1691
1692                   if (bit_nr >= 0)
1693                     {
1694                       *l = 4;
1695                       if (!real_l)
1696                         output_asm_insn ((AS1 (clr,%A0) CR_TAB
1697                                           AS1 (clr,%B0) CR_TAB
1698                                           "set"), operands);
1699                       if (!real_l)
1700                         avr_output_bld (operands, bit_nr);
1701
1702                       return "";
1703                     }
1704                 }
1705
1706               if ((INTVAL (src) & 0xff) == 0)
1707                 {
1708                   *l = 5;
1709                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1710                           AS1 (clr,%A0)             CR_TAB
1711                           AS2 (ldi,r31,hi8(%1))     CR_TAB
1712                           AS2 (mov,%B0,r31)         CR_TAB
1713                           AS2 (mov,r31,__tmp_reg__));
1714                 }
1715               else if ((INTVAL (src) & 0xff00) == 0)
1716                 {
1717                   *l = 5;
1718                   return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1719                           AS2 (ldi,r31,lo8(%1))     CR_TAB
1720                           AS2 (mov,%A0,r31)         CR_TAB
1721                           AS1 (clr,%B0)             CR_TAB
1722                           AS2 (mov,r31,__tmp_reg__));
1723                 }
1724             }
1725           
1726           /* Last resort, equal to loading from memory.  */
1727           *l = 6;
1728           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
1729                   AS2 (ldi,r31,lo8(%1))     CR_TAB
1730                   AS2 (mov,%A0,r31)         CR_TAB
1731                   AS2 (ldi,r31,hi8(%1))     CR_TAB
1732                   AS2 (mov,%B0,r31)         CR_TAB
1733                   AS2 (mov,r31,__tmp_reg__));
1734         }
1735       else if (GET_CODE (src) == MEM)
1736         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
1737     }
1738   else if (GET_CODE (dest) == MEM)
1739     {
1740       const char *template;
1741
1742       if (src == const0_rtx)
1743         operands[1] = zero_reg_rtx;
1744
1745       template = out_movhi_mr_r (insn, operands, real_l);
1746
1747       if (!real_l)
1748         output_asm_insn (template, operands);
1749
1750       operands[1] = src;
1751       return "";
1752     }
1753   fatal_insn ("invalid insn:", insn);
1754   return "";
1755 }
1756
1757 const char *
1758 out_movqi_r_mr (rtx insn, rtx op[], int *l)
1759 {
1760   rtx dest = op[0];
1761   rtx src = op[1];
1762   rtx x = XEXP (src, 0);
1763   int dummy;
1764   
1765   if (!l)
1766     l = &dummy;
1767   
1768   if (CONSTANT_ADDRESS_P (x))
1769     {
1770       if (avr_io_address_p (x, 1))
1771         {
1772           *l = 1;
1773           return AS2 (in,%0,%1-0x20);
1774         }
1775       *l = 2;
1776       return AS2 (lds,%0,%1);
1777     }
1778   /* memory access by reg+disp */
1779   else if (GET_CODE (x) == PLUS
1780       && REG_P (XEXP (x,0))
1781       && GET_CODE (XEXP (x,1)) == CONST_INT)
1782     {
1783       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
1784         {
1785           int disp = INTVAL (XEXP (x,1));
1786           if (REGNO (XEXP (x,0)) != REG_Y)
1787             fatal_insn ("incorrect insn:",insn);
1788
1789           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1790             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
1791                             AS2 (ldd,%0,Y+63)     CR_TAB
1792                             AS2 (sbiw,r28,%o1-63));
1793
1794           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1795                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1796                           AS2 (ld,%0,Y)            CR_TAB
1797                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1798                           AS2 (sbci,r29,hi8(%o1)));
1799         }
1800       else if (REGNO (XEXP (x,0)) == REG_X)
1801         {
1802           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
1803              it but I have this situation with extremal optimizing options.  */
1804           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
1805               || reg_unused_after (insn, XEXP (x,0)))
1806             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
1807                             AS2 (ld,%0,X));
1808
1809           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
1810                           AS2 (ld,%0,X)      CR_TAB
1811                           AS2 (sbiw,r26,%o1));
1812         }
1813       *l = 1;
1814       return AS2 (ldd,%0,%1);
1815     }
1816   *l = 1;
1817   return AS2 (ld,%0,%1);
1818 }
1819
1820 const char *
1821 out_movhi_r_mr (rtx insn, rtx op[], int *l)
1822 {
1823   rtx dest = op[0];
1824   rtx src = op[1];
1825   rtx base = XEXP (src, 0);
1826   int reg_dest = true_regnum (dest);
1827   int reg_base = true_regnum (base);
1828   int tmp;
1829
1830   if (!l)
1831     l = &tmp;
1832
1833   if (reg_base > 0)
1834     {
1835       if (reg_dest == reg_base)         /* R = (R) */
1836         {
1837           *l = 3;
1838           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
1839                   AS2 (ld,%B0,%1) CR_TAB
1840                   AS2 (mov,%A0,__tmp_reg__));
1841         }
1842       else if (reg_base == REG_X)        /* (R26) */
1843         {
1844           if (reg_unused_after (insn, base))
1845             {
1846               *l = 2;
1847               return (AS2 (ld,%A0,X+) CR_TAB
1848                       AS2 (ld,%B0,X));
1849             }
1850           *l  = 3;
1851           return (AS2 (ld,%A0,X+) CR_TAB
1852                   AS2 (ld,%B0,X) CR_TAB
1853                   AS2 (sbiw,r26,1));
1854         }
1855       else                      /* (R)  */
1856         {
1857           *l = 2;
1858           return (AS2 (ld,%A0,%1)    CR_TAB
1859                   AS2 (ldd,%B0,%1+1));
1860         }
1861     }
1862   else if (GET_CODE (base) == PLUS) /* (R + i) */
1863     {
1864       int disp = INTVAL (XEXP (base, 1));
1865       int reg_base = true_regnum (XEXP (base, 0));
1866       
1867       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
1868         {
1869           if (REGNO (XEXP (base, 0)) != REG_Y)
1870             fatal_insn ("incorrect insn:",insn);
1871           
1872           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
1873             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
1874                             AS2 (ldd,%A0,Y+62)    CR_TAB
1875                             AS2 (ldd,%B0,Y+63)    CR_TAB
1876                             AS2 (sbiw,r28,%o1-62));
1877
1878           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
1879                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
1880                           AS2 (ld,%A0,Y)           CR_TAB
1881                           AS2 (ldd,%B0,Y+1)        CR_TAB
1882                           AS2 (subi,r28,lo8(%o1))  CR_TAB
1883                           AS2 (sbci,r29,hi8(%o1)));
1884         }
1885       if (reg_base == REG_X)
1886         {
1887           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
1888              it but I have this situation with extremal
1889              optimization options.  */
1890           
1891           *l = 4;
1892           if (reg_base == reg_dest)
1893             return (AS2 (adiw,r26,%o1)      CR_TAB
1894                     AS2 (ld,__tmp_reg__,X+) CR_TAB
1895                     AS2 (ld,%B0,X)          CR_TAB
1896                     AS2 (mov,%A0,__tmp_reg__));
1897
1898           return (AS2 (adiw,r26,%o1) CR_TAB
1899                   AS2 (ld,%A0,X+)    CR_TAB
1900                   AS2 (ld,%B0,X)     CR_TAB
1901                   AS2 (sbiw,r26,%o1+1));
1902         }
1903
1904       if (reg_base == reg_dest)
1905         {
1906           *l = 3;
1907           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
1908                   AS2 (ldd,%B0,%B1)         CR_TAB
1909                   AS2 (mov,%A0,__tmp_reg__));
1910         }
1911       
1912       *l = 2;
1913       return (AS2 (ldd,%A0,%A1) CR_TAB
1914               AS2 (ldd,%B0,%B1));
1915     }
1916   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
1917     {
1918       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1919         fatal_insn ("incorrect insn:", insn);
1920
1921       *l = 2;
1922       return (AS2 (ld,%B0,%1) CR_TAB
1923               AS2 (ld,%A0,%1));
1924     }
1925   else if (GET_CODE (base) == POST_INC) /* (R++) */
1926     {
1927       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
1928         fatal_insn ("incorrect insn:", insn);
1929
1930       *l = 2;
1931       return (AS2 (ld,%A0,%1)  CR_TAB
1932               AS2 (ld,%B0,%1));
1933     }
1934   else if (CONSTANT_ADDRESS_P (base))
1935     {
1936       if (avr_io_address_p (base, 2))
1937         {
1938           *l = 2;
1939           return (AS2 (in,%A0,%A1-0x20) CR_TAB
1940                   AS2 (in,%B0,%B1-0x20));
1941         }
1942       *l = 4;
1943       return (AS2 (lds,%A0,%A1) CR_TAB
1944               AS2 (lds,%B0,%B1));
1945     }
1946   
1947   fatal_insn ("unknown move insn:",insn);
1948   return "";
1949 }
1950
1951 const char *
1952 out_movsi_r_mr (rtx insn, rtx op[], int *l)
1953 {
1954   rtx dest = op[0];
1955   rtx src = op[1];
1956   rtx base = XEXP (src, 0);
1957   int reg_dest = true_regnum (dest);
1958   int reg_base = true_regnum (base);
1959   int tmp;
1960
1961   if (!l)
1962     l = &tmp;
1963   
1964   if (reg_base > 0)
1965     {
1966       if (reg_base == REG_X)        /* (R26) */
1967         {
1968           if (reg_dest == REG_X)
1969             /* "ld r26,-X" is undefined */
1970             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
1971                           AS2 (ld,r29,X)          CR_TAB
1972                           AS2 (ld,r28,-X)         CR_TAB
1973                           AS2 (ld,__tmp_reg__,-X) CR_TAB
1974                           AS2 (sbiw,r26,1)        CR_TAB
1975                           AS2 (ld,r26,X)          CR_TAB
1976                           AS2 (mov,r27,__tmp_reg__));
1977           else if (reg_dest == REG_X - 2)
1978             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
1979                           AS2 (ld,%B0,X+) CR_TAB
1980                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
1981                           AS2 (ld,%D0,X)  CR_TAB
1982                           AS2 (mov,%C0,__tmp_reg__));
1983           else if (reg_unused_after (insn, base))
1984             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
1985                            AS2 (ld,%B0,X+) CR_TAB
1986                            AS2 (ld,%C0,X+) CR_TAB
1987                            AS2 (ld,%D0,X));
1988           else
1989             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
1990                            AS2 (ld,%B0,X+) CR_TAB
1991                            AS2 (ld,%C0,X+) CR_TAB
1992                            AS2 (ld,%D0,X)  CR_TAB
1993                            AS2 (sbiw,r26,3));
1994         }
1995       else
1996         {
1997           if (reg_dest == reg_base)
1998             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
1999                           AS2 (ldd,%C0,%1+2) CR_TAB
2000                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2001                           AS2 (ld,%A0,%1)  CR_TAB
2002                           AS2 (mov,%B0,__tmp_reg__));
2003           else if (reg_base == reg_dest + 2)
2004             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2005                           AS2 (ldd,%B0,%1+1) CR_TAB
2006                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2007                           AS2 (ldd,%D0,%1+3) CR_TAB
2008                           AS2 (mov,%C0,__tmp_reg__));
2009           else
2010             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2011                           AS2 (ldd,%B0,%1+1) CR_TAB
2012                           AS2 (ldd,%C0,%1+2) CR_TAB
2013                           AS2 (ldd,%D0,%1+3));
2014         }
2015     }
2016   else if (GET_CODE (base) == PLUS) /* (R + i) */
2017     {
2018       int disp = INTVAL (XEXP (base, 1));
2019       
2020       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2021         {
2022           if (REGNO (XEXP (base, 0)) != REG_Y)
2023             fatal_insn ("incorrect insn:",insn);
2024
2025           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2026             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2027                             AS2 (ldd,%A0,Y+60)    CR_TAB
2028                             AS2 (ldd,%B0,Y+61)    CR_TAB
2029                             AS2 (ldd,%C0,Y+62)    CR_TAB
2030                             AS2 (ldd,%D0,Y+63)    CR_TAB
2031                             AS2 (sbiw,r28,%o1-60));
2032
2033           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2034                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2035                           AS2 (ld,%A0,Y)           CR_TAB
2036                           AS2 (ldd,%B0,Y+1)        CR_TAB
2037                           AS2 (ldd,%C0,Y+2)        CR_TAB
2038                           AS2 (ldd,%D0,Y+3)        CR_TAB
2039                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2040                           AS2 (sbci,r29,hi8(%o1)));
2041         }
2042
2043       reg_base = true_regnum (XEXP (base, 0));
2044       if (reg_base == REG_X)
2045         {
2046           /* R = (X + d) */
2047           if (reg_dest == REG_X)
2048             {
2049               *l = 7;
2050               /* "ld r26,-X" is undefined */
2051               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2052                       AS2 (ld,r29,X)          CR_TAB
2053                       AS2 (ld,r28,-X)         CR_TAB
2054                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2055                       AS2 (sbiw,r26,1)        CR_TAB
2056                       AS2 (ld,r26,X)          CR_TAB
2057                       AS2 (mov,r27,__tmp_reg__));
2058             }
2059           *l = 6;
2060           if (reg_dest == REG_X - 2)
2061             return (AS2 (adiw,r26,%o1)      CR_TAB
2062                     AS2 (ld,r24,X+)         CR_TAB
2063                     AS2 (ld,r25,X+)         CR_TAB
2064                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2065                     AS2 (ld,r27,X)          CR_TAB
2066                     AS2 (mov,r26,__tmp_reg__));
2067
2068           return (AS2 (adiw,r26,%o1) CR_TAB
2069                   AS2 (ld,%A0,X+)    CR_TAB
2070                   AS2 (ld,%B0,X+)    CR_TAB
2071                   AS2 (ld,%C0,X+)    CR_TAB
2072                   AS2 (ld,%D0,X)     CR_TAB
2073                   AS2 (sbiw,r26,%o1+3));
2074         }
2075       if (reg_dest == reg_base)
2076         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2077                       AS2 (ldd,%C0,%C1) CR_TAB
2078                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2079                       AS2 (ldd,%A0,%A1) CR_TAB
2080                       AS2 (mov,%B0,__tmp_reg__));
2081       else if (reg_dest == reg_base - 2)
2082         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2083                       AS2 (ldd,%B0,%B1) CR_TAB
2084                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2085                       AS2 (ldd,%D0,%D1) CR_TAB
2086                       AS2 (mov,%C0,__tmp_reg__));
2087       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2088                     AS2 (ldd,%B0,%B1) CR_TAB
2089                     AS2 (ldd,%C0,%C1) CR_TAB
2090                     AS2 (ldd,%D0,%D1));
2091     }
2092   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2093     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2094                   AS2 (ld,%C0,%1) CR_TAB
2095                   AS2 (ld,%B0,%1) CR_TAB
2096                   AS2 (ld,%A0,%1));
2097   else if (GET_CODE (base) == POST_INC) /* (R++) */
2098     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2099                   AS2 (ld,%B0,%1) CR_TAB
2100                   AS2 (ld,%C0,%1) CR_TAB
2101                   AS2 (ld,%D0,%1));
2102   else if (CONSTANT_ADDRESS_P (base))
2103       return *l=8, (AS2 (lds,%A0,%A1) CR_TAB
2104                     AS2 (lds,%B0,%B1) CR_TAB
2105                     AS2 (lds,%C0,%C1) CR_TAB
2106                     AS2 (lds,%D0,%D1));
2107     
2108   fatal_insn ("unknown move insn:",insn);
2109   return "";
2110 }
2111
2112 const char *
2113 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2114 {
2115   rtx dest = op[0];
2116   rtx src = op[1];
2117   rtx base = XEXP (dest, 0);
2118   int reg_base = true_regnum (base);
2119   int reg_src = true_regnum (src);
2120   int tmp;
2121   
2122   if (!l)
2123     l = &tmp;
2124   
2125   if (CONSTANT_ADDRESS_P (base))
2126     return *l=8,(AS2 (sts,%A0,%A1) CR_TAB
2127                  AS2 (sts,%B0,%B1) CR_TAB
2128                  AS2 (sts,%C0,%C1) CR_TAB
2129                  AS2 (sts,%D0,%D1));
2130   if (reg_base > 0)                 /* (r) */
2131     {
2132       if (reg_base == REG_X)                /* (R26) */
2133         {
2134           if (reg_src == REG_X)
2135             {
2136               /* "st X+,r26" is undefined */
2137               if (reg_unused_after (insn, base))
2138                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2139                               AS2 (st,X,r26)            CR_TAB
2140                               AS2 (adiw,r26,1)          CR_TAB
2141                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2142                               AS2 (st,X+,r28)           CR_TAB
2143                               AS2 (st,X,r29));
2144               else
2145                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2146                               AS2 (st,X,r26)            CR_TAB
2147                               AS2 (adiw,r26,1)          CR_TAB
2148                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2149                               AS2 (st,X+,r28)           CR_TAB
2150                               AS2 (st,X,r29)            CR_TAB
2151                               AS2 (sbiw,r26,3));
2152             }
2153           else if (reg_base == reg_src + 2)
2154             {
2155               if (reg_unused_after (insn, base))
2156                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2157                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2158                               AS2 (st,%0+,%A1) CR_TAB
2159                               AS2 (st,%0+,%B1) CR_TAB
2160                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2161                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2162                               AS1 (clr,__zero_reg__));
2163               else
2164                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2165                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2166                               AS2 (st,%0+,%A1) CR_TAB
2167                               AS2 (st,%0+,%B1) CR_TAB
2168                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2169                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2170                               AS1 (clr,__zero_reg__)     CR_TAB
2171                               AS2 (sbiw,r26,3));
2172             }
2173           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2174                         AS2 (st,%0+,%B1) CR_TAB
2175                         AS2 (st,%0+,%C1) CR_TAB
2176                         AS2 (st,%0,%D1)  CR_TAB
2177                         AS2 (sbiw,r26,3));
2178         }
2179       else
2180         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2181                       AS2 (std,%0+1,%B1) CR_TAB
2182                       AS2 (std,%0+2,%C1) CR_TAB
2183                       AS2 (std,%0+3,%D1));
2184     }
2185   else if (GET_CODE (base) == PLUS) /* (R + i) */
2186     {
2187       int disp = INTVAL (XEXP (base, 1));
2188       reg_base = REGNO (XEXP (base, 0));
2189       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2190         {
2191           if (reg_base != REG_Y)
2192             fatal_insn ("incorrect insn:",insn);
2193
2194           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2195             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2196                             AS2 (std,Y+60,%A1)    CR_TAB
2197                             AS2 (std,Y+61,%B1)    CR_TAB
2198                             AS2 (std,Y+62,%C1)    CR_TAB
2199                             AS2 (std,Y+63,%D1)    CR_TAB
2200                             AS2 (sbiw,r28,%o0-60));
2201
2202           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2203                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2204                           AS2 (st,Y,%A1)           CR_TAB
2205                           AS2 (std,Y+1,%B1)        CR_TAB
2206                           AS2 (std,Y+2,%C1)        CR_TAB
2207                           AS2 (std,Y+3,%D1)        CR_TAB
2208                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2209                           AS2 (sbci,r29,hi8(%o0)));
2210         }
2211       if (reg_base == REG_X)
2212         {
2213           /* (X + d) = R */
2214           if (reg_src == REG_X)
2215             {
2216               *l = 9;
2217               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2218                       AS2 (mov,__zero_reg__,r27) CR_TAB
2219                       AS2 (adiw,r26,%o0)         CR_TAB
2220                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2221                       AS2 (st,X+,__zero_reg__)   CR_TAB
2222                       AS2 (st,X+,r28)            CR_TAB
2223                       AS2 (st,X,r29)             CR_TAB
2224                       AS1 (clr,__zero_reg__)     CR_TAB
2225                       AS2 (sbiw,r26,%o0+3));
2226             }
2227           else if (reg_src == REG_X - 2)
2228             {
2229               *l = 9;
2230               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2231                       AS2 (mov,__zero_reg__,r27) CR_TAB
2232                       AS2 (adiw,r26,%o0)         CR_TAB
2233                       AS2 (st,X+,r24)            CR_TAB
2234                       AS2 (st,X+,r25)            CR_TAB
2235                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2236                       AS2 (st,X,__zero_reg__)    CR_TAB
2237                       AS1 (clr,__zero_reg__)     CR_TAB
2238                       AS2 (sbiw,r26,%o0+3));
2239             }
2240           *l = 6;
2241           return (AS2 (adiw,r26,%o0) CR_TAB
2242                   AS2 (st,X+,%A1)    CR_TAB
2243                   AS2 (st,X+,%B1)    CR_TAB
2244                   AS2 (st,X+,%C1)    CR_TAB
2245                   AS2 (st,X,%D1)     CR_TAB
2246                   AS2 (sbiw,r26,%o0+3));
2247         }
2248       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2249                     AS2 (std,%B0,%B1) CR_TAB
2250                     AS2 (std,%C0,%C1) CR_TAB
2251                     AS2 (std,%D0,%D1));
2252     }
2253   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2254     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2255                   AS2 (st,%0,%C1) CR_TAB
2256                   AS2 (st,%0,%B1) CR_TAB
2257                   AS2 (st,%0,%A1));
2258   else if (GET_CODE (base) == POST_INC) /* (R++) */
2259     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2260                   AS2 (st,%0,%B1) CR_TAB
2261                   AS2 (st,%0,%C1) CR_TAB
2262                   AS2 (st,%0,%D1));
2263   fatal_insn ("unknown move insn:",insn);
2264   return "";
2265 }
2266
2267 const char *
2268 output_movsisf(rtx insn, rtx operands[], int *l)
2269 {
2270   int dummy;
2271   rtx dest = operands[0];
2272   rtx src = operands[1];
2273   int *real_l = l;
2274   
2275   if (!l)
2276     l = &dummy;
2277   
2278   if (register_operand (dest, VOIDmode))
2279     {
2280       if (register_operand (src, VOIDmode)) /* mov r,r */
2281         {
2282           if (true_regnum (dest) > true_regnum (src))
2283             {
2284               if (AVR_ENHANCED)
2285                 {
2286                   *l = 2;
2287                   return (AS2 (movw,%C0,%C1) CR_TAB
2288                           AS2 (movw,%A0,%A1));
2289                 }
2290               *l = 4;
2291               return (AS2 (mov,%D0,%D1) CR_TAB
2292                       AS2 (mov,%C0,%C1) CR_TAB
2293                       AS2 (mov,%B0,%B1) CR_TAB
2294                       AS2 (mov,%A0,%A1));
2295             }
2296           else
2297             {
2298               if (AVR_ENHANCED)
2299                 {
2300                   *l = 2;
2301                   return (AS2 (movw,%A0,%A1) CR_TAB
2302                           AS2 (movw,%C0,%C1));
2303                 }
2304               *l = 4;
2305               return (AS2 (mov,%A0,%A1) CR_TAB
2306                       AS2 (mov,%B0,%B1) CR_TAB
2307                       AS2 (mov,%C0,%C1) CR_TAB
2308                       AS2 (mov,%D0,%D1));
2309             }
2310         }
2311       else if (CONSTANT_P (src))
2312         {
2313           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2314             {
2315               *l = 4;
2316               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2317                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2318                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2319                       AS2 (ldi,%D0,hhi8(%1)));
2320             }
2321           
2322           if (GET_CODE (src) == CONST_INT)
2323             {
2324               const char *const clr_op0 =
2325                 AVR_ENHANCED ? (AS1 (clr,%A0) CR_TAB
2326                                 AS1 (clr,%B0) CR_TAB
2327                                 AS2 (movw,%C0,%A0))
2328                              : (AS1 (clr,%A0) CR_TAB
2329                                 AS1 (clr,%B0) CR_TAB
2330                                 AS1 (clr,%C0) CR_TAB
2331                                 AS1 (clr,%D0));
2332
2333               if (src == const0_rtx) /* mov r,L */
2334                 {
2335                   *l = AVR_ENHANCED ? 3 : 4;
2336                   return clr_op0;
2337                 }
2338               else if (src == const1_rtx)
2339                 {
2340                   if (!real_l)
2341                     output_asm_insn (clr_op0, operands);
2342                   *l = AVR_ENHANCED ? 4 : 5;
2343                   return AS1 (inc,%A0);
2344                 }
2345               else if (src == constm1_rtx)
2346                 {
2347                   /* Immediate constants -1 to any register */
2348                   if (AVR_ENHANCED)
2349                     {
2350                       *l = 4;
2351                       return (AS1 (clr,%A0)     CR_TAB
2352                               AS1 (dec,%A0)     CR_TAB
2353                               AS2 (mov,%B0,%A0) CR_TAB
2354                               AS2 (movw,%C0,%A0));
2355                     }
2356                   *l = 5;
2357                   return (AS1 (clr,%A0)     CR_TAB
2358                           AS1 (dec,%A0)     CR_TAB
2359                           AS2 (mov,%B0,%A0) CR_TAB
2360                           AS2 (mov,%C0,%A0) CR_TAB
2361                           AS2 (mov,%D0,%A0));
2362                 }
2363               else
2364                 {
2365                   int bit_nr = exact_log2 (INTVAL (src));
2366
2367                   if (bit_nr >= 0)
2368                     {
2369                       *l = AVR_ENHANCED ? 5 : 6;
2370                       if (!real_l)
2371                         {
2372                           output_asm_insn (clr_op0, operands);
2373                           output_asm_insn ("set", operands);
2374                         }
2375                       if (!real_l)
2376                         avr_output_bld (operands, bit_nr);
2377
2378                       return "";
2379                     }
2380                 }
2381             }
2382           
2383           /* Last resort, better than loading from memory.  */
2384           *l = 10;
2385           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2386                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2387                   AS2 (mov,%A0,r31)         CR_TAB
2388                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2389                   AS2 (mov,%B0,r31)         CR_TAB
2390                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2391                   AS2 (mov,%C0,r31)         CR_TAB
2392                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2393                   AS2 (mov,%D0,r31)         CR_TAB
2394                   AS2 (mov,r31,__tmp_reg__));
2395         }
2396       else if (GET_CODE (src) == MEM)
2397         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2398     }
2399   else if (GET_CODE (dest) == MEM)
2400     {
2401       const char *template;
2402
2403       if (src == const0_rtx)
2404           operands[1] = zero_reg_rtx;
2405
2406       template = out_movsi_mr_r (insn, operands, real_l);
2407
2408       if (!real_l)
2409         output_asm_insn (template, operands);
2410
2411       operands[1] = src;
2412       return "";
2413     }
2414   fatal_insn ("invalid insn:", insn);
2415   return "";
2416 }
2417
2418 const char *
2419 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2420 {
2421   rtx dest = op[0];
2422   rtx src = op[1];
2423   rtx x = XEXP (dest, 0);
2424   int dummy;
2425
2426   if (!l)
2427     l = &dummy;
2428   
2429   if (CONSTANT_ADDRESS_P (x))
2430     {
2431       if (avr_io_address_p (x, 1))
2432         {
2433           *l = 1;
2434           return AS2 (out,%0-0x20,%1);
2435         }
2436       *l = 2;
2437       return AS2 (sts,%0,%1);
2438     }
2439   /* memory access by reg+disp */
2440   else if (GET_CODE (x) == PLUS 
2441       && REG_P (XEXP (x,0))
2442       && GET_CODE (XEXP (x,1)) == CONST_INT)
2443     {
2444       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2445         {
2446           int disp = INTVAL (XEXP (x,1));
2447           if (REGNO (XEXP (x,0)) != REG_Y)
2448             fatal_insn ("incorrect insn:",insn);
2449
2450           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2451             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2452                             AS2 (std,Y+63,%1)     CR_TAB
2453                             AS2 (sbiw,r28,%o0-63));
2454
2455           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2456                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2457                           AS2 (st,Y,%1)            CR_TAB
2458                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2459                           AS2 (sbci,r29,hi8(%o0)));
2460         }
2461       else if (REGNO (XEXP (x,0)) == REG_X)
2462         {
2463           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2464             {
2465               if (reg_unused_after (insn, XEXP (x,0)))
2466                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2467                                 AS2 (adiw,r26,%o0)       CR_TAB
2468                                 AS2 (st,X,__tmp_reg__));
2469
2470               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2471                               AS2 (adiw,r26,%o0)       CR_TAB
2472                               AS2 (st,X,__tmp_reg__)   CR_TAB
2473                               AS2 (sbiw,r26,%o0));
2474             }
2475           else
2476             {
2477               if (reg_unused_after (insn, XEXP (x,0)))
2478                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2479                                 AS2 (st,X,%1));
2480
2481               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2482                               AS2 (st,X,%1)      CR_TAB
2483                               AS2 (sbiw,r26,%o0));
2484             }
2485         }
2486       *l = 1;
2487       return AS2 (std,%0,%1);
2488     }
2489   *l = 1;
2490   return AS2 (st,%0,%1);
2491 }
2492
2493 const char *
2494 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2495 {
2496   rtx dest = op[0];
2497   rtx src = op[1];
2498   rtx base = XEXP (dest, 0);
2499   int reg_base = true_regnum (base);
2500   int reg_src = true_regnum (src);
2501   int tmp;
2502   if (!l)
2503     l = &tmp;
2504   if (CONSTANT_ADDRESS_P (base))
2505     {
2506       if (avr_io_address_p (base, 2))
2507         {
2508           *l = 2;
2509           return (AS2 (out,%B0-0x20,%B1) CR_TAB
2510                   AS2 (out,%A0-0x20,%A1));
2511         }
2512       return *l = 4, (AS2 (sts,%B0,%B1) CR_TAB
2513                       AS2 (sts,%A0,%A1));
2514     }
2515   if (reg_base > 0)
2516     {
2517       if (reg_base == REG_X)
2518         {
2519           if (reg_src == REG_X)
2520             {
2521               /* "st X+,r26" is undefined */
2522               if (reg_unused_after (insn, src))
2523                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2524                               AS2 (st,X,r26)            CR_TAB
2525                               AS2 (adiw,r26,1)          CR_TAB
2526                               AS2 (st,X,__tmp_reg__));
2527               else
2528                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2529                               AS2 (st,X,r26)            CR_TAB
2530                               AS2 (adiw,r26,1)          CR_TAB
2531                               AS2 (st,X,__tmp_reg__)    CR_TAB
2532                               AS2 (sbiw,r26,1));
2533             }
2534           else
2535             {
2536               if (reg_unused_after (insn, base))
2537                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2538                               AS2 (st,X,%B1));
2539               else
2540                 return *l=3, (AS2 (st  ,X+,%A1) CR_TAB
2541                               AS2 (st  ,X,%B1) CR_TAB
2542                               AS2 (sbiw,r26,1));
2543             }
2544         }
2545       else
2546         return  *l=2, (AS2 (st ,%0,%A1)    CR_TAB
2547                        AS2 (std,%0+1,%B1));
2548     }
2549   else if (GET_CODE (base) == PLUS)
2550     {
2551       int disp = INTVAL (XEXP (base, 1));
2552       reg_base = REGNO (XEXP (base, 0));
2553       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2554         {
2555           if (reg_base != REG_Y)
2556             fatal_insn ("incorrect insn:",insn);
2557
2558           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2559             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2560                             AS2 (std,Y+62,%A1)    CR_TAB
2561                             AS2 (std,Y+63,%B1)    CR_TAB
2562                             AS2 (sbiw,r28,%o0-62));
2563
2564           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2565                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2566                           AS2 (st,Y,%A1)           CR_TAB
2567                           AS2 (std,Y+1,%B1)        CR_TAB
2568                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2569                           AS2 (sbci,r29,hi8(%o0)));
2570         }
2571       if (reg_base == REG_X)
2572         {
2573           /* (X + d) = R */
2574           if (reg_src == REG_X)
2575             {
2576               *l = 7;
2577               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2578                       AS2 (mov,__zero_reg__,r27) CR_TAB
2579                       AS2 (adiw,r26,%o0)         CR_TAB
2580                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2581                       AS2 (st,X,__zero_reg__)    CR_TAB
2582                       AS1 (clr,__zero_reg__)     CR_TAB
2583                       AS2 (sbiw,r26,%o0+1));
2584             }
2585           *l = 4;
2586           return (AS2 (adiw,r26,%o0) CR_TAB
2587                   AS2 (st,X+,%A1)    CR_TAB
2588                   AS2 (st,X,%B1)     CR_TAB
2589                   AS2 (sbiw,r26,%o0+1));
2590         }
2591       return *l=2, (AS2 (std,%A0,%A1)    CR_TAB
2592                     AS2 (std,%B0,%B1));
2593     }
2594   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2595     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2596                   AS2 (st,%0,%A1));
2597   else if (GET_CODE (base) == POST_INC) /* (R++) */
2598     return *l=2, (AS2 (st,%0,%A1)  CR_TAB
2599                   AS2 (st,%0,%B1));
2600   fatal_insn ("unknown move insn:",insn);
2601   return "";
2602 }
2603
2604 /* Return 1 if frame pointer for current function required.  */
2605
2606 int
2607 frame_pointer_required_p (void)
2608 {
2609   return (current_function_calls_alloca
2610           || current_function_args_info.nregs == 0
2611           || get_frame_size () > 0);
2612 }
2613
2614 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2615
2616 static RTX_CODE
2617 compare_condition (rtx insn)
2618 {
2619   rtx next = next_real_insn (insn);
2620   RTX_CODE cond = UNKNOWN;
2621   if (next && GET_CODE (next) == JUMP_INSN)
2622     {
2623       rtx pat = PATTERN (next);
2624       rtx src = SET_SRC (pat);
2625       rtx t = XEXP (src, 0);
2626       cond = GET_CODE (t);
2627     }
2628   return cond;
2629 }
2630
2631 /* Returns nonzero if INSN is a tst insn that only tests the sign.  */
2632
2633 static int
2634 compare_sign_p (rtx insn)
2635 {
2636   RTX_CODE cond = compare_condition (insn);
2637   return (cond == GE || cond == LT);
2638 }
2639
2640 /* Returns nonzero if the next insn is a JUMP_INSN with a condition
2641    that needs to be swapped (GT, GTU, LE, LEU).  */
2642
2643 int
2644 compare_diff_p (rtx insn)
2645 {
2646   RTX_CODE cond = compare_condition (insn);
2647   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
2648 }
2649
2650 /* Returns nonzero if INSN is a compare insn with the EQ or NE condition.  */
2651
2652 int
2653 compare_eq_p (rtx insn)
2654 {
2655   RTX_CODE cond = compare_condition (insn);
2656   return (cond == EQ || cond == NE);
2657 }
2658
2659
2660 /* Output test instruction for HImode.  */
2661
2662 const char *
2663 out_tsthi (rtx insn, int *l)
2664 {
2665   if (compare_sign_p (insn))
2666     {
2667       if (l) *l = 1;
2668       return AS1 (tst,%B0);
2669     }
2670   if (reg_unused_after (insn, SET_SRC (PATTERN (insn)))
2671       && compare_eq_p (insn))
2672     {
2673       /* Faster than sbiw if we can clobber the operand.  */
2674       if (l) *l = 1;
2675       return AS2 (or,%A0,%B0);
2676     }
2677   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2678     {
2679       if (l) *l = 1;
2680       return AS2 (sbiw,%0,0);
2681     }
2682   if (l) *l = 2;
2683   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2684           AS2 (cpc,%B0,__zero_reg__));
2685 }
2686
2687
2688 /* Output test instruction for SImode.  */
2689
2690 const char *
2691 out_tstsi (rtx insn, int *l)
2692 {
2693   if (compare_sign_p (insn))
2694     {
2695       if (l) *l = 1;
2696       return AS1 (tst,%D0);
2697     }
2698   if (test_hard_reg_class (ADDW_REGS, SET_SRC (PATTERN (insn))))
2699     {
2700       if (l) *l = 3;
2701       return (AS2 (sbiw,%A0,0) CR_TAB
2702               AS2 (cpc,%C0,__zero_reg__) CR_TAB
2703               AS2 (cpc,%D0,__zero_reg__));
2704     }
2705   if (l) *l = 4;
2706   return (AS2 (cp,%A0,__zero_reg__) CR_TAB
2707           AS2 (cpc,%B0,__zero_reg__) CR_TAB
2708           AS2 (cpc,%C0,__zero_reg__) CR_TAB
2709           AS2 (cpc,%D0,__zero_reg__));
2710 }
2711
2712
2713 /* Generate asm equivalent for various shifts.
2714    Shift count is a CONST_INT, MEM or REG.
2715    This only handles cases that are not already
2716    carefully hand-optimized in ?sh??i3_out.  */
2717
2718 void
2719 out_shift_with_cnt (const char *template, rtx insn, rtx operands[],
2720                     int *len, int t_len)
2721 {
2722   rtx op[10];
2723   char str[500];
2724   int second_label = 1;
2725   int saved_in_tmp = 0;
2726   int use_zero_reg = 0;
2727
2728   op[0] = operands[0];
2729   op[1] = operands[1];
2730   op[2] = operands[2];
2731   op[3] = operands[3];
2732   str[0] = 0;
2733
2734   if (len)
2735     *len = 1;
2736
2737   if (GET_CODE (operands[2]) == CONST_INT)
2738     {
2739       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2740       int count = INTVAL (operands[2]);
2741       int max_len = 10;  /* If larger than this, always use a loop.  */
2742
2743       if (count < 8 && !scratch)
2744         use_zero_reg = 1;
2745
2746       if (optimize_size)
2747         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
2748
2749       if (t_len * count <= max_len)
2750         {
2751           /* Output shifts inline with no loop - faster.  */
2752           if (len)
2753             *len = t_len * count;
2754           else
2755             {
2756               while (count-- > 0)
2757                 output_asm_insn (template, op);
2758             }
2759
2760           return;
2761         }
2762
2763       if (scratch)
2764         {
2765           if (!len)
2766             strcat (str, AS2 (ldi,%3,%2));
2767         }
2768       else if (use_zero_reg)
2769         {
2770           /* Hack to save one word: use __zero_reg__ as loop counter.
2771              Set one bit, then shift in a loop until it is 0 again.  */
2772
2773           op[3] = zero_reg_rtx;
2774           if (len)
2775             *len = 2;
2776           else
2777             strcat (str, ("set" CR_TAB
2778                           AS2 (bld,%3,%2-1)));
2779         }
2780       else
2781         {
2782           /* No scratch register available, use one from LD_REGS (saved in
2783              __tmp_reg__) that doesn't overlap with registers to shift.  */
2784
2785           op[3] = gen_rtx_REG (QImode,
2786                            ((true_regnum (operands[0]) - 1) & 15) + 16);
2787           op[4] = tmp_reg_rtx;
2788           saved_in_tmp = 1;
2789
2790           if (len)
2791             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
2792           else
2793             strcat (str, (AS2 (mov,%4,%3) CR_TAB
2794                           AS2 (ldi,%3,%2)));
2795         }
2796
2797       second_label = 0;
2798     }
2799   else if (GET_CODE (operands[2]) == MEM)
2800     {
2801       rtx op_mov[10];
2802       
2803       op[3] = op_mov[0] = tmp_reg_rtx;
2804       op_mov[1] = op[2];
2805
2806       if (len)
2807         out_movqi_r_mr (insn, op_mov, len);
2808       else
2809         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
2810     }
2811   else if (register_operand (operands[2], QImode))
2812     {
2813       if (reg_unused_after (insn, operands[2]))
2814         op[3] = op[2];
2815       else
2816         {
2817           op[3] = tmp_reg_rtx;
2818           if (!len)
2819             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
2820         }
2821     }
2822   else
2823     fatal_insn ("bad shift insn:", insn);
2824
2825   if (second_label)
2826     {
2827       if (len)
2828         ++*len;
2829       else
2830         strcat (str, AS1 (rjmp,2f));
2831     }
2832
2833   if (len)
2834     *len += t_len + 2;  /* template + dec + brXX */
2835   else
2836     {
2837       strcat (str, "\n1:\t");
2838       strcat (str, template);
2839       strcat (str, second_label ? "\n2:\t" : "\n\t");
2840       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
2841       strcat (str, CR_TAB);
2842       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
2843       if (saved_in_tmp)
2844         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
2845       output_asm_insn (str, op);
2846     }
2847 }
2848
2849
2850 /* 8bit shift left ((char)x << i)   */
2851
2852 const char *
2853 ashlqi3_out (rtx insn, rtx operands[], int *len)
2854 {
2855   if (GET_CODE (operands[2]) == CONST_INT)
2856     {
2857       int k;
2858
2859       if (!len)
2860         len = &k;
2861
2862       switch (INTVAL (operands[2]))
2863         {
2864         default:
2865           *len = 1;
2866           return AS1 (clr,%0);
2867           
2868         case 1:
2869           *len = 1;
2870           return AS1 (lsl,%0);
2871           
2872         case 2:
2873           *len = 2;
2874           return (AS1 (lsl,%0) CR_TAB
2875                   AS1 (lsl,%0));
2876
2877         case 3:
2878           *len = 3;
2879           return (AS1 (lsl,%0) CR_TAB
2880                   AS1 (lsl,%0) CR_TAB
2881                   AS1 (lsl,%0));
2882
2883         case 4:
2884           if (test_hard_reg_class (LD_REGS, operands[0]))
2885             {
2886               *len = 2;
2887               return (AS1 (swap,%0) CR_TAB
2888                       AS2 (andi,%0,0xf0));
2889             }
2890           *len = 4;
2891           return (AS1 (lsl,%0) CR_TAB
2892                   AS1 (lsl,%0) CR_TAB
2893                   AS1 (lsl,%0) CR_TAB
2894                   AS1 (lsl,%0));
2895
2896         case 5:
2897           if (test_hard_reg_class (LD_REGS, operands[0]))
2898             {
2899               *len = 3;
2900               return (AS1 (swap,%0) CR_TAB
2901                       AS1 (lsl,%0)  CR_TAB
2902                       AS2 (andi,%0,0xe0));
2903             }
2904           *len = 5;
2905           return (AS1 (lsl,%0) CR_TAB
2906                   AS1 (lsl,%0) CR_TAB
2907                   AS1 (lsl,%0) CR_TAB
2908                   AS1 (lsl,%0) CR_TAB
2909                   AS1 (lsl,%0));
2910
2911         case 6:
2912           if (test_hard_reg_class (LD_REGS, operands[0]))
2913             {
2914               *len = 4;
2915               return (AS1 (swap,%0) CR_TAB
2916                       AS1 (lsl,%0)  CR_TAB
2917                       AS1 (lsl,%0)  CR_TAB
2918                       AS2 (andi,%0,0xc0));
2919             }
2920           *len = 6;
2921           return (AS1 (lsl,%0) CR_TAB
2922                   AS1 (lsl,%0) CR_TAB
2923                   AS1 (lsl,%0) CR_TAB
2924                   AS1 (lsl,%0) CR_TAB
2925                   AS1 (lsl,%0) CR_TAB
2926                   AS1 (lsl,%0));
2927
2928         case 7:
2929           *len = 3;
2930           return (AS1 (ror,%0) CR_TAB
2931                   AS1 (clr,%0) CR_TAB
2932                   AS1 (ror,%0));
2933         }
2934     }
2935   else if (CONSTANT_P (operands[2]))
2936     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
2937
2938   out_shift_with_cnt (AS1 (lsl,%0),
2939                       insn, operands, len, 1);
2940   return "";
2941 }
2942
2943
2944 /* 16bit shift left ((short)x << i)   */
2945
2946 const char *
2947 ashlhi3_out (rtx insn, rtx operands[], int *len)
2948 {
2949   if (GET_CODE (operands[2]) == CONST_INT)
2950     {
2951       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
2952       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
2953       int k;
2954       int *t = len;
2955
2956       if (!len)
2957         len = &k;
2958       
2959       switch (INTVAL (operands[2]))
2960         {
2961         case 4:
2962           if (optimize_size && scratch)
2963             break;  /* 5 */
2964           if (ldi_ok)
2965             {
2966               *len = 6;
2967               return (AS1 (swap,%A0)      CR_TAB
2968                       AS1 (swap,%B0)      CR_TAB
2969                       AS2 (andi,%B0,0xf0) CR_TAB
2970                       AS2 (eor,%B0,%A0)   CR_TAB
2971                       AS2 (andi,%A0,0xf0) CR_TAB
2972                       AS2 (eor,%B0,%A0));
2973             }
2974           if (scratch)
2975             {
2976               *len = 7;
2977               return (AS1 (swap,%A0)    CR_TAB
2978                       AS1 (swap,%B0)    CR_TAB
2979                       AS2 (ldi,%3,0xf0) CR_TAB
2980                       AS2 (and,%B0,%3)  CR_TAB
2981                       AS2 (eor,%B0,%A0) CR_TAB
2982                       AS2 (and,%A0,%3)  CR_TAB
2983                       AS2 (eor,%B0,%A0));
2984             }
2985           break;  /* optimize_size ? 6 : 8 */
2986
2987         case 5:
2988           if (optimize_size)
2989             break;  /* scratch ? 5 : 6 */
2990           if (ldi_ok)
2991             {
2992               *len = 8;
2993               return (AS1 (lsl,%A0)       CR_TAB
2994                       AS1 (rol,%B0)       CR_TAB
2995                       AS1 (swap,%A0)      CR_TAB
2996                       AS1 (swap,%B0)      CR_TAB
2997                       AS2 (andi,%B0,0xf0) CR_TAB
2998                       AS2 (eor,%B0,%A0)   CR_TAB
2999                       AS2 (andi,%A0,0xf0) CR_TAB
3000                       AS2 (eor,%B0,%A0));
3001             }
3002           if (scratch)
3003             {
3004               *len = 9;
3005               return (AS1 (lsl,%A0)     CR_TAB
3006                       AS1 (rol,%B0)     CR_TAB
3007                       AS1 (swap,%A0)    CR_TAB
3008                       AS1 (swap,%B0)    CR_TAB
3009                       AS2 (ldi,%3,0xf0) CR_TAB
3010                       AS2 (and,%B0,%3)  CR_TAB
3011                       AS2 (eor,%B0,%A0) CR_TAB
3012                       AS2 (and,%A0,%3)  CR_TAB
3013                       AS2 (eor,%B0,%A0));
3014             }
3015           break;  /* 10 */
3016
3017         case 6:
3018           if (optimize_size)
3019             break;  /* scratch ? 5 : 6 */
3020           *len = 9;
3021           return (AS1 (clr,__tmp_reg__) CR_TAB
3022                   AS1 (lsr,%B0)         CR_TAB
3023                   AS1 (ror,%A0)         CR_TAB
3024                   AS1 (ror,__tmp_reg__) CR_TAB
3025                   AS1 (lsr,%B0)         CR_TAB
3026                   AS1 (ror,%A0)         CR_TAB
3027                   AS1 (ror,__tmp_reg__) CR_TAB
3028                   AS2 (mov,%B0,%A0)     CR_TAB
3029                   AS2 (mov,%A0,__tmp_reg__));
3030
3031         case 7:
3032           *len = 5;
3033           return (AS1 (lsr,%B0)     CR_TAB
3034                   AS2 (mov,%B0,%A0) CR_TAB
3035                   AS1 (clr,%A0)     CR_TAB
3036                   AS1 (ror,%B0)     CR_TAB
3037                   AS1 (ror,%A0));
3038
3039         case 8:
3040           if (true_regnum (operands[0]) + 1 == true_regnum (operands[1]))
3041             return *len = 1, AS1 (clr,%A0);
3042           else
3043             return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3044                               AS1 (clr,%A0));
3045
3046         case 9:
3047           *len = 3;
3048           return (AS2 (mov,%B0,%A0) CR_TAB
3049                   AS1 (clr,%A0)     CR_TAB
3050                   AS1 (lsl,%B0));
3051
3052         case 10:
3053           *len = 4;
3054           return (AS2 (mov,%B0,%A0) CR_TAB
3055                   AS1 (clr,%A0)     CR_TAB
3056                   AS1 (lsl,%B0)     CR_TAB
3057                   AS1 (lsl,%B0));
3058
3059         case 11:
3060           *len = 5;
3061           return (AS2 (mov,%B0,%A0) CR_TAB
3062                   AS1 (clr,%A0)     CR_TAB
3063                   AS1 (lsl,%B0)     CR_TAB
3064                   AS1 (lsl,%B0)     CR_TAB
3065                   AS1 (lsl,%B0));
3066
3067         case 12:
3068           if (ldi_ok)
3069             {
3070               *len = 4;
3071               return (AS2 (mov,%B0,%A0) CR_TAB
3072                       AS1 (clr,%A0)     CR_TAB
3073                       AS1 (swap,%B0)    CR_TAB
3074                       AS2 (andi,%B0,0xf0));
3075             }
3076           if (scratch)
3077             {
3078               *len = 5;
3079               return (AS2 (mov,%B0,%A0) CR_TAB
3080                       AS1 (clr,%A0)     CR_TAB
3081                       AS1 (swap,%B0)    CR_TAB
3082                       AS2 (ldi,%3,0xf0) CR_TAB
3083                       AS2 (and,%B0,%3));
3084             }
3085           *len = 6;
3086           return (AS2 (mov,%B0,%A0) CR_TAB
3087                   AS1 (clr,%A0)     CR_TAB
3088                   AS1 (lsl,%B0)     CR_TAB
3089                   AS1 (lsl,%B0)     CR_TAB
3090                   AS1 (lsl,%B0)     CR_TAB
3091                   AS1 (lsl,%B0));
3092
3093         case 13:
3094           if (ldi_ok)
3095             {
3096               *len = 5;
3097               return (AS2 (mov,%B0,%A0) CR_TAB
3098                       AS1 (clr,%A0)     CR_TAB
3099                       AS1 (swap,%B0)    CR_TAB
3100                       AS1 (lsl,%B0)     CR_TAB
3101                       AS2 (andi,%B0,0xe0));
3102             }
3103           if (AVR_ENHANCED && scratch)
3104             {
3105               *len = 5;
3106               return (AS2 (ldi,%3,0x20) CR_TAB
3107                       AS2 (mul,%A0,%3)  CR_TAB
3108                       AS2 (mov,%B0,r0)  CR_TAB
3109                       AS1 (clr,%A0)     CR_TAB
3110                       AS1 (clr,__zero_reg__));
3111             }
3112           if (optimize_size && scratch)
3113             break;  /* 5 */
3114           if (scratch)
3115             {
3116               *len = 6;
3117               return (AS2 (mov,%B0,%A0) CR_TAB
3118                       AS1 (clr,%A0)     CR_TAB
3119                       AS1 (swap,%B0)    CR_TAB
3120                       AS1 (lsl,%B0)     CR_TAB
3121                       AS2 (ldi,%3,0xe0) CR_TAB
3122                       AS2 (and,%B0,%3));
3123             }
3124           if (AVR_ENHANCED)
3125             {
3126               *len = 6;
3127               return ("set"            CR_TAB
3128                       AS2 (bld,r1,5)   CR_TAB
3129                       AS2 (mul,%A0,r1) CR_TAB
3130                       AS2 (mov,%B0,r0) CR_TAB
3131                       AS1 (clr,%A0)    CR_TAB
3132                       AS1 (clr,__zero_reg__));
3133             }
3134           *len = 7;
3135           return (AS2 (mov,%B0,%A0) CR_TAB
3136                   AS1 (clr,%A0)     CR_TAB
3137                   AS1 (lsl,%B0)     CR_TAB
3138                   AS1 (lsl,%B0)     CR_TAB
3139                   AS1 (lsl,%B0)     CR_TAB
3140                   AS1 (lsl,%B0)     CR_TAB
3141                   AS1 (lsl,%B0));
3142
3143         case 14:
3144           if (AVR_ENHANCED && ldi_ok)
3145             {
3146               *len = 5;
3147               return (AS2 (ldi,%B0,0x40) CR_TAB
3148                       AS2 (mul,%A0,%B0)  CR_TAB
3149                       AS2 (mov,%B0,r0)   CR_TAB
3150                       AS1 (clr,%A0)      CR_TAB
3151                       AS1 (clr,__zero_reg__));
3152             }
3153           if (AVR_ENHANCED && scratch)
3154             {
3155               *len = 5;
3156               return (AS2 (ldi,%3,0x40) CR_TAB
3157                       AS2 (mul,%A0,%3)  CR_TAB
3158                       AS2 (mov,%B0,r0)  CR_TAB
3159                       AS1 (clr,%A0)     CR_TAB
3160                       AS1 (clr,__zero_reg__));
3161             }
3162           if (optimize_size && ldi_ok)
3163             {
3164               *len = 5;
3165               return (AS2 (mov,%B0,%A0) CR_TAB
3166                       AS2 (ldi,%A0,6) "\n1:\t"
3167                       AS1 (lsl,%B0)     CR_TAB
3168                       AS1 (dec,%A0)     CR_TAB
3169                       AS1 (brne,1b));
3170             }
3171           if (optimize_size && scratch)
3172             break;  /* 5 */
3173           *len = 6;
3174           return (AS1 (clr,%B0) CR_TAB
3175                   AS1 (lsr,%A0) CR_TAB
3176                   AS1 (ror,%B0) CR_TAB
3177                   AS1 (lsr,%A0) CR_TAB
3178                   AS1 (ror,%B0) CR_TAB
3179                   AS1 (clr,%A0));
3180
3181         case 15:
3182           *len = 4;
3183           return (AS1 (clr,%B0) CR_TAB
3184                   AS1 (lsr,%A0) CR_TAB
3185                   AS1 (ror,%B0) CR_TAB
3186                   AS1 (clr,%A0));
3187         }
3188       len = t;
3189     }
3190   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3191                        AS1 (rol,%B0)),
3192                        insn, operands, len, 2);
3193   return "";
3194 }
3195
3196
3197 /* 32bit shift left ((long)x << i)   */
3198
3199 const char *
3200 ashlsi3_out (rtx insn, rtx operands[], int *len)
3201 {
3202   if (GET_CODE (operands[2]) == CONST_INT)
3203     {
3204       int k;
3205       int *t = len;
3206       
3207       if (!len)
3208         len = &k;
3209       
3210       switch (INTVAL (operands[2]))
3211         {
3212         case 8:
3213           {
3214             int reg0 = true_regnum (operands[0]);
3215             int reg1 = true_regnum (operands[1]);
3216             *len = 4;
3217             if (reg0 >= reg1)
3218               return (AS2 (mov,%D0,%C1)  CR_TAB
3219                       AS2 (mov,%C0,%B1)  CR_TAB
3220                       AS2 (mov,%B0,%A1)  CR_TAB
3221                       AS1 (clr,%A0));
3222             else if (reg0 + 1 == reg1)
3223               {
3224                 *len = 1;
3225                 return AS1 (clr,%A0);
3226               }
3227             else
3228               return (AS1 (clr,%A0)      CR_TAB
3229                       AS2 (mov,%B0,%A1)  CR_TAB
3230                       AS2 (mov,%C0,%B1)  CR_TAB
3231                       AS2 (mov,%D0,%C1));
3232           }
3233
3234         case 16:
3235           {
3236             int reg0 = true_regnum (operands[0]);
3237             int reg1 = true_regnum (operands[1]);
3238             *len = 4;
3239             if (AVR_ENHANCED && (reg0 + 2 != reg1))
3240               {
3241                 *len = 3;
3242                 return (AS2 (movw,%C0,%A1) CR_TAB
3243                         AS1 (clr,%B0)      CR_TAB
3244                         AS1 (clr,%A0));
3245               }
3246             if (reg0 + 1 >= reg1)
3247               return (AS2 (mov,%D0,%B1)  CR_TAB
3248                       AS2 (mov,%C0,%A1)  CR_TAB
3249                       AS1 (clr,%B0)      CR_TAB
3250                       AS1 (clr,%A0));
3251             if (reg0 + 2 == reg1)
3252               {
3253                 *len = 2;
3254                 return (AS1 (clr,%B0)      CR_TAB
3255                         AS1 (clr,%A0));
3256               }
3257             else
3258               return (AS2 (mov,%C0,%A1)  CR_TAB
3259                       AS2 (mov,%D0,%B1)  CR_TAB
3260                       AS1 (clr,%B0)      CR_TAB
3261                       AS1 (clr,%A0));
3262           }
3263
3264         case 24:
3265           *len = 4;
3266           if (true_regnum (operands[0]) + 3 != true_regnum (operands[1]))
3267             return (AS2 (mov,%D0,%A1)  CR_TAB
3268                     AS1 (clr,%C0)      CR_TAB
3269                     AS1 (clr,%B0)      CR_TAB
3270                     AS1 (clr,%A0));
3271           else
3272             {
3273               *len = 3;
3274               return (AS1 (clr,%C0)      CR_TAB
3275                       AS1 (clr,%B0)      CR_TAB
3276                       AS1 (clr,%A0));
3277             }
3278
3279         case 31:
3280           *len = 6;
3281           return (AS1 (clr,%D0) CR_TAB
3282                   AS1 (lsr,%A0) CR_TAB
3283                   AS1 (ror,%D0) CR_TAB
3284                   AS1 (clr,%C0) CR_TAB
3285                   AS1 (clr,%B0) CR_TAB
3286                   AS1 (clr,%A0));
3287         }
3288       len = t;
3289     }
3290   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3291                        AS1 (rol,%B0) CR_TAB
3292                        AS1 (rol,%C0) CR_TAB
3293                        AS1 (rol,%D0)),
3294                        insn, operands, len, 4);
3295   return "";
3296 }
3297
3298 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3299
3300 const char *
3301 ashrqi3_out (rtx insn, rtx operands[], int *len)
3302 {
3303   if (GET_CODE (operands[2]) == CONST_INT)
3304     {
3305       int k;
3306
3307       if (!len)
3308         len = &k;
3309
3310       switch (INTVAL (operands[2]))
3311         {
3312         case 1:
3313           *len = 1;
3314           return AS1 (asr,%0);
3315
3316         case 2:
3317           *len = 2;
3318           return (AS1 (asr,%0) CR_TAB
3319                   AS1 (asr,%0));
3320
3321         case 3:
3322           *len = 3;
3323           return (AS1 (asr,%0) CR_TAB
3324                   AS1 (asr,%0) CR_TAB
3325                   AS1 (asr,%0));
3326
3327         case 4:
3328           *len = 4;
3329           return (AS1 (asr,%0) CR_TAB
3330                   AS1 (asr,%0) CR_TAB
3331                   AS1 (asr,%0) CR_TAB
3332                   AS1 (asr,%0));
3333
3334         case 5:
3335           *len = 5;
3336           return (AS1 (asr,%0) CR_TAB
3337                   AS1 (asr,%0) CR_TAB
3338                   AS1 (asr,%0) CR_TAB
3339                   AS1 (asr,%0) CR_TAB
3340                   AS1 (asr,%0));
3341
3342         case 6:
3343           *len = 4;
3344           return (AS2 (bst,%0,6)  CR_TAB
3345                   AS1 (lsl,%0)    CR_TAB
3346                   AS2 (sbc,%0,%0) CR_TAB
3347                   AS2 (bld,%0,0));
3348
3349         default:
3350         case 7:
3351           *len = 2;
3352           return (AS1 (lsl,%0) CR_TAB
3353                   AS2 (sbc,%0,%0));
3354         }
3355     }
3356   else if (CONSTANT_P (operands[2]))
3357     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3358
3359   out_shift_with_cnt (AS1 (asr,%0),
3360                       insn, operands, len, 1);
3361   return "";
3362 }
3363
3364
3365 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3366
3367 const char *
3368 ashrhi3_out (rtx insn, rtx operands[], int *len)
3369 {
3370   if (GET_CODE (operands[2]) == CONST_INT)
3371     {
3372       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3373       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3374       int k;
3375       int *t = len;
3376       
3377       if (!len)
3378         len = &k;
3379
3380       switch (INTVAL (operands[2]))
3381         {
3382         case 4:
3383         case 5:
3384           /* XXX try to optimize this too? */
3385           break;
3386
3387         case 6:
3388           if (optimize_size)
3389             break;  /* scratch ? 5 : 6 */
3390           *len = 8;
3391           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3392                   AS2 (mov,%A0,%B0)         CR_TAB
3393                   AS1 (lsl,__tmp_reg__)     CR_TAB
3394                   AS1 (rol,%A0)             CR_TAB
3395                   AS2 (sbc,%B0,%B0)         CR_TAB
3396                   AS1 (lsl,__tmp_reg__)     CR_TAB
3397                   AS1 (rol,%A0)             CR_TAB
3398                   AS1 (rol,%B0));
3399
3400         case 7:
3401           *len = 4;
3402           return (AS1 (lsl,%A0)     CR_TAB
3403                   AS2 (mov,%A0,%B0) CR_TAB
3404                   AS1 (rol,%A0)     CR_TAB
3405                   AS2 (sbc,%B0,%B0));
3406
3407         case 8:
3408           {
3409             int reg0 = true_regnum (operands[0]);
3410             int reg1 = true_regnum (operands[1]);
3411
3412             if (reg0 == reg1)
3413               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3414                                 AS1 (lsl,%B0)     CR_TAB
3415                                 AS2 (sbc,%B0,%B0));
3416             else if (reg0 == reg1 + 1)
3417               return *len = 3, (AS1 (clr,%B0)    CR_TAB
3418                                 AS2 (sbrc,%A0,7) CR_TAB
3419                                 AS1 (dec,%B0));
3420
3421             return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3422                               AS1 (clr,%B0)     CR_TAB
3423                               AS2 (sbrc,%A0,7)  CR_TAB
3424                               AS1 (dec,%B0));
3425           }
3426
3427         case 9:
3428           *len = 4;
3429           return (AS2 (mov,%A0,%B0) CR_TAB
3430                   AS1 (lsl,%B0)      CR_TAB
3431                   AS2 (sbc,%B0,%B0) CR_TAB
3432                   AS1 (asr,%A0));
3433
3434         case 10:
3435           *len = 5;
3436           return (AS2 (mov,%A0,%B0) CR_TAB
3437                   AS1 (lsl,%B0)     CR_TAB
3438                   AS2 (sbc,%B0,%B0) CR_TAB
3439                   AS1 (asr,%A0)     CR_TAB
3440                   AS1 (asr,%A0));
3441
3442         case 11:
3443           if (AVR_ENHANCED && ldi_ok)
3444             {
3445               *len = 5;
3446               return (AS2 (ldi,%A0,0x20) CR_TAB
3447                       AS2 (muls,%B0,%A0) CR_TAB
3448                       AS2 (mov,%A0,r1)   CR_TAB
3449                       AS2 (sbc,%B0,%B0)  CR_TAB
3450                       AS1 (clr,__zero_reg__));
3451             }
3452           if (optimize_size && scratch)
3453             break;  /* 5 */
3454           *len = 6;
3455           return (AS2 (mov,%A0,%B0) CR_TAB
3456                   AS1 (lsl,%B0)     CR_TAB
3457                   AS2 (sbc,%B0,%B0) CR_TAB
3458                   AS1 (asr,%A0)     CR_TAB
3459                   AS1 (asr,%A0)     CR_TAB
3460                   AS1 (asr,%A0));
3461
3462         case 12:
3463           if (AVR_ENHANCED && ldi_ok)
3464             {
3465               *len = 5;
3466               return (AS2 (ldi,%A0,0x10) CR_TAB
3467                       AS2 (muls,%B0,%A0) CR_TAB
3468                       AS2 (mov,%A0,r1)   CR_TAB
3469                       AS2 (sbc,%B0,%B0)  CR_TAB
3470                       AS1 (clr,__zero_reg__));
3471             }
3472           if (optimize_size && scratch)
3473             break;  /* 5 */
3474           *len = 7;
3475           return (AS2 (mov,%A0,%B0) CR_TAB
3476                   AS1 (lsl,%B0)     CR_TAB
3477                   AS2 (sbc,%B0,%B0) CR_TAB
3478                   AS1 (asr,%A0)     CR_TAB
3479                   AS1 (asr,%A0)     CR_TAB
3480                   AS1 (asr,%A0)     CR_TAB
3481                   AS1 (asr,%A0));
3482
3483         case 13:
3484           if (AVR_ENHANCED && ldi_ok)
3485             {
3486               *len = 5;
3487               return (AS2 (ldi,%A0,0x08) CR_TAB
3488                       AS2 (muls,%B0,%A0) CR_TAB
3489                       AS2 (mov,%A0,r1)   CR_TAB
3490                       AS2 (sbc,%B0,%B0)  CR_TAB
3491                       AS1 (clr,__zero_reg__));
3492             }
3493           if (optimize_size)
3494             break;  /* scratch ? 5 : 7 */
3495           *len = 8;
3496           return (AS2 (mov,%A0,%B0) CR_TAB
3497                   AS1 (lsl,%B0)     CR_TAB
3498                   AS2 (sbc,%B0,%B0) CR_TAB
3499                   AS1 (asr,%A0)     CR_TAB
3500                   AS1 (asr,%A0)     CR_TAB
3501                   AS1 (asr,%A0)     CR_TAB
3502                   AS1 (asr,%A0)     CR_TAB
3503                   AS1 (asr,%A0));
3504
3505         case 14:
3506           *len = 5;
3507           return (AS1 (lsl,%B0)     CR_TAB
3508                   AS2 (sbc,%A0,%A0) CR_TAB
3509                   AS1 (lsl,%B0)     CR_TAB
3510                   AS2 (mov,%B0,%A0) CR_TAB
3511                   AS1 (rol,%A0));
3512
3513         case 15:
3514           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
3515                             AS2 (sbc,%A0,%A0) CR_TAB
3516                             AS2 (mov,%B0,%A0));
3517         }
3518       len = t;
3519     }
3520   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
3521                        AS1 (ror,%A0)),
3522                        insn, operands, len, 2);
3523   return "";
3524 }
3525
3526
3527 /* 32bit arithmetic shift right  ((signed long)x >> i) */
3528
3529 const char *
3530 ashrsi3_out (rtx insn, rtx operands[], int *len)
3531 {
3532   if (GET_CODE (operands[2]) == CONST_INT)
3533     {
3534       int k;
3535       int *t = len;
3536       
3537       if (!len)
3538         len = &k;
3539       
3540       switch (INTVAL (operands[2]))
3541         {
3542         case 8:
3543           {
3544             int reg0 = true_regnum (operands[0]);
3545             int reg1 = true_regnum (operands[1]);
3546             *len=6;
3547             if (reg0 <= reg1)
3548               return (AS2 (mov,%A0,%B1) CR_TAB
3549                       AS2 (mov,%B0,%C1) CR_TAB
3550                       AS2 (mov,%C0,%D1) CR_TAB
3551                       AS1 (clr,%D0)     CR_TAB
3552                       AS2 (sbrc,%C0,7)  CR_TAB
3553                       AS1 (dec,%D0));
3554             else if (reg0 == reg1 + 1)
3555               {
3556                 *len = 3;
3557                 return (AS1 (clr,%D0)     CR_TAB
3558                         AS2 (sbrc,%C0,7)  CR_TAB
3559                         AS1 (dec,%D0));
3560               }
3561             else
3562               return (AS1 (clr,%D0)     CR_TAB
3563                       AS2 (sbrc,%D1,7)  CR_TAB
3564                       AS1 (dec,%D0)     CR_TAB
3565                       AS2 (mov,%C0,%D1) CR_TAB
3566                       AS2 (mov,%B0,%C1) CR_TAB
3567                       AS2 (mov,%A0,%B1));
3568           }
3569           
3570         case 16:
3571           {
3572             int reg0 = true_regnum (operands[0]);
3573             int reg1 = true_regnum (operands[1]);
3574             *len=6;
3575             if (AVR_ENHANCED && (reg0 != reg1 + 2))
3576               {
3577                 *len = 5;
3578                 return (AS2 (movw,%A0,%C1) CR_TAB
3579                         AS1 (clr,%D0)      CR_TAB
3580                         AS2 (sbrc,%B0,7)   CR_TAB
3581                         AS1 (com,%D0)      CR_TAB
3582                         AS2 (mov,%C0,%D0));
3583               }
3584             if (reg0 <= reg1 + 1)
3585               return (AS2 (mov,%A0,%C1) CR_TAB
3586                       AS2 (mov,%B0,%D1) CR_TAB
3587                       AS1 (clr,%D0)     CR_TAB
3588                       AS2 (sbrc,%B0,7)  CR_TAB
3589                       AS1 (com,%D0)     CR_TAB
3590                       AS2 (mov,%C0,%D0));
3591             else if (reg0 == reg1 + 2)
3592               return *len = 4, (AS1 (clr,%D0)     CR_TAB
3593                                 AS2 (sbrc,%B0,7)  CR_TAB
3594                                 AS1 (com,%D0)     CR_TAB
3595                                 AS2 (mov,%C0,%D0));
3596             else
3597               return (AS2 (mov,%B0,%D1) CR_TAB
3598                       AS2 (mov,%A0,%C1) CR_TAB
3599                       AS1 (clr,%D0)     CR_TAB
3600                       AS2 (sbrc,%B0,7)  CR_TAB
3601                       AS1 (com,%D0)     CR_TAB
3602                       AS2 (mov,%C0,%D0));
3603           }
3604
3605         case 24:
3606           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 3)
3607             return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
3608                               AS1 (clr,%D0)     CR_TAB
3609                               AS2 (sbrc,%A0,7)  CR_TAB
3610                               AS1 (com,%D0)     CR_TAB
3611                               AS2 (mov,%B0,%D0) CR_TAB
3612                               AS2 (mov,%C0,%D0));
3613           else
3614             return *len = 5, (AS1 (clr,%D0)     CR_TAB
3615                               AS2 (sbrc,%A0,7)  CR_TAB
3616                               AS1 (com,%D0)     CR_TAB
3617                               AS2 (mov,%B0,%D0) CR_TAB
3618                               AS2 (mov,%C0,%D0));
3619
3620         case 31:
3621           if (AVR_ENHANCED)
3622             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
3623                               AS2 (sbc,%A0,%A0) CR_TAB
3624                               AS2 (mov,%B0,%A0) CR_TAB
3625                               AS2 (movw,%C0,%A0));
3626           else
3627             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
3628                               AS2 (sbc,%A0,%A0) CR_TAB
3629                               AS2 (mov,%B0,%A0) CR_TAB
3630                               AS2 (mov,%C0,%A0) CR_TAB
3631                               AS2 (mov,%D0,%A0));
3632         }
3633       len = t;
3634     }
3635   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
3636                        AS1 (ror,%C0) CR_TAB
3637                        AS1 (ror,%B0) CR_TAB
3638                        AS1 (ror,%A0)),
3639                        insn, operands, len, 4);
3640   return "";
3641 }
3642
3643 /* 8bit logic shift right ((unsigned char)x >> i) */
3644
3645 const char *
3646 lshrqi3_out (rtx insn, rtx operands[], int *len)
3647 {
3648   if (GET_CODE (operands[2]) == CONST_INT)
3649     {
3650       int k;
3651
3652       if (!len)
3653         len = &k;
3654       
3655       switch (INTVAL (operands[2]))
3656         {
3657         default:
3658           *len = 1;
3659           return AS1 (clr,%0);
3660
3661         case 1:
3662           *len = 1;
3663           return AS1 (lsr,%0);
3664
3665         case 2:
3666           *len = 2;
3667           return (AS1 (lsr,%0) CR_TAB
3668                   AS1 (lsr,%0));
3669         case 3:
3670           *len = 3;
3671           return (AS1 (lsr,%0) CR_TAB
3672                   AS1 (lsr,%0) CR_TAB
3673                   AS1 (lsr,%0));
3674           
3675         case 4:
3676           if (test_hard_reg_class (LD_REGS, operands[0]))
3677             {
3678               *len=2;
3679               return (AS1 (swap,%0) CR_TAB
3680                       AS2 (andi,%0,0x0f));
3681             }
3682           *len = 4;
3683           return (AS1 (lsr,%0) CR_TAB
3684                   AS1 (lsr,%0) CR_TAB
3685                   AS1 (lsr,%0) CR_TAB
3686                   AS1 (lsr,%0));
3687           
3688         case 5:
3689           if (test_hard_reg_class (LD_REGS, operands[0]))
3690             {
3691               *len = 3;
3692               return (AS1 (swap,%0) CR_TAB
3693                       AS1 (lsr,%0)  CR_TAB
3694                       AS2 (andi,%0,0x7));
3695             }
3696           *len = 5;
3697           return (AS1 (lsr,%0) CR_TAB
3698                   AS1 (lsr,%0) CR_TAB
3699                   AS1 (lsr,%0) CR_TAB
3700                   AS1 (lsr,%0) CR_TAB
3701                   AS1 (lsr,%0));
3702           
3703         case 6:
3704           if (test_hard_reg_class (LD_REGS, operands[0]))
3705             {
3706               *len = 4;
3707               return (AS1 (swap,%0) CR_TAB
3708                       AS1 (lsr,%0)  CR_TAB
3709                       AS1 (lsr,%0)  CR_TAB
3710                       AS2 (andi,%0,0x3));
3711             }
3712           *len = 6;
3713           return (AS1 (lsr,%0) CR_TAB
3714                   AS1 (lsr,%0) CR_TAB
3715                   AS1 (lsr,%0) CR_TAB
3716                   AS1 (lsr,%0) CR_TAB
3717                   AS1 (lsr,%0) CR_TAB
3718                   AS1 (lsr,%0));
3719           
3720         case 7:
3721           *len = 3;
3722           return (AS1 (rol,%0) CR_TAB
3723                   AS1 (clr,%0) CR_TAB
3724                   AS1 (rol,%0));
3725         }
3726     }
3727   else if (CONSTANT_P (operands[2]))
3728     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3729   
3730   out_shift_with_cnt (AS1 (lsr,%0),
3731                       insn, operands, len, 1);
3732   return "";
3733 }
3734
3735 /* 16bit logic shift right ((unsigned short)x >> i) */
3736
3737 const char *
3738 lshrhi3_out (rtx insn, rtx operands[], int *len)
3739 {
3740   if (GET_CODE (operands[2]) == CONST_INT)
3741     {
3742       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3743       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3744       int k;
3745       int *t = len;
3746
3747       if (!len)
3748         len = &k;
3749       
3750       switch (INTVAL (operands[2]))
3751         {
3752         case 4:
3753           if (optimize_size && scratch)
3754             break;  /* 5 */
3755           if (ldi_ok)
3756             {
3757               *len = 6;
3758               return (AS1 (swap,%B0)      CR_TAB
3759                       AS1 (swap,%A0)      CR_TAB
3760                       AS2 (andi,%A0,0x0f) CR_TAB
3761                       AS2 (eor,%A0,%B0)   CR_TAB
3762                       AS2 (andi,%B0,0x0f) CR_TAB
3763                       AS2 (eor,%A0,%B0));
3764             }
3765           if (scratch)
3766             {
3767               *len = 7;
3768               return (AS1 (swap,%B0)    CR_TAB
3769                       AS1 (swap,%A0)    CR_TAB
3770                       AS2 (ldi,%3,0x0f) CR_TAB
3771                       AS2 (and,%A0,%3)  CR_TAB
3772                       AS2 (eor,%A0,%B0) CR_TAB
3773                       AS2 (and,%B0,%3)  CR_TAB
3774                       AS2 (eor,%A0,%B0));
3775             }
3776           break;  /* optimize_size ? 6 : 8 */
3777
3778         case 5:
3779           if (optimize_size)
3780             break;  /* scratch ? 5 : 6 */
3781           if (ldi_ok)
3782             {
3783               *len = 8;
3784               return (AS1 (lsr,%B0)       CR_TAB
3785                       AS1 (ror,%A0)       CR_TAB
3786                       AS1 (swap,%B0)      CR_TAB
3787                       AS1 (swap,%A0)      CR_TAB
3788                       AS2 (andi,%A0,0x0f) CR_TAB
3789                       AS2 (eor,%A0,%B0)   CR_TAB
3790                       AS2 (andi,%B0,0x0f) CR_TAB
3791                       AS2 (eor,%A0,%B0));
3792             }
3793           if (scratch)
3794             {
3795               *len = 9;
3796               return (AS1 (lsr,%B0)     CR_TAB
3797                       AS1 (ror,%A0)     CR_TAB
3798                       AS1 (swap,%B0)    CR_TAB
3799                       AS1 (swap,%A0)    CR_TAB
3800                       AS2 (ldi,%3,0x0f) CR_TAB
3801                       AS2 (and,%A0,%3)  CR_TAB
3802                       AS2 (eor,%A0,%B0) CR_TAB
3803                       AS2 (and,%B0,%3)  CR_TAB
3804                       AS2 (eor,%A0,%B0));
3805             }
3806           break;  /* 10 */
3807
3808         case 6:
3809           if (optimize_size)
3810             break;  /* scratch ? 5 : 6 */
3811           *len = 9;
3812           return (AS1 (clr,__tmp_reg__) CR_TAB
3813                   AS1 (lsl,%A0)         CR_TAB
3814                   AS1 (rol,%B0)         CR_TAB
3815                   AS1 (rol,__tmp_reg__) CR_TAB
3816                   AS1 (lsl,%A0)         CR_TAB
3817                   AS1 (rol,%B0)         CR_TAB
3818                   AS1 (rol,__tmp_reg__) CR_TAB
3819                   AS2 (mov,%A0,%B0)     CR_TAB
3820                   AS2 (mov,%B0,__tmp_reg__));
3821
3822         case 7:
3823           *len = 5;
3824           return (AS1 (lsl,%A0)     CR_TAB
3825                   AS2 (mov,%A0,%B0) CR_TAB
3826                   AS1 (rol,%A0)     CR_TAB
3827                   AS2 (sbc,%B0,%B0) CR_TAB
3828                   AS1 (neg,%B0));
3829
3830         case 8:
3831           if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1)
3832             return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
3833                               AS1 (clr,%B0));
3834           else
3835             return *len = 1, AS1 (clr,%B0);
3836
3837         case 9:
3838           *len = 3;
3839           return (AS2 (mov,%A0,%B0) CR_TAB
3840                   AS1 (clr,%B0)     CR_TAB
3841                   AS1 (lsr,%A0));
3842
3843         case 10:
3844           *len = 4;
3845           return (AS2 (mov,%A0,%B0) CR_TAB
3846                   AS1 (clr,%B0)     CR_TAB
3847                   AS1 (lsr,%A0)     CR_TAB
3848                   AS1 (lsr,%A0));
3849
3850         case 11:
3851           *len = 5;
3852           return (AS2 (mov,%A0,%B0) CR_TAB
3853                   AS1 (clr,%B0)     CR_TAB
3854                   AS1 (lsr,%A0)     CR_TAB
3855                   AS1 (lsr,%A0)     CR_TAB
3856                   AS1 (lsr,%A0));
3857
3858         case 12:
3859           if (ldi_ok)
3860             {
3861               *len = 4;
3862               return (AS2 (mov,%A0,%B0) CR_TAB
3863                       AS1 (clr,%B0)     CR_TAB