OSDN Git Service

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