OSDN Git Service

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