OSDN Git Service

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