OSDN Git Service

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