OSDN Git Service

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