OSDN Git Service

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