OSDN Git Service

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