OSDN Git Service

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