OSDN Git Service

* config/avr/avr.md (peephole casesi+2): Use -1 instead of 65536.
[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, 2011 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 "insn-codes.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "diagnostic-core.h"
39 #include "obstack.h"
40 #include "function.h"
41 #include "recog.h"
42 #include "optabs.h"
43 #include "ggc.h"
44 #include "langhooks.h"
45 #include "tm_p.h"
46 #include "target.h"
47 #include "target-def.h"
48 #include "params.h"
49 #include "df.h"
50
51 /* Maximal allowed offset for an address in the LD command */
52 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
53
54 /* Return true if STR starts with PREFIX and false, otherwise.  */
55 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
56
57 #define AVR_SECTION_PROGMEM (SECTION_MACH_DEP << 0)
58
59 static void avr_option_override (void);
60 static int avr_naked_function_p (tree);
61 static int interrupt_function_p (tree);
62 static int signal_function_p (tree);
63 static int avr_OS_task_function_p (tree);
64 static int avr_OS_main_function_p (tree);
65 static int avr_regs_to_save (HARD_REG_SET *);
66 static int get_sequence_length (rtx insns);
67 static int sequent_regs_live (void);
68 static const char *ptrreg_to_str (int);
69 static const char *cond_string (enum rtx_code);
70 static int avr_num_arg_regs (enum machine_mode, const_tree);
71
72 static rtx avr_legitimize_address (rtx, rtx, enum machine_mode);
73 static tree avr_handle_progmem_attribute (tree *, tree, tree, int, bool *);
74 static tree avr_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
75 static tree avr_handle_fntype_attribute (tree *, tree, tree, int, bool *);
76 static bool avr_assemble_integer (rtx, unsigned int, int);
77 static void avr_file_start (void);
78 static void avr_file_end (void);
79 static bool avr_legitimate_address_p (enum machine_mode, rtx, bool);
80 static void avr_asm_function_end_prologue (FILE *);
81 static void avr_asm_function_begin_epilogue (FILE *);
82 static bool avr_cannot_modify_jumps_p (void);
83 static rtx avr_function_value (const_tree, const_tree, bool);
84 static rtx avr_libcall_value (enum machine_mode, const_rtx);
85 static bool avr_function_value_regno_p (const unsigned int);
86 static void avr_insert_attributes (tree, tree *);
87 static void avr_asm_init_sections (void);
88 static unsigned int avr_section_type_flags (tree, const char *, int);
89
90 static void avr_reorg (void);
91 static void avr_asm_out_ctor (rtx, int);
92 static void avr_asm_out_dtor (rtx, int);
93 static int avr_register_move_cost (enum machine_mode, reg_class_t, reg_class_t);
94 static int avr_memory_move_cost (enum machine_mode, reg_class_t, bool);
95 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
96                                  int, bool);
97 static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
98 static int avr_address_cost (rtx, bool);
99 static bool avr_return_in_memory (const_tree, const_tree);
100 static struct machine_function * avr_init_machine_status (void);
101 static void avr_init_builtins (void);
102 static rtx avr_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
103 static rtx avr_builtin_setjmp_frame_value (void);
104 static bool avr_hard_regno_scratch_ok (unsigned int);
105 static unsigned int avr_case_values_threshold (void);
106 static bool avr_frame_pointer_required_p (void);
107 static bool avr_can_eliminate (const int, const int);
108 static bool avr_class_likely_spilled_p (reg_class_t c);
109 static rtx avr_function_arg (cumulative_args_t , enum machine_mode,
110                              const_tree, bool);
111 static void avr_function_arg_advance (cumulative_args_t, enum machine_mode,
112                                       const_tree, bool);
113 static bool avr_function_ok_for_sibcall (tree, tree);
114 static void avr_asm_named_section (const char *name, unsigned int flags, tree decl);
115 static void avr_encode_section_info (tree, rtx, int);
116 static section* avr_asm_function_rodata_section (tree);
117 static section* avr_asm_select_section (tree, int, unsigned HOST_WIDE_INT);
118
119 /* Allocate registers from r25 to r8 for parameters for function calls.  */
120 #define FIRST_CUM_REG 26
121
122 /* Temporary register RTX (gen_rtx_REG (QImode, TMP_REGNO)) */
123 static GTY(()) rtx tmp_reg_rtx;
124
125 /* Zeroed register RTX (gen_rtx_REG (QImode, ZERO_REGNO)) */
126 static GTY(()) rtx zero_reg_rtx;
127
128 /* AVR register names {"r0", "r1", ..., "r31"} */
129 static const char *const avr_regnames[] = REGISTER_NAMES;
130
131 /* Preprocessor macros to define depending on MCU type.  */
132 const char *avr_extra_arch_macro;
133
134 /* Current architecture.  */
135 const struct base_arch_s *avr_current_arch;
136
137 /* Current device.  */
138 const struct mcu_type_s *avr_current_device;
139
140 /* Section to put switch tables in.  */
141 static GTY(()) section *progmem_swtable_section;
142
143 /* Unnamed section associated to __attribute__((progmem)) aka. PROGMEM.  */
144 static GTY(()) section *progmem_section;
145
146 /* To track if code will use .bss and/or .data.  */
147 bool avr_need_clear_bss_p = false;
148 bool avr_need_copy_data_p = false;
149
150 /* AVR attributes.  */
151 static const struct attribute_spec avr_attribute_table[] =
152 {
153   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
154        affects_type_identity } */
155   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
156     false },
157   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
158     false },
159   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
160     false },
161   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
162     false },
163   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
164     false },
165   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
166     false },
167   { NULL,        0, 0, false, false, false, NULL, false }
168 };
169 \f
170 /* Initialize the GCC target structure.  */
171 #undef TARGET_ASM_ALIGNED_HI_OP
172 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
173 #undef TARGET_ASM_ALIGNED_SI_OP
174 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
175 #undef TARGET_ASM_UNALIGNED_HI_OP
176 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
177 #undef TARGET_ASM_UNALIGNED_SI_OP
178 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
179 #undef TARGET_ASM_INTEGER
180 #define TARGET_ASM_INTEGER avr_assemble_integer
181 #undef TARGET_ASM_FILE_START
182 #define TARGET_ASM_FILE_START avr_file_start
183 #undef TARGET_ASM_FILE_END
184 #define TARGET_ASM_FILE_END avr_file_end
185
186 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
187 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
188 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
189 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
190
191 #undef TARGET_FUNCTION_VALUE
192 #define TARGET_FUNCTION_VALUE avr_function_value
193 #undef TARGET_LIBCALL_VALUE
194 #define TARGET_LIBCALL_VALUE avr_libcall_value
195 #undef TARGET_FUNCTION_VALUE_REGNO_P
196 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
197
198 #undef TARGET_ATTRIBUTE_TABLE
199 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
200 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
201 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
202 #undef TARGET_INSERT_ATTRIBUTES
203 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
204 #undef TARGET_SECTION_TYPE_FLAGS
205 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
206
207 #undef TARGET_ASM_NAMED_SECTION
208 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
209 #undef TARGET_ASM_INIT_SECTIONS
210 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
211 #undef TARGET_ENCODE_SECTION_INFO
212 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
213 #undef TARGET_ASM_SELECT_SECTION
214 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
215
216 #undef TARGET_REGISTER_MOVE_COST
217 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
218 #undef TARGET_MEMORY_MOVE_COST
219 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
220 #undef TARGET_RTX_COSTS
221 #define TARGET_RTX_COSTS avr_rtx_costs
222 #undef TARGET_ADDRESS_COST
223 #define TARGET_ADDRESS_COST avr_address_cost
224 #undef TARGET_MACHINE_DEPENDENT_REORG
225 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
226 #undef TARGET_FUNCTION_ARG
227 #define TARGET_FUNCTION_ARG avr_function_arg
228 #undef TARGET_FUNCTION_ARG_ADVANCE
229 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
230
231 #undef TARGET_LEGITIMIZE_ADDRESS
232 #define TARGET_LEGITIMIZE_ADDRESS avr_legitimize_address
233
234 #undef TARGET_RETURN_IN_MEMORY
235 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
236
237 #undef TARGET_STRICT_ARGUMENT_NAMING
238 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
239
240 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
241 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
242
243 #undef TARGET_HARD_REGNO_SCRATCH_OK
244 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
245 #undef TARGET_CASE_VALUES_THRESHOLD
246 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
247
248 #undef TARGET_LEGITIMATE_ADDRESS_P
249 #define TARGET_LEGITIMATE_ADDRESS_P avr_legitimate_address_p
250
251 #undef TARGET_FRAME_POINTER_REQUIRED
252 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
253 #undef TARGET_CAN_ELIMINATE
254 #define TARGET_CAN_ELIMINATE avr_can_eliminate
255
256 #undef TARGET_CLASS_LIKELY_SPILLED_P
257 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
258
259 #undef TARGET_OPTION_OVERRIDE
260 #define TARGET_OPTION_OVERRIDE avr_option_override
261
262 #undef TARGET_CANNOT_MODIFY_JUMPS_P
263 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
264
265 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
266 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
267
268 #undef TARGET_INIT_BUILTINS
269 #define TARGET_INIT_BUILTINS avr_init_builtins
270
271 #undef TARGET_EXPAND_BUILTIN
272 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
273
274 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
275 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
276
277 struct gcc_target targetm = TARGET_INITIALIZER;
278 \f
279
280 /* Custom function to replace string prefix.
281
282    Return a ggc-allocated string with strlen (OLD_PREFIX) characters removed
283    from the start of OLD_STR and then prepended with NEW_PREFIX.  */
284
285 static inline const char*
286 avr_replace_prefix (const char *old_str,
287                     const char *old_prefix, const char *new_prefix)
288 {
289   char *new_str;
290   size_t len = strlen (old_str) + strlen (new_prefix) - strlen (old_prefix);
291
292   gcc_assert (strlen (old_prefix) <= strlen (old_str));
293
294   /* Unfortunately, ggc_alloc_string returns a const char* and thus cannot be
295      used here.  */
296      
297   new_str = (char*) ggc_alloc_atomic (1 + len);
298
299   strcat (stpcpy (new_str, new_prefix), old_str + strlen (old_prefix));
300   
301   return (const char*) new_str;
302 }
303
304
305 /* Custom function to count number of set bits.  */
306
307 static inline int
308 avr_popcount (unsigned int val)
309 {
310   int pop = 0;
311
312   while (val)
313     {
314       val &= val-1;
315       pop++;
316     }
317
318   return pop;
319 }
320
321
322 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
323    Return true if the least significant N_BYTES bytes of XVAL all have a
324    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
325    of integers which contains an integer N iff bit N of POP_MASK is set.  */
326    
327 bool
328 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
329 {
330   int i;
331
332   enum machine_mode mode = GET_MODE (xval);
333
334   if (VOIDmode == mode)
335     mode = SImode;
336
337   for (i = 0; i < n_bytes; i++)
338     {
339       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
340       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
341
342       if (0 == (pop_mask & (1 << avr_popcount (val8))))
343         return false;
344     }
345
346   return true;
347 }
348
349 static void
350 avr_option_override (void)
351 {
352   flag_delete_null_pointer_checks = 0;
353
354   avr_current_device = &avr_mcu_types[avr_mcu_index];
355   avr_current_arch = &avr_arch_types[avr_current_device->arch];
356   avr_extra_arch_macro = avr_current_device->macro;
357
358   tmp_reg_rtx  = gen_rtx_REG (QImode, TMP_REGNO);
359   zero_reg_rtx = gen_rtx_REG (QImode, ZERO_REGNO);
360
361   init_machine_status = avr_init_machine_status;
362 }
363
364 /* Function to set up the backend function structure.  */
365
366 static struct machine_function *
367 avr_init_machine_status (void)
368 {
369   return ggc_alloc_cleared_machine_function ();
370 }
371
372 /* Return register class for register R.  */
373
374 enum reg_class
375 avr_regno_reg_class (int r)
376 {
377   static const enum reg_class reg_class_tab[] =
378     {
379       R0_REG,
380       /* r1 - r15 */
381       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
382       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
383       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
384       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
385       /* r16 - r23 */
386       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
387       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
388       /* r24, r25 */
389       ADDW_REGS, ADDW_REGS,
390       /* X: r26, 27 */
391       POINTER_X_REGS, POINTER_X_REGS,
392       /* Y: r28, r29 */
393       POINTER_Y_REGS, POINTER_Y_REGS,
394       /* Z: r30, r31 */
395       POINTER_Z_REGS, POINTER_Z_REGS,
396       /* SP: SPL, SPH */
397       STACK_REG, STACK_REG
398     };
399
400   if (r <= 33)
401     return reg_class_tab[r];
402   
403   return ALL_REGS;
404 }
405
406 /* A helper for the subsequent function attribute used to dig for
407    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
408
409 static inline int
410 avr_lookup_function_attribute1 (const_tree func, const char *name)
411 {
412   if (FUNCTION_DECL == TREE_CODE (func))
413     {
414       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
415         {
416           return true;
417         }
418       
419       func = TREE_TYPE (func);
420     }
421
422   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
423               || TREE_CODE (func) == METHOD_TYPE);
424   
425   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
426 }
427
428 /* Return nonzero if FUNC is a naked function.  */
429
430 static int
431 avr_naked_function_p (tree func)
432 {
433   return avr_lookup_function_attribute1 (func, "naked");
434 }
435
436 /* Return nonzero if FUNC is an interrupt function as specified
437    by the "interrupt" attribute.  */
438
439 static int
440 interrupt_function_p (tree func)
441 {
442   return avr_lookup_function_attribute1 (func, "interrupt");
443 }
444
445 /* Return nonzero if FUNC is a signal function as specified
446    by the "signal" attribute.  */
447
448 static int
449 signal_function_p (tree func)
450 {
451   return avr_lookup_function_attribute1 (func, "signal");
452 }
453
454 /* Return nonzero if FUNC is an OS_task function.  */
455
456 static int
457 avr_OS_task_function_p (tree func)
458 {
459   return avr_lookup_function_attribute1 (func, "OS_task");
460 }
461
462 /* Return nonzero if FUNC is an OS_main function.  */
463
464 static int
465 avr_OS_main_function_p (tree func)
466 {
467   return avr_lookup_function_attribute1 (func, "OS_main");
468 }
469
470 /* Return the number of hard registers to push/pop in the prologue/epilogue
471    of the current function, and optionally store these registers in SET.  */
472
473 static int
474 avr_regs_to_save (HARD_REG_SET *set)
475 {
476   int reg, count;
477   int int_or_sig_p = (interrupt_function_p (current_function_decl)
478                       || signal_function_p (current_function_decl));
479
480   if (set)
481     CLEAR_HARD_REG_SET (*set);
482   count = 0;
483
484   /* No need to save any registers if the function never returns or 
485      has the "OS_task" or "OS_main" attribute.  */
486   if (TREE_THIS_VOLATILE (current_function_decl)
487       || cfun->machine->is_OS_task
488       || cfun->machine->is_OS_main)
489     return 0;
490
491   for (reg = 0; reg < 32; reg++)
492     {
493       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
494          any global register variables.  */
495       if (fixed_regs[reg])
496         continue;
497
498       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
499           || (df_regs_ever_live_p (reg)
500               && (int_or_sig_p || !call_used_regs[reg])
501               && !(frame_pointer_needed
502                    && (reg == REG_Y || reg == (REG_Y+1)))))
503         {
504           if (set)
505             SET_HARD_REG_BIT (*set, reg);
506           count++;
507         }
508     }
509   return count;
510 }
511
512 /* Return true if register FROM can be eliminated via register TO.  */
513
514 bool
515 avr_can_eliminate (const int from, const int to)
516 {
517   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
518           || ((from == FRAME_POINTER_REGNUM 
519                || from == FRAME_POINTER_REGNUM + 1)
520               && !frame_pointer_needed));
521 }
522
523 /* Compute offset between arg_pointer and frame_pointer.  */
524
525 int
526 avr_initial_elimination_offset (int from, int to)
527 {
528   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
529     return 0;
530   else
531     {
532       int offset = frame_pointer_needed ? 2 : 0;
533       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
534
535       offset += avr_regs_to_save (NULL);
536       return get_frame_size () + (avr_pc_size) + 1 + offset;
537     }
538 }
539
540 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
541    frame pointer by +STARTING_FRAME_OFFSET.
542    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
543    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
544
545 rtx avr_builtin_setjmp_frame_value (void)
546 {
547   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
548                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
549 }
550
551 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
552    This is return address of function.  */
553 rtx 
554 avr_return_addr_rtx (int count, rtx tem)
555 {
556   rtx r;
557     
558   /* Can only return this function's return address. Others not supported.  */
559   if (count)
560      return NULL;
561
562   if (AVR_3_BYTE_PC)
563     {
564       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
565       warning (0, "'builtin_return_address' contains only 2 bytes of address");
566     }
567   else
568     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
569
570   r = gen_rtx_PLUS (Pmode, tem, r);
571   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
572   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
573   return  r;
574 }
575
576 /* Return 1 if the function epilogue is just a single "ret".  */
577
578 int
579 avr_simple_epilogue (void)
580 {
581   return (! frame_pointer_needed
582           && get_frame_size () == 0
583           && avr_regs_to_save (NULL) == 0
584           && ! interrupt_function_p (current_function_decl)
585           && ! signal_function_p (current_function_decl)
586           && ! avr_naked_function_p (current_function_decl)
587           && ! TREE_THIS_VOLATILE (current_function_decl));
588 }
589
590 /* This function checks sequence of live registers.  */
591
592 static int
593 sequent_regs_live (void)
594 {
595   int reg;
596   int live_seq=0;
597   int cur_seq=0;
598
599   for (reg = 0; reg < 18; ++reg)
600     {
601       if (fixed_regs[reg])
602         {
603           /* Don't recognize sequences that contain global register
604              variables.  */
605       
606           if (live_seq != 0)
607             return 0;
608           else
609             continue;
610         }
611       
612       if (!call_used_regs[reg])
613         {
614           if (df_regs_ever_live_p (reg))
615             {
616               ++live_seq;
617               ++cur_seq;
618             }
619           else
620             cur_seq = 0;
621         }
622     }
623
624   if (!frame_pointer_needed)
625     {
626       if (df_regs_ever_live_p (REG_Y))
627         {
628           ++live_seq;
629           ++cur_seq;
630         }
631       else
632         cur_seq = 0;
633
634       if (df_regs_ever_live_p (REG_Y+1))
635         {
636           ++live_seq;
637           ++cur_seq;
638         }
639       else
640         cur_seq = 0;
641     }
642   else
643     {
644       cur_seq += 2;
645       live_seq += 2;
646     }
647   return (cur_seq == live_seq) ? live_seq : 0;
648 }
649
650 /* Obtain the length sequence of insns.  */
651
652 int
653 get_sequence_length (rtx insns)
654 {
655   rtx insn;
656   int length;
657   
658   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
659     length += get_attr_length (insn);
660                 
661   return length;
662 }
663
664 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
665
666 rtx
667 avr_incoming_return_addr_rtx (void)
668 {
669   /* The return address is at the top of the stack.  Note that the push
670      was via post-decrement, which means the actual address is off by one.  */
671   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
672 }
673
674 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
675
676 static void
677 emit_push_byte (unsigned regno, bool frame_related_p)
678 {
679   rtx mem, reg, insn;
680
681   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
682   mem = gen_frame_mem (QImode, mem);
683   reg = gen_rtx_REG (QImode, regno);
684
685   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
686   if (frame_related_p)
687     RTX_FRAME_RELATED_P (insn) = 1;
688
689   cfun->machine->stack_usage++;
690 }
691
692
693 /*  Output function prologue.  */
694
695 void
696 expand_prologue (void)
697 {
698   int live_seq;
699   HARD_REG_SET set;
700   int minimize;
701   HOST_WIDE_INT size = get_frame_size();
702   rtx insn;
703   
704   /* Init cfun->machine.  */
705   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
706   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
707   cfun->machine->is_signal = signal_function_p (current_function_decl);
708   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
709   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
710   cfun->machine->stack_usage = 0;
711   
712   /* Prologue: naked.  */
713   if (cfun->machine->is_naked)
714     {
715       return;
716     }
717
718   avr_regs_to_save (&set);
719   live_seq = sequent_regs_live ();
720   minimize = (TARGET_CALL_PROLOGUES
721               && !cfun->machine->is_interrupt
722               && !cfun->machine->is_signal
723               && !cfun->machine->is_OS_task
724               && !cfun->machine->is_OS_main
725               && live_seq);
726
727   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
728     {
729       /* Enable interrupts.  */
730       if (cfun->machine->is_interrupt)
731         emit_insn (gen_enable_interrupt ());
732         
733       /* Push zero reg.  */
734       emit_push_byte (ZERO_REGNO, true);
735
736       /* Push tmp reg.  */
737       emit_push_byte (TMP_REGNO, true);
738
739       /* Push SREG.  */
740       /* ??? There's no dwarf2 column reserved for SREG.  */
741       emit_move_insn (tmp_reg_rtx, gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)));
742       emit_push_byte (TMP_REGNO, false);
743
744       /* Push RAMPZ.  */
745       /* ??? There's no dwarf2 column reserved for RAMPZ.  */
746       if (AVR_HAVE_RAMPZ 
747           && TEST_HARD_REG_BIT (set, REG_Z)
748           && TEST_HARD_REG_BIT (set, REG_Z + 1))
749         {
750           emit_move_insn (tmp_reg_rtx,
751                           gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)));
752           emit_push_byte (TMP_REGNO, false);
753         }
754         
755       /* Clear zero reg.  */
756       emit_move_insn (zero_reg_rtx, const0_rtx);
757
758       /* Prevent any attempt to delete the setting of ZERO_REG!  */
759       emit_use (zero_reg_rtx);
760     }
761   if (minimize && (frame_pointer_needed 
762                    || (AVR_2_BYTE_PC && live_seq > 6)
763                    || live_seq > 7)) 
764     {
765       int first_reg, reg, offset;
766
767       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
768                       gen_int_mode (size, HImode));
769
770       insn = emit_insn (gen_call_prologue_saves
771                         (gen_int_mode (live_seq, HImode),
772                          gen_int_mode (size + live_seq, HImode)));
773       RTX_FRAME_RELATED_P (insn) = 1;
774
775       /* Describe the effect of the unspec_volatile call to prologue_saves.
776          Note that this formulation assumes that add_reg_note pushes the
777          notes to the front.  Thus we build them in the reverse order of
778          how we want dwarf2out to process them.  */
779
780       /* The function does always set frame_pointer_rtx, but whether that
781          is going to be permanent in the function is frame_pointer_needed.  */
782       add_reg_note (insn, REG_CFA_ADJUST_CFA,
783                     gen_rtx_SET (VOIDmode,
784                                  (frame_pointer_needed
785                                   ? frame_pointer_rtx : stack_pointer_rtx),
786                                  plus_constant (stack_pointer_rtx,
787                                                 -(size + live_seq))));
788
789       /* Note that live_seq always contains r28+r29, but the other
790          registers to be saved are all below 18.  */
791       first_reg = 18 - (live_seq - 2);
792
793       for (reg = 29, offset = -live_seq + 1;
794            reg >= first_reg;
795            reg = (reg == 28 ? 17 : reg - 1), ++offset)
796         {
797           rtx m, r;
798
799           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
800           r = gen_rtx_REG (QImode, reg);
801           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
802         }
803
804       cfun->machine->stack_usage += size + live_seq;
805     }
806   else
807     {
808       int reg;
809       for (reg = 0; reg < 32; ++reg)
810         if (TEST_HARD_REG_BIT (set, reg))
811           emit_push_byte (reg, true);
812
813       if (frame_pointer_needed)
814         {
815           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
816             {
817               /* Push frame pointer.  Always be consistent about the
818                  ordering of pushes -- epilogue_restores expects the
819                  register pair to be pushed low byte first.  */
820               emit_push_byte (REG_Y, true);
821               emit_push_byte (REG_Y + 1, true);
822             }
823
824           if (!size)
825             {
826               insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
827               RTX_FRAME_RELATED_P (insn) = 1;
828             }
829           else
830             {
831               /*  Creating a frame can be done by direct manipulation of the
832                   stack or via the frame pointer. These two methods are:
833                     fp=sp
834                     fp-=size
835                     sp=fp
836                   OR
837                     sp-=size
838                     fp=sp
839               the optimum method depends on function type, stack and frame size.
840               To avoid a complex logic, both methods are tested and shortest
841               is selected.  */
842               rtx myfp;
843               rtx fp_plus_insns; 
844
845               if (AVR_HAVE_8BIT_SP)
846                 {
847                   /* The high byte (r29) doesn't change.  Prefer 'subi'
848                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
849                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
850                 }
851               else 
852                 {
853                   /*  Normal sized addition.  */
854                   myfp = frame_pointer_rtx;
855                 }
856
857               /* Method 1-Adjust frame pointer.  */
858               start_sequence ();
859
860               /* Normally the dwarf2out frame-related-expr interpreter does
861                  not expect to have the CFA change once the frame pointer is
862                  set up.  Thus we avoid marking the move insn below and
863                  instead indicate that the entire operation is complete after
864                  the frame pointer subtraction is done.  */
865
866               emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
867
868               insn = emit_move_insn (myfp, plus_constant (myfp, -size));
869               RTX_FRAME_RELATED_P (insn) = 1;
870               add_reg_note (insn, REG_CFA_ADJUST_CFA,
871                             gen_rtx_SET (VOIDmode, frame_pointer_rtx,
872                                          plus_constant (stack_pointer_rtx,
873                                                         -size)));
874
875               /* Copy to stack pointer.  Note that since we've already
876                  changed the CFA to the frame pointer this operation
877                  need not be annotated at all.  */
878               if (AVR_HAVE_8BIT_SP)
879                 {
880                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
881                 }
882               else if (TARGET_NO_INTERRUPTS 
883                        || cfun->machine->is_signal
884                        || cfun->machine->is_OS_main)
885                 {
886                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
887                                                      frame_pointer_rtx));
888                 }
889               else if (cfun->machine->is_interrupt)
890                 {
891                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
892                                                     frame_pointer_rtx));
893                 }
894               else
895                 {
896                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
897                 }
898
899               fp_plus_insns = get_insns ();
900               end_sequence ();
901
902               /* Method 2-Adjust Stack pointer.  */
903               if (size <= 6)
904                 {
905                   rtx sp_plus_insns;
906
907                   start_sequence ();
908
909                   insn = plus_constant (stack_pointer_rtx, -size);
910                   insn = emit_move_insn (stack_pointer_rtx, insn);
911                   RTX_FRAME_RELATED_P (insn) = 1;
912                   
913                   insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
914                   RTX_FRAME_RELATED_P (insn) = 1;
915
916                   sp_plus_insns = get_insns ();
917                   end_sequence ();
918
919                   /* Use shortest method.  */
920                   if (get_sequence_length (sp_plus_insns) 
921                       < get_sequence_length (fp_plus_insns))
922                     emit_insn (sp_plus_insns);
923                   else
924                     emit_insn (fp_plus_insns);
925                 }
926               else
927                 emit_insn (fp_plus_insns);
928
929               cfun->machine->stack_usage += size;
930             }
931         }
932     }
933
934   if (flag_stack_usage_info)
935     current_function_static_stack_size = cfun->machine->stack_usage;
936 }
937
938 /* Output summary at end of function prologue.  */
939
940 static void
941 avr_asm_function_end_prologue (FILE *file)
942 {
943   if (cfun->machine->is_naked)
944     {
945       fputs ("/* prologue: naked */\n", file);
946     }
947   else
948     {
949       if (cfun->machine->is_interrupt)
950         {
951           fputs ("/* prologue: Interrupt */\n", file);
952         }
953       else if (cfun->machine->is_signal)
954         {
955           fputs ("/* prologue: Signal */\n", file);
956         }
957       else
958         fputs ("/* prologue: function */\n", file);
959     }
960   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
961                  get_frame_size());
962   fprintf (file, "/* stack size = %d */\n",
963                  cfun->machine->stack_usage);
964   /* Create symbol stack offset here so all functions have it. Add 1 to stack
965      usage for offset so that SP + .L__stack_offset = return address.  */
966   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
967 }
968
969
970 /* Implement EPILOGUE_USES.  */
971
972 int
973 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
974 {
975   if (reload_completed 
976       && cfun->machine
977       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
978     return 1;
979   return 0;
980 }
981
982 /*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
983
984 static void
985 emit_pop_byte (unsigned regno)
986 {
987   rtx mem, reg;
988
989   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
990   mem = gen_frame_mem (QImode, mem);
991   reg = gen_rtx_REG (QImode, regno);
992
993   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
994 }
995
996 /*  Output RTL epilogue.  */
997
998 void
999 expand_epilogue (bool sibcall_p)
1000 {
1001   int reg;
1002   int live_seq;
1003   HARD_REG_SET set;      
1004   int minimize;
1005   HOST_WIDE_INT size = get_frame_size();
1006   
1007   /* epilogue: naked  */
1008   if (cfun->machine->is_naked)
1009     {
1010       gcc_assert (!sibcall_p);
1011       
1012       emit_jump_insn (gen_return ());
1013       return;
1014     }
1015
1016   avr_regs_to_save (&set);
1017   live_seq = sequent_regs_live ();
1018   minimize = (TARGET_CALL_PROLOGUES
1019               && !cfun->machine->is_interrupt
1020               && !cfun->machine->is_signal
1021               && !cfun->machine->is_OS_task
1022               && !cfun->machine->is_OS_main
1023               && live_seq);
1024   
1025   if (minimize && (frame_pointer_needed || live_seq > 4))
1026     {
1027       if (frame_pointer_needed)
1028         {
1029           /*  Get rid of frame.  */
1030           emit_move_insn(frame_pointer_rtx,
1031                          gen_rtx_PLUS (HImode, frame_pointer_rtx,
1032                                        gen_int_mode (size, HImode)));
1033         }
1034       else
1035         {
1036           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1037         }
1038         
1039       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1040     }
1041   else
1042     {
1043       if (frame_pointer_needed)
1044         {
1045           if (size)
1046             {
1047               /* Try two methods to adjust stack and select shortest.  */
1048               rtx myfp;
1049               rtx fp_plus_insns;
1050
1051               if (AVR_HAVE_8BIT_SP)
1052                 {
1053                   /* The high byte (r29) doesn't change - prefer 'subi' 
1054                      (1 cycle) over 'sbiw' (2 cycles, same size).  */
1055                   myfp = gen_rtx_REG (QImode, FRAME_POINTER_REGNUM);
1056                 }
1057               else 
1058                 {
1059                   /* Normal sized addition.  */
1060                   myfp = frame_pointer_rtx;
1061                 }
1062               
1063               /* Method 1-Adjust frame pointer.  */
1064               start_sequence ();
1065
1066               emit_move_insn (myfp, plus_constant (myfp, size));
1067
1068               /* Copy to stack pointer.  */
1069               if (AVR_HAVE_8BIT_SP)
1070                 {
1071                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1072                 }
1073               else if (TARGET_NO_INTERRUPTS 
1074                        || cfun->machine->is_signal)
1075                 {
1076                   emit_insn (gen_movhi_sp_r_irq_off (stack_pointer_rtx, 
1077                                                      frame_pointer_rtx));
1078                 }
1079               else if (cfun->machine->is_interrupt)
1080                 {
1081                   emit_insn (gen_movhi_sp_r_irq_on (stack_pointer_rtx, 
1082                                                     frame_pointer_rtx));
1083                 }
1084               else
1085                 {
1086                   emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1087                 }
1088
1089               fp_plus_insns = get_insns ();
1090               end_sequence ();        
1091
1092               /* Method 2-Adjust Stack pointer.  */
1093               if (size <= 5)
1094                 {
1095                   rtx sp_plus_insns;
1096
1097                   start_sequence ();
1098
1099                   emit_move_insn (stack_pointer_rtx,
1100                                   plus_constant (stack_pointer_rtx, size));
1101
1102                   sp_plus_insns = get_insns ();
1103                   end_sequence ();
1104
1105                   /* Use shortest method.  */
1106                   if (get_sequence_length (sp_plus_insns) 
1107                       < get_sequence_length (fp_plus_insns))
1108                     emit_insn (sp_plus_insns);
1109                   else
1110                     emit_insn (fp_plus_insns);
1111                 }
1112               else
1113                 emit_insn (fp_plus_insns);
1114             }
1115           if (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1116             {
1117               /* Restore previous frame_pointer.  See expand_prologue for
1118                  rationale for not using pophi.  */
1119               emit_pop_byte (REG_Y + 1);
1120               emit_pop_byte (REG_Y);
1121             }
1122         }
1123
1124       /* Restore used registers.  */
1125       for (reg = 31; reg >= 0; --reg)
1126         if (TEST_HARD_REG_BIT (set, reg))
1127           emit_pop_byte (reg);
1128
1129       if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1130         {
1131           /* Restore RAMPZ using tmp reg as scratch.  */
1132           if (AVR_HAVE_RAMPZ 
1133               && TEST_HARD_REG_BIT (set, REG_Z)
1134               && TEST_HARD_REG_BIT (set, REG_Z + 1))
1135             {
1136               emit_pop_byte (TMP_REGNO);
1137               emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (RAMPZ_ADDR)), 
1138                               tmp_reg_rtx);
1139             }
1140
1141           /* Restore SREG using tmp reg as scratch.  */
1142           emit_pop_byte (TMP_REGNO);
1143       
1144           emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (SREG_ADDR)), 
1145                           tmp_reg_rtx);
1146
1147           /* Restore tmp REG.  */
1148           emit_pop_byte (TMP_REGNO);
1149
1150           /* Restore zero REG.  */
1151           emit_pop_byte (ZERO_REGNO);
1152         }
1153
1154       if (!sibcall_p)
1155         emit_jump_insn (gen_return ());
1156     }
1157 }
1158
1159 /* Output summary messages at beginning of function epilogue.  */
1160
1161 static void
1162 avr_asm_function_begin_epilogue (FILE *file)
1163 {
1164   fprintf (file, "/* epilogue start */\n");
1165 }
1166
1167
1168 /* Implement TARGET_CANNOT_MODITY_JUMPS_P */
1169
1170 static bool
1171 avr_cannot_modify_jumps_p (void)
1172 {
1173
1174   /* Naked Functions must not have any instructions after
1175      their epilogue, see PR42240 */
1176      
1177   if (reload_completed
1178       && cfun->machine
1179       && cfun->machine->is_naked)
1180     {
1181       return true;
1182     }
1183
1184   return false;
1185 }
1186
1187
1188 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1189    machine for a memory operand of mode MODE.  */
1190
1191 bool
1192 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1193 {
1194   enum reg_class r = NO_REGS;
1195   
1196   if (TARGET_ALL_DEBUG)
1197     {
1198       fprintf (stderr, "mode: (%s) %s %s %s %s:",
1199                GET_MODE_NAME(mode),
1200                strict ? "(strict)": "",
1201                reload_completed ? "(reload_completed)": "",
1202                reload_in_progress ? "(reload_in_progress)": "",
1203                reg_renumber ? "(reg_renumber)" : "");
1204       if (GET_CODE (x) == PLUS
1205           && REG_P (XEXP (x, 0))
1206           && GET_CODE (XEXP (x, 1)) == CONST_INT
1207           && INTVAL (XEXP (x, 1)) >= 0
1208           && INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode)
1209           && reg_renumber
1210           )
1211         fprintf (stderr, "(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1212                  true_regnum (XEXP (x, 0)));
1213       debug_rtx (x);
1214     }
1215   
1216   if (REG_P (x) && (strict ? REG_OK_FOR_BASE_STRICT_P (x)
1217                     : REG_OK_FOR_BASE_NOSTRICT_P (x)))
1218     r = POINTER_REGS;
1219   else if (CONSTANT_ADDRESS_P (x))
1220     r = ALL_REGS;
1221   else if (GET_CODE (x) == PLUS
1222            && REG_P (XEXP (x, 0))
1223            && GET_CODE (XEXP (x, 1)) == CONST_INT
1224            && INTVAL (XEXP (x, 1)) >= 0)
1225     {
1226       int fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1227       if (fit)
1228         {
1229           if (! strict
1230               || REGNO (XEXP (x,0)) == REG_X
1231               || REGNO (XEXP (x,0)) == REG_Y
1232               || REGNO (XEXP (x,0)) == REG_Z)
1233             r = BASE_POINTER_REGS;
1234           if (XEXP (x,0) == frame_pointer_rtx
1235               || XEXP (x,0) == arg_pointer_rtx)
1236             r = BASE_POINTER_REGS;
1237         }
1238       else if (frame_pointer_needed && XEXP (x,0) == frame_pointer_rtx)
1239         r = POINTER_Y_REGS;
1240     }
1241   else if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC)
1242            && REG_P (XEXP (x, 0))
1243            && (strict ? REG_OK_FOR_BASE_STRICT_P (XEXP (x, 0))
1244                : REG_OK_FOR_BASE_NOSTRICT_P (XEXP (x, 0))))
1245     {
1246       r = POINTER_REGS;
1247     }
1248   if (TARGET_ALL_DEBUG)
1249     {
1250       fprintf (stderr, "   ret = %c\n", r + '0');
1251     }
1252   return r == NO_REGS ? 0 : (int)r;
1253 }
1254
1255 /* Attempts to replace X with a valid
1256    memory address for an operand of mode MODE  */
1257
1258 rtx
1259 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1260 {
1261   x = oldx;
1262   if (TARGET_ALL_DEBUG)
1263     {
1264       fprintf (stderr, "legitimize_address mode: %s", GET_MODE_NAME(mode));
1265       debug_rtx (oldx);
1266     }
1267   
1268   if (GET_CODE (oldx) == PLUS
1269       && REG_P (XEXP (oldx,0)))
1270     {
1271       if (REG_P (XEXP (oldx,1)))
1272         x = force_reg (GET_MODE (oldx), oldx);
1273       else if (GET_CODE (XEXP (oldx, 1)) == CONST_INT)
1274         {
1275           int offs = INTVAL (XEXP (oldx,1));
1276           if (frame_pointer_rtx != XEXP (oldx,0))
1277             if (offs > MAX_LD_OFFSET (mode))
1278               {
1279                 if (TARGET_ALL_DEBUG)
1280                   fprintf (stderr, "force_reg (big offset)\n");
1281                 x = force_reg (GET_MODE (oldx), oldx);
1282               }
1283         }
1284     }
1285   return x;
1286 }
1287
1288
1289 /* Helper function to print assembler resp. track instruction
1290    sequence lengths.
1291    
1292    If PLEN == NULL:
1293        Output assembler code from template TPL with operands supplied
1294        by OPERANDS.  This is just forwarding to output_asm_insn.
1295    
1296    If PLEN != NULL:
1297        If N_WORDS >= 0  Add N_WORDS to *PLEN.
1298        If N_WORDS < 0   Set *PLEN to -N_WORDS.
1299        Don't output anything.
1300 */
1301
1302 static void
1303 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1304 {
1305   if (NULL == plen)
1306     {
1307       output_asm_insn (tpl, operands);
1308     }
1309   else
1310     {
1311       if (n_words < 0)
1312         *plen = -n_words;
1313       else
1314         *plen += n_words;
1315     }
1316 }
1317
1318
1319 /* Return a pointer register name as a string.  */
1320
1321 static const char *
1322 ptrreg_to_str (int regno)
1323 {
1324   switch (regno)
1325     {
1326     case REG_X: return "X";
1327     case REG_Y: return "Y";
1328     case REG_Z: return "Z";
1329     default:
1330       output_operand_lossage ("address operand requires constraint for X, Y, or Z register");
1331     }
1332   return NULL;
1333 }
1334
1335 /* Return the condition name as a string.
1336    Used in conditional jump constructing  */
1337
1338 static const char *
1339 cond_string (enum rtx_code code)
1340 {
1341   switch (code)
1342     {
1343     case NE:
1344       return "ne";
1345     case EQ:
1346       return "eq";
1347     case GE:
1348       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1349         return "pl";
1350       else
1351         return "ge";
1352     case LT:
1353       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1354         return "mi";
1355       else
1356         return "lt";
1357     case GEU:
1358       return "sh";
1359     case LTU:
1360       return "lo";
1361     default:
1362       gcc_unreachable ();
1363     }
1364 }
1365
1366 /* Output ADDR to FILE as address.  */
1367
1368 void
1369 print_operand_address (FILE *file, rtx addr)
1370 {
1371   switch (GET_CODE (addr))
1372     {
1373     case REG:
1374       fprintf (file, ptrreg_to_str (REGNO (addr)));
1375       break;
1376
1377     case PRE_DEC:
1378       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1379       break;
1380
1381     case POST_INC:
1382       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1383       break;
1384
1385     default:
1386       if (CONSTANT_ADDRESS_P (addr)
1387           && text_segment_operand (addr, VOIDmode))
1388         {
1389           rtx x = addr;
1390           if (GET_CODE (x) == CONST)
1391             x = XEXP (x, 0);
1392           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
1393             {
1394               /* Assembler gs() will implant word address. Make offset 
1395                  a byte offset inside gs() for assembler. This is 
1396                  needed because the more logical (constant+gs(sym)) is not 
1397                  accepted by gas. For 128K and lower devices this is ok. For
1398                  large devices it will create a Trampoline to offset from symbol 
1399                  which may not be what the user really wanted.  */
1400               fprintf (file, "gs(");
1401               output_addr_const (file, XEXP (x,0));
1402               fprintf (file,"+" HOST_WIDE_INT_PRINT_DEC ")", 2 * INTVAL (XEXP (x,1)));
1403               if (AVR_3_BYTE_PC)
1404                 if (warning (0, "pointer offset from symbol maybe incorrect"))
1405                   {
1406                     output_addr_const (stderr, addr);
1407                     fprintf(stderr,"\n");
1408                   }
1409             }
1410           else
1411             {
1412               fprintf (file, "gs(");
1413               output_addr_const (file, addr);
1414               fprintf (file, ")");
1415             }
1416         }
1417       else
1418         output_addr_const (file, addr);
1419     }
1420 }
1421
1422
1423 /* Output X as assembler operand to file FILE.  */
1424      
1425 void
1426 print_operand (FILE *file, rtx x, int code)
1427 {
1428   int abcd = 0;
1429
1430   if (code >= 'A' && code <= 'D')
1431     abcd = code - 'A';
1432
1433   if (code == '~')
1434     {
1435       if (!AVR_HAVE_JMP_CALL)
1436         fputc ('r', file);
1437     }
1438   else if (code == '!')
1439     {
1440       if (AVR_HAVE_EIJMP_EICALL)
1441         fputc ('e', file);
1442     }
1443   else if (REG_P (x))
1444     {
1445       if (x == zero_reg_rtx)
1446         fprintf (file, "__zero_reg__");
1447       else
1448         fprintf (file, reg_names[true_regnum (x) + abcd]);
1449     }
1450   else if (GET_CODE (x) == CONST_INT)
1451     fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) + abcd);
1452   else if (GET_CODE (x) == MEM)
1453     {
1454       rtx addr = XEXP (x,0);
1455       if (code == 'm')
1456         {
1457            if (!CONSTANT_P (addr))
1458             fatal_insn ("bad address, not a constant):", addr);
1459           /* Assembler template with m-code is data - not progmem section */
1460           if (text_segment_operand (addr, VOIDmode))
1461             if (warning ( 0, "accessing data memory with program memory address"))
1462               {
1463                 output_addr_const (stderr, addr);
1464                 fprintf(stderr,"\n");
1465               }
1466           output_addr_const (file, addr);
1467         }
1468       else if (code == 'o')
1469         {
1470           if (GET_CODE (addr) != PLUS)
1471             fatal_insn ("bad address, not (reg+disp):", addr);
1472
1473           print_operand (file, XEXP (addr, 1), 0);
1474         }
1475       else if (code == 'p' || code == 'r')
1476         {
1477           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1478             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1479           
1480           if (code == 'p')
1481             print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1482           else
1483             print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1484         }
1485       else if (GET_CODE (addr) == PLUS)
1486         {
1487           print_operand_address (file, XEXP (addr,0));
1488           if (REGNO (XEXP (addr, 0)) == REG_X)
1489             fatal_insn ("internal compiler error.  Bad address:"
1490                         ,addr);
1491           fputc ('+', file);
1492           print_operand (file, XEXP (addr,1), code);
1493         }
1494       else
1495         print_operand_address (file, addr);
1496     }
1497   else if (code == 'x')
1498     {
1499       /* Constant progmem address - like used in jmp or call */
1500       if (0 == text_segment_operand (x, VOIDmode))
1501             if (warning ( 0, "accessing program  memory with data memory address"))
1502           {
1503             output_addr_const (stderr, x);
1504             fprintf(stderr,"\n");
1505           }
1506       /* Use normal symbol for direct address no linker trampoline needed */
1507       output_addr_const (file, x);
1508     }
1509   else if (GET_CODE (x) == CONST_DOUBLE)
1510     {
1511       long val;
1512       REAL_VALUE_TYPE rv;
1513       if (GET_MODE (x) != SFmode)
1514         fatal_insn ("internal compiler error.  Unknown mode:", x);
1515       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1516       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1517       fprintf (file, "0x%lx", val);
1518     }
1519   else if (code == 'j')
1520     fputs (cond_string (GET_CODE (x)), file);
1521   else if (code == 'k')
1522     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
1523   else
1524     print_operand_address (file, x);
1525 }
1526
1527 /* Update the condition code in the INSN.  */
1528
1529 void
1530 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
1531 {
1532   rtx set;
1533   
1534   switch (get_attr_cc (insn))
1535     {
1536     case CC_NONE:
1537       /* Insn does not affect CC at all.  */
1538       break;
1539
1540     case CC_SET_N:
1541       CC_STATUS_INIT;
1542       break;
1543
1544     case CC_SET_ZN:
1545       set = single_set (insn);
1546       CC_STATUS_INIT;
1547       if (set)
1548         {
1549           cc_status.flags |= CC_NO_OVERFLOW;
1550           cc_status.value1 = SET_DEST (set);
1551         }
1552       break;
1553
1554     case CC_SET_CZN:
1555       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
1556          The V flag may or may not be known but that's ok because
1557          alter_cond will change tests to use EQ/NE.  */
1558       set = single_set (insn);
1559       CC_STATUS_INIT;
1560       if (set)
1561         {
1562           cc_status.value1 = SET_DEST (set);
1563           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1564         }
1565       break;
1566
1567     case CC_COMPARE:
1568       set = single_set (insn);
1569       CC_STATUS_INIT;
1570       if (set)
1571         cc_status.value1 = SET_SRC (set);
1572       break;
1573       
1574     case CC_CLOBBER:
1575       /* Insn doesn't leave CC in a usable state.  */
1576       CC_STATUS_INIT;
1577
1578       /* Correct CC for the ashrqi3 with the shift count as CONST_INT < 6 */
1579       set = single_set (insn);
1580       if (set)
1581         {
1582           rtx src = SET_SRC (set);
1583           
1584           if (GET_CODE (src) == ASHIFTRT
1585               && GET_MODE (src) == QImode)
1586             {
1587               rtx x = XEXP (src, 1);
1588
1589               if (CONST_INT_P (x)
1590                   && IN_RANGE (INTVAL (x), 1, 5))
1591                 {
1592                   cc_status.value1 = SET_DEST (set);
1593                   cc_status.flags |= CC_OVERFLOW_UNUSABLE;
1594                 }
1595             }
1596         }
1597       break;
1598     }
1599 }
1600
1601 /* Choose mode for jump insn:
1602    1 - relative jump in range -63 <= x <= 62 ;
1603    2 - relative jump in range -2046 <= x <= 2045 ;
1604    3 - absolute jump (only for ATmega[16]03).  */
1605
1606 int
1607 avr_jump_mode (rtx x, rtx insn)
1608 {
1609   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
1610                                             ? XEXP (x, 0) : x));
1611   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
1612   int jump_distance = cur_addr - dest_addr;
1613   
1614   if (-63 <= jump_distance && jump_distance <= 62)
1615     return 1;
1616   else if (-2046 <= jump_distance && jump_distance <= 2045)
1617     return 2;
1618   else if (AVR_HAVE_JMP_CALL)
1619     return 3;
1620   
1621   return 2;
1622 }
1623
1624 /* return an AVR condition jump commands.
1625    X is a comparison RTX.
1626    LEN is a number returned by avr_jump_mode function.
1627    if REVERSE nonzero then condition code in X must be reversed.  */
1628
1629 const char *
1630 ret_cond_branch (rtx x, int len, int reverse)
1631 {
1632   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
1633   
1634   switch (cond)
1635     {
1636     case GT:
1637       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1638         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1639                             AS1 (brpl,%0)) :
1640                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1641                             AS1 (brmi,.+2) CR_TAB
1642                             AS1 (rjmp,%0)) :
1643                 (AS1 (breq,.+6) CR_TAB
1644                  AS1 (brmi,.+4) CR_TAB
1645                  AS1 (jmp,%0)));
1646           
1647       else
1648         return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1649                             AS1 (brge,%0)) :
1650                 len == 2 ? (AS1 (breq,.+4) CR_TAB
1651                             AS1 (brlt,.+2) CR_TAB
1652                             AS1 (rjmp,%0)) :
1653                 (AS1 (breq,.+6) CR_TAB
1654                  AS1 (brlt,.+4) CR_TAB
1655                  AS1 (jmp,%0)));
1656     case GTU:
1657       return (len == 1 ? (AS1 (breq,.+2) CR_TAB
1658                           AS1 (brsh,%0)) :
1659               len == 2 ? (AS1 (breq,.+4) CR_TAB
1660                           AS1 (brlo,.+2) CR_TAB
1661                           AS1 (rjmp,%0)) :
1662               (AS1 (breq,.+6) CR_TAB
1663                AS1 (brlo,.+4) CR_TAB
1664                AS1 (jmp,%0)));
1665     case LE:
1666       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1667         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1668                             AS1 (brmi,%0)) :
1669                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1670                             AS1 (brpl,.+2) CR_TAB
1671                             AS1 (rjmp,%0)) :
1672                 (AS1 (breq,.+2) CR_TAB
1673                  AS1 (brpl,.+4) CR_TAB
1674                  AS1 (jmp,%0)));
1675       else
1676         return (len == 1 ? (AS1 (breq,%0) CR_TAB
1677                             AS1 (brlt,%0)) :
1678                 len == 2 ? (AS1 (breq,.+2) CR_TAB
1679                             AS1 (brge,.+2) CR_TAB
1680                             AS1 (rjmp,%0)) :
1681                 (AS1 (breq,.+2) CR_TAB
1682                  AS1 (brge,.+4) CR_TAB
1683                  AS1 (jmp,%0)));
1684     case LEU:
1685       return (len == 1 ? (AS1 (breq,%0) CR_TAB
1686                           AS1 (brlo,%0)) :
1687               len == 2 ? (AS1 (breq,.+2) CR_TAB
1688                           AS1 (brsh,.+2) CR_TAB
1689                           AS1 (rjmp,%0)) :
1690               (AS1 (breq,.+2) CR_TAB
1691                AS1 (brsh,.+4) CR_TAB
1692                AS1 (jmp,%0)));
1693     default:
1694       if (reverse)
1695         {
1696           switch (len)
1697             {
1698             case 1:
1699               return AS1 (br%k1,%0);
1700             case 2:
1701               return (AS1 (br%j1,.+2) CR_TAB
1702                       AS1 (rjmp,%0));
1703             default:
1704               return (AS1 (br%j1,.+4) CR_TAB
1705                       AS1 (jmp,%0));
1706             }
1707         }
1708         else
1709           {
1710             switch (len)
1711               {
1712               case 1:
1713                 return AS1 (br%j1,%0);
1714               case 2:
1715                 return (AS1 (br%k1,.+2) CR_TAB
1716                         AS1 (rjmp,%0));
1717               default:
1718                 return (AS1 (br%k1,.+4) CR_TAB
1719                         AS1 (jmp,%0));
1720               }
1721           }
1722     }
1723   return "";
1724 }
1725
1726 /* Output insn cost for next insn.  */
1727
1728 void
1729 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
1730                     int num_operands ATTRIBUTE_UNUSED)
1731 {
1732   if (TARGET_ALL_DEBUG)
1733     {
1734       rtx set = single_set (insn);
1735
1736       if (set)
1737         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
1738                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
1739       else
1740         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
1741                  rtx_cost (PATTERN (insn), INSN, 0,
1742                            optimize_insn_for_speed_p()));
1743     }
1744 }
1745
1746 /* Return 0 if undefined, 1 if always true or always false.  */
1747
1748 int
1749 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
1750 {
1751   unsigned int max = (mode == QImode ? 0xff :
1752                       mode == HImode ? 0xffff :
1753                       mode == SImode ? 0xffffffff : 0);
1754   if (max && op && GET_CODE (x) == CONST_INT)
1755     {
1756       if (unsigned_condition (op) != op)
1757         max >>= 1;
1758
1759       if (max != (INTVAL (x) & max)
1760           && INTVAL (x) != 0xff)
1761         return 1;
1762     }
1763   return 0;
1764 }
1765
1766
1767 /* Returns nonzero if REGNO is the number of a hard
1768    register in which function arguments are sometimes passed.  */
1769
1770 int
1771 function_arg_regno_p(int r)
1772 {
1773   return (r >= 8 && r <= 25);
1774 }
1775
1776 /* Initializing the variable cum for the state at the beginning
1777    of the argument list.  */
1778
1779 void
1780 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
1781                       tree fndecl ATTRIBUTE_UNUSED)
1782 {
1783   cum->nregs = 18;
1784   cum->regno = FIRST_CUM_REG;
1785   if (!libname && stdarg_p (fntype))
1786     cum->nregs = 0;
1787
1788   /* Assume the calle may be tail called */
1789   
1790   cfun->machine->sibcall_fails = 0;
1791 }
1792
1793 /* Returns the number of registers to allocate for a function argument.  */
1794
1795 static int
1796 avr_num_arg_regs (enum machine_mode mode, const_tree type)
1797 {
1798   int size;
1799
1800   if (mode == BLKmode)
1801     size = int_size_in_bytes (type);
1802   else
1803     size = GET_MODE_SIZE (mode);
1804
1805   /* Align all function arguments to start in even-numbered registers.
1806      Odd-sized arguments leave holes above them.  */
1807
1808   return (size + 1) & ~1;
1809 }
1810
1811 /* Controls whether a function argument is passed
1812    in a register, and which register.  */
1813
1814 static rtx
1815 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
1816                   const_tree type, bool named ATTRIBUTE_UNUSED)
1817 {
1818   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1819   int bytes = avr_num_arg_regs (mode, type);
1820
1821   if (cum->nregs && bytes <= cum->nregs)
1822     return gen_rtx_REG (mode, cum->regno - bytes);
1823
1824   return NULL_RTX;
1825 }
1826
1827 /* Update the summarizer variable CUM to advance past an argument
1828    in the argument list.  */
1829    
1830 static void
1831 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
1832                           const_tree type, bool named ATTRIBUTE_UNUSED)
1833 {
1834   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
1835   int bytes = avr_num_arg_regs (mode, type);
1836
1837   cum->nregs -= bytes;
1838   cum->regno -= bytes;
1839
1840   /* A parameter is being passed in a call-saved register. As the original
1841      contents of these regs has to be restored before leaving the function,
1842      a function must not pass arguments in call-saved regs in order to get
1843      tail-called. */
1844   
1845   if (cum->regno >= 8
1846       && cum->nregs >= 0
1847       && !call_used_regs[cum->regno])
1848     {
1849       /* FIXME: We ship info on failing tail-call in struct machine_function.
1850          This uses internals of calls.c:expand_call() and the way args_so_far
1851          is used. targetm.function_ok_for_sibcall() needs to be extended to
1852          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
1853          dependent so that such an extension is not wanted. */
1854       
1855       cfun->machine->sibcall_fails = 1;
1856     }
1857
1858   /* Test if all registers needed by the ABI are actually available.  If the
1859      user has fixed a GPR needed to pass an argument, an (implicit) function
1860      call will clobber that fixed register.  See PR45099 for an example.  */
1861   
1862   if (cum->regno >= 8
1863       && cum->nregs >= 0)
1864     {
1865       int regno;
1866
1867       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
1868         if (fixed_regs[regno])
1869           warning (0, "fixed register %s used to pass parameter to function",
1870                    reg_names[regno]);
1871     }
1872       
1873   if (cum->nregs <= 0)
1874     {
1875       cum->nregs = 0;
1876       cum->regno = FIRST_CUM_REG;
1877     }
1878 }
1879
1880 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
1881 /* Decide whether we can make a sibling call to a function.  DECL is the
1882    declaration of the function being targeted by the call and EXP is the
1883    CALL_EXPR representing the call. */
1884
1885 static bool
1886 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
1887 {
1888   tree fntype_callee;
1889
1890   /* Tail-calling must fail if callee-saved regs are used to pass
1891      function args.  We must not tail-call when `epilogue_restores'
1892      is used.  Unfortunately, we cannot tell at this point if that
1893      actually will happen or not, and we cannot step back from
1894      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
1895   
1896   if (cfun->machine->sibcall_fails
1897       || TARGET_CALL_PROLOGUES)
1898     {
1899       return false;
1900     }
1901   
1902   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
1903
1904   if (decl_callee)
1905     {
1906       decl_callee = TREE_TYPE (decl_callee);
1907     }
1908   else
1909     {
1910       decl_callee = fntype_callee;
1911       
1912       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
1913              && METHOD_TYPE != TREE_CODE (decl_callee))
1914         {
1915           decl_callee = TREE_TYPE (decl_callee);
1916         }
1917     }
1918
1919   /* Ensure that caller and callee have compatible epilogues */
1920   
1921   if (interrupt_function_p (current_function_decl)
1922       || signal_function_p (current_function_decl)
1923       || avr_naked_function_p (decl_callee)
1924       || avr_naked_function_p (current_function_decl)
1925       /* FIXME: For OS_task and OS_main, we are over-conservative.
1926          This is due to missing documentation of these attributes
1927          and what they actually should do and should not do. */
1928       || (avr_OS_task_function_p (decl_callee)
1929           != avr_OS_task_function_p (current_function_decl))
1930       || (avr_OS_main_function_p (decl_callee)
1931           != avr_OS_main_function_p (current_function_decl)))
1932     {
1933       return false;
1934     }
1935  
1936   return true;
1937 }
1938
1939 /***********************************************************************
1940   Functions for outputting various mov's for a various modes
1941 ************************************************************************/
1942 const char *
1943 output_movqi (rtx insn, rtx operands[], int *l)
1944 {
1945   int dummy;
1946   rtx dest = operands[0];
1947   rtx src = operands[1];
1948   int *real_l = l;
1949   
1950   if (!l)
1951     l = &dummy;
1952
1953   *l = 1;
1954   
1955   if (register_operand (dest, QImode))
1956     {
1957       if (register_operand (src, QImode)) /* mov r,r */
1958         {
1959           if (test_hard_reg_class (STACK_REG, dest))
1960             return AS2 (out,%0,%1);
1961           else if (test_hard_reg_class (STACK_REG, src))
1962             return AS2 (in,%0,%1);
1963           
1964           return AS2 (mov,%0,%1);
1965         }
1966       else if (CONSTANT_P (src))
1967         {
1968           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
1969             return AS2 (ldi,%0,lo8(%1));
1970           
1971           if (GET_CODE (src) == CONST_INT)
1972             {
1973               if (src == const0_rtx) /* mov r,L */
1974                 return AS1 (clr,%0);
1975               else if (src == const1_rtx)
1976                 {
1977                   *l = 2;
1978                   return (AS1 (clr,%0) CR_TAB
1979                           AS1 (inc,%0));
1980                 }
1981               else if (src == constm1_rtx)
1982                 {
1983                   /* Immediate constants -1 to any register */
1984                   *l = 2;
1985                   return (AS1 (clr,%0) CR_TAB
1986                           AS1 (dec,%0));
1987                 }
1988               else
1989                 {
1990                   int bit_nr = exact_log2 (INTVAL (src));
1991
1992                   if (bit_nr >= 0)
1993                     {
1994                       *l = 3;
1995                       if (!real_l)
1996                         output_asm_insn ((AS1 (clr,%0) CR_TAB
1997                                           "set"), operands);
1998                       if (!real_l)
1999                         avr_output_bld (operands, bit_nr);
2000
2001                       return "";
2002                     }
2003                 }
2004             }
2005           
2006           /* Last resort, larger than loading from memory.  */
2007           *l = 4;
2008           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2009                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2010                   AS2 (mov,%0,r31)          CR_TAB
2011                   AS2 (mov,r31,__tmp_reg__));
2012         }
2013       else if (GET_CODE (src) == MEM)
2014         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
2015     }
2016   else if (GET_CODE (dest) == MEM)
2017     {
2018       const char *templ;
2019
2020       if (src == const0_rtx)
2021         operands[1] = zero_reg_rtx;
2022
2023       templ = out_movqi_mr_r (insn, operands, real_l);
2024
2025       if (!real_l)
2026         output_asm_insn (templ, operands);
2027
2028       operands[1] = src;
2029     }
2030   return "";
2031 }
2032
2033
2034 const char *
2035 output_movhi (rtx insn, rtx operands[], int *l)
2036 {
2037   int dummy;
2038   rtx dest = operands[0];
2039   rtx src = operands[1];
2040   int *real_l = l;
2041   
2042   if (!l)
2043     l = &dummy;
2044   
2045   if (register_operand (dest, HImode))
2046     {
2047       if (register_operand (src, HImode)) /* mov r,r */
2048         {
2049           if (test_hard_reg_class (STACK_REG, dest))
2050             {
2051               if (AVR_HAVE_8BIT_SP)
2052                 return *l = 1, AS2 (out,__SP_L__,%A1);
2053               /* Use simple load of stack pointer if no interrupts are 
2054                  used.  */
2055               else if (TARGET_NO_INTERRUPTS)
2056                 return *l = 2, (AS2 (out,__SP_H__,%B1) CR_TAB
2057                                 AS2 (out,__SP_L__,%A1));
2058               *l = 5;
2059               return (AS2 (in,__tmp_reg__,__SREG__)  CR_TAB
2060                       "cli"                          CR_TAB
2061                       AS2 (out,__SP_H__,%B1)         CR_TAB
2062                       AS2 (out,__SREG__,__tmp_reg__) CR_TAB
2063                       AS2 (out,__SP_L__,%A1));
2064             }
2065           else if (test_hard_reg_class (STACK_REG, src))
2066             {
2067               *l = 2;   
2068               return (AS2 (in,%A0,__SP_L__) CR_TAB
2069                       AS2 (in,%B0,__SP_H__));
2070             }
2071
2072           if (AVR_HAVE_MOVW)
2073             {
2074               *l = 1;
2075               return (AS2 (movw,%0,%1));
2076             }
2077           else
2078             {
2079               *l = 2;
2080               return (AS2 (mov,%A0,%A1) CR_TAB
2081                       AS2 (mov,%B0,%B1));
2082             }
2083         }
2084       else if (CONSTANT_P (src))
2085         {
2086           return output_reload_inhi (operands, NULL, real_l);
2087         }
2088       else if (GET_CODE (src) == MEM)
2089         return out_movhi_r_mr (insn, operands, real_l); /* mov r,m */
2090     }
2091   else if (GET_CODE (dest) == MEM)
2092     {
2093       const char *templ;
2094
2095       if (src == const0_rtx)
2096         operands[1] = zero_reg_rtx;
2097
2098       templ = out_movhi_mr_r (insn, operands, real_l);
2099
2100       if (!real_l)
2101         output_asm_insn (templ, operands);
2102
2103       operands[1] = src;
2104       return "";
2105     }
2106   fatal_insn ("invalid insn:", insn);
2107   return "";
2108 }
2109
2110 const char *
2111 out_movqi_r_mr (rtx insn, rtx op[], int *l)
2112 {
2113   rtx dest = op[0];
2114   rtx src = op[1];
2115   rtx x = XEXP (src, 0);
2116   int dummy;
2117   
2118   if (!l)
2119     l = &dummy;
2120   
2121   if (CONSTANT_ADDRESS_P (x))
2122     {
2123       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2124         {
2125           *l = 1;
2126           return AS2 (in,%0,__SREG__);
2127         }
2128       if (optimize > 0 && io_address_operand (x, QImode))
2129         {
2130           *l = 1;
2131           return AS2 (in,%0,%m1-0x20);
2132         }
2133       *l = 2;
2134       return AS2 (lds,%0,%m1);
2135     }
2136   /* memory access by reg+disp */
2137   else if (GET_CODE (x) == PLUS
2138       && REG_P (XEXP (x,0))
2139       && GET_CODE (XEXP (x,1)) == CONST_INT)
2140     {
2141       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (src))) >= 63)
2142         {
2143           int disp = INTVAL (XEXP (x,1));
2144           if (REGNO (XEXP (x,0)) != REG_Y)
2145             fatal_insn ("incorrect insn:",insn);
2146
2147           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2148             return *l = 3, (AS2 (adiw,r28,%o1-63) CR_TAB
2149                             AS2 (ldd,%0,Y+63)     CR_TAB
2150                             AS2 (sbiw,r28,%o1-63));
2151
2152           return *l = 5, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2153                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2154                           AS2 (ld,%0,Y)            CR_TAB
2155                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2156                           AS2 (sbci,r29,hi8(%o1)));
2157         }
2158       else if (REGNO (XEXP (x,0)) == REG_X)
2159         {
2160           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2161              it but I have this situation with extremal optimizing options.  */
2162           if (reg_overlap_mentioned_p (dest, XEXP (x,0))
2163               || reg_unused_after (insn, XEXP (x,0)))
2164             return *l = 2, (AS2 (adiw,r26,%o1) CR_TAB
2165                             AS2 (ld,%0,X));
2166
2167           return *l = 3, (AS2 (adiw,r26,%o1) CR_TAB
2168                           AS2 (ld,%0,X)      CR_TAB
2169                           AS2 (sbiw,r26,%o1));
2170         }
2171       *l = 1;
2172       return AS2 (ldd,%0,%1);
2173     }
2174   *l = 1;
2175   return AS2 (ld,%0,%1);
2176 }
2177
2178 const char *
2179 out_movhi_r_mr (rtx insn, rtx op[], int *l)
2180 {
2181   rtx dest = op[0];
2182   rtx src = op[1];
2183   rtx base = XEXP (src, 0);
2184   int reg_dest = true_regnum (dest);
2185   int reg_base = true_regnum (base);
2186   /* "volatile" forces reading low byte first, even if less efficient,
2187      for correct operation with 16-bit I/O registers.  */
2188   int mem_volatile_p = MEM_VOLATILE_P (src);
2189   int tmp;
2190
2191   if (!l)
2192     l = &tmp;
2193
2194   if (reg_base > 0)
2195     {
2196       if (reg_dest == reg_base)         /* R = (R) */
2197         {
2198           *l = 3;
2199           return (AS2 (ld,__tmp_reg__,%1+) CR_TAB
2200                   AS2 (ld,%B0,%1) CR_TAB
2201                   AS2 (mov,%A0,__tmp_reg__));
2202         }
2203       else if (reg_base == REG_X)        /* (R26) */
2204         {
2205           if (reg_unused_after (insn, base))
2206             {
2207               *l = 2;
2208               return (AS2 (ld,%A0,X+) CR_TAB
2209                       AS2 (ld,%B0,X));
2210             }
2211           *l  = 3;
2212           return (AS2 (ld,%A0,X+) CR_TAB
2213                   AS2 (ld,%B0,X) CR_TAB
2214                   AS2 (sbiw,r26,1));
2215         }
2216       else                      /* (R)  */
2217         {
2218           *l = 2;
2219           return (AS2 (ld,%A0,%1)    CR_TAB
2220                   AS2 (ldd,%B0,%1+1));
2221         }
2222     }
2223   else if (GET_CODE (base) == PLUS) /* (R + i) */
2224     {
2225       int disp = INTVAL (XEXP (base, 1));
2226       int reg_base = true_regnum (XEXP (base, 0));
2227       
2228       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2229         {
2230           if (REGNO (XEXP (base, 0)) != REG_Y)
2231             fatal_insn ("incorrect insn:",insn);
2232           
2233           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2234             return *l = 4, (AS2 (adiw,r28,%o1-62) CR_TAB
2235                             AS2 (ldd,%A0,Y+62)    CR_TAB
2236                             AS2 (ldd,%B0,Y+63)    CR_TAB
2237                             AS2 (sbiw,r28,%o1-62));
2238
2239           return *l = 6, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2240                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2241                           AS2 (ld,%A0,Y)           CR_TAB
2242                           AS2 (ldd,%B0,Y+1)        CR_TAB
2243                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2244                           AS2 (sbci,r29,hi8(%o1)));
2245         }
2246       if (reg_base == REG_X)
2247         {
2248           /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
2249              it but I have this situation with extremal
2250              optimization options.  */
2251           
2252           *l = 4;
2253           if (reg_base == reg_dest)
2254             return (AS2 (adiw,r26,%o1)      CR_TAB
2255                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2256                     AS2 (ld,%B0,X)          CR_TAB
2257                     AS2 (mov,%A0,__tmp_reg__));
2258
2259           return (AS2 (adiw,r26,%o1) CR_TAB
2260                   AS2 (ld,%A0,X+)    CR_TAB
2261                   AS2 (ld,%B0,X)     CR_TAB
2262                   AS2 (sbiw,r26,%o1+1));
2263         }
2264
2265       if (reg_base == reg_dest)
2266         {
2267           *l = 3;
2268           return (AS2 (ldd,__tmp_reg__,%A1) CR_TAB
2269                   AS2 (ldd,%B0,%B1)         CR_TAB
2270                   AS2 (mov,%A0,__tmp_reg__));
2271         }
2272       
2273       *l = 2;
2274       return (AS2 (ldd,%A0,%A1) CR_TAB
2275               AS2 (ldd,%B0,%B1));
2276     }
2277   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2278     {
2279       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2280         fatal_insn ("incorrect insn:", insn);
2281
2282       if (mem_volatile_p)
2283         {
2284           if (REGNO (XEXP (base, 0)) == REG_X)
2285             {
2286               *l = 4;
2287               return (AS2 (sbiw,r26,2)  CR_TAB
2288                       AS2 (ld,%A0,X+)   CR_TAB
2289                       AS2 (ld,%B0,X)    CR_TAB
2290                       AS2 (sbiw,r26,1));
2291             }
2292           else
2293             {
2294               *l = 3;
2295               return (AS2 (sbiw,%r1,2)   CR_TAB
2296                       AS2 (ld,%A0,%p1)  CR_TAB
2297                       AS2 (ldd,%B0,%p1+1));
2298             }
2299         }
2300
2301       *l = 2;
2302       return (AS2 (ld,%B0,%1) CR_TAB
2303               AS2 (ld,%A0,%1));
2304     }
2305   else if (GET_CODE (base) == POST_INC) /* (R++) */
2306     {
2307       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
2308         fatal_insn ("incorrect insn:", insn);
2309
2310       *l = 2;
2311       return (AS2 (ld,%A0,%1)  CR_TAB
2312               AS2 (ld,%B0,%1));
2313     }
2314   else if (CONSTANT_ADDRESS_P (base))
2315     {
2316       if (optimize > 0 && io_address_operand (base, HImode))
2317         {
2318           *l = 2;
2319           return (AS2 (in,%A0,%m1-0x20) CR_TAB
2320                   AS2 (in,%B0,%m1+1-0x20));
2321         }
2322       *l = 4;
2323       return (AS2 (lds,%A0,%m1) CR_TAB
2324               AS2 (lds,%B0,%m1+1));
2325     }
2326   
2327   fatal_insn ("unknown move insn:",insn);
2328   return "";
2329 }
2330
2331 const char *
2332 out_movsi_r_mr (rtx insn, rtx op[], int *l)
2333 {
2334   rtx dest = op[0];
2335   rtx src = op[1];
2336   rtx base = XEXP (src, 0);
2337   int reg_dest = true_regnum (dest);
2338   int reg_base = true_regnum (base);
2339   int tmp;
2340
2341   if (!l)
2342     l = &tmp;
2343   
2344   if (reg_base > 0)
2345     {
2346       if (reg_base == REG_X)        /* (R26) */
2347         {
2348           if (reg_dest == REG_X)
2349             /* "ld r26,-X" is undefined */
2350             return *l=7, (AS2 (adiw,r26,3)        CR_TAB
2351                           AS2 (ld,r29,X)          CR_TAB
2352                           AS2 (ld,r28,-X)         CR_TAB
2353                           AS2 (ld,__tmp_reg__,-X) CR_TAB
2354                           AS2 (sbiw,r26,1)        CR_TAB
2355                           AS2 (ld,r26,X)          CR_TAB
2356                           AS2 (mov,r27,__tmp_reg__));
2357           else if (reg_dest == REG_X - 2)
2358             return *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2359                           AS2 (ld,%B0,X+) CR_TAB
2360                           AS2 (ld,__tmp_reg__,X+)  CR_TAB
2361                           AS2 (ld,%D0,X)  CR_TAB
2362                           AS2 (mov,%C0,__tmp_reg__));
2363           else if (reg_unused_after (insn, base))
2364             return  *l=4, (AS2 (ld,%A0,X+)  CR_TAB
2365                            AS2 (ld,%B0,X+) CR_TAB
2366                            AS2 (ld,%C0,X+) CR_TAB
2367                            AS2 (ld,%D0,X));
2368           else
2369             return  *l=5, (AS2 (ld,%A0,X+)  CR_TAB
2370                            AS2 (ld,%B0,X+) CR_TAB
2371                            AS2 (ld,%C0,X+) CR_TAB
2372                            AS2 (ld,%D0,X)  CR_TAB
2373                            AS2 (sbiw,r26,3));
2374         }
2375       else
2376         {
2377           if (reg_dest == reg_base)
2378             return *l=5, (AS2 (ldd,%D0,%1+3) CR_TAB
2379                           AS2 (ldd,%C0,%1+2) CR_TAB
2380                           AS2 (ldd,__tmp_reg__,%1+1)  CR_TAB
2381                           AS2 (ld,%A0,%1)  CR_TAB
2382                           AS2 (mov,%B0,__tmp_reg__));
2383           else if (reg_base == reg_dest + 2)
2384             return *l=5, (AS2 (ld ,%A0,%1)    CR_TAB
2385                           AS2 (ldd,%B0,%1+1) CR_TAB
2386                           AS2 (ldd,__tmp_reg__,%1+2)  CR_TAB
2387                           AS2 (ldd,%D0,%1+3) CR_TAB
2388                           AS2 (mov,%C0,__tmp_reg__));
2389           else
2390             return *l=4, (AS2 (ld ,%A0,%1)   CR_TAB
2391                           AS2 (ldd,%B0,%1+1) CR_TAB
2392                           AS2 (ldd,%C0,%1+2) CR_TAB
2393                           AS2 (ldd,%D0,%1+3));
2394         }
2395     }
2396   else if (GET_CODE (base) == PLUS) /* (R + i) */
2397     {
2398       int disp = INTVAL (XEXP (base, 1));
2399       
2400       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2401         {
2402           if (REGNO (XEXP (base, 0)) != REG_Y)
2403             fatal_insn ("incorrect insn:",insn);
2404
2405           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2406             return *l = 6, (AS2 (adiw,r28,%o1-60) CR_TAB
2407                             AS2 (ldd,%A0,Y+60)    CR_TAB
2408                             AS2 (ldd,%B0,Y+61)    CR_TAB
2409                             AS2 (ldd,%C0,Y+62)    CR_TAB
2410                             AS2 (ldd,%D0,Y+63)    CR_TAB
2411                             AS2 (sbiw,r28,%o1-60));
2412
2413           return *l = 8, (AS2 (subi,r28,lo8(-%o1)) CR_TAB
2414                           AS2 (sbci,r29,hi8(-%o1)) CR_TAB
2415                           AS2 (ld,%A0,Y)           CR_TAB
2416                           AS2 (ldd,%B0,Y+1)        CR_TAB
2417                           AS2 (ldd,%C0,Y+2)        CR_TAB
2418                           AS2 (ldd,%D0,Y+3)        CR_TAB
2419                           AS2 (subi,r28,lo8(%o1))  CR_TAB
2420                           AS2 (sbci,r29,hi8(%o1)));
2421         }
2422
2423       reg_base = true_regnum (XEXP (base, 0));
2424       if (reg_base == REG_X)
2425         {
2426           /* R = (X + d) */
2427           if (reg_dest == REG_X)
2428             {
2429               *l = 7;
2430               /* "ld r26,-X" is undefined */
2431               return (AS2 (adiw,r26,%o1+3)    CR_TAB
2432                       AS2 (ld,r29,X)          CR_TAB
2433                       AS2 (ld,r28,-X)         CR_TAB
2434                       AS2 (ld,__tmp_reg__,-X) CR_TAB
2435                       AS2 (sbiw,r26,1)        CR_TAB
2436                       AS2 (ld,r26,X)          CR_TAB
2437                       AS2 (mov,r27,__tmp_reg__));
2438             }
2439           *l = 6;
2440           if (reg_dest == REG_X - 2)
2441             return (AS2 (adiw,r26,%o1)      CR_TAB
2442                     AS2 (ld,r24,X+)         CR_TAB
2443                     AS2 (ld,r25,X+)         CR_TAB
2444                     AS2 (ld,__tmp_reg__,X+) CR_TAB
2445                     AS2 (ld,r27,X)          CR_TAB
2446                     AS2 (mov,r26,__tmp_reg__));
2447
2448           return (AS2 (adiw,r26,%o1) CR_TAB
2449                   AS2 (ld,%A0,X+)    CR_TAB
2450                   AS2 (ld,%B0,X+)    CR_TAB
2451                   AS2 (ld,%C0,X+)    CR_TAB
2452                   AS2 (ld,%D0,X)     CR_TAB
2453                   AS2 (sbiw,r26,%o1+3));
2454         }
2455       if (reg_dest == reg_base)
2456         return *l=5, (AS2 (ldd,%D0,%D1) CR_TAB
2457                       AS2 (ldd,%C0,%C1) CR_TAB
2458                       AS2 (ldd,__tmp_reg__,%B1)  CR_TAB
2459                       AS2 (ldd,%A0,%A1) CR_TAB
2460                       AS2 (mov,%B0,__tmp_reg__));
2461       else if (reg_dest == reg_base - 2)
2462         return *l=5, (AS2 (ldd,%A0,%A1) CR_TAB
2463                       AS2 (ldd,%B0,%B1) CR_TAB
2464                       AS2 (ldd,__tmp_reg__,%C1)  CR_TAB
2465                       AS2 (ldd,%D0,%D1) CR_TAB
2466                       AS2 (mov,%C0,__tmp_reg__));
2467       return *l=4, (AS2 (ldd,%A0,%A1) CR_TAB
2468                     AS2 (ldd,%B0,%B1) CR_TAB
2469                     AS2 (ldd,%C0,%C1) CR_TAB
2470                     AS2 (ldd,%D0,%D1));
2471     }
2472   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2473     return *l=4, (AS2 (ld,%D0,%1) CR_TAB
2474                   AS2 (ld,%C0,%1) CR_TAB
2475                   AS2 (ld,%B0,%1) CR_TAB
2476                   AS2 (ld,%A0,%1));
2477   else if (GET_CODE (base) == POST_INC) /* (R++) */
2478     return *l=4, (AS2 (ld,%A0,%1) CR_TAB
2479                   AS2 (ld,%B0,%1) CR_TAB
2480                   AS2 (ld,%C0,%1) CR_TAB
2481                   AS2 (ld,%D0,%1));
2482   else if (CONSTANT_ADDRESS_P (base))
2483       return *l=8, (AS2 (lds,%A0,%m1) CR_TAB
2484                     AS2 (lds,%B0,%m1+1) CR_TAB
2485                     AS2 (lds,%C0,%m1+2) CR_TAB
2486                     AS2 (lds,%D0,%m1+3));
2487     
2488   fatal_insn ("unknown move insn:",insn);
2489   return "";
2490 }
2491
2492 const char *
2493 out_movsi_mr_r (rtx insn, rtx op[], int *l)
2494 {
2495   rtx dest = op[0];
2496   rtx src = op[1];
2497   rtx base = XEXP (dest, 0);
2498   int reg_base = true_regnum (base);
2499   int reg_src = true_regnum (src);
2500   int tmp;
2501   
2502   if (!l)
2503     l = &tmp;
2504   
2505   if (CONSTANT_ADDRESS_P (base))
2506     return *l=8,(AS2 (sts,%m0,%A1) CR_TAB
2507                  AS2 (sts,%m0+1,%B1) CR_TAB
2508                  AS2 (sts,%m0+2,%C1) CR_TAB
2509                  AS2 (sts,%m0+3,%D1));
2510   if (reg_base > 0)                 /* (r) */
2511     {
2512       if (reg_base == REG_X)                /* (R26) */
2513         {
2514           if (reg_src == REG_X)
2515             {
2516               /* "st X+,r26" is undefined */
2517               if (reg_unused_after (insn, base))
2518                 return *l=6, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2519                               AS2 (st,X,r26)            CR_TAB
2520                               AS2 (adiw,r26,1)          CR_TAB
2521                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2522                               AS2 (st,X+,r28)           CR_TAB
2523                               AS2 (st,X,r29));
2524               else
2525                 return *l=7, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2526                               AS2 (st,X,r26)            CR_TAB
2527                               AS2 (adiw,r26,1)          CR_TAB
2528                               AS2 (st,X+,__tmp_reg__)   CR_TAB
2529                               AS2 (st,X+,r28)           CR_TAB
2530                               AS2 (st,X,r29)            CR_TAB
2531                               AS2 (sbiw,r26,3));
2532             }
2533           else if (reg_base == reg_src + 2)
2534             {
2535               if (reg_unused_after (insn, base))
2536                 return *l=7, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2537                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2538                               AS2 (st,%0+,%A1) CR_TAB
2539                               AS2 (st,%0+,%B1) CR_TAB
2540                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2541                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2542                               AS1 (clr,__zero_reg__));
2543               else
2544                 return *l=8, (AS2 (mov,__zero_reg__,%C1) CR_TAB
2545                               AS2 (mov,__tmp_reg__,%D1) CR_TAB
2546                               AS2 (st,%0+,%A1) CR_TAB
2547                               AS2 (st,%0+,%B1) CR_TAB
2548                               AS2 (st,%0+,__zero_reg__)  CR_TAB
2549                               AS2 (st,%0,__tmp_reg__)   CR_TAB
2550                               AS1 (clr,__zero_reg__)     CR_TAB
2551                               AS2 (sbiw,r26,3));
2552             }
2553           return *l=5, (AS2 (st,%0+,%A1)  CR_TAB
2554                         AS2 (st,%0+,%B1) CR_TAB
2555                         AS2 (st,%0+,%C1) CR_TAB
2556                         AS2 (st,%0,%D1)  CR_TAB
2557                         AS2 (sbiw,r26,3));
2558         }
2559       else
2560         return *l=4, (AS2 (st,%0,%A1)    CR_TAB
2561                       AS2 (std,%0+1,%B1) CR_TAB
2562                       AS2 (std,%0+2,%C1) CR_TAB
2563                       AS2 (std,%0+3,%D1));
2564     }
2565   else if (GET_CODE (base) == PLUS) /* (R + i) */
2566     {
2567       int disp = INTVAL (XEXP (base, 1));
2568       reg_base = REGNO (XEXP (base, 0));
2569       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2570         {
2571           if (reg_base != REG_Y)
2572             fatal_insn ("incorrect insn:",insn);
2573
2574           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2575             return *l = 6, (AS2 (adiw,r28,%o0-60) CR_TAB
2576                             AS2 (std,Y+60,%A1)    CR_TAB
2577                             AS2 (std,Y+61,%B1)    CR_TAB
2578                             AS2 (std,Y+62,%C1)    CR_TAB
2579                             AS2 (std,Y+63,%D1)    CR_TAB
2580                             AS2 (sbiw,r28,%o0-60));
2581
2582           return *l = 8, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2583                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2584                           AS2 (st,Y,%A1)           CR_TAB
2585                           AS2 (std,Y+1,%B1)        CR_TAB
2586                           AS2 (std,Y+2,%C1)        CR_TAB
2587                           AS2 (std,Y+3,%D1)        CR_TAB
2588                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2589                           AS2 (sbci,r29,hi8(%o0)));
2590         }
2591       if (reg_base == REG_X)
2592         {
2593           /* (X + d) = R */
2594           if (reg_src == REG_X)
2595             {
2596               *l = 9;
2597               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2598                       AS2 (mov,__zero_reg__,r27) CR_TAB
2599                       AS2 (adiw,r26,%o0)         CR_TAB
2600                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2601                       AS2 (st,X+,__zero_reg__)   CR_TAB
2602                       AS2 (st,X+,r28)            CR_TAB
2603                       AS2 (st,X,r29)             CR_TAB
2604                       AS1 (clr,__zero_reg__)     CR_TAB
2605                       AS2 (sbiw,r26,%o0+3));
2606             }
2607           else if (reg_src == REG_X - 2)
2608             {
2609               *l = 9;
2610               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2611                       AS2 (mov,__zero_reg__,r27) CR_TAB
2612                       AS2 (adiw,r26,%o0)         CR_TAB
2613                       AS2 (st,X+,r24)            CR_TAB
2614                       AS2 (st,X+,r25)            CR_TAB
2615                       AS2 (st,X+,__tmp_reg__)    CR_TAB
2616                       AS2 (st,X,__zero_reg__)    CR_TAB
2617                       AS1 (clr,__zero_reg__)     CR_TAB
2618                       AS2 (sbiw,r26,%o0+3));
2619             }
2620           *l = 6;
2621           return (AS2 (adiw,r26,%o0) CR_TAB
2622                   AS2 (st,X+,%A1)    CR_TAB
2623                   AS2 (st,X+,%B1)    CR_TAB
2624                   AS2 (st,X+,%C1)    CR_TAB
2625                   AS2 (st,X,%D1)     CR_TAB
2626                   AS2 (sbiw,r26,%o0+3));
2627         }
2628       return *l=4, (AS2 (std,%A0,%A1)    CR_TAB
2629                     AS2 (std,%B0,%B1) CR_TAB
2630                     AS2 (std,%C0,%C1) CR_TAB
2631                     AS2 (std,%D0,%D1));
2632     }
2633   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2634     return *l=4, (AS2 (st,%0,%D1) CR_TAB
2635                   AS2 (st,%0,%C1) CR_TAB
2636                   AS2 (st,%0,%B1) CR_TAB
2637                   AS2 (st,%0,%A1));
2638   else if (GET_CODE (base) == POST_INC) /* (R++) */
2639     return *l=4, (AS2 (st,%0,%A1)  CR_TAB
2640                   AS2 (st,%0,%B1) CR_TAB
2641                   AS2 (st,%0,%C1) CR_TAB
2642                   AS2 (st,%0,%D1));
2643   fatal_insn ("unknown move insn:",insn);
2644   return "";
2645 }
2646
2647 const char *
2648 output_movsisf (rtx insn, rtx operands[], int *l)
2649 {
2650   int dummy;
2651   rtx dest = operands[0];
2652   rtx src = operands[1];
2653   int *real_l = l;
2654   
2655   if (!l)
2656     l = &dummy;
2657   
2658   if (register_operand (dest, VOIDmode))
2659     {
2660       if (register_operand (src, VOIDmode)) /* mov r,r */
2661         {
2662           if (true_regnum (dest) > true_regnum (src))
2663             {
2664               if (AVR_HAVE_MOVW)
2665                 {
2666                   *l = 2;
2667                   return (AS2 (movw,%C0,%C1) CR_TAB
2668                           AS2 (movw,%A0,%A1));
2669                 }
2670               *l = 4;
2671               return (AS2 (mov,%D0,%D1) CR_TAB
2672                       AS2 (mov,%C0,%C1) CR_TAB
2673                       AS2 (mov,%B0,%B1) CR_TAB
2674                       AS2 (mov,%A0,%A1));
2675             }
2676           else
2677             {
2678               if (AVR_HAVE_MOVW)
2679                 {
2680                   *l = 2;
2681                   return (AS2 (movw,%A0,%A1) CR_TAB
2682                           AS2 (movw,%C0,%C1));
2683                 }
2684               *l = 4;
2685               return (AS2 (mov,%A0,%A1) CR_TAB
2686                       AS2 (mov,%B0,%B1) CR_TAB
2687                       AS2 (mov,%C0,%C1) CR_TAB
2688                       AS2 (mov,%D0,%D1));
2689             }
2690         }
2691       else if (CONST_INT_P (src)
2692                || CONST_DOUBLE_P (src))
2693         {
2694           return output_reload_insisf (operands, NULL_RTX, real_l);
2695         }
2696       else if (CONSTANT_P (src))
2697         {
2698           if (test_hard_reg_class (LD_REGS, dest)) /* ldi d,i */
2699             {
2700               *l = 4;
2701               return (AS2 (ldi,%A0,lo8(%1))  CR_TAB
2702                       AS2 (ldi,%B0,hi8(%1))  CR_TAB
2703                       AS2 (ldi,%C0,hlo8(%1)) CR_TAB
2704                       AS2 (ldi,%D0,hhi8(%1)));
2705             }
2706           /* Last resort, better than loading from memory.  */
2707           *l = 10;
2708           return (AS2 (mov,__tmp_reg__,r31) CR_TAB
2709                   AS2 (ldi,r31,lo8(%1))     CR_TAB
2710                   AS2 (mov,%A0,r31)         CR_TAB
2711                   AS2 (ldi,r31,hi8(%1))     CR_TAB
2712                   AS2 (mov,%B0,r31)         CR_TAB
2713                   AS2 (ldi,r31,hlo8(%1))    CR_TAB
2714                   AS2 (mov,%C0,r31)         CR_TAB
2715                   AS2 (ldi,r31,hhi8(%1))    CR_TAB
2716                   AS2 (mov,%D0,r31)         CR_TAB
2717                   AS2 (mov,r31,__tmp_reg__));
2718         }
2719       else if (GET_CODE (src) == MEM)
2720         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
2721     }
2722   else if (GET_CODE (dest) == MEM)
2723     {
2724       const char *templ;
2725
2726       if (src == CONST0_RTX (GET_MODE (dest)))
2727           operands[1] = zero_reg_rtx;
2728
2729       templ = out_movsi_mr_r (insn, operands, real_l);
2730
2731       if (!real_l)
2732         output_asm_insn (templ, operands);
2733
2734       operands[1] = src;
2735       return "";
2736     }
2737   fatal_insn ("invalid insn:", insn);
2738   return "";
2739 }
2740
2741 const char *
2742 out_movqi_mr_r (rtx insn, rtx op[], int *l)
2743 {
2744   rtx dest = op[0];
2745   rtx src = op[1];
2746   rtx x = XEXP (dest, 0);
2747   int dummy;
2748
2749   if (!l)
2750     l = &dummy;
2751   
2752   if (CONSTANT_ADDRESS_P (x))
2753     {
2754       if (CONST_INT_P (x) && INTVAL (x) == SREG_ADDR)
2755         {
2756           *l = 1;
2757           return AS2 (out,__SREG__,%1);
2758         }
2759       if (optimize > 0 && io_address_operand (x, QImode))
2760         {
2761           *l = 1;
2762           return AS2 (out,%m0-0x20,%1);
2763         }
2764       *l = 2;
2765       return AS2 (sts,%m0,%1);
2766     }
2767   /* memory access by reg+disp */
2768   else if (GET_CODE (x) == PLUS 
2769       && REG_P (XEXP (x,0))
2770       && GET_CODE (XEXP (x,1)) == CONST_INT)
2771     {
2772       if ((INTVAL (XEXP (x,1)) - GET_MODE_SIZE (GET_MODE (dest))) >= 63)
2773         {
2774           int disp = INTVAL (XEXP (x,1));
2775           if (REGNO (XEXP (x,0)) != REG_Y)
2776             fatal_insn ("incorrect insn:",insn);
2777
2778           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2779             return *l = 3, (AS2 (adiw,r28,%o0-63) CR_TAB
2780                             AS2 (std,Y+63,%1)     CR_TAB
2781                             AS2 (sbiw,r28,%o0-63));
2782
2783           return *l = 5, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2784                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2785                           AS2 (st,Y,%1)            CR_TAB
2786                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2787                           AS2 (sbci,r29,hi8(%o0)));
2788         }
2789       else if (REGNO (XEXP (x,0)) == REG_X)
2790         {
2791           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
2792             {
2793               if (reg_unused_after (insn, XEXP (x,0)))
2794                 return *l = 3, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2795                                 AS2 (adiw,r26,%o0)       CR_TAB
2796                                 AS2 (st,X,__tmp_reg__));
2797
2798               return *l = 4, (AS2 (mov,__tmp_reg__,%1) CR_TAB
2799                               AS2 (adiw,r26,%o0)       CR_TAB
2800                               AS2 (st,X,__tmp_reg__)   CR_TAB
2801                               AS2 (sbiw,r26,%o0));
2802             }
2803           else
2804             {
2805               if (reg_unused_after (insn, XEXP (x,0)))
2806                 return *l = 2, (AS2 (adiw,r26,%o0) CR_TAB
2807                                 AS2 (st,X,%1));
2808
2809               return *l = 3, (AS2 (adiw,r26,%o0) CR_TAB
2810                               AS2 (st,X,%1)      CR_TAB
2811                               AS2 (sbiw,r26,%o0));
2812             }
2813         }
2814       *l = 1;
2815       return AS2 (std,%0,%1);
2816     }
2817   *l = 1;
2818   return AS2 (st,%0,%1);
2819 }
2820
2821 const char *
2822 out_movhi_mr_r (rtx insn, rtx op[], int *l)
2823 {
2824   rtx dest = op[0];
2825   rtx src = op[1];
2826   rtx base = XEXP (dest, 0);
2827   int reg_base = true_regnum (base);
2828   int reg_src = true_regnum (src);
2829   /* "volatile" forces writing high byte first, even if less efficient,
2830      for correct operation with 16-bit I/O registers.  */
2831   int mem_volatile_p = MEM_VOLATILE_P (dest);
2832   int tmp;
2833
2834   if (!l)
2835     l = &tmp;
2836   if (CONSTANT_ADDRESS_P (base))
2837     {
2838       if (optimize > 0 && io_address_operand (base, HImode))
2839         {
2840           *l = 2;
2841           return (AS2 (out,%m0+1-0x20,%B1) CR_TAB
2842                   AS2 (out,%m0-0x20,%A1));
2843         }
2844       return *l = 4, (AS2 (sts,%m0+1,%B1) CR_TAB
2845                       AS2 (sts,%m0,%A1));
2846     }
2847   if (reg_base > 0)
2848     {
2849       if (reg_base == REG_X)
2850         {
2851           if (reg_src == REG_X)
2852             {
2853               /* "st X+,r26" and "st -X,r26" are undefined.  */
2854               if (!mem_volatile_p && reg_unused_after (insn, src))
2855                 return *l=4, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2856                               AS2 (st,X,r26)            CR_TAB
2857                               AS2 (adiw,r26,1)          CR_TAB
2858                               AS2 (st,X,__tmp_reg__));
2859               else
2860                 return *l=5, (AS2 (mov,__tmp_reg__,r27) CR_TAB
2861                               AS2 (adiw,r26,1)          CR_TAB
2862                               AS2 (st,X,__tmp_reg__)    CR_TAB
2863                               AS2 (sbiw,r26,1)          CR_TAB
2864                               AS2 (st,X,r26));
2865             }
2866           else
2867             {
2868               if (!mem_volatile_p && reg_unused_after (insn, base))
2869                 return *l=2, (AS2 (st,X+,%A1) CR_TAB
2870                               AS2 (st,X,%B1));
2871               else
2872                 return *l=3, (AS2 (adiw,r26,1) CR_TAB
2873                               AS2 (st,X,%B1)   CR_TAB
2874                               AS2 (st,-X,%A1));
2875             }
2876         }
2877       else
2878         return  *l=2, (AS2 (std,%0+1,%B1) CR_TAB
2879                        AS2 (st,%0,%A1));
2880     }
2881   else if (GET_CODE (base) == PLUS)
2882     {
2883       int disp = INTVAL (XEXP (base, 1));
2884       reg_base = REGNO (XEXP (base, 0));
2885       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
2886         {
2887           if (reg_base != REG_Y)
2888             fatal_insn ("incorrect insn:",insn);
2889
2890           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
2891             return *l = 4, (AS2 (adiw,r28,%o0-62) CR_TAB
2892                             AS2 (std,Y+63,%B1)    CR_TAB
2893                             AS2 (std,Y+62,%A1)    CR_TAB
2894                             AS2 (sbiw,r28,%o0-62));
2895
2896           return *l = 6, (AS2 (subi,r28,lo8(-%o0)) CR_TAB
2897                           AS2 (sbci,r29,hi8(-%o0)) CR_TAB
2898                           AS2 (std,Y+1,%B1)        CR_TAB
2899                           AS2 (st,Y,%A1)           CR_TAB
2900                           AS2 (subi,r28,lo8(%o0))  CR_TAB
2901                           AS2 (sbci,r29,hi8(%o0)));
2902         }
2903       if (reg_base == REG_X)
2904         {
2905           /* (X + d) = R */
2906           if (reg_src == REG_X)
2907             {
2908               *l = 7;
2909               return (AS2 (mov,__tmp_reg__,r26)  CR_TAB
2910                       AS2 (mov,__zero_reg__,r27) CR_TAB
2911                       AS2 (adiw,r26,%o0+1)       CR_TAB
2912                       AS2 (st,X,__zero_reg__)    CR_TAB
2913                       AS2 (st,-X,__tmp_reg__)    CR_TAB
2914                       AS1 (clr,__zero_reg__)     CR_TAB
2915                       AS2 (sbiw,r26,%o0));
2916             }
2917           *l = 4;
2918           return (AS2 (adiw,r26,%o0+1) CR_TAB
2919                   AS2 (st,X,%B1)       CR_TAB
2920                   AS2 (st,-X,%A1)      CR_TAB
2921                   AS2 (sbiw,r26,%o0));
2922         }
2923       return *l=2, (AS2 (std,%B0,%B1)    CR_TAB
2924                     AS2 (std,%A0,%A1));
2925     }
2926   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
2927     return *l=2, (AS2 (st,%0,%B1) CR_TAB
2928                   AS2 (st,%0,%A1));
2929   else if (GET_CODE (base) == POST_INC) /* (R++) */
2930     {
2931       if (mem_volatile_p)
2932         {
2933           if (REGNO (XEXP (base, 0)) == REG_X)
2934             {
2935               *l = 4;
2936               return (AS2 (adiw,r26,1)  CR_TAB
2937                       AS2 (st,X,%B1)    CR_TAB
2938                       AS2 (st,-X,%A1)   CR_TAB
2939                       AS2 (adiw,r26,2));
2940             }
2941           else
2942             {
2943               *l = 3;
2944               return (AS2 (std,%p0+1,%B1) CR_TAB
2945                       AS2 (st,%p0,%A1)    CR_TAB
2946                       AS2 (adiw,%r0,2));
2947             }
2948         }
2949
2950       *l = 2;
2951       return (AS2 (st,%0,%A1)  CR_TAB
2952             AS2 (st,%0,%B1));
2953     }
2954   fatal_insn ("unknown move insn:",insn);
2955   return "";
2956 }
2957
2958 /* Return 1 if frame pointer for current function required.  */
2959
2960 bool
2961 avr_frame_pointer_required_p (void)
2962 {
2963   return (cfun->calls_alloca
2964           || crtl->args.info.nregs == 0
2965           || get_frame_size () > 0);
2966 }
2967
2968 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
2969
2970 static RTX_CODE
2971 compare_condition (rtx insn)
2972 {
2973   rtx next = next_real_insn (insn);
2974
2975   if (next && JUMP_P (next))
2976     {
2977       rtx pat = PATTERN (next);
2978       rtx src = SET_SRC (pat);
2979       
2980       if (IF_THEN_ELSE == GET_CODE (src))
2981         return GET_CODE (XEXP (src, 0));
2982     }
2983   
2984   return UNKNOWN;
2985 }
2986
2987
2988 /* Returns true iff INSN is a tst insn that only tests the sign.  */
2989
2990 static bool
2991 compare_sign_p (rtx insn)
2992 {
2993   RTX_CODE cond = compare_condition (insn);
2994   return (cond == GE || cond == LT);
2995 }
2996
2997
2998 /* Returns true iff the next insn is a JUMP_INSN with a condition
2999    that needs to be swapped (GT, GTU, LE, LEU).  */
3000
3001 static bool
3002 compare_diff_p (rtx insn)
3003 {
3004   RTX_CODE cond = compare_condition (insn);
3005   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
3006 }
3007
3008 /* Returns true iff INSN is a compare insn with the EQ or NE condition.  */
3009
3010 static bool
3011 compare_eq_p (rtx insn)
3012 {
3013   RTX_CODE cond = compare_condition (insn);
3014   return (cond == EQ || cond == NE);
3015 }
3016
3017
3018 /* Output compare instruction
3019
3020       compare (XOP[0], XOP[1])
3021
3022    for an HI/SI register XOP[0] and an integer XOP[1].  Return "".
3023    XOP[2] is an 8-bit scratch register as needed.
3024
3025    PLEN == NULL:  Output instructions.
3026    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
3027                   Don't output anything.  */
3028
3029 const char*
3030 avr_out_compare (rtx insn, rtx *xop, int *plen)
3031 {
3032   /* Register to compare and value to compare against. */
3033   rtx xreg = xop[0];
3034   rtx xval = xop[1];
3035   
3036   /* MODE of the comparison.  */
3037   enum machine_mode mode = GET_MODE (xreg);
3038
3039   /* Number of bytes to operate on.  */
3040   int i, n_bytes = GET_MODE_SIZE (mode);
3041
3042   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
3043   int clobber_val = -1;
3044
3045   gcc_assert (REG_P (xreg)
3046               && CONST_INT_P (xval));
3047   
3048   if (plen)
3049     *plen = 0;
3050
3051   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
3052      against 0 by ORing the bytes.  This is one instruction shorter.  */
3053
3054   if (!test_hard_reg_class (LD_REGS, xreg)
3055       && compare_eq_p (insn)
3056       && reg_unused_after (insn, xreg))
3057     {
3058       if (xval == const1_rtx)
3059         {
3060           avr_asm_len ("dec %A0" CR_TAB
3061                        "or %A0,%B0", xop, plen, 2);
3062           
3063           if (n_bytes == 4)
3064             avr_asm_len ("or %A0,%C0" CR_TAB
3065                          "or %A0,%D0", xop, plen, 2);
3066
3067           return "";
3068         }
3069       else if (xval == constm1_rtx)
3070         {
3071           if (n_bytes == 4)
3072             avr_asm_len ("and %A0,%D0" CR_TAB
3073                          "and %A0,%C0", xop, plen, 2);
3074           
3075           avr_asm_len ("and %A0,%B0" CR_TAB
3076                        "com %A0", xop, plen, 2);
3077           
3078           return "";
3079         }
3080     }
3081
3082   for (i = 0; i < n_bytes; i++)
3083     {
3084       /* We compare byte-wise.  */
3085       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
3086       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
3087
3088       /* 8-bit value to compare with this byte.  */
3089       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
3090
3091       /* Registers R16..R31 can operate with immediate.  */
3092       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
3093
3094       xop[0] = reg8;
3095       xop[1] = gen_int_mode (val8, QImode);
3096
3097       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
3098
3099       if (i == 0
3100           && test_hard_reg_class (ADDW_REGS, reg8))
3101         {
3102           int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
3103           
3104           if (IN_RANGE (val16, 0, 63)
3105               && (val8 == 0
3106                   || reg_unused_after (insn, xreg)))
3107             {
3108               avr_asm_len ("sbiw %0,%1", xop, plen, 1);
3109               i++;
3110               continue;
3111             }
3112
3113           if (n_bytes == 2
3114               && IN_RANGE (val16, -63, -1)
3115               && compare_eq_p (insn)
3116               && reg_unused_after (insn, xreg))
3117             {
3118               avr_asm_len ("adiw %0,%n1", xop, plen, 1);
3119               break;
3120             }
3121         }
3122
3123       /* Comparing against 0 is easy.  */
3124       
3125       if (val8 == 0)
3126         {
3127           avr_asm_len (i == 0
3128                        ? "cp %0,__zero_reg__"
3129                        : "cpc %0,__zero_reg__", xop, plen, 1);
3130           continue;
3131         }
3132
3133       /* Upper registers can compare and subtract-with-carry immediates.
3134          Notice that compare instructions do the same as respective subtract
3135          instruction; the only difference is that comparisons don't write
3136          the result back to the target register.  */
3137
3138       if (ld_reg_p)
3139         {
3140           if (i == 0)
3141             {
3142               avr_asm_len ("cpi %0,%1", xop, plen, 1);
3143               continue;
3144             }
3145           else if (reg_unused_after (insn, xreg))
3146             {
3147               avr_asm_len ("sbci %0,%1", xop, plen, 1);
3148               continue;
3149             }
3150         }
3151
3152       /* Must load the value into the scratch register.  */
3153
3154       gcc_assert (REG_P (xop[2]));
3155               
3156       if (clobber_val != (int) val8)
3157         avr_asm_len ("ldi %2,%1", xop, plen, 1);
3158       clobber_val = (int) val8;
3159               
3160       avr_asm_len (i == 0
3161                    ? "cp %0,%2"
3162                    : "cpc %0,%2", xop, plen, 1);
3163     }
3164
3165   return "";
3166 }
3167
3168
3169 /* Output test instruction for HImode.  */
3170
3171 const char*
3172 avr_out_tsthi (rtx insn, rtx *op, int *plen)
3173 {
3174   if (compare_sign_p (insn))
3175     {
3176       avr_asm_len ("tst %B0", op, plen, -1);
3177     }
3178   else if (reg_unused_after (insn, op[0])
3179            && compare_eq_p (insn))
3180     {
3181       /* Faster than sbiw if we can clobber the operand.  */
3182       avr_asm_len ("or %A0,%B0", op, plen, -1);
3183     }
3184   else
3185     {
3186       avr_out_compare (insn, op, plen);
3187     }
3188
3189   return "";
3190 }
3191
3192
3193 /* Output test instruction for SImode.  */
3194
3195 const char*
3196 avr_out_tstsi (rtx insn, rtx *op, int *plen)
3197 {
3198   if (compare_sign_p (insn))
3199     {
3200       avr_asm_len ("tst %D0", op, plen, -1);
3201     }
3202   else if (reg_unused_after (insn, op[0])
3203            && compare_eq_p (insn))
3204     {
3205       /* Faster than sbiw if we can clobber the operand.  */
3206       avr_asm_len ("or %A0,%B0" CR_TAB
3207                    "or %A0,%C0" CR_TAB
3208                    "or %A0,%D0", op, plen, -3);
3209     }
3210   else
3211     {
3212       avr_out_compare (insn, op, plen);
3213     }
3214
3215   return "";
3216 }
3217
3218
3219 /* Generate asm equivalent for various shifts.
3220    Shift count is a CONST_INT, MEM or REG.
3221    This only handles cases that are not already
3222    carefully hand-optimized in ?sh??i3_out.  */
3223
3224 void
3225 out_shift_with_cnt (const char *templ, rtx insn, rtx operands[],
3226                     int *len, int t_len)
3227 {
3228   rtx op[10];
3229   char str[500];
3230   int second_label = 1;
3231   int saved_in_tmp = 0;
3232   int use_zero_reg = 0;
3233
3234   op[0] = operands[0];
3235   op[1] = operands[1];
3236   op[2] = operands[2];
3237   op[3] = operands[3];
3238   str[0] = 0;
3239
3240   if (len)
3241     *len = 1;
3242
3243   if (GET_CODE (operands[2]) == CONST_INT)
3244     {
3245       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3246       int count = INTVAL (operands[2]);
3247       int max_len = 10;  /* If larger than this, always use a loop.  */
3248
3249       if (count <= 0)
3250         {
3251           if (len)
3252             *len = 0;
3253           return;
3254         }
3255
3256       if (count < 8 && !scratch)
3257         use_zero_reg = 1;
3258
3259       if (optimize_size)
3260         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
3261
3262       if (t_len * count <= max_len)
3263         {
3264           /* Output shifts inline with no loop - faster.  */
3265           if (len)
3266             *len = t_len * count;
3267           else
3268             {
3269               while (count-- > 0)
3270                 output_asm_insn (templ, op);
3271             }
3272
3273           return;
3274         }
3275
3276       if (scratch)
3277         {
3278           if (!len)
3279             strcat (str, AS2 (ldi,%3,%2));
3280         }
3281       else if (use_zero_reg)
3282         {
3283           /* Hack to save one word: use __zero_reg__ as loop counter.
3284              Set one bit, then shift in a loop until it is 0 again.  */
3285
3286           op[3] = zero_reg_rtx;
3287           if (len)
3288             *len = 2;
3289           else
3290             strcat (str, ("set" CR_TAB
3291                           AS2 (bld,%3,%2-1)));
3292         }
3293       else
3294         {
3295           /* No scratch register available, use one from LD_REGS (saved in
3296              __tmp_reg__) that doesn't overlap with registers to shift.  */
3297
3298           op[3] = gen_rtx_REG (QImode,
3299                            ((true_regnum (operands[0]) - 1) & 15) + 16);
3300           op[4] = tmp_reg_rtx;
3301           saved_in_tmp = 1;
3302
3303           if (len)
3304             *len = 3;  /* Includes "mov %3,%4" after the loop.  */
3305           else
3306             strcat (str, (AS2 (mov,%4,%3) CR_TAB
3307                           AS2 (ldi,%3,%2)));
3308         }
3309
3310       second_label = 0;
3311     }
3312   else if (GET_CODE (operands[2]) == MEM)
3313     {
3314       rtx op_mov[10];
3315       
3316       op[3] = op_mov[0] = tmp_reg_rtx;
3317       op_mov[1] = op[2];
3318
3319       if (len)
3320         out_movqi_r_mr (insn, op_mov, len);
3321       else
3322         output_asm_insn (out_movqi_r_mr (insn, op_mov, NULL), op_mov);
3323     }
3324   else if (register_operand (operands[2], QImode))
3325     {
3326       if (reg_unused_after (insn, operands[2])
3327           && !reg_overlap_mentioned_p (operands[0], operands[2]))
3328         {
3329           op[3] = op[2];
3330         }
3331       else
3332         {
3333           op[3] = tmp_reg_rtx;
3334           if (!len)
3335             strcat (str, (AS2 (mov,%3,%2) CR_TAB));
3336         }
3337     }
3338   else
3339     fatal_insn ("bad shift insn:", insn);
3340
3341   if (second_label)
3342     {
3343       if (len)
3344         ++*len;
3345       else
3346         strcat (str, AS1 (rjmp,2f));
3347     }
3348
3349   if (len)
3350     *len += t_len + 2;  /* template + dec + brXX */
3351   else
3352     {
3353       strcat (str, "\n1:\t");
3354       strcat (str, templ);
3355       strcat (str, second_label ? "\n2:\t" : "\n\t");
3356       strcat (str, use_zero_reg ? AS1 (lsr,%3) : AS1 (dec,%3));
3357       strcat (str, CR_TAB);
3358       strcat (str, second_label ? AS1 (brpl,1b) : AS1 (brne,1b));
3359       if (saved_in_tmp)
3360         strcat (str, (CR_TAB AS2 (mov,%3,%4)));
3361       output_asm_insn (str, op);
3362     }
3363 }
3364
3365
3366 /* 8bit shift left ((char)x << i)   */
3367
3368 const char *
3369 ashlqi3_out (rtx insn, rtx operands[], int *len)
3370 {
3371   if (GET_CODE (operands[2]) == CONST_INT)
3372     {
3373       int k;
3374
3375       if (!len)
3376         len = &k;
3377
3378       switch (INTVAL (operands[2]))
3379         {
3380         default:
3381           if (INTVAL (operands[2]) < 8)
3382             break;
3383
3384           *len = 1;
3385           return AS1 (clr,%0);
3386           
3387         case 1:
3388           *len = 1;
3389           return AS1 (lsl,%0);
3390           
3391         case 2:
3392           *len = 2;
3393           return (AS1 (lsl,%0) CR_TAB
3394                   AS1 (lsl,%0));
3395
3396         case 3:
3397           *len = 3;
3398           return (AS1 (lsl,%0) CR_TAB
3399                   AS1 (lsl,%0) CR_TAB
3400                   AS1 (lsl,%0));
3401
3402         case 4:
3403           if (test_hard_reg_class (LD_REGS, operands[0]))
3404             {
3405               *len = 2;
3406               return (AS1 (swap,%0) CR_TAB
3407                       AS2 (andi,%0,0xf0));
3408             }
3409           *len = 4;
3410           return (AS1 (lsl,%0) CR_TAB
3411                   AS1 (lsl,%0) CR_TAB
3412                   AS1 (lsl,%0) CR_TAB
3413                   AS1 (lsl,%0));
3414
3415         case 5:
3416           if (test_hard_reg_class (LD_REGS, operands[0]))
3417             {
3418               *len = 3;
3419               return (AS1 (swap,%0) CR_TAB
3420                       AS1 (lsl,%0)  CR_TAB
3421                       AS2 (andi,%0,0xe0));
3422             }
3423           *len = 5;
3424           return (AS1 (lsl,%0) CR_TAB
3425                   AS1 (lsl,%0) CR_TAB
3426                   AS1 (lsl,%0) CR_TAB
3427                   AS1 (lsl,%0) CR_TAB
3428                   AS1 (lsl,%0));
3429
3430         case 6:
3431           if (test_hard_reg_class (LD_REGS, operands[0]))
3432             {
3433               *len = 4;
3434               return (AS1 (swap,%0) CR_TAB
3435                       AS1 (lsl,%0)  CR_TAB
3436                       AS1 (lsl,%0)  CR_TAB
3437                       AS2 (andi,%0,0xc0));
3438             }
3439           *len = 6;
3440           return (AS1 (lsl,%0) CR_TAB
3441                   AS1 (lsl,%0) CR_TAB
3442                   AS1 (lsl,%0) CR_TAB
3443                   AS1 (lsl,%0) CR_TAB
3444                   AS1 (lsl,%0) CR_TAB
3445                   AS1 (lsl,%0));
3446
3447         case 7:
3448           *len = 3;
3449           return (AS1 (ror,%0) CR_TAB
3450                   AS1 (clr,%0) CR_TAB
3451                   AS1 (ror,%0));
3452         }
3453     }
3454   else if (CONSTANT_P (operands[2]))
3455     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3456
3457   out_shift_with_cnt (AS1 (lsl,%0),
3458                       insn, operands, len, 1);
3459   return "";
3460 }
3461
3462
3463 /* 16bit shift left ((short)x << i)   */
3464
3465 const char *
3466 ashlhi3_out (rtx insn, rtx operands[], int *len)
3467 {
3468   if (GET_CODE (operands[2]) == CONST_INT)
3469     {
3470       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3471       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3472       int k;
3473       int *t = len;
3474
3475       if (!len)
3476         len = &k;
3477       
3478       switch (INTVAL (operands[2]))
3479         {
3480         default:
3481           if (INTVAL (operands[2]) < 16)
3482             break;
3483
3484           *len = 2;
3485           return (AS1 (clr,%B0) CR_TAB
3486                   AS1 (clr,%A0));
3487
3488         case 4:
3489           if (optimize_size && scratch)
3490             break;  /* 5 */
3491           if (ldi_ok)
3492             {
3493               *len = 6;
3494               return (AS1 (swap,%A0)      CR_TAB
3495                       AS1 (swap,%B0)      CR_TAB
3496                       AS2 (andi,%B0,0xf0) CR_TAB
3497                       AS2 (eor,%B0,%A0)   CR_TAB
3498                       AS2 (andi,%A0,0xf0) CR_TAB
3499                       AS2 (eor,%B0,%A0));
3500             }
3501           if (scratch)
3502             {
3503               *len = 7;
3504               return (AS1 (swap,%A0)    CR_TAB
3505                       AS1 (swap,%B0)    CR_TAB
3506                       AS2 (ldi,%3,0xf0) CR_TAB
3507                       "and %B0,%3"      CR_TAB
3508                       AS2 (eor,%B0,%A0) CR_TAB
3509                       "and %A0,%3"      CR_TAB
3510                       AS2 (eor,%B0,%A0));
3511             }
3512           break;  /* optimize_size ? 6 : 8 */
3513
3514         case 5:
3515           if (optimize_size)
3516             break;  /* scratch ? 5 : 6 */
3517           if (ldi_ok)
3518             {
3519               *len = 8;
3520               return (AS1 (lsl,%A0)       CR_TAB
3521                       AS1 (rol,%B0)       CR_TAB
3522                       AS1 (swap,%A0)      CR_TAB
3523                       AS1 (swap,%B0)      CR_TAB
3524                       AS2 (andi,%B0,0xf0) CR_TAB
3525                       AS2 (eor,%B0,%A0)   CR_TAB
3526                       AS2 (andi,%A0,0xf0) CR_TAB
3527                       AS2 (eor,%B0,%A0));
3528             }
3529           if (scratch)
3530             {
3531               *len = 9;
3532               return (AS1 (lsl,%A0)     CR_TAB
3533                       AS1 (rol,%B0)     CR_TAB
3534                       AS1 (swap,%A0)    CR_TAB
3535                       AS1 (swap,%B0)    CR_TAB
3536                       AS2 (ldi,%3,0xf0) CR_TAB
3537                       "and %B0,%3"      CR_TAB
3538                       AS2 (eor,%B0,%A0) CR_TAB
3539                       "and %A0,%3"      CR_TAB
3540                       AS2 (eor,%B0,%A0));
3541             }
3542           break;  /* 10 */
3543
3544         case 6:
3545           if (optimize_size)
3546             break;  /* scratch ? 5 : 6 */
3547           *len = 9;
3548           return (AS1 (clr,__tmp_reg__) CR_TAB
3549                   AS1 (lsr,%B0)         CR_TAB
3550                   AS1 (ror,%A0)         CR_TAB
3551                   AS1 (ror,__tmp_reg__) CR_TAB
3552                   AS1 (lsr,%B0)         CR_TAB
3553                   AS1 (ror,%A0)         CR_TAB
3554                   AS1 (ror,__tmp_reg__) CR_TAB
3555                   AS2 (mov,%B0,%A0)     CR_TAB
3556                   AS2 (mov,%A0,__tmp_reg__));
3557
3558         case 7:
3559           *len = 5;
3560           return (AS1 (lsr,%B0)     CR_TAB
3561                   AS2 (mov,%B0,%A0) CR_TAB
3562                   AS1 (clr,%A0)     CR_TAB
3563                   AS1 (ror,%B0)     CR_TAB
3564                   AS1 (ror,%A0));
3565
3566         case 8:
3567           return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB
3568                             AS1 (clr,%A0));
3569
3570         case 9:
3571           *len = 3;
3572           return (AS2 (mov,%B0,%A0) CR_TAB
3573                   AS1 (clr,%A0)     CR_TAB
3574                   AS1 (lsl,%B0));
3575
3576         case 10:
3577           *len = 4;
3578           return (AS2 (mov,%B0,%A0) CR_TAB
3579                   AS1 (clr,%A0)     CR_TAB
3580                   AS1 (lsl,%B0)     CR_TAB
3581                   AS1 (lsl,%B0));
3582
3583         case 11:
3584           *len = 5;
3585           return (AS2 (mov,%B0,%A0) CR_TAB
3586                   AS1 (clr,%A0)     CR_TAB
3587                   AS1 (lsl,%B0)     CR_TAB
3588                   AS1 (lsl,%B0)     CR_TAB
3589                   AS1 (lsl,%B0));
3590
3591         case 12:
3592           if (ldi_ok)
3593             {
3594               *len = 4;
3595               return (AS2 (mov,%B0,%A0) CR_TAB
3596                       AS1 (clr,%A0)     CR_TAB
3597                       AS1 (swap,%B0)    CR_TAB
3598                       AS2 (andi,%B0,0xf0));
3599             }
3600           if (scratch)
3601             {
3602               *len = 5;
3603               return (AS2 (mov,%B0,%A0) CR_TAB
3604                       AS1 (clr,%A0)     CR_TAB
3605                       AS1 (swap,%B0)    CR_TAB
3606                       AS2 (ldi,%3,0xf0) CR_TAB
3607                       "and %B0,%3");
3608             }
3609           *len = 6;
3610           return (AS2 (mov,%B0,%A0) CR_TAB
3611                   AS1 (clr,%A0)     CR_TAB
3612                   AS1 (lsl,%B0)     CR_TAB
3613                   AS1 (lsl,%B0)     CR_TAB
3614                   AS1 (lsl,%B0)     CR_TAB
3615                   AS1 (lsl,%B0));
3616
3617         case 13:
3618           if (ldi_ok)
3619             {
3620               *len = 5;
3621               return (AS2 (mov,%B0,%A0) CR_TAB
3622                       AS1 (clr,%A0)     CR_TAB
3623                       AS1 (swap,%B0)    CR_TAB
3624                       AS1 (lsl,%B0)     CR_TAB
3625                       AS2 (andi,%B0,0xe0));
3626             }
3627           if (AVR_HAVE_MUL && scratch)
3628             {
3629               *len = 5;
3630               return (AS2 (ldi,%3,0x20) CR_TAB
3631                       AS2 (mul,%A0,%3)  CR_TAB
3632                       AS2 (mov,%B0,r0)  CR_TAB
3633                       AS1 (clr,%A0)     CR_TAB
3634                       AS1 (clr,__zero_reg__));
3635             }
3636           if (optimize_size && scratch)
3637             break;  /* 5 */
3638           if (scratch)
3639             {
3640               *len = 6;
3641               return (AS2 (mov,%B0,%A0) CR_TAB
3642                       AS1 (clr,%A0)     CR_TAB
3643                       AS1 (swap,%B0)    CR_TAB
3644                       AS1 (lsl,%B0)     CR_TAB
3645                       AS2 (ldi,%3,0xe0) CR_TAB
3646                       "and %B0,%3");
3647             }
3648           if (AVR_HAVE_MUL)
3649             {
3650               *len = 6;
3651               return ("set"            CR_TAB
3652                       AS2 (bld,r1,5)   CR_TAB
3653                       AS2 (mul,%A0,r1) CR_TAB
3654                       AS2 (mov,%B0,r0) CR_TAB
3655                       AS1 (clr,%A0)    CR_TAB
3656                       AS1 (clr,__zero_reg__));
3657             }
3658           *len = 7;
3659           return (AS2 (mov,%B0,%A0) CR_TAB
3660                   AS1 (clr,%A0)     CR_TAB
3661                   AS1 (lsl,%B0)     CR_TAB
3662                   AS1 (lsl,%B0)     CR_TAB
3663                   AS1 (lsl,%B0)     CR_TAB
3664                   AS1 (lsl,%B0)     CR_TAB
3665                   AS1 (lsl,%B0));
3666
3667         case 14:
3668           if (AVR_HAVE_MUL && ldi_ok)
3669             {
3670               *len = 5;
3671               return (AS2 (ldi,%B0,0x40) CR_TAB
3672                       AS2 (mul,%A0,%B0)  CR_TAB
3673                       AS2 (mov,%B0,r0)   CR_TAB
3674                       AS1 (clr,%A0)      CR_TAB
3675                       AS1 (clr,__zero_reg__));
3676             }
3677           if (AVR_HAVE_MUL && scratch)
3678             {
3679               *len = 5;
3680               return (AS2 (ldi,%3,0x40) CR_TAB
3681                       AS2 (mul,%A0,%3)  CR_TAB
3682                       AS2 (mov,%B0,r0)  CR_TAB
3683                       AS1 (clr,%A0)     CR_TAB
3684                       AS1 (clr,__zero_reg__));
3685             }
3686           if (optimize_size && ldi_ok)
3687             {
3688               *len = 5;
3689               return (AS2 (mov,%B0,%A0) CR_TAB
3690                       AS2 (ldi,%A0,6) "\n1:\t"
3691                       AS1 (lsl,%B0)     CR_TAB
3692                       AS1 (dec,%A0)     CR_TAB
3693                       AS1 (brne,1b));
3694             }
3695           if (optimize_size && scratch)
3696             break;  /* 5 */
3697           *len = 6;
3698           return (AS1 (clr,%B0) CR_TAB
3699                   AS1 (lsr,%A0) CR_TAB
3700                   AS1 (ror,%B0) CR_TAB
3701                   AS1 (lsr,%A0) CR_TAB
3702                   AS1 (ror,%B0) CR_TAB
3703                   AS1 (clr,%A0));
3704
3705         case 15:
3706           *len = 4;
3707           return (AS1 (clr,%B0) CR_TAB
3708                   AS1 (lsr,%A0) CR_TAB
3709                   AS1 (ror,%B0) CR_TAB
3710                   AS1 (clr,%A0));
3711         }
3712       len = t;
3713     }
3714   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3715                        AS1 (rol,%B0)),
3716                        insn, operands, len, 2);
3717   return "";
3718 }
3719
3720
3721 /* 32bit shift left ((long)x << i)   */
3722
3723 const char *
3724 ashlsi3_out (rtx insn, rtx operands[], int *len)
3725 {
3726   if (GET_CODE (operands[2]) == CONST_INT)
3727     {
3728       int k;
3729       int *t = len;
3730       
3731       if (!len)
3732         len = &k;
3733       
3734       switch (INTVAL (operands[2]))
3735         {
3736         default:
3737           if (INTVAL (operands[2]) < 32)
3738             break;
3739
3740           if (AVR_HAVE_MOVW)
3741             return *len = 3, (AS1 (clr,%D0) CR_TAB
3742                               AS1 (clr,%C0) CR_TAB
3743                               AS2 (movw,%A0,%C0));
3744           *len = 4;
3745           return (AS1 (clr,%D0) CR_TAB
3746                   AS1 (clr,%C0) CR_TAB
3747                   AS1 (clr,%B0) CR_TAB
3748                   AS1 (clr,%A0));
3749
3750         case 8:
3751           {
3752             int reg0 = true_regnum (operands[0]);
3753             int reg1 = true_regnum (operands[1]);
3754             *len = 4;
3755             if (reg0 >= reg1)
3756               return (AS2 (mov,%D0,%C1)  CR_TAB
3757                       AS2 (mov,%C0,%B1)  CR_TAB
3758                       AS2 (mov,%B0,%A1)  CR_TAB
3759                       AS1 (clr,%A0));
3760             else
3761               return (AS1 (clr,%A0)      CR_TAB
3762                       AS2 (mov,%B0,%A1)  CR_TAB
3763                       AS2 (mov,%C0,%B1)  CR_TAB
3764                       AS2 (mov,%D0,%C1));
3765           }
3766
3767         case 16:
3768           {
3769             int reg0 = true_regnum (operands[0]);
3770             int reg1 = true_regnum (operands[1]);
3771             if (reg0 + 2 == reg1)
3772               return *len = 2, (AS1 (clr,%B0)      CR_TAB
3773                                 AS1 (clr,%A0));
3774             if (AVR_HAVE_MOVW)
3775               return *len = 3, (AS2 (movw,%C0,%A1) CR_TAB
3776                                 AS1 (clr,%B0)      CR_TAB
3777                                 AS1 (clr,%A0));
3778             else
3779               return *len = 4, (AS2 (mov,%C0,%A1)  CR_TAB
3780                                 AS2 (mov,%D0,%B1)  CR_TAB
3781                                 AS1 (clr,%B0)      CR_TAB
3782                                 AS1 (clr,%A0));
3783           }
3784
3785         case 24:
3786           *len = 4;
3787           return (AS2 (mov,%D0,%A1)  CR_TAB
3788                   AS1 (clr,%C0)      CR_TAB
3789                   AS1 (clr,%B0)      CR_TAB
3790                   AS1 (clr,%A0));
3791
3792         case 31:
3793           *len = 6;
3794           return (AS1 (clr,%D0) CR_TAB
3795                   AS1 (lsr,%A0) CR_TAB
3796                   AS1 (ror,%D0) CR_TAB
3797                   AS1 (clr,%C0) CR_TAB
3798                   AS1 (clr,%B0) CR_TAB
3799                   AS1 (clr,%A0));
3800         }
3801       len = t;
3802     }
3803   out_shift_with_cnt ((AS1 (lsl,%A0) CR_TAB
3804                        AS1 (rol,%B0) CR_TAB
3805                        AS1 (rol,%C0) CR_TAB
3806                        AS1 (rol,%D0)),
3807                        insn, operands, len, 4);
3808   return "";
3809 }
3810
3811 /* 8bit arithmetic shift right  ((signed char)x >> i) */
3812
3813 const char *
3814 ashrqi3_out (rtx insn, rtx operands[], int *len)
3815 {
3816   if (GET_CODE (operands[2]) == CONST_INT)
3817     {
3818       int k;
3819
3820       if (!len)
3821         len = &k;
3822
3823       switch (INTVAL (operands[2]))
3824         {
3825         case 1:
3826           *len = 1;
3827           return AS1 (asr,%0);
3828
3829         case 2:
3830           *len = 2;
3831           return (AS1 (asr,%0) CR_TAB
3832                   AS1 (asr,%0));
3833
3834         case 3:
3835           *len = 3;
3836           return (AS1 (asr,%0) CR_TAB
3837                   AS1 (asr,%0) CR_TAB
3838                   AS1 (asr,%0));
3839
3840         case 4:
3841           *len = 4;
3842           return (AS1 (asr,%0) CR_TAB
3843                   AS1 (asr,%0) CR_TAB
3844                   AS1 (asr,%0) CR_TAB
3845                   AS1 (asr,%0));
3846
3847         case 5:
3848           *len = 5;
3849           return (AS1 (asr,%0) CR_TAB
3850                   AS1 (asr,%0) CR_TAB
3851                   AS1 (asr,%0) CR_TAB
3852                   AS1 (asr,%0) CR_TAB
3853                   AS1 (asr,%0));
3854
3855         case 6:
3856           *len = 4;
3857           return (AS2 (bst,%0,6)  CR_TAB
3858                   AS1 (lsl,%0)    CR_TAB
3859                   AS2 (sbc,%0,%0) CR_TAB
3860                   AS2 (bld,%0,0));
3861
3862         default:
3863           if (INTVAL (operands[2]) < 8)
3864             break;
3865
3866           /* fall through */
3867
3868         case 7:
3869           *len = 2;
3870           return (AS1 (lsl,%0) CR_TAB
3871                   AS2 (sbc,%0,%0));
3872         }
3873     }
3874   else if (CONSTANT_P (operands[2]))
3875     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
3876
3877   out_shift_with_cnt (AS1 (asr,%0),
3878                       insn, operands, len, 1);
3879   return "";
3880 }
3881
3882
3883 /* 16bit arithmetic shift right  ((signed short)x >> i) */
3884
3885 const char *
3886 ashrhi3_out (rtx insn, rtx operands[], int *len)
3887 {
3888   if (GET_CODE (operands[2]) == CONST_INT)
3889     {
3890       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
3891       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
3892       int k;
3893       int *t = len;
3894       
3895       if (!len)
3896         len = &k;
3897
3898       switch (INTVAL (operands[2]))
3899         {
3900         case 4:
3901         case 5:
3902           /* XXX try to optimize this too? */
3903           break;
3904
3905         case 6:
3906           if (optimize_size)
3907             break;  /* scratch ? 5 : 6 */
3908           *len = 8;
3909           return (AS2 (mov,__tmp_reg__,%A0) CR_TAB
3910                   AS2 (mov,%A0,%B0)         CR_TAB
3911                   AS1 (lsl,__tmp_reg__)     CR_TAB
3912                   AS1 (rol,%A0)             CR_TAB
3913                   AS2 (sbc,%B0,%B0)         CR_TAB
3914                   AS1 (lsl,__tmp_reg__)     CR_TAB
3915                   AS1 (rol,%A0)             CR_TAB
3916                   AS1 (rol,%B0));
3917
3918         case 7:
3919           *len = 4;
3920           return (AS1 (lsl,%A0)     CR_TAB
3921                   AS2 (mov,%A0,%B0) CR_TAB
3922                   AS1 (rol,%A0)     CR_TAB
3923                   AS2 (sbc,%B0,%B0));
3924
3925         case 8:
3926           {
3927             int reg0 = true_regnum (operands[0]);
3928             int reg1 = true_regnum (operands[1]);
3929
3930             if (reg0 == reg1)
3931               return *len = 3, (AS2 (mov,%A0,%B0) CR_TAB
3932                                 AS1 (lsl,%B0)     CR_TAB
3933                                 AS2 (sbc,%B0,%B0));
3934             else 
3935               return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB
3936                                 AS1 (clr,%B0)     CR_TAB
3937                                 AS2 (sbrc,%A0,7)  CR_TAB
3938                                 AS1 (dec,%B0));
3939           }
3940
3941         case 9:
3942           *len = 4;
3943           return (AS2 (mov,%A0,%B0) CR_TAB
3944                   AS1 (lsl,%B0)      CR_TAB
3945                   AS2 (sbc,%B0,%B0) CR_TAB
3946                   AS1 (asr,%A0));
3947
3948         case 10:
3949           *len = 5;
3950           return (AS2 (mov,%A0,%B0) CR_TAB
3951                   AS1 (lsl,%B0)     CR_TAB
3952                   AS2 (sbc,%B0,%B0) CR_TAB
3953                   AS1 (asr,%A0)     CR_TAB
3954                   AS1 (asr,%A0));
3955
3956         case 11:
3957           if (AVR_HAVE_MUL && ldi_ok)
3958             {
3959               *len = 5;
3960               return (AS2 (ldi,%A0,0x20) CR_TAB
3961                       AS2 (muls,%B0,%A0) CR_TAB
3962                       AS2 (mov,%A0,r1)   CR_TAB
3963                       AS2 (sbc,%B0,%B0)  CR_TAB
3964                       AS1 (clr,__zero_reg__));
3965             }
3966           if (optimize_size && scratch)
3967             break;  /* 5 */
3968           *len = 6;
3969           return (AS2 (mov,%A0,%B0) CR_TAB
3970                   AS1 (lsl,%B0)     CR_TAB
3971                   AS2 (sbc,%B0,%B0) CR_TAB
3972                   AS1 (asr,%A0)     CR_TAB
3973                   AS1 (asr,%A0)     CR_TAB
3974                   AS1 (asr,%A0));
3975
3976         case 12:
3977           if (AVR_HAVE_MUL && ldi_ok)
3978             {
3979               *len = 5;
3980               return (AS2 (ldi,%A0,0x10) CR_TAB
3981                       AS2 (muls,%B0,%A0) CR_TAB
3982                       AS2 (mov,%A0,r1)   CR_TAB
3983                       AS2 (sbc,%B0,%B0)  CR_TAB
3984                       AS1 (clr,__zero_reg__));
3985             }
3986           if (optimize_size && scratch)
3987             break;  /* 5 */
3988           *len = 7;
3989           return (AS2 (mov,%A0,%B0) CR_TAB
3990                   AS1 (lsl,%B0)     CR_TAB
3991                   AS2 (sbc,%B0,%B0) CR_TAB
3992                   AS1 (asr,%A0)     CR_TAB
3993                   AS1 (asr,%A0)     CR_TAB
3994                   AS1 (asr,%A0)     CR_TAB
3995                   AS1 (asr,%A0));
3996
3997         case 13:
3998           if (AVR_HAVE_MUL && ldi_ok)
3999             {
4000               *len = 5;
4001               return (AS2 (ldi,%A0,0x08) CR_TAB
4002                       AS2 (muls,%B0,%A0) CR_TAB
4003                       AS2 (mov,%A0,r1)   CR_TAB
4004                       AS2 (sbc,%B0,%B0)  CR_TAB
4005                       AS1 (clr,__zero_reg__));
4006             }
4007           if (optimize_size)
4008             break;  /* scratch ? 5 : 7 */
4009           *len = 8;
4010           return (AS2 (mov,%A0,%B0) CR_TAB
4011                   AS1 (lsl,%B0)     CR_TAB
4012                   AS2 (sbc,%B0,%B0) CR_TAB
4013                   AS1 (asr,%A0)     CR_TAB
4014                   AS1 (asr,%A0)     CR_TAB
4015                   AS1 (asr,%A0)     CR_TAB
4016                   AS1 (asr,%A0)     CR_TAB
4017                   AS1 (asr,%A0));
4018
4019         case 14:
4020           *len = 5;
4021           return (AS1 (lsl,%B0)     CR_TAB
4022                   AS2 (sbc,%A0,%A0) CR_TAB
4023                   AS1 (lsl,%B0)     CR_TAB
4024                   AS2 (mov,%B0,%A0) CR_TAB
4025                   AS1 (rol,%A0));
4026
4027         default:
4028           if (INTVAL (operands[2]) < 16)
4029             break;
4030
4031           /* fall through */
4032
4033         case 15:
4034           return *len = 3, (AS1 (lsl,%B0)     CR_TAB
4035                             AS2 (sbc,%A0,%A0) CR_TAB
4036                             AS2 (mov,%B0,%A0));
4037         }
4038       len = t;
4039     }
4040   out_shift_with_cnt ((AS1 (asr,%B0) CR_TAB
4041                        AS1 (ror,%A0)),
4042                        insn, operands, len, 2);
4043   return "";
4044 }
4045
4046
4047 /* 32bit arithmetic shift right  ((signed long)x >> i) */
4048
4049 const char *
4050 ashrsi3_out (rtx insn, rtx operands[], int *len)
4051 {
4052   if (GET_CODE (operands[2]) == CONST_INT)
4053     {
4054       int k;
4055       int *t = len;
4056       
4057       if (!len)
4058         len = &k;
4059       
4060       switch (INTVAL (operands[2]))
4061         {
4062         case 8:
4063           {
4064             int reg0 = true_regnum (operands[0]);
4065             int reg1 = true_regnum (operands[1]);
4066             *len=6;
4067             if (reg0 <= reg1)
4068               return (AS2 (mov,%A0,%B1) CR_TAB
4069                       AS2 (mov,%B0,%C1) CR_TAB
4070                       AS2 (mov,%C0,%D1) CR_TAB
4071                       AS1 (clr,%D0)     CR_TAB
4072                       AS2 (sbrc,%C0,7)  CR_TAB
4073                       AS1 (dec,%D0));
4074             else
4075               return (AS1 (clr,%D0)     CR_TAB
4076                       AS2 (sbrc,%D1,7)  CR_TAB
4077                       AS1 (dec,%D0)     CR_TAB
4078                       AS2 (mov,%C0,%D1) CR_TAB
4079                       AS2 (mov,%B0,%C1) CR_TAB
4080                       AS2 (mov,%A0,%B1));
4081           }
4082           
4083         case 16:
4084           {
4085             int reg0 = true_regnum (operands[0]);
4086             int reg1 = true_regnum (operands[1]);
4087             
4088             if (reg0 == reg1 + 2)
4089               return *len = 4, (AS1 (clr,%D0)     CR_TAB
4090                                 AS2 (sbrc,%B0,7)  CR_TAB
4091                                 AS1 (com,%D0)     CR_TAB
4092                                 AS2 (mov,%C0,%D0));
4093             if (AVR_HAVE_MOVW)
4094               return *len = 5, (AS2 (movw,%A0,%C1) CR_TAB
4095                                 AS1 (clr,%D0)      CR_TAB
4096                                 AS2 (sbrc,%B0,7)   CR_TAB
4097                                 AS1 (com,%D0)      CR_TAB
4098                                 AS2 (mov,%C0,%D0));
4099             else 
4100               return *len = 6, (AS2 (mov,%B0,%D1) CR_TAB
4101                                 AS2 (mov,%A0,%C1) CR_TAB
4102                                 AS1 (clr,%D0)     CR_TAB
4103                                 AS2 (sbrc,%B0,7)  CR_TAB
4104                                 AS1 (com,%D0)     CR_TAB
4105                                 AS2 (mov,%C0,%D0));
4106           }
4107
4108         case 24:
4109           return *len = 6, (AS2 (mov,%A0,%D1) CR_TAB
4110                             AS1 (clr,%D0)     CR_TAB
4111                             AS2 (sbrc,%A0,7)  CR_TAB
4112                             AS1 (com,%D0)     CR_TAB
4113                             AS2 (mov,%B0,%D0) CR_TAB
4114                             AS2 (mov,%C0,%D0));
4115
4116         default:
4117           if (INTVAL (operands[2]) < 32)
4118             break;
4119
4120           /* fall through */
4121
4122         case 31:
4123           if (AVR_HAVE_MOVW)
4124             return *len = 4, (AS1 (lsl,%D0)     CR_TAB
4125                               AS2 (sbc,%A0,%A0) CR_TAB
4126                               AS2 (mov,%B0,%A0) CR_TAB
4127                               AS2 (movw,%C0,%A0));
4128           else
4129             return *len = 5, (AS1 (lsl,%D0)     CR_TAB
4130                               AS2 (sbc,%A0,%A0) CR_TAB
4131                               AS2 (mov,%B0,%A0) CR_TAB
4132                               AS2 (mov,%C0,%A0) CR_TAB
4133                               AS2 (mov,%D0,%A0));
4134         }
4135       len = t;
4136     }
4137   out_shift_with_cnt ((AS1 (asr,%D0) CR_TAB
4138                        AS1 (ror,%C0) CR_TAB
4139                        AS1 (ror,%B0) CR_TAB
4140                        AS1 (ror,%A0)),
4141                        insn, operands, len, 4);
4142   return "";
4143 }
4144
4145 /* 8bit logic shift right ((unsigned char)x >> i) */
4146
4147 const char *
4148 lshrqi3_out (rtx insn, rtx operands[], int *len)
4149 {
4150   if (GET_CODE (operands[2]) == CONST_INT)
4151     {
4152       int k;
4153
4154       if (!len)
4155         len = &k;
4156       
4157       switch (INTVAL (operands[2]))
4158         {
4159         default:
4160           if (INTVAL (operands[2]) < 8)
4161             break;
4162
4163           *len = 1;
4164           return AS1 (clr,%0);
4165
4166         case 1:
4167           *len = 1;
4168           return AS1 (lsr,%0);
4169
4170         case 2:
4171           *len = 2;
4172           return (AS1 (lsr,%0) CR_TAB
4173                   AS1 (lsr,%0));
4174         case 3:
4175           *len = 3;
4176           return (AS1 (lsr,%0) CR_TAB
4177                   AS1 (lsr,%0) CR_TAB
4178                   AS1 (lsr,%0));
4179           
4180         case 4:
4181           if (test_hard_reg_class (LD_REGS, operands[0]))
4182             {
4183               *len=2;
4184               return (AS1 (swap,%0) CR_TAB
4185                       AS2 (andi,%0,0x0f));
4186             }
4187           *len = 4;
4188           return (AS1 (lsr,%0) CR_TAB
4189                   AS1 (lsr,%0) CR_TAB
4190                   AS1 (lsr,%0) CR_TAB
4191                   AS1 (lsr,%0));
4192           
4193         case 5:
4194           if (test_hard_reg_class (LD_REGS, operands[0]))
4195             {
4196               *len = 3;
4197               return (AS1 (swap,%0) CR_TAB
4198                       AS1 (lsr,%0)  CR_TAB
4199                       AS2 (andi,%0,0x7));
4200             }
4201           *len = 5;
4202           return (AS1 (lsr,%0) CR_TAB
4203                   AS1 (lsr,%0) CR_TAB
4204                   AS1 (lsr,%0) CR_TAB
4205                   AS1 (lsr,%0) CR_TAB
4206                   AS1 (lsr,%0));
4207           
4208         case 6:
4209           if (test_hard_reg_class (LD_REGS, operands[0]))
4210             {
4211               *len = 4;
4212               return (AS1 (swap,%0) CR_TAB
4213                       AS1 (lsr,%0)  CR_TAB
4214                       AS1 (lsr,%0)  CR_TAB
4215                       AS2 (andi,%0,0x3));
4216             }
4217           *len = 6;
4218           return (AS1 (lsr,%0) CR_TAB
4219                   AS1 (lsr,%0) CR_TAB
4220                   AS1 (lsr,%0) CR_TAB
4221                   AS1 (lsr,%0) CR_TAB
4222                   AS1 (lsr,%0) CR_TAB
4223                   AS1 (lsr,%0));
4224           
4225         case 7:
4226           *len = 3;
4227           return (AS1 (rol,%0) CR_TAB
4228                   AS1 (clr,%0) CR_TAB
4229                   AS1 (rol,%0));
4230         }
4231     }
4232   else if (CONSTANT_P (operands[2]))
4233     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
4234   
4235   out_shift_with_cnt (AS1 (lsr,%0),
4236                       insn, operands, len, 1);
4237   return "";
4238 }
4239
4240 /* 16bit logic shift right ((unsigned short)x >> i) */
4241
4242 const char *
4243 lshrhi3_out (rtx insn, rtx operands[], int *len)
4244 {
4245   if (GET_CODE (operands[2]) == CONST_INT)
4246     {
4247       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
4248       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
4249       int k;
4250       int *t = len;
4251
4252       if (!len)
4253         len = &k;
4254       
4255       switch (INTVAL (operands[2]))
4256         {
4257         default:
4258           if (INTVAL (operands[2]) < 16)
4259             break;
4260
4261           *len = 2;
4262           return (AS1 (clr,%B0) CR_TAB
4263                   AS1 (clr,%A0));
4264
4265         case 4:
4266           if (optimize_size && scratch)
4267             break;  /* 5 */
4268           if (ldi_ok)
4269             {
4270               *len = 6;
4271               return (AS1 (swap,%B0)      CR_TAB
4272                       AS1 (swap,%A0)      CR_TAB
4273                       AS2 (andi,%A0,0x0f) CR_TAB
4274                       AS2 (eor,%A0,%B0)   CR_TAB
4275                       AS2 (andi,%B0,0x0f) CR_TAB
4276                       AS2 (eor,%A0,%B0));
4277             }
4278           if (scratch)
4279             {
4280               *len = 7;
4281               return (AS1 (swap,%B0)    CR_TAB
4282                       AS1 (swap,%A0)    CR_TAB
4283                       AS2 (ldi,%3,0x0f) CR_TAB
4284                       "and %A0,%3"      CR_TAB
4285                       AS2 (eor,%A0,%B0) CR_TAB
4286                       "and %B0,%3"      CR_TAB
4287                       AS2 (eor,%A0,%B0));
4288             }
4289           break;  /* optimize_size ? 6 : 8 */
4290
4291         case 5:
4292           if (optimize_size)
4293             break;  /* scratch ? 5 : 6 */
4294           if (ldi_ok)
4295             {
4296               *len = 8;
4297               return (AS1 (lsr,%B0)       CR_TAB
4298                       AS1 (ror,%A0)       CR_TAB
4299                       AS1 (swap,%B0)      CR_TAB
4300                       AS1 (swap,%A0)      CR_TAB
4301                       AS2 (andi,%A0,0x0f) CR_TAB
4302                       AS2 (eor,%A0,%B0)   CR_TAB
4303                       AS2 (andi,%B0,0x0f) CR_TAB
4304                       AS2 (eor,%A0,%B0));
4305             }
4306           if (scratch)
4307             {
4308               *len = 9;
4309               return (AS1 (lsr,%B0)     CR_TAB
4310                       AS1 (ror,%A0)     CR_TAB
4311                       AS1 (swap,%B0)    CR_TAB
4312                       AS1 (swap,%A0)    CR_TAB
4313                       AS2 (ldi,%3,0x0f) CR_TAB
4314                       "and %A0,%3"      CR_TAB
4315                       AS2 (eor,%A0,%B0) CR_TAB
4316                       "and %B0,%3"      CR_TAB
4317                       AS2 (eor,%A0,%B0));
4318             }
4319           break;  /* 10 */
4320
4321         case 6:
4322           if (optimize_size)
4323             break;  /* scratch ? 5 : 6 */
4324           *len = 9;
4325           return (AS1 (clr,__tmp_reg__) CR_TAB
4326                   AS1 (lsl,%A0)         CR_TAB
4327                   AS1 (rol,%B0)         CR_TAB
4328                   AS1 (rol,__tmp_reg__) CR_TAB
4329                   AS1 (lsl,%A0)         CR_TAB
4330                   AS1 (rol,%B0)         CR_TAB
4331                   AS1 (rol,__tmp_reg__) CR_TAB
4332                   AS2 (mov,%A0,%B0)     CR_TAB
4333                   AS2 (mov,%B0,__tmp_reg__));
4334
4335         case 7:
4336           *len = 5;
4337           return (AS1 (lsl,%A0)     CR_TAB
4338                   AS2 (mov,%A0,%B0) CR_TAB
4339                   AS1 (rol,%A0)     CR_TAB
4340                   AS2 (sbc,%B0,%B0) CR_TAB
4341                   AS1 (neg,%B0));
4342
4343         case 8:
4344           return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB
4345                             AS1 (clr,%B0));
4346
4347         case 9:
4348           *len = 3;
4349           return (AS2 (mov,%A0,%B0) CR_TAB
4350                   AS1 (clr,%B0)     CR_TAB
4351                   AS1 (lsr,%A0));
4352
4353         case 10:
4354           *len = 4;
4355           return (AS2 (mov,%A0,%B0) CR_TAB
4356                   AS1 (clr,%B0)     CR_TAB
4357                   AS1 (lsr,%A0)     CR_TAB
4358                   AS1 (lsr,%A0));
4359
4360         case 11:
4361           *len = 5;
4362           return (AS2 (mov,%A0,%B0) CR_TAB
4363                   AS1 (clr,%B0)     CR_TAB
4364                   AS1 (lsr,%A0)     CR_TAB
4365                   AS1 (lsr,%A0)     CR_TAB
4366                   AS1 (lsr,%A0));
4367
4368         case 12:
4369           if (ldi_ok)
4370             {
4371               *len = 4;
4372               return (AS2 (mov,%A0,%B0) CR_TAB
4373                       AS1 (clr,%B0)     CR_TAB
4374                       AS1 (swap,%A0)    CR_TAB
4375                       AS2 (andi,%A0,0x0f));
4376             }
4377           if (scratch)
4378             {
4379               *len = 5;
4380               return (AS2 (mov,%A0,%B0) CR_TAB
4381                       AS1 (clr,%B0)     CR_TAB
4382                       AS1 (swap,%A0)    CR_TAB
4383                       AS2 (ldi,%3,0x0f) CR_TAB
4384                       "and %A0,%3");
4385             }
4386           *len = 6;
4387           return (AS2 (mov,%A0,%B0) CR_TAB
4388                   AS1 (clr,%B0)     CR_TAB
4389                   AS1 (lsr,%A0)     CR_TAB
4390                   AS1 (lsr,%A0)     CR_TAB
4391                   AS1 (lsr,%A0)     CR_TAB
4392                   AS1 (lsr,%A0));
4393
4394         case 13:
4395           if (ldi_ok)
4396             {
4397               *len = 5;
4398               return (AS2 (mov,%A0,%B0) CR_TAB
4399                       AS1 (clr,%B0)     CR_TAB
4400                       AS1 (swap,%A0)    CR_TAB
4401                       AS1 (lsr,%A0)     CR_TAB
4402                       AS2 (andi,%A0,0x07));
4403             }
4404           if (AVR_HAVE_MUL && scratch)
4405             {
4406               *len = 5;
4407               return (AS2 (ldi,%3,0x08) CR_TAB
4408                       AS2 (mul,%B0,%3)  CR_TAB
4409                       AS2 (mov,%A0,r1)  CR_TAB
4410                       AS1 (clr,%B0)     CR_TAB
4411                       AS1 (clr,__zero_reg__));
4412             }
4413           if (optimize_size && scratch)
4414             break;  /* 5 */
4415           if (scratch)
4416             {
4417               *len = 6;
4418               return (AS2 (mov,%A0,%B0) CR_TAB
4419                       AS1 (clr,%B0)     CR_TAB
4420                       AS1 (swap,%A0)    CR_TAB
4421                       AS1 (lsr,%A0)     CR_TAB
4422                       AS2 (ldi,%3,0x07) CR_TAB
4423                       "and %A0,%3");
4424             }
4425           if (AVR_HAVE_MUL)
4426             {
4427               *len = 6;
4428               return ("set"            CR_TAB
4429                       AS2 (bld,r1,3)   CR_TAB
4430                       AS2 (mul,%B0,r1) CR_TAB
4431                       AS2 (mov,%A0,r1) CR_TAB
4432                       AS1 (clr,%B0)    CR_TAB
4433                       AS1 (clr,__zero_reg__));
4434             }
4435           *len = 7;
4436           return (AS2 (mov,%A0,%B0) CR_TAB
4437                   AS1 (clr,%B0)     CR_TAB
4438                   AS1 (lsr,%A0)     CR_TAB
4439                   AS1 (lsr,%A0)     CR_TAB
4440                   AS1 (lsr,%A0)     CR_TAB
4441                   AS1 (lsr,%A0)     CR_TAB
4442                   AS1 (lsr,%A0));
4443
4444         case 14:
4445           if (AVR_HAVE_MUL && ldi_ok)
4446             {
4447               *len = 5;
4448               return (AS2 (ldi,%A0,0x04) CR_TAB
4449                       AS2 (mul,%B0,%A0)  CR_TAB
4450                       AS2 (mov,%A0,r1)   CR_TAB
4451                       AS1 (clr,%B0)      CR_TAB
4452                       AS1 (clr,__zero_reg__));
4453             }
4454           if (AVR_HAVE_MUL && scratch)
4455             {
4456               *len = 5;
4457               return (AS2 (ldi,%3,0x04) CR_TAB
4458                       AS2 (mul,%B0,%3)  CR_TAB
4459                       AS2 (mov,%A0,r1)  CR_TAB
4460                       AS1 (clr,%B0)     CR_TAB
4461                       AS1 (clr,__zero_reg__));
4462             }
4463           if (optimize_size && ldi_ok)
4464             {
4465               *len = 5;
4466               return (AS2 (mov,%A0,%B0) CR_TAB
4467                       AS2 (ldi,%B0,6) "\n1:\t"
4468                       AS1 (lsr,%A0)     CR_TAB
4469                       AS1 (dec,%B0)     CR_TAB
4470                       AS1 (brne,1b));
4471             }
4472           if (optimize_size && scratch)
4473             break;  /* 5 */
4474           *len = 6;
4475           return (AS1 (clr,%A0) CR_TAB
4476                   AS1 (lsl,%B0) CR_TAB
4477                   AS1 (rol,%A0) CR_TAB
4478                   AS1 (lsl,%B0) CR_TAB
4479                   AS1 (rol,%A0) CR_TAB
4480                   AS1 (clr,%B0));
4481
4482         case 15:
4483           *len = 4;
4484           return (AS1 (clr,%A0) CR_TAB
4485                   AS1 (lsl,%B0) CR_TAB
4486                   AS1 (rol,%A0) CR_TAB
4487                   AS1 (clr,%B0));
4488         }
4489       len = t;
4490     }
4491   out_shift_with_cnt ((AS1 (lsr,%B0) CR_TAB
4492                        AS1 (ror,%A0)),
4493                        insn, operands, len, 2);
4494   return "";
4495 }
4496
4497 /* 32bit logic shift right ((unsigned int)x >> i) */
4498
4499 const char *
4500 lshrsi3_out (rtx insn, rtx operands[], int *len)
4501 {
4502   if (GET_CODE (operands[2]) == CONST_INT)
4503     {
4504       int k;
4505       int *t = len;
4506       
4507       if (!len)
4508         len = &k;
4509       
4510       switch (INTVAL (operands[2]))
4511         {
4512         default:
4513           if (INTVAL (operands[2]) < 32)
4514             break;
4515
4516           if (AVR_HAVE_MOVW)
4517             return *len = 3, (AS1 (clr,%D0) CR_TAB
4518                               AS1 (clr,%C0) CR_TAB
4519                               AS2 (movw,%A0,%C0));
4520           *len = 4;
4521           return (AS1 (clr,%D0) CR_TAB
4522                   AS1 (clr,%C0) CR_TAB
4523                   AS1 (clr,%B0) CR_TAB
4524                   AS1 (clr,%A0));
4525
4526         case 8:
4527           {
4528             int reg0 = true_regnum (operands[0]);
4529             int reg1 = true_regnum (operands[1]);
4530             *len = 4;
4531             if (reg0 <= reg1)
4532               return (AS2 (mov,%A0,%B1) CR_TAB
4533                       AS2 (mov,%B0,%C1) CR_TAB
4534                       AS2 (mov,%C0,%D1) CR_TAB
4535                       AS1 (clr,%D0));
4536             else
4537               return (AS1 (clr,%D0)     CR_TAB
4538                       AS2 (mov,%C0,%D1) CR_TAB
4539                       AS2 (mov,%B0,%C1) CR_TAB
4540                       AS2 (mov,%A0,%B1)); 
4541           }
4542           
4543         case 16:
4544           {
4545             int reg0 = true_regnum (operands[0]);
4546             int reg1 = true_regnum (operands[1]);
4547
4548             if (reg0 == reg1 + 2)
4549               return *len = 2, (AS1 (clr,%C0)     CR_TAB
4550                                 AS1 (clr,%D0));
4551             if (AVR_HAVE_MOVW)
4552               return *len = 3, (AS2 (movw,%A0,%C1) CR_TAB
4553                                 AS1 (clr,%C0)      CR_TAB
4554                                 AS1 (clr,%D0));
4555             else
4556               return *len = 4, (AS2 (mov,%B0,%D1) CR_TAB
4557                                 AS2 (mov,%A0,%C1) CR_TAB
4558                                 AS1 (clr,%C0)     CR_TAB
4559                                 AS1 (clr,%D0));
4560           }
4561           
4562         case 24:
4563           return *len = 4, (AS2 (mov,%A0,%D1) CR_TAB
4564                             AS1 (clr,%B0)     CR_TAB
4565                             AS1 (clr,%C0)     CR_TAB
4566                             AS1 (clr,%D0));
4567
4568         case 31:
4569           *len = 6;
4570           return (AS1 (clr,%A0)    CR_TAB
4571                   AS2 (sbrc,%D0,7) CR_TAB
4572                   AS1 (inc,%A0)    CR_TAB
4573                   AS1 (clr,%B0)    CR_TAB
4574                   AS1 (clr,%C0)    CR_TAB
4575                   AS1 (clr,%D0));
4576         }
4577       len = t;
4578     }
4579   out_shift_with_cnt ((AS1 (lsr,%D0) CR_TAB
4580                        AS1 (ror,%C0) CR_TAB
4581                        AS1 (ror,%B0) CR_TAB
4582                        AS1 (ror,%A0)),
4583                       insn, operands, len, 4);
4584   return "";
4585 }
4586
4587
4588 /* Output addition of register XOP[0] and compile time constant XOP[2]:
4589
4590       XOP[0] = XOP[0] + XOP[2]
4591
4592    and return "".  If PLEN == NULL, print assembler instructions to perform the
4593    addition; otherwise, set *PLEN to the length of the instruction sequence (in
4594    words) printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register.
4595    CODE == PLUS:  perform addition by using ADD instructions.
4596    CODE == MINUS: perform addition by using SUB instructions.  */
4597
4598 static void
4599 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code)
4600 {
4601   /* MODE of the operation.  */
4602   enum machine_mode mode = GET_MODE (xop[0]);
4603
4604   /* Number of bytes to operate on.  */
4605   int i, n_bytes = GET_MODE_SIZE (mode);
4606
4607   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
4608   int clobber_val = -1;
4609
4610   /* op[0]: 8-bit destination register
4611      op[1]: 8-bit const int
4612      op[2]: 8-bit scratch register */
4613   rtx op[3];
4614
4615   /* Started the operation?  Before starting the operation we may skip
4616      adding 0.  This is no more true after the operation started because
4617      carry must be taken into account.  */
4618   bool started = false;
4619
4620   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
4621   rtx xval = xop[2];
4622
4623   if (MINUS == code)
4624     xval = gen_int_mode (-UINTVAL (xval), mode);
4625
4626   op[2] = xop[3];
4627
4628   if (plen)
4629     *plen = 0;
4630
4631   for (i = 0; i < n_bytes; i++)
4632     {
4633       /* We operate byte-wise on the destination.  */
4634       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
4635       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
4636
4637       /* 8-bit value to operate with this byte. */
4638       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4639
4640       /* Registers R16..R31 can operate with immediate.  */
4641       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4642
4643       op[0] = reg8;
4644       op[1] = GEN_INT (val8);
4645       
4646       if (!started && i % 2 == 0
4647           && test_hard_reg_class (ADDW_REGS, reg8))
4648         {
4649           rtx xval16 = simplify_gen_subreg (HImode, xval, mode, i);
4650           unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
4651
4652           /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
4653              i.e. operate word-wise.  */
4654
4655           if (val16 < 64)
4656             {
4657               if (val16 != 0)
4658                 {
4659                   started = true;
4660                   avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
4661                                op, plen, 1);
4662                 }
4663
4664               i++;
4665               continue;
4666             }
4667         }
4668
4669       if (val8 == 0)
4670         {
4671           if (started)
4672             avr_asm_len (code == PLUS
4673                          ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
4674                          op, plen, 1);
4675           continue;
4676         }
4677
4678       switch (code)
4679         {
4680         case PLUS:
4681
4682           gcc_assert (plen != NULL || REG_P (op[2]));
4683
4684           if (clobber_val != (int) val8)
4685             avr_asm_len ("ldi %2,%1", op, plen, 1);
4686           clobber_val = (int) val8;
4687               
4688           avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
4689
4690           break; /* PLUS */
4691
4692         case MINUS:
4693
4694           if (ld_reg_p)
4695             avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
4696           else
4697             {
4698               gcc_assert (plen != NULL || REG_P (op[2]));
4699
4700               if (clobber_val != (int) val8)
4701                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4702               clobber_val = (int) val8;
4703               
4704               avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
4705             }
4706
4707           break; /* MINUS */
4708           
4709         default:
4710           /* Unknown code */
4711           gcc_unreachable();
4712         }
4713
4714       started = true;
4715
4716     } /* for all sub-bytes */
4717 }
4718
4719
4720 /* Output addition of register XOP[0] and compile time constant XOP[2]:
4721
4722       XOP[0] = XOP[0] + XOP[2]
4723
4724    and return "".  If PLEN == NULL, print assembler instructions to perform the
4725    addition; otherwise, set *PLEN to the length of the instruction sequence (in
4726    words) printed with PLEN == NULL.  */
4727
4728 const char*
4729 avr_out_plus (rtx *xop, int *plen)
4730 {
4731   int len_plus, len_minus;
4732
4733   /* Work out if  XOP[0] += XOP[2]  is better or  XOP[0] -= -XOP[2].  */
4734   
4735   avr_out_plus_1 (xop, &len_plus, PLUS);
4736   avr_out_plus_1 (xop, &len_minus, MINUS);
4737
4738   if (plen)
4739     *plen = (len_minus <= len_plus) ? len_minus : len_plus;
4740   else if (len_minus <= len_plus)
4741     avr_out_plus_1 (xop, NULL, MINUS);
4742   else
4743     avr_out_plus_1 (xop, NULL, PLUS);
4744
4745   return "";
4746 }
4747
4748
4749 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
4750    time constant XOP[2]:
4751
4752       XOP[0] = XOP[0] <op> XOP[2]
4753
4754    and return "".  If PLEN == NULL, print assembler instructions to perform the
4755    operation; otherwise, set *PLEN to the length of the instruction sequence
4756    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
4757    register or SCRATCH if no clobber register is needed for the operation.  */
4758
4759 const char*
4760 avr_out_bitop (rtx insn, rtx *xop, int *plen)
4761 {
4762   /* CODE and MODE of the operation.  */
4763   enum rtx_code code = GET_CODE (SET_SRC (single_set (insn)));
4764   enum machine_mode mode = GET_MODE (xop[0]);
4765
4766   /* Number of bytes to operate on.  */
4767   int i, n_bytes = GET_MODE_SIZE (mode);
4768
4769   /* Value of T-flag (0 or 1) or -1 if unknow.  */
4770   int set_t = -1;
4771
4772   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
4773   int clobber_val = -1;
4774
4775   /* op[0]: 8-bit destination register
4776      op[1]: 8-bit const int
4777      op[2]: 8-bit clobber register or SCRATCH
4778      op[3]: 8-bit register containing 0xff or NULL_RTX  */
4779   rtx op[4];
4780
4781   op[2] = xop[3];
4782   op[3] = NULL_RTX;
4783
4784   if (plen)
4785     *plen = 0;
4786
4787   for (i = 0; i < n_bytes; i++)
4788     {
4789       /* We operate byte-wise on the destination.  */
4790       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
4791       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
4792
4793       /* 8-bit value to operate with this byte. */
4794       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
4795
4796       /* Number of bits set in the current byte of the constant.  */
4797       int pop8 = avr_popcount (val8);
4798
4799       /* Registers R16..R31 can operate with immediate.  */
4800       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
4801
4802       op[0] = reg8;
4803       op[1] = GEN_INT (val8);
4804     
4805       switch (code)
4806         {
4807         case IOR:
4808
4809           if (0 == pop8)
4810             continue;
4811           else if (ld_reg_p)
4812             avr_asm_len ("ori %0,%1", op, plen, 1);
4813           else if (1 == pop8)
4814             {
4815               if (set_t != 1)
4816                 avr_asm_len ("set", op, plen, 1);
4817               set_t = 1;
4818               
4819               op[1] = GEN_INT (exact_log2 (val8));
4820               avr_asm_len ("bld %0,%1", op, plen, 1);
4821             }
4822           else if (8 == pop8)
4823             {
4824               if (op[3] != NULL_RTX)
4825                 avr_asm_len ("mov %0,%3", op, plen, 1);
4826               else
4827                 avr_asm_len ("clr %0" CR_TAB
4828                              "dec %0", op, plen, 2);
4829
4830               op[3] = op[0];
4831             }
4832           else
4833             {
4834               if (clobber_val != (int) val8)
4835                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4836               clobber_val = (int) val8;
4837               
4838               avr_asm_len ("or %0,%2", op, plen, 1);
4839             }
4840
4841           continue; /* IOR */
4842
4843         case AND:
4844
4845           if (8 == pop8)
4846             continue;
4847           else if (0 == pop8)
4848             avr_asm_len ("clr %0", op, plen, 1);
4849           else if (ld_reg_p)
4850             avr_asm_len ("andi %0,%1", op, plen, 1);
4851           else if (7 == pop8)
4852             {
4853               if (set_t != 0)
4854                 avr_asm_len ("clt", op, plen, 1);
4855               set_t = 0;
4856               
4857               op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
4858               avr_asm_len ("bld %0,%1", op, plen, 1);
4859             }
4860           else
4861             {
4862               if (clobber_val != (int) val8)
4863                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4864               clobber_val = (int) val8;
4865               
4866               avr_asm_len ("and %0,%2", op, plen, 1);
4867             }
4868
4869           continue; /* AND */
4870           
4871         case XOR:
4872
4873           if (0 == pop8)
4874             continue;
4875           else if (8 == pop8)
4876             avr_asm_len ("com %0", op, plen, 1);
4877           else if (ld_reg_p && val8 == (1 << 7))
4878             avr_asm_len ("subi %0,%1", op, plen, 1);
4879           else
4880             {
4881               if (clobber_val != (int) val8)
4882                 avr_asm_len ("ldi %2,%1", op, plen, 1);
4883               clobber_val = (int) val8;
4884               
4885               avr_asm_len ("eor %0,%2", op, plen, 1);
4886             }
4887
4888           continue; /* XOR */
4889           
4890         default:
4891           /* Unknown rtx_code */
4892           gcc_unreachable();
4893         }
4894     } /* for all sub-bytes */
4895
4896   return "";
4897 }
4898
4899 /* Create RTL split patterns for byte sized rotate expressions.  This
4900   produces a series of move instructions and considers overlap situations.
4901   Overlapping non-HImode operands need a scratch register.  */
4902
4903 bool
4904 avr_rotate_bytes (rtx operands[])
4905 {
4906     int i, j;
4907     enum machine_mode mode = GET_MODE (operands[0]);
4908     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
4909     bool same_reg = rtx_equal_p (operands[0], operands[1]);
4910     int num = INTVAL (operands[2]);
4911     rtx scratch = operands[3];
4912     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
4913        Word move if no scratch is needed, otherwise use size of scratch.  */
4914     enum machine_mode move_mode = QImode;
4915     int move_size, offset, size;
4916
4917     if (num & 0xf)
4918       move_mode = QImode;
4919     else if ((mode == SImode && !same_reg) || !overlapped)
4920       move_mode = HImode;
4921     else
4922       move_mode = GET_MODE (scratch);
4923
4924     /* Force DI rotate to use QI moves since other DI moves are currently split
4925        into QI moves so forward propagation works better.  */
4926     if (mode == DImode)
4927       move_mode = QImode;
4928     /* Make scratch smaller if needed.  */
4929     if (SCRATCH != GET_CODE (scratch)
4930         && HImode == GET_MODE (scratch)
4931         && QImode == move_mode)
4932       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0); 
4933
4934     move_size = GET_MODE_SIZE (move_mode);
4935     /* Number of bytes/words to rotate.  */
4936     offset = (num  >> 3) / move_size;
4937     /* Number of moves needed.  */
4938     size = GET_MODE_SIZE (mode) / move_size;
4939     /* Himode byte swap is special case to avoid a scratch register.  */
4940     if (mode == HImode && same_reg)
4941       {
4942         /* HImode byte swap, using xor.  This is as quick as using scratch.  */
4943         rtx src, dst;
4944         src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
4945         dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
4946         if (!rtx_equal_p (dst, src))
4947           {
4948              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
4949              emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
4950              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
4951           }
4952       }    
4953     else  
4954       {
4955 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
4956         /* Create linked list of moves to determine move order.  */
4957         struct {
4958           rtx src, dst;
4959           int links;
4960         } move[MAX_SIZE + 8];
4961         int blocked, moves;
4962
4963         gcc_assert (size <= MAX_SIZE);
4964         /* Generate list of subreg moves.  */
4965         for (i = 0; i < size; i++)
4966           {
4967             int from = i;
4968             int to = (from + offset) % size;          
4969             move[i].src = simplify_gen_subreg (move_mode, operands[1],
4970                                                 mode, from * move_size);
4971             move[i].dst = simplify_gen_subreg (move_mode, operands[0],
4972                                                 mode, to   * move_size);
4973             move[i].links = -1;
4974            }
4975         /* Mark dependence where a dst of one move is the src of another move.
4976            The first move is a conflict as it must wait until second is
4977            performed.  We ignore moves to self - we catch this later.  */
4978         if (overlapped)
4979           for (i = 0; i < size; i++)
4980             if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
4981               for (j = 0; j < size; j++)
4982                 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
4983                   {
4984                     /* The dst of move i is the src of move j.  */
4985                     move[i].links = j;
4986                     break;
4987                   }
4988
4989         blocked = -1;
4990         moves = 0;
4991         /* Go through move list and perform non-conflicting moves.  As each
4992            non-overlapping move is made, it may remove other conflicts
4993            so the process is repeated until no conflicts remain.  */
4994         do
4995           {
4996             blocked = -1;
4997             moves = 0;
4998             /* Emit move where dst is not also a src or we have used that
4999                src already.  */
5000             for (i = 0; i < size; i++)
5001               if (move[i].src != NULL_RTX)
5002                 {
5003                   if (move[i].links == -1
5004                       || move[move[i].links].src == NULL_RTX)
5005                     {
5006                       moves++;
5007                       /* Ignore NOP moves to self.  */
5008                       if (!rtx_equal_p (move[i].dst, move[i].src))
5009                         emit_move_insn (move[i].dst, move[i].src);
5010
5011                       /* Remove  conflict from list.  */
5012                       move[i].src = NULL_RTX;
5013                     }
5014                   else
5015                     blocked = i;
5016                 }
5017
5018             /* Check for deadlock. This is when no moves occurred and we have
5019                at least one blocked move.  */
5020             if (moves == 0 && blocked != -1)
5021               {
5022                 /* Need to use scratch register to break deadlock.
5023                    Add move to put dst of blocked move into scratch.
5024                    When this move occurs, it will break chain deadlock.
5025                    The scratch register is substituted for real move.  */
5026
5027                 gcc_assert (SCRATCH != GET_CODE (scratch));
5028
5029                 move[size].src = move[blocked].dst;
5030                 move[size].dst =  scratch;
5031                 /* Scratch move is never blocked.  */
5032                 move[size].links = -1; 
5033                 /* Make sure we have valid link.  */
5034                 gcc_assert (move[blocked].links != -1);
5035                 /* Replace src of  blocking move with scratch reg.  */
5036                 move[move[blocked].links].src = scratch;
5037                 /* Make dependent on scratch move occuring.  */
5038                 move[blocked].links = size; 
5039                 size=size+1;
5040               }
5041           }
5042         while (blocked != -1);
5043       }
5044     return true;
5045 }
5046
5047 /* Modifies the length assigned to instruction INSN
5048    LEN is the initially computed length of the insn.  */
5049
5050 int
5051 adjust_insn_length (rtx insn, int len)
5052 {
5053   rtx *op = recog_data.operand;
5054   enum attr_adjust_len adjust_len;
5055
5056   /* Some complex insns don't need length adjustment and therefore
5057      the length need not/must not be adjusted for these insns.
5058      It is easier to state this in an insn attribute "adjust_len" than
5059      to clutter up code here...  */
5060   
5061   if (-1 == recog_memoized (insn))
5062     {
5063       return len;
5064     }
5065
5066   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
5067
5068   adjust_len = get_attr_adjust_len (insn);
5069
5070   if (adjust_len == ADJUST_LEN_NO)
5071     {
5072       /* Nothing to adjust: The length from attribute "length" is fine.
5073          This is the default.  */
5074       
5075       return len;
5076     }
5077   
5078   /* Extract insn's operands.  */
5079   
5080   extract_constrain_insn_cached (insn);
5081   
5082   /* Dispatch to right function.  */
5083   
5084   switch (adjust_len)
5085     {
5086     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
5087     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
5088       
5089     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
5090       
5091     case ADJUST_LEN_OUT_PLUS: avr_out_plus (op, &len); break;
5092       
5093     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
5094     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
5095     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
5096       
5097     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
5098     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
5099     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
5100
5101     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
5102     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
5103     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
5104
5105     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
5106     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
5107     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
5108
5109     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
5110     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
5111     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
5112       
5113     default:
5114       gcc_unreachable();
5115     }
5116   
5117   return len;
5118 }
5119
5120 /* Return nonzero if register REG dead after INSN.  */
5121
5122 int
5123 reg_unused_after (rtx insn, rtx reg)
5124 {
5125   return (dead_or_set_p (insn, reg)
5126           || (REG_P(reg) && _reg_unused_after (insn, reg)));
5127 }
5128
5129 /* Return nonzero if REG is not used after INSN.
5130    We assume REG is a reload reg, and therefore does
5131    not live past labels.  It may live past calls or jumps though.  */
5132
5133 int
5134 _reg_unused_after (rtx insn, rtx reg)
5135 {
5136   enum rtx_code code;
5137   rtx set;
5138
5139   /* If the reg is set by this instruction, then it is safe for our
5140      case.  Disregard the case where this is a store to memory, since
5141      we are checking a register used in the store address.  */
5142   set = single_set (insn);
5143   if (set && GET_CODE (SET_DEST (set)) != MEM
5144       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5145     return 1;
5146
5147   while ((insn = NEXT_INSN (insn)))
5148     {
5149       rtx set;
5150       code = GET_CODE (insn);
5151
5152 #if 0
5153       /* If this is a label that existed before reload, then the register
5154          if dead here.  However, if this is a label added by reorg, then
5155          the register may still be live here.  We can't tell the difference,
5156          so we just ignore labels completely.  */
5157       if (code == CODE_LABEL)
5158         return 1;
5159       /* else */
5160 #endif
5161
5162       if (!INSN_P (insn))
5163         continue;
5164
5165       if (code == JUMP_INSN)
5166         return 0;
5167
5168       /* If this is a sequence, we must handle them all at once.
5169          We could have for instance a call that sets the target register,
5170          and an insn in a delay slot that uses the register.  In this case,
5171          we must return 0.  */
5172       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
5173         {
5174           int i;
5175           int retval = 0;
5176
5177           for (i = 0; i < XVECLEN (PATTERN (insn), 0); i++)
5178             {
5179               rtx this_insn = XVECEXP (PATTERN (insn), 0, i);
5180               rtx set = single_set (this_insn);
5181
5182               if (GET_CODE (this_insn) == CALL_INSN)
5183                 code = CALL_INSN;
5184               else if (GET_CODE (this_insn) == JUMP_INSN)
5185                 {
5186                   if (INSN_ANNULLED_BRANCH_P (this_insn))
5187                     return 0;
5188                   code = JUMP_INSN;
5189                 }
5190
5191               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
5192                 return 0;
5193               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5194                 {
5195                   if (GET_CODE (SET_DEST (set)) != MEM)
5196                     retval = 1;
5197                   else
5198                     return 0;
5199                 }
5200               if (set == 0
5201                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
5202                 return 0;
5203             }
5204           if (retval == 1)
5205             return 1;
5206           else if (code == JUMP_INSN)
5207             return 0;
5208         }
5209
5210       if (code == CALL_INSN)
5211         {
5212           rtx tem;
5213           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
5214             if (GET_CODE (XEXP (tem, 0)) == USE
5215                 && REG_P (XEXP (XEXP (tem, 0), 0))
5216                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
5217               return 0;
5218           if (call_used_regs[REGNO (reg)]) 
5219             return 1;
5220         }
5221
5222       set = single_set (insn);
5223
5224       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
5225         return 0;
5226       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
5227         return GET_CODE (SET_DEST (set)) != MEM;
5228       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
5229         return 0;
5230     }
5231   return 1;
5232 }
5233
5234 /* Target hook for assembling integer objects.  The AVR version needs
5235    special handling for references to certain labels.  */
5236
5237 static bool
5238 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
5239 {
5240   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
5241       && text_segment_operand (x, VOIDmode) )
5242     {
5243       fputs ("\t.word\tgs(", asm_out_file);
5244       output_addr_const (asm_out_file, x);
5245       fputs (")\n", asm_out_file);
5246       return true;
5247     }
5248   return default_assemble_integer (x, size, aligned_p);
5249 }
5250
5251 /* Worker function for ASM_DECLARE_FUNCTION_NAME.  */
5252
5253 void
5254 avr_asm_declare_function_name (FILE *file, const char *name, tree decl)
5255 {
5256
5257   /* If the function has the 'signal' or 'interrupt' attribute, test to
5258      make sure that the name of the function is "__vector_NN" so as to
5259      catch when the user misspells the interrupt vector name.  */
5260
5261   if (cfun->machine->is_interrupt)
5262     {
5263       if (!STR_PREFIX_P (name, "__vector"))
5264         {
5265           warning_at (DECL_SOURCE_LOCATION (decl), 0,
5266                       "%qs appears to be a misspelled interrupt handler",
5267                       name);
5268         }
5269     }
5270   else if (cfun->machine->is_signal)
5271     {
5272       if (!STR_PREFIX_P (name, "__vector"))
5273         {
5274            warning_at (DECL_SOURCE_LOCATION (decl), 0,
5275                        "%qs appears to be a misspelled signal handler",
5276                        name);
5277         }
5278     }
5279
5280   ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
5281   ASM_OUTPUT_LABEL (file, name);
5282 }
5283
5284
5285 /* Return value is nonzero if pseudos that have been
5286    assigned to registers of class CLASS would likely be spilled
5287    because registers of CLASS are needed for spill registers.  */
5288
5289 static bool
5290 avr_class_likely_spilled_p (reg_class_t c)
5291 {
5292   return (c != ALL_REGS && c != ADDW_REGS);
5293 }
5294
5295 /* Valid attributes:
5296    progmem - put data to program memory;
5297    signal - make a function to be hardware interrupt. After function
5298    prologue interrupts are disabled;
5299    interrupt - make a function to be hardware interrupt. After function
5300    prologue interrupts are enabled;
5301    naked     - don't generate function prologue/epilogue and `ret' command.
5302
5303    Only `progmem' attribute valid for type.  */
5304
5305 /* Handle a "progmem" attribute; arguments as in
5306    struct attribute_spec.handler.  */
5307 static tree
5308 avr_handle_progmem_attribute (tree *node, tree name,
5309                               tree args ATTRIBUTE_UNUSED,
5310                               int flags ATTRIBUTE_UNUSED,
5311                               bool *no_add_attrs)
5312 {
5313   if (DECL_P (*node))
5314     {
5315       if (TREE_CODE (*node) == TYPE_DECL)
5316         {
5317           /* This is really a decl attribute, not a type attribute,
5318              but try to handle it for GCC 3.0 backwards compatibility.  */
5319
5320           tree type = TREE_TYPE (*node);
5321           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
5322           tree newtype = build_type_attribute_variant (type, attr);
5323
5324           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
5325           TREE_TYPE (*node) = newtype;
5326           *no_add_attrs = true;
5327         }
5328       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
5329         {
5330           *no_add_attrs = false;
5331         }
5332       else
5333         {
5334           warning (OPT_Wattributes, "%qE attribute ignored",
5335                    name);
5336           *no_add_attrs = true;
5337         }
5338     }
5339
5340   return NULL_TREE;
5341 }
5342
5343 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
5344    struct attribute_spec.handler.  */
5345
5346 static tree
5347 avr_handle_fndecl_attribute (tree *node, tree name,
5348                              tree args ATTRIBUTE_UNUSED,
5349                              int flags ATTRIBUTE_UNUSED,
5350                              bool *no_add_attrs)
5351 {
5352   if (TREE_CODE (*node) != FUNCTION_DECL)
5353     {
5354       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5355                name);
5356       *no_add_attrs = true;
5357     }
5358
5359   return NULL_TREE;
5360 }
5361
5362 static tree
5363 avr_handle_fntype_attribute (tree *node, tree name,
5364                              tree args ATTRIBUTE_UNUSED,
5365                              int flags ATTRIBUTE_UNUSED,
5366                              bool *no_add_attrs)
5367 {
5368   if (TREE_CODE (*node) != FUNCTION_TYPE)
5369     {
5370       warning (OPT_Wattributes, "%qE attribute only applies to functions",
5371                name);
5372       *no_add_attrs = true;
5373     }
5374
5375   return NULL_TREE;
5376 }
5377
5378 /* Look for attribute `progmem' in DECL
5379    if found return 1, otherwise 0.  */
5380
5381 int
5382 avr_progmem_p (tree decl, tree attributes)
5383 {
5384   tree a;
5385
5386   if (TREE_CODE (decl) != VAR_DECL)
5387     return 0;
5388
5389   if (NULL_TREE
5390       != lookup_attribute ("progmem", attributes))
5391     return 1;
5392
5393   a=decl;
5394   do
5395     a = TREE_TYPE(a);
5396   while (TREE_CODE (a) == ARRAY_TYPE);
5397
5398   if (a == error_mark_node)
5399     return 0;
5400
5401   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
5402     return 1;
5403   
5404   return 0;
5405 }
5406
5407 /* Add the section attribute if the variable is in progmem.  */
5408
5409 static void
5410 avr_insert_attributes (tree node, tree *attributes)
5411 {
5412   if (TREE_CODE (node) == VAR_DECL
5413       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
5414       && avr_progmem_p (node, *attributes))
5415     {
5416       tree node0 = node;
5417
5418       /* For C++, we have to peel arrays in order to get correct
5419          determination of readonlyness.  */
5420       
5421       do
5422         node0 = TREE_TYPE (node0);
5423       while (TREE_CODE (node0) == ARRAY_TYPE);
5424
5425       if (error_mark_node == node0)
5426         return;
5427       
5428       if (!TYPE_READONLY (node0))
5429         {
5430           error ("variable %q+D must be const in order to be put into"
5431                  " read-only section by means of %<__attribute__((progmem))%>",
5432                  node);
5433         }
5434     }
5435 }
5436
5437
5438 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
5439 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
5440 /* Track need of __do_clear_bss.  */
5441
5442 void
5443 avr_asm_output_aligned_decl_common (FILE * stream, const_tree decl ATTRIBUTE_UNUSED,
5444                                     const char *name, unsigned HOST_WIDE_INT size,
5445                                     unsigned int align, bool local_p)
5446 {
5447   avr_need_clear_bss_p = true;
5448
5449   if (local_p)
5450     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
5451   else
5452     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
5453 }
5454
5455
5456 /* Unnamed section callback for data_section
5457    to track need of __do_copy_data.  */
5458
5459 static void
5460 avr_output_data_section_asm_op (const void *data)
5461 {
5462   avr_need_copy_data_p = true;
5463   
5464   /* Dispatch to default.  */
5465   output_section_asm_op (data);
5466 }
5467
5468
5469 /* Unnamed section callback for bss_section
5470    to track need of __do_clear_bss.  */
5471
5472 static void
5473 avr_output_bss_section_asm_op (const void *data)
5474 {
5475   avr_need_clear_bss_p = true;
5476   
5477   /* Dispatch to default.  */
5478   output_section_asm_op (data);
5479 }
5480
5481
5482 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
5483
5484 static void
5485 avr_asm_init_sections (void)
5486 {
5487   /* Set up a section for jump tables.  Alignment is handled by
5488      ASM_OUTPUT_BEFORE_CASE_LABEL.  */
5489   
5490   if (AVR_HAVE_JMP_CALL)
5491     {
5492       progmem_swtable_section
5493         = get_unnamed_section (0, output_section_asm_op,
5494                                "\t.section\t.progmem.gcc_sw_table"
5495                                ",\"a\",@progbits");
5496     }
5497   else
5498     {
5499       progmem_swtable_section
5500         = get_unnamed_section (SECTION_CODE, output_section_asm_op,
5501                                "\t.section\t.progmem.gcc_sw_table"
5502                                ",\"ax\",@progbits");
5503     }
5504
5505   progmem_section
5506     = get_unnamed_section (0, output_section_asm_op,
5507                            "\t.section\t.progmem.data,\"a\",@progbits");
5508   
5509   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
5510      resp. `avr_need_copy_data_p'.  */
5511   
5512   readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
5513   data_section->unnamed.callback = avr_output_data_section_asm_op;
5514   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
5515 }
5516
5517
5518 /* Implement `TARGET_ASM_FUNCTION_RODATA_SECTION'.  */
5519
5520 static section*
5521 avr_asm_function_rodata_section (tree decl)
5522 {
5523   /* If a function is unused and optimized out by -ffunction-sections
5524      and --gc-sections, ensure that the same will happen for its jump
5525      tables by putting them into individual sections.  */
5526
5527   unsigned int flags;
5528   section * frodata;
5529
5530   /* Get the frodata section from the default function in varasm.c
5531      but treat function-associated data-like jump tables as code
5532      rather than as user defined data.  AVR has no constant pools.  */
5533   {
5534     int fdata = flag_data_sections;
5535
5536     flag_data_sections = flag_function_sections;
5537     frodata = default_function_rodata_section (decl);
5538     flag_data_sections = fdata;
5539     flags = frodata->common.flags;
5540   }
5541
5542   if (frodata != readonly_data_section
5543       && flags & SECTION_NAMED)
5544     {
5545       /* Adjust section flags and replace section name prefix.  */
5546
5547       unsigned int i;
5548
5549       static const char* const prefix[] =
5550         {
5551           ".rodata",          ".progmem.gcc_sw_table",
5552           ".gnu.linkonce.r.", ".gnu.linkonce.t."
5553         };
5554
5555       for (i = 0; i < sizeof (prefix) / sizeof (*prefix); i += 2)
5556         {
5557           const char * old_prefix = prefix[i];
5558           const char * new_prefix = prefix[i+1];
5559           const char * name = frodata->named.name;
5560
5561           if (STR_PREFIX_P (name, old_prefix))
5562             {
5563               const char *rname = avr_replace_prefix (name, old_prefix, new_prefix);
5564
5565               flags &= ~SECTION_CODE;
5566               flags |= AVR_HAVE_JMP_CALL ? 0 : SECTION_CODE;
5567               
5568               return get_section (rname, flags, frodata->named.decl);
5569             }
5570         }
5571     }
5572         
5573   return progmem_swtable_section;
5574 }
5575
5576
5577 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
5578 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
5579
5580 static void
5581 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
5582 {
5583   if (flags & AVR_SECTION_PROGMEM)
5584     {
5585       const char *old_prefix = ".rodata";
5586       const char *new_prefix = ".progmem.data";
5587       const char *sname = new_prefix;
5588       
5589       if (STR_PREFIX_P (name, old_prefix))
5590         {
5591           sname = avr_replace_prefix (name, old_prefix, new_prefix);
5592         }
5593
5594       default_elf_asm_named_section (sname, flags, decl);
5595
5596       return;
5597     }
5598   
5599   if (!avr_need_copy_data_p)
5600     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
5601                             || STR_PREFIX_P (name, ".rodata")
5602                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
5603   
5604   if (!avr_need_clear_bss_p)
5605     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
5606   
5607   default_elf_asm_named_section (name, flags, decl);
5608 }
5609
5610 static unsigned int
5611 avr_section_type_flags (tree decl, const char *name, int reloc)
5612 {
5613   unsigned int flags = default_section_type_flags (decl, name, reloc);
5614
5615   if (STR_PREFIX_P (name, ".noinit"))
5616     {
5617       if (decl && TREE_CODE (decl) == VAR_DECL
5618           && DECL_INITIAL (decl) == NULL_TREE)
5619         flags |= SECTION_BSS;  /* @nobits */
5620       else
5621         warning (0, "only uninitialized variables can be placed in the "
5622                  ".noinit section");
5623     }
5624
5625   if (decl && DECL_P (decl)
5626       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5627     {
5628       flags &= ~SECTION_WRITE;
5629       flags |= AVR_SECTION_PROGMEM;
5630     }
5631   
5632   return flags;
5633 }
5634
5635
5636 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
5637
5638 static void
5639 avr_encode_section_info (tree decl, rtx rtl,
5640                          int new_decl_p)
5641 {
5642   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
5643      readily available, see PR34734.  So we postpone the warning
5644      about uninitialized data in program memory section until here.  */
5645    
5646   if (new_decl_p
5647       && decl && DECL_P (decl)
5648       && NULL_TREE == DECL_INITIAL (decl)
5649       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5650     {
5651       warning (OPT_Wuninitialized,
5652                "uninitialized variable %q+D put into "
5653                "program memory area", decl);
5654     }
5655
5656   default_encode_section_info (decl, rtl, new_decl_p);
5657 }
5658
5659
5660 /* Implement `TARGET_ASM_SELECT_SECTION' */
5661
5662 static section *
5663 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
5664 {
5665   section * sect = default_elf_select_section (decl, reloc, align);
5666   
5667   if (decl && DECL_P (decl)
5668       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
5669     {
5670       if (sect->common.flags & SECTION_NAMED)
5671         {
5672           const char * name = sect->named.name;
5673           const char * old_prefix = ".rodata";
5674           const char * new_prefix = ".progmem.data";
5675
5676           if (STR_PREFIX_P (name, old_prefix))
5677             {
5678               const char *sname = avr_replace_prefix (name, old_prefix, new_prefix);
5679
5680               return get_section (sname, sect->common.flags, sect->named.decl);
5681             }
5682         }
5683           
5684       return progmem_section;
5685     }
5686
5687   return sect;
5688 }
5689
5690 /* Implement `TARGET_ASM_FILE_START'.  */
5691 /* Outputs some appropriate text to go at the start of an assembler
5692    file.  */
5693
5694 static void
5695 avr_file_start (void)
5696 {
5697   if (avr_current_arch->asm_only)
5698     error ("MCU %qs supported for assembler only", avr_current_device->name);
5699
5700   default_file_start ();
5701
5702 /*  fprintf (asm_out_file, "\t.arch %s\n", avr_current_device->name);*/
5703   fputs ("__SREG__ = 0x3f\n"
5704          "__SP_H__ = 0x3e\n"
5705          "__SP_L__ = 0x3d\n", asm_out_file);
5706   
5707   fputs ("__tmp_reg__ = 0\n" 
5708          "__zero_reg__ = 1\n", asm_out_file);
5709 }
5710
5711
5712 /* Implement `TARGET_ASM_FILE_END'.  */
5713 /* Outputs to the stdio stream FILE some
5714    appropriate text to go at the end of an assembler file.  */
5715
5716 static void
5717 avr_file_end (void)
5718 {
5719   /* Output these only if there is anything in the
5720      .data* / .rodata* / .gnu.linkonce.* resp. .bss*
5721      input section(s) - some code size can be saved by not
5722      linking in the initialization code from libgcc if resp.
5723      sections are empty.  */
5724
5725   if (avr_need_copy_data_p)
5726     fputs (".global __do_copy_data\n", asm_out_file);
5727
5728   if (avr_need_clear_bss_p)
5729     fputs (".global __do_clear_bss\n", asm_out_file);
5730 }
5731
5732 /* Choose the order in which to allocate hard registers for
5733    pseudo-registers local to a basic block.
5734
5735    Store the desired register order in the array `reg_alloc_order'.
5736    Element 0 should be the register to allocate first; element 1, the
5737    next register; and so on.  */
5738
5739 void
5740 order_regs_for_local_alloc (void)
5741 {
5742   unsigned int i;
5743   static const int order_0[] = {
5744     24,25,
5745     18,19,
5746     20,21,
5747     22,23,
5748     30,31,
5749     26,27,
5750     28,29,
5751     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5752     0,1,
5753     32,33,34,35
5754   };
5755   static const int order_1[] = {
5756     18,19,
5757     20,21,
5758     22,23,
5759     24,25,
5760     30,31,
5761     26,27,
5762     28,29,
5763     17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5764     0,1,
5765     32,33,34,35
5766   };
5767   static const int order_2[] = {
5768     25,24,
5769     23,22,
5770     21,20,
5771     19,18,
5772     30,31,
5773     26,27,
5774     28,29,
5775     17,16,
5776     15,14,13,12,11,10,9,8,7,6,5,4,3,2,
5777     1,0,
5778     32,33,34,35
5779   };
5780   
5781   const int *order = (TARGET_ORDER_1 ? order_1 :
5782                       TARGET_ORDER_2 ? order_2 :
5783                       order_0);
5784   for (i=0; i < ARRAY_SIZE (order_0); ++i)
5785       reg_alloc_order[i] = order[i];
5786 }
5787
5788
5789 /* Implement `TARGET_REGISTER_MOVE_COST' */
5790
5791 static int
5792 avr_register_move_cost (enum machine_mode mode ATTRIBUTE_UNUSED,
5793                         reg_class_t from, reg_class_t to)
5794 {
5795   return (from == STACK_REG ? 6
5796           : to == STACK_REG ? 12
5797           : 2);
5798 }
5799
5800
5801 /* Implement `TARGET_MEMORY_MOVE_COST' */
5802
5803 static int
5804 avr_memory_move_cost (enum machine_mode mode, reg_class_t rclass ATTRIBUTE_UNUSED,
5805                       bool in ATTRIBUTE_UNUSED)
5806 {
5807   return (mode == QImode ? 2
5808           : mode == HImode ? 4
5809           : mode == SImode ? 8
5810           : mode == SFmode ? 8
5811           : 16);
5812 }
5813
5814
5815 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
5816    cost of an RTX operand given its context.  X is the rtx of the
5817    operand, MODE is its mode, and OUTER is the rtx_code of this
5818    operand's parent operator.  */
5819
5820 static int
5821 avr_operand_rtx_cost (rtx x, enum machine_mode mode, enum rtx_code outer,
5822                       int opno, bool speed)
5823 {
5824   enum rtx_code code = GET_CODE (x);
5825   int total;
5826
5827   switch (code)
5828     {
5829     case REG:
5830     case SUBREG:
5831       return 0;
5832
5833     case CONST_INT:
5834     case CONST_DOUBLE:
5835       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
5836
5837     default:
5838       break;
5839     }
5840
5841   total = 0;
5842   avr_rtx_costs (x, code, outer, opno, &total, speed);
5843   return total;
5844 }
5845
5846 /* The AVR backend's rtx_cost function.  X is rtx expression whose cost
5847    is to be calculated.  Return true if the complete cost has been
5848    computed, and false if subexpressions should be scanned.  In either
5849    case, *TOTAL contains the cost result.  */
5850
5851 static bool
5852 avr_rtx_costs (rtx x, int codearg, int outer_code ATTRIBUTE_UNUSED,
5853                int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5854 {
5855   enum rtx_code code = (enum rtx_code) codearg;
5856   enum machine_mode mode = GET_MODE (x);
5857   HOST_WIDE_INT val;
5858
5859   switch (code)
5860     {
5861     case CONST_INT:
5862     case CONST_DOUBLE:
5863     case SYMBOL_REF:
5864     case CONST:
5865     case LABEL_REF:
5866       /* Immediate constants are as cheap as registers.  */
5867       *total = 0;
5868       return true;
5869
5870     case MEM:
5871       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5872       return true;
5873
5874     case NEG:
5875       switch (mode)
5876         {
5877         case QImode:
5878         case SFmode:
5879           *total = COSTS_N_INSNS (1);
5880           break;
5881
5882         case HImode:
5883           *total = COSTS_N_INSNS (3);
5884           break;
5885
5886         case SImode:
5887           *total = COSTS_N_INSNS (7);
5888           break;
5889
5890         default:
5891           return false;
5892         }
5893       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5894       return true;
5895
5896     case ABS:
5897       switch (mode)
5898         {
5899         case QImode:
5900         case SFmode:
5901           *total = COSTS_N_INSNS (1);
5902           break;
5903
5904         default:
5905           return false;
5906         }
5907       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5908       return true;
5909
5910     case NOT:
5911       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
5912       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5913       return true;
5914
5915     case ZERO_EXTEND:
5916       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
5917                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5918       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5919       return true;
5920
5921     case SIGN_EXTEND:
5922       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
5923                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
5924       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5925       return true;
5926
5927     case PLUS:
5928       switch (mode)
5929         {
5930         case QImode:
5931           if (AVR_HAVE_MUL
5932               && MULT == GET_CODE (XEXP (x, 0))
5933               && register_operand (XEXP (x, 1), QImode))
5934             {
5935               /* multiply-add */
5936               *total = COSTS_N_INSNS (speed ? 4 : 3);
5937               /* multiply-add with constant: will be split and load constant. */
5938               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
5939                 *total = COSTS_N_INSNS (1) + *total;
5940               return true;
5941             }
5942           *total = COSTS_N_INSNS (1);
5943           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5944             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
5945           break;
5946
5947         case HImode:
5948           if (AVR_HAVE_MUL
5949               && (MULT == GET_CODE (XEXP (x, 0))
5950                   || ASHIFT == GET_CODE (XEXP (x, 0)))
5951               && register_operand (XEXP (x, 1), HImode)
5952               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
5953                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
5954             {
5955               /* multiply-add */
5956               *total = COSTS_N_INSNS (speed ? 5 : 4);
5957               /* multiply-add with constant: will be split and load constant. */
5958               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
5959                 *total = COSTS_N_INSNS (1) + *total;
5960               return true;
5961             }
5962           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5963             {
5964               *total = COSTS_N_INSNS (2);
5965               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
5966                                               speed);
5967             }
5968           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5969             *total = COSTS_N_INSNS (1);
5970           else
5971             *total = COSTS_N_INSNS (2);
5972           break;
5973
5974         case SImode:
5975           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5976             {
5977               *total = COSTS_N_INSNS (4);
5978               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
5979                                               speed);
5980             }
5981           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
5982             *total = COSTS_N_INSNS (1);
5983           else
5984             *total = COSTS_N_INSNS (4);
5985           break;
5986
5987         default:
5988           return false;
5989         }
5990       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
5991       return true;
5992
5993     case MINUS:
5994       if (AVR_HAVE_MUL
5995           && QImode == mode
5996           && register_operand (XEXP (x, 0), QImode)
5997           && MULT == GET_CODE (XEXP (x, 1)))
5998         {
5999           /* multiply-sub */
6000           *total = COSTS_N_INSNS (speed ? 4 : 3);
6001           /* multiply-sub with constant: will be split and load constant. */
6002           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
6003             *total = COSTS_N_INSNS (1) + *total;
6004           return true;
6005         }
6006       if (AVR_HAVE_MUL
6007           && HImode == mode
6008           && register_operand (XEXP (x, 0), HImode)
6009           && (MULT == GET_CODE (XEXP (x, 1))
6010               || ASHIFT == GET_CODE (XEXP (x, 1)))
6011           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
6012               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
6013         {
6014           /* multiply-sub */
6015           *total = COSTS_N_INSNS (speed ? 5 : 4);
6016           /* multiply-sub with constant: will be split and load constant. */
6017           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
6018             *total = COSTS_N_INSNS (1) + *total;
6019           return true;
6020         }
6021     case AND:
6022     case IOR:
6023       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
6024       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6025       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6026         *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6027       return true;
6028
6029     case XOR:
6030       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
6031       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6032       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6033       return true;
6034
6035     case MULT:
6036       switch (mode)
6037         {
6038         case QImode:
6039           if (AVR_HAVE_MUL)
6040             *total = COSTS_N_INSNS (!speed ? 3 : 4);
6041           else if (!speed)
6042             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6043           else
6044             return false;
6045           break;
6046
6047         case HImode:
6048           if (AVR_HAVE_MUL)
6049             {
6050               rtx op0 = XEXP (x, 0);
6051               rtx op1 = XEXP (x, 1);
6052               enum rtx_code code0 = GET_CODE (op0);
6053               enum rtx_code code1 = GET_CODE (op1);
6054               bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
6055               bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
6056
6057               if (ex0
6058                   && (u8_operand (op1, HImode)
6059                       || s8_operand (op1, HImode)))
6060                 {
6061                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
6062                   return true;
6063                 }
6064               if (ex0
6065                   && register_operand (op1, HImode))
6066                 {
6067                   *total = COSTS_N_INSNS (!speed ? 5 : 8);
6068                   return true;
6069                 }
6070               else if (ex0 || ex1)
6071                 {
6072                   *total = COSTS_N_INSNS (!speed ? 3 : 5);
6073                   return true;
6074                 }
6075               else if (register_operand (op0, HImode)
6076                        && (u8_operand (op1, HImode)
6077                            || s8_operand (op1, HImode)))
6078                 {
6079                   *total = COSTS_N_INSNS (!speed ? 6 : 9);
6080                   return true;
6081                 }
6082               else
6083                 *total = COSTS_N_INSNS (!speed ? 7 : 10);
6084             }
6085           else if (!speed)
6086             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6087           else
6088             return false;
6089           break;
6090
6091         case SImode:
6092           if (AVR_HAVE_MUL)
6093             {
6094               if (!speed)
6095                 {
6096                   /* Add some additional costs besides CALL like moves etc.  */
6097
6098                   *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
6099                 }
6100               else
6101                 {
6102                   /* Just a rough estimate.  Even with -O2 we don't want bulky
6103                      code expanded inline.  */
6104
6105                   *total = COSTS_N_INSNS (25);
6106                 }
6107             }
6108           else
6109             {
6110               if (speed)
6111                 *total = COSTS_N_INSNS (300);
6112               else
6113                 /* Add some additional costs besides CALL like moves etc.  */
6114                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
6115             }
6116           
6117           return true;
6118           
6119         default:
6120           return false;
6121         }
6122       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6123       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6124       return true;
6125
6126     case DIV:
6127     case MOD:
6128     case UDIV:
6129     case UMOD:
6130       if (!speed)
6131         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
6132       else
6133         return false;
6134       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6135       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6136       return true;
6137
6138     case ROTATE:
6139       switch (mode)
6140         {
6141         case QImode:
6142           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
6143             *total = COSTS_N_INSNS (1);
6144
6145           break;
6146
6147         case HImode:
6148           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
6149             *total = COSTS_N_INSNS (3);
6150
6151           break;
6152
6153         case SImode:
6154           if (CONST_INT_P (XEXP (x, 1)))
6155             switch (INTVAL (XEXP (x, 1)))
6156               {
6157               case 8:
6158               case 24:
6159                 *total = COSTS_N_INSNS (5);
6160                 break;
6161               case 16:
6162                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
6163                 break;
6164               }
6165           break;
6166
6167         default:
6168           return false;
6169         }
6170       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6171       return true;    
6172
6173     case ASHIFT:
6174       switch (mode)
6175         {
6176         case QImode:
6177           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6178             {
6179               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6180               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6181                                               speed);
6182             }
6183           else
6184             {
6185               val = INTVAL (XEXP (x, 1));
6186               if (val == 7)
6187                 *total = COSTS_N_INSNS (3);
6188               else if (val >= 0 && val <= 7)
6189                 *total = COSTS_N_INSNS (val);
6190               else
6191                 *total = COSTS_N_INSNS (1);
6192             }
6193           break;
6194
6195         case HImode:
6196           if (AVR_HAVE_MUL)
6197             {
6198               if (const_2_to_7_operand (XEXP (x, 1), HImode)
6199                   && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
6200                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
6201                 {
6202                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
6203                   return true;
6204                 }
6205             }
6206           
6207           if (const1_rtx == (XEXP (x, 1))
6208               && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
6209             {
6210               *total = COSTS_N_INSNS (2);
6211               return true;
6212             }
6213           
6214           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6215             {
6216               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6217               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6218                                               speed);
6219             }
6220           else
6221             switch (INTVAL (XEXP (x, 1)))
6222               {
6223               case 0:
6224                 *total = 0;
6225                 break;
6226               case 1:
6227               case 8:
6228                 *total = COSTS_N_INSNS (2);
6229                 break;
6230               case 9:
6231                 *total = COSTS_N_INSNS (3);
6232                 break;
6233               case 2:
6234               case 3:
6235               case 10:
6236               case 15:
6237                 *total = COSTS_N_INSNS (4);
6238                 break;
6239               case 7:
6240               case 11:
6241               case 12:
6242                 *total = COSTS_N_INSNS (5);
6243                 break;
6244               case 4:
6245                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
6246                 break;
6247               case 6:
6248                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
6249                 break;
6250               case 5:
6251                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
6252                 break;
6253               default:
6254                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6255                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6256                                                 speed);
6257               }
6258           break;
6259
6260         case SImode:
6261           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6262             {
6263               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6264               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6265                                               speed);
6266             }
6267           else
6268             switch (INTVAL (XEXP (x, 1)))
6269               {
6270               case 0:
6271                 *total = 0;
6272                 break;
6273               case 24:
6274                 *total = COSTS_N_INSNS (3);
6275                 break;
6276               case 1:
6277               case 8:
6278               case 16:
6279                 *total = COSTS_N_INSNS (4);
6280                 break;
6281               case 31:
6282                 *total = COSTS_N_INSNS (6);
6283                 break;
6284               case 2:
6285                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6286                 break;
6287               default:
6288                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6289                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6290                                                 speed);
6291               }
6292           break;
6293
6294         default:
6295           return false;
6296         }
6297       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6298       return true;
6299
6300     case ASHIFTRT:
6301       switch (mode)
6302         {
6303         case QImode:
6304           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6305             {
6306               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6307               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6308                                               speed);
6309             }
6310           else
6311             {
6312               val = INTVAL (XEXP (x, 1));
6313               if (val == 6)
6314                 *total = COSTS_N_INSNS (4);
6315               else if (val == 7)
6316                 *total = COSTS_N_INSNS (2);
6317               else if (val >= 0 && val <= 7)
6318                 *total = COSTS_N_INSNS (val);
6319               else
6320                 *total = COSTS_N_INSNS (1);
6321             }
6322           break;
6323
6324         case HImode:
6325           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6326             {
6327               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6328               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6329                                               speed);
6330             }
6331           else
6332             switch (INTVAL (XEXP (x, 1)))
6333               {
6334               case 0:
6335                 *total = 0;
6336                 break;
6337               case 1:
6338                 *total = COSTS_N_INSNS (2);
6339                 break;
6340               case 15:
6341                 *total = COSTS_N_INSNS (3);
6342                 break;
6343               case 2:
6344               case 7:
6345               case 8:
6346               case 9:
6347                 *total = COSTS_N_INSNS (4);
6348                 break;
6349               case 10:
6350               case 14:
6351                 *total = COSTS_N_INSNS (5);
6352                 break;
6353               case 11:
6354                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
6355                 break;
6356               case 12:
6357                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
6358                 break;
6359               case 6:
6360               case 13:
6361                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
6362                 break;
6363               default:
6364                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6365                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6366                                                 speed);
6367               }
6368           break;
6369
6370         case SImode:
6371           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6372             {
6373               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6374               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6375                                               speed);
6376             }
6377           else
6378             switch (INTVAL (XEXP (x, 1)))
6379               {
6380               case 0:
6381                 *total = 0;
6382                 break;
6383               case 1:
6384                 *total = COSTS_N_INSNS (4);
6385                 break;
6386               case 8:
6387               case 16:
6388               case 24:
6389                 *total = COSTS_N_INSNS (6);
6390                 break;
6391               case 2:
6392                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6393                 break;
6394               case 31:
6395                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
6396                 break;
6397               default:
6398                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6399                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6400                                                 speed);
6401               }
6402           break;
6403
6404         default:
6405           return false;
6406         }
6407       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6408       return true;
6409
6410     case LSHIFTRT:
6411       switch (mode)
6412         {
6413         case QImode:
6414           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6415             {
6416               *total = COSTS_N_INSNS (!speed ? 4 : 17);
6417               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6418                                               speed);
6419             }
6420           else
6421             {
6422               val = INTVAL (XEXP (x, 1));
6423               if (val == 7)
6424                 *total = COSTS_N_INSNS (3);
6425               else if (val >= 0 && val <= 7)
6426                 *total = COSTS_N_INSNS (val);
6427               else
6428                 *total = COSTS_N_INSNS (1);
6429             }
6430           break;
6431
6432         case HImode:
6433           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6434             {
6435               *total = COSTS_N_INSNS (!speed ? 5 : 41);
6436               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6437                                               speed);
6438             }
6439           else
6440             switch (INTVAL (XEXP (x, 1)))
6441               {
6442               case 0:
6443                 *total = 0;
6444                 break;
6445               case 1:
6446               case 8:
6447                 *total = COSTS_N_INSNS (2);
6448                 break;
6449               case 9:
6450                 *total = COSTS_N_INSNS (3);
6451                 break;
6452               case 2:
6453               case 10:
6454               case 15:
6455                 *total = COSTS_N_INSNS (4);
6456                 break;
6457               case 7:
6458               case 11:
6459                 *total = COSTS_N_INSNS (5);
6460                 break;
6461               case 3:
6462               case 12:
6463               case 13:
6464               case 14:
6465                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
6466                 break;
6467               case 4:
6468                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
6469                 break;
6470               case 5:
6471               case 6:
6472                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
6473                 break;
6474               default:
6475                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
6476                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6477                                                 speed);
6478               }
6479           break;
6480
6481         case SImode:
6482           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6483             {
6484               *total = COSTS_N_INSNS (!speed ? 7 : 113);
6485               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6486                                               speed);
6487             }
6488           else
6489             switch (INTVAL (XEXP (x, 1)))
6490               {
6491               case 0:
6492                 *total = 0;
6493                 break;
6494               case 1:
6495                 *total = COSTS_N_INSNS (4);
6496                 break;
6497               case 2:
6498                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
6499                 break;
6500               case 8:
6501               case 16:
6502               case 24:
6503                 *total = COSTS_N_INSNS (4);
6504                 break;
6505               case 31:
6506                 *total = COSTS_N_INSNS (6);
6507                 break;
6508               default:
6509                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
6510                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
6511                                                 speed);
6512               }
6513           break;
6514
6515         default:
6516           return false;
6517         }
6518       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6519       return true;
6520
6521     case COMPARE:
6522       switch (GET_MODE (XEXP (x, 0)))
6523         {
6524         case QImode:
6525           *total = COSTS_N_INSNS (1);
6526           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6527             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6528           break;
6529
6530         case HImode:
6531           *total = COSTS_N_INSNS (2);
6532           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6533             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6534           else if (INTVAL (XEXP (x, 1)) != 0)
6535             *total += COSTS_N_INSNS (1);
6536           break;
6537
6538         case SImode:
6539           *total = COSTS_N_INSNS (4);
6540           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
6541             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
6542           else if (INTVAL (XEXP (x, 1)) != 0)
6543             *total += COSTS_N_INSNS (3);
6544           break;
6545
6546         default:
6547           return false;
6548         }
6549       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
6550       return true;
6551
6552     case TRUNCATE:
6553       if (AVR_HAVE_MUL
6554           && LSHIFTRT == GET_CODE (XEXP (x, 0))
6555           && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
6556           && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
6557         {
6558           if (QImode == mode || HImode == mode)
6559             {
6560               *total = COSTS_N_INSNS (2);
6561               return true;
6562             }
6563         }
6564       break;
6565
6566     default:
6567       break;
6568     }
6569   return false;
6570 }
6571
6572 /* Calculate the cost of a memory address.  */
6573
6574 static int
6575 avr_address_cost (rtx x, bool speed ATTRIBUTE_UNUSED)
6576 {
6577   if (GET_CODE (x) == PLUS
6578       && GET_CODE (XEXP (x,1)) == CONST_INT
6579       && (REG_P (XEXP (x,0)) || GET_CODE (XEXP (x,0)) == SUBREG)
6580       && INTVAL (XEXP (x,1)) >= 61)
6581     return 18;
6582   if (CONSTANT_ADDRESS_P (x))
6583     {
6584       if (optimize > 0 && io_address_operand (x, QImode))
6585         return 2;
6586       return 4;
6587     }
6588   return 4;
6589 }
6590
6591 /* Test for extra memory constraint 'Q'.
6592    It's a memory address based on Y or Z pointer with valid displacement.  */
6593
6594 int
6595 extra_constraint_Q (rtx x)
6596 {
6597   if (GET_CODE (XEXP (x,0)) == PLUS
6598       && REG_P (XEXP (XEXP (x,0), 0))
6599       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
6600       && (INTVAL (XEXP (XEXP (x,0), 1))
6601           <= MAX_LD_OFFSET (GET_MODE (x))))
6602     {
6603       rtx xx = XEXP (XEXP (x,0), 0);
6604       int regno = REGNO (xx);
6605       if (TARGET_ALL_DEBUG)
6606         {
6607           fprintf (stderr, ("extra_constraint:\n"
6608                             "reload_completed: %d\n"
6609                             "reload_in_progress: %d\n"),
6610                    reload_completed, reload_in_progress);
6611           debug_rtx (x);
6612         }
6613       if (regno >= FIRST_PSEUDO_REGISTER)
6614         return 1;               /* allocate pseudos */
6615       else if (regno == REG_Z || regno == REG_Y)
6616         return 1;               /* strictly check */
6617       else if (xx == frame_pointer_rtx
6618                || xx == arg_pointer_rtx)
6619         return 1;               /* XXX frame & arg pointer checks */
6620     }
6621   return 0;
6622 }
6623
6624 /* Convert condition code CONDITION to the valid AVR condition code.  */
6625
6626 RTX_CODE
6627 avr_normalize_condition (RTX_CODE condition)
6628 {
6629   switch (condition)
6630     {
6631     case GT:
6632       return GE;
6633     case GTU:
6634       return GEU;
6635     case LE:
6636       return LT;
6637     case LEU:
6638       return LTU;
6639     default:
6640       gcc_unreachable ();
6641     }
6642 }
6643
6644 /* Helper function for `avr_reorg'.  */
6645
6646 static rtx
6647 avr_compare_pattern (rtx insn)
6648 {
6649   rtx pattern = single_set (insn);
6650
6651   if (pattern
6652       && NONJUMP_INSN_P (insn)
6653       && SET_DEST (pattern) == cc0_rtx
6654       && GET_CODE (SET_SRC (pattern)) == COMPARE)
6655     {
6656       return pattern;
6657     }
6658
6659   return NULL_RTX;
6660 }
6661
6662 /* Helper function for `avr_reorg'.  */
6663
6664 /* Expansion of switch/case decision trees leads to code like
6665
6666        cc0 = compare (Reg, Num)
6667        if (cc0 == 0)
6668          goto L1
6669          
6670        cc0 = compare (Reg, Num)
6671        if (cc0 > 0)
6672          goto L2
6673
6674    The second comparison is superfluous and can be deleted.
6675    The second jump condition can be transformed from a
6676    "difficult" one to a "simple" one because "cc0 > 0" and
6677    "cc0 >= 0" will have the same effect here.
6678
6679    This function relies on the way switch/case is being expaned
6680    as binary decision tree.  For example code see PR 49903.
6681          
6682    Return TRUE if optimization performed.
6683    Return FALSE if nothing changed.
6684
6685    INSN1 is a comparison, i.e. avr_compare_pattern != 0.
6686
6687    We don't want to do this in text peephole because it is
6688    tedious to work out jump offsets there and the second comparison
6689    might have been transormed by `avr_reorg'.
6690
6691    RTL peephole won't do because peephole2 does not scan across
6692    basic blocks.  */                
6693                         
6694 static bool
6695 avr_reorg_remove_redundant_compare (rtx insn1)
6696 {
6697   rtx comp1, ifelse1, xcond1, branch1;
6698   rtx comp2, ifelse2, xcond2, branch2, insn2;
6699   enum rtx_code code;
6700   rtx jump, target, cond;
6701   
6702   /* Look out for:  compare1 - branch1 - compare2 - branch2  */
6703
6704   branch1 = next_nonnote_nondebug_insn (insn1);
6705   if (!branch1 || !JUMP_P (branch1))
6706     return false;
6707
6708   insn2 = next_nonnote_nondebug_insn (branch1);
6709   if (!insn2 || !avr_compare_pattern (insn2))
6710     return false;
6711
6712   branch2 = next_nonnote_nondebug_insn (insn2);
6713   if (!branch2 || !JUMP_P (branch2))
6714     return false;
6715
6716   comp1 = avr_compare_pattern (insn1);
6717   comp2 = avr_compare_pattern (insn2);
6718   xcond1 = single_set (branch1);
6719   xcond2 = single_set (branch2);
6720   
6721   if (!comp1 || !comp2
6722       || !rtx_equal_p (comp1, comp2)
6723       || !xcond1 || SET_DEST (xcond1) != pc_rtx
6724       || !xcond2 || SET_DEST (xcond2) != pc_rtx
6725       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
6726       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
6727     {
6728       return false;
6729     }
6730
6731   comp1 = SET_SRC (comp1);
6732   ifelse1 = SET_SRC (xcond1);
6733   ifelse2 = SET_SRC (xcond2);
6734
6735   /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE.  */
6736
6737   if (EQ != GET_CODE (XEXP (ifelse1, 0))
6738       || !REG_P (XEXP (comp1, 0))
6739       || !CONST_INT_P (XEXP (comp1, 1))
6740       || XEXP (ifelse1, 2) != pc_rtx
6741       || XEXP (ifelse2, 2) != pc_rtx
6742       || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
6743       || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
6744       || !COMPARISON_P (XEXP (ifelse2, 0))
6745       || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
6746       || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
6747       || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
6748       || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
6749     {
6750       return false;
6751     }
6752
6753   /* We filtered the insn sequence to look like
6754
6755         (set (cc0)
6756              (compare (reg:M N)
6757                       (const_int VAL)))
6758         (set (pc)
6759              (if_then_else (eq (cc0)
6760                                (const_int 0))
6761                            (label_ref L1)
6762                            (pc)))
6763                            
6764         (set (cc0)
6765              (compare (reg:M N)
6766                       (const_int VAL)))
6767         (set (pc)
6768              (if_then_else (CODE (cc0)
6769                                  (const_int 0))
6770                            (label_ref L2)
6771                            (pc)))
6772   */
6773
6774   code = GET_CODE (XEXP (ifelse2, 0));
6775
6776   /* Map GT/GTU to GE/GEU which is easier for AVR.
6777      The first two instructions compare/branch on EQ
6778      so we may replace the difficult
6779         
6780         if (x == VAL)   goto L1;
6781         if (x > VAL)    goto L2;
6782
6783      with easy
6784          
6785          if (x == VAL)   goto L1;
6786          if (x >= VAL)   goto L2;
6787
6788      Similarly, replace LE/LEU by LT/LTU.  */
6789   
6790   switch (code)
6791     {
6792     case EQ:
6793     case LT:  case LTU:
6794     case GE:  case GEU:
6795       break;
6796
6797     case LE:  case LEU:
6798     case GT:  case GTU:
6799       code = avr_normalize_condition (code);
6800       break;
6801       
6802     default:
6803       return false;
6804     }
6805
6806   /* Wrap the branches into UNSPECs so they won't be changed or
6807      optimized in the remainder.  */
6808
6809   target = XEXP (XEXP (ifelse1, 1), 0);
6810   cond = XEXP (ifelse1, 0);
6811   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
6812
6813   JUMP_LABEL (jump) = JUMP_LABEL (branch1);
6814
6815   target = XEXP (XEXP (ifelse2, 1), 0);
6816   cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
6817   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
6818
6819   JUMP_LABEL (jump) = JUMP_LABEL (branch2);
6820
6821   /* The comparisons in insn1 and insn2 are exactly the same;
6822      insn2 is superfluous so delete it.  */
6823      
6824   delete_insn (insn2);
6825   delete_insn (branch1);
6826   delete_insn (branch2);
6827
6828   return true;
6829 }
6830
6831
6832 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
6833 /* Optimize conditional jumps.  */
6834
6835 static void
6836 avr_reorg (void)
6837 {
6838   rtx insn = get_insns();
6839   
6840   for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
6841     {
6842       rtx pattern = avr_compare_pattern (insn);
6843       
6844       if (!pattern)
6845         continue;
6846
6847       if (optimize
6848           && avr_reorg_remove_redundant_compare (insn))
6849         {
6850           continue;
6851         }
6852
6853       if (compare_diff_p (insn))
6854         {
6855           /* Now we work under compare insn with difficult branch.  */
6856           
6857           rtx next = next_real_insn (insn);
6858           rtx pat = PATTERN (next);
6859
6860           pattern = SET_SRC (pattern);
6861           
6862           if (true_regnum (XEXP (pattern, 0)) >= 0
6863               && true_regnum (XEXP (pattern, 1)) >= 0)
6864             {
6865               rtx x = XEXP (pattern, 0);
6866               rtx src = SET_SRC (pat);
6867               rtx t = XEXP (src,0);
6868               PUT_CODE (t, swap_condition (GET_CODE (t)));
6869               XEXP (pattern, 0) = XEXP (pattern, 1);
6870               XEXP (pattern, 1) = x;
6871               INSN_CODE (next) = -1;
6872             }
6873           else if (true_regnum (XEXP (pattern, 0)) >= 0
6874                    && XEXP (pattern, 1) == const0_rtx)
6875             {
6876               /* This is a tst insn, we can reverse it.  */
6877               rtx src = SET_SRC (pat);
6878               rtx t = XEXP (src,0);
6879     
6880               PUT_CODE (t, swap_condition (GET_CODE (t)));
6881               XEXP (pattern, 1) = XEXP (pattern, 0);
6882               XEXP (pattern, 0) = const0_rtx;
6883               INSN_CODE (next) = -1;
6884               INSN_CODE (insn) = -1;
6885             }
6886           else if (true_regnum (XEXP (pattern, 0)) >= 0
6887                    && CONST_INT_P (XEXP (pattern, 1)))
6888             {
6889               rtx x = XEXP (pattern, 1);
6890               rtx src = SET_SRC (pat);
6891               rtx t = XEXP (src,0);
6892               enum machine_mode mode = GET_MODE (XEXP (pattern, 0));
6893               
6894               if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
6895                 {
6896                   XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
6897                   PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
6898                   INSN_CODE (next) = -1;
6899                   INSN_CODE (insn) = -1;
6900                 }
6901             }
6902         }
6903     }
6904 }
6905
6906 /* Returns register number for function return value.*/
6907
6908 static inline unsigned int
6909 avr_ret_register (void)
6910 {
6911   return 24;
6912 }
6913
6914 /* Worker function for TARGET_FUNCTION_VALUE_REGNO_P.  */
6915
6916 static bool
6917 avr_function_value_regno_p (const unsigned int regno)
6918 {
6919   return (regno == avr_ret_register ());
6920 }
6921
6922 /* Create an RTX representing the place where a
6923    library function returns a value of mode MODE.  */
6924
6925 static rtx
6926 avr_libcall_value (enum machine_mode mode,
6927                    const_rtx func ATTRIBUTE_UNUSED)
6928 {
6929   int offs = GET_MODE_SIZE (mode);
6930   if (offs < 2)
6931     offs = 2;
6932   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
6933 }
6934
6935 /* Create an RTX representing the place where a
6936    function returns a value of data type VALTYPE.  */
6937
6938 static rtx
6939 avr_function_value (const_tree type,
6940                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6941                     bool outgoing ATTRIBUTE_UNUSED)
6942 {
6943   unsigned int offs;
6944
6945   if (TYPE_MODE (type) != BLKmode)
6946     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
6947   
6948   offs = int_size_in_bytes (type);
6949   if (offs < 2)
6950     offs = 2;
6951   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
6952     offs = GET_MODE_SIZE (SImode);
6953   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
6954     offs = GET_MODE_SIZE (DImode);
6955   
6956   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
6957 }
6958
6959 int
6960 test_hard_reg_class (enum reg_class rclass, rtx x)
6961 {
6962   int regno = true_regnum (x);
6963   if (regno < 0)
6964     return 0;
6965
6966   if (TEST_HARD_REG_CLASS (rclass, regno))
6967     return 1;
6968
6969   return 0;
6970 }
6971
6972
6973 int
6974 jump_over_one_insn_p (rtx insn, rtx dest)
6975 {
6976   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
6977                       ? XEXP (dest, 0)
6978                       : dest);
6979   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
6980   int dest_addr = INSN_ADDRESSES (uid);
6981   return dest_addr - jump_addr == get_attr_length (insn) + 1;
6982 }
6983
6984 /* Returns 1 if a value of mode MODE can be stored starting with hard
6985    register number REGNO.  On the enhanced core, anything larger than
6986    1 byte must start in even numbered register for "movw" to work
6987    (this way we don't have to check for odd registers everywhere).  */
6988
6989 int
6990 avr_hard_regno_mode_ok (int regno, enum machine_mode mode)
6991 {
6992   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
6993         Disallowing QI et al. in these regs might lead to code like
6994             (set (subreg:QI (reg:HI 28) n) ...)
6995         which will result in wrong code because reload does not
6996         handle SUBREGs of hard regsisters like this.
6997         This could be fixed in reload.  However, it appears
6998         that fixing reload is not wanted by reload people.  */
6999   
7000   /* Any GENERAL_REGS register can hold 8-bit values.  */
7001   
7002   if (GET_MODE_SIZE (mode) == 1)
7003     return 1;
7004
7005   /* FIXME: Ideally, the following test is not needed.
7006         However, it turned out that it can reduce the number
7007         of spill fails.  AVR and it's poor endowment with
7008         address registers is extreme stress test for reload.  */
7009   
7010   if (GET_MODE_SIZE (mode) >= 4
7011       && regno >= REG_X)
7012     return 0;
7013
7014   /* All modes larger than 8 bits should start in an even register.  */
7015   
7016   return !(regno & 1);
7017 }
7018
7019
7020 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
7021 /* Set 32-bit register OP[0] to compile-time constant OP[1].
7022    CLOBBER_REG is a QI clobber register or NULL_RTX.
7023    LEN == NULL: output instructions.
7024    LEN != NULL: set *LEN to the length of the instruction sequence
7025                 (in words) printed with LEN = NULL.
7026    If CLEAR_P is true, OP[0] had been cleard to Zero already.
7027    If CLEAR_P is false, nothing is known about OP[0].  */
7028
7029 static void
7030 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
7031 {
7032   rtx src = op[1];
7033   rtx dest = op[0];
7034   rtx xval, xdest[4];
7035   int ival[4];
7036   int clobber_val = 1234;
7037   bool cooked_clobber_p = false;
7038   bool set_p = false;
7039   unsigned int n;
7040   enum machine_mode mode = GET_MODE (dest);
7041   
7042   gcc_assert (REG_P (dest));
7043
7044   if (len)
7045     *len = 0;
7046   
7047   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
7048      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
7049   
7050   if (14 == REGNO (dest)
7051       && 4 == GET_MODE_SIZE (mode))
7052     {
7053       clobber_reg = gen_rtx_REG (QImode, 17);
7054     }
7055
7056   /* We might need a clobber reg but don't have one.  Look at the value
7057      to be loaded more closely.  A clobber is only needed if it contains
7058      a byte that is neither 0, -1 or a power of 2.  */
7059   
7060   if (NULL_RTX == clobber_reg
7061       && !test_hard_reg_class (LD_REGS, dest)
7062       && !avr_popcount_each_byte (src, GET_MODE_SIZE (mode),
7063                                   (1 << 0) | (1 << 1) | (1 << 8)))
7064     {
7065       /* We have no clobber register but need one.  Cook one up.
7066          That's cheaper than loading from constant pool.  */
7067       
7068       cooked_clobber_p = true;
7069       clobber_reg = gen_rtx_REG (QImode, REG_Z + 1);
7070       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
7071     }
7072
7073   /* Now start filling DEST from LSB to MSB.  */
7074   
7075   for (n = 0; n < GET_MODE_SIZE (mode); n++)
7076     {
7077       bool done_byte = false;
7078       unsigned int j;
7079       rtx xop[3];
7080
7081       /* Crop the n-th sub-byte.  */
7082       
7083       xval = simplify_gen_subreg (QImode, src, mode, n);
7084       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
7085       ival[n] = INTVAL (xval);
7086
7087       /* Look if we can reuse the low word by means of MOVW.  */
7088       
7089       if (n == 2
7090           && AVR_HAVE_MOVW)
7091         {
7092           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
7093           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
7094
7095           if (INTVAL (lo16) == INTVAL (hi16))
7096             {
7097               if (0 != INTVAL (lo16)
7098                   || !clear_p)
7099                 {
7100                   avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
7101                 }
7102               
7103               break;
7104             }
7105         }
7106
7107       /* Use CLR to zero a value so that cc0 is set as expected
7108          for zero.  */
7109       
7110       if (ival[n] == 0)
7111         {
7112           if (!clear_p)
7113             avr_asm_len ("clr %0", &xdest[n], len, 1);
7114           
7115           continue;
7116         }
7117
7118       if (clobber_val == ival[n]
7119           && REGNO (clobber_reg) == REGNO (xdest[n]))
7120         {
7121           continue;
7122         }
7123
7124       /* LD_REGS can use LDI to move a constant value */
7125       
7126       if (test_hard_reg_class (LD_REGS, xdest[n]))
7127         {
7128           xop[0] = xdest[n];
7129           xop[1] = xval;
7130           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
7131           continue;
7132         }
7133
7134       /* Try to reuse value already loaded in some lower byte. */
7135       
7136       for (j = 0; j < n; j++)
7137         if (ival[j] == ival[n])
7138           {
7139             xop[0] = xdest[n];
7140             xop[1] = xdest[j];
7141             
7142             avr_asm_len ("mov %0,%1", xop, len, 1);
7143             done_byte = true;
7144             break;
7145           }
7146
7147       if (done_byte)
7148         continue;
7149
7150       /* Need no clobber reg for -1: Use CLR/DEC */
7151       
7152       if (-1 == ival[n])
7153         {
7154           if (!clear_p)
7155             avr_asm_len ("clr %0", &xdest[n], len, 1);
7156           
7157           avr_asm_len ("dec %0", &xdest[n], len, 1);
7158           continue;
7159         }
7160       else if (1 == ival[n])
7161         {
7162           if (!clear_p)
7163             avr_asm_len ("clr %0", &xdest[n], len, 1);
7164           
7165           avr_asm_len ("inc %0", &xdest[n], len, 1);
7166           continue;
7167         }
7168
7169       /* Use T flag or INC to manage powers of 2 if we have
7170          no clobber reg.  */
7171
7172       if (NULL_RTX == clobber_reg
7173           && single_one_operand (xval, QImode))
7174         {
7175           xop[0] = xdest[n];
7176           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
7177
7178           gcc_assert (constm1_rtx != xop[1]);
7179
7180           if (!set_p)
7181             {
7182               set_p = true;
7183               avr_asm_len ("set", xop, len, 1);
7184             }
7185
7186           if (!clear_p)
7187             avr_asm_len ("clr %0", xop, len, 1);
7188           
7189           avr_asm_len ("bld %0,%1", xop, len, 1);
7190           continue;
7191         }
7192
7193       /* We actually need the LD_REGS clobber reg.  */
7194
7195       gcc_assert (NULL_RTX != clobber_reg);
7196         
7197       xop[0] = xdest[n];
7198       xop[1] = xval;
7199       xop[2] = clobber_reg;
7200       clobber_val = ival[n];
7201         
7202       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
7203                    "mov %0,%2", xop, len, 2);
7204     }
7205   
7206   /* If we cooked up a clobber reg above, restore it.  */
7207   
7208   if (cooked_clobber_p)
7209     {
7210       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
7211     }
7212 }
7213
7214
7215 /* Reload the constant OP[1] into the HI register OP[0].
7216    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
7217    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
7218    need a clobber reg or have to cook one up.
7219
7220    PLEN == NULL: Output instructions.
7221    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
7222                  by the insns printed.
7223
7224    Return "".  */
7225
7226 const char*
7227 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
7228 {
7229   if (CONST_INT_P (op[1]))
7230     {
7231       output_reload_in_const (op, clobber_reg, plen, false);
7232     }
7233   else if (test_hard_reg_class (LD_REGS, op[0]))
7234     {
7235       avr_asm_len ("ldi %A0,lo8(%1)" CR_TAB
7236                    "ldi %B0,hi8(%1)", op, plen, -2);
7237     }
7238   else
7239     {
7240       rtx xop[3];
7241
7242       xop[0] = op[0];
7243       xop[1] = op[1];
7244       xop[2] = clobber_reg;
7245       
7246       if (plen)
7247         *plen = 0;
7248       
7249       if (clobber_reg == NULL_RTX)
7250         {
7251           /* No scratch register provided: cook une up.  */
7252           
7253           xop[2] = gen_rtx_REG (QImode, REG_Z + 1);
7254           avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
7255         }
7256       
7257       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
7258                    "mov %A0,%2"     CR_TAB
7259                    "ldi %2,hi8(%1)" CR_TAB
7260                    "mov %B0,%2", xop, plen, 4);
7261
7262       if (clobber_reg == NULL_RTX)
7263         {
7264           avr_asm_len ("mov %2,__tmp_reg__", xop, plen, 1);
7265         }
7266     }
7267
7268   return "";
7269 }
7270
7271
7272 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
7273    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
7274    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
7275    need a clobber reg or have to cook one up.
7276
7277    LEN == NULL: Output instructions.
7278    
7279    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
7280                 by the insns printed.
7281
7282    Return "".  */
7283
7284 const char *
7285 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
7286 {
7287   gcc_assert (REG_P (op[0])
7288               && CONSTANT_P (op[1]));
7289
7290   if (AVR_HAVE_MOVW
7291       && !test_hard_reg_class (LD_REGS, op[0]))
7292     {
7293       int len_clr, len_noclr;
7294       
7295       /* In some cases it is better to clear the destination beforehand, e.g.
7296
7297              CLR R2   CLR R3   MOVW R4,R2   INC R2
7298
7299          is shorther than
7300
7301              CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
7302
7303          We find it too tedious to work that out in the print function.
7304          Instead, we call the print function twice to get the lengths of
7305          both methods and use the shortest one.  */
7306          
7307       output_reload_in_const (op, clobber_reg, &len_clr, true);
7308       output_reload_in_const (op, clobber_reg, &len_noclr, false);
7309       
7310       if (len_noclr - len_clr == 4)
7311         {
7312           /* Default needs 4 CLR instructions: clear register beforehand.  */
7313           
7314           avr_asm_len ("clr %A0" CR_TAB
7315                        "clr %B0" CR_TAB
7316                        "movw %C0,%A0", &op[0], len, 3);
7317           
7318           output_reload_in_const (op, clobber_reg, len, true);
7319           
7320           if (len)
7321             *len += 3;
7322
7323           return "";
7324         }
7325     }
7326
7327   /* Default: destination not pre-cleared.  */
7328
7329   output_reload_in_const (op, clobber_reg, len, false);
7330   return "";
7331 }
7332
7333 void
7334 avr_output_bld (rtx operands[], int bit_nr)
7335 {
7336   static char s[] = "bld %A0,0";
7337
7338   s[5] = 'A' + (bit_nr >> 3);
7339   s[8] = '0' + (bit_nr & 7);
7340   output_asm_insn (s, operands);
7341 }
7342
7343 void
7344 avr_output_addr_vec_elt (FILE *stream, int value)
7345 {
7346   if (AVR_HAVE_JMP_CALL)
7347     fprintf (stream, "\t.word gs(.L%d)\n", value);
7348   else
7349     fprintf (stream, "\trjmp .L%d\n", value);
7350 }
7351
7352 /* Returns true if SCRATCH are safe to be allocated as a scratch
7353    registers (for a define_peephole2) in the current function.  */
7354
7355 bool
7356 avr_hard_regno_scratch_ok (unsigned int regno)
7357 {
7358   /* Interrupt functions can only use registers that have already been saved
7359      by the prologue, even if they would normally be call-clobbered.  */
7360
7361   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
7362       && !df_regs_ever_live_p (regno))
7363     return false;
7364
7365   /* Don't allow hard registers that might be part of the frame pointer.
7366      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
7367      and don't care for a frame pointer that spans more than one register.  */
7368
7369   if ((!reload_completed || frame_pointer_needed)
7370       && (regno == REG_Y || regno == REG_Y + 1))
7371     {
7372       return false;
7373     }
7374
7375   return true;
7376 }
7377
7378 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
7379
7380 int
7381 avr_hard_regno_rename_ok (unsigned int old_reg,
7382                           unsigned int new_reg)
7383 {
7384   /* Interrupt functions can only use registers that have already been
7385      saved by the prologue, even if they would normally be
7386      call-clobbered.  */
7387
7388   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
7389       && !df_regs_ever_live_p (new_reg))
7390     return 0;
7391
7392   /* Don't allow hard registers that might be part of the frame pointer.
7393      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
7394      and don't care for a frame pointer that spans more than one register.  */
7395
7396   if ((!reload_completed || frame_pointer_needed)
7397       && (old_reg == REG_Y || old_reg == REG_Y + 1
7398           || new_reg == REG_Y || new_reg == REG_Y + 1))
7399     {
7400       return 0;
7401     }
7402   
7403   return 1;
7404 }
7405
7406 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
7407    or memory location in the I/O space (QImode only).
7408
7409    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
7410    Operand 1: register operand to test, or CONST_INT memory address.
7411    Operand 2: bit number.
7412    Operand 3: label to jump to if the test is true.  */
7413
7414 const char *
7415 avr_out_sbxx_branch (rtx insn, rtx operands[])
7416 {
7417   enum rtx_code comp = GET_CODE (operands[0]);
7418   int long_jump = (get_attr_length (insn) >= 4);
7419   int reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
7420
7421   if (comp == GE)
7422     comp = EQ;
7423   else if (comp == LT)
7424     comp = NE;
7425
7426   if (reverse)
7427     comp = reverse_condition (comp);
7428
7429   if (GET_CODE (operands[1]) == CONST_INT)
7430     {
7431       if (INTVAL (operands[1]) < 0x40)
7432         {
7433           if (comp == EQ)
7434             output_asm_insn (AS2 (sbis,%m1-0x20,%2), operands);
7435           else
7436             output_asm_insn (AS2 (sbic,%m1-0x20,%2), operands);
7437         }
7438       else
7439         {
7440           output_asm_insn (AS2 (in,__tmp_reg__,%m1-0x20), operands);
7441           if (comp == EQ)
7442             output_asm_insn (AS2 (sbrs,__tmp_reg__,%2), operands);
7443           else
7444             output_asm_insn (AS2 (sbrc,__tmp_reg__,%2), operands);
7445         }
7446     }
7447   else  /* GET_CODE (operands[1]) == REG */
7448     {
7449       if (GET_MODE (operands[1]) == QImode)
7450         {
7451           if (comp == EQ)
7452             output_asm_insn (AS2 (sbrs,%1,%2), operands);
7453           else
7454             output_asm_insn (AS2 (sbrc,%1,%2), operands);
7455         }
7456       else  /* HImode or SImode */
7457         {
7458           static char buf[] = "sbrc %A1,0";
7459           int bit_nr = INTVAL (operands[2]);
7460           buf[3] = (comp == EQ) ? 's' : 'c';
7461           buf[6] = 'A' + (bit_nr >> 3);
7462           buf[9] = '0' + (bit_nr & 7);
7463           output_asm_insn (buf, operands);
7464         }
7465     }
7466
7467   if (long_jump)
7468     return (AS1 (rjmp,.+4) CR_TAB
7469             AS1 (jmp,%x3));
7470   if (!reverse)
7471     return AS1 (rjmp,%x3);
7472   return "";
7473 }
7474
7475 /* Worker function for TARGET_ASM_CONSTRUCTOR.  */
7476
7477 static void
7478 avr_asm_out_ctor (rtx symbol, int priority)
7479 {
7480   fputs ("\t.global __do_global_ctors\n", asm_out_file);
7481   default_ctor_section_asm_out_constructor (symbol, priority);
7482 }
7483
7484 /* Worker function for TARGET_ASM_DESTRUCTOR.  */
7485
7486 static void
7487 avr_asm_out_dtor (rtx symbol, int priority)
7488 {
7489   fputs ("\t.global __do_global_dtors\n", asm_out_file);
7490   default_dtor_section_asm_out_destructor (symbol, priority);
7491 }
7492
7493 /* Worker function for TARGET_RETURN_IN_MEMORY.  */
7494
7495 static bool
7496 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7497 {
7498   if (TYPE_MODE (type) == BLKmode)
7499     {
7500       HOST_WIDE_INT size = int_size_in_bytes (type);
7501       return (size == -1 || size > 8);
7502     }
7503   else
7504     return false;
7505 }
7506
7507 /* Worker function for CASE_VALUES_THRESHOLD.  */
7508
7509 unsigned int avr_case_values_threshold (void)
7510 {
7511   return (!AVR_HAVE_JMP_CALL || TARGET_CALL_PROLOGUES) ? 8 : 17;
7512 }
7513
7514 /* Helper for __builtin_avr_delay_cycles */
7515
7516 static void
7517 avr_expand_delay_cycles (rtx operands0)
7518 {
7519   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
7520   unsigned HOST_WIDE_INT cycles_used;
7521   unsigned HOST_WIDE_INT loop_count;
7522   
7523   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
7524     {
7525       loop_count = ((cycles - 9) / 6) + 1;
7526       cycles_used = ((loop_count - 1) * 6) + 9;
7527       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode)));
7528       cycles -= cycles_used;
7529     }
7530   
7531   if (IN_RANGE (cycles, 262145, 83886081))
7532     {
7533       loop_count = ((cycles - 7) / 5) + 1;
7534       if (loop_count > 0xFFFFFF)
7535         loop_count = 0xFFFFFF;
7536       cycles_used = ((loop_count - 1) * 5) + 7;
7537       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode)));
7538       cycles -= cycles_used;
7539     }
7540   
7541   if (IN_RANGE (cycles, 768, 262144))
7542     {
7543       loop_count = ((cycles - 5) / 4) + 1;
7544       if (loop_count > 0xFFFF)
7545         loop_count = 0xFFFF;
7546       cycles_used = ((loop_count - 1) * 4) + 5;
7547       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode)));
7548       cycles -= cycles_used;
7549     }
7550   
7551   if (IN_RANGE (cycles, 6, 767))
7552     {
7553       loop_count = cycles / 3;
7554       if (loop_count > 255) 
7555         loop_count = 255;
7556       cycles_used = loop_count * 3;
7557       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode)));
7558       cycles -= cycles_used;
7559       }
7560   
7561   while (cycles >= 2)
7562     {
7563       emit_insn (gen_nopv (GEN_INT(2)));
7564       cycles -= 2;
7565     }
7566
7567   if (cycles == 1)
7568     {
7569       emit_insn (gen_nopv (GEN_INT(1)));
7570       cycles--;
7571     }
7572 }
7573
7574 /* IDs for all the AVR builtins.  */
7575
7576 enum avr_builtin_id
7577   {
7578     AVR_BUILTIN_NOP,
7579     AVR_BUILTIN_SEI,
7580     AVR_BUILTIN_CLI,
7581     AVR_BUILTIN_WDR,
7582     AVR_BUILTIN_SLEEP,
7583     AVR_BUILTIN_SWAP,
7584     AVR_BUILTIN_FMUL,
7585     AVR_BUILTIN_FMULS,
7586     AVR_BUILTIN_FMULSU,
7587     AVR_BUILTIN_DELAY_CYCLES
7588   };
7589
7590 #define DEF_BUILTIN(NAME, TYPE, CODE)                                   \
7591   do                                                                    \
7592     {                                                                   \
7593       add_builtin_function ((NAME), (TYPE), (CODE), BUILT_IN_MD,        \
7594                             NULL, NULL_TREE);                           \
7595     } while (0)
7596
7597
7598 /* Implement `TARGET_INIT_BUILTINS' */
7599 /* Set up all builtin functions for this target.  */
7600
7601 static void
7602 avr_init_builtins (void)
7603 {
7604   tree void_ftype_void
7605     = build_function_type_list (void_type_node, NULL_TREE);
7606   tree uchar_ftype_uchar
7607     = build_function_type_list (unsigned_char_type_node, 
7608                                 unsigned_char_type_node,
7609                                 NULL_TREE);
7610   tree uint_ftype_uchar_uchar
7611     = build_function_type_list (unsigned_type_node, 
7612                                 unsigned_char_type_node,
7613                                 unsigned_char_type_node, 
7614                                 NULL_TREE);
7615   tree int_ftype_char_char
7616     = build_function_type_list (integer_type_node, 
7617                                 char_type_node,
7618                                 char_type_node, 
7619                                 NULL_TREE);
7620   tree int_ftype_char_uchar
7621     = build_function_type_list (integer_type_node, 
7622                                 char_type_node,
7623                                 unsigned_char_type_node, 
7624                                 NULL_TREE);
7625   tree void_ftype_ulong
7626     = build_function_type_list (void_type_node, 
7627                                 long_unsigned_type_node,
7628                                 NULL_TREE);
7629
7630   DEF_BUILTIN ("__builtin_avr_nop", void_ftype_void, AVR_BUILTIN_NOP);
7631   DEF_BUILTIN ("__builtin_avr_sei", void_ftype_void, AVR_BUILTIN_SEI);
7632   DEF_BUILTIN ("__builtin_avr_cli", void_ftype_void, AVR_BUILTIN_CLI);
7633   DEF_BUILTIN ("__builtin_avr_wdr", void_ftype_void, AVR_BUILTIN_WDR);
7634   DEF_BUILTIN ("__builtin_avr_sleep", void_ftype_void, AVR_BUILTIN_SLEEP);
7635   DEF_BUILTIN ("__builtin_avr_swap", uchar_ftype_uchar, AVR_BUILTIN_SWAP);
7636   DEF_BUILTIN ("__builtin_avr_delay_cycles", void_ftype_ulong, 
7637                AVR_BUILTIN_DELAY_CYCLES);
7638
7639   DEF_BUILTIN ("__builtin_avr_fmul", uint_ftype_uchar_uchar, 
7640                AVR_BUILTIN_FMUL);
7641   DEF_BUILTIN ("__builtin_avr_fmuls", int_ftype_char_char, 
7642                AVR_BUILTIN_FMULS);
7643   DEF_BUILTIN ("__builtin_avr_fmulsu", int_ftype_char_uchar, 
7644                AVR_BUILTIN_FMULSU);
7645 }
7646
7647 #undef DEF_BUILTIN
7648
7649 struct avr_builtin_description
7650 {
7651   const enum insn_code icode;
7652   const char *const name;
7653   const enum avr_builtin_id id;
7654 };
7655
7656 static const struct avr_builtin_description
7657 bdesc_1arg[] =
7658   {
7659     { CODE_FOR_rotlqi3_4, "__builtin_avr_swap", AVR_BUILTIN_SWAP }
7660   };
7661
7662 static const struct avr_builtin_description
7663 bdesc_2arg[] =
7664   {
7665     { CODE_FOR_fmul, "__builtin_avr_fmul", AVR_BUILTIN_FMUL },
7666     { CODE_FOR_fmuls, "__builtin_avr_fmuls", AVR_BUILTIN_FMULS },
7667     { CODE_FOR_fmulsu, "__builtin_avr_fmulsu", AVR_BUILTIN_FMULSU }
7668   };
7669
7670 /* Subroutine of avr_expand_builtin to take care of unop insns.  */
7671
7672 static rtx
7673 avr_expand_unop_builtin (enum insn_code icode, tree exp,
7674                          rtx target)
7675 {
7676   rtx pat;
7677   tree arg0 = CALL_EXPR_ARG (exp, 0);
7678   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7679   enum machine_mode op0mode = GET_MODE (op0);
7680   enum machine_mode tmode = insn_data[icode].operand[0].mode;
7681   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7682
7683   if (! target
7684       || GET_MODE (target) != tmode
7685       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7686     {
7687       target = gen_reg_rtx (tmode);
7688     }
7689
7690   if (op0mode == SImode && mode0 == HImode)
7691     {
7692       op0mode = HImode;
7693       op0 = gen_lowpart (HImode, op0);
7694     }
7695   
7696   gcc_assert (op0mode == mode0 || op0mode == VOIDmode);
7697
7698   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7699     op0 = copy_to_mode_reg (mode0, op0);
7700
7701   pat = GEN_FCN (icode) (target, op0);
7702   if (! pat)
7703     return 0;
7704   
7705   emit_insn (pat);
7706   
7707   return target;
7708 }
7709
7710
7711 /* Subroutine of avr_expand_builtin to take care of binop insns.  */
7712
7713 static rtx
7714 avr_expand_binop_builtin (enum insn_code icode, tree exp, rtx target)
7715 {
7716   rtx pat;
7717   tree arg0 = CALL_EXPR_ARG (exp, 0);
7718   tree arg1 = CALL_EXPR_ARG (exp, 1);
7719   rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7720   rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7721   enum machine_mode op0mode = GET_MODE (op0);
7722   enum machine_mode op1mode = GET_MODE (op1);
7723   enum machine_mode tmode = insn_data[icode].operand[0].mode;
7724   enum machine_mode mode0 = insn_data[icode].operand[1].mode;
7725   enum machine_mode mode1 = insn_data[icode].operand[2].mode;
7726
7727   if (! target
7728       || GET_MODE (target) != tmode
7729       || ! (*insn_data[icode].operand[0].predicate) (target, tmode))
7730     {
7731       target = gen_reg_rtx (tmode);
7732     }
7733
7734   if ((op0mode == SImode || op0mode == VOIDmode) && mode0 == HImode)
7735     {
7736       op0mode = HImode;
7737       op0 = gen_lowpart (HImode, op0);
7738     }
7739   
7740   if ((op1mode == SImode || op1mode == VOIDmode) && mode1 == HImode)
7741     {
7742       op1mode = HImode;
7743       op1 = gen_lowpart (HImode, op1);
7744     }
7745   
7746   /* In case the insn wants input operands in modes different from
7747      the result, abort.  */
7748   
7749   gcc_assert ((op0mode == mode0 || op0mode == VOIDmode)
7750               && (op1mode == mode1 || op1mode == VOIDmode));
7751
7752   if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
7753     op0 = copy_to_mode_reg (mode0, op0);
7754   
7755   if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
7756     op1 = copy_to_mode_reg (mode1, op1);
7757
7758   pat = GEN_FCN (icode) (target, op0, op1);
7759   
7760   if (! pat)
7761     return 0;
7762
7763   emit_insn (pat);
7764   return target;
7765 }
7766
7767
7768 /* Expand an expression EXP that calls a built-in function,
7769    with result going to TARGET if that's convenient
7770    (and in mode MODE if that's convenient).
7771    SUBTARGET may be used as the target for computing one of EXP's operands.
7772    IGNORE is nonzero if the value is to be ignored.  */
7773
7774 static rtx
7775 avr_expand_builtin (tree exp, rtx target,
7776                     rtx subtarget ATTRIBUTE_UNUSED,
7777                     enum machine_mode mode ATTRIBUTE_UNUSED,
7778                     int ignore ATTRIBUTE_UNUSED)
7779 {
7780   size_t i;
7781   const struct avr_builtin_description *d;
7782   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
7783   unsigned int id = DECL_FUNCTION_CODE (fndecl);
7784   tree arg0;
7785   rtx op0;
7786
7787   switch (id)
7788     {
7789     case AVR_BUILTIN_NOP:
7790       emit_insn (gen_nopv (GEN_INT(1)));
7791       return 0;
7792       
7793     case AVR_BUILTIN_SEI:
7794       emit_insn (gen_enable_interrupt ());
7795       return 0;
7796       
7797     case AVR_BUILTIN_CLI:
7798       emit_insn (gen_disable_interrupt ());
7799       return 0;
7800       
7801     case AVR_BUILTIN_WDR:
7802       emit_insn (gen_wdr ());
7803       return 0;
7804       
7805     case AVR_BUILTIN_SLEEP:
7806       emit_insn (gen_sleep ());
7807       return 0;
7808       
7809     case AVR_BUILTIN_DELAY_CYCLES:
7810       {
7811         arg0 = CALL_EXPR_ARG (exp, 0);
7812         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7813
7814         if (! CONST_INT_P (op0))
7815           error ("__builtin_avr_delay_cycles expects a compile time integer constant.");
7816
7817         avr_expand_delay_cycles (op0);
7818         return 0;
7819       }
7820     }
7821
7822   for (i = 0, d = bdesc_1arg; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
7823     if (d->id == id)
7824       return avr_expand_unop_builtin (d->icode, exp, target);
7825
7826   for (i = 0, d = bdesc_2arg; i < ARRAY_SIZE (bdesc_2arg); i++, d++)
7827     if (d->id == id)
7828       return avr_expand_binop_builtin (d->icode, exp, target);
7829
7830   gcc_unreachable ();
7831 }
7832
7833
7834 #include "gt-avr.h"