OSDN Git Service

Backport from 2012-09-28 trunk r191821.
[pf3gnuchains/gcc-fork.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006, 2007, 2008,
3    2009, 2010, 2011 Free Software Foundation, Inc.
4    Contributed by Denis Chertykov (chertykov@gmail.com)
5
6    This file is part of GCC.
7
8    GCC is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3, or (at your option)
11    any later version.
12    
13    GCC is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with GCC; see the file COPYING3.  If not see
20    <http://www.gnu.org/licenses/>.  */
21
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "rtl.h"
27 #include "regs.h"
28 #include "hard-reg-set.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-attr.h"
32 #include "insn-codes.h"
33 #include "flags.h"
34 #include "reload.h"
35 #include "tree.h"
36 #include "output.h"
37 #include "expr.h"
38 #include "c-family/c-common.h"
39 #include "diagnostic-core.h"
40 #include "obstack.h"
41 #include "function.h"
42 #include "recog.h"
43 #include "optabs.h"
44 #include "ggc.h"
45 #include "langhooks.h"
46 #include "tm_p.h"
47 #include "target.h"
48 #include "target-def.h"
49 #include "params.h"
50 #include "df.h"
51
52 /* Maximal allowed offset for an address in the LD command */
53 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
54
55 /* Return true if STR starts with PREFIX and false, otherwise.  */
56 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
57
58 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
59    address space where data is to be located.
60    As the only non-generic address spaces are all located in Flash,
61    this can be used to test if data shall go into some .progmem* section.
62    This must be the rightmost field of machine dependent section flags.  */
63 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
64
65 /* Similar 4-bit region for SYMBOL_REF_FLAGS.  */
66 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
67
68 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
69    Set address-space AS in SYMBOL_REF_FLAGS of SYM  */
70 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS)                       \
71   do {                                                          \
72     SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM;         \
73     SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP;      \
74   } while (0)
75
76 /* Read address-space from SYMBOL_REF_FLAGS of SYM  */
77 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM)                          \
78   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
79    / SYMBOL_FLAG_MACH_DEP)
80
81 /* Known address spaces.  The order must be the same as in the respective
82    enum from avr.h (or designated initialized must be used).  */
83 const avr_addrspace_t avr_addrspace[] =
84 {
85     { ADDR_SPACE_RAM,  0, 2, ""     ,   0 },
86     { ADDR_SPACE_FLASH,  1, 2, "__flash",   0 },
87     { ADDR_SPACE_FLASH1, 1, 2, "__flash1",  1 },
88     { ADDR_SPACE_FLASH2, 1, 2, "__flash2",  2 },
89     { ADDR_SPACE_FLASH3, 1, 2, "__flash3",  3 },
90     { ADDR_SPACE_FLASH4, 1, 2, "__flash4",  4 },
91     { ADDR_SPACE_FLASH5, 1, 2, "__flash5",  5 },
92     { ADDR_SPACE_MEMX, 1, 3, "__memx",  0 },
93     { 0              , 0, 0, NULL,      0 }
94 };
95
96 /* Map 64-k Flash segment to section prefix.  */
97 static const char* const progmem_section_prefix[6] =
98   {
99     ".progmem.data",
100     ".progmem1.data",
101     ".progmem2.data",
102     ".progmem3.data",
103     ".progmem4.data",
104     ".progmem5.data"
105   };
106
107 /* Holding RAM addresses of some SFRs used by the compiler and that
108    are unique over all devices in an architecture like 'avr4'.  */
109   
110 typedef struct
111 {
112   /* SREG: The pocessor status */
113   int sreg;
114
115   /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
116   int ccp;
117   int rampd;
118   int rampx;
119   int rampy;
120
121   /* RAMPZ: The high byte of 24-bit address used with ELPM */ 
122   int rampz;
123
124   /* SP: The stack pointer and its low and high byte */
125   int sp_l;
126   int sp_h;
127 } avr_addr_t;
128
129 static avr_addr_t avr_addr;
130
131
132 /* Prototypes for local helper functions.  */
133
134 static const char* out_movqi_r_mr (rtx, rtx[], int*);
135 static const char* out_movhi_r_mr (rtx, rtx[], int*);
136 static const char* out_movsi_r_mr (rtx, rtx[], int*);
137 static const char* out_movqi_mr_r (rtx, rtx[], int*);
138 static const char* out_movhi_mr_r (rtx, rtx[], int*);
139 static const char* out_movsi_mr_r (rtx, rtx[], int*);
140
141 static int get_sequence_length (rtx insns);
142 static int sequent_regs_live (void);
143 static const char *ptrreg_to_str (int);
144 static const char *cond_string (enum rtx_code);
145 static int avr_num_arg_regs (enum machine_mode, const_tree);
146 static int avr_operand_rtx_cost (rtx, enum machine_mode, enum rtx_code,
147                                  int, bool);
148 static void output_reload_in_const (rtx*, rtx, int*, bool);
149 static struct machine_function * avr_init_machine_status (void);
150
151
152 /* Prototypes for hook implementors if needed before their implementation.  */
153
154 static bool avr_rtx_costs (rtx, int, int, int, int *, bool);
155
156
157 /* Allocate registers from r25 to r8 for parameters for function calls.  */
158 #define FIRST_CUM_REG 26
159
160 /* Implicit target register of LPM instruction (R0) */
161 extern GTY(()) rtx lpm_reg_rtx;
162 rtx lpm_reg_rtx;
163
164 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
165 extern GTY(()) rtx lpm_addr_reg_rtx;
166 rtx lpm_addr_reg_rtx;
167
168 /* Temporary register RTX (reg:QI TMP_REGNO) */
169 extern GTY(()) rtx tmp_reg_rtx;
170 rtx tmp_reg_rtx;
171
172 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
173 extern GTY(()) rtx zero_reg_rtx;
174 rtx zero_reg_rtx;
175
176 /* RTXs for all general purpose registers as QImode */
177 extern GTY(()) rtx all_regs_rtx[32];
178 rtx all_regs_rtx[32];
179
180 /* SREG, the processor status */
181 extern GTY(()) rtx sreg_rtx;
182 rtx sreg_rtx;
183
184 /* RAMP* special function registers */
185 extern GTY(()) rtx rampd_rtx;
186 extern GTY(()) rtx rampx_rtx;
187 extern GTY(()) rtx rampy_rtx;
188 extern GTY(()) rtx rampz_rtx;
189 rtx rampd_rtx;
190 rtx rampx_rtx;
191 rtx rampy_rtx;
192 rtx rampz_rtx;
193
194 /* RTX containing the strings "" and "e", respectively */
195 static GTY(()) rtx xstring_empty;
196 static GTY(()) rtx xstring_e;
197
198 /* Preprocessor macros to define depending on MCU type.  */
199 const char *avr_extra_arch_macro;
200
201 /* Current architecture.  */
202 const struct base_arch_s *avr_current_arch;
203
204 /* Current device.  */
205 const struct mcu_type_s *avr_current_device;
206
207 /* Section to put switch tables in.  */
208 static GTY(()) section *progmem_swtable_section;
209
210 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
211    or to address space __flash*.  */
212 static GTY(()) section *progmem_section[6];
213
214 /* Condition for insns/expanders from avr-dimode.md.  */
215 bool avr_have_dimode = true;
216
217 /* To track if code will use .bss and/or .data.  */
218 bool avr_need_clear_bss_p = false;
219 bool avr_need_copy_data_p = false;
220
221 \f
222
223 /* Custom function to count number of set bits.  */
224
225 static inline int
226 avr_popcount (unsigned int val)
227 {
228   int pop = 0;
229
230   while (val)
231     {
232       val &= val-1;
233       pop++;
234     }
235
236   return pop;
237 }
238
239
240 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
241    Return true if the least significant N_BYTES bytes of XVAL all have a
242    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
243    of integers which contains an integer N iff bit N of POP_MASK is set.  */
244    
245 bool
246 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
247 {
248   int i;
249
250   enum machine_mode mode = GET_MODE (xval);
251
252   if (VOIDmode == mode)
253     mode = SImode;
254
255   for (i = 0; i < n_bytes; i++)
256     {
257       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
258       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
259
260       if (0 == (pop_mask & (1 << avr_popcount (val8))))
261         return false;
262     }
263
264   return true;
265 }
266
267 static void
268 avr_option_override (void)
269 {
270   flag_delete_null_pointer_checks = 0;
271
272   /* caller-save.c looks for call-clobbered hard registers that are assigned
273      to pseudos that cross calls and tries so save-restore them around calls
274      in order to reduce the number of stack slots needed.
275
276      This might leads to situations where reload is no more able to cope
277      with the challenge of AVR's very few address registers and fails to
278      perform the requested spills.  */
279   
280   if (avr_strict_X)
281     flag_caller_saves = 0;
282
283   /* Unwind tables currently require a frame pointer for correctness,
284      see toplev.c:process_options().  */
285
286   if ((flag_unwind_tables
287        || flag_non_call_exceptions
288        || flag_asynchronous_unwind_tables)
289       && !ACCUMULATE_OUTGOING_ARGS)
290     {
291       flag_omit_frame_pointer = 0;
292     }
293
294   avr_current_device = &avr_mcu_types[avr_mcu_index];
295   avr_current_arch = &avr_arch_types[avr_current_device->arch];
296   avr_extra_arch_macro = avr_current_device->macro;
297   
298   /* RAM addresses of some SFRs common to all Devices in respective Arch. */
299
300   /* SREG: Status Register containing flags like I (global IRQ) */
301   avr_addr.sreg = 0x3F + avr_current_arch->sfr_offset;
302
303   /* RAMPZ: Address' high part when loading via ELPM */
304   avr_addr.rampz = 0x3B + avr_current_arch->sfr_offset;
305
306   avr_addr.rampy = 0x3A + avr_current_arch->sfr_offset;
307   avr_addr.rampx = 0x39 + avr_current_arch->sfr_offset;
308   avr_addr.rampd = 0x38 + avr_current_arch->sfr_offset;
309   avr_addr.ccp = 0x34 + avr_current_arch->sfr_offset;
310
311   /* SP: Stack Pointer (SP_H:SP_L) */
312   avr_addr.sp_l = 0x3D + avr_current_arch->sfr_offset;
313   avr_addr.sp_h = avr_addr.sp_l + 1;
314
315   init_machine_status = avr_init_machine_status;
316
317   avr_log_set_avr_log();
318 }
319
320 /* Function to set up the backend function structure.  */
321
322 static struct machine_function *
323 avr_init_machine_status (void)
324 {
325   return ggc_alloc_cleared_machine_function ();
326 }
327
328
329 /* Implement `INIT_EXPANDERS'.  */
330 /* The function works like a singleton.  */
331
332 void
333 avr_init_expanders (void)
334 {
335   int regno;
336
337   for (regno = 0; regno < 32; regno ++)
338     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
339
340   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
341   tmp_reg_rtx  = all_regs_rtx[TMP_REGNO];
342   zero_reg_rtx = all_regs_rtx[ZERO_REGNO];
343
344   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
345
346   sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
347   rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
348   rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
349   rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
350   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
351
352   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
353   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
354 }
355
356
357 /* Return register class for register R.  */
358
359 enum reg_class
360 avr_regno_reg_class (int r)
361 {
362   static const enum reg_class reg_class_tab[] =
363     {
364       R0_REG,
365       /* r1 - r15 */
366       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
367       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
368       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
369       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
370       /* r16 - r23 */
371       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
372       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
373       /* r24, r25 */
374       ADDW_REGS, ADDW_REGS,
375       /* X: r26, 27 */
376       POINTER_X_REGS, POINTER_X_REGS,
377       /* Y: r28, r29 */
378       POINTER_Y_REGS, POINTER_Y_REGS,
379       /* Z: r30, r31 */
380       POINTER_Z_REGS, POINTER_Z_REGS,
381       /* SP: SPL, SPH */
382       STACK_REG, STACK_REG
383     };
384
385   if (r <= 33)
386     return reg_class_tab[r];
387   
388   return ALL_REGS;
389 }
390
391
392 static bool
393 avr_scalar_mode_supported_p (enum machine_mode mode)
394 {
395   if (PSImode == mode)
396     return true;
397
398   return default_scalar_mode_supported_p (mode);
399 }
400
401
402 /* Return TRUE if DECL is a VAR_DECL located in Flash and FALSE, otherwise.  */
403
404 static bool
405 avr_decl_flash_p (tree decl)
406 {
407   if (TREE_CODE (decl) != VAR_DECL
408       || TREE_TYPE (decl) == error_mark_node)
409     {
410       return false;
411     }
412
413   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
414 }
415
416
417 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit Flash
418    address space and FALSE, otherwise.  */
419  
420 static bool
421 avr_decl_memx_p (tree decl)
422 {
423   if (TREE_CODE (decl) != VAR_DECL
424       || TREE_TYPE (decl) == error_mark_node)
425     {
426       return false;
427     }
428
429   return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
430 }
431
432
433 /* Return TRUE if X is a MEM rtx located in Flash and FALSE, otherwise.  */
434
435 bool
436 avr_mem_flash_p (rtx x)
437 {
438   return (MEM_P (x)
439           && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
440 }
441
442
443 /* Return TRUE if X is a MEM rtx located in the 24-bit Flash
444    address space and FALSE, otherwise.  */
445
446 bool
447 avr_mem_memx_p (rtx x)
448 {
449   return (MEM_P (x)
450           && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
451 }
452
453
454 /* A helper for the subsequent function attribute used to dig for
455    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
456
457 static inline int
458 avr_lookup_function_attribute1 (const_tree func, const char *name)
459 {
460   if (FUNCTION_DECL == TREE_CODE (func))
461     {
462       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
463         {
464           return true;
465         }
466       
467       func = TREE_TYPE (func);
468     }
469
470   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
471               || TREE_CODE (func) == METHOD_TYPE);
472   
473   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
474 }
475
476 /* Return nonzero if FUNC is a naked function.  */
477
478 static int
479 avr_naked_function_p (tree func)
480 {
481   return avr_lookup_function_attribute1 (func, "naked");
482 }
483
484 /* Return nonzero if FUNC is an interrupt function as specified
485    by the "interrupt" attribute.  */
486
487 static int
488 avr_interrupt_function_p (tree func)
489 {
490   return avr_lookup_function_attribute1 (func, "interrupt");
491 }
492
493 /* Return nonzero if FUNC is a signal function as specified
494    by the "signal" attribute.  */
495
496 static int
497 avr_signal_function_p (tree func)
498 {
499   return avr_lookup_function_attribute1 (func, "signal");
500 }
501
502 /* Return nonzero if FUNC is an OS_task function.  */
503
504 static int
505 avr_OS_task_function_p (tree func)
506 {
507   return avr_lookup_function_attribute1 (func, "OS_task");
508 }
509
510 /* Return nonzero if FUNC is an OS_main function.  */
511
512 static int
513 avr_OS_main_function_p (tree func)
514 {
515   return avr_lookup_function_attribute1 (func, "OS_main");
516 }
517
518
519 /* Implement `TARGET_SET_CURRENT_FUNCTION'.  */
520 /* Sanity cheching for above function attributes.  */
521
522 static void
523 avr_set_current_function (tree decl)
524 {
525   location_t loc;
526   const char *isr;
527
528   if (decl == NULL_TREE
529       || current_function_decl == NULL_TREE
530       || current_function_decl == error_mark_node
531       || cfun->machine->attributes_checked_p)
532     return;
533
534   loc = DECL_SOURCE_LOCATION (decl);
535
536   cfun->machine->is_naked = avr_naked_function_p (decl);
537   cfun->machine->is_signal = avr_signal_function_p (decl);
538   cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
539   cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
540   cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
541
542   isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
543
544   /* Too much attributes make no sense as they request conflicting features. */
545
546   if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
547       + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
548     error_at (loc, "function attributes %qs, %qs and %qs are mutually"
549                " exclusive", "OS_task", "OS_main", isr);
550
551   /* 'naked' will hide effects of 'OS_task' and 'OS_main'.  */
552
553   if (cfun->machine->is_naked
554       && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
555     warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
556                 " no effect on %qs function", "OS_task", "OS_main", "naked");
557
558   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
559     {
560       tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
561       tree ret = TREE_TYPE (TREE_TYPE (decl));
562       const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
563       
564       /* Silently ignore 'signal' if 'interrupt' is present.  AVR-LibC startet
565          using this when it switched from SIGNAL and INTERRUPT to ISR.  */
566
567       if (cfun->machine->is_interrupt)
568         cfun->machine->is_signal = 0;
569
570       /* Interrupt handlers must be  void __vector (void)  functions.  */
571
572       if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
573         error_at (loc, "%qs function cannot have arguments", isr);
574
575       if (TREE_CODE (ret) != VOID_TYPE)
576         error_at (loc, "%qs function cannot return a value", isr);
577
578       /* If the function has the 'signal' or 'interrupt' attribute, ensure
579          that the name of the function is "__vector_NN" so as to catch
580          when the user misspells the vector name.  */
581
582       if (!STR_PREFIX_P (name, "__vector"))
583         warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
584                     name, isr);
585     }
586
587   /* Avoid the above diagnosis to be printed more than once.  */
588   
589   cfun->machine->attributes_checked_p = 1;
590 }
591
592
593 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
594
595 int
596 avr_accumulate_outgoing_args (void)
597 {
598   if (!cfun)
599     return TARGET_ACCUMULATE_OUTGOING_ARGS;
600
601   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
602         what offset is correct.  In some cases it is relative to
603         virtual_outgoing_args_rtx and in others it is relative to
604         virtual_stack_vars_rtx.  For example code see
605             gcc.c-torture/execute/built-in-setjmp.c
606             gcc.c-torture/execute/builtins/sprintf-chk.c   */
607   
608   return (TARGET_ACCUMULATE_OUTGOING_ARGS
609           && !(cfun->calls_setjmp
610                || cfun->has_nonlocal_label));
611 }
612
613
614 /* Report contribution of accumulated outgoing arguments to stack size.  */
615
616 static inline int
617 avr_outgoing_args_size (void)
618 {
619   return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
620 }
621
622
623 /* Implement `STARTING_FRAME_OFFSET'.  */
624 /* This is the offset from the frame pointer register to the first stack slot
625    that contains a variable living in the frame.  */
626
627 int
628 avr_starting_frame_offset (void)
629 {
630   return 1 + avr_outgoing_args_size ();
631 }
632
633
634 /* Return the number of hard registers to push/pop in the prologue/epilogue
635    of the current function, and optionally store these registers in SET.  */
636
637 static int
638 avr_regs_to_save (HARD_REG_SET *set)
639 {
640   int reg, count;
641   int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
642
643   if (set)
644     CLEAR_HARD_REG_SET (*set);
645   count = 0;
646
647   /* No need to save any registers if the function never returns or 
648      has the "OS_task" or "OS_main" attribute.  */
649   if (TREE_THIS_VOLATILE (current_function_decl)
650       || cfun->machine->is_OS_task
651       || cfun->machine->is_OS_main)
652     return 0;
653
654   for (reg = 0; reg < 32; reg++)
655     {
656       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
657          any global register variables.  */
658       if (fixed_regs[reg])
659         continue;
660
661       if ((int_or_sig_p && !current_function_is_leaf && call_used_regs[reg])
662           || (df_regs_ever_live_p (reg)
663               && (int_or_sig_p || !call_used_regs[reg])
664               /* Don't record frame pointer registers here.  They are treated
665                  indivitually in prologue.  */
666               && !(frame_pointer_needed
667                    && (reg == REG_Y || reg == (REG_Y+1)))))
668         {
669           if (set)
670             SET_HARD_REG_BIT (*set, reg);
671           count++;
672         }
673     }
674   return count;
675 }
676
677
678 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
679
680 static bool
681 avr_allocate_stack_slots_for_args (void)
682 {
683   return !cfun->machine->is_naked;
684 }
685
686
687 /* Return true if register FROM can be eliminated via register TO.  */
688
689 static bool
690 avr_can_eliminate (const int from, const int to)
691 {
692   return ((from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
693           || (frame_pointer_needed && to == FRAME_POINTER_REGNUM)
694           || ((from == FRAME_POINTER_REGNUM 
695                || from == FRAME_POINTER_REGNUM + 1)
696               && !frame_pointer_needed));
697 }
698
699 /* Compute offset between arg_pointer and frame_pointer.  */
700
701 int
702 avr_initial_elimination_offset (int from, int to)
703 {
704   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
705     return 0;
706   else
707     {
708       int offset = frame_pointer_needed ? 2 : 0;
709       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
710       
711       offset += avr_regs_to_save (NULL);
712       return (get_frame_size () + avr_outgoing_args_size()
713               + avr_pc_size + 1 + offset);
714     }
715 }
716
717 /* Actual start of frame is virtual_stack_vars_rtx this is offset from 
718    frame pointer by +STARTING_FRAME_OFFSET.
719    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
720    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
721
722 static rtx
723 avr_builtin_setjmp_frame_value (void)
724 {
725   return gen_rtx_MINUS (Pmode, virtual_stack_vars_rtx, 
726                         gen_int_mode (STARTING_FRAME_OFFSET, Pmode));
727 }
728
729 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3 byte PC).
730    This is return address of function.  */
731 rtx 
732 avr_return_addr_rtx (int count, rtx tem)
733 {
734   rtx r;
735     
736   /* Can only return this function's return address. Others not supported.  */
737   if (count)
738      return NULL;
739
740   if (AVR_3_BYTE_PC)
741     {
742       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
743       warning (0, "'builtin_return_address' contains only 2 bytes of address");
744     }
745   else
746     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
747
748   r = gen_rtx_PLUS (Pmode, tem, r);
749   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
750   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
751   return  r;
752 }
753
754 /* Return 1 if the function epilogue is just a single "ret".  */
755
756 int
757 avr_simple_epilogue (void)
758 {
759   return (! frame_pointer_needed
760           && get_frame_size () == 0
761           && avr_outgoing_args_size() == 0
762           && avr_regs_to_save (NULL) == 0
763           && ! cfun->machine->is_interrupt
764           && ! cfun->machine->is_signal
765           && ! cfun->machine->is_naked
766           && ! TREE_THIS_VOLATILE (current_function_decl));
767 }
768
769 /* This function checks sequence of live registers.  */
770
771 static int
772 sequent_regs_live (void)
773 {
774   int reg;
775   int live_seq=0;
776   int cur_seq=0;
777
778   for (reg = 0; reg < 18; ++reg)
779     {
780       if (fixed_regs[reg])
781         {
782           /* Don't recognize sequences that contain global register
783              variables.  */
784       
785           if (live_seq != 0)
786             return 0;
787           else
788             continue;
789         }
790       
791       if (!call_used_regs[reg])
792         {
793           if (df_regs_ever_live_p (reg))
794             {
795               ++live_seq;
796               ++cur_seq;
797             }
798           else
799             cur_seq = 0;
800         }
801     }
802
803   if (!frame_pointer_needed)
804     {
805       if (df_regs_ever_live_p (REG_Y))
806         {
807           ++live_seq;
808           ++cur_seq;
809         }
810       else
811         cur_seq = 0;
812
813       if (df_regs_ever_live_p (REG_Y+1))
814         {
815           ++live_seq;
816           ++cur_seq;
817         }
818       else
819         cur_seq = 0;
820     }
821   else
822     {
823       cur_seq += 2;
824       live_seq += 2;
825     }
826   return (cur_seq == live_seq) ? live_seq : 0;
827 }
828
829 /* Obtain the length sequence of insns.  */
830
831 int
832 get_sequence_length (rtx insns)
833 {
834   rtx insn;
835   int length;
836   
837   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
838     length += get_attr_length (insn);
839                 
840   return length;
841 }
842
843 /*  Implement INCOMING_RETURN_ADDR_RTX.  */
844
845 rtx
846 avr_incoming_return_addr_rtx (void)
847 {
848   /* The return address is at the top of the stack.  Note that the push
849      was via post-decrement, which means the actual address is off by one.  */
850   return gen_frame_mem (HImode, plus_constant (stack_pointer_rtx, 1));
851 }
852
853 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
854
855 static void
856 emit_push_byte (unsigned regno, bool frame_related_p)
857 {
858   rtx mem, reg, insn;
859
860   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
861   mem = gen_frame_mem (QImode, mem);
862   reg = gen_rtx_REG (QImode, regno);
863
864   insn = emit_insn (gen_rtx_SET (VOIDmode, mem, reg));
865   if (frame_related_p)
866     RTX_FRAME_RELATED_P (insn) = 1;
867
868   cfun->machine->stack_usage++;
869 }
870
871
872 /*  Helper for expand_prologue.  Emit a push of a SFR via tmp_reg.
873     SFR is a MEM representing the memory location of the SFR.
874     If CLR_P then clear the SFR after the push using zero_reg.  */
875
876 static void
877 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
878 {
879   rtx insn;
880   
881   gcc_assert (MEM_P (sfr));
882
883   /* IN __tmp_reg__, IO(SFR) */
884   insn = emit_move_insn (tmp_reg_rtx, sfr);
885   if (frame_related_p)
886     RTX_FRAME_RELATED_P (insn) = 1;
887   
888   /* PUSH __tmp_reg__ */
889   emit_push_byte (TMP_REGNO, frame_related_p);
890
891   if (clr_p)
892     {
893       /* OUT IO(SFR), __zero_reg__ */
894       insn = emit_move_insn (sfr, const0_rtx);
895       if (frame_related_p)
896         RTX_FRAME_RELATED_P (insn) = 1;
897     }
898 }
899
900 static void
901 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
902 {
903   rtx insn;
904   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
905   int live_seq = sequent_regs_live ();
906
907   HOST_WIDE_INT size_max
908     = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
909
910   bool minimize = (TARGET_CALL_PROLOGUES
911                    && size < size_max
912                    && live_seq
913                    && !isr_p
914                    && !cfun->machine->is_OS_task
915                    && !cfun->machine->is_OS_main);
916   
917   if (minimize
918       && (frame_pointer_needed
919           || avr_outgoing_args_size() > 8
920           || (AVR_2_BYTE_PC && live_seq > 6)
921           || live_seq > 7)) 
922     {
923       rtx pattern;
924       int first_reg, reg, offset;
925
926       emit_move_insn (gen_rtx_REG (HImode, REG_X), 
927                       gen_int_mode (size, HImode));
928
929       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
930                                          gen_int_mode (live_seq+size, HImode));
931       insn = emit_insn (pattern);
932       RTX_FRAME_RELATED_P (insn) = 1;
933
934       /* Describe the effect of the unspec_volatile call to prologue_saves.
935          Note that this formulation assumes that add_reg_note pushes the
936          notes to the front.  Thus we build them in the reverse order of
937          how we want dwarf2out to process them.  */
938
939       /* The function does always set frame_pointer_rtx, but whether that
940          is going to be permanent in the function is frame_pointer_needed.  */
941
942       add_reg_note (insn, REG_CFA_ADJUST_CFA,
943                     gen_rtx_SET (VOIDmode, (frame_pointer_needed
944                                             ? frame_pointer_rtx
945                                             : stack_pointer_rtx),
946                                  plus_constant (stack_pointer_rtx,
947                                                 -(size + live_seq))));
948
949       /* Note that live_seq always contains r28+r29, but the other
950          registers to be saved are all below 18.  */
951
952       first_reg = 18 - (live_seq - 2);
953
954       for (reg = 29, offset = -live_seq + 1;
955            reg >= first_reg;
956            reg = (reg == 28 ? 17 : reg - 1), ++offset)
957         {
958           rtx m, r;
959
960           m = gen_rtx_MEM (QImode, plus_constant (stack_pointer_rtx, offset));
961           r = gen_rtx_REG (QImode, reg);
962           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (VOIDmode, m, r));
963         }
964
965       cfun->machine->stack_usage += size + live_seq;
966     }
967   else /* !minimize */
968     {
969       int reg;
970       
971       for (reg = 0; reg < 32; ++reg)
972         if (TEST_HARD_REG_BIT (set, reg))
973           emit_push_byte (reg, true);
974
975       if (frame_pointer_needed
976           && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
977         {
978           /* Push frame pointer.  Always be consistent about the
979              ordering of pushes -- epilogue_restores expects the
980              register pair to be pushed low byte first.  */
981           
982           emit_push_byte (REG_Y, true);
983           emit_push_byte (REG_Y + 1, true);
984         }
985           
986       if (frame_pointer_needed
987           && size == 0)
988         {
989           insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
990           RTX_FRAME_RELATED_P (insn) = 1;
991         }
992       
993       if (size != 0)
994         {
995           /*  Creating a frame can be done by direct manipulation of the
996               stack or via the frame pointer. These two methods are:
997                   fp =  sp
998                   fp -= size
999                   sp =  fp
1000               or
1001                   sp -= size
1002                   fp =  sp    (*)
1003               the optimum method depends on function type, stack and
1004               frame size.  To avoid a complex logic, both methods are
1005               tested and shortest is selected.
1006
1007               There is also the case where SIZE != 0 and no frame pointer is
1008               needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1009               In that case, insn (*) is not needed in that case.
1010               We use the X register as scratch. This is save because in X
1011               is call-clobbered.
1012                  In an interrupt routine, the case of SIZE != 0 together with
1013               !frame_pointer_needed can only occur if the function is not a
1014               leaf function and thus X has already been saved.  */
1015               
1016           int irq_state = -1;
1017           HOST_WIDE_INT size_cfa = size;
1018           rtx fp_plus_insns, fp, my_fp;
1019
1020           gcc_assert (frame_pointer_needed
1021                       || !isr_p
1022                       || !current_function_is_leaf);
1023           
1024           fp = my_fp = (frame_pointer_needed
1025                         ? frame_pointer_rtx
1026                         : gen_rtx_REG (Pmode, REG_X));
1027           
1028           if (AVR_HAVE_8BIT_SP)
1029             {
1030               /* The high byte (r29) does not change:
1031                  Prefer SUBI (1 cycle) over SBIW (2 cycles, same size).  */
1032
1033               my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1034             }
1035
1036           /* Cut down size and avoid size = 0 so that we don't run
1037              into ICE like PR52488 in the remainder.  */
1038
1039           if (size > size_max)
1040             {
1041               /* Don't error so that insane code from newlib still compiles
1042                  and does not break building newlib.  As PR51345 is implemented
1043                  now, there are multilib variants with -msp8.
1044                  
1045                  If user wants sanity checks he can use -Wstack-usage=
1046                  or similar options.
1047
1048                  For CFA we emit the original, non-saturated size so that
1049                  the generic machinery is aware of the real stack usage and
1050                  will print the above diagnostic as expected.  */
1051               
1052               size = size_max;
1053             }
1054
1055           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, -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_CZN:
2179       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2180          The V flag may or may not be known but that's ok because
2181          alter_cond will change tests to use EQ/NE.  */
2182       set = single_set (insn);
2183       CC_STATUS_INIT;
2184       if (set)
2185         {
2186           cc_status.value1 = SET_DEST (set);
2187           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2188         }
2189       break;
2190
2191     case CC_COMPARE:
2192       set = single_set (insn);
2193       CC_STATUS_INIT;
2194       if (set)
2195         cc_status.value1 = SET_SRC (set);
2196       break;
2197       
2198     case CC_CLOBBER:
2199       /* Insn doesn't leave CC in a usable state.  */
2200       CC_STATUS_INIT;
2201       break;
2202     }
2203 }
2204
2205 /* Choose mode for jump insn:
2206    1 - relative jump in range -63 <= x <= 62 ;
2207    2 - relative jump in range -2046 <= x <= 2045 ;
2208    3 - absolute jump (only for ATmega[16]03).  */
2209
2210 int
2211 avr_jump_mode (rtx x, rtx insn)
2212 {
2213   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2214                                             ? XEXP (x, 0) : x));
2215   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2216   int jump_distance = cur_addr - dest_addr;
2217   
2218   if (-63 <= jump_distance && jump_distance <= 62)
2219     return 1;
2220   else if (-2046 <= jump_distance && jump_distance <= 2045)
2221     return 2;
2222   else if (AVR_HAVE_JMP_CALL)
2223     return 3;
2224   
2225   return 2;
2226 }
2227
2228 /* return an AVR condition jump commands.
2229    X is a comparison RTX.
2230    LEN is a number returned by avr_jump_mode function.
2231    if REVERSE nonzero then condition code in X must be reversed.  */
2232
2233 const char *
2234 ret_cond_branch (rtx x, int len, int reverse)
2235 {
2236   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2237   
2238   switch (cond)
2239     {
2240     case GT:
2241       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2242         return (len == 1 ? ("breq .+2" CR_TAB
2243                             "brpl %0") :
2244                 len == 2 ? ("breq .+4" CR_TAB
2245                             "brmi .+2" CR_TAB
2246                             "rjmp %0") :
2247                 ("breq .+6" CR_TAB
2248                  "brmi .+4" CR_TAB
2249                  "jmp %0"));
2250           
2251       else
2252         return (len == 1 ? ("breq .+2" CR_TAB
2253                             "brge %0") :
2254                 len == 2 ? ("breq .+4" CR_TAB
2255                             "brlt .+2" CR_TAB
2256                             "rjmp %0") :
2257                 ("breq .+6" CR_TAB
2258                  "brlt .+4" CR_TAB
2259                  "jmp %0"));
2260     case GTU:
2261       return (len == 1 ? ("breq .+2" CR_TAB
2262                           "brsh %0") :
2263               len == 2 ? ("breq .+4" CR_TAB
2264                           "brlo .+2" CR_TAB
2265                           "rjmp %0") :
2266               ("breq .+6" CR_TAB
2267                "brlo .+4" CR_TAB
2268                "jmp %0"));
2269     case LE:
2270       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2271         return (len == 1 ? ("breq %0" CR_TAB
2272                             "brmi %0") :
2273                 len == 2 ? ("breq .+2" CR_TAB
2274                             "brpl .+2" CR_TAB
2275                             "rjmp %0") :
2276                 ("breq .+2" CR_TAB
2277                  "brpl .+4" CR_TAB
2278                  "jmp %0"));
2279       else
2280         return (len == 1 ? ("breq %0" CR_TAB
2281                             "brlt %0") :
2282                 len == 2 ? ("breq .+2" CR_TAB
2283                             "brge .+2" CR_TAB
2284                             "rjmp %0") :
2285                 ("breq .+2" CR_TAB
2286                  "brge .+4" CR_TAB
2287                  "jmp %0"));
2288     case LEU:
2289       return (len == 1 ? ("breq %0" CR_TAB
2290                           "brlo %0") :
2291               len == 2 ? ("breq .+2" CR_TAB
2292                           "brsh .+2" CR_TAB
2293                           "rjmp %0") :
2294               ("breq .+2" CR_TAB
2295                "brsh .+4" CR_TAB
2296                "jmp %0"));
2297     default:
2298       if (reverse)
2299         {
2300           switch (len)
2301             {
2302             case 1:
2303               return "br%k1 %0";
2304             case 2:
2305               return ("br%j1 .+2" CR_TAB
2306                       "rjmp %0");
2307             default:
2308               return ("br%j1 .+4" CR_TAB
2309                       "jmp %0");
2310             }
2311         }
2312       else
2313         {
2314           switch (len)
2315             {
2316             case 1:
2317               return "br%j1 %0";
2318             case 2:
2319               return ("br%k1 .+2" CR_TAB
2320                       "rjmp %0");
2321             default:
2322               return ("br%k1 .+4" CR_TAB
2323                       "jmp %0");
2324             }
2325         }
2326     }
2327   return "";
2328 }
2329
2330 /* Output insn cost for next insn.  */
2331
2332 void
2333 final_prescan_insn (rtx insn, rtx *operand ATTRIBUTE_UNUSED,
2334                     int num_operands ATTRIBUTE_UNUSED)
2335 {
2336   if (avr_log.rtx_costs)
2337     {
2338       rtx set = single_set (insn);
2339
2340       if (set)
2341         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
2342                  set_src_cost (SET_SRC (set), optimize_insn_for_speed_p ()));
2343       else
2344         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
2345                  rtx_cost (PATTERN (insn), INSN, 0,
2346                            optimize_insn_for_speed_p()));
2347     }
2348 }
2349
2350 /* Return 0 if undefined, 1 if always true or always false.  */
2351
2352 int
2353 avr_simplify_comparison_p (enum machine_mode mode, RTX_CODE op, rtx x)
2354 {
2355   unsigned int max = (mode == QImode ? 0xff :
2356                       mode == HImode ? 0xffff :
2357                       mode == PSImode ? 0xffffff :
2358                       mode == SImode ? 0xffffffff : 0);
2359   if (max && op && GET_CODE (x) == CONST_INT)
2360     {
2361       if (unsigned_condition (op) != op)
2362         max >>= 1;
2363
2364       if (max != (INTVAL (x) & max)
2365           && INTVAL (x) != 0xff)
2366         return 1;
2367     }
2368   return 0;
2369 }
2370
2371
2372 /* Returns nonzero if REGNO is the number of a hard
2373    register in which function arguments are sometimes passed.  */
2374
2375 int
2376 function_arg_regno_p(int r)
2377 {
2378   return (r >= 8 && r <= 25);
2379 }
2380
2381 /* Initializing the variable cum for the state at the beginning
2382    of the argument list.  */
2383
2384 void
2385 init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2386                       tree fndecl ATTRIBUTE_UNUSED)
2387 {
2388   cum->nregs = 18;
2389   cum->regno = FIRST_CUM_REG;
2390   if (!libname && stdarg_p (fntype))
2391     cum->nregs = 0;
2392
2393   /* Assume the calle may be tail called */
2394   
2395   cfun->machine->sibcall_fails = 0;
2396 }
2397
2398 /* Returns the number of registers to allocate for a function argument.  */
2399
2400 static int
2401 avr_num_arg_regs (enum machine_mode mode, const_tree type)
2402 {
2403   int size;
2404
2405   if (mode == BLKmode)
2406     size = int_size_in_bytes (type);
2407   else
2408     size = GET_MODE_SIZE (mode);
2409
2410   /* Align all function arguments to start in even-numbered registers.
2411      Odd-sized arguments leave holes above them.  */
2412
2413   return (size + 1) & ~1;
2414 }
2415
2416 /* Controls whether a function argument is passed
2417    in a register, and which register.  */
2418
2419 static rtx
2420 avr_function_arg (cumulative_args_t cum_v, enum machine_mode mode,
2421                   const_tree type, bool named ATTRIBUTE_UNUSED)
2422 {
2423   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2424   int bytes = avr_num_arg_regs (mode, type);
2425
2426   if (cum->nregs && bytes <= cum->nregs)
2427     return gen_rtx_REG (mode, cum->regno - bytes);
2428
2429   return NULL_RTX;
2430 }
2431
2432 /* Update the summarizer variable CUM to advance past an argument
2433    in the argument list.  */
2434    
2435 static void
2436 avr_function_arg_advance (cumulative_args_t cum_v, enum machine_mode mode,
2437                           const_tree type, bool named ATTRIBUTE_UNUSED)
2438 {
2439   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2440   int bytes = avr_num_arg_regs (mode, type);
2441
2442   cum->nregs -= bytes;
2443   cum->regno -= bytes;
2444
2445   /* A parameter is being passed in a call-saved register. As the original
2446      contents of these regs has to be restored before leaving the function,
2447      a function must not pass arguments in call-saved regs in order to get
2448      tail-called. */
2449   
2450   if (cum->regno >= 8
2451       && cum->nregs >= 0
2452       && !call_used_regs[cum->regno])
2453     {
2454       /* FIXME: We ship info on failing tail-call in struct machine_function.
2455          This uses internals of calls.c:expand_call() and the way args_so_far
2456          is used. targetm.function_ok_for_sibcall() needs to be extended to
2457          pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
2458          dependent so that such an extension is not wanted. */
2459       
2460       cfun->machine->sibcall_fails = 1;
2461     }
2462
2463   /* Test if all registers needed by the ABI are actually available.  If the
2464      user has fixed a GPR needed to pass an argument, an (implicit) function
2465      call will clobber that fixed register.  See PR45099 for an example.  */
2466   
2467   if (cum->regno >= 8
2468       && cum->nregs >= 0)
2469     {
2470       int regno;
2471
2472       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2473         if (fixed_regs[regno])
2474           warning (0, "fixed register %s used to pass parameter to function",
2475                    reg_names[regno]);
2476     }
2477       
2478   if (cum->nregs <= 0)
2479     {
2480       cum->nregs = 0;
2481       cum->regno = FIRST_CUM_REG;
2482     }
2483 }
2484
2485 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2486 /* Decide whether we can make a sibling call to a function.  DECL is the
2487    declaration of the function being targeted by the call and EXP is the
2488    CALL_EXPR representing the call. */
2489
2490 static bool
2491 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2492 {
2493   tree fntype_callee;
2494
2495   /* Tail-calling must fail if callee-saved regs are used to pass
2496      function args.  We must not tail-call when `epilogue_restores'
2497      is used.  Unfortunately, we cannot tell at this point if that
2498      actually will happen or not, and we cannot step back from
2499      tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
2500   
2501   if (cfun->machine->sibcall_fails
2502       || TARGET_CALL_PROLOGUES)
2503     {
2504       return false;
2505     }
2506   
2507   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2508
2509   if (decl_callee)
2510     {
2511       decl_callee = TREE_TYPE (decl_callee);
2512     }
2513   else
2514     {
2515       decl_callee = fntype_callee;
2516       
2517       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2518              && METHOD_TYPE != TREE_CODE (decl_callee))
2519         {
2520           decl_callee = TREE_TYPE (decl_callee);
2521         }
2522     }
2523
2524   /* Ensure that caller and callee have compatible epilogues */
2525   
2526   if (cfun->machine->is_interrupt
2527       || cfun->machine->is_signal
2528       || cfun->machine->is_naked
2529       || avr_naked_function_p (decl_callee)
2530       /* FIXME: For OS_task and OS_main, we are over-conservative.
2531          This is due to missing documentation of these attributes
2532          and what they actually should do and should not do. */
2533       || (avr_OS_task_function_p (decl_callee)
2534           != cfun->machine->is_OS_task)
2535       || (avr_OS_main_function_p (decl_callee)
2536           != cfun->machine->is_OS_main))
2537     {
2538       return false;
2539     }
2540  
2541   return true;
2542 }
2543
2544 /***********************************************************************
2545   Functions for outputting various mov's for a various modes
2546 ************************************************************************/
2547
2548 /* Return true if a value of mode MODE is read from flash by
2549    __load_* function from libgcc.  */
2550
2551 bool
2552 avr_load_libgcc_p (rtx op)
2553 {
2554   enum machine_mode mode = GET_MODE (op);
2555   int n_bytes = GET_MODE_SIZE (mode);
2556         
2557   return (n_bytes > 2
2558           && !AVR_HAVE_LPMX
2559           && MEM_P (op)
2560           && MEM_ADDR_SPACE (op) == ADDR_SPACE_FLASH);
2561 }
2562
2563 /* Return true if a value of mode MODE is read by __xload_* function.  */
2564
2565 bool
2566 avr_xload_libgcc_p (enum machine_mode mode)
2567 {
2568   int n_bytes = GET_MODE_SIZE (mode);
2569   
2570   return (n_bytes > 1
2571           || avr_current_device->n_flash > 1);
2572 }
2573
2574
2575 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
2576    OP[1] in AS1 to register OP[0].
2577    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2578    Return "".  */
2579
2580 static const char*
2581 avr_out_lpm (rtx insn, rtx *op, int *plen)
2582 {
2583   rtx xop[3];
2584   rtx dest = op[0];
2585   rtx src = SET_SRC (single_set (insn));
2586   rtx addr;
2587   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
2588   RTX_CODE code;
2589   addr_space_t as = MEM_ADDR_SPACE (src);
2590
2591   if (plen)
2592     *plen = 0;
2593   
2594   if (MEM_P (dest))
2595     {
2596       warning (0, "writing to address space %qs not supported",
2597                avr_addrspace[MEM_ADDR_SPACE (dest)].name);
2598       
2599       return "";
2600     }
2601
2602   addr = XEXP (src, 0);
2603   code = GET_CODE (addr);
2604
2605   gcc_assert (REG_P (dest));
2606   gcc_assert (REG == code || POST_INC == code);
2607
2608   /* Only 1-byte moves from __flash are representes as open coded
2609      mov insns.  All other loads from flash are not handled here but
2610      by some UNSPEC instead, see respective FIXME in machine description.  */
2611   
2612   gcc_assert (as == ADDR_SPACE_FLASH);
2613   gcc_assert (n_bytes == 1);
2614
2615   xop[0] = dest;
2616   xop[1] = lpm_addr_reg_rtx;
2617   xop[2] = lpm_reg_rtx;
2618
2619   switch (code)
2620     {
2621     default:
2622       gcc_unreachable();
2623
2624     case REG:
2625
2626       gcc_assert (REG_Z == REGNO (addr));
2627       
2628       return AVR_HAVE_LPMX
2629         ? avr_asm_len ("lpm %0,%a1", xop, plen, 1)
2630         : avr_asm_len ("lpm" CR_TAB
2631                        "mov %0,%2", xop, plen, 2);
2632       
2633     case POST_INC:
2634       
2635       gcc_assert (REG_Z == REGNO (XEXP (addr, 0)));
2636
2637       return AVR_HAVE_LPMX
2638         ? avr_asm_len ("lpm %0,%a1+", xop, plen, 1)
2639         : avr_asm_len ("lpm"        CR_TAB
2640                        "adiw %1, 1" CR_TAB
2641                        "mov %0,%2", xop, plen, 3);
2642     }
2643
2644   return "";
2645 }
2646
2647
2648 /* If PLEN == NULL: Ouput instructions to load $0 with a value from
2649    flash address $1:Z.  If $1 = 0 we can use LPM to read, otherwise
2650    use ELPM.
2651    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
2652    Return "".  */
2653
2654 const char*
2655 avr_load_lpm (rtx insn, rtx *op, int *plen)
2656 {
2657   rtx xop[4];
2658   int n, n_bytes = GET_MODE_SIZE (GET_MODE (op[0]));
2659   rtx xsegment = op[1];
2660   bool clobber_z = PARALLEL == GET_CODE (PATTERN (insn));
2661   bool r30_in_tmp = false;
2662   
2663   if (plen)
2664     *plen = 0;
2665   
2666   xop[1] = lpm_addr_reg_rtx;
2667   xop[2] = lpm_reg_rtx;
2668   xop[3] = xstring_empty;
2669   
2670   /* Set RAMPZ as needed.  */
2671   
2672   if (REG_P (xsegment))
2673     {
2674       avr_asm_len ("out __RAMPZ__,%0", &xsegment, plen, 1);
2675       xop[3] = xstring_e;
2676     }
2677   
2678   /* Load the individual bytes from LSB to MSB.  */
2679   
2680   for (n = 0; n < n_bytes; n++)
2681     {
2682       xop[0] = all_regs_rtx[REGNO (op[0]) + n];
2683       
2684       if ((CONST_INT_P (xsegment) && AVR_HAVE_LPMX)
2685           || (REG_P (xsegment) && AVR_HAVE_ELPMX))
2686         {
2687           if (n == n_bytes-1)
2688             avr_asm_len ("%3lpm %0,%a1", xop, plen, 1);
2689           else if (REGNO (xop[0]) == REG_Z)
2690             {
2691               avr_asm_len ("%3lpm %2,%a1+", xop, plen, 1);
2692               r30_in_tmp = true;
2693             }
2694           else
2695             avr_asm_len ("%3lpm %0,%a1+", xop, plen, 1);
2696         }
2697       else
2698         {
2699           gcc_assert (clobber_z);
2700           
2701           avr_asm_len ("%3lpm" CR_TAB
2702                        "mov %0,%2", xop, plen, 2);
2703
2704           if (n != n_bytes-1)
2705             avr_asm_len ("adiw %1,1", xop, plen, 1);
2706         }
2707     }
2708   
2709   if (r30_in_tmp)
2710     avr_asm_len ("mov %1,%2", xop, plen, 1);
2711   
2712   if (!clobber_z
2713       && n_bytes > 1
2714       && !reg_unused_after (insn, lpm_addr_reg_rtx)
2715       && !reg_overlap_mentioned_p (op[0], lpm_addr_reg_rtx))
2716     {
2717       xop[2] = GEN_INT (n_bytes-1);
2718       avr_asm_len ("sbiw %1,%2", xop, plen, 1);
2719     }
2720   
2721   if (REG_P (xsegment) && AVR_HAVE_RAMPD)
2722     {
2723       /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM */
2724       
2725       avr_asm_len ("out __RAMPZ__,__zero_reg__", xop, plen, 1);
2726     }
2727
2728   return "";
2729 }
2730
2731
2732 /* Worker function for xload_8 insn.  */
2733
2734 const char*
2735 avr_out_xload (rtx insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
2736 {
2737   rtx xop[4];
2738
2739   xop[0] = op[0];
2740   xop[1] = op[1];
2741   xop[2] = lpm_addr_reg_rtx;
2742   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
2743
2744   if (plen)
2745     *plen = 0;
2746
2747   avr_asm_len ("sbrc %1,7" CR_TAB
2748                "ld %3,%a2" CR_TAB
2749                "sbrs %1,7", xop, plen, 3);
2750
2751   avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, 1);
2752
2753   if (REGNO (xop[0]) != REGNO (xop[3]))
2754     avr_asm_len ("mov %0,%3", xop, plen, 1);
2755   
2756   return "";
2757 }
2758
2759
2760 const char*
2761 output_movqi (rtx insn, rtx operands[], int *real_l)
2762 {
2763   rtx dest = operands[0];
2764   rtx src = operands[1];
2765   
2766   if (avr_mem_flash_p (src)
2767       || avr_mem_flash_p (dest))
2768     {
2769       return avr_out_lpm (insn, operands, real_l);
2770     }
2771
2772   if (real_l)
2773     *real_l = 1;
2774   
2775   if (register_operand (dest, QImode))
2776     {
2777       if (register_operand (src, QImode)) /* mov r,r */
2778         {
2779           if (test_hard_reg_class (STACK_REG, dest))
2780             return "out %0,%1";
2781           else if (test_hard_reg_class (STACK_REG, src))
2782             return "in %0,%1";
2783           
2784           return "mov %0,%1";
2785         }
2786       else if (CONSTANT_P (src))
2787         {
2788           output_reload_in_const (operands, NULL_RTX, real_l, false);
2789           return "";
2790         }
2791       else if (MEM_P (src))
2792         return out_movqi_r_mr (insn, operands, real_l); /* mov r,m */
2793     }
2794   else if (MEM_P (dest))
2795     {
2796       rtx xop[2];
2797
2798       xop[0] = dest;
2799       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2800
2801       return out_movqi_mr_r (insn, xop, real_l);
2802     }
2803   return "";
2804 }
2805
2806
2807 const char *
2808 output_movhi (rtx insn, rtx xop[], int *plen)
2809 {
2810   rtx dest = xop[0];
2811   rtx src = xop[1];
2812
2813   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
2814   
2815   if (avr_mem_flash_p (src)
2816       || avr_mem_flash_p (dest))
2817     {
2818       return avr_out_lpm (insn, xop, plen);
2819     }
2820
2821   if (REG_P (dest))
2822     {
2823       if (REG_P (src)) /* mov r,r */
2824         {
2825           if (test_hard_reg_class (STACK_REG, dest))
2826             {
2827               if (AVR_HAVE_8BIT_SP)
2828                 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
2829
2830               if (AVR_XMEGA)
2831                 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
2832                                     "out __SP_H__,%B1", xop, plen, -2);
2833               
2834               /* Use simple load of SP if no interrupts are  used.  */
2835               
2836               return TARGET_NO_INTERRUPTS
2837                 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
2838                                "out __SP_L__,%A1", xop, plen, -2)
2839
2840                 : avr_asm_len ("in __tmp_reg__,__SREG__"  CR_TAB
2841                                "cli"                      CR_TAB
2842                                "out __SP_H__,%B1"         CR_TAB
2843                                "out __SREG__,__tmp_reg__" CR_TAB
2844                                "out __SP_L__,%A1", xop, plen, -5);
2845             }
2846           else if (test_hard_reg_class (STACK_REG, src))
2847             {
2848               return !AVR_HAVE_SPH
2849                 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
2850                                "clr %B0", xop, plen, -2)
2851                 
2852                 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
2853                                "in %B0,__SP_H__", xop, plen, -2);
2854             }
2855
2856           return AVR_HAVE_MOVW
2857             ? avr_asm_len ("movw %0,%1", xop, plen, -1)
2858
2859             : avr_asm_len ("mov %A0,%A1" CR_TAB
2860                            "mov %B0,%B1", xop, plen, -2);
2861         } /* REG_P (src) */
2862       else if (CONSTANT_P (src))
2863         {
2864           return output_reload_inhi (xop, NULL, plen);
2865         }
2866       else if (MEM_P (src))
2867         {
2868           return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
2869         }
2870     }
2871   else if (MEM_P (dest))
2872     {
2873       rtx xop[2];
2874
2875       xop[0] = dest;
2876       xop[1] = src == const0_rtx ? zero_reg_rtx : src;
2877
2878       return out_movhi_mr_r (insn, xop, plen);
2879     }
2880   
2881   fatal_insn ("invalid insn:", insn);
2882   
2883   return "";
2884 }
2885
2886 static const char*
2887 out_movqi_r_mr (rtx insn, rtx op[], int *plen)
2888 {
2889   rtx dest = op[0];
2890   rtx src = op[1];
2891   rtx x = XEXP (src, 0);
2892   
2893   if (CONSTANT_ADDRESS_P (x))
2894     {
2895       return optimize > 0 && io_address_operand (x, QImode)
2896         ? avr_asm_len ("in %0,%i1", op, plen, -1)
2897         : avr_asm_len ("lds %0,%m1", op, plen, -2);
2898     }
2899   else if (GET_CODE (x) == PLUS
2900            && REG_P (XEXP (x, 0))
2901            && CONST_INT_P (XEXP (x, 1)))
2902     {
2903       /* memory access by reg+disp */
2904
2905       int disp = INTVAL (XEXP (x, 1));
2906       
2907       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
2908         {
2909           if (REGNO (XEXP (x, 0)) != REG_Y)
2910             fatal_insn ("incorrect insn:",insn);
2911
2912           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
2913             return avr_asm_len ("adiw r28,%o1-63" CR_TAB
2914                                 "ldd %0,Y+63"     CR_TAB
2915                                 "sbiw r28,%o1-63", op, plen, -3);
2916
2917           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
2918                               "sbci r29,hi8(-%o1)" CR_TAB
2919                               "ld %0,Y"            CR_TAB
2920                               "subi r28,lo8(%o1)"  CR_TAB
2921                               "sbci r29,hi8(%o1)", op, plen, -5);
2922         }
2923       else if (REGNO (XEXP (x, 0)) == REG_X)
2924         {
2925           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
2926              it but I have this situation with extremal optimizing options.  */
2927           
2928           avr_asm_len ("adiw r26,%o1" CR_TAB
2929                        "ld %0,X", op, plen, -2);
2930           
2931           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
2932               && !reg_unused_after (insn, XEXP (x,0)))
2933             {
2934               avr_asm_len ("sbiw r26,%o1", op, plen, 1);
2935             }
2936
2937           return "";
2938         }
2939
2940       return avr_asm_len ("ldd %0,%1", op, plen, -1);
2941     }
2942   
2943   return avr_asm_len ("ld %0,%1", op, plen, -1);
2944 }
2945
2946 static const char*
2947 out_movhi_r_mr (rtx insn, rtx op[], int *plen)
2948 {
2949   rtx dest = op[0];
2950   rtx src = op[1];
2951   rtx base = XEXP (src, 0);
2952   int reg_dest = true_regnum (dest);
2953   int reg_base = true_regnum (base);
2954   /* "volatile" forces reading low byte first, even if less efficient,
2955      for correct operation with 16-bit I/O registers.  */
2956   int mem_volatile_p = MEM_VOLATILE_P (src);
2957
2958   if (reg_base > 0)
2959     {
2960       if (reg_dest == reg_base)         /* R = (R) */
2961         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
2962                             "ld %B0,%1"          CR_TAB
2963                             "mov %A0,__tmp_reg__", op, plen, -3);
2964
2965       if (reg_base != REG_X)
2966         return avr_asm_len ("ld %A0,%1" CR_TAB
2967                             "ldd %B0,%1+1", op, plen, -2);
2968       
2969       avr_asm_len ("ld %A0,X+" CR_TAB
2970                    "ld %B0,X", op, plen, -2);
2971           
2972       if (!reg_unused_after (insn, base))
2973         avr_asm_len ("sbiw r26,1", op, plen, 1);
2974
2975       return "";
2976     }
2977   else if (GET_CODE (base) == PLUS) /* (R + i) */
2978     {
2979       int disp = INTVAL (XEXP (base, 1));
2980       int reg_base = true_regnum (XEXP (base, 0));
2981       
2982       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
2983         {
2984           if (REGNO (XEXP (base, 0)) != REG_Y)
2985             fatal_insn ("incorrect insn:",insn);
2986           
2987           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
2988             ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
2989                            "ldd %A0,Y+62"    CR_TAB
2990                            "ldd %B0,Y+63"    CR_TAB
2991                            "sbiw r28,%o1-62", op, plen, -4)
2992
2993             : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
2994                            "sbci r29,hi8(-%o1)" CR_TAB
2995                            "ld %A0,Y"           CR_TAB
2996                            "ldd %B0,Y+1"        CR_TAB
2997                            "subi r28,lo8(%o1)"  CR_TAB
2998                            "sbci r29,hi8(%o1)", op, plen, -6);
2999         }
3000
3001       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3002          it but I have this situation with extremal
3003          optimization options.  */
3004
3005       if (reg_base == REG_X)
3006         return reg_base == reg_dest
3007           ? avr_asm_len ("adiw r26,%o1"      CR_TAB
3008                          "ld __tmp_reg__,X+" CR_TAB
3009                          "ld %B0,X"          CR_TAB
3010                          "mov %A0,__tmp_reg__", op, plen, -4)
3011
3012           : avr_asm_len ("adiw r26,%o1" CR_TAB
3013                          "ld %A0,X+"    CR_TAB
3014                          "ld %B0,X"     CR_TAB
3015                          "sbiw r26,%o1+1", op, plen, -4);
3016
3017       return reg_base == reg_dest
3018         ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3019                        "ldd %B0,%B1"         CR_TAB
3020                        "mov %A0,__tmp_reg__", op, plen, -3)
3021
3022         : avr_asm_len ("ldd %A0,%A1" CR_TAB
3023                        "ldd %B0,%B1", op, plen, -2);
3024     }
3025   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3026     {
3027       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3028         fatal_insn ("incorrect insn:", insn);
3029
3030       if (!mem_volatile_p)
3031         return avr_asm_len ("ld %B0,%1" CR_TAB
3032                             "ld %A0,%1", op, plen, -2);
3033       
3034       return REGNO (XEXP (base, 0)) == REG_X
3035         ? avr_asm_len ("sbiw r26,2"  CR_TAB
3036                        "ld %A0,X+"   CR_TAB
3037                        "ld %B0,X"    CR_TAB
3038                        "sbiw r26,1", op, plen, -4)
3039         
3040         : avr_asm_len ("sbiw %r1,2"  CR_TAB
3041                        "ld %A0,%p1"  CR_TAB
3042                        "ldd %B0,%p1+1", op, plen, -3);
3043     }
3044   else if (GET_CODE (base) == POST_INC) /* (R++) */
3045     {
3046       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3047         fatal_insn ("incorrect insn:", insn);
3048
3049       return avr_asm_len ("ld %A0,%1"  CR_TAB
3050                           "ld %B0,%1", op, plen, -2);
3051     }
3052   else if (CONSTANT_ADDRESS_P (base))
3053     {
3054       return optimize > 0 && io_address_operand (base, HImode)
3055         ? avr_asm_len ("in %A0,%i1" CR_TAB
3056                        "in %B0,%i1+1", op, plen, -2)
3057
3058         : avr_asm_len ("lds %A0,%m1" CR_TAB
3059                        "lds %B0,%m1+1", op, plen, -4);
3060     }
3061   
3062   fatal_insn ("unknown move insn:",insn);
3063   return "";
3064 }
3065
3066 static const char*
3067 out_movsi_r_mr (rtx insn, rtx op[], int *l)
3068 {
3069   rtx dest = op[0];
3070   rtx src = op[1];
3071   rtx base = XEXP (src, 0);
3072   int reg_dest = true_regnum (dest);
3073   int reg_base = true_regnum (base);
3074   int tmp;
3075
3076   if (!l)
3077     l = &tmp;
3078   
3079   if (reg_base > 0)
3080     {
3081       if (reg_base == REG_X)        /* (R26) */
3082         {
3083           if (reg_dest == REG_X)
3084             /* "ld r26,-X" is undefined */
3085             return *l=7, ("adiw r26,3"        CR_TAB
3086                           "ld r29,X"          CR_TAB
3087                           "ld r28,-X"         CR_TAB
3088                           "ld __tmp_reg__,-X" CR_TAB
3089                           "sbiw r26,1"        CR_TAB
3090                           "ld r26,X"          CR_TAB
3091                           "mov r27,__tmp_reg__");
3092           else if (reg_dest == REG_X - 2)
3093             return *l=5, ("ld %A0,X+"          CR_TAB
3094                           "ld %B0,X+"          CR_TAB
3095                           "ld __tmp_reg__,X+"  CR_TAB
3096                           "ld %D0,X"           CR_TAB
3097                           "mov %C0,__tmp_reg__");
3098           else if (reg_unused_after (insn, base))
3099             return  *l=4, ("ld %A0,X+"  CR_TAB
3100                            "ld %B0,X+" CR_TAB
3101                            "ld %C0,X+" CR_TAB
3102                            "ld %D0,X");
3103           else
3104             return  *l=5, ("ld %A0,X+"  CR_TAB
3105                            "ld %B0,X+" CR_TAB
3106                            "ld %C0,X+" CR_TAB
3107                            "ld %D0,X"  CR_TAB
3108                            "sbiw r26,3");
3109         }
3110       else
3111         {
3112           if (reg_dest == reg_base)
3113             return *l=5, ("ldd %D0,%1+3" CR_TAB
3114                           "ldd %C0,%1+2" CR_TAB
3115                           "ldd __tmp_reg__,%1+1"  CR_TAB
3116                           "ld %A0,%1"  CR_TAB
3117                           "mov %B0,__tmp_reg__");
3118           else if (reg_base == reg_dest + 2)
3119             return *l=5, ("ld %A0,%1"             CR_TAB
3120                           "ldd %B0,%1+1"          CR_TAB
3121                           "ldd __tmp_reg__,%1+2"  CR_TAB
3122                           "ldd %D0,%1+3"          CR_TAB
3123                           "mov %C0,__tmp_reg__");
3124           else
3125             return *l=4, ("ld %A0,%1"    CR_TAB
3126                           "ldd %B0,%1+1" CR_TAB
3127                           "ldd %C0,%1+2" CR_TAB
3128                           "ldd %D0,%1+3");
3129         }
3130     }
3131   else if (GET_CODE (base) == PLUS) /* (R + i) */
3132     {
3133       int disp = INTVAL (XEXP (base, 1));
3134       
3135       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3136         {
3137           if (REGNO (XEXP (base, 0)) != REG_Y)
3138             fatal_insn ("incorrect insn:",insn);
3139
3140           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3141             return *l = 6, ("adiw r28,%o1-60" CR_TAB
3142                             "ldd %A0,Y+60"    CR_TAB
3143                             "ldd %B0,Y+61"    CR_TAB
3144                             "ldd %C0,Y+62"    CR_TAB
3145                             "ldd %D0,Y+63"    CR_TAB
3146                             "sbiw r28,%o1-60");
3147
3148           return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3149                           "sbci r29,hi8(-%o1)" CR_TAB
3150                           "ld %A0,Y"           CR_TAB
3151                           "ldd %B0,Y+1"        CR_TAB
3152                           "ldd %C0,Y+2"        CR_TAB
3153                           "ldd %D0,Y+3"        CR_TAB
3154                           "subi r28,lo8(%o1)"  CR_TAB
3155                           "sbci r29,hi8(%o1)");
3156         }
3157
3158       reg_base = true_regnum (XEXP (base, 0));
3159       if (reg_base == REG_X)
3160         {
3161           /* R = (X + d) */
3162           if (reg_dest == REG_X)
3163             {
3164               *l = 7;
3165               /* "ld r26,-X" is undefined */
3166               return ("adiw r26,%o1+3"    CR_TAB
3167                       "ld r29,X"          CR_TAB
3168                       "ld r28,-X"         CR_TAB
3169                       "ld __tmp_reg__,-X" CR_TAB
3170                       "sbiw r26,1"        CR_TAB
3171                       "ld r26,X"          CR_TAB
3172                       "mov r27,__tmp_reg__");
3173             }
3174           *l = 6;
3175           if (reg_dest == REG_X - 2)
3176             return ("adiw r26,%o1"      CR_TAB
3177                     "ld r24,X+"         CR_TAB
3178                     "ld r25,X+"         CR_TAB
3179                     "ld __tmp_reg__,X+" CR_TAB
3180                     "ld r27,X"          CR_TAB
3181                     "mov r26,__tmp_reg__");
3182
3183           return ("adiw r26,%o1" CR_TAB
3184                   "ld %A0,X+"    CR_TAB
3185                   "ld %B0,X+"    CR_TAB
3186                   "ld %C0,X+"    CR_TAB
3187                   "ld %D0,X"     CR_TAB
3188                   "sbiw r26,%o1+3");
3189         }
3190       if (reg_dest == reg_base)
3191         return *l=5, ("ldd %D0,%D1"          CR_TAB
3192                       "ldd %C0,%C1"          CR_TAB
3193                       "ldd __tmp_reg__,%B1"  CR_TAB
3194                       "ldd %A0,%A1"          CR_TAB
3195                       "mov %B0,__tmp_reg__");
3196       else if (reg_dest == reg_base - 2)
3197         return *l=5, ("ldd %A0,%A1"          CR_TAB
3198                       "ldd %B0,%B1"          CR_TAB
3199                       "ldd __tmp_reg__,%C1"  CR_TAB
3200                       "ldd %D0,%D1"          CR_TAB
3201                       "mov %C0,__tmp_reg__");
3202       return *l=4, ("ldd %A0,%A1" CR_TAB
3203                     "ldd %B0,%B1" CR_TAB
3204                     "ldd %C0,%C1" CR_TAB
3205                     "ldd %D0,%D1");
3206     }
3207   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3208     return *l=4, ("ld %D0,%1" CR_TAB
3209                   "ld %C0,%1" CR_TAB
3210                   "ld %B0,%1" CR_TAB
3211                   "ld %A0,%1");
3212   else if (GET_CODE (base) == POST_INC) /* (R++) */
3213     return *l=4, ("ld %A0,%1" CR_TAB
3214                   "ld %B0,%1" CR_TAB
3215                   "ld %C0,%1" CR_TAB
3216                   "ld %D0,%1");
3217   else if (CONSTANT_ADDRESS_P (base))
3218     return *l=8, ("lds %A0,%m1"   CR_TAB
3219                   "lds %B0,%m1+1" CR_TAB
3220                   "lds %C0,%m1+2" CR_TAB
3221                   "lds %D0,%m1+3");
3222     
3223   fatal_insn ("unknown move insn:",insn);
3224   return "";
3225 }
3226
3227 static const char*
3228 out_movsi_mr_r (rtx insn, rtx op[], int *l)
3229 {
3230   rtx dest = op[0];
3231   rtx src = op[1];
3232   rtx base = XEXP (dest, 0);
3233   int reg_base = true_regnum (base);
3234   int reg_src = true_regnum (src);
3235   int tmp;
3236   
3237   if (!l)
3238     l = &tmp;
3239   
3240   if (CONSTANT_ADDRESS_P (base))
3241     return *l=8,("sts %m0,%A1" CR_TAB
3242                  "sts %m0+1,%B1" CR_TAB
3243                  "sts %m0+2,%C1" CR_TAB
3244                  "sts %m0+3,%D1");
3245   if (reg_base > 0)                 /* (r) */
3246     {
3247       if (reg_base == REG_X)                /* (R26) */
3248         {
3249           if (reg_src == REG_X)
3250             {
3251               /* "st X+,r26" is undefined */
3252               if (reg_unused_after (insn, base))
3253                 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
3254                               "st X,r26"            CR_TAB
3255                               "adiw r26,1"          CR_TAB
3256                               "st X+,__tmp_reg__"   CR_TAB
3257                               "st X+,r28"           CR_TAB
3258                               "st X,r29");
3259               else
3260                 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
3261                               "st X,r26"            CR_TAB
3262                               "adiw r26,1"          CR_TAB
3263                               "st X+,__tmp_reg__"   CR_TAB
3264                               "st X+,r28"           CR_TAB
3265                               "st X,r29"            CR_TAB
3266                               "sbiw r26,3");
3267             }
3268           else if (reg_base == reg_src + 2)
3269             {
3270               if (reg_unused_after (insn, base))
3271                 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
3272                               "mov __tmp_reg__,%D1"  CR_TAB
3273                               "st %0+,%A1"           CR_TAB
3274                               "st %0+,%B1"           CR_TAB
3275                               "st %0+,__zero_reg__"  CR_TAB
3276                               "st %0,__tmp_reg__"    CR_TAB
3277                               "clr __zero_reg__");
3278               else
3279                 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
3280                               "mov __tmp_reg__,%D1"  CR_TAB
3281                               "st %0+,%A1"           CR_TAB
3282                               "st %0+,%B1"           CR_TAB
3283                               "st %0+,__zero_reg__"  CR_TAB
3284                               "st %0,__tmp_reg__"    CR_TAB
3285                               "clr __zero_reg__"     CR_TAB
3286                               "sbiw r26,3");
3287             }
3288           return *l=5, ("st %0+,%A1" CR_TAB
3289                         "st %0+,%B1" CR_TAB
3290                         "st %0+,%C1" CR_TAB
3291                         "st %0,%D1"  CR_TAB
3292                         "sbiw r26,3");
3293         }
3294       else
3295         return *l=4, ("st %0,%A1"    CR_TAB
3296                       "std %0+1,%B1" CR_TAB
3297                       "std %0+2,%C1" CR_TAB
3298                       "std %0+3,%D1");
3299     }
3300   else if (GET_CODE (base) == PLUS) /* (R + i) */
3301     {
3302       int disp = INTVAL (XEXP (base, 1));
3303       reg_base = REGNO (XEXP (base, 0));
3304       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
3305         {
3306           if (reg_base != REG_Y)
3307             fatal_insn ("incorrect insn:",insn);
3308
3309           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
3310             return *l = 6, ("adiw r28,%o0-60" CR_TAB
3311                             "std Y+60,%A1"    CR_TAB
3312                             "std Y+61,%B1"    CR_TAB
3313                             "std Y+62,%C1"    CR_TAB
3314                             "std Y+63,%D1"    CR_TAB
3315                             "sbiw r28,%o0-60");
3316
3317           return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
3318                           "sbci r29,hi8(-%o0)" CR_TAB
3319                           "st Y,%A1"           CR_TAB
3320                           "std Y+1,%B1"        CR_TAB
3321                           "std Y+2,%C1"        CR_TAB
3322                           "std Y+3,%D1"        CR_TAB
3323                           "subi r28,lo8(%o0)"  CR_TAB
3324                           "sbci r29,hi8(%o0)");
3325         }
3326       if (reg_base == REG_X)
3327         {
3328           /* (X + d) = R */
3329           if (reg_src == REG_X)
3330             {
3331               *l = 9;
3332               return ("mov __tmp_reg__,r26"  CR_TAB
3333                       "mov __zero_reg__,r27" CR_TAB
3334                       "adiw r26,%o0"         CR_TAB
3335                       "st X+,__tmp_reg__"    CR_TAB
3336                       "st X+,__zero_reg__"   CR_TAB
3337                       "st X+,r28"            CR_TAB
3338                       "st X,r29"             CR_TAB
3339                       "clr __zero_reg__"     CR_TAB
3340                       "sbiw r26,%o0+3");
3341             }
3342           else if (reg_src == REG_X - 2)
3343             {
3344               *l = 9;
3345               return ("mov __tmp_reg__,r26"  CR_TAB
3346                       "mov __zero_reg__,r27" CR_TAB
3347                       "adiw r26,%o0"         CR_TAB
3348                       "st X+,r24"            CR_TAB
3349                       "st X+,r25"            CR_TAB
3350                       "st X+,__tmp_reg__"    CR_TAB
3351                       "st X,__zero_reg__"    CR_TAB
3352                       "clr __zero_reg__"     CR_TAB
3353                       "sbiw r26,%o0+3");
3354             }
3355           *l = 6;
3356           return ("adiw r26,%o0" CR_TAB
3357                   "st X+,%A1"    CR_TAB
3358                   "st X+,%B1"    CR_TAB
3359                   "st X+,%C1"    CR_TAB
3360                   "st X,%D1"     CR_TAB
3361                   "sbiw r26,%o0+3");
3362         }
3363       return *l=4, ("std %A0,%A1" CR_TAB
3364                     "std %B0,%B1" CR_TAB
3365                     "std %C0,%C1" CR_TAB
3366                     "std %D0,%D1");
3367     }
3368   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3369     return *l=4, ("st %0,%D1" CR_TAB
3370                   "st %0,%C1" CR_TAB
3371                   "st %0,%B1" CR_TAB
3372                   "st %0,%A1");
3373   else if (GET_CODE (base) == POST_INC) /* (R++) */
3374     return *l=4, ("st %0,%A1" CR_TAB
3375                   "st %0,%B1" CR_TAB
3376                   "st %0,%C1" CR_TAB
3377                   "st %0,%D1");
3378   fatal_insn ("unknown move insn:",insn);
3379   return "";
3380 }
3381
3382 const char *
3383 output_movsisf (rtx insn, rtx operands[], int *l)
3384 {
3385   int dummy;
3386   rtx dest = operands[0];
3387   rtx src = operands[1];
3388   int *real_l = l;
3389   
3390   if (avr_mem_flash_p (src)
3391       || avr_mem_flash_p (dest))
3392     {
3393       return avr_out_lpm (insn, operands, real_l);
3394     }
3395
3396   if (!l)
3397     l = &dummy;
3398   
3399   if (register_operand (dest, VOIDmode))
3400     {
3401       if (register_operand (src, VOIDmode)) /* mov r,r */
3402         {
3403           if (true_regnum (dest) > true_regnum (src))
3404             {
3405               if (AVR_HAVE_MOVW)
3406                 {
3407                   *l = 2;
3408                   return ("movw %C0,%C1" CR_TAB
3409                           "movw %A0,%A1");
3410                 }
3411               *l = 4;
3412               return ("mov %D0,%D1" CR_TAB
3413                       "mov %C0,%C1" CR_TAB
3414                       "mov %B0,%B1" CR_TAB
3415                       "mov %A0,%A1");
3416             }
3417           else
3418             {
3419               if (AVR_HAVE_MOVW)
3420                 {
3421                   *l = 2;
3422                   return ("movw %A0,%A1" CR_TAB
3423                           "movw %C0,%C1");
3424                 }
3425               *l = 4;
3426               return ("mov %A0,%A1" CR_TAB
3427                       "mov %B0,%B1" CR_TAB
3428                       "mov %C0,%C1" CR_TAB
3429                       "mov %D0,%D1");
3430             }
3431         }
3432       else if (CONSTANT_P (src))
3433         {
3434           return output_reload_insisf (operands, NULL_RTX, real_l);
3435         }
3436       else if (GET_CODE (src) == MEM)
3437         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
3438     }
3439   else if (GET_CODE (dest) == MEM)
3440     {