OSDN Git Service

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