OSDN Git Service

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