OSDN Git Service

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