OSDN Git Service

* config/avr/avr.md (SREG_ADDR): Remove constant definition.
[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 "c-family/c-common.h"
39 #include "diagnostic-core.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "optabs.h"
44 #include "ggc.h"
45 #include "langhooks.h"
46 #include "tm_p.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "params.h"
50 #include "df.h"
51
52 /* Maximal allowed offset for an address in the LD command */
53 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
54
55 /* Return true if STR starts with PREFIX and false, otherwise.  */
56 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
57
58 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
59    address space where data is to be located.
60    As the only non-generic address spaces are all located in Flash,
61    this can be used to test if data shall go into some .progmem* section.
62    This must be the rightmost field of machine dependent section flags.  */
63 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
64
65 /* Similar 4-bit region for SYMBOL_REF_FLAGS.  */
66 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
67
68 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
69    Set address-space AS in SYMBOL_REF_FLAGS of SYM  */
70 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS)                       \
71   do {                                                          \
72     SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM;         \
73     SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP;      \
74   } while (0)
75
76 /* Read address-space from SYMBOL_REF_FLAGS of SYM  */
77 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM)                          \
78   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
79    / SYMBOL_FLAG_MACH_DEP)
80
81 /* Known address spaces.  The order must be the same as in the respective
82    enum from avr.h (or designated initialized must be used).  */
83 const avr_addrspace_t avr_addrspace[] =
84 {
85     { ADDR_SPACE_RAM,  0, 2, ""     ,   0 },
86     { ADDR_SPACE_FLASH,  1, 2, "__flash",   0 },
87     { ADDR_SPACE_FLASH1, 1, 2, "__flash1",  1 },
88     { ADDR_SPACE_FLASH2, 1, 2, "__flash2",  2 },
89     { ADDR_SPACE_FLASH3, 1, 2, "__flash3",  3 },
90     { ADDR_SPACE_FLASH4, 1, 2, "__flash4",  4 },
91     { ADDR_SPACE_FLASH5, 1, 2, "__flash5",  5 },
92     { ADDR_SPACE_MEMX, 1, 3, "__memx",  0 },
93     { 0              , 0, 0, NULL,      0 }
94 };
95
96 /* Map 64-k Flash segment to section prefix.  */
97 static const char* const progmem_section_prefix[6] =
98   {
99     ".progmem.data",
100     ".progmem1.data",
101     ".progmem2.data",
102     ".progmem3.data",
103     ".progmem4.data",
104     ".progmem5.data"
105   };
106
107 /* Holding RAM addresses of some SFRs used by the compiler and that
108    are unique over all devices in an architecture like 'avr4'.  */
109   
110 typedef struct
111 {
112   /* SREG: The pocessor status */
113   int sreg;
114
115   /* RAMPZ: The high byte of 24-bit address used with ELPM */ 
116   int rampz;
117
118   /* SP: The stack pointer and its low and high byte */
119   int sp_l;
120   int sp_h;
121 } avr_addr_t;
122
123 static avr_addr_t avr_addr;
124
125
126 /* Prototypes for local helper functions.  */
127
128 static const char* out_movqi_r_mr (rtx, rtx[], int*);
129 static const char* out_movhi_r_mr (rtx, rtx[], int*);
130 static const char* out_movsi_r_mr (rtx, rtx[], int*);
131 static const char* out_movqi_mr_r (rtx, rtx[], int*);
132 static const char* out_movhi_mr_r (rtx, rtx[], int*);
133 static const char* out_movsi_mr_r (rtx, rtx[], int*);
134
135 static int avr_naked_function_p (tree);
136 static int interrupt_function_p (tree);
137 static int signal_function_p (tree);
138 static int avr_OS_task_function_p (tree);
139 static int avr_OS_main_function_p (tree);
140 static int avr_regs_to_save (HARD_REG_SET *);
141 static int get_sequence_length (rtx insns);
142 static int sequent_regs_live (void);
143 static const char *ptrreg_to_str (int);
144 static const char *cond_string (enum rtx_code);
145 static int avr_num_arg_regs (enum machine_mode, const_tree);
146 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
147                                  int, bool);
148 static void output_reload_in_const (rtx*, rtx, int*, bool);
149 static struct machine_function * avr_init_machine_status (void);
150
151
152 /* Prototypes for hook implementors if needed before their implementation.  */
153
154 static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
155
156
157 /* Allocate registers from r25 to r8 for parameters for function calls.  */
158 #define FIRST_CUM_REG 26
159
160 /* Implicit target register of LPM instruction (R0) */
161 extern GTY(()) rtx lpm_reg_rtx;
162 rtx lpm_reg_rtx;
163
164 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
165 extern GTY(()) rtx lpm_addr_reg_rtx;
166 rtx lpm_addr_reg_rtx;
167
168 /* Temporary register RTX (reg:QI TMP_REGNO) */
169 extern GTY(()) rtx tmp_reg_rtx;
170 rtx tmp_reg_rtx;
171
172 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
173 extern GTY(()) rtx zero_reg_rtx;
174 rtx zero_reg_rtx;
175
176 /* RTXs for all general purpose registers as QImode */
177 extern GTY(()) rtx all_regs_rtx[32];
178 rtx all_regs_rtx[32];
179
180 /* RAMPZ special function register */
181 extern GTY(()) rtx rampz_rtx;
182 rtx rampz_rtx;
183
184 /* RTX containing the strings "" and "e", respectively */
185 static GTY(()) rtx xstring_empty;
186 static GTY(()) rtx xstring_e;
187
188 /* Preprocessor macros to define depending on MCU type.  */
189 const char *avr_extra_arch_macro;
190
191 /* Current architecture.  */
192 const struct base_arch_s *avr_current_arch;
193
194 /* Current device.  */
195 const struct mcu_type_s *avr_current_device;
196
197 /* Section to put switch tables in.  */
198 static GTY(()) section *progmem_swtable_section;
199
200 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
201    or to address space __flash*.  */
202 static GTY(()) section *progmem_section[6];
203
204 /* Condition for insns/expanders from avr-dimode.md.  */
205 bool avr_have_dimode = true;
206
207 /* To track if code will use .bss and/or .data.  */
208 bool avr_need_clear_bss_p = false;
209 bool avr_need_copy_data_p = false;
210
211 \f
212 /* Initialize the GCC target structure.  */
213 #undef TARGET_ASM_ALIGNED_HI_OP
214 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
215 #undef TARGET_ASM_ALIGNED_SI_OP
216 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
217 #undef TARGET_ASM_UNALIGNED_HI_OP
218 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
219 #undef TARGET_ASM_UNALIGNED_SI_OP
220 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
221 #undef TARGET_ASM_INTEGER
222 #define TARGET_ASM_INTEGER avr_assemble_integer
223 #undef TARGET_ASM_FILE_START
224 #define TARGET_ASM_FILE_START avr_file_start
225 #undef TARGET_ASM_FILE_END
226 #define TARGET_ASM_FILE_END avr_file_end
227
228 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
229 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
230 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
231 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
232
233 #undef TARGET_FUNCTION_VALUE
234 #define TARGET_FUNCTION_VALUE avr_function_value
235 #undef TARGET_LIBCALL_VALUE
236 #define TARGET_LIBCALL_VALUE avr_libcall_value
237 #undef TARGET_FUNCTION_VALUE_REGNO_P
238 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
239
240 #undef TARGET_ATTRIBUTE_TABLE
241 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
242 #undef TARGET_INSERT_ATTRIBUTES
243 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
244 #undef TARGET_SECTION_TYPE_FLAGS
245 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
246
247 #undef TARGET_ASM_NAMED_SECTION
248 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
249 #undef TARGET_ASM_INIT_SECTIONS
250 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
251 #undef TARGET_ENCODE_SECTION_INFO
252 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
253 #undef TARGET_ASM_SELECT_SECTION
254 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
255
256 #undef TARGET_REGISTER_MOVE_COST
257 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
258 #undef TARGET_MEMORY_MOVE_COST
259 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
260 #undef TARGET_RTX_COSTS
261 #define TARGET_RTX_COSTS avr_rtx_costs
262 #undef TARGET_ADDRESS_COST
263 #define TARGET_ADDRESS_COST avr_address_cost
264 #undef TARGET_MACHINE_DEPENDENT_REORG
265 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
266 #undef TARGET_FUNCTION_ARG
267 #define TARGET_FUNCTION_ARG avr_function_arg
268 #undef TARGET_FUNCTION_ARG_ADVANCE
269 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
270
271 #undef TARGET_RETURN_IN_MEMORY
272 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
273
274 #undef TARGET_STRICT_ARGUMENT_NAMING
275 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
276
277 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
278 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
279
280 #undef TARGET_HARD_REGNO_SCRATCH_OK
281 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
282 #undef TARGET_CASE_VALUES_THRESHOLD
283 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
284
285 #undef TARGET_FRAME_POINTER_REQUIRED
286 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
287 #undef TARGET_CAN_ELIMINATE
288 #define TARGET_CAN_ELIMINATE avr_can_eliminate
289
290 #undef TARGET_CLASS_LIKELY_SPILLED_P
291 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
292
293 #undef TARGET_OPTION_OVERRIDE
294 #define TARGET_OPTION_OVERRIDE avr_option_override
295
296 #undef TARGET_CANNOT_MODIFY_JUMPS_P
297 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
298
299 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
300 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
301
302 #undef TARGET_INIT_BUILTINS
303 #define TARGET_INIT_BUILTINS avr_init_builtins
304
305 #undef TARGET_EXPAND_BUILTIN
306 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
307
308 #undef TARGET_ASM_FUNCTION_RODATA_SECTION
309 #define TARGET_ASM_FUNCTION_RODATA_SECTION avr_asm_function_rodata_section
310
311 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
312 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
313
314 #undef  TARGET_ADDR_SPACE_SUBSET_P
315 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
316
317 #undef  TARGET_ADDR_SPACE_CONVERT
318 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
319
320 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
321 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
322
323 #undef  TARGET_ADDR_SPACE_POINTER_MODE
324 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
325
326 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
327 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P avr_addr_space_legitimate_address_p
328
329 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
330 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
331
332 #undef  TARGET_PRINT_OPERAND
333 #define TARGET_PRINT_OPERAND avr_print_operand
334 #undef  TARGET_PRINT_OPERAND_ADDRESS
335 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
336 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
337 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
338
339 \f
340
341 /* Custom function to count number of set bits.  */
342
343 static inline int
344 avr_popcount (unsigned int val)
345 {
346   int pop = 0;
347
348   while (val)
349     {
350       val &= val-1;
351       pop++;
352     }
353
354   return pop;
355 }
356
357
358 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
359    Return true if the least significant N_BYTES bytes of XVAL all have a
360    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
361    of integers which contains an integer N iff bit N of POP_MASK is set.  */
362    
363 bool
364 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
365 {
366   int i;
367
368   enum machine_mode mode = GET_MODE (xval);
369
370   if (VOIDmode == mode)
371     mode = SImode;
372
373   for (i = 0; i < n_bytes; i++)
374     {
375       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
376       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
377
378       if (0 == (pop_mask & (1 << avr_popcount (val8))))
379         return false;
380     }
381
382   return true;
383 }
384
385 static void
386 avr_option_override (void)
387 {
388   flag_delete_null_pointer_checks = 0;
389
390   /* caller-save.c looks for call-clobbered hard registers that are assigned
391      to pseudos that cross calls and tries so save-restore them around calls
392      in order to reduce the number of stack slots needed.
393
394      This might leads to situations where reload is no more able to cope
395      with the challenge of AVR's very few address registers and fails to
396      perform the requested spills.  */
397   
398   if (avr_strict_X)
399     flag_caller_saves = 0;
400
401   /* Unwind tables currently require a frame pointer for correctness,
402      see toplev.c:process_options().  */
403
404   if ((flag_unwind_tables
405        || flag_non_call_exceptions
406        || flag_asynchronous_unwind_tables)
407       && !ACCUMULATE_OUTGOING_ARGS)
408     {
409       flag_omit_frame_pointer = 0;
410     }
411
412   avr_current_device = &avr_mcu_types[avr_mcu_index];
413   avr_current_arch = &avr_arch_types[avr_current_device->arch];
414   avr_extra_arch_macro = avr_current_device->macro;
415   
416   /* RAM addresses of some SFRs common to all Devices in respective Arch. */
417
418   /* SREG: Status Register containing flags like I (global IRQ) */
419   avr_addr.sreg = 0x3F + avr_current_arch->sfr_offset;
420
421   /* RAMPZ: Address' high part when loading via ELPM */
422   avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
423
424   /* SP: Stack Pointer (SP_H:SP_L) */
425   avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
426   avr_addr.sp_h = avr_addr.sp_l + 1;
427
428   init_machine_status = avr_init_machine_status;
429
430   avr_log_set_avr_log();
431 }
432
433 /* Function to set up the backend function structure.  */
434
435 static struct machine_function *
436 avr_init_machine_status (void)
437 {
438   return ggc_alloc_cleared_machine_function ();
439 }
440
441
442 /* Implement `INIT_EXPANDERS'.  */
443 /* The function works like a singleton.  */
444
445 void
446 avr_init_expanders (void)
447 {
448   int regno;
449
450   static bool done = false;
451
452   if (done)
453     return;
454   else
455     done = true;
456
457   for (regno = 0; regno < 32; regno ++)
458     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
459
460   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
461   tmp_reg_rtx  = all_regs_rtx[TMP_REGNO];
462   zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
463
464   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
465
466   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
467
468   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
469   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
470 }
471
472
473 /* Return register class for register R.  */
474
475 enum reg_class
476 avr_regno_reg_class (int r)
477 {
478   static const enum reg_class reg_class_tab[] =
479     {
480       R0_REG,
481       /* r1 - r15 */
482       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
483       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
484       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
485       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
486       /* r16 - r23 */
487       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
488       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
489       /* r24, r25 */
490       ADDW_REGS, ADDW_REGS,
491       /* X: r26, 27 */
492       POINTER_X_REGS, POINTER_X_REGS,
493       /* Y: r28, r29 */
494       POINTER_Y_REGS, POINTER_Y_REGS,
495       /* Z: r30, r31 */
496       POINTER_Z_REGS, POINTER_Z_REGS,
497       /* SP: SPL, SPH */
498       STACK_REG, STACK_REG
499     };
500
501   if (r <= 33)
502     return reg_class_tab[r];
503   
504   return ALL_REGS;
505 }
506
507
508 static bool
509 avr_scalar_mode_supported_p (enum machine_mode mode)
510 {
511   if (PSImode == mode)
512     return true;
513
514   return default_scalar_mode_supported_p (mode);
515 }
516
517
518 /* Return TRUE if DECL is a VAR_DECL located in Flash and FALSE, otherwise.  */
519
520 static bool
521 avr_decl_flash_p (tree decl)
522 {
523   if (TREE_CODE (decl) != VAR_DECL
524       || TREE_TYPE (decl) == error_mark_node)
525     {
526       return false;
527     }
528
529   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
530 }
531
532
533 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit Flash
534    address space and FALSE, otherwise.  */
535  
536 static bool
537 avr_decl_memx_p (tree decl)
538 {
539   if (TREE_CODE (decl) != VAR_DECL
540       || TREE_TYPE (decl) == error_mark_node)
541     {
542       return false;
543     }
544
545   return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
546 }
547
548
549 /* Return TRUE if X is a MEM rtx located in Flash and FALSE, otherwise.  */
550
551 bool
552 avr_mem_flash_p (rtx x)
553 {
554   return (MEM_P (x)
555           && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
556 }
557
558
559 /* Return TRUE if X is a MEM rtx located in the 24-bit Flash
560    address space and FALSE, otherwise.  */
561
562 bool
563 avr_mem_memx_p (rtx x)
564 {
565   return (MEM_P (x)
566           && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
567 }
568
569
570 /* A helper for the subsequent function attribute used to dig for
571    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
572
573 static inline int
574 avr_lookup_function_attribute1 (const_tree func, const char *name)
575 {
576   if (FUNCTION_DECL == TREE_CODE (func))
577     {
578       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
579         {
580           return true;
581         }
582       
583       func = TREE_TYPE (func);
584     }
585
586   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
587               || TREE_CODE (func) == METHOD_TYPE);
588   
589   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
590 }
591
592 /* Return nonzero if FUNC is a naked function.  */
593
594 static int
595 avr_naked_function_p (tree func)
596 {
597   return avr_lookup_function_attribute1 (func, "naked");
598 }
599
600 /* Return nonzero if FUNC is an interrupt function as specified
601    by the "interrupt" attribute.  */
602
603 static int
604 interrupt_function_p (tree func)
605 {
606   return avr_lookup_function_attribute1 (func, "interrupt");
607 }
608
609 /* Return nonzero if FUNC is a signal function as specified
610    by the "signal" attribute.  */
611
612 static int
613 signal_function_p (tree func)
614 {
615   return avr_lookup_function_attribute1 (func, "signal");
616 }
617
618 /* Return nonzero if FUNC is an OS_task function.  */
619
620 static int
621 avr_OS_task_function_p (tree func)
622 {
623   return avr_lookup_function_attribute1 (func, "OS_task");
624 }
625
626 /* Return nonzero if FUNC is an OS_main function.  */
627
628 static int
629 avr_OS_main_function_p (tree func)
630 {
631   return avr_lookup_function_attribute1 (func, "OS_main");
632 }
633
634
635 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
636 bool
637 avr_accumulate_outgoing_args (void)
638 {
639   if (!cfun)
640     return TARGET_ACCUMULATE_OUTGOING_ARGS;
641
642   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
643         what offset is correct.  In some cases it is relative to
644         virtual_outgoing_args_rtx and in others it is relative to
645         virtual_stack_vars_rtx.  For example code see
646             gcc.c-torture/execute/built-in-setjmp.c
647             gcc.c-torture/execute/builtins/sprintf-chk.c   */
648   
649   return (TARGET_ACCUMULATE_OUTGOING_ARGS
650           && !(cfun->calls_setjmp
651                || cfun->has_nonlocal_label));
652 }
653
654
655 /* Report contribution of accumulated outgoing arguments to stack size.  */
656
657 static inline int
658 avr_outgoing_args_size (void)
659 {
660   return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
661 }
662
663
664 /* Implement `STARTING_FRAME_OFFSET'.  */
665 /* This is the offset from the frame pointer register to the first stack slot
666    that contains a variable living in the frame.  */
667
668 int
669 avr_starting_frame_offset (void)
670 {
671   return 1 + avr_outgoing_args_size ();
672 }
673
674
675 /* Return the number of hard registers to push/pop in the prologue/epilogue
676    of the current function, and optionally store these registers in SET.  */
677
678 static int
679 avr_regs_to_save (HARD_REG_SET *set)
680 {
681   int reg, count;
682   int int_or_sig_p = (interrupt_function_p (current_function_decl)
683                       || signal_function_p (current_function_decl));
684
685   if (set)
686     CLEAR_HARD_REG_SET (*set);
687   count = 0;
688
689   /* No need to save any registers if the function never returns or 
690      has the "OS_task" or "OS_main" attribute.  */
691   if (TREE_THIS_VOLATILE (current_function_decl)
692       || cfun->machine->is_OS_task
693       || cfun->machine->is_OS_main)
694     return 0;
695
696   for (reg = 0; reg < 32; reg++)
697     {
698       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
699          any global register variables.  */
700       if (fixed_regs[reg])
701         continue;
702
703       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
704           || (df_regs_ever_live_p (reg)
705               && (int_or_sig_p || !call_used_regs[reg])
706               /* Don't record frame pointer registers here.  They are treated
707                  indivitually in prologue.  */
708               && !(frame_pointer_needed
709                    && (reg == REG_Y || reg == (REG_Y+1)))))
710         {
711           if (set)
712             SET_HARD_REG_BIT (*set, reg);
713           count++;
714         }
715     }
716   return count;
717 }
718
719 /* Return true if register FROM can be eliminated via register TO.  */
720
721 static bool
722 avr_can_eliminate (const int from, const int to)
723 {
724   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
725           || (frame_pointer_needed && to == FRAME_POINTER_REGNUM)
726           || ((from == FRAME_POINTER_REGNUM 
727                || from == FRAME_POINTER_REGNUM + 1)
728               && !frame_pointer_needed));
729 }
730
731 /* Compute offset between arg_pointer and frame_pointer.  */
732
733 int
734 avr_initial_elimination_offset (int from, int to)
735 {
736   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
737     return 0;
738   else
739     {
740       int offset = frame_pointer_needed ? 2 : 0;
741       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
742       
743       offset += avr_regs_to_save (NULL);
744       return (get_frame_size () + avr_outgoing_args_size()
745               + avr_pc_size + 1 + offset);
746     }
747 }
748
749 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
750    frame pointer by +STARTING_FRAME_OFFSET.
751    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
752    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
753
754 static rtx
755 avr_builtin_setjmp_frame_value (void)
756 {
757   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
758                         gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
759 }
760
761 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
762    This is return address of function.  */
763 rtx 
764 avr_return_addr_rtx (int count, rtx tem)
765 {
766   rtx r;
767     
768   /* Can only return this function's return address. Others not supported.  */
769   if (count)
770      return NULL;
771
772   if (AVR_3_BYTE_PC)
773     {
774       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
775       warning (0, "'builtin_return_address' contains only 2 bytes of address");
776     }
777   else
778     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
779
780   r = gen_rtx_PLUS (Pmode, tem, r);
781   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
782   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
783   return  r;
784 }
785
786 /* Return 1 if the function epilogue is just a single "ret".  */
787
788 int
789 avr_simple_epilogue (void)
790 {
791   return (! frame_pointer_needed
792           && get_frame_size () == 0
793           && avr_outgoing_args_size() == 0
794           && avr_regs_to_save (NULL) == 0
795           && ! interrupt_function_p (current_function_decl)
796           && ! signal_function_p (current_function_decl)
797           && ! avr_naked_function_p (current_function_decl)
798           && ! TREE_THIS_VOLATILE (current_function_decl));
799 }
800
801 /* This function checks sequence of live registers.  */
802
803 static int
804 sequent_regs_live (void)
805 {
806   int reg;
807   int live_seq=0;
808   int cur_seq=0;
809
810   for (reg = 0; reg < 18; ++reg)
811     {
812       if (fixed_regs[reg])
813         {
814           /* Don't recognize sequences that contain global register
815              variables.  */
816       
817           if (live_seq != 0)
818             return 0;
819           else
820             continue;
821         }
822       
823       if (!call_used_regs[reg])
824         {
825           if (df_regs_ever_live_p (reg))
826             {
827               ++live_seq;
828               ++cur_seq;
829             }
830           else
831             cur_seq = 0;
832         }
833     }
834
835   if (!frame_pointer_needed)
836     {
837       if (df_regs_ever_live_p (REG_Y))
838         {
839           ++live_seq;
840           ++cur_seq;
841         }
842       else
843         cur_seq = 0;
844
845       if (df_regs_ever_live_p (REG_Y+1))
846         {
847           ++live_seq;
848           ++cur_seq;
849         }
850       else
851         cur_seq = 0;
852     }
853   else
854     {
855       cur_seq += 2;
856       live_seq += 2;
857     }
858   return (cur_seq == live_seq) ? live_seq : 0;
859 }
860
861 /* Obtain the length sequence of insns.  */
862
863 int
864 get_sequence_length (rtx insns)
865 {
866   rtx insn;
867   int length;
868   
869   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
870     length += get_attr_length (insn);
871                 
872   return length;
873 }
874
875 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
876
877 rtx
878 avr_incoming_return_addr_rtx (void)
879 {
880   /* The return address is at the top of the stack.  Note that the push
881      was via post-decrement, which means the actual address is off by one.  */
882   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
883 }
884
885 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
886
887 static void
888 emit_push_byte (unsigned regno, bool frame_related_p)
889 {
890   rtx mem, reg, insn;
891
892   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
893   mem = gen_frame_mem (QImode, mem);
894   reg = gen_rtx_REG (QImode, regno);
895
896   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
897   if (frame_related_p)
898     RTX_FRAME_RELATED_P (insn) = 1;
899
900   cfun->machine->stack_usage++;
901 }
902
903 static void
904 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
905 {
906   rtx insn;
907   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
908   int live_seq = sequent_regs_live ();
909
910   bool minimize = (TARGET_CALL_PROLOGUES
911                    && live_seq
912                    && !isr_p
913                    && !cfun->machine->is_OS_task
914                    && !cfun->machine->is_OS_main);
915   
916   if (minimize
917       && (frame_pointer_needed
918           || avr_outgoing_args_size() > 8
919           || (AVR_2_BYTE_PC && live_seq > 6)
920           || live_seq > 7)) 
921     {
922       rtx pattern;
923       int first_reg, reg, offset;
924
925       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
926                       gen_int_mode (size, HImode));
927
928       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
929                                          gen_int_mode (live_seq+size, HImode));
930       insn = emit_insn (pattern);
931       RTX_FRAME_RELATED_P (insn) = 1;
932
933       /* Describe the effect of the unspec_volatile call to prologue_saves.
934          Note that this formulation assumes that add_reg_note pushes the
935          notes to the front.  Thus we build them in the reverse order of
936          how we want dwarf2out to process them.  */
937
938       /* The function does always set frame_pointer_rtx, but whether that
939          is going to be permanent in the function is frame_pointer_needed.  */
940
941       add_reg_note (insn, REG_CFA_ADJUST_CFA,
942                     gen_rtx_SET (VOIDmode, (frame_pointer_needed
943                                             ? frame_pointer_rtx
944                                             : stack_pointer_rtx),
945                                  plus_constant (stack_pointer_rtx,
946                                                 -(size + live_seq))));
947
948       /* Note that live_seq always contains r28+r29, but the other
949          registers to be saved are all below 18.  */
950
951       first_reg = 18 - (live_seq - 2);
952
953       for (reg = 29, offset = -live_seq + 1;
954            reg >= first_reg;
955            reg = (reg == 28 ? 17 : reg - 1), ++offset)
956         {
957           rtx m, r;
958
959           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
960           r = gen_rtx_REG (QImode, reg);
961           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
962         }
963
964       cfun->machine->stack_usage += size + live_seq;
965     }
966   else /* !minimize */
967     {
968       int reg;
969       
970       for (reg = 0; reg < 32; ++reg)
971         if (TEST_HARD_REG_BIT (set, reg))
972           emit_push_byte (reg, true);
973
974       if (frame_pointer_needed
975           && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
976         {
977           /* Push frame pointer.  Always be consistent about the
978              ordering of pushes -- epilogue_restores expects the
979              register pair to be pushed low byte first.  */
980           
981           emit_push_byte (REG_Y, true);
982           emit_push_byte (REG_Y + 1, true);
983         }
984           
985       if (frame_pointer_needed
986           && size == 0)
987         {
988           insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
989           RTX_FRAME_RELATED_P (insn) = 1;
990         }
991       
992       if (size != 0)
993         {
994           /*  Creating a frame can be done by direct manipulation of the
995               stack or via the frame pointer. These two methods are:
996                   fp =  sp
997                   fp -= size
998                   sp =  fp
999               or
1000                   sp -= size
1001                   fp =  sp    (*)
1002               the optimum method depends on function type, stack and
1003               frame size.  To avoid a complex logic, both methods are
1004               tested and shortest is selected.
1005
1006               There is also the case where SIZE != 0 and no frame pointer is
1007               needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1008               In that case, insn (*) is not needed in that case.
1009               We use the X register as scratch. This is save because in X
1010               is call-clobbered.
1011                  In an interrupt routine, the case of SIZE != 0 together with
1012               !frame_pointer_needed can only occur if the function is not a
1013               leaf function and thus X has already been saved.  */
1014               
1015           rtx fp_plus_insns, fp, my_fp;
1016           rtx sp_minus_size = plus_constant (stack_pointer_rtx, -size);
1017
1018           gcc_assert (frame_pointer_needed
1019                       || !isr_p
1020                       || !current_function_is_leaf);
1021           
1022           fp = my_fp = (frame_pointer_needed
1023                         ? frame_pointer_rtx
1024                         : gen_rtx_REG (Pmode, REG_X));
1025           
1026           if (AVR_HAVE_8BIT_SP)
1027             {
1028               /* The high byte (r29) does not change:
1029                  Prefer SUBI (1 cycle) over ABIW (2 cycles, same size).  */
1030
1031               my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1032             }
1033
1034           /************  Method 1: Adjust frame pointer  ************/
1035           
1036           start_sequence ();
1037
1038           /* Normally, the dwarf2out frame-related-expr interpreter does
1039              not expect to have the CFA change once the frame pointer is
1040              set up.  Thus, we avoid marking the move insn below and
1041              instead indicate that the entire operation is complete after
1042              the frame pointer subtraction is done.  */
1043           
1044           insn = emit_move_insn (fp, stack_pointer_rtx);
1045           if (!frame_pointer_needed)
1046             RTX_FRAME_RELATED_P (insn) = 1;
1047
1048           insn = emit_move_insn (my_fp, plus_constant (my_fp, -size));
1049           RTX_FRAME_RELATED_P (insn) = 1;
1050           
1051           if (frame_pointer_needed)
1052             {
1053               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1054                             gen_rtx_SET (VOIDmode, fp, sp_minus_size));
1055             }
1056           
1057           /* Copy to stack pointer.  Note that since we've already
1058              changed the CFA to the frame pointer this operation
1059              need not be annotated if frame pointer is needed.  */
1060               
1061           if (AVR_HAVE_8BIT_SP)
1062             {
1063               insn = emit_move_insn (stack_pointer_rtx, fp);
1064             }
1065           else if (TARGET_NO_INTERRUPTS 
1066                    || isr_p
1067                    || cfun->machine->is_OS_main)
1068             {
1069               rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
1070               
1071               insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1072                                                 fp, irqs_are_on));
1073             }
1074           else
1075             {
1076               insn = emit_move_insn (stack_pointer_rtx, fp);
1077             }
1078
1079           if (!frame_pointer_needed)
1080             RTX_FRAME_RELATED_P (insn) = 1;
1081
1082           fp_plus_insns = get_insns ();
1083           end_sequence ();
1084           
1085           /************  Method 2: Adjust Stack pointer  ************/
1086
1087           /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1088              can only handle specific offsets.  */
1089           
1090           if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1091             {
1092               rtx sp_plus_insns;
1093               
1094               start_sequence ();
1095
1096               insn = emit_move_insn (stack_pointer_rtx, sp_minus_size);
1097               RTX_FRAME_RELATED_P (insn) = 1;
1098
1099               if (frame_pointer_needed)
1100                 {
1101                   insn = emit_move_insn (fp, stack_pointer_rtx);
1102                   RTX_FRAME_RELATED_P (insn) = 1;
1103                 }
1104
1105               sp_plus_insns = get_insns ();
1106               end_sequence ();
1107
1108               /************ Use shortest method  ************/
1109                   
1110               emit_insn (get_sequence_length (sp_plus_insns)
1111                          < get_sequence_length (fp_plus_insns)
1112                          ? sp_plus_insns
1113                          : fp_plus_insns);
1114             }
1115           else
1116             {
1117               emit_insn (fp_plus_insns);
1118             }
1119
1120           cfun->machine->stack_usage += size;
1121         } /* !minimize && size != 0 */
1122     } /* !minimize */
1123 }
1124
1125
1126 /*  Output function prologue.  */
1127
1128 void
1129 expand_prologue (void)
1130 {
1131   HARD_REG_SET set;
1132   HOST_WIDE_INT size;
1133
1134   size = get_frame_size() + avr_outgoing_args_size();
1135   
1136   /* Init cfun->machine.  */
1137   cfun->machine->is_naked = avr_naked_function_p (current_function_decl);
1138   cfun->machine->is_interrupt = interrupt_function_p (current_function_decl);
1139   cfun->machine->is_signal = signal_function_p (current_function_decl);
1140   cfun->machine->is_OS_task = avr_OS_task_function_p (current_function_decl);
1141   cfun->machine->is_OS_main = avr_OS_main_function_p (current_function_decl);
1142   cfun->machine->stack_usage = 0;
1143   
1144   /* Prologue: naked.  */
1145   if (cfun->machine->is_naked)
1146     {
1147       return;
1148     }
1149
1150   avr_regs_to_save (&set);
1151
1152   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1153     {
1154       /* Enable interrupts.  */
1155       if (cfun->machine->is_interrupt)
1156         emit_insn (gen_enable_interrupt ());
1157         
1158       /* Push zero reg.  */
1159       emit_push_byte (ZERO_REGNO, true);
1160
1161       /* Push tmp reg.  */
1162       emit_push_byte (TMP_REGNO, true);
1163
1164       /* Push SREG.  */
1165       /* ??? There's no dwarf2 column reserved for SREG.  */
1166       emit_move_insn (tmp_reg_rtx,
1167                       gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg)));
1168       emit_push_byte (TMP_REGNO, false);
1169
1170       /* Push RAMPZ.  */
1171       /* ??? There's no dwarf2 column reserved for RAMPZ.  */
1172       if (AVR_HAVE_RAMPZ 
1173           && TEST_HARD_REG_BIT (set, REG_Z)
1174           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1175         {
1176           emit_move_insn (tmp_reg_rtx, rampz_rtx);
1177           emit_push_byte (TMP_REGNO, false);
1178         }
1179         
1180       /* Clear zero reg.  */
1181       emit_move_insn (zero_reg_rtx, const0_rtx);
1182
1183       /* Prevent any attempt to delete the setting of ZERO_REG!  */
1184       emit_use (zero_reg_rtx);
1185     }
1186
1187   avr_prologue_setup_frame (size, set);
1188   
1189   if (flag_stack_usage_info)
1190     current_function_static_stack_size = cfun->machine->stack_usage;
1191 }
1192
1193 /* Output summary at end of function prologue.  */
1194
1195 static void
1196 avr_asm_function_end_prologue (FILE *file)
1197 {
1198   if (cfun->machine->is_naked)
1199     {
1200       fputs ("/* prologue: naked */\n", file);
1201     }
1202   else
1203     {
1204       if (cfun->machine->is_interrupt)
1205         {
1206           fputs ("/* prologue: Interrupt */\n", file);
1207         }
1208       else if (cfun->machine->is_signal)
1209         {
1210           fputs ("/* prologue: Signal */\n", file);
1211         }
1212       else
1213         fputs ("/* prologue: function */\n", file);
1214     }
1215
1216   if (ACCUMULATE_OUTGOING_ARGS)
1217     fprintf (file, "/* outgoing args size = %d */\n",
1218              avr_outgoing_args_size());
1219
1220   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1221                  get_frame_size());
1222   fprintf (file, "/* stack size = %d */\n",
1223                  cfun->machine->stack_usage);
1224   /* Create symbol stack offset here so all functions have it. Add 1 to stack
1225      usage for offset so that SP + .L__stack_offset = return address.  */
1226   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1227 }
1228
1229
1230 /* Implement EPILOGUE_USES.  */
1231
1232 int
1233 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1234 {
1235   if (reload_completed 
1236       && cfun->machine
1237       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1238     return 1;
1239   return 0;
1240 }
1241
1242 /*  Helper for expand_epilogue.  Emit a pop of a byte register.  */
1243
1244 static void
1245 emit_pop_byte (unsigned regno)
1246 {
1247   rtx mem, reg;
1248
1249   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1250   mem = gen_frame_mem (QImode, mem);
1251   reg = gen_rtx_REG (QImode, regno);
1252
1253   emit_insn (gen_rtx_SET (VOIDmode, reg, mem));
1254 }
1255
1256 /*  Output RTL epilogue.  */
1257
1258 void
1259 expand_epilogue (bool sibcall_p)
1260 {
1261   int reg;
1262   int live_seq;
1263   HARD_REG_SET set;      
1264   int minimize;
1265   HOST_WIDE_INT size;
1266   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1267
1268   size = get_frame_size() + avr_outgoing_args_size();
1269   
1270   /* epilogue: naked  */
1271   if (cfun->machine->is_naked)
1272     {
1273       gcc_assert (!sibcall_p);
1274       
1275       emit_jump_insn (gen_return ());
1276       return;
1277     }
1278
1279   avr_regs_to_save (&set);
1280   live_seq = sequent_regs_live ();
1281   
1282   minimize = (TARGET_CALL_PROLOGUES
1283               && live_seq
1284               && !isr_p
1285               && !cfun->machine->is_OS_task
1286               && !cfun->machine->is_OS_main);
1287   
1288   if (minimize
1289       && (live_seq > 4
1290           || frame_pointer_needed
1291           || size))
1292     {
1293       /*  Get rid of frame.  */
1294       
1295       if (!frame_pointer_needed)
1296         {
1297           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1298         }
1299
1300       if (size)
1301         {
1302           emit_move_insn (frame_pointer_rtx,
1303                           plus_constant (frame_pointer_rtx, size));
1304         }
1305         
1306       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1307       return;
1308     }
1309       
1310   if (size)
1311     {
1312       /* Try two methods to adjust stack and select shortest.  */
1313           
1314       rtx fp, my_fp;
1315       rtx fp_plus_insns;
1316
1317       gcc_assert (frame_pointer_needed
1318                   || !isr_p
1319                   || !current_function_is_leaf);
1320       
1321       fp = my_fp = (frame_pointer_needed
1322                     ? frame_pointer_rtx
1323                     : gen_rtx_REG (Pmode, REG_X));
1324
1325       if (AVR_HAVE_8BIT_SP)
1326         {
1327           /* The high byte (r29) does not change:
1328              Prefer SUBI (1 cycle) over SBIW (2 cycles).  */
1329                   
1330           my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1331         }
1332               
1333       /********** Method 1: Adjust fp register  **********/
1334               
1335       start_sequence ();
1336
1337       if (!frame_pointer_needed)
1338         emit_move_insn (fp, stack_pointer_rtx);
1339
1340       emit_move_insn (my_fp, plus_constant (my_fp, size));
1341
1342       /* Copy to stack pointer.  */
1343               
1344       if (AVR_HAVE_8BIT_SP)
1345         {
1346           emit_move_insn (stack_pointer_rtx, fp);
1347         }
1348       else if (TARGET_NO_INTERRUPTS 
1349                || isr_p
1350                || cfun->machine->is_OS_main)
1351         {
1352           rtx irqs_are_on = GEN_INT (!!cfun->machine->is_interrupt);
1353           
1354           emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp, irqs_are_on));
1355         }
1356       else
1357         {
1358           emit_move_insn (stack_pointer_rtx, fp);
1359         }
1360
1361       fp_plus_insns = get_insns ();
1362       end_sequence ();        
1363
1364       /********** Method 2: Adjust Stack pointer  **********/
1365       
1366       if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1367         {
1368           rtx sp_plus_insns;
1369
1370           start_sequence ();
1371
1372           emit_move_insn (stack_pointer_rtx,
1373                           plus_constant (stack_pointer_rtx, size));
1374
1375           sp_plus_insns = get_insns ();
1376           end_sequence ();
1377
1378           /************ Use shortest method  ************/
1379           
1380           emit_insn (get_sequence_length (sp_plus_insns)
1381                      < get_sequence_length (fp_plus_insns)
1382                      ? sp_plus_insns
1383                      : fp_plus_insns);
1384         }
1385       else
1386         emit_insn (fp_plus_insns);
1387     } /* size != 0 */
1388           
1389   if (frame_pointer_needed
1390       && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1391     {
1392       /* Restore previous frame_pointer.  See expand_prologue for
1393          rationale for not using pophi.  */
1394               
1395       emit_pop_byte (REG_Y + 1);
1396       emit_pop_byte (REG_Y);
1397     }
1398
1399   /* Restore used registers.  */
1400   
1401   for (reg = 31; reg >= 0; --reg)
1402     if (TEST_HARD_REG_BIT (set, reg))
1403       emit_pop_byte (reg);
1404
1405   if (isr_p)
1406     {
1407       /* Restore RAMPZ using tmp reg as scratch.  */
1408       
1409       if (AVR_HAVE_RAMPZ 
1410           && TEST_HARD_REG_BIT (set, REG_Z)
1411           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1412         {
1413           emit_pop_byte (TMP_REGNO);
1414           emit_move_insn (rampz_rtx, tmp_reg_rtx);
1415         }
1416
1417       /* Restore SREG using tmp reg as scratch.  */
1418       
1419       emit_pop_byte (TMP_REGNO);
1420       emit_move_insn (gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg)), 
1421                       tmp_reg_rtx);
1422
1423       /* Restore tmp REG.  */
1424       emit_pop_byte (TMP_REGNO);
1425
1426       /* Restore zero REG.  */
1427       emit_pop_byte (ZERO_REGNO);
1428     }
1429
1430   if (!sibcall_p)
1431     emit_jump_insn (gen_return ());
1432 }
1433
1434 /* Output summary messages at beginning of function epilogue.  */
1435
1436 static void
1437 avr_asm_function_begin_epilogue (FILE *file)
1438 {
1439   fprintf (file, "/* epilogue start */\n");
1440 }
1441
1442
1443 /* Implement TARGET_CANNOT_MODITY_JUMPS_P */
1444
1445 static bool
1446 avr_cannot_modify_jumps_p (void)
1447 {
1448
1449   /* Naked Functions must not have any instructions after
1450      their epilogue, see PR42240 */
1451      
1452   if (reload_completed
1453       && cfun->machine
1454       && cfun->machine->is_naked)
1455     {
1456       return true;
1457     }
1458
1459   return false;
1460 }
1461
1462
1463 /* Helper function for `avr_legitimate_address_p'.  */
1464
1465 static inline bool
1466 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1467                        RTX_CODE outer_code, bool strict)
1468 {
1469   return (REG_P (reg)
1470           && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1471                                                  as, outer_code, UNKNOWN)
1472               || (!strict
1473                   && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1474 }
1475
1476
1477 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1478    machine for a memory operand of mode MODE.  */
1479
1480 static bool
1481 avr_legitimate_address_p (enum machine_mode mode, rtx x, bool strict)
1482 {
1483   bool ok = CONSTANT_ADDRESS_P (x);
1484   
1485   switch (GET_CODE (x))
1486     {
1487     case REG:
1488       ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1489                                   MEM, strict);
1490
1491       if (strict
1492           && DImode == mode
1493           && REG_X == REGNO (x))
1494         {
1495           ok = false;
1496         }
1497       break;
1498
1499     case POST_INC:
1500     case PRE_DEC:
1501       ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1502                                   GET_CODE (x), strict);
1503       break;
1504
1505     case PLUS:
1506       {
1507         rtx reg = XEXP (x, 0);
1508         rtx op1 = XEXP (x, 1);
1509         
1510         if (REG_P (reg)
1511             && CONST_INT_P (op1)
1512             && INTVAL (op1) >= 0)
1513           {
1514             bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1515
1516             if (fit)
1517               {
1518                 ok = (! strict
1519                       || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1520                                                 PLUS, strict));
1521           
1522                 if (reg == frame_pointer_rtx
1523                     || reg == arg_pointer_rtx)
1524                   {
1525                     ok = true;
1526                   }
1527               }
1528             else if (frame_pointer_needed
1529                      && reg == frame_pointer_rtx)
1530               {
1531                 ok = true;
1532               }
1533           }
1534       }
1535       break;
1536       
1537     default:
1538       break;
1539     }
1540   
1541   if (avr_log.legitimate_address_p)
1542     {
1543       avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1544                  "reload_completed=%d reload_in_progress=%d %s:",
1545                  ok, mode, strict, reload_completed, reload_in_progress,
1546                  reg_renumber ? "(reg_renumber)" : "");
1547       
1548       if (GET_CODE (x) == PLUS
1549           && REG_P (XEXP (x, 0))
1550           && CONST_INT_P (XEXP (x, 1))
1551           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1552           && reg_renumber)
1553         {
1554           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1555                      true_regnum (XEXP (x, 0)));
1556         }
1557       
1558       avr_edump ("\n%r\n", x);
1559     }
1560   
1561   return ok;
1562 }
1563
1564
1565 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1566    now only a helper for avr_addr_space_legitimize_address.  */
1567 /* Attempts to replace X with a valid
1568    memory address for an operand of mode MODE  */
1569
1570 static rtx
1571 avr_legitimize_address (rtx x, rtx oldx, enum machine_mode mode)
1572 {
1573   bool big_offset_p = false;
1574   
1575   x = oldx;
1576   
1577   if (GET_CODE (oldx) == PLUS
1578       && REG_P (XEXP (oldx, 0)))
1579     {
1580       if (REG_P (XEXP (oldx, 1)))
1581         x = force_reg (GET_MODE (oldx), oldx);
1582       else if (CONST_INT_P (XEXP (oldx, 1)))
1583         {
1584           int offs = INTVAL (XEXP (oldx, 1));
1585           if (frame_pointer_rtx != XEXP (oldx, 0)
1586               && offs > MAX_LD_OFFSET (mode))
1587             {
1588               big_offset_p = true;
1589               x = force_reg (GET_MODE (oldx), oldx);
1590             }
1591         }
1592     }
1593   
1594   if (avr_log.legitimize_address)
1595     {
1596       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1597
1598       if (x != oldx)
1599         avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1600     }
1601
1602   return x;
1603 }
1604
1605
1606 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
1607 /* This will allow register R26/27 to be used where it is no worse than normal
1608    base pointers R28/29 or R30/31.  For example, if base offset is greater
1609    than 63 bytes or for R++ or --R addressing.  */
1610
1611 rtx
1612 avr_legitimize_reload_address (rtx *px, enum machine_mode mode,
1613                                int opnum, int type, int addr_type,
1614                                int ind_levels ATTRIBUTE_UNUSED,
1615                                rtx (*mk_memloc)(rtx,int))
1616 {
1617   rtx x = *px;
1618   
1619   if (avr_log.legitimize_reload_address)
1620     avr_edump ("\n%?:%m %r\n", mode, x);
1621   
1622   if (1 && (GET_CODE (x) == POST_INC
1623             || GET_CODE (x) == PRE_DEC))
1624     {
1625       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1626                    POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1627                    opnum, RELOAD_OTHER);
1628       
1629       if (avr_log.legitimize_reload_address)
1630         avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1631                    POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1632       
1633       return x;
1634     }
1635   
1636   if (GET_CODE (x) == PLUS
1637       && REG_P (XEXP (x, 0))
1638       && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1639       && CONST_INT_P (XEXP (x, 1))
1640       && INTVAL (XEXP (x, 1)) >= 1)
1641     {
1642       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1643       
1644       if (fit)
1645         {
1646           if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1647             {
1648               int regno = REGNO (XEXP (x, 0));
1649               rtx mem = mk_memloc (x, regno);
1650               
1651               push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
1652                            POINTER_REGS, Pmode, VOIDmode, 0, 0,
1653                            1, addr_type);
1654               
1655               if (avr_log.legitimize_reload_address)
1656                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1657                            POINTER_REGS, XEXP (mem, 0), NULL_RTX);
1658               
1659               push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
1660                            BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1661                            opnum, type);
1662               
1663               if (avr_log.legitimize_reload_address)
1664                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
1665                            BASE_POINTER_REGS, mem, NULL_RTX);
1666               
1667               return x;
1668             }
1669         }
1670       else if (! (frame_pointer_needed
1671                   && XEXP (x, 0) == frame_pointer_rtx))
1672         {
1673           push_reload (x, NULL_RTX, px, NULL,
1674                        POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
1675                        opnum, type);
1676           
1677           if (avr_log.legitimize_reload_address)
1678             avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
1679                        POINTER_REGS, x, NULL_RTX);
1680           
1681           return x;
1682         }
1683     }
1684   
1685   return NULL_RTX;
1686 }
1687
1688
1689 /* Helper function to print assembler resp. track instruction
1690    sequence lengths.  Always return "".
1691    
1692    If PLEN == NULL:
1693        Output assembler code from template TPL with operands supplied
1694        by OPERANDS.  This is just forwarding to output_asm_insn.
1695    
1696    If PLEN != NULL:
1697        If N_WORDS >= 0  Add N_WORDS to *PLEN.
1698        If N_WORDS < 0   Set *PLEN to -N_WORDS.
1699        Don't output anything.
1700 */
1701
1702 static const char*
1703 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
1704 {
1705   if (NULL == plen)
1706     {
1707       output_asm_insn (tpl, operands);
1708     }
1709   else
1710     {
1711       if (n_words < 0)
1712         *plen = -n_words;
1713       else
1714         *plen += n_words;
1715     }
1716
1717   return "";
1718 }
1719
1720
1721 /* Return a pointer register name as a string.  */
1722
1723 static const char *
1724 ptrreg_to_str (int regno)
1725 {
1726   switch (regno)
1727     {
1728     case REG_X: return "X";
1729     case REG_Y: return "Y";
1730     case REG_Z: return "Z";
1731     default:
1732       output_operand_lossage ("address operand requires constraint for"
1733                               " X, Y, or Z register");
1734     }
1735   return NULL;
1736 }
1737
1738 /* Return the condition name as a string.
1739    Used in conditional jump constructing  */
1740
1741 static const char *
1742 cond_string (enum rtx_code code)
1743 {
1744   switch (code)
1745     {
1746     case NE:
1747       return "ne";
1748     case EQ:
1749       return "eq";
1750     case GE:
1751       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1752         return "pl";
1753       else
1754         return "ge";
1755     case LT:
1756       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
1757         return "mi";
1758       else
1759         return "lt";
1760     case GEU:
1761       return "sh";
1762     case LTU:
1763       return "lo";
1764     default:
1765       gcc_unreachable ();
1766     }
1767
1768   return "";
1769 }
1770
1771
1772 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'.  */
1773 /* Output ADDR to FILE as address.  */
1774
1775 static void
1776 avr_print_operand_address (FILE *file, rtx addr)
1777 {
1778   switch (GET_CODE (addr))
1779     {
1780     case REG:
1781       fprintf (file, ptrreg_to_str (REGNO (addr)));
1782       break;
1783
1784     case PRE_DEC:
1785       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1786       break;
1787
1788     case POST_INC:
1789       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
1790       break;
1791
1792     default:
1793       if (CONSTANT_ADDRESS_P (addr)
1794           && text_segment_operand (addr, VOIDmode))
1795         {
1796           rtx x = addr;
1797           if (GET_CODE (x) == CONST)
1798             x = XEXP (x, 0);
1799           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
1800             {
1801               /* Assembler gs() will implant word address. Make offset 
1802                  a byte offset inside gs() for assembler. This is 
1803                  needed because the more logical (constant+gs(sym)) is not 
1804                  accepted by gas. For 128K and lower devices this is ok.
1805                  For large devices it will create a Trampoline to offset
1806                  from symbol which may not be what the user really wanted.  */
1807               fprintf (file, "gs(");
1808               output_addr_const (file, XEXP (x,0));
1809               fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
1810                        2 * INTVAL (XEXP (x, 1)));
1811               if (AVR_3_BYTE_PC)
1812                 if (warning (0, "pointer offset from symbol maybe incorrect"))
1813                   {
1814                     output_addr_const (stderr, addr);
1815                     fprintf(stderr,"\n");
1816                   }
1817             }
1818           else
1819             {
1820               fprintf (file, "gs(");
1821               output_addr_const (file, addr);
1822               fprintf (file, ")");
1823             }
1824         }
1825       else
1826         output_addr_const (file, addr);
1827     }
1828 }
1829
1830
1831 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'.  */
1832
1833 static bool
1834 avr_print_operand_punct_valid_p (unsigned char code)
1835 {
1836   return code == '~' || code == '!';
1837 }
1838
1839
1840 /* Implement `TARGET_PRINT_OPERAND'.  */
1841 /* Output X as assembler operand to file FILE.
1842    For a description of supported %-codes, see top of avr.md.  */
1843
1844 static void
1845 avr_print_operand (FILE *file, rtx x, int code)
1846 {
1847   int abcd = 0;
1848
1849   if (code >= 'A' && code <= 'D')
1850     abcd = code - 'A';
1851
1852   if (code == '~')
1853     {
1854       if (!AVR_HAVE_JMP_CALL)
1855         fputc ('r', file);
1856     }
1857   else if (code == '!')
1858     {
1859       if (AVR_HAVE_EIJMP_EICALL)
1860         fputc ('e', file);
1861     }
1862   else if (code == 't'
1863            || code == 'T')
1864     {
1865       static int t_regno = -1;
1866       static int t_nbits = -1;
1867
1868       if (REG_P (x) && t_regno < 0 && code == 'T')
1869         {
1870           t_regno = REGNO (x);
1871           t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
1872         }
1873       else if (CONST_INT_P (x) && t_regno >= 0
1874                && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
1875         {
1876           int bpos = INTVAL (x);
1877
1878           fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
1879           if (code == 'T')
1880             fprintf (file, ",%d", bpos % 8);
1881
1882           t_regno = -1;
1883         }
1884       else
1885         fatal_insn ("operands to %T/%t must be reg + const_int:", x);
1886     }
1887   else if (REG_P (x))
1888     {
1889       if (x == zero_reg_rtx)
1890         fprintf (file, "__zero_reg__");
1891       else
1892         fprintf (file, reg_names[true_regnum (x) + abcd]);
1893     }
1894   else if (CONST_INT_P (x))
1895     {
1896       HOST_WIDE_INT ival = INTVAL (x);
1897         
1898       if ('i' != code)
1899         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
1900       else if (low_io_address_operand (x, VOIDmode)
1901                || high_io_address_operand (x, VOIDmode))
1902         {
1903           if (ival == avr_addr.rampz)       fprintf (file, "__RAMPZ__");
1904           else if (ival == avr_addr.sreg)   fprintf (file, "__SREG__");
1905           else if (ival == avr_addr.sp_l)   fprintf (file, "__SP_L__");
1906           else if (ival == avr_addr.sp_h)   fprintf (file, "__SP_H__");
1907           else
1908             {
1909               fprintf (file, HOST_WIDE_INT_PRINT_HEX,
1910                        ival - avr_current_arch->sfr_offset);
1911             }
1912         }
1913       else
1914         fatal_insn ("bad address, not an I/O address:", x);
1915     }
1916   else if (MEM_P (x))
1917     {
1918       rtx addr = XEXP (x, 0);
1919       
1920       if (code == 'm')
1921         {
1922           if (!CONSTANT_P (addr))
1923             fatal_insn ("bad address, not a constant:", addr);
1924           /* Assembler template with m-code is data - not progmem section */
1925           if (text_segment_operand (addr, VOIDmode))
1926             if (warning (0, "accessing data memory with"
1927                          " program memory address"))
1928               {
1929                 output_addr_const (stderr, addr);
1930                 fprintf(stderr,"\n");
1931               }
1932           output_addr_const (file, addr);
1933         }
1934       else if (code == 'i')
1935         {
1936           avr_print_operand (file, addr, 'i');
1937         }
1938       else if (code == 'o')
1939         {
1940           if (GET_CODE (addr) != PLUS)
1941             fatal_insn ("bad address, not (reg+disp):", addr);
1942
1943           avr_print_operand (file, XEXP (addr, 1), 0);
1944         }
1945       else if (code == 'p' || code == 'r')
1946         {
1947           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
1948             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
1949           
1950           if (code == 'p')
1951             avr_print_operand_address (file, XEXP (addr, 0));  /* X, Y, Z */
1952           else
1953             avr_print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
1954         }
1955       else if (GET_CODE (addr) == PLUS)
1956         {
1957           avr_print_operand_address (file, XEXP (addr,0));
1958           if (REGNO (XEXP (addr, 0)) == REG_X)
1959             fatal_insn ("internal compiler error.  Bad address:"
1960                         ,addr);
1961           fputc ('+', file);
1962           avr_print_operand (file, XEXP (addr,1), code);
1963         }
1964       else
1965         avr_print_operand_address (file, addr);
1966     }
1967   else if (code == 'i')
1968     {
1969       fatal_insn ("bad address, not an I/O address:", x);
1970     }
1971   else if (code == 'x')
1972     {
1973       /* Constant progmem address - like used in jmp or call */
1974       if (0 == text_segment_operand (x, VOIDmode))
1975         if (warning (0, "accessing program memory"
1976                      " with data memory address"))
1977           {
1978             output_addr_const (stderr, x);
1979             fprintf(stderr,"\n");
1980           }
1981       /* Use normal symbol for direct address no linker trampoline needed */
1982       output_addr_const (file, x);
1983     }
1984   else if (GET_CODE (x) == CONST_DOUBLE)
1985     {
1986       long val;
1987       REAL_VALUE_TYPE rv;
1988       if (GET_MODE (x) != SFmode)
1989         fatal_insn ("internal compiler error.  Unknown mode:", x);
1990       REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
1991       REAL_VALUE_TO_TARGET_SINGLE (rv, val);
1992       fprintf (file, "0x%lx", val);
1993     }
1994   else if (GET_CODE (x) == CONST_STRING)
1995     fputs (XSTR (x, 0), file);
1996   else if (code == 'j')
1997     fputs (cond_string (GET_CODE (x)), file);
1998   else if (code == 'k')
1999     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2000   else
2001     avr_print_operand_address (file, x);
2002 }
2003
2004 /* Update the condition code in the INSN.  */
2005
2006 void
2007 notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn)
2008 {
2009   rtx set;
2010   enum attr_cc cc = get_attr_cc (insn);
2011   
2012   switch (cc)
2013     {
2014     default:
2015       break;
2016
2017     case CC_OUT_PLUS:
2018     case CC_OUT_PLUS_NOCLOBBER:
2019     case CC_LDI:
2020       {
2021         rtx *op = recog_data.operand;
2022         int len_dummy, icc;
2023         
2024         /* Extract insn's operands.  */
2025         extract_constrain_insn_cached (insn);
2026
2027         switch (cc)
2028           {
2029           default:
2030             gcc_unreachable();
2031             
2032           case CC_OUT_PLUS:
2033             avr_out_plus (op, &len_dummy, &icc);
2034             cc = (enum attr_cc) icc;
2035             break;
2036             
2037           case CC_OUT_PLUS_NOCLOBBER:
2038             avr_out_plus_noclobber (op, &len_dummy, &icc);
2039             cc = (enum attr_cc) icc;
2040             break;
2041
2042           case CC_LDI:
2043
2044             cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2045                   && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2046               /* Loading zero-reg with 0 uses CLI and thus clobbers cc0.  */
2047               ? CC_CLOBBER
2048               /* Any other "r,rL" combination does not alter cc0.  */
2049               : CC_NONE;
2050             
2051             break;
2052           } /* inner switch */
2053
2054         break;
2055       }
2056     } /* outer swicth */
2057
2058   switch (cc)
2059     {
2060     default:
2061       /* Special values like CC_OUT_PLUS from above have been
2062          mapped to "standard" CC_* values so we never come here.  */
2063       
2064       gcc_unreachable();
2065       break;
2066       
2067     case CC_NONE:
2068       /* Insn does not affect CC at all.  */
2069       break;
2070
2071     case CC_SET_N:
2072       CC_STATUS_INIT;
2073       break;
2074
2075     case CC_SET_ZN:
2076       set = single_set (insn);
2077       CC_STATUS_INIT;
2078       if (set)
2079         {
2080           cc_status.flags |= CC_NO_OVERFLOW;
2081           cc_status.value1 = SET_DEST (set);
2082         }
2083       break;
2084
2085     case CC_SET_CZN:
2086       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2087          The V flag may or may not be known but that's ok because
2088          alter_cond will change tests to use EQ/NE.  */
2089       set = single_set (insn);
2090       CC_STATUS_INIT;
2091       if (set)
2092         {
2093           cc_status.value1 = SET_DEST (set);
2094           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2095         }
2096       break;
2097
2098     case CC_COMPARE:
2099       set = single_set (insn);
2100       CC_STATUS_INIT;
2101       if (set)
2102         cc_status.value1 = SET_SRC (set);
2103       break;
2104       
2105     case CC_CLOBBER:
2106       /* Insn doesn't leave CC in a usable state.  */
2107       CC_STATUS_INIT;
2108       break;
2109     }
2110 }
2111
2112 /* Choose mode for jump insn:
2113    1 - relative jump in range -63 <= x <= 62 ;
2114    2 - relative jump in range -2046 <= x <= 2045 ;
2115    3 - absolute jump (only for ATmega[16]03).  */
2116
2117 int
2118 avr_jump_mode (rtx x, rtx insn)
2119 {
2120   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2121                                             ? XEXP (x, 0) : x));
2122   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2123   int jump_distance = cur_addr - dest_addr;
2124   
2125   if (-63 <= jump_distance && jump_distance <= 62)
2126     return 1;
2127   else if (-2046 <= jump_distance && jump_distance <= 2045)
2128     return 2;
2129   else if (AVR_HAVE_JMP_CALL)
2130     return 3;
2131   
2132   return 2;
2133 }
2134
2135 /* return an AVR condition jump commands.
2136    X is a comparison RTX.
2137    LEN is a number returned by avr_jump_mode function.
2138    if REVERSE nonzero then condition code in X must be reversed.  */
2139
2140 const char *
2141 ret_cond_branch (rtx x, int len, int reverse)
2142 {
2143   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2144   
2145   switch (cond)
2146     {
2147     case GT:
2148       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2149         return (len == 1 ? ("breq .+2" CR_TAB
2150                             "brpl %0") :
2151                 len == 2 ? ("breq .+4" CR_TAB
2152                             "brmi .+2" CR_TAB
2153                             "rjmp %0") :
2154                 ("breq .+6" CR_TAB
2155                  "brmi .+4" CR_TAB
2156                  "jmp %0"));
2157           
2158       else
2159         return (len == 1 ? ("breq .+2" CR_TAB
2160                             "brge %0") :
2161                 len == 2 ? ("breq .+4" CR_TAB
2162                             "brlt .+2" CR_TAB
2163                             "rjmp %0") :
2164                 ("breq .+6" CR_TAB
2165                  "brlt .+4" CR_TAB
2166                  "jmp %0"));
2167     case GTU:
2168       return (len == 1 ? ("breq .+2" CR_TAB
2169                           "brsh %0") :
2170               len == 2 ? ("breq .+4" CR_TAB
2171                           "brlo .+2" CR_TAB
2172                           "rjmp %0") :
2173               ("breq .+6" CR_TAB
2174                "brlo .+4" CR_TAB
2175                "jmp %0"));
2176     case LE:
2177       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2178         return (len == 1 ? ("breq %0" CR_TAB
2179                             "brmi %0") :
2180                 len == 2 ? ("breq .+2" CR_TAB
2181                             "brpl .+2" CR_TAB
2182                             "rjmp %0") :
2183                 ("breq .+2" CR_TAB
2184                  "brpl .+4" CR_TAB
2185                  "jmp %0"));
2186       else
2187         return (len == 1 ? ("breq %0" CR_TAB
2188                             "brlt %0") :
2189                 len == 2 ? ("breq .+2" CR_TAB
2190                             "brge .+2" CR_TAB
2191                             "rjmp %0") :
2192                 ("breq .+2" CR_TAB
2193                  "brge .+4" CR_TAB
2194                  "jmp %0"));
2195     case LEU:
2196       return (len == 1 ? ("breq %0" CR_TAB
2197                           "brlo %0") :
2198               len == 2 ? ("breq .+2" CR_TAB
2199                           "brsh .+2" CR_TAB
2200                           "rjmp %0") :
2201               ("breq .+2" CR_TAB
2202                "brsh .+4" CR_TAB
2203                "jmp %0"));
2204     default:
2205       if (reverse)
2206         {
2207           switch (len)
2208             {
2209             case 1:
2210               return "br%k1 %0";
2211             case 2:
2212               return ("br%j1 .+2" CR_TAB
2213                       "rjmp %0");
2214             default:
2215               return ("br%j1 .+4" CR_TAB
2216                       "jmp %0");
2217             }
2218         }
2219       else
2220         {
2221           switch (len)
2222             {
2223             case 1:
2224               return "br%j1 %0";
2225             case 2:
2226               return ("br%k1 .+2" CR_TAB
2227                       "rjmp %0");
2228             default:
2229               return ("br%k1 .+4" CR_TAB
2230                       "jmp %0");
2231             }
2232         }
2233     }
2234   return "";
2235 }
2236
2237 /* Output insn cost for next insn.  */
2238
2239 void
2240 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
2241                     int num_operands ATTRIBUTE_UNUSED)
2242 {
2243   if (avr_log.rtx_costs)
2244     {
2245       rtx set = single_set (insn);
2246
2247       if (set)
2248         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
2249                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2250       else
2251         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
2252                  rtx_cost (PATTERN (insn), INSN, 0,
2253                            optimize_insn_for_speed_p()));
2254     }
2255 }
2256
2257 /* Return 0 if undefined, 1 if always true or always false.  */
2258
2259 int
2260 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
2261 {
2262   unsigned int max = (mode == QImode ? 0xff :
2263                       mode == HImode ? 0xffff :
2264                       mode == PSImode ? 0xffffff :
2265                       mode == SImode ? 0xffffffff : 0);
2266   if (max && op && GET_CODE (x) == CONST_INT)
2267     {
2268       if (unsigned_condition (op) != op)
2269         max >>= 1;
2270
2271       if (max != (INTVAL (x) & max)
2272           && INTVAL (x) != 0xff)
2273         return 1;
2274     }
2275   return 0;
2276 }
2277
2278
2279 /* Returns nonzero if REGNO is the number of a hard
2280    register in which function arguments are sometimes passed.  */
2281
2282 int
2283 function_arg_regno_p(int r)
2284 {
2285   return (r >= 8 && r <= 25);
2286 }
2287
2288 /* Initializing the variable cum for the state at the beginning
2289    of the argument list.  */
2290
2291 void
2292 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2293                       tree fndecl ATTRIBUTE_UNUSED)
2294 {
2295   cum->nregs = 18;
2296   cum->regno = FIRST_CUM_REG;
2297   if (!libname && stdarg_p (fntype))
2298     cum->nregs = 0;
2299
2300   /* Assume the calle may be tail called */
2301   
2302   cfun->machine->sibcall_fails = 0;
2303 }
2304
2305 /* Returns the number of registers to allocate for a function argument.  */
2306
2307 static int
2308 avr_num_arg_regs (enum machine_mode mode, const_tree type)
2309 {
2310   int size;
2311
2312   if (mode == BLKmode)
2313     size = int_size_in_bytes (type);
2314   else
2315     size = GET_MODE_SIZE (mode);
2316
2317   /* Align all function arguments to start in even-numbered registers.
2318      Odd-sized arguments leave holes above them.  */
2319
2320   return (size + 1) & ~1;
2321 }
2322
2323 /* Controls whether a function argument is passed
2324    in a register, and which register.  */
2325
2326 static rtx
2327 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2328                   const_tree type, bool named ATTRIBUTE_UNUSED)
2329 {
2330   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2331   int bytes = avr_num_arg_regs (mode, type);
2332
2333   if (cum->nregs && bytes <= cum->nregs)
2334     return gen_rtx_REG (mode, cum->regno - bytes);
2335
2336   return NULL_RTX;
2337 }
2338
2339 /* Update the summarizer variable CUM to advance past an argument
2340    in the argument list.  */
2341    
2342 static void
2343 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2344                           const_tree type, bool named ATTRIBUTE_UNUSED)
2345 {
2346   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2347   int bytes = avr_num_arg_regs (mode, type);
2348
2349   cum->nregs -= bytes;
2350   cum->regno -= bytes;
2351
2352   /* A parameter is being passed in a call-saved register. As the original
2353      contents of these regs has to be restored before leaving the function,
2354      a function must not pass arguments in call-saved regs in order to get
2355      tail-called. */
2356   
2357   if (cum->regno >= 8
2358       && cum->nregs >= 0
2359       && !call_used_regs[cum->regno])
2360     {
2361       /* FIXME: We ship info on failing tail-call in struct machine_function.
2362          This uses internals of calls.c:expand_call() and the way args_so_far
2363          is used. targetm.function_ok_for_sibcall() needs to be extended to
2364          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2365          dependent so that such an extension is not wanted. */
2366       
2367       cfun->machine->sibcall_fails = 1;
2368     }
2369
2370   /* Test if all registers needed by the ABI are actually available.  If the
2371      user has fixed a GPR needed to pass an argument, an (implicit) function
2372      call will clobber that fixed register.  See PR45099 for an example.  */
2373   
2374   if (cum->regno >= 8
2375       && cum->nregs >= 0)
2376     {
2377       int regno;
2378
2379       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2380         if (fixed_regs[regno])
2381           warning (0, "fixed register %s used to pass parameter to function",
2382                    reg_names[regno]);
2383     }
2384       
2385   if (cum->nregs <= 0)
2386     {
2387       cum->nregs = 0;
2388       cum->regno = FIRST_CUM_REG;
2389     }
2390 }
2391
2392 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2393 /* Decide whether we can make a sibling call to a function.  DECL is the
2394    declaration of the function being targeted by the call and EXP is the
2395    CALL_EXPR representing the call. */
2396
2397 static bool
2398 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2399 {
2400   tree fntype_callee;
2401
2402   /* Tail-calling must fail if callee-saved regs are used to pass
2403      function args.  We must not tail-call when `epilogue_restores'
2404      is used.  Unfortunately, we cannot tell at this point if that
2405      actually will happen or not, and we cannot step back from
2406      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2407   
2408   if (cfun->machine->sibcall_fails
2409       || TARGET_CALL_PROLOGUES)
2410     {
2411       return false;
2412     }
2413   
2414   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2415
2416   if (decl_callee)
2417     {
2418       decl_callee = TREE_TYPE (decl_callee);
2419     }
2420   else
2421     {
2422       decl_callee = fntype_callee;
2423       
2424       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2425              && METHOD_TYPE != TREE_CODE (decl_callee))
2426         {
2427           decl_callee = TREE_TYPE (decl_callee);
2428         }
2429     }
2430
2431   /* Ensure that caller and callee have compatible epilogues */
2432   
2433   if (interrupt_function_p (current_function_decl)
2434       || signal_function_p (current_function_decl)
2435       || avr_naked_function_p (decl_callee)
2436       || avr_naked_function_p (current_function_decl)
2437       /* FIXME: For OS_task and OS_main, we are over-conservative.
2438          This is due to missing documentation of these attributes
2439          and what they actually should do and should not do. */
2440       || (avr_OS_task_function_p (decl_callee)
2441           != avr_OS_task_function_p (current_function_decl))
2442       || (avr_OS_main_function_p (decl_callee)
2443           != avr_OS_main_function_p (current_function_decl)))
2444     {
2445       return false;
2446     }
2447  
2448   return true;
2449 }
2450
2451 /***********************************************************************
2452   Functions for outputting various mov's for a various modes
2453 ************************************************************************/
2454
2455 /* Return true if a value of mode MODE is read from flash by
2456    __load_* function from libgcc.  */
2457
2458 bool
2459 avr_load_libgcc_p (rtx op)
2460 {
2461   enum machine_mode mode = GET_MODE (op);
2462   int n_bytes = GET_MODE_SIZE (mode);
2463         
2464   return (n_bytes > 2
2465           && !AVR_HAVE_LPMX
2466           && avr_mem_flash_p (op));
2467 }
2468
2469 /* Return true if a value of mode MODE is read by __xload_* function.  */
2470
2471 bool
2472 avr_xload_libgcc_p (enum machine_mode mode)
2473 {
2474   int n_bytes = GET_MODE_SIZE (mode);
2475   
2476   return (n_bytes > 1
2477           || avr_current_arch->n_segments > 1);
2478 }
2479
2480
2481 /* Find an unused d-register to be used as scratch in INSN.
2482    EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2483    is a register, skip all possible return values that overlap EXCLUDE.
2484    The policy for the returned register is similar to that of
2485    `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2486    of INSN.
2487
2488    Return a QImode d-register or NULL_RTX if nothing found.  */
2489
2490 static rtx
2491 avr_find_unused_d_reg (rtx insn, rtx exclude)
2492 {
2493   int regno;
2494   bool isr_p = (interrupt_function_p (current_function_decl)
2495                 || signal_function_p (current_function_decl));
2496
2497   for (regno = 16; regno < 32; regno++)
2498     {
2499       rtx reg = all_regs_rtx[regno];
2500       
2501       if ((exclude
2502            && reg_overlap_mentioned_p (exclude, reg))
2503           || fixed_regs[regno])
2504         {
2505           continue;
2506         }
2507
2508       /* Try non-live register */
2509
2510       if (!df_regs_ever_live_p (regno)
2511           && (TREE_THIS_VOLATILE (current_function_decl)
2512               || cfun->machine->is_OS_task
2513               || cfun->machine->is_OS_main
2514               || (!isr_p && call_used_regs[regno])))
2515         {
2516           return reg;
2517         }
2518
2519       /* Any live register can be used if it is unused after.
2520          Prologue/epilogue will care for it as needed.  */
2521       
2522       if (df_regs_ever_live_p (regno)
2523           && reg_unused_after (insn, reg))
2524         {
2525           return reg;
2526         }
2527     }
2528
2529   return NULL_RTX;
2530 }
2531
2532
2533 /* Helper function for the next function in the case where only restricted
2534    version of LPM instruction is available.  */
2535
2536 static const char*
2537 avr_out_lpm_no_lpmx (rtx insn, rtx *xop, int *plen)
2538 {
2539   rtx dest = xop[0];
2540   rtx addr = xop[1];
2541   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2542   int regno_dest;
2543
2544   regno_dest = REGNO (dest);
2545
2546   /* The implicit target register of LPM.  */
2547   xop[3] = lpm_reg_rtx;
2548
2549   switch (GET_CODE (addr))
2550     {
2551     default:
2552       gcc_unreachable();
2553
2554     case REG:
2555
2556       gcc_assert (REG_Z == REGNO (addr));
2557
2558       switch (n_bytes)
2559         {
2560         default:
2561           gcc_unreachable();
2562
2563         case 1:
2564           avr_asm_len ("%4lpm", xop, plen, 1);
2565
2566           if (regno_dest != LPM_REGNO)
2567             avr_asm_len ("mov %0,%3", xop, plen, 1);
2568
2569           return "";
2570
2571         case 2:
2572           if (REGNO (dest) == REG_Z)
2573             return avr_asm_len ("%4lpm"      CR_TAB
2574                                 "push %3"    CR_TAB
2575                                 "adiw %2,1"  CR_TAB
2576                                 "%4lpm"      CR_TAB
2577                                 "mov %B0,%3" CR_TAB
2578                                 "pop %A0", xop, plen, 6);
2579           
2580           avr_asm_len ("%4lpm"      CR_TAB
2581                        "mov %A0,%3" CR_TAB
2582                        "adiw %2,1"  CR_TAB
2583                        "%4lpm"      CR_TAB
2584                        "mov %B0,%3", xop, plen, 5);
2585                 
2586           if (!reg_unused_after (insn, addr))
2587             avr_asm_len ("sbiw %2,1", xop, plen, 1);
2588           
2589           break; /* 2 */
2590         }
2591       
2592       break; /* REG */
2593
2594     case POST_INC:
2595
2596       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2597                   && n_bytes <= 4);
2598
2599       if (regno_dest == LPM_REGNO)
2600         avr_asm_len ("%4lpm"      CR_TAB
2601                      "adiw %2,1", xop, plen, 2);
2602       else
2603         avr_asm_len ("%4lpm"      CR_TAB
2604                      "mov %A0,%3" CR_TAB
2605                      "adiw %2,1", xop, plen, 3);
2606
2607       if (n_bytes >= 2)
2608         avr_asm_len ("%4lpm"      CR_TAB
2609                      "mov %B0,%3" CR_TAB
2610                      "adiw %2,1", xop, plen, 3);
2611
2612       if (n_bytes >= 3)
2613         avr_asm_len ("%4lpm"      CR_TAB
2614                      "mov %C0,%3" CR_TAB
2615                      "adiw %2,1", xop, plen, 3);
2616
2617       if (n_bytes >= 4)
2618         avr_asm_len ("%4lpm"      CR_TAB
2619                      "mov %D0,%3" CR_TAB
2620                      "adiw %2,1", xop, plen, 3);
2621
2622       break; /* POST_INC */
2623       
2624     } /* switch CODE (addr) */
2625       
2626   return "";
2627 }
2628
2629
2630 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
2631    OP[1] in AS1 to register OP[0].
2632    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2633    Return "".  */
2634
2635 static const char*
2636 avr_out_lpm (rtx insn, rtx *op, int *plen)
2637 {
2638   rtx xop[6];
2639   rtx dest = op[0];
2640   rtx src = SET_SRC (single_set (insn));
2641   rtx addr;
2642   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2643   int regno_dest;
2644   int segment;
2645   RTX_CODE code;
2646   addr_space_t as = MEM_ADDR_SPACE (src);
2647
2648   if (plen)
2649     *plen = 0;
2650   
2651   if (MEM_P (dest))
2652     {
2653       warning (0, "writing to address space %qs not supported",
2654                avr_addrspace[MEM_ADDR_SPACE (dest)].name);
2655       
2656       return "";
2657     }
2658
2659   addr = XEXP (src, 0);
2660   code = GET_CODE (addr);
2661
2662   gcc_assert (REG_P (dest));
2663   gcc_assert (REG == code || POST_INC == code);
2664
2665   xop[0] = dest;
2666   xop[1] = addr;
2667   xop[2] = lpm_addr_reg_rtx;
2668   xop[4] = xstring_empty;
2669   xop[5] = tmp_reg_rtx;
2670
2671   regno_dest = REGNO (dest);
2672
2673   /* Cut down segment number to a number the device actually supports.
2674      We do this late to preserve the address space's name for diagnostics.  */
2675
2676   segment = avr_addrspace[as].segment % avr_current_arch->n_segments;
2677
2678   /* Set RAMPZ as needed.  */
2679
2680   if (segment)
2681     {
2682       xop[4] = GEN_INT (segment);
2683       
2684       if (xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx),
2685           xop[3])
2686         {
2687           avr_asm_len ("ldi %3,%4" CR_TAB
2688                        "out __RAMPZ__,%3", xop, plen, 2);
2689         }
2690       else if (segment == 1)
2691         {
2692           avr_asm_len ("clr %5" CR_TAB
2693                        "inc %5" CR_TAB
2694                        "out __RAMPZ__,%5", xop, plen, 3);
2695         }
2696       else
2697         {
2698           avr_asm_len ("mov %5,%2"         CR_TAB
2699                        "ldi %2,%4"         CR_TAB
2700                        "out __RAMPZ__,%2"  CR_TAB
2701                        "mov %2,%5", xop, plen, 4);
2702         }
2703       
2704       xop[4] = xstring_e;
2705
2706       if (!AVR_HAVE_ELPMX)
2707         return avr_out_lpm_no_lpmx (insn, xop, plen);
2708     }
2709   else if (!AVR_HAVE_LPMX)
2710     {
2711       return avr_out_lpm_no_lpmx (insn, xop, plen);
2712     }
2713
2714   /* We have [E]LPMX: Output reading from Flash the comfortable way.  */
2715
2716   switch (GET_CODE (addr))
2717     {
2718     default:
2719       gcc_unreachable();
2720
2721     case REG:
2722
2723       gcc_assert (REG_Z == REGNO (addr));
2724
2725       switch (n_bytes)
2726         {
2727         default:
2728           gcc_unreachable();
2729
2730         case 1:
2731           return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
2732
2733         case 2:
2734           if (REGNO (dest) == REG_Z)
2735             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
2736                                 "%4lpm %B0,%a2" CR_TAB
2737                                 "mov %A0,%5", xop, plen, 3);
2738           else
2739             {
2740               avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2741                            "%4lpm %B0,%a2", xop, plen, 2);
2742                 
2743               if (!reg_unused_after (insn, addr))
2744                 avr_asm_len ("sbiw %2,1", xop, plen, 1);
2745             }
2746           
2747           break; /* 2 */
2748
2749         case 3:
2750
2751           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2752                        "%4lpm %B0,%a2+" CR_TAB
2753                        "%4lpm %C0,%a2", xop, plen, 3);
2754                 
2755           if (!reg_unused_after (insn, addr))
2756             avr_asm_len ("sbiw %2,2", xop, plen, 1);
2757
2758           break; /* 3 */
2759       
2760         case 4:
2761
2762           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
2763                        "%4lpm %B0,%a2+", xop, plen, 2);
2764           
2765           if (REGNO (dest) == REG_Z - 2)
2766             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
2767                                 "%4lpm %C0,%a2"          CR_TAB
2768                                 "mov %D0,%5", xop, plen, 3);
2769           else
2770             {
2771               avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
2772                            "%4lpm %D0,%a2", xop, plen, 2);
2773                 
2774               if (!reg_unused_after (insn, addr))
2775                 avr_asm_len ("sbiw %2,3", xop, plen, 1);
2776             }
2777
2778           break; /* 4 */
2779         } /* n_bytes */
2780       
2781       break; /* REG */
2782
2783     case POST_INC:
2784
2785       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
2786                   && n_bytes <= 4);
2787
2788       avr_asm_len                    ("%4lpm %A0,%a2+", xop, plen, 1);
2789       if (n_bytes >= 2)  avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
2790       if (n_bytes >= 3)  avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
2791       if (n_bytes >= 4)  avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
2792
2793       break; /* POST_INC */
2794
2795     } /* switch CODE (addr) */
2796       
2797   return "";
2798 }
2799
2800
2801 /* Worker function for xload_8 insn.  */
2802
2803 const char*
2804 avr_out_xload (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
2805 {
2806   rtx xop[4];
2807
2808   xop[0] = op[0];
2809   xop[1] = op[1];
2810   xop[2] = lpm_addr_reg_rtx;
2811   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
2812
2813   if (plen)
2814     *plen = 0;
2815
2816   avr_asm_len ("ld %3,%a2" CR_TAB
2817                "sbrs %1,7", xop, plen, 2);
2818
2819   avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1);
2820
2821   if (REGNO (xop[0]) != REGNO (xop[3]))
2822     avr_asm_len ("mov %0,%3", xop, plen, 1);
2823   
2824   return "";
2825 }
2826
2827
2828 const char *
2829 output_movqi (rtx insn, rtx operands[], int *l)
2830 {
2831   int dummy;
2832   rtx dest = operands[0];
2833   rtx src = operands[1];
2834   int *real_l = l;
2835   
2836   if (avr_mem_flash_p (src)
2837       || avr_mem_flash_p (dest))
2838     {
2839       return avr_out_lpm (insn, operands, real_l);
2840     }
2841
2842   if (!l)
2843     l = &dummy;
2844
2845   *l = 1;
2846   
2847   if (register_operand (dest, QImode))
2848     {
2849       if (register_operand (src, QImode)) /* mov r,r */
2850         {
2851           if (test_hard_reg_class (STACK_REG, dest))
2852             return "out %0,%1";
2853           else if (test_hard_reg_class (STACK_REG, src))
2854             return "in %0,%1";
2855           
2856           return "mov %0,%1";
2857         }
2858       else if (CONSTANT_P (src))
2859         {
2860           output_reload_in_const (operands, NULL_RTX, real_l, false);
2861           return "";
2862         }
2863       else if (GET_CODE (src) == MEM)
2864         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
2865     }
2866   else if (GET_CODE (dest) == MEM)
2867     {
2868       rtx xop[2];
2869
2870       xop[0] = dest;
2871       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2872
2873       return out_movqi_mr_r (insn, xop, real_l);
2874     }
2875   return "";
2876 }
2877
2878
2879 const char *
2880 output_movhi (rtx insn, rtx xop[], int *plen)
2881 {
2882   rtx dest = xop[0];
2883   rtx src = xop[1];
2884
2885   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
2886   
2887   if (avr_mem_flash_p (src)
2888       || avr_mem_flash_p (dest))
2889     {
2890       return avr_out_lpm (insn, xop, plen);
2891     }
2892
2893   if (REG_P (dest))
2894     {
2895       if (REG_P (src)) /* mov r,r */
2896         {
2897           if (test_hard_reg_class (STACK_REG, dest))
2898             {
2899               if (AVR_HAVE_8BIT_SP)
2900                 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
2901               
2902               /* Use simple load of SP if no interrupts are  used.  */
2903               
2904               return TARGET_NO_INTERRUPTS
2905                 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
2906                                "out __SP_L__,%A1", xop, plen, -2)
2907
2908                 : avr_asm_len ("in __tmp_reg__,__SREG__"  CR_TAB
2909                                "cli"                      CR_TAB
2910                                "out __SP_H__,%B1"         CR_TAB
2911                                "out __SREG__,__tmp_reg__" CR_TAB
2912                                "out __SP_L__,%A1", xop, plen, -5);
2913             }
2914           else if (test_hard_reg_class (STACK_REG, src))
2915             {
2916               return AVR_HAVE_8BIT_SP
2917                 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
2918                                "clr %B0", xop, plen, -2)
2919                 
2920                 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
2921                                "in %B0,__SP_H__", xop, plen, -2);
2922             }
2923
2924           return AVR_HAVE_MOVW
2925             ? avr_asm_len ("movw %0,%1", xop, plen, -1)
2926
2927             : avr_asm_len ("mov %A0,%A1" CR_TAB
2928                            "mov %B0,%B1", xop, plen, -2);
2929         } /* REG_P (src) */
2930       else if (CONSTANT_P (src))
2931         {
2932           return output_reload_inhi (xop, NULL, plen);
2933         }
2934       else if (MEM_P (src))
2935         {
2936           return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
2937         }
2938     }
2939   else if (MEM_P (dest))
2940     {
2941       rtx xop[2];
2942
2943       xop[0] = dest;
2944       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2945
2946       return out_movhi_mr_r (insn, xop, plen);
2947     }
2948   
2949   fatal_insn ("invalid insn:", insn);
2950   
2951   return "";
2952 }
2953
2954 static const char*
2955 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
2956 {
2957   rtx dest = op[0];
2958   rtx src = op[1];
2959   rtx x = XEXP (src, 0);
2960   
2961   if (CONSTANT_ADDRESS_P (x))
2962     {
2963       return optimize > 0 && io_address_operand (x, QImode)
2964         ? avr_asm_len ("in %0,%i1", op, plen, -1)
2965         : avr_asm_len ("lds %0,%m1", op, plen, -2);
2966     }
2967   else if (GET_CODE (x) == PLUS
2968            && REG_P (XEXP (x, 0))
2969            && CONST_INT_P (XEXP (x, 1)))
2970     {
2971       /* memory access by reg+disp */
2972
2973       int disp = INTVAL (XEXP (x, 1));
2974       
2975       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
2976         {
2977           if (REGNO (XEXP (x, 0)) != REG_Y)
2978             fatal_insn ("incorrect insn:",insn);
2979
2980           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2981             return avr_asm_len ("adiw r28,%o1-63" CR_TAB
2982                                 "ldd %0,Y+63"     CR_TAB
2983                                 "sbiw r28,%o1-63", op, plen, -3);
2984
2985           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
2986                               "sbci r29,hi8(-%o1)" CR_TAB
2987                               "ld %0,Y"            CR_TAB
2988                               "subi r28,lo8(%o1)"  CR_TAB
2989                               "sbci r29,hi8(%o1)", op, plen, -5);
2990         }
2991       else if (REGNO (XEXP (x, 0)) == REG_X)
2992         {
2993           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2994              it but I have this situation with extremal optimizing options.  */
2995           
2996           avr_asm_len ("adiw r26,%o1" CR_TAB
2997                        "ld %0,X", op, plen, -2);
2998           
2999           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3000               && !reg_unused_after (insn, XEXP (x,0)))
3001             {
3002               avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3003             }
3004
3005           return "";
3006         }
3007
3008       return avr_asm_len ("ldd %0,%1", op, plen, -1);
3009     }
3010   
3011   return avr_asm_len ("ld %0,%1", op, plen, -1);
3012 }
3013
3014 static const char*
3015 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
3016 {
3017   rtx dest = op[0];
3018   rtx src = op[1];
3019   rtx base = XEXP (src, 0);
3020   int reg_dest = true_regnum (dest);
3021   int reg_base = true_regnum (base);
3022   /* "volatile" forces reading low byte first, even if less efficient,
3023      for correct operation with 16-bit I/O registers.  */
3024   int mem_volatile_p = MEM_VOLATILE_P (src);
3025
3026   if (reg_base > 0)
3027     {
3028       if (reg_dest == reg_base)         /* R = (R) */
3029         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3030                             "ld %B0,%1"          CR_TAB
3031                             "mov %A0,__tmp_reg__", op, plen, -3);
3032
3033       if (reg_base != REG_X)
3034         return avr_asm_len ("ld %A0,%1" CR_TAB
3035                             "ldd %B0,%1+1", op, plen, -2);
3036       
3037       avr_asm_len ("ld %A0,X+" CR_TAB
3038                    "ld %B0,X", op, plen, -2);
3039           
3040       if (!reg_unused_after (insn, base))
3041         avr_asm_len ("sbiw r26,1", op, plen, 1);
3042
3043       return "";
3044     }
3045   else if (GET_CODE (base) == PLUS) /* (R + i) */
3046     {
3047       int disp = INTVAL (XEXP (base, 1));
3048       int reg_base = true_regnum (XEXP (base, 0));
3049       
3050       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3051         {
3052           if (REGNO (XEXP (base, 0)) != REG_Y)
3053             fatal_insn ("incorrect insn:",insn);
3054           
3055           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3056             ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3057                            "ldd %A0,Y+62"    CR_TAB
3058                            "ldd %B0,Y+63"    CR_TAB
3059                            "sbiw r28,%o1-62", op, plen, -4)
3060
3061             : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3062                            "sbci r29,hi8(-%o1)" CR_TAB
3063                            "ld %A0,Y"           CR_TAB
3064                            "ldd %B0,Y+1"        CR_TAB
3065                            "subi r28,lo8(%o1)"  CR_TAB
3066                            "sbci r29,hi8(%o1)", op, plen, -6);
3067         }
3068
3069       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3070          it but I have this situation with extremal
3071          optimization options.  */
3072
3073       if (reg_base == REG_X)
3074         return reg_base == reg_dest
3075           ? avr_asm_len ("adiw r26,%o1"      CR_TAB
3076                          "ld __tmp_reg__,X+" CR_TAB
3077                          "ld %B0,X"          CR_TAB
3078                          "mov %A0,__tmp_reg__", op, plen, -4)
3079
3080           : avr_asm_len ("adiw r26,%o1" CR_TAB
3081                          "ld %A0,X+"    CR_TAB
3082                          "ld %B0,X"     CR_TAB
3083                          "sbiw r26,%o1+1", op, plen, -4);
3084
3085       return reg_base == reg_dest
3086         ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3087                        "ldd %B0,%B1"         CR_TAB
3088                        "mov %A0,__tmp_reg__", op, plen, -3)
3089
3090         : avr_asm_len ("ldd %A0,%A1" CR_TAB
3091                        "ldd %B0,%B1", op, plen, -2);
3092     }
3093   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3094     {
3095       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3096         fatal_insn ("incorrect insn:", insn);
3097
3098       if (!mem_volatile_p)
3099         return avr_asm_len ("ld %B0,%1" CR_TAB
3100                             "ld %A0,%1", op, plen, -2);
3101       
3102       return REGNO (XEXP (base, 0)) == REG_X
3103         ? avr_asm_len ("sbiw r26,2"  CR_TAB
3104                        "ld %A0,X+"   CR_TAB
3105                        "ld %B0,X"    CR_TAB
3106                        "sbiw r26,1", op, plen, -4)
3107         
3108         : avr_asm_len ("sbiw %r1,2"  CR_TAB
3109                        "ld %A0,%p1"  CR_TAB
3110                        "ldd %B0,%p1+1", op, plen, -3);
3111     }
3112   else if (GET_CODE (base) == POST_INC) /* (R++) */
3113     {
3114       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3115         fatal_insn ("incorrect insn:", insn);
3116
3117       return avr_asm_len ("ld %A0,%1"  CR_TAB
3118                           "ld %B0,%1", op, plen, -2);
3119     }
3120   else if (CONSTANT_ADDRESS_P (base))
3121     {
3122       return optimize > 0 && io_address_operand (base, HImode)
3123         ? avr_asm_len ("in %A0,%i1" CR_TAB
3124                        "in %B0,%i1+1", op, plen, -2)
3125
3126         : avr_asm_len ("lds %A0,%m1" CR_TAB
3127                        "lds %B0,%m1+1", op, plen, -4);
3128     }
3129   
3130   fatal_insn ("unknown move insn:",insn);
3131   return "";
3132 }
3133
3134 static const char*
3135 out_movsi_r_mr (rtx insn, rtx op[], int *l)
3136 {
3137   rtx dest = op[0];
3138   rtx src = op[1];
3139   rtx base = XEXP (src, 0);
3140   int reg_dest = true_regnum (dest);
3141   int reg_base = true_regnum (base);
3142   int tmp;
3143
3144   if (!l)
3145     l = &tmp;
3146   
3147   if (reg_base > 0)
3148     {
3149       if (reg_base == REG_X)        /* (R26) */
3150         {
3151           if (reg_dest == REG_X)
3152             /* "ld r26,-X" is undefined */
3153             return *l=7, ("adiw r26,3"        CR_TAB
3154                           "ld r29,X"          CR_TAB
3155                           "ld r28,-X"         CR_TAB
3156                           "ld __tmp_reg__,-X" CR_TAB
3157                           "sbiw r26,1"        CR_TAB
3158                           "ld r26,X"          CR_TAB
3159                           "mov r27,__tmp_reg__");
3160           else if (reg_dest == REG_X - 2)
3161             return *l=5, ("ld %A0,X+"          CR_TAB
3162                           "ld %B0,X+"          CR_TAB
3163                           "ld __tmp_reg__,X+"  CR_TAB
3164                           "ld %D0,X"           CR_TAB
3165                           "mov %C0,__tmp_reg__");
3166           else if (reg_unused_after (insn, base))
3167             return  *l=4, ("ld %A0,X+"  CR_TAB
3168                            "ld %B0,X+" CR_TAB
3169                            "ld %C0,X+" CR_TAB
3170                            "ld %D0,X");
3171           else
3172             return  *l=5, ("ld %A0,X+"  CR_TAB
3173                            "ld %B0,X+" CR_TAB
3174                            "ld %C0,X+" CR_TAB
3175                            "ld %D0,X"  CR_TAB
3176                            "sbiw r26,3");
3177         }
3178       else
3179         {
3180           if (reg_dest == reg_base)
3181             return *l=5, ("ldd %D0,%1+3" CR_TAB
3182                           "ldd %C0,%1+2" CR_TAB
3183                           "ldd __tmp_reg__,%1+1"  CR_TAB
3184                           "ld %A0,%1"  CR_TAB
3185                           "mov %B0,__tmp_reg__");
3186           else if (reg_base == reg_dest + 2)
3187             return *l=5, ("ld %A0,%1"             CR_TAB
3188                           "ldd %B0,%1+1"          CR_TAB
3189                           "ldd __tmp_reg__,%1+2"  CR_TAB
3190                           "ldd %D0,%1+3"          CR_TAB
3191                           "mov %C0,__tmp_reg__");
3192           else
3193             return *l=4, ("ld %A0,%1"    CR_TAB
3194                           "ldd %B0,%1+1" CR_TAB
3195                           "ldd %C0,%1+2" CR_TAB
3196                           "ldd %D0,%1+3");
3197         }
3198     }
3199   else if (GET_CODE (base) == PLUS) /* (R + i) */
3200     {
3201       int disp = INTVAL (XEXP (base, 1));
3202       
3203       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3204         {
3205           if (REGNO (XEXP (base, 0)) != REG_Y)
3206             fatal_insn ("incorrect insn:",insn);
3207
3208           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3209             return *l = 6, ("adiw r28,%o1-60" CR_TAB
3210                             "ldd %A0,Y+60"    CR_TAB
3211                             "ldd %B0,Y+61"    CR_TAB
3212                             "ldd %C0,Y+62"    CR_TAB
3213                             "ldd %D0,Y+63"    CR_TAB
3214                             "sbiw r28,%o1-60");
3215
3216           return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3217                           "sbci r29,hi8(-%o1)" CR_TAB
3218                           "ld %A0,Y"           CR_TAB
3219                           "ldd %B0,Y+1"        CR_TAB
3220                           "ldd %C0,Y+2"        CR_TAB
3221                           "ldd %D0,Y+3"        CR_TAB
3222                           "subi r28,lo8(%o1)"  CR_TAB
3223                           "sbci r29,hi8(%o1)");
3224         }
3225
3226       reg_base = true_regnum (XEXP (base, 0));
3227       if (reg_base == REG_X)
3228         {
3229           /* R = (X + d) */
3230           if (reg_dest == REG_X)
3231             {
3232               *l = 7;
3233               /* "ld r26,-X" is undefined */
3234               return ("adiw r26,%o1+3"    CR_TAB
3235                       "ld r29,X"          CR_TAB
3236                       "ld r28,-X"         CR_TAB
3237                       "ld __tmp_reg__,-X" CR_TAB
3238                       "sbiw r26,1"        CR_TAB
3239                       "ld r26,X"          CR_TAB
3240                       "mov r27,__tmp_reg__");
3241             }
3242           *l = 6;
3243           if (reg_dest == REG_X - 2)
3244             return ("adiw r26,%o1"      CR_TAB
3245                     "ld r24,X+"         CR_TAB
3246                     "ld r25,X+"         CR_TAB
3247                     "ld __tmp_reg__,X+" CR_TAB
3248                     "ld r27,X"          CR_TAB
3249                     "mov r26,__tmp_reg__");
3250
3251           return ("adiw r26,%o1" CR_TAB
3252                   "ld %A0,X+"    CR_TAB
3253                   "ld %B0,X+"    CR_TAB
3254                   "ld %C0,X+"    CR_TAB
3255                   "ld %D0,X"     CR_TAB
3256                   "sbiw r26,%o1+3");
3257         }
3258       if (reg_dest == reg_base)
3259         return *l=5, ("ldd %D0,%D1"          CR_TAB
3260                       "ldd %C0,%C1"          CR_TAB
3261                       "ldd __tmp_reg__,%B1"  CR_TAB
3262                       "ldd %A0,%A1"          CR_TAB
3263                       "mov %B0,__tmp_reg__");
3264       else if (reg_dest == reg_base - 2)
3265         return *l=5, ("ldd %A0,%A1"          CR_TAB
3266                       "ldd %B0,%B1"          CR_TAB
3267                       "ldd __tmp_reg__,%C1"  CR_TAB
3268                       "ldd %D0,%D1"          CR_TAB
3269                       "mov %C0,__tmp_reg__");
3270       return *l=4, ("ldd %A0,%A1" CR_TAB
3271                     "ldd %B0,%B1" CR_TAB
3272                     "ldd %C0,%C1" CR_TAB
3273                     "ldd %D0,%D1");
3274     }
3275   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3276     return *l=4, ("ld %D0,%1" CR_TAB
3277                   "ld %C0,%1" CR_TAB
3278                   "ld %B0,%1" CR_TAB
3279                   "ld %A0,%1");
3280   else if (GET_CODE (base) == POST_INC) /* (R++) */
3281     return *l=4, ("ld %A0,%1" CR_TAB
3282                   "ld %B0,%1" CR_TAB
3283                   "ld %C0,%1" CR_TAB
3284                   "ld %D0,%1");
3285   else if (CONSTANT_ADDRESS_P (base))
3286     return *l=8, ("lds %A0,%m1"   CR_TAB
3287                   "lds %B0,%m1+1" CR_TAB
3288                   "lds %C0,%m1+2" CR_TAB
3289                   "lds %D0,%m1+3");
3290     
3291   fatal_insn ("unknown move insn:",insn);
3292   return "";
3293 }
3294
3295 static const char*
3296 out_movsi_mr_r (rtx insn, rtx op[], int *l)
3297 {
3298   rtx dest = op[0];
3299   rtx src = op[1];
3300   rtx base = XEXP (dest, 0);
3301   int reg_base = true_regnum (base);
3302   int reg_src = true_regnum (src);
3303   int tmp;
3304   
3305   if (!l)
3306     l = &tmp;
3307   
3308   if (CONSTANT_ADDRESS_P (base))
3309     return *l=8,("sts %m0,%A1" CR_TAB
3310                  "sts %m0+1,%B1" CR_TAB
3311                  "sts %m0+2,%C1" CR_TAB
3312                  "sts %m0+3,%D1");
3313   if (reg_base > 0)                 /* (r) */
3314     {
3315       if (reg_base == REG_X)                /* (R26) */
3316         {
3317           if (reg_src == REG_X)
3318             {
3319               /* "st X+,r26" is undefined */
3320               if (reg_unused_after (insn, base))
3321                 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
3322                               "st X,r26"            CR_TAB
3323                               "adiw r26,1"          CR_TAB
3324                               "st X+,__tmp_reg__"   CR_TAB
3325                               "st X+,r28"           CR_TAB
3326                               "st X,r29");
3327               else
3328                 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
3329                               "st X,r26"            CR_TAB
3330                               "adiw r26,1"          CR_TAB
3331                               "st X+,__tmp_reg__"   CR_TAB
3332                               "st X+,r28"           CR_TAB
3333                               "st X,r29"            CR_TAB
3334                               "sbiw r26,3");
3335             }
3336           else if (reg_base == reg_src + 2)
3337             {
3338               if (reg_unused_after (insn, base))
3339                 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
3340                               "mov __tmp_reg__,%D1"  CR_TAB
3341                               "st %0+,%A1"           CR_TAB
3342                               "st %0+,%B1"           CR_TAB
3343                               "st %0+,__zero_reg__"  CR_TAB
3344                               "st %0,__tmp_reg__"    CR_TAB
3345                               "clr __zero_reg__");
3346               else
3347                 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
3348                               "mov __tmp_reg__,%D1"  CR_TAB
3349                               "st %0+,%A1"           CR_TAB
3350                               "st %0+,%B1"           CR_TAB
3351                               "st %0+,__zero_reg__"  CR_TAB
3352                               "st %0,__tmp_reg__"    CR_TAB
3353                               "clr __zero_reg__"     CR_TAB
3354                               "sbiw r26,3");
3355             }
3356           return *l=5, ("st %0+,%A1" CR_TAB
3357                         "st %0+,%B1" CR_TAB
3358                         "st %0+,%C1" CR_TAB
3359                         "st %0,%D1"  CR_TAB
3360                         "sbiw r26,3");
3361         }
3362       else
3363         return *l=4, ("st %0,%A1"    CR_TAB
3364                       "std %0+1,%B1" CR_TAB
3365                       "std %0+2,%C1" CR_TAB
3366                       "std %0+3,%D1");
3367     }
3368   else if (GET_CODE (base) == PLUS) /* (R + i) */
3369     {
3370       int disp = INTVAL (XEXP (base, 1));
3371       reg_base = REGNO (XEXP (base, 0));
3372       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3373         {
3374           if (reg_base != REG_Y)
3375             fatal_insn ("incorrect insn:",insn);
3376
3377           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3378             return *l = 6, ("adiw r28,%o0-60" CR_TAB
3379                             "std Y+60,%A1"    CR_TAB
3380                             "std Y+61,%B1"    CR_TAB
3381                             "std Y+62,%C1"    CR_TAB
3382                             "std Y+63,%D1"    CR_TAB
3383                             "sbiw r28,%o0-60");
3384
3385           return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
3386                           "sbci r29,hi8(-%o0)" CR_TAB
3387                           "st Y,%A1"           CR_TAB
3388                           "std Y+1,%B1"        CR_TAB
3389                           "std Y+2,%C1"        CR_TAB
3390                           "std Y+3,%D1"        CR_TAB
3391                           "subi r28,lo8(%o0)"  CR_TAB
3392                           "sbci r29,hi8(%o0)");
3393         }
3394       if (reg_base == REG_X)
3395         {
3396           /* (X + d) = R */
3397           if (reg_src == REG_X)
3398             {
3399               *l = 9;
3400               return ("mov __tmp_reg__,r26"  CR_TAB
3401                       "mov __zero_reg__,r27" CR_TAB
3402                       "adiw r26,%o0"         CR_TAB
3403                       "st X+,__tmp_reg__"    CR_TAB
3404                       "st X+,__zero_reg__"   CR_TAB
3405                       "st X+,r28"            CR_TAB
3406                       "st X,r29"             CR_TAB
3407                       "clr __zero_reg__"     CR_TAB
3408                       "sbiw r26,%o0+3");
3409             }
3410           else if (reg_src == REG_X - 2)
3411             {
3412               *l = 9;
3413               return ("mov __tmp_reg__,r26"  CR_TAB
3414                       "mov __zero_reg__,r27" CR_TAB
3415                       "adiw r26,%o0"         CR_TAB
3416                       "st X+,r24"            CR_TAB
3417                       "st X+,r25"            CR_TAB
3418                       "st X+,__tmp_reg__"    CR_TAB
3419                       "st X,__zero_reg__"    CR_TAB
3420                       "clr __zero_reg__"     CR_TAB
3421                       "sbiw r26,%o0+3");
3422             }
3423           *l = 6;
3424           return ("adiw r26,%o0" CR_TAB
3425                   "st X+,%A1"    CR_TAB
3426                   "st X+,%B1"    CR_TAB
3427                   "st X+,%C1"    CR_TAB
3428                   "st X,%D1"     CR_TAB
3429                   "sbiw r26,%o0+3");
3430         }
3431       return *l=4, ("std %A0,%A1" CR_TAB
3432                     "std %B0,%B1" CR_TAB
3433                     "std %C0,%C1" CR_TAB
3434                     "std %D0,%D1");
3435     }
3436   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3437     return *l=4, ("st %0,%D1" CR_TAB
3438                   "st %0,%C1" CR_TAB
3439                   "st %0,%B1" CR_TAB
3440                   "st %0,%A1");
3441   else if (GET_CODE (base) == POST_INC) /* (R++) */
3442     return *l=4, ("st %0,%A1" CR_TAB
3443                   "st %0,%B1" CR_TAB
3444                   "st %0,%C1" CR_TAB
3445                   "st %0,%D1");
3446   fatal_insn ("unknown move insn:",insn);
3447   return "";
3448 }
3449
3450 const char *
3451 output_movsisf (rtx insn, rtx operands[], int *l)
3452 {
3453   int dummy;
3454   rtx