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