OSDN Git Service

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