OSDN Git Service

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