OSDN Git Service

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