61ff5156fddb118e0fc5e9e8767e3873947d55c1
[platform/upstream/linaro-gcc.git] / gcc / config / avr / avr.c
1 /* Subroutines for insn-output.c for ATMEL AVR micro controllers
2    Copyright (C) 1998-2016 Free Software Foundation, Inc.
3    Contributed by Denis Chertykov (chertykov@gmail.com)
4
5    This file is part of GCC.
6
7    GCC is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3, or (at your option)
10    any later version.
11    
12    GCC is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "backend.h"
25 #include "target.h"
26 #include "rtl.h"
27 #include "c-family/c-common.h"
28 #include "cfghooks.h"
29 #include "df.h"
30 #include "tm_p.h"
31 #include "optabs.h"
32 #include "regs.h"
33 #include "emit-rtl.h"
34 #include "recog.h"
35 #include "conditions.h"
36 #include "insn-attr.h"
37 #include "reload.h"
38 #include "varasm.h"
39 #include "calls.h"
40 #include "stor-layout.h"
41 #include "output.h"
42 #include "explow.h"
43 #include "expr.h"
44 #include "langhooks.h"
45 #include "cfgrtl.h"
46 #include "params.h"
47 #include "builtins.h"
48 #include "context.h"
49 #include "tree-pass.h"
50
51 /* This file should be included last.  */
52 #include "target-def.h"
53
54 /* Maximal allowed offset for an address in the LD command */
55 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
56
57 /* Return true if STR starts with PREFIX and false, otherwise.  */
58 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
59
60 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
61    address space where data is to be located.
62    As the only non-generic address spaces are all located in flash,
63    this can be used to test if data shall go into some .progmem* section.
64    This must be the rightmost field of machine dependent section flags.  */
65 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
66
67 /* Similar 4-bit region for SYMBOL_REF_FLAGS.  */
68 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
69
70 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
71    Set address-space AS in SYMBOL_REF_FLAGS of SYM  */
72 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS)                       \
73   do {                                                          \
74     SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM;         \
75     SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP;      \
76   } while (0)
77
78 /* Read address-space from SYMBOL_REF_FLAGS of SYM  */
79 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM)                          \
80   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
81    / SYMBOL_FLAG_MACH_DEP)
82
83 #define TINY_ADIW(REG1, REG2, I)                                \
84     "subi " #REG1 ",lo8(-(" #I "))" CR_TAB                      \
85     "sbci " #REG2 ",hi8(-(" #I "))"
86
87 #define TINY_SBIW(REG1, REG2, I)                                \
88     "subi " #REG1 ",lo8((" #I "))" CR_TAB                       \
89     "sbci " #REG2 ",hi8((" #I "))"
90
91 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
92 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
93
94 /* Known address spaces.  The order must be the same as in the respective
95    enum from avr.h (or designated initialized must be used).  */
96 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
97 {
98   { ADDR_SPACE_RAM,  0, 2, "", 0, NULL },
99   { ADDR_SPACE_FLASH,  1, 2, "__flash",   0, ".progmem.data" },
100   { ADDR_SPACE_FLASH1, 1, 2, "__flash1",  1, ".progmem1.data" },
101   { ADDR_SPACE_FLASH2, 1, 2, "__flash2",  2, ".progmem2.data" },
102   { ADDR_SPACE_FLASH3, 1, 2, "__flash3",  3, ".progmem3.data" },
103   { ADDR_SPACE_FLASH4, 1, 2, "__flash4",  4, ".progmem4.data" },
104   { ADDR_SPACE_FLASH5, 1, 2, "__flash5",  5, ".progmem5.data" },
105   { ADDR_SPACE_MEMX, 1, 3, "__memx",  0, ".progmemx.data" },
106 };
107
108
109 /* Holding RAM addresses of some SFRs used by the compiler and that
110    are unique over all devices in an architecture like 'avr4'.  */
111
112 typedef struct
113 {
114   /* SREG: The processor status */
115   int sreg;
116
117   /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
118   int ccp;
119   int rampd;
120   int rampx;
121   int rampy;
122
123   /* RAMPZ: The high byte of 24-bit address used with ELPM */
124   int rampz;
125
126   /* SP: The stack pointer and its low and high byte */
127   int sp_l;
128   int sp_h;
129 } avr_addr_t;
130
131 static avr_addr_t avr_addr;
132
133
134 /* Prototypes for local helper functions.  */
135
136 static const char* out_movqi_r_mr (rtx_insn *, rtx[], int*);
137 static const char* out_movhi_r_mr (rtx_insn *, rtx[], int*);
138 static const char* out_movsi_r_mr (rtx_insn *, rtx[], int*);
139 static const char* out_movqi_mr_r (rtx_insn *, rtx[], int*);
140 static const char* out_movhi_mr_r (rtx_insn *, rtx[], int*);
141 static const char* out_movsi_mr_r (rtx_insn *, rtx[], int*);
142
143 static int get_sequence_length (rtx_insn *insns);
144 static int sequent_regs_live (void);
145 static const char *ptrreg_to_str (int);
146 static const char *cond_string (enum rtx_code);
147 static int avr_num_arg_regs (machine_mode, const_tree);
148 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
149                                  int, bool);
150 static void output_reload_in_const (rtx*, rtx, int*, bool);
151 static struct machine_function * avr_init_machine_status (void);
152
153
154 /* Prototypes for hook implementors if needed before their implementation.  */
155
156 static bool avr_rtx_costs (rtx, machine_mode, int, int, int*, bool);
157
158
159 /* Allocate registers from r25 to r8 for parameters for function calls.  */
160 #define FIRST_CUM_REG 26
161
162 /* Last call saved register */
163 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? 19 : 17)
164
165 /* Implicit target register of LPM instruction (R0) */
166 extern GTY(()) rtx lpm_reg_rtx;
167 rtx lpm_reg_rtx;
168
169 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
170 extern GTY(()) rtx lpm_addr_reg_rtx;
171 rtx lpm_addr_reg_rtx;
172
173 /* Temporary register RTX (reg:QI TMP_REGNO) */
174 extern GTY(()) rtx tmp_reg_rtx;
175 rtx tmp_reg_rtx;
176
177 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
178 extern GTY(()) rtx zero_reg_rtx;
179 rtx zero_reg_rtx;
180
181 /* RTXs for all general purpose registers as QImode */
182 extern GTY(()) rtx all_regs_rtx[32];
183 rtx all_regs_rtx[32];
184
185 /* SREG, the processor status */
186 extern GTY(()) rtx sreg_rtx;
187 rtx sreg_rtx;
188
189 /* RAMP* special function registers */
190 extern GTY(()) rtx rampd_rtx;
191 extern GTY(()) rtx rampx_rtx;
192 extern GTY(()) rtx rampy_rtx;
193 extern GTY(()) rtx rampz_rtx;
194 rtx rampd_rtx;
195 rtx rampx_rtx;
196 rtx rampy_rtx;
197 rtx rampz_rtx;
198
199 /* RTX containing the strings "" and "e", respectively */
200 static GTY(()) rtx xstring_empty;
201 static GTY(()) rtx xstring_e;
202
203 /* Current architecture.  */
204 const avr_arch_t *avr_arch;
205
206 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
207    or to address space __flash* or __memx.  Only used as singletons inside
208    avr_asm_select_section, but it must not be local there because of GTY.  */
209 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
210
211 /* Condition for insns/expanders from avr-dimode.md.  */
212 bool avr_have_dimode = true;
213
214 /* To track if code will use .bss and/or .data.  */
215 bool avr_need_clear_bss_p = false;
216 bool avr_need_copy_data_p = false;
217
218 \f
219 /* Transform UP into lowercase and write the result to LO.
220    You must provide enough space for LO.  Return LO.  */
221
222 static char*
223 avr_tolower (char *lo, const char *up)
224 {
225   char *lo0 = lo;
226
227   for (; *up; up++, lo++)
228     *lo = TOLOWER (*up);
229
230   *lo = '\0';
231
232   return lo0;
233 }
234
235
236 /* Custom function to count number of set bits.  */
237
238 static inline int
239 avr_popcount (unsigned int val)
240 {
241   int pop = 0;
242
243   while (val)
244     {
245       val &= val-1;
246       pop++;
247     }
248
249   return pop;
250 }
251
252
253 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
254    Return true if the least significant N_BYTES bytes of XVAL all have a
255    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
256    of integers which contains an integer N iff bit N of POP_MASK is set.  */
257
258 bool
259 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
260 {
261   int i;
262
263   machine_mode mode = GET_MODE (xval);
264
265   if (VOIDmode == mode)
266     mode = SImode;
267
268   for (i = 0; i < n_bytes; i++)
269     {
270       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
271       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
272
273       if (0 == (pop_mask & (1 << avr_popcount (val8))))
274         return false;
275     }
276
277   return true;
278 }
279
280
281 /* Access some RTX as INT_MODE.  If X is a CONST_FIXED we can get
282    the bit representation of X by "casting" it to CONST_INT.  */
283
284 rtx
285 avr_to_int_mode (rtx x)
286 {
287   machine_mode mode = GET_MODE (x);
288
289   return VOIDmode == mode
290     ? x
291     : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
292 }
293
294
295 static const pass_data avr_pass_data_recompute_notes =
296 {
297   RTL_PASS,      // type
298   "",            // name (will be patched)
299   OPTGROUP_NONE, // optinfo_flags
300   TV_DF_SCAN,    // tv_id
301   0,             // properties_required
302   0,             // properties_provided
303   0,             // properties_destroyed
304   0,             // todo_flags_start
305   TODO_df_finish | TODO_df_verify // todo_flags_finish
306 };
307
308
309 class avr_pass_recompute_notes : public rtl_opt_pass
310 {
311 public:
312   avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
313     : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
314   {
315     this->name = name;
316   }
317
318   virtual unsigned int execute (function*)
319   {
320     df_note_add_problem ();
321     df_analyze ();
322
323     return 0;
324   }
325 }; // avr_pass_recompute_notes
326
327
328 static void
329 avr_register_passes (void)
330 {
331   /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD
332      notes which are used by `avr.c::reg_unused_after' and branch offset
333      computations.  These notes must be correct, i.e. there must be no
334      dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331.
335
336      DF needs (correct) CFG, hence right before free_cfg is the last
337      opportunity to rectify notes.  */
338
339   register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"),
340                  PASS_POS_INSERT_BEFORE, "*free_cfg", 1);
341 }
342
343
344 /* Set `avr_arch' as specified by `-mmcu='.
345    Return true on success.  */
346
347 static bool
348 avr_set_core_architecture (void)
349 {
350   /* Search for mcu core architecture.  */
351
352   if (!avr_mmcu)
353     avr_mmcu = AVR_MMCU_DEFAULT;
354
355   avr_arch = &avr_arch_types[0];
356
357   for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
358     {
359       if (NULL == mcu->name)
360         {
361           /* Reached the end of `avr_mcu_types'.  This should actually never
362              happen as options are provided by device-specs.  It could be a
363              typo in a device-specs or calling the compiler proper directly
364              with -mmcu=<device>. */
365
366           error ("unknown core architecture %qs specified with %qs",
367                  avr_mmcu, "-mmcu=");
368           avr_inform_core_architectures ();
369           break;
370         }
371       else if (0 == strcmp (mcu->name, avr_mmcu)
372                // Is this a proper architecture ? 
373                && NULL == mcu->macro)
374         {
375           avr_arch = &avr_arch_types[mcu->arch_id];
376           if (avr_n_flash < 0)
377             avr_n_flash = mcu->n_flash;
378
379           return true;
380         }
381     }
382
383   return false;
384 }
385
386
387 /* Implement `TARGET_OPTION_OVERRIDE'.  */
388
389 static void
390 avr_option_override (void)
391 {
392   /* Disable -fdelete-null-pointer-checks option for AVR target.
393      This option compiler assumes that dereferencing of a null pointer
394      would halt the program.  For AVR this assumption is not true and
395      programs can safely dereference null pointers.  Changes made by this
396      option may not work properly for AVR.  So disable this option. */
397
398   flag_delete_null_pointer_checks = 0;
399
400   /* caller-save.c looks for call-clobbered hard registers that are assigned
401      to pseudos that cross calls and tries so save-restore them around calls
402      in order to reduce the number of stack slots needed.
403
404      This might lead to situations where reload is no more able to cope
405      with the challenge of AVR's very few address registers and fails to
406      perform the requested spills.  */
407
408   if (avr_strict_X)
409     flag_caller_saves = 0;
410
411   /* Allow optimizer to introduce store data races. This used to be the
412      default - it was changed because bigger targets did not see any
413      performance decrease. For the AVR though, disallowing data races
414      introduces additional code in LIM and increases reg pressure.  */
415
416   maybe_set_param_value (PARAM_ALLOW_STORE_DATA_RACES, 1,
417       global_options.x_param_values,
418       global_options_set.x_param_values);
419
420   /* Unwind tables currently require a frame pointer for correctness,
421      see toplev.c:process_options().  */
422
423   if ((flag_unwind_tables
424        || flag_non_call_exceptions
425        || flag_asynchronous_unwind_tables)
426       && !ACCUMULATE_OUTGOING_ARGS)
427     {
428       flag_omit_frame_pointer = 0;
429     }
430
431   if (flag_pic == 1)
432     warning (OPT_fpic, "-fpic is not supported");
433   if (flag_pic == 2)
434     warning (OPT_fPIC, "-fPIC is not supported");
435   if (flag_pie == 1)
436     warning (OPT_fpie, "-fpie is not supported");
437   if (flag_pie == 2)
438     warning (OPT_fPIE, "-fPIE is not supported");
439
440   if (!avr_set_core_architecture())
441     return;
442
443   /* RAM addresses of some SFRs common to all devices in respective arch. */
444
445   /* SREG: Status Register containing flags like I (global IRQ) */
446   avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
447
448   /* RAMPZ: Address' high part when loading via ELPM */
449   avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
450
451   avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
452   avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
453   avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
454   avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
455
456   /* SP: Stack Pointer (SP_H:SP_L) */
457   avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
458   avr_addr.sp_h = avr_addr.sp_l + 1;
459
460   init_machine_status = avr_init_machine_status;
461
462   avr_log_set_avr_log();
463
464   /* Register some avr-specific pass(es).  There is no canonical place for
465      pass registration.  This function is convenient.  */
466
467   avr_register_passes ();
468 }
469
470 /* Function to set up the backend function structure.  */
471
472 static struct machine_function *
473 avr_init_machine_status (void)
474 {
475   return ggc_cleared_alloc<machine_function> ();
476 }
477
478
479 /* Implement `INIT_EXPANDERS'.  */
480 /* The function works like a singleton.  */
481
482 void
483 avr_init_expanders (void)
484 {
485   int regno;
486
487   for (regno = 0; regno < 32; regno ++)
488     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
489
490   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
491   tmp_reg_rtx  = all_regs_rtx[AVR_TMP_REGNO];
492   zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
493
494   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
495
496   sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
497   rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
498   rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
499   rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
500   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
501
502   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
503   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
504
505   /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
506      to be present */
507   if (AVR_TINY)
508     avr_have_dimode = false;
509 }
510
511
512 /* Implement `REGNO_REG_CLASS'.  */
513 /* Return register class for register R.  */
514
515 enum reg_class
516 avr_regno_reg_class (int r)
517 {
518   static const enum reg_class reg_class_tab[] =
519     {
520       R0_REG,
521       /* r1 - r15 */
522       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
523       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
524       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
525       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
526       /* r16 - r23 */
527       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
528       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
529       /* r24, r25 */
530       ADDW_REGS, ADDW_REGS,
531       /* X: r26, 27 */
532       POINTER_X_REGS, POINTER_X_REGS,
533       /* Y: r28, r29 */
534       POINTER_Y_REGS, POINTER_Y_REGS,
535       /* Z: r30, r31 */
536       POINTER_Z_REGS, POINTER_Z_REGS,
537       /* SP: SPL, SPH */
538       STACK_REG, STACK_REG
539     };
540
541   if (r <= 33)
542     return reg_class_tab[r];
543
544   return ALL_REGS;
545 }
546
547
548 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'.  */
549
550 static bool
551 avr_scalar_mode_supported_p (machine_mode mode)
552 {
553   if (ALL_FIXED_POINT_MODE_P (mode))
554     return true;
555
556   if (PSImode == mode)
557     return true;
558
559   return default_scalar_mode_supported_p (mode);
560 }
561
562
563 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise.  */
564
565 static bool
566 avr_decl_flash_p (tree decl)
567 {
568   if (TREE_CODE (decl) != VAR_DECL
569       || TREE_TYPE (decl) == error_mark_node)
570     {
571       return false;
572     }
573
574   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
575 }
576
577
578 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
579    address space and FALSE, otherwise.  */
580
581 static bool
582 avr_decl_memx_p (tree decl)
583 {
584   if (TREE_CODE (decl) != VAR_DECL
585       || TREE_TYPE (decl) == error_mark_node)
586     {
587       return false;
588     }
589
590   return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
591 }
592
593
594 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise.  */
595
596 bool
597 avr_mem_flash_p (rtx x)
598 {
599   return (MEM_P (x)
600           && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
601 }
602
603
604 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
605    address space and FALSE, otherwise.  */
606
607 bool
608 avr_mem_memx_p (rtx x)
609 {
610   return (MEM_P (x)
611           && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
612 }
613
614
615 /* A helper for the subsequent function attribute used to dig for
616    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
617
618 static inline int
619 avr_lookup_function_attribute1 (const_tree func, const char *name)
620 {
621   if (FUNCTION_DECL == TREE_CODE (func))
622     {
623       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
624         {
625           return true;
626         }
627
628       func = TREE_TYPE (func);
629     }
630
631   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
632               || TREE_CODE (func) == METHOD_TYPE);
633
634   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
635 }
636
637 /* Return nonzero if FUNC is a naked function.  */
638
639 static int
640 avr_naked_function_p (tree func)
641 {
642   return avr_lookup_function_attribute1 (func, "naked");
643 }
644
645 /* Return nonzero if FUNC is an interrupt function as specified
646    by the "interrupt" attribute.  */
647
648 static int
649 avr_interrupt_function_p (tree func)
650 {
651   return avr_lookup_function_attribute1 (func, "interrupt");
652 }
653
654 /* Return nonzero if FUNC is a signal function as specified
655    by the "signal" attribute.  */
656
657 static int
658 avr_signal_function_p (tree func)
659 {
660   return avr_lookup_function_attribute1 (func, "signal");
661 }
662
663 /* Return nonzero if FUNC is an OS_task function.  */
664
665 static int
666 avr_OS_task_function_p (tree func)
667 {
668   return avr_lookup_function_attribute1 (func, "OS_task");
669 }
670
671 /* Return nonzero if FUNC is an OS_main function.  */
672
673 static int
674 avr_OS_main_function_p (tree func)
675 {
676   return avr_lookup_function_attribute1 (func, "OS_main");
677 }
678
679
680 /* Implement `TARGET_SET_CURRENT_FUNCTION'.  */
681 /* Sanity cheching for above function attributes.  */
682
683 static void
684 avr_set_current_function (tree decl)
685 {
686   location_t loc;
687   const char *isr;
688
689   if (decl == NULL_TREE
690       || current_function_decl == NULL_TREE
691       || current_function_decl == error_mark_node
692       || ! cfun->machine
693       || cfun->machine->attributes_checked_p)
694     return;
695
696   loc = DECL_SOURCE_LOCATION (decl);
697
698   cfun->machine->is_naked = avr_naked_function_p (decl);
699   cfun->machine->is_signal = avr_signal_function_p (decl);
700   cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
701   cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
702   cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
703
704   isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
705
706   /* Too much attributes make no sense as they request conflicting features. */
707
708   if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
709       + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
710     error_at (loc, "function attributes %qs, %qs and %qs are mutually"
711                " exclusive", "OS_task", "OS_main", isr);
712
713   /* 'naked' will hide effects of 'OS_task' and 'OS_main'.  */
714
715   if (cfun->machine->is_naked
716       && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
717     warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
718                 " no effect on %qs function", "OS_task", "OS_main", "naked");
719
720   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
721     {
722       tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
723       tree ret = TREE_TYPE (TREE_TYPE (decl));
724       const char *name;
725
726       name = DECL_ASSEMBLER_NAME_SET_P (decl)
727         ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
728         : IDENTIFIER_POINTER (DECL_NAME (decl));
729
730       /* Skip a leading '*' that might still prefix the assembler name,
731          e.g. in non-LTO runs.  */
732
733       name = default_strip_name_encoding (name);
734
735       /* Silently ignore 'signal' if 'interrupt' is present.  AVR-LibC startet
736          using this when it switched from SIGNAL and INTERRUPT to ISR.  */
737
738       if (cfun->machine->is_interrupt)
739         cfun->machine->is_signal = 0;
740
741       /* Interrupt handlers must be  void __vector (void)  functions.  */
742
743       if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
744         error_at (loc, "%qs function cannot have arguments", isr);
745
746       if (TREE_CODE (ret) != VOID_TYPE)
747         error_at (loc, "%qs function cannot return a value", isr);
748
749       /* If the function has the 'signal' or 'interrupt' attribute, ensure
750          that the name of the function is "__vector_NN" so as to catch
751          when the user misspells the vector name.  */
752
753       if (!STR_PREFIX_P (name, "__vector"))
754         warning_at (loc, 0, "%qs appears to be a misspelled %s handler",
755                     name, isr);
756     }
757
758   /* Don't print the above diagnostics more than once.  */
759
760   cfun->machine->attributes_checked_p = 1;
761 }
762
763
764 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
765
766 int
767 avr_accumulate_outgoing_args (void)
768 {
769   if (!cfun)
770     return TARGET_ACCUMULATE_OUTGOING_ARGS;
771
772   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
773         what offset is correct.  In some cases it is relative to
774         virtual_outgoing_args_rtx and in others it is relative to
775         virtual_stack_vars_rtx.  For example code see
776             gcc.c-torture/execute/built-in-setjmp.c
777             gcc.c-torture/execute/builtins/sprintf-chk.c   */
778
779   return (TARGET_ACCUMULATE_OUTGOING_ARGS
780           && !(cfun->calls_setjmp
781                || cfun->has_nonlocal_label));
782 }
783
784
785 /* Report contribution of accumulated outgoing arguments to stack size.  */
786
787 static inline int
788 avr_outgoing_args_size (void)
789 {
790   return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
791 }
792
793
794 /* Implement `STARTING_FRAME_OFFSET'.  */
795 /* This is the offset from the frame pointer register to the first stack slot
796    that contains a variable living in the frame.  */
797
798 int
799 avr_starting_frame_offset (void)
800 {
801   return 1 + avr_outgoing_args_size ();
802 }
803
804
805 /* Return the number of hard registers to push/pop in the prologue/epilogue
806    of the current function, and optionally store these registers in SET.  */
807
808 static int
809 avr_regs_to_save (HARD_REG_SET *set)
810 {
811   int reg, count;
812   int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
813
814   if (set)
815     CLEAR_HARD_REG_SET (*set);
816   count = 0;
817
818   /* No need to save any registers if the function never returns or
819      has the "OS_task" or "OS_main" attribute.  */
820
821   if (TREE_THIS_VOLATILE (current_function_decl)
822       || cfun->machine->is_OS_task
823       || cfun->machine->is_OS_main)
824     return 0;
825
826   for (reg = 0; reg < 32; reg++)
827     {
828       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
829          any global register variables.  */
830
831       if (fixed_regs[reg])
832         continue;
833
834       if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
835           || (df_regs_ever_live_p (reg)
836               && (int_or_sig_p || !call_used_regs[reg])
837               /* Don't record frame pointer registers here.  They are treated
838                  indivitually in prologue.  */
839               && !(frame_pointer_needed
840                    && (reg == REG_Y || reg == (REG_Y+1)))))
841         {
842           if (set)
843             SET_HARD_REG_BIT (*set, reg);
844           count++;
845         }
846     }
847   return count;
848 }
849
850
851 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
852
853 static bool
854 avr_allocate_stack_slots_for_args (void)
855 {
856   return !cfun->machine->is_naked;
857 }
858
859
860 /* Return true if register FROM can be eliminated via register TO.  */
861
862 static bool
863 avr_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
864 {
865   return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
866           || !frame_pointer_needed);
867 }
868
869
870 /* Implement `TARGET_WARN_FUNC_RETURN'.  */
871
872 static bool
873 avr_warn_func_return (tree decl)
874 {
875   /* Naked functions are implemented entirely in assembly, including the
876      return sequence, so suppress warnings about this.  */
877
878   return !avr_naked_function_p (decl);
879 }
880
881 /* Compute offset between arg_pointer and frame_pointer.  */
882
883 int
884 avr_initial_elimination_offset (int from, int to)
885 {
886   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
887     return 0;
888   else
889     {
890       int offset = frame_pointer_needed ? 2 : 0;
891       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
892
893       offset += avr_regs_to_save (NULL);
894       return (get_frame_size () + avr_outgoing_args_size()
895               + avr_pc_size + 1 + offset);
896     }
897 }
898
899
900 /* Helper for the function below.  */
901
902 static void
903 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
904 {
905   *node = make_node (FIXED_POINT_TYPE);
906   TYPE_SATURATING (*node) = sat_p;
907   TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
908   TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
909   TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
910   TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
911   TYPE_ALIGN (*node) = 8;
912   SET_TYPE_MODE (*node, mode);
913
914   layout_type (*node);
915 }
916
917
918 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'.  */
919
920 static tree
921 avr_build_builtin_va_list (void)
922 {
923   /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
924      This is more appropriate for the 8-bit machine AVR than 128-bit modes.
925      The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
926      which is auto-generated by genmodes, but the compiler assigns [U]DAmode
927      to the long long accum modes instead of the desired [U]TAmode.
928
929      Fix this now, right after node setup in tree.c:build_common_tree_nodes().
930      This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
931      which built-in defines macros like __ULLACCUM_FBIT__ that are used by
932      libgcc to detect IBIT and FBIT.  */
933
934   avr_adjust_type_node (&ta_type_node, TAmode, 0);
935   avr_adjust_type_node (&uta_type_node, UTAmode, 0);
936   avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
937   avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
938
939   unsigned_long_long_accum_type_node = uta_type_node;
940   long_long_accum_type_node = ta_type_node;
941   sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
942   sat_long_long_accum_type_node = sat_ta_type_node;
943
944   /* Dispatch to the default handler.  */
945
946   return std_build_builtin_va_list ();
947 }
948
949
950 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'.  */
951 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
952    frame pointer by +STARTING_FRAME_OFFSET.
953    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
954    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
955
956 static rtx
957 avr_builtin_setjmp_frame_value (void)
958 {
959   rtx xval = gen_reg_rtx (Pmode);
960   emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
961                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
962   return xval;
963 }
964
965
966 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
967    This is return address of function.  */
968
969 rtx
970 avr_return_addr_rtx (int count, rtx tem)
971 {
972   rtx r;
973
974   /* Can only return this function's return address. Others not supported.  */
975   if (count)
976      return NULL;
977
978   if (AVR_3_BYTE_PC)
979     {
980       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
981       warning (0, "%<builtin_return_address%> contains only 2 bytes"
982                " of address");
983     }
984   else
985     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
986
987   r = gen_rtx_PLUS (Pmode, tem, r);
988   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
989   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
990   return  r;
991 }
992
993 /* Return 1 if the function epilogue is just a single "ret".  */
994
995 int
996 avr_simple_epilogue (void)
997 {
998   return (! frame_pointer_needed
999           && get_frame_size () == 0
1000           && avr_outgoing_args_size() == 0
1001           && avr_regs_to_save (NULL) == 0
1002           && ! cfun->machine->is_interrupt
1003           && ! cfun->machine->is_signal
1004           && ! cfun->machine->is_naked
1005           && ! TREE_THIS_VOLATILE (current_function_decl));
1006 }
1007
1008 /* This function checks sequence of live registers.  */
1009
1010 static int
1011 sequent_regs_live (void)
1012 {
1013   int reg;
1014   int live_seq = 0;
1015   int cur_seq = 0;
1016
1017   for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
1018     {
1019       if (fixed_regs[reg])
1020         {
1021           /* Don't recognize sequences that contain global register
1022              variables.  */
1023
1024           if (live_seq != 0)
1025             return 0;
1026           else
1027             continue;
1028         }
1029
1030       if (!call_used_regs[reg])
1031         {
1032           if (df_regs_ever_live_p (reg))
1033             {
1034               ++live_seq;
1035               ++cur_seq;
1036             }
1037           else
1038             cur_seq = 0;
1039         }
1040     }
1041
1042   if (!frame_pointer_needed)
1043     {
1044       if (df_regs_ever_live_p (REG_Y))
1045         {
1046           ++live_seq;
1047           ++cur_seq;
1048         }
1049       else
1050         cur_seq = 0;
1051
1052       if (df_regs_ever_live_p (REG_Y+1))
1053         {
1054           ++live_seq;
1055           ++cur_seq;
1056         }
1057       else
1058         cur_seq = 0;
1059     }
1060   else
1061     {
1062       cur_seq += 2;
1063       live_seq += 2;
1064     }
1065   return (cur_seq == live_seq) ? live_seq : 0;
1066 }
1067
1068 /* Obtain the length sequence of insns.  */
1069
1070 int
1071 get_sequence_length (rtx_insn *insns)
1072 {
1073   rtx_insn *insn;
1074   int length;
1075
1076   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
1077     length += get_attr_length (insn);
1078
1079   return length;
1080 }
1081
1082
1083 /*  Implement `INCOMING_RETURN_ADDR_RTX'.  */
1084
1085 rtx
1086 avr_incoming_return_addr_rtx (void)
1087 {
1088   /* The return address is at the top of the stack.  Note that the push
1089      was via post-decrement, which means the actual address is off by one.  */
1090   return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
1091 }
1092
1093 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
1094
1095 static void
1096 emit_push_byte (unsigned regno, bool frame_related_p)
1097 {
1098   rtx mem, reg;
1099   rtx_insn *insn;
1100
1101   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
1102   mem = gen_frame_mem (QImode, mem);
1103   reg = gen_rtx_REG (QImode, regno);
1104
1105   insn = emit_insn (gen_rtx_SET (mem, reg));
1106   if (frame_related_p)
1107     RTX_FRAME_RELATED_P (insn) = 1;
1108
1109   cfun->machine->stack_usage++;
1110 }
1111
1112
1113 /*  Helper for expand_prologue.  Emit a push of a SFR via tmp_reg.
1114     SFR is a MEM representing the memory location of the SFR.
1115     If CLR_P then clear the SFR after the push using zero_reg.  */
1116
1117 static void
1118 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
1119 {
1120   rtx_insn *insn;
1121
1122   gcc_assert (MEM_P (sfr));
1123
1124   /* IN __tmp_reg__, IO(SFR) */
1125   insn = emit_move_insn (tmp_reg_rtx, sfr);
1126   if (frame_related_p)
1127     RTX_FRAME_RELATED_P (insn) = 1;
1128
1129   /* PUSH __tmp_reg__ */
1130   emit_push_byte (AVR_TMP_REGNO, frame_related_p);
1131
1132   if (clr_p)
1133     {
1134       /* OUT IO(SFR), __zero_reg__ */
1135       insn = emit_move_insn (sfr, const0_rtx);
1136       if (frame_related_p)
1137         RTX_FRAME_RELATED_P (insn) = 1;
1138     }
1139 }
1140
1141 static void
1142 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1143 {
1144   rtx_insn *insn;
1145   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1146   int live_seq = sequent_regs_live ();
1147
1148   HOST_WIDE_INT size_max
1149     = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1150
1151   bool minimize = (TARGET_CALL_PROLOGUES
1152                    && size < size_max
1153                    && live_seq
1154                    && !isr_p
1155                    && !cfun->machine->is_OS_task
1156                    && !cfun->machine->is_OS_main
1157                    && !AVR_TINY);
1158
1159   if (minimize
1160       && (frame_pointer_needed
1161           || avr_outgoing_args_size() > 8
1162           || (AVR_2_BYTE_PC && live_seq > 6)
1163           || live_seq > 7))
1164     {
1165       rtx pattern;
1166       int first_reg, reg, offset;
1167
1168       emit_move_insn (gen_rtx_REG (HImode, REG_X),
1169                       gen_int_mode (size, HImode));
1170
1171       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1172                                          gen_int_mode (live_seq+size, HImode));
1173       insn = emit_insn (pattern);
1174       RTX_FRAME_RELATED_P (insn) = 1;
1175
1176       /* Describe the effect of the unspec_volatile call to prologue_saves.
1177          Note that this formulation assumes that add_reg_note pushes the
1178          notes to the front.  Thus we build them in the reverse order of
1179          how we want dwarf2out to process them.  */
1180
1181       /* The function does always set frame_pointer_rtx, but whether that
1182          is going to be permanent in the function is frame_pointer_needed.  */
1183
1184       add_reg_note (insn, REG_CFA_ADJUST_CFA,
1185                     gen_rtx_SET ((frame_pointer_needed
1186                                   ? frame_pointer_rtx
1187                                   : stack_pointer_rtx),
1188                                  plus_constant (Pmode, stack_pointer_rtx,
1189                                                 -(size + live_seq))));
1190
1191       /* Note that live_seq always contains r28+r29, but the other
1192          registers to be saved are all below 18.  */
1193
1194       first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
1195
1196       for (reg = 29, offset = -live_seq + 1;
1197            reg >= first_reg;
1198            reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
1199         {
1200           rtx m, r;
1201
1202           m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1203                                                   offset));
1204           r = gen_rtx_REG (QImode, reg);
1205           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
1206         }
1207
1208       cfun->machine->stack_usage += size + live_seq;
1209     }
1210   else /* !minimize */
1211     {
1212       int reg;
1213
1214       for (reg = 0; reg < 32; ++reg)
1215         if (TEST_HARD_REG_BIT (set, reg))
1216           emit_push_byte (reg, true);
1217
1218       if (frame_pointer_needed
1219           && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1220         {
1221           /* Push frame pointer.  Always be consistent about the
1222              ordering of pushes -- epilogue_restores expects the
1223              register pair to be pushed low byte first.  */
1224
1225           emit_push_byte (REG_Y, true);
1226           emit_push_byte (REG_Y + 1, true);
1227         }
1228
1229       if (frame_pointer_needed
1230           && size == 0)
1231         {
1232           insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1233           RTX_FRAME_RELATED_P (insn) = 1;
1234         }
1235
1236       if (size != 0)
1237         {
1238           /*  Creating a frame can be done by direct manipulation of the
1239               stack or via the frame pointer. These two methods are:
1240                   fp =  sp
1241                   fp -= size
1242                   sp =  fp
1243               or
1244                   sp -= size
1245                   fp =  sp    (*)
1246               the optimum method depends on function type, stack and
1247               frame size.  To avoid a complex logic, both methods are
1248               tested and shortest is selected.
1249
1250               There is also the case where SIZE != 0 and no frame pointer is
1251               needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1252               In that case, insn (*) is not needed in that case.
1253               We use the X register as scratch. This is save because in X
1254               is call-clobbered.
1255                  In an interrupt routine, the case of SIZE != 0 together with
1256               !frame_pointer_needed can only occur if the function is not a
1257               leaf function and thus X has already been saved.  */
1258
1259           int irq_state = -1;
1260           HOST_WIDE_INT size_cfa = size, neg_size;
1261           rtx_insn *fp_plus_insns;
1262           rtx fp, my_fp;
1263
1264           gcc_assert (frame_pointer_needed
1265                       || !isr_p
1266                       || !crtl->is_leaf);
1267
1268           fp = my_fp = (frame_pointer_needed
1269                         ? frame_pointer_rtx
1270                         : gen_rtx_REG (Pmode, REG_X));
1271
1272           if (AVR_HAVE_8BIT_SP)
1273             {
1274               /* The high byte (r29) does not change:
1275                  Prefer SUBI (1 cycle) over SBIW (2 cycles, same size).  */
1276
1277               my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1278             }
1279
1280           /* Cut down size and avoid size = 0 so that we don't run
1281              into ICE like PR52488 in the remainder.  */
1282
1283           if (size > size_max)
1284             {
1285               /* Don't error so that insane code from newlib still compiles
1286                  and does not break building newlib.  As PR51345 is implemented
1287                  now, there are multilib variants with -msp8.
1288
1289                  If user wants sanity checks he can use -Wstack-usage=
1290                  or similar options.
1291
1292                  For CFA we emit the original, non-saturated size so that
1293                  the generic machinery is aware of the real stack usage and
1294                  will print the above diagnostic as expected.  */
1295
1296               size = size_max;
1297             }
1298
1299           size = trunc_int_for_mode (size, GET_MODE (my_fp));
1300           neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1301
1302           /************  Method 1: Adjust frame pointer  ************/
1303
1304           start_sequence ();
1305
1306           /* Normally, the dwarf2out frame-related-expr interpreter does
1307              not expect to have the CFA change once the frame pointer is
1308              set up.  Thus, we avoid marking the move insn below and
1309              instead indicate that the entire operation is complete after
1310              the frame pointer subtraction is done.  */
1311
1312           insn = emit_move_insn (fp, stack_pointer_rtx);
1313           if (frame_pointer_needed)
1314             {
1315               RTX_FRAME_RELATED_P (insn) = 1;
1316               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1317                             gen_rtx_SET (fp, stack_pointer_rtx));
1318             }
1319
1320           insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1321                                                        my_fp, neg_size));
1322
1323           if (frame_pointer_needed)
1324             {
1325               RTX_FRAME_RELATED_P (insn) = 1;
1326               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1327                             gen_rtx_SET (fp, plus_constant (Pmode, fp,
1328                                                             -size_cfa)));
1329             }
1330
1331           /* Copy to stack pointer.  Note that since we've already
1332              changed the CFA to the frame pointer this operation
1333              need not be annotated if frame pointer is needed.
1334              Always move through unspec, see PR50063.
1335              For meaning of irq_state see movhi_sp_r insn.  */
1336
1337           if (cfun->machine->is_interrupt)
1338             irq_state = 1;
1339
1340           if (TARGET_NO_INTERRUPTS
1341               || cfun->machine->is_signal
1342               || cfun->machine->is_OS_main)
1343             irq_state = 0;
1344
1345           if (AVR_HAVE_8BIT_SP)
1346             irq_state = 2;
1347
1348           insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1349                                             fp, GEN_INT (irq_state)));
1350           if (!frame_pointer_needed)
1351             {
1352               RTX_FRAME_RELATED_P (insn) = 1;
1353               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1354                             gen_rtx_SET (stack_pointer_rtx,
1355                                          plus_constant (Pmode,
1356                                                         stack_pointer_rtx,
1357                                                         -size_cfa)));
1358             }
1359
1360           fp_plus_insns = get_insns ();
1361           end_sequence ();
1362
1363           /************  Method 2: Adjust Stack pointer  ************/
1364
1365           /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1366              can only handle specific offsets.  */
1367
1368           if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1369             {
1370               rtx_insn *sp_plus_insns;
1371
1372               start_sequence ();
1373
1374               insn = emit_move_insn (stack_pointer_rtx,
1375                                      plus_constant (Pmode, stack_pointer_rtx,
1376                                                     -size));
1377               RTX_FRAME_RELATED_P (insn) = 1;
1378               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1379                             gen_rtx_SET (stack_pointer_rtx,
1380                                          plus_constant (Pmode,
1381                                                         stack_pointer_rtx,
1382                                                         -size_cfa)));
1383               if (frame_pointer_needed)
1384                 {
1385                   insn = emit_move_insn (fp, stack_pointer_rtx);
1386                   RTX_FRAME_RELATED_P (insn) = 1;
1387                 }
1388
1389               sp_plus_insns = get_insns ();
1390               end_sequence ();
1391
1392               /************ Use shortest method  ************/
1393
1394               emit_insn (get_sequence_length (sp_plus_insns)
1395                          < get_sequence_length (fp_plus_insns)
1396                          ? sp_plus_insns
1397                          : fp_plus_insns);
1398             }
1399           else
1400             {
1401               emit_insn (fp_plus_insns);
1402             }
1403
1404           cfun->machine->stack_usage += size_cfa;
1405         } /* !minimize && size != 0 */
1406     } /* !minimize */
1407 }
1408
1409
1410 /*  Output function prologue.  */
1411
1412 void
1413 avr_expand_prologue (void)
1414 {
1415   HARD_REG_SET set;
1416   HOST_WIDE_INT size;
1417
1418   size = get_frame_size() + avr_outgoing_args_size();
1419
1420   cfun->machine->stack_usage = 0;
1421
1422   /* Prologue: naked.  */
1423   if (cfun->machine->is_naked)
1424     {
1425       return;
1426     }
1427
1428   avr_regs_to_save (&set);
1429
1430   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1431     {
1432       /* Enable interrupts.  */
1433       if (cfun->machine->is_interrupt)
1434         emit_insn (gen_enable_interrupt ());
1435
1436       /* Push zero reg.  */
1437       emit_push_byte (AVR_ZERO_REGNO, true);
1438
1439       /* Push tmp reg.  */
1440       emit_push_byte (AVR_TMP_REGNO, true);
1441
1442       /* Push SREG.  */
1443       /* ??? There's no dwarf2 column reserved for SREG.  */
1444       emit_push_sfr (sreg_rtx, false, false /* clr */);
1445
1446       /* Clear zero reg.  */
1447       emit_move_insn (zero_reg_rtx, const0_rtx);
1448
1449       /* Prevent any attempt to delete the setting of ZERO_REG!  */
1450       emit_use (zero_reg_rtx);
1451
1452       /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1453          ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z.  */
1454
1455       if (AVR_HAVE_RAMPD)
1456         emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1457
1458       if (AVR_HAVE_RAMPX
1459           && TEST_HARD_REG_BIT (set, REG_X)
1460           && TEST_HARD_REG_BIT (set, REG_X + 1))
1461         {
1462           emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1463         }
1464
1465       if (AVR_HAVE_RAMPY
1466           && (frame_pointer_needed
1467               || (TEST_HARD_REG_BIT (set, REG_Y)
1468                   && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1469         {
1470           emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1471         }
1472
1473       if (AVR_HAVE_RAMPZ
1474           && TEST_HARD_REG_BIT (set, REG_Z)
1475           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1476         {
1477           emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1478         }
1479     }  /* is_interrupt is_signal */
1480
1481   avr_prologue_setup_frame (size, set);
1482
1483   if (flag_stack_usage_info)
1484     current_function_static_stack_size = cfun->machine->stack_usage;
1485 }
1486
1487
1488 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'.  */
1489 /* Output summary at end of function prologue.  */
1490
1491 static void
1492 avr_asm_function_end_prologue (FILE *file)
1493 {
1494   if (cfun->machine->is_naked)
1495     {
1496       fputs ("/* prologue: naked */\n", file);
1497     }
1498   else
1499     {
1500       if (cfun->machine->is_interrupt)
1501         {
1502           fputs ("/* prologue: Interrupt */\n", file);
1503         }
1504       else if (cfun->machine->is_signal)
1505         {
1506           fputs ("/* prologue: Signal */\n", file);
1507         }
1508       else
1509         fputs ("/* prologue: function */\n", file);
1510     }
1511
1512   if (ACCUMULATE_OUTGOING_ARGS)
1513     fprintf (file, "/* outgoing args size = %d */\n",
1514              avr_outgoing_args_size());
1515
1516   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1517                  get_frame_size());
1518   fprintf (file, "/* stack size = %d */\n",
1519                  cfun->machine->stack_usage);
1520   /* Create symbol stack offset here so all functions have it. Add 1 to stack
1521      usage for offset so that SP + .L__stack_offset = return address.  */
1522   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1523 }
1524
1525
1526 /* Implement `EPILOGUE_USES'.  */
1527
1528 int
1529 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1530 {
1531   if (reload_completed
1532       && cfun->machine
1533       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1534     return 1;
1535   return 0;
1536 }
1537
1538 /*  Helper for avr_expand_epilogue.  Emit a pop of a byte register.  */
1539
1540 static void
1541 emit_pop_byte (unsigned regno)
1542 {
1543   rtx mem, reg;
1544
1545   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1546   mem = gen_frame_mem (QImode, mem);
1547   reg = gen_rtx_REG (QImode, regno);
1548
1549   emit_insn (gen_rtx_SET (reg, mem));
1550 }
1551
1552 /*  Output RTL epilogue.  */
1553
1554 void
1555 avr_expand_epilogue (bool sibcall_p)
1556 {
1557   int reg;
1558   int live_seq;
1559   HARD_REG_SET set;
1560   int minimize;
1561   HOST_WIDE_INT size;
1562   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1563
1564   size = get_frame_size() + avr_outgoing_args_size();
1565
1566   /* epilogue: naked  */
1567   if (cfun->machine->is_naked)
1568     {
1569       gcc_assert (!sibcall_p);
1570
1571       emit_jump_insn (gen_return ());
1572       return;
1573     }
1574
1575   avr_regs_to_save (&set);
1576   live_seq = sequent_regs_live ();
1577
1578   minimize = (TARGET_CALL_PROLOGUES
1579               && live_seq
1580               && !isr_p
1581               && !cfun->machine->is_OS_task
1582               && !cfun->machine->is_OS_main
1583               && !AVR_TINY);
1584
1585   if (minimize
1586       && (live_seq > 4
1587           || frame_pointer_needed
1588           || size))
1589     {
1590       /*  Get rid of frame.  */
1591
1592       if (!frame_pointer_needed)
1593         {
1594           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1595         }
1596
1597       if (size)
1598         {
1599           emit_move_insn (frame_pointer_rtx,
1600                           plus_constant (Pmode, frame_pointer_rtx, size));
1601         }
1602
1603       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1604       return;
1605     }
1606
1607   if (size)
1608     {
1609       /* Try two methods to adjust stack and select shortest.  */
1610
1611       int irq_state = -1;
1612       rtx fp, my_fp;
1613       rtx_insn *fp_plus_insns;
1614       HOST_WIDE_INT size_max;
1615
1616       gcc_assert (frame_pointer_needed
1617                   || !isr_p
1618                   || !crtl->is_leaf);
1619
1620       fp = my_fp = (frame_pointer_needed
1621                     ? frame_pointer_rtx
1622                     : gen_rtx_REG (Pmode, REG_X));
1623
1624       if (AVR_HAVE_8BIT_SP)
1625         {
1626           /* The high byte (r29) does not change:
1627              Prefer SUBI (1 cycle) over SBIW (2 cycles).  */
1628
1629           my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1630         }
1631
1632       /* For rationale see comment in prologue generation.  */
1633
1634       size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1635       if (size > size_max)
1636         size = size_max;
1637       size = trunc_int_for_mode (size, GET_MODE (my_fp));
1638
1639       /********** Method 1: Adjust fp register  **********/
1640
1641       start_sequence ();
1642
1643       if (!frame_pointer_needed)
1644         emit_move_insn (fp, stack_pointer_rtx);
1645
1646       emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1647
1648       /* Copy to stack pointer.  */
1649
1650       if (TARGET_NO_INTERRUPTS)
1651         irq_state = 0;
1652
1653       if (AVR_HAVE_8BIT_SP)
1654         irq_state = 2;
1655
1656       emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1657                                  GEN_INT (irq_state)));
1658
1659       fp_plus_insns = get_insns ();
1660       end_sequence ();
1661
1662       /********** Method 2: Adjust Stack pointer  **********/
1663
1664       if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1665         {
1666           rtx_insn *sp_plus_insns;
1667
1668           start_sequence ();
1669
1670           emit_move_insn (stack_pointer_rtx,
1671                           plus_constant (Pmode, stack_pointer_rtx, size));
1672
1673           sp_plus_insns = get_insns ();
1674           end_sequence ();
1675
1676           /************ Use shortest method  ************/
1677
1678           emit_insn (get_sequence_length (sp_plus_insns)
1679                      < get_sequence_length (fp_plus_insns)
1680                      ? sp_plus_insns
1681                      : fp_plus_insns);
1682         }
1683       else
1684         emit_insn (fp_plus_insns);
1685     } /* size != 0 */
1686
1687   if (frame_pointer_needed
1688       && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1689     {
1690       /* Restore previous frame_pointer.  See avr_expand_prologue for
1691          rationale for not using pophi.  */
1692
1693       emit_pop_byte (REG_Y + 1);
1694       emit_pop_byte (REG_Y);
1695     }
1696
1697   /* Restore used registers.  */
1698
1699   for (reg = 31; reg >= 0; --reg)
1700     if (TEST_HARD_REG_BIT (set, reg))
1701       emit_pop_byte (reg);
1702
1703   if (isr_p)
1704     {
1705       /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1706          The conditions to restore them must be tha same as in prologue.  */
1707
1708       if (AVR_HAVE_RAMPZ
1709           && TEST_HARD_REG_BIT (set, REG_Z)
1710           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1711         {
1712           emit_pop_byte (TMP_REGNO);
1713           emit_move_insn (rampz_rtx, tmp_reg_rtx);
1714         }
1715
1716       if (AVR_HAVE_RAMPY
1717           && (frame_pointer_needed
1718               || (TEST_HARD_REG_BIT (set, REG_Y)
1719                   && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1720         {
1721           emit_pop_byte (TMP_REGNO);
1722           emit_move_insn (rampy_rtx, tmp_reg_rtx);
1723         }
1724
1725       if (AVR_HAVE_RAMPX
1726           && TEST_HARD_REG_BIT (set, REG_X)
1727           && TEST_HARD_REG_BIT (set, REG_X + 1))
1728         {
1729           emit_pop_byte (TMP_REGNO);
1730           emit_move_insn (rampx_rtx, tmp_reg_rtx);
1731         }
1732
1733       if (AVR_HAVE_RAMPD)
1734         {
1735           emit_pop_byte (TMP_REGNO);
1736           emit_move_insn (rampd_rtx, tmp_reg_rtx);
1737         }
1738
1739       /* Restore SREG using tmp_reg as scratch.  */
1740
1741       emit_pop_byte (AVR_TMP_REGNO);
1742       emit_move_insn (sreg_rtx, tmp_reg_rtx);
1743
1744       /* Restore tmp REG.  */
1745       emit_pop_byte (AVR_TMP_REGNO);
1746
1747       /* Restore zero REG.  */
1748       emit_pop_byte (AVR_ZERO_REGNO);
1749     }
1750
1751   if (!sibcall_p)
1752     emit_jump_insn (gen_return ());
1753 }
1754
1755
1756 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'.  */
1757
1758 static void
1759 avr_asm_function_begin_epilogue (FILE *file)
1760 {
1761   fprintf (file, "/* epilogue start */\n");
1762 }
1763
1764
1765 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'.  */
1766
1767 static bool
1768 avr_cannot_modify_jumps_p (void)
1769 {
1770
1771   /* Naked Functions must not have any instructions after
1772      their epilogue, see PR42240 */
1773
1774   if (reload_completed
1775       && cfun->machine
1776       && cfun->machine->is_naked)
1777     {
1778       return true;
1779     }
1780
1781   return false;
1782 }
1783
1784
1785 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'.  */
1786
1787 static bool
1788 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1789 {
1790   /* FIXME:  Non-generic addresses are not mode-dependent in themselves.
1791        This hook just serves to hack around PR rtl-optimization/52543 by
1792        claiming that non-generic addresses were mode-dependent so that
1793        lower-subreg.c will skip these addresses.  lower-subreg.c sets up fake
1794        RTXes to probe SET and MEM costs and assumes that MEM is always in the
1795        generic address space which is not true.  */
1796
1797   return !ADDR_SPACE_GENERIC_P (as);
1798 }
1799
1800
1801 /* Helper function for `avr_legitimate_address_p'.  */
1802
1803 static inline bool
1804 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1805                        RTX_CODE outer_code, bool strict)
1806 {
1807   return (REG_P (reg)
1808           && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1809                                                  as, outer_code, UNKNOWN)
1810               || (!strict
1811                   && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1812 }
1813
1814
1815 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1816    machine for a memory operand of mode MODE.  */
1817
1818 static bool
1819 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1820 {
1821   bool ok = CONSTANT_ADDRESS_P (x);
1822
1823   switch (GET_CODE (x))
1824     {
1825     case REG:
1826       ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1827                                   MEM, strict);
1828
1829       if (strict
1830           && GET_MODE_SIZE (mode) > 4
1831           && REG_X == REGNO (x))
1832         {
1833           ok = false;
1834         }
1835       break;
1836
1837     case POST_INC:
1838     case PRE_DEC:
1839       ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1840                                   GET_CODE (x), strict);
1841       break;
1842
1843     case PLUS:
1844       {
1845         rtx reg = XEXP (x, 0);
1846         rtx op1 = XEXP (x, 1);
1847
1848         if (REG_P (reg)
1849             && CONST_INT_P (op1)
1850             && INTVAL (op1) >= 0)
1851           {
1852             bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1853
1854             if (fit)
1855               {
1856                 ok = (! strict
1857                       || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1858                                                 PLUS, strict));
1859
1860                 if (reg == frame_pointer_rtx
1861                     || reg == arg_pointer_rtx)
1862                   {
1863                     ok = true;
1864                   }
1865               }
1866             else if (frame_pointer_needed
1867                      && reg == frame_pointer_rtx)
1868               {
1869                 ok = true;
1870               }
1871           }
1872       }
1873       break;
1874
1875     default:
1876       break;
1877     }
1878
1879   if (AVR_TINY
1880       && CONSTANT_ADDRESS_P (x))
1881     {
1882       /* avrtiny's load / store instructions only cover addresses 0..0xbf:
1883          IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf.  */
1884
1885       ok = (CONST_INT_P (x)
1886             && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)));
1887     }
1888
1889   if (avr_log.legitimate_address_p)
1890     {
1891       avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1892                  "reload_completed=%d reload_in_progress=%d %s:",
1893                  ok, mode, strict, reload_completed, reload_in_progress,
1894                  reg_renumber ? "(reg_renumber)" : "");
1895
1896       if (GET_CODE (x) == PLUS
1897           && REG_P (XEXP (x, 0))
1898           && CONST_INT_P (XEXP (x, 1))
1899           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1900           && reg_renumber)
1901         {
1902           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1903                      true_regnum (XEXP (x, 0)));
1904         }
1905
1906       avr_edump ("\n%r\n", x);
1907     }
1908
1909   return ok;
1910 }
1911
1912
1913 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1914    now only a helper for avr_addr_space_legitimize_address.  */
1915 /* Attempts to replace X with a valid
1916    memory address for an operand of mode MODE  */
1917
1918 static rtx
1919 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
1920 {
1921   bool big_offset_p = false;
1922
1923   x = oldx;
1924
1925   if (GET_CODE (oldx) == PLUS
1926       && REG_P (XEXP (oldx, 0)))
1927     {
1928       if (REG_P (XEXP (oldx, 1)))
1929         x = force_reg (GET_MODE (oldx), oldx);
1930       else if (CONST_INT_P (XEXP (oldx, 1)))
1931         {
1932           int offs = INTVAL (XEXP (oldx, 1));
1933           if (frame_pointer_rtx != XEXP (oldx, 0)
1934               && offs > MAX_LD_OFFSET (mode))
1935             {
1936               big_offset_p = true;
1937               x = force_reg (GET_MODE (oldx), oldx);
1938             }
1939         }
1940     }
1941
1942   if (avr_log.legitimize_address)
1943     {
1944       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1945
1946       if (x != oldx)
1947         avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1948     }
1949
1950   return x;
1951 }
1952
1953
1954 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
1955 /* This will allow register R26/27 to be used where it is no worse than normal
1956    base pointers R28/29 or R30/31.  For example, if base offset is greater
1957    than 63 bytes or for R++ or --R addressing.  */
1958
1959 rtx
1960 avr_legitimize_reload_address (rtx *px, machine_mode mode,
1961                                int opnum, int type, int addr_type,
1962                                int ind_levels ATTRIBUTE_UNUSED,
1963                                rtx (*mk_memloc)(rtx,int))
1964 {
1965   rtx x = *px;
1966
1967   if (avr_log.legitimize_reload_address)
1968     avr_edump ("\n%?:%m %r\n", mode, x);
1969
1970   if (1 && (GET_CODE (x) == POST_INC
1971             || GET_CODE (x) == PRE_DEC))
1972     {
1973       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1974                    POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1975                    opnum, RELOAD_OTHER);
1976
1977       if (avr_log.legitimize_reload_address)
1978         avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1979                    POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1980
1981       return x;
1982     }
1983
1984   if (GET_CODE (x) == PLUS
1985       && REG_P (XEXP (x, 0))
1986       && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
1987       && CONST_INT_P (XEXP (x, 1))
1988       && INTVAL (XEXP (x, 1)) >= 1)
1989     {
1990       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
1991
1992       if (fit)
1993         {
1994           if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
1995             {
1996               int regno = REGNO (XEXP (x, 0));
1997               rtx mem = mk_memloc (x, regno);
1998
1999               push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
2000                            POINTER_REGS, Pmode, VOIDmode, 0, 0,
2001                            1, (enum reload_type) addr_type);
2002
2003               if (avr_log.legitimize_reload_address)
2004                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2005                            POINTER_REGS, XEXP (mem, 0), NULL_RTX);
2006
2007               push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
2008                            BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2009                            opnum, (enum reload_type) type);
2010
2011               if (avr_log.legitimize_reload_address)
2012                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2013                            BASE_POINTER_REGS, mem, NULL_RTX);
2014
2015               return x;
2016             }
2017         }
2018       else if (! (frame_pointer_needed
2019                   && XEXP (x, 0) == frame_pointer_rtx))
2020         {
2021           push_reload (x, NULL_RTX, px, NULL,
2022                        POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2023                        opnum, (enum reload_type) type);
2024
2025           if (avr_log.legitimize_reload_address)
2026             avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
2027                        POINTER_REGS, x, NULL_RTX);
2028
2029           return x;
2030         }
2031     }
2032
2033   return NULL_RTX;
2034 }
2035
2036
2037 /* Implement `TARGET_SECONDARY_RELOAD' */
2038
2039 static reg_class_t
2040 avr_secondary_reload (bool in_p, rtx x,
2041                       reg_class_t reload_class ATTRIBUTE_UNUSED,
2042                       machine_mode mode, secondary_reload_info *sri)
2043 {
2044   if (in_p
2045       && MEM_P (x)
2046       && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2047       && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
2048     {
2049       /* For the non-generic 16-bit spaces we need a d-class scratch.  */
2050
2051       switch (mode)
2052         {
2053         default:
2054           gcc_unreachable();
2055
2056         case QImode:  sri->icode = CODE_FOR_reload_inqi; break;
2057         case QQmode:  sri->icode = CODE_FOR_reload_inqq; break;
2058         case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
2059
2060         case HImode:  sri->icode = CODE_FOR_reload_inhi; break;
2061         case HQmode:  sri->icode = CODE_FOR_reload_inhq; break;
2062         case HAmode:  sri->icode = CODE_FOR_reload_inha; break;
2063         case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
2064         case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
2065
2066         case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
2067
2068         case SImode:  sri->icode = CODE_FOR_reload_insi; break;
2069         case SFmode:  sri->icode = CODE_FOR_reload_insf; break;
2070         case SQmode:  sri->icode = CODE_FOR_reload_insq; break;
2071         case SAmode:  sri->icode = CODE_FOR_reload_insa; break;
2072         case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
2073         case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
2074         }
2075     }
2076
2077   return NO_REGS;
2078 }
2079
2080
2081 /* Helper function to print assembler resp. track instruction
2082    sequence lengths.  Always return "".
2083
2084    If PLEN == NULL:
2085        Output assembler code from template TPL with operands supplied
2086        by OPERANDS.  This is just forwarding to output_asm_insn.
2087
2088    If PLEN != NULL:
2089        If N_WORDS >= 0  Add N_WORDS to *PLEN.
2090        If N_WORDS < 0   Set *PLEN to -N_WORDS.
2091        Don't output anything.
2092 */
2093
2094 static const char*
2095 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2096 {
2097   if (NULL == plen)
2098     {
2099       output_asm_insn (tpl, operands);
2100     }
2101   else
2102     {
2103       if (n_words < 0)
2104         *plen = -n_words;
2105       else
2106         *plen += n_words;
2107     }
2108
2109   return "";
2110 }
2111
2112
2113 /* Return a pointer register name as a string.  */
2114
2115 static const char*
2116 ptrreg_to_str (int regno)
2117 {
2118   switch (regno)
2119     {
2120     case REG_X: return "X";
2121     case REG_Y: return "Y";
2122     case REG_Z: return "Z";
2123     default:
2124       output_operand_lossage ("address operand requires constraint for"
2125                               " X, Y, or Z register");
2126     }
2127   return NULL;
2128 }
2129
2130 /* Return the condition name as a string.
2131    Used in conditional jump constructing  */
2132
2133 static const char*
2134 cond_string (enum rtx_code code)
2135 {
2136   switch (code)
2137     {
2138     case NE:
2139       return "ne";
2140     case EQ:
2141       return "eq";
2142     case GE:
2143       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2144         return "pl";
2145       else
2146         return "ge";
2147     case LT:
2148       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2149         return "mi";
2150       else
2151         return "lt";
2152     case GEU:
2153       return "sh";
2154     case LTU:
2155       return "lo";
2156     default:
2157       gcc_unreachable ();
2158     }
2159
2160   return "";
2161 }
2162
2163
2164 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'.  */
2165 /* Output ADDR to FILE as address.  */
2166
2167 static void
2168 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
2169 {
2170   switch (GET_CODE (addr))
2171     {
2172     case REG:
2173       fprintf (file, ptrreg_to_str (REGNO (addr)));
2174       break;
2175
2176     case PRE_DEC:
2177       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2178       break;
2179
2180     case POST_INC:
2181       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2182       break;
2183
2184     default:
2185       if (CONSTANT_ADDRESS_P (addr)
2186           && text_segment_operand (addr, VOIDmode))
2187         {
2188           rtx x = addr;
2189           if (GET_CODE (x) == CONST)
2190             x = XEXP (x, 0);
2191           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2192             {
2193               /* Assembler gs() will implant word address.  Make offset
2194                  a byte offset inside gs() for assembler.  This is
2195                  needed because the more logical (constant+gs(sym)) is not
2196                  accepted by gas.  For 128K and smaller devices this is ok.
2197                  For large devices it will create a trampoline to offset
2198                  from symbol which may not be what the user really wanted.  */
2199
2200               fprintf (file, "gs(");
2201               output_addr_const (file, XEXP (x,0));
2202               fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2203                        2 * INTVAL (XEXP (x, 1)));
2204               if (AVR_3_BYTE_PC)
2205                 if (warning (0, "pointer offset from symbol maybe incorrect"))
2206                   {
2207                     output_addr_const (stderr, addr);
2208                     fprintf(stderr,"\n");
2209                   }
2210             }
2211           else
2212             {
2213               fprintf (file, "gs(");
2214               output_addr_const (file, addr);
2215               fprintf (file, ")");
2216             }
2217         }
2218       else
2219         output_addr_const (file, addr);
2220     }
2221 }
2222
2223
2224 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'.  */
2225
2226 static bool
2227 avr_print_operand_punct_valid_p (unsigned char code)
2228 {
2229   return code == '~' || code == '!';
2230 }
2231
2232
2233 /* Implement `TARGET_PRINT_OPERAND'.  */
2234 /* Output X as assembler operand to file FILE.
2235    For a description of supported %-codes, see top of avr.md.  */
2236
2237 static void
2238 avr_print_operand (FILE *file, rtx x, int code)
2239 {
2240   int abcd = 0, ef = 0, ij = 0;
2241
2242   if (code >= 'A' && code <= 'D')
2243     abcd = code - 'A';
2244   else if (code == 'E' || code == 'F')
2245     ef = code - 'E';
2246   else if (code == 'I' || code == 'J')
2247     ij = code - 'I';
2248
2249   if (code == '~')
2250     {
2251       if (!AVR_HAVE_JMP_CALL)
2252         fputc ('r', file);
2253     }
2254   else if (code == '!')
2255     {
2256       if (AVR_HAVE_EIJMP_EICALL)
2257         fputc ('e', file);
2258     }
2259   else if (code == 't'
2260            || code == 'T')
2261     {
2262       static int t_regno = -1;
2263       static int t_nbits = -1;
2264
2265       if (REG_P (x) && t_regno < 0 && code == 'T')
2266         {
2267           t_regno = REGNO (x);
2268           t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2269         }
2270       else if (CONST_INT_P (x) && t_regno >= 0
2271                && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2272         {
2273           int bpos = INTVAL (x);
2274
2275           fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2276           if (code == 'T')
2277             fprintf (file, ",%d", bpos % 8);
2278
2279           t_regno = -1;
2280         }
2281       else
2282         fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2283     }
2284   else if (code == 'E' || code == 'F')
2285     {
2286       rtx op = XEXP(x, 0);
2287       fprintf (file, reg_names[REGNO (op) + ef]);
2288     }
2289   else if (code == 'I' || code == 'J')
2290     {
2291       rtx op = XEXP(XEXP(x, 0), 0);
2292       fprintf (file, reg_names[REGNO (op) + ij]);
2293     }
2294   else if (REG_P (x))
2295     {
2296       if (x == zero_reg_rtx)
2297         fprintf (file, "__zero_reg__");
2298       else if (code == 'r' && REGNO (x) < 32)
2299         fprintf (file, "%d", (int) REGNO (x));
2300       else
2301         fprintf (file, reg_names[REGNO (x) + abcd]);
2302     }
2303   else if (CONST_INT_P (x))
2304     {
2305       HOST_WIDE_INT ival = INTVAL (x);
2306
2307       if ('i' != code)
2308         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2309       else if (low_io_address_operand (x, VOIDmode)
2310                || high_io_address_operand (x, VOIDmode))
2311         {
2312           if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2313             fprintf (file, "__RAMPZ__");
2314           else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2315             fprintf (file, "__RAMPY__");
2316           else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2317             fprintf (file, "__RAMPX__");
2318           else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2319             fprintf (file, "__RAMPD__");
2320           else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
2321             fprintf (file, "__CCP__");
2322           else if (ival == avr_addr.sreg)   fprintf (file, "__SREG__");
2323           else if (ival == avr_addr.sp_l)   fprintf (file, "__SP_L__");
2324           else if (ival == avr_addr.sp_h)   fprintf (file, "__SP_H__");
2325           else
2326             {
2327               fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2328                        ival - avr_arch->sfr_offset);
2329             }
2330         }
2331       else
2332         fatal_insn ("bad address, not an I/O address:", x);
2333     }
2334   else if (MEM_P (x))
2335     {
2336       rtx addr = XEXP (x, 0);
2337
2338       if (code == 'm')
2339         {
2340           if (!CONSTANT_P (addr))
2341             fatal_insn ("bad address, not a constant:", addr);
2342           /* Assembler template with m-code is data - not progmem section */
2343           if (text_segment_operand (addr, VOIDmode))
2344             if (warning (0, "accessing data memory with"
2345                          " program memory address"))
2346               {
2347                 output_addr_const (stderr, addr);
2348                 fprintf(stderr,"\n");
2349               }
2350           output_addr_const (file, addr);
2351         }
2352       else if (code == 'i')
2353         {
2354           avr_print_operand (file, addr, 'i');
2355         }
2356       else if (code == 'o')
2357         {
2358           if (GET_CODE (addr) != PLUS)
2359             fatal_insn ("bad address, not (reg+disp):", addr);
2360
2361           avr_print_operand (file, XEXP (addr, 1), 0);
2362         }
2363       else if (code == 'b')
2364         {
2365           if (GET_CODE (addr) != PLUS)
2366                fatal_insn ("bad address, not (reg+disp):", addr);
2367
2368           avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2369         }
2370       else if (code == 'p' || code == 'r')
2371         {
2372           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2373             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2374
2375           if (code == 'p')
2376             /* X, Y, Z */
2377             avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2378           else
2379             avr_print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
2380         }
2381       else if (GET_CODE (addr) == PLUS)
2382         {
2383           avr_print_operand_address (file, VOIDmode, XEXP (addr,0));
2384           if (REGNO (XEXP (addr, 0)) == REG_X)
2385             fatal_insn ("internal compiler error.  Bad address:"
2386                         ,addr);
2387           fputc ('+', file);
2388           avr_print_operand (file, XEXP (addr,1), code);
2389         }
2390       else
2391         avr_print_operand_address (file, VOIDmode, addr);
2392     }
2393   else if (code == 'i')
2394     {
2395       if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
2396         avr_print_operand_address
2397           (file, VOIDmode, plus_constant (HImode, x, -avr_arch->sfr_offset));
2398       else
2399         fatal_insn ("bad address, not an I/O address:", x);
2400     }
2401   else if (code == 'x')
2402     {
2403       /* Constant progmem address - like used in jmp or call */
2404       if (0 == text_segment_operand (x, VOIDmode))
2405         if (warning (0, "accessing program memory"
2406                      " with data memory address"))
2407           {
2408             output_addr_const (stderr, x);
2409             fprintf(stderr,"\n");
2410           }
2411       /* Use normal symbol for direct address no linker trampoline needed */
2412       output_addr_const (file, x);
2413     }
2414   else if (CONST_FIXED_P (x))
2415     {
2416       HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2417       if (code != 0)
2418         output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2419                                 code);
2420       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2421     }
2422   else if (GET_CODE (x) == CONST_DOUBLE)
2423     {
2424       long val;
2425       if (GET_MODE (x) != SFmode)
2426         fatal_insn ("internal compiler error.  Unknown mode:", x);
2427       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
2428       fprintf (file, "0x%lx", val);
2429     }
2430   else if (GET_CODE (x) == CONST_STRING)
2431     fputs (XSTR (x, 0), file);
2432   else if (code == 'j')
2433     fputs (cond_string (GET_CODE (x)), file);
2434   else if (code == 'k')
2435     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2436   else
2437     avr_print_operand_address (file, VOIDmode, x);
2438 }
2439
2440
2441 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.  */
2442
2443 /* Prefer sequence of loads/stores for moves of size upto
2444    two - two pairs of load/store instructions are always better
2445    than the 5 instruction sequence for a loop (1 instruction
2446    for loop counter setup, and 4 for the body of the loop). */
2447
2448 static bool
2449 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
2450                                      unsigned int align ATTRIBUTE_UNUSED,
2451                                      enum by_pieces_operation op,
2452                                      bool speed_p)
2453 {
2454
2455   if (op != MOVE_BY_PIECES || (speed_p && (size > (MOVE_MAX_PIECES))))
2456     return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
2457
2458   return size <= (MOVE_MAX_PIECES);
2459 }
2460
2461
2462 /* Worker function for `NOTICE_UPDATE_CC'.  */
2463 /* Update the condition code in the INSN.  */
2464
2465 void
2466 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
2467 {
2468   rtx set;
2469   enum attr_cc cc = get_attr_cc (insn);
2470
2471   switch (cc)
2472     {
2473     default:
2474       break;
2475
2476     case CC_PLUS:
2477     case CC_LDI:
2478       {
2479         rtx *op = recog_data.operand;
2480         int len_dummy, icc;
2481
2482         /* Extract insn's operands.  */
2483         extract_constrain_insn_cached (insn);
2484
2485         switch (cc)
2486           {
2487           default:
2488             gcc_unreachable();
2489
2490           case CC_PLUS:
2491             avr_out_plus (insn, op, &len_dummy, &icc);
2492             cc = (enum attr_cc) icc;
2493             break;
2494
2495           case CC_LDI:
2496
2497             cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2498                   && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2499               /* Loading zero-reg with 0 uses CLR and thus clobbers cc0.  */
2500               ? CC_CLOBBER
2501               /* Any other "r,rL" combination does not alter cc0.  */
2502               : CC_NONE;
2503
2504             break;
2505           } /* inner switch */
2506
2507         break;
2508       }
2509     } /* outer swicth */
2510
2511   switch (cc)
2512     {
2513     default:
2514       /* Special values like CC_OUT_PLUS from above have been
2515          mapped to "standard" CC_* values so we never come here.  */
2516
2517       gcc_unreachable();
2518       break;
2519
2520     case CC_NONE:
2521       /* Insn does not affect CC at all, but it might set some registers
2522          that are stored in cc_status.  If such a register is affected by
2523          the current insn, for example by means of a SET or a CLOBBER,
2524          then we must reset cc_status; cf. PR77326.
2525
2526          Unfortunately, set_of cannot be used as reg_overlap_mentioned_p
2527          will abort on COMPARE (which might be found in cc_status.value1/2).
2528          Thus work out the registers set by the insn and regs mentioned
2529          in cc_status.value1/2.  */
2530
2531       if (cc_status.value1
2532           || cc_status.value2)
2533         {
2534           HARD_REG_SET regs_used;
2535           HARD_REG_SET regs_set;
2536           CLEAR_HARD_REG_SET (regs_used);
2537
2538           if (cc_status.value1
2539               && !CONSTANT_P (cc_status.value1))
2540             {
2541               find_all_hard_regs (cc_status.value1, &regs_used);
2542             }
2543
2544           if (cc_status.value2
2545               && !CONSTANT_P (cc_status.value2))
2546             {
2547               find_all_hard_regs (cc_status.value2, &regs_used);
2548             }
2549
2550           find_all_hard_reg_sets (insn, &regs_set, false);
2551
2552           if (hard_reg_set_intersect_p (regs_used, regs_set))
2553             {
2554               CC_STATUS_INIT;
2555             }
2556         }
2557
2558       break; // CC_NONE
2559
2560     case CC_SET_N:
2561       CC_STATUS_INIT;
2562       break;
2563
2564     case CC_SET_ZN:
2565       set = single_set (insn);
2566       CC_STATUS_INIT;
2567       if (set)
2568         {
2569           cc_status.flags |= CC_NO_OVERFLOW;
2570           cc_status.value1 = SET_DEST (set);
2571         }
2572       break;
2573
2574     case CC_SET_VZN:
2575       /* Insn like INC, DEC, NEG that set Z,N,V.  We currently don't make use
2576          of this combination, cf. also PR61055.  */
2577       CC_STATUS_INIT;
2578       break;
2579
2580     case CC_SET_CZN:
2581       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2582          The V flag may or may not be known but that's ok because
2583          alter_cond will change tests to use EQ/NE.  */
2584       set = single_set (insn);
2585       CC_STATUS_INIT;
2586       if (set)
2587         {
2588           cc_status.value1 = SET_DEST (set);
2589           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2590         }
2591       break;
2592
2593     case CC_COMPARE:
2594       set = single_set (insn);
2595       CC_STATUS_INIT;
2596       if (set)
2597         cc_status.value1 = SET_SRC (set);
2598       break;
2599
2600     case CC_CLOBBER:
2601       /* Insn doesn't leave CC in a usable state.  */
2602       CC_STATUS_INIT;
2603       break;
2604     }
2605 }
2606
2607 /* Choose mode for jump insn:
2608    1 - relative jump in range -63 <= x <= 62 ;
2609    2 - relative jump in range -2046 <= x <= 2045 ;
2610    3 - absolute jump (only for ATmega[16]03).  */
2611
2612 int
2613 avr_jump_mode (rtx x, rtx_insn *insn)
2614 {
2615   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2616                                             ? XEXP (x, 0) : x));
2617   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2618   int jump_distance = cur_addr - dest_addr;
2619
2620   if (-63 <= jump_distance && jump_distance <= 62)
2621     return 1;
2622   else if (-2046 <= jump_distance && jump_distance <= 2045)
2623     return 2;
2624   else if (AVR_HAVE_JMP_CALL)
2625     return 3;
2626
2627   return 2;
2628 }
2629
2630 /* Return an AVR condition jump commands.
2631    X is a comparison RTX.
2632    LEN is a number returned by avr_jump_mode function.
2633    If REVERSE nonzero then condition code in X must be reversed.  */
2634
2635 const char*
2636 ret_cond_branch (rtx x, int len, int reverse)
2637 {
2638   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2639
2640   switch (cond)
2641     {
2642     case GT:
2643       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2644         return (len == 1 ? ("breq .+2" CR_TAB
2645                             "brpl %0") :
2646                 len == 2 ? ("breq .+4" CR_TAB
2647                             "brmi .+2" CR_TAB
2648                             "rjmp %0") :
2649                 ("breq .+6" CR_TAB
2650                  "brmi .+4" CR_TAB
2651                  "jmp %0"));
2652
2653       else
2654         return (len == 1 ? ("breq .+2" CR_TAB
2655                             "brge %0") :
2656                 len == 2 ? ("breq .+4" CR_TAB
2657                             "brlt .+2" CR_TAB
2658                             "rjmp %0") :
2659                 ("breq .+6" CR_TAB
2660                  "brlt .+4" CR_TAB
2661                  "jmp %0"));
2662     case GTU:
2663       return (len == 1 ? ("breq .+2" CR_TAB
2664                           "brsh %0") :
2665               len == 2 ? ("breq .+4" CR_TAB
2666                           "brlo .+2" CR_TAB
2667                           "rjmp %0") :
2668               ("breq .+6" CR_TAB
2669                "brlo .+4" CR_TAB
2670                "jmp %0"));
2671     case LE:
2672       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2673         return (len == 1 ? ("breq %0" CR_TAB
2674                             "brmi %0") :
2675                 len == 2 ? ("breq .+2" CR_TAB
2676                             "brpl .+2" CR_TAB
2677                             "rjmp %0") :
2678                 ("breq .+2" CR_TAB
2679                  "brpl .+4" CR_TAB
2680                  "jmp %0"));
2681       else
2682         return (len == 1 ? ("breq %0" CR_TAB
2683                             "brlt %0") :
2684                 len == 2 ? ("breq .+2" CR_TAB
2685                             "brge .+2" CR_TAB
2686                             "rjmp %0") :
2687                 ("breq .+2" CR_TAB
2688                  "brge .+4" CR_TAB
2689                  "jmp %0"));
2690     case LEU:
2691       return (len == 1 ? ("breq %0" CR_TAB
2692                           "brlo %0") :
2693               len == 2 ? ("breq .+2" CR_TAB
2694                           "brsh .+2" CR_TAB
2695                           "rjmp %0") :
2696               ("breq .+2" CR_TAB
2697                "brsh .+4" CR_TAB
2698                "jmp %0"));
2699     default:
2700       if (reverse)
2701         {
2702           switch (len)
2703             {
2704             case 1:
2705               return "br%k1 %0";
2706             case 2:
2707               return ("br%j1 .+2" CR_TAB
2708                       "rjmp %0");
2709             default:
2710               return ("br%j1 .+4" CR_TAB
2711                       "jmp %0");
2712             }
2713         }
2714       else
2715         {
2716           switch (len)
2717             {
2718             case 1:
2719               return "br%j1 %0";
2720             case 2:
2721               return ("br%k1 .+2" CR_TAB
2722                       "rjmp %0");
2723             default:
2724               return ("br%k1 .+4" CR_TAB
2725                       "jmp %0");
2726             }
2727         }
2728     }
2729   return "";
2730 }
2731
2732
2733 /* Worker function for `FINAL_PRESCAN_INSN'.  */
2734 /* Output insn cost for next insn.  */
2735
2736 void
2737 avr_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
2738                         int num_operands ATTRIBUTE_UNUSED)
2739 {
2740   if (avr_log.rtx_costs)
2741     {
2742       rtx set = single_set (insn);
2743
2744       if (set)
2745         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
2746                  set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
2747                                optimize_insn_for_speed_p ()));
2748       else
2749         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
2750                  rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
2751                            optimize_insn_for_speed_p()));
2752     }
2753 }
2754
2755 /* Return 0 if undefined, 1 if always true or always false.  */
2756
2757 int
2758 avr_simplify_comparison_p (machine_mode mode, RTX_CODE op, rtx x)
2759 {
2760   unsigned int max = (mode == QImode ? 0xff :
2761                       mode == HImode ? 0xffff :
2762                       mode == PSImode ? 0xffffff :
2763                       mode == SImode ? 0xffffffff : 0);
2764   if (max && op && CONST_INT_P (x))
2765     {
2766       if (unsigned_condition (op) != op)
2767         max >>= 1;
2768
2769       if (max != (INTVAL (x) & max)
2770           && INTVAL (x) != 0xff)
2771         return 1;
2772     }
2773   return 0;
2774 }
2775
2776
2777 /* Worker function for `FUNCTION_ARG_REGNO_P'.  */
2778 /* Returns nonzero if REGNO is the number of a hard
2779    register in which function arguments are sometimes passed.  */
2780
2781 int
2782 avr_function_arg_regno_p(int r)
2783 {
2784   return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
2785 }
2786
2787
2788 /* Worker function for `INIT_CUMULATIVE_ARGS'.  */
2789 /* Initializing the variable cum for the state at the beginning
2790    of the argument list.  */
2791
2792 void
2793 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2794                           tree fndecl ATTRIBUTE_UNUSED)
2795 {
2796   cum->nregs = AVR_TINY ? 6 : 18;
2797   cum->regno = FIRST_CUM_REG;
2798   if (!libname && stdarg_p (fntype))
2799     cum->nregs = 0;
2800
2801   /* Assume the calle may be tail called */
2802
2803   cfun->machine->sibcall_fails = 0;
2804 }
2805
2806 /* Returns the number of registers to allocate for a function argument.  */
2807
2808 static int
2809 avr_num_arg_regs (machine_mode mode, const_tree type)
2810 {
2811   int size;
2812
2813   if (mode == BLKmode)
2814     size = int_size_in_bytes (type);
2815   else
2816     size = GET_MODE_SIZE (mode);
2817
2818   /* Align all function arguments to start in even-numbered registers.
2819      Odd-sized arguments leave holes above them.  */
2820
2821   return (size + 1) & ~1;
2822 }
2823
2824
2825 /* Implement `TARGET_FUNCTION_ARG'.  */
2826 /* Controls whether a function argument is passed
2827    in a register, and which register.  */
2828
2829 static rtx
2830 avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
2831                   const_tree type, bool named ATTRIBUTE_UNUSED)
2832 {
2833   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2834   int bytes = avr_num_arg_regs (mode, type);
2835
2836   if (cum->nregs && bytes <= cum->nregs)
2837     return gen_rtx_REG (mode, cum->regno - bytes);
2838
2839   return NULL_RTX;
2840 }
2841
2842
2843 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'.  */
2844 /* Update the summarizer variable CUM to advance past an argument
2845    in the argument list.  */
2846
2847 static void
2848 avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2849                           const_tree type, bool named ATTRIBUTE_UNUSED)
2850 {
2851   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2852   int bytes = avr_num_arg_regs (mode, type);
2853
2854   cum->nregs -= bytes;
2855   cum->regno -= bytes;
2856
2857   /* A parameter is being passed in a call-saved register.  As the original
2858      contents of these regs has to be restored before leaving the function,
2859      a function must not pass arguments in call-saved regs in order to get
2860      tail-called.  */
2861
2862   if (cum->regno >= 8
2863       && cum->nregs >= 0
2864       && !call_used_regs[cum->regno])
2865     {
2866       /* FIXME: We ship info on failing tail-call in struct machine_function.
2867          This uses internals of calls.c:expand_call() and the way args_so_far
2868          is used.  targetm.function_ok_for_sibcall() needs to be extended to
2869          pass &args_so_far, too.  At present, CUMULATIVE_ARGS is target
2870          dependent so that such an extension is not wanted.  */
2871
2872       cfun->machine->sibcall_fails = 1;
2873     }
2874
2875   /* Test if all registers needed by the ABI are actually available.  If the
2876      user has fixed a GPR needed to pass an argument, an (implicit) function
2877      call will clobber that fixed register.  See PR45099 for an example.  */
2878
2879   if (cum->regno >= 8
2880       && cum->nregs >= 0)
2881     {
2882       int regno;
2883
2884       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2885         if (fixed_regs[regno])
2886           warning (0, "fixed register %s used to pass parameter to function",
2887                    reg_names[regno]);
2888     }
2889
2890   if (cum->nregs <= 0)
2891     {
2892       cum->nregs = 0;
2893       cum->regno = FIRST_CUM_REG;
2894     }
2895 }
2896
2897 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2898 /* Decide whether we can make a sibling call to a function.  DECL is the
2899    declaration of the function being targeted by the call and EXP is the
2900    CALL_EXPR representing the call.  */
2901
2902 static bool
2903 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2904 {
2905   tree fntype_callee;
2906
2907   /* Tail-calling must fail if callee-saved regs are used to pass
2908      function args.  We must not tail-call when `epilogue_restores'
2909      is used.  Unfortunately, we cannot tell at this point if that
2910      actually will happen or not, and we cannot step back from
2911      tail-calling.  Thus, we inhibit tail-calling with -mcall-prologues.  */
2912
2913   if (cfun->machine->sibcall_fails
2914       || TARGET_CALL_PROLOGUES)
2915     {
2916       return false;
2917     }
2918
2919   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2920
2921   if (decl_callee)
2922     {
2923       decl_callee = TREE_TYPE (decl_callee);
2924     }
2925   else
2926     {
2927       decl_callee = fntype_callee;
2928
2929       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2930              && METHOD_TYPE != TREE_CODE (decl_callee))
2931         {
2932           decl_callee = TREE_TYPE (decl_callee);
2933         }
2934     }
2935
2936   /* Ensure that caller and callee have compatible epilogues */
2937
2938   if (cfun->machine->is_interrupt
2939       || cfun->machine->is_signal
2940       || cfun->machine->is_naked
2941       || avr_naked_function_p (decl_callee)
2942       /* FIXME: For OS_task and OS_main, this might be over-conservative.  */
2943       || (avr_OS_task_function_p (decl_callee)
2944           != cfun->machine->is_OS_task)
2945       || (avr_OS_main_function_p (decl_callee)
2946           != cfun->machine->is_OS_main))
2947     {
2948       return false;
2949     }
2950
2951   return true;
2952 }
2953
2954 /***********************************************************************
2955   Functions for outputting various mov's for a various modes
2956 ************************************************************************/
2957
2958 /* Return true if a value of mode MODE is read from flash by
2959    __load_* function from libgcc.  */
2960
2961 bool
2962 avr_load_libgcc_p (rtx op)
2963 {
2964   machine_mode mode = GET_MODE (op);
2965   int n_bytes = GET_MODE_SIZE (mode);
2966
2967   return (n_bytes > 2
2968           && !AVR_HAVE_LPMX
2969           && avr_mem_flash_p (op));
2970 }
2971
2972 /* Return true if a value of mode MODE is read by __xload_* function.  */
2973
2974 bool
2975 avr_xload_libgcc_p (machine_mode mode)
2976 {
2977   int n_bytes = GET_MODE_SIZE (mode);
2978
2979   return (n_bytes > 1
2980           || avr_n_flash > 1);
2981 }
2982
2983
2984 /* Fixme: This is a hack because secondary reloads don't works as expected.
2985
2986    Find an unused d-register to be used as scratch in INSN.
2987    EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
2988    is a register, skip all possible return values that overlap EXCLUDE.
2989    The policy for the returned register is similar to that of
2990    `reg_unused_after', i.e. the returned register may overlap the SET_DEST
2991    of INSN.
2992
2993    Return a QImode d-register or NULL_RTX if nothing found.  */
2994
2995 static rtx
2996 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
2997 {
2998   int regno;
2999   bool isr_p = (avr_interrupt_function_p (current_function_decl)
3000                 || avr_signal_function_p (current_function_decl));
3001
3002   for (regno = 16; regno < 32; regno++)
3003     {
3004       rtx reg = all_regs_rtx[regno];
3005
3006       if ((exclude
3007            && reg_overlap_mentioned_p (exclude, reg))
3008           || fixed_regs[regno])
3009         {
3010           continue;
3011         }
3012
3013       /* Try non-live register */
3014
3015       if (!df_regs_ever_live_p (regno)
3016           && (TREE_THIS_VOLATILE (current_function_decl)
3017               || cfun->machine->is_OS_task
3018               || cfun->machine->is_OS_main
3019               || (!isr_p && call_used_regs[regno])))
3020         {
3021           return reg;
3022         }
3023
3024       /* Any live register can be used if it is unused after.
3025          Prologue/epilogue will care for it as needed.  */
3026
3027       if (df_regs_ever_live_p (regno)
3028           && reg_unused_after (insn, reg))
3029         {
3030           return reg;
3031         }
3032     }
3033
3034   return NULL_RTX;
3035 }
3036
3037
3038 /* Helper function for the next function in the case where only restricted
3039    version of LPM instruction is available.  */
3040
3041 static const char*
3042 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
3043 {
3044   rtx dest = xop[0];
3045   rtx addr = xop[1];
3046   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3047   int regno_dest;
3048
3049   regno_dest = REGNO (dest);
3050
3051   /* The implicit target register of LPM.  */
3052   xop[3] = lpm_reg_rtx;
3053
3054   switch (GET_CODE (addr))
3055     {
3056     default:
3057       gcc_unreachable();
3058
3059     case REG:
3060
3061       gcc_assert (REG_Z == REGNO (addr));
3062
3063       switch (n_bytes)
3064         {
3065         default:
3066           gcc_unreachable();
3067
3068         case 1:
3069           avr_asm_len ("%4lpm", xop, plen, 1);
3070
3071           if (regno_dest != LPM_REGNO)
3072             avr_asm_len ("mov %0,%3", xop, plen, 1);
3073
3074           return "";
3075
3076         case 2:
3077           if (REGNO (dest) == REG_Z)
3078             return avr_asm_len ("%4lpm"      CR_TAB
3079                                 "push %3"    CR_TAB
3080                                 "adiw %2,1"  CR_TAB
3081                                 "%4lpm"      CR_TAB
3082                                 "mov %B0,%3" CR_TAB
3083                                 "pop %A0", xop, plen, 6);
3084
3085           avr_asm_len ("%4lpm"      CR_TAB
3086                        "mov %A0,%3" CR_TAB
3087                        "adiw %2,1"  CR_TAB
3088                        "%4lpm"      CR_TAB
3089                        "mov %B0,%3", xop, plen, 5);
3090
3091           if (!reg_unused_after (insn, addr))
3092             avr_asm_len ("sbiw %2,1", xop, plen, 1);
3093
3094           break; /* 2 */
3095         }
3096
3097       break; /* REG */
3098
3099     case POST_INC:
3100
3101       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3102                   && n_bytes <= 4);
3103
3104       if (regno_dest == LPM_REGNO)
3105         avr_asm_len ("%4lpm"      CR_TAB
3106                      "adiw %2,1", xop, plen, 2);
3107       else
3108         avr_asm_len ("%4lpm"      CR_TAB
3109                      "mov %A0,%3" CR_TAB
3110                      "adiw %2,1", xop, plen, 3);
3111
3112       if (n_bytes >= 2)
3113         avr_asm_len ("%4lpm"      CR_TAB
3114                      "mov %B0,%3" CR_TAB
3115                      "adiw %2,1", xop, plen, 3);
3116
3117       if (n_bytes >= 3)
3118         avr_asm_len ("%4lpm"      CR_TAB
3119                      "mov %C0,%3" CR_TAB
3120                      "adiw %2,1", xop, plen, 3);
3121
3122       if (n_bytes >= 4)
3123         avr_asm_len ("%4lpm"      CR_TAB
3124                      "mov %D0,%3" CR_TAB
3125                      "adiw %2,1", xop, plen, 3);
3126
3127       break; /* POST_INC */
3128
3129     } /* switch CODE (addr) */
3130
3131   return "";
3132 }
3133
3134
3135 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
3136    OP[1] in AS1 to register OP[0].
3137    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
3138    Return "".  */
3139
3140 const char*
3141 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
3142 {
3143   rtx xop[7];
3144   rtx dest = op[0];
3145   rtx src = SET_SRC (single_set (insn));
3146   rtx addr;
3147   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3148   int segment;
3149   RTX_CODE code;
3150   addr_space_t as = MEM_ADDR_SPACE (src);
3151
3152   if (plen)
3153     *plen = 0;
3154
3155   if (MEM_P (dest))
3156     {
3157       warning (0, "writing to address space %qs not supported",
3158                avr_addrspace[MEM_ADDR_SPACE (dest)].name);
3159
3160       return "";
3161     }
3162
3163   addr = XEXP (src, 0);
3164   code = GET_CODE (addr);
3165
3166   gcc_assert (REG_P (dest));
3167   gcc_assert (REG == code || POST_INC == code);
3168
3169   xop[0] = dest;
3170   xop[1] = addr;
3171   xop[2] = lpm_addr_reg_rtx;
3172   xop[4] = xstring_empty;
3173   xop[5] = tmp_reg_rtx;
3174   xop[6] = XEXP (rampz_rtx, 0);
3175
3176   segment = avr_addrspace[as].segment;
3177
3178   /* Set RAMPZ as needed.  */
3179
3180   if (segment)
3181     {
3182       xop[4] = GEN_INT (segment);
3183       xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
3184
3185       if (xop[3] != NULL_RTX)
3186         {
3187           avr_asm_len ("ldi %3,%4" CR_TAB
3188                        "out %i6,%3", xop, plen, 2);
3189         }
3190       else if (segment == 1)
3191         {
3192           avr_asm_len ("clr %5" CR_TAB
3193                        "inc %5" CR_TAB
3194                        "out %i6,%5", xop, plen, 3);
3195         }
3196       else
3197         {
3198           avr_asm_len ("mov %5,%2"         CR_TAB
3199                        "ldi %2,%4"         CR_TAB
3200                        "out %i6,%2"  CR_TAB
3201                        "mov %2,%5", xop, plen, 4);
3202         }
3203
3204       xop[4] = xstring_e;
3205
3206       if (!AVR_HAVE_ELPMX)
3207         return avr_out_lpm_no_lpmx (insn, xop, plen);
3208     }
3209   else if (!AVR_HAVE_LPMX)
3210     {
3211       return avr_out_lpm_no_lpmx (insn, xop, plen);
3212     }
3213
3214   /* We have [E]LPMX: Output reading from Flash the comfortable way.  */
3215
3216   switch (GET_CODE (addr))
3217     {
3218     default:
3219       gcc_unreachable();
3220
3221     case REG:
3222
3223       gcc_assert (REG_Z == REGNO (addr));
3224
3225       switch (n_bytes)
3226         {
3227         default:
3228           gcc_unreachable();
3229
3230         case 1:
3231           return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
3232
3233         case 2:
3234           if (REGNO (dest) == REG_Z)
3235             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3236                                 "%4lpm %B0,%a2" CR_TAB
3237                                 "mov %A0,%5", xop, plen, 3);
3238           else
3239             {
3240               avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3241                            "%4lpm %B0,%a2", xop, plen, 2);
3242
3243               if (!reg_unused_after (insn, addr))
3244                 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3245             }
3246
3247           break; /* 2 */
3248
3249         case 3:
3250
3251           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3252                        "%4lpm %B0,%a2+" CR_TAB
3253                        "%4lpm %C0,%a2", xop, plen, 3);
3254
3255           if (!reg_unused_after (insn, addr))
3256             avr_asm_len ("sbiw %2,2", xop, plen, 1);
3257
3258           break; /* 3 */
3259
3260         case 4:
3261
3262           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3263                        "%4lpm %B0,%a2+", xop, plen, 2);
3264
3265           if (REGNO (dest) == REG_Z - 2)
3266             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3267                                 "%4lpm %C0,%a2"          CR_TAB
3268                                 "mov %D0,%5", xop, plen, 3);
3269           else
3270             {
3271               avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3272                            "%4lpm %D0,%a2", xop, plen, 2);
3273
3274               if (!reg_unused_after (insn, addr))
3275                 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3276             }
3277
3278           break; /* 4 */
3279         } /* n_bytes */
3280
3281       break; /* REG */
3282
3283     case POST_INC:
3284
3285       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3286                   && n_bytes <= 4);
3287
3288       avr_asm_len                    ("%4lpm %A0,%a2+", xop, plen, 1);
3289       if (n_bytes >= 2)  avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3290       if (n_bytes >= 3)  avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3291       if (n_bytes >= 4)  avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3292
3293       break; /* POST_INC */
3294
3295     } /* switch CODE (addr) */
3296
3297   if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3298     {
3299       /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM.  */
3300
3301       xop[0] = zero_reg_rtx;
3302       avr_asm_len ("out %i6,%0", xop, plen, 1);
3303     }
3304
3305   return "";
3306 }
3307
3308
3309 /* Worker function for xload_8 insn.  */
3310
3311 const char*
3312 avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3313 {
3314   rtx xop[4];
3315
3316   xop[0] = op[0];
3317   xop[1] = op[1];
3318   xop[2] = lpm_addr_reg_rtx;
3319   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3320
3321   avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3322
3323   avr_asm_len ("sbrc %1,7" CR_TAB
3324                "ld %3,%a2", xop, plen, 2);
3325
3326   if (REGNO (xop[0]) != REGNO (xop[3]))
3327     avr_asm_len ("mov %0,%3", xop, plen, 1);
3328
3329   return "";
3330 }
3331
3332
3333 const char*
3334 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
3335 {
3336   rtx dest = operands[0];
3337   rtx src = operands[1];
3338
3339   if (avr_mem_flash_p (src)
3340       || avr_mem_flash_p (dest))
3341     {
3342       return avr_out_lpm (insn, operands, plen);
3343     }
3344
3345   gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3346
3347   if (REG_P (dest))
3348     {
3349       if (REG_P (src)) /* mov r,r */
3350         {
3351           if (test_hard_reg_class (STACK_REG, dest))
3352             return avr_asm_len ("out %0,%1", operands, plen, -1);
3353           else if (test_hard_reg_class (STACK_REG, src))
3354             return avr_asm_len ("in %0,%1", operands, plen, -1);
3355
3356           return avr_asm_len ("mov %0,%1", operands, plen, -1);
3357         }
3358       else if (CONSTANT_P (src))
3359         {
3360           output_reload_in_const (operands, NULL_RTX, plen, false);
3361           return "";
3362         }
3363       else if (MEM_P (src))
3364         return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3365     }
3366   else if (MEM_P (dest))
3367     {
3368       rtx xop[2];
3369
3370       xop[0] = dest;
3371       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3372
3373       return out_movqi_mr_r (insn, xop, plen);
3374     }
3375
3376   return "";
3377 }
3378
3379
3380 const char *
3381 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
3382 {
3383   rtx dest = xop[0];
3384   rtx src = xop[1];
3385
3386   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3387
3388   if (avr_mem_flash_p (src)
3389       || avr_mem_flash_p (dest))
3390     {
3391       return avr_out_lpm (insn, xop, plen);
3392     }
3393
3394   gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3395
3396   if (REG_P (dest))
3397     {
3398       if (REG_P (src)) /* mov r,r */
3399         {
3400           if (test_hard_reg_class (STACK_REG, dest))
3401             {
3402               if (AVR_HAVE_8BIT_SP)
3403                 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3404
3405               if (AVR_XMEGA)
3406                 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3407                                     "out __SP_H__,%B1", xop, plen, -2);
3408
3409               /* Use simple load of SP if no interrupts are  used.  */
3410
3411               return TARGET_NO_INTERRUPTS
3412                 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3413                                "out __SP_L__,%A1", xop, plen, -2)
3414                 : avr_asm_len ("in __tmp_reg__,__SREG__"  CR_TAB
3415                                "cli"                      CR_TAB
3416                                "out __SP_H__,%B1"         CR_TAB
3417                                "out __SREG__,__tmp_reg__" CR_TAB
3418                                "out __SP_L__,%A1", xop, plen, -5);
3419             }
3420           else if (test_hard_reg_class (STACK_REG, src))
3421             {
3422               return !AVR_HAVE_SPH
3423                 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3424                                "clr %B0", xop, plen, -2)
3425
3426                 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3427                                "in %B0,__SP_H__", xop, plen, -2);
3428             }
3429
3430           return AVR_HAVE_MOVW
3431             ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3432
3433             : avr_asm_len ("mov %A0,%A1" CR_TAB
3434                            "mov %B0,%B1", xop, plen, -2);
3435         } /* REG_P (src) */
3436       else if (CONSTANT_P (src))
3437         {
3438           return output_reload_inhi (xop, NULL, plen);
3439         }
3440       else if (MEM_P (src))
3441         {
3442           return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3443         }
3444     }
3445   else if (MEM_P (dest))
3446     {
3447       rtx xop[2];
3448
3449       xop[0] = dest;
3450       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3451
3452       return out_movhi_mr_r (insn, xop, plen);
3453     }
3454
3455   fatal_insn ("invalid insn:", insn);
3456
3457   return "";
3458 }
3459
3460
3461 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
3462
3463 static const char*
3464 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
3465 {
3466   rtx dest = op[0];
3467   rtx src = op[1];
3468   rtx x = XEXP (src, 0);
3469
3470   avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3471                "ld %0,%b1" , op, plen, -3);
3472
3473   if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3474       && !reg_unused_after (insn, XEXP (x,0)))
3475     avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
3476
3477   return "";
3478 }
3479
3480 static const char*
3481 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3482 {
3483   rtx dest = op[0];
3484   rtx src = op[1];
3485   rtx x = XEXP (src, 0);
3486
3487   if (CONSTANT_ADDRESS_P (x))
3488     {
3489       int n_words = AVR_TINY ? 1 : 2;
3490       return optimize > 0 && io_address_operand (x, QImode)
3491         ? avr_asm_len ("in %0,%i1", op, plen, -1)
3492         : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
3493     }
3494
3495   if (GET_CODE (x) == PLUS
3496            && REG_P (XEXP (x, 0))
3497            && CONST_INT_P (XEXP (x, 1)))
3498     {
3499       /* memory access by reg+disp */
3500
3501       int disp = INTVAL (XEXP (x, 1));
3502
3503       if (AVR_TINY)
3504         return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
3505
3506       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3507         {
3508           if (REGNO (XEXP (x, 0)) != REG_Y)
3509             fatal_insn ("incorrect insn:",insn);
3510
3511           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3512             return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3513                                 "ldd %0,Y+63"     CR_TAB
3514                                 "sbiw r28,%o1-63", op, plen, -3);
3515
3516           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3517                               "sbci r29,hi8(-%o1)" CR_TAB
3518                               "ld %0,Y"            CR_TAB
3519                               "subi r28,lo8(%o1)"  CR_TAB
3520                               "sbci r29,hi8(%o1)", op, plen, -5);
3521         }
3522       else if (REGNO (XEXP (x, 0)) == REG_X)
3523         {
3524           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3525              it but I have this situation with extremal optimizing options.  */
3526
3527           avr_asm_len ("adiw r26,%o1" CR_TAB
3528                        "ld %0,X", op, plen, -2);
3529
3530           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3531               && !reg_unused_after (insn, XEXP (x,0)))
3532             {
3533               avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3534             }
3535
3536           return "";
3537         }
3538
3539       return avr_asm_len ("ldd %0,%1", op, plen, -1);
3540     }
3541
3542   return avr_asm_len ("ld %0,%1", op, plen, -1);
3543 }
3544
3545
3546 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3547
3548 static const char*
3549 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
3550 {
3551   rtx dest = op[0];
3552   rtx src = op[1];
3553   rtx base = XEXP (src, 0);
3554
3555   int reg_dest = true_regnum (dest);
3556   int reg_base = true_regnum (base);
3557
3558   if (reg_dest == reg_base)         /* R = (R) */
3559     return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3560                         "ld %B0,%1"          CR_TAB
3561                         "mov %A0,__tmp_reg__", op, plen, -3);
3562
3563   return avr_asm_len ("ld %A0,%1"             CR_TAB
3564                       TINY_ADIW (%E1, %F1, 1) CR_TAB
3565                       "ld %B0,%1"             CR_TAB
3566                       TINY_SBIW (%E1, %F1, 1), op, plen, -6);
3567 }
3568
3569
3570 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3571
3572 static const char*
3573 avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
3574 {
3575   rtx dest = op[0];
3576   rtx src = op[1];
3577   rtx base = XEXP (src, 0);
3578
3579   int reg_dest = true_regnum (dest);
3580   int reg_base = true_regnum (XEXP (base, 0));
3581
3582   if (reg_base == reg_dest)
3583     {
3584       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3585                           "ld __tmp_reg__,%b1+"     CR_TAB
3586                           "ld %B0,%b1"              CR_TAB
3587                           "mov %A0,__tmp_reg__", op, plen, -5);
3588     }
3589   else
3590     {
3591       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3592                           "ld %A0,%b1+"             CR_TAB
3593                           "ld %B0,%b1"              CR_TAB
3594                           TINY_SBIW (%I1, %J1, %o1+1), op, plen, -6);
3595     }
3596 }
3597
3598
3599 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3600
3601 static const char*
3602 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
3603 {
3604   int mem_volatile_p = 0;
3605   rtx dest = op[0];
3606   rtx src = op[1];
3607   rtx base = XEXP (src, 0);
3608
3609   /* "volatile" forces reading low byte first, even if less efficient,
3610      for correct operation with 16-bit I/O registers.  */
3611   mem_volatile_p = MEM_VOLATILE_P (src);
3612
3613   if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3614     fatal_insn ("incorrect insn:", insn);
3615
3616   if (!mem_volatile_p)
3617     return avr_asm_len ("ld %B0,%1" CR_TAB
3618                         "ld %A0,%1", op, plen, -2);
3619
3620   return avr_asm_len (TINY_SBIW (%I1, %J1, 2)  CR_TAB
3621                       "ld %A0,%p1+"            CR_TAB
3622                       "ld %B0,%p1"             CR_TAB
3623                       TINY_SBIW (%I1, %J1, 1), op, plen, -6);
3624 }
3625
3626
3627 static const char*
3628 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3629 {
3630   rtx dest = op[0];
3631   rtx src = op[1];
3632   rtx base = XEXP (src, 0);
3633   int reg_dest = true_regnum (dest);
3634   int reg_base = true_regnum (base);
3635   /* "volatile" forces reading low byte first, even if less efficient,
3636      for correct operation with 16-bit I/O registers.  */
3637   int mem_volatile_p = MEM_VOLATILE_P (src);
3638
3639   if (reg_base > 0)
3640     {
3641       if (AVR_TINY)
3642         return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
3643
3644       if (reg_dest == reg_base)         /* R = (R) */
3645         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3646                             "ld %B0,%1"          CR_TAB
3647                             "mov %A0,__tmp_reg__", op, plen, -3);
3648
3649       if (reg_base != REG_X)
3650         return avr_asm_len ("ld %A0,%1" CR_TAB
3651                             "ldd %B0,%1+1", op, plen, -2);
3652
3653       avr_asm_len ("ld %A0,X+" CR_TAB
3654                    "ld %B0,X", op, plen, -2);
3655
3656       if (!reg_unused_after (insn, base))
3657         avr_asm_len ("sbiw r26,1", op, plen, 1);
3658
3659       return "";
3660     }
3661   else if (GET_CODE (base) == PLUS) /* (R + i) */
3662     {
3663       int disp = INTVAL (XEXP (base, 1));
3664       int reg_base = true_regnum (XEXP (base, 0));
3665
3666       if (AVR_TINY)
3667         return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
3668
3669       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3670         {
3671           if (REGNO (XEXP (base, 0)) != REG_Y)
3672             fatal_insn ("incorrect insn:",insn);
3673
3674           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3675             ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3676                            "ldd %A0,Y+62"    CR_TAB
3677                            "ldd %B0,Y+63"    CR_TAB
3678                            "sbiw r28,%o1-62", op, plen, -4)
3679
3680               : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3681                            "sbci r29,hi8(-%o1)" CR_TAB
3682                            "ld %A0,Y"           CR_TAB
3683                            "ldd %B0,Y+1"        CR_TAB
3684                            "subi r28,lo8(%o1)"  CR_TAB
3685                            "sbci r29,hi8(%o1)", op, plen, -6);
3686         }
3687
3688       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3689          it but I have this situation with extremal
3690          optimization options.  */
3691
3692       if (reg_base == REG_X)
3693         return reg_base == reg_dest
3694           ? avr_asm_len ("adiw r26,%o1"      CR_TAB
3695                          "ld __tmp_reg__,X+" CR_TAB
3696                          "ld %B0,X"          CR_TAB
3697                          "mov %A0,__tmp_reg__", op, plen, -4)
3698
3699           : avr_asm_len ("adiw r26,%o1" CR_TAB
3700                          "ld %A0,X+"    CR_TAB
3701                          "ld %B0,X"     CR_TAB
3702                          "sbiw r26,%o1+1", op, plen, -4);
3703
3704       return reg_base == reg_dest
3705         ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3706                        "ldd %B0,%B1"         CR_TAB
3707                        "mov %A0,__tmp_reg__", op, plen, -3)
3708
3709         : avr_asm_len ("ldd %A0,%A1" CR_TAB
3710                        "ldd %B0,%B1", op, plen, -2);
3711     }
3712   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3713     {
3714       if (AVR_TINY)
3715         return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
3716
3717       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3718         fatal_insn ("incorrect insn:", insn);
3719
3720       if (!mem_volatile_p)
3721         return avr_asm_len ("ld %B0,%1" CR_TAB
3722                             "ld %A0,%1", op, plen, -2);
3723
3724       return REGNO (XEXP (base, 0)) == REG_X
3725         ? avr_asm_len ("sbiw r26,2"  CR_TAB
3726                        "ld %A0,X+"   CR_TAB
3727                        "ld %B0,X"    CR_TAB
3728                        "sbiw r26,1", op, plen, -4)
3729
3730         : avr_asm_len ("sbiw %r1,2"  CR_TAB
3731                        "ld %A0,%p1"  CR_TAB
3732                        "ldd %B0,%p1+1", op, plen, -3);
3733     }
3734   else if (GET_CODE (base) == POST_INC) /* (R++) */
3735     {
3736       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3737         fatal_insn ("incorrect insn:", insn);
3738
3739       return avr_asm_len ("ld %A0,%1"  CR_TAB
3740                           "ld %B0,%1", op, plen, -2);
3741     }
3742   else if (CONSTANT_ADDRESS_P (base))
3743     {
3744       int n_words = AVR_TINY ? 2 : 4;
3745       return optimize > 0 && io_address_operand (base, HImode)
3746         ? avr_asm_len ("in %A0,%i1" CR_TAB
3747                        "in %B0,%i1+1", op, plen, -2)
3748
3749         : avr_asm_len ("lds %A0,%m1" CR_TAB
3750                        "lds %B0,%m1+1", op, plen, -n_words);
3751     }
3752
3753   fatal_insn ("unknown move insn:",insn);
3754   return "";
3755 }
3756
3757 static const char*
3758 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3759 {
3760   rtx dest = op[0];
3761   rtx src = op[1];
3762   rtx base = XEXP (src, 0);
3763   int reg_dest = true_regnum (dest);
3764   int reg_base = true_regnum (base);
3765
3766   if (reg_dest == reg_base)
3767     {
3768       /* "ld r26,-X" is undefined */
3769       return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
3770                       "ld %D0,%1"             CR_TAB
3771                       "ld %C0,-%1"            CR_TAB
3772                       "ld __tmp_reg__,-%1"    CR_TAB
3773                       TINY_SBIW (%E1, %F1, 1) CR_TAB
3774                       "ld %A0,%1"             CR_TAB
3775                       "mov %B0,__tmp_reg__");
3776     }
3777   else if (reg_dest == reg_base - 2)
3778     {
3779       return *l = 5, ("ld %A0,%1+"            CR_TAB
3780                       "ld %B0,%1+"            CR_TAB
3781                       "ld __tmp_reg__,%1+"    CR_TAB
3782                       "ld %D0,%1"             CR_TAB
3783                       "mov %C0,__tmp_reg__");
3784     }
3785   else if (reg_unused_after (insn, base))
3786     {
3787       return *l = 4, ("ld %A0,%1+"    CR_TAB
3788                       "ld %B0,%1+"    CR_TAB
3789                       "ld %C0,%1+"    CR_TAB
3790                       "ld %D0,%1");
3791     }
3792   else
3793     {
3794       return *l = 6, ("ld %A0,%1+"    CR_TAB
3795                       "ld %B0,%1+"    CR_TAB
3796                       "ld %C0,%1+"    CR_TAB
3797                       "ld %D0,%1"     CR_TAB
3798                       TINY_SBIW (%E1, %F1, 3));
3799     }
3800 }
3801
3802
3803 static const char*
3804 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3805 {
3806   rtx dest = op[0];
3807   rtx src = op[1];
3808   rtx base = XEXP (src, 0);
3809   int reg_dest = true_regnum (dest);
3810   int reg_base = true_regnum (XEXP (base, 0));
3811
3812   if (reg_dest == reg_base)
3813     {
3814       /* "ld r26,-X" is undefined */
3815       return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
3816                       "ld %D0,%b1"                CR_TAB
3817                       "ld %C0,-%b1"               CR_TAB
3818                       "ld __tmp_reg__,-%b1"       CR_TAB
3819                       TINY_SBIW (%I1, %J1, 1)     CR_TAB
3820                       "ld %A0,%b1"                CR_TAB
3821                       "mov %B0,__tmp_reg__");
3822     }
3823   else if (reg_dest == reg_base - 2)
3824     {
3825       return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3826                       "ld %A0,%b1+"             CR_TAB
3827                       "ld %B0,%b1+"             CR_TAB
3828                       "ld __tmp_reg__,%b1+"     CR_TAB
3829                       "ld %D0,%b1"              CR_TAB
3830                       "mov %C0,__tmp_reg__");
3831     }
3832   else if (reg_unused_after (insn, XEXP (base, 0)))
3833     {
3834       return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3835                       "ld %A0,%b1+"             CR_TAB
3836                       "ld %B0,%b1+"             CR_TAB
3837                       "ld %C0,%b1+"             CR_TAB
3838                       "ld %D0,%b1");
3839     }
3840   else
3841     {
3842       return *l = 8, (TINY_ADIW (%I1, %J1, %o1)  CR_TAB
3843                       "ld %A0,%b1+"              CR_TAB
3844                       "ld %B0,%b1+"              CR_TAB
3845                       "ld %C0,%b1+"              CR_TAB
3846                       "ld %D0,%b1"               CR_TAB
3847                       TINY_SBIW (%I1, %J1, %o1+3));
3848     }
3849 }
3850
3851 static const char*
3852 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
3853 {
3854   rtx dest = op[0];
3855   rtx src = op[1];
3856   rtx base = XEXP (src, 0);
3857   int reg_dest = true_regnum (dest);
3858   int reg_base = true_regnum (base);
3859   int tmp;
3860
3861   if (!l)
3862     l = &tmp;
3863
3864   if (reg_base > 0)
3865     {
3866       if (AVR_TINY)
3867         return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
3868
3869       if (reg_base == REG_X)        /* (R26) */
3870         {
3871           if (reg_dest == REG_X)
3872             /* "ld r26,-X" is undefined */
3873             return *l=7, ("adiw r26,3"        CR_TAB
3874                           "ld r29,X"          CR_TAB
3875                           "ld r28,-X"         CR_TAB
3876                           "ld __tmp_reg__,-X" CR_TAB
3877                           "sbiw r26,1"        CR_TAB
3878                           "ld r26,X"          CR_TAB
3879                           "mov r27,__tmp_reg__");
3880           else if (reg_dest == REG_X - 2)
3881             return *l=5, ("ld %A0,X+"          CR_TAB
3882                           "ld %B0,X+"          CR_TAB
3883                           "ld __tmp_reg__,X+"  CR_TAB
3884                           "ld %D0,X"           CR_TAB
3885                           "mov %C0,__tmp_reg__");
3886           else if (reg_unused_after (insn, base))
3887             return  *l=4, ("ld %A0,X+"  CR_TAB
3888                            "ld %B0,X+" CR_TAB
3889                            "ld %C0,X+" CR_TAB
3890                            "ld %D0,X");
3891           else
3892             return  *l=5, ("ld %A0,X+"  CR_TAB
3893                            "ld %B0,X+" CR_TAB
3894                            "ld %C0,X+" CR_TAB
3895                            "ld %D0,X"  CR_TAB
3896                            "sbiw r26,3");
3897         }
3898       else
3899         {
3900           if (reg_dest == reg_base)
3901             return *l=5, ("ldd %D0,%1+3" CR_TAB
3902                           "ldd %C0,%1+2" CR_TAB
3903                           "ldd __tmp_reg__,%1+1"  CR_TAB
3904                           "ld %A0,%1"  CR_TAB
3905                           "mov %B0,__tmp_reg__");
3906           else if (reg_base == reg_dest + 2)
3907             return *l=5, ("ld %A0,%1"             CR_TAB
3908                           "ldd %B0,%1+1"          CR_TAB
3909                           "ldd __tmp_reg__,%1+2"  CR_TAB
3910                           "ldd %D0,%1+3"          CR_TAB
3911                           "mov %C0,__tmp_reg__");
3912           else
3913             return *l=4, ("ld %A0,%1"    CR_TAB
3914                           "ldd %B0,%1+1" CR_TAB
3915                           "ldd %C0,%1+2" CR_TAB
3916                           "ldd %D0,%1+3");
3917         }
3918     }
3919   else if (GET_CODE (base) == PLUS) /* (R + i) */
3920     {
3921       int disp = INTVAL (XEXP (base, 1));
3922
3923       if (AVR_TINY)
3924         return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
3925
3926       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3927         {
3928           if (REGNO (XEXP (base, 0)) != REG_Y)
3929             fatal_insn ("incorrect insn:",insn);
3930
3931           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3932             return *l = 6, ("adiw r28,%o1-60" CR_TAB
3933                             "ldd %A0,Y+60"    CR_TAB
3934                             "ldd %B0,Y+61"    CR_TAB
3935                             "ldd %C0,Y+62"    CR_TAB
3936                             "ldd %D0,Y+63"    CR_TAB
3937                             "sbiw r28,%o1-60");
3938
3939           return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3940                           "sbci r29,hi8(-%o1)" CR_TAB
3941                           "ld %A0,Y"           CR_TAB
3942                           "ldd %B0,Y+1"        CR_TAB
3943                           "ldd %C0,Y+2"        CR_TAB
3944                           "ldd %D0,Y+3"        CR_TAB
3945                           "subi r28,lo8(%o1)"  CR_TAB
3946                           "sbci r29,hi8(%o1)");
3947         }
3948
3949       reg_base = true_regnum (XEXP (base, 0));
3950       if (reg_base == REG_X)
3951         {
3952           /* R = (X + d) */
3953           if (reg_dest == REG_X)
3954             {
3955               *l = 7;
3956               /* "ld r26,-X" is undefined */
3957               return ("adiw r26,%o1+3"    CR_TAB
3958                       "ld r29,X"          CR_TAB
3959                       "ld r28,-X"         CR_TAB
3960                       "ld __tmp_reg__,-X" CR_TAB
3961                       "sbiw r26,1"        CR_TAB
3962                       "ld r26,X"          CR_TAB
3963                       "mov r27,__tmp_reg__");
3964             }
3965           *l = 6;
3966           if (reg_dest == REG_X - 2)
3967             return ("adiw r26,%o1"      CR_TAB
3968                     "ld r24,X+"         CR_TAB
3969                     "ld r25,X+"         CR_TAB
3970                     "ld __tmp_reg__,X+" CR_TAB
3971                     "ld r27,X"          CR_TAB
3972                     "mov r26,__tmp_reg__");
3973
3974           return ("adiw r26,%o1" CR_TAB
3975                   "ld %A0,X+"    CR_TAB
3976                   "ld %B0,X+"    CR_TAB
3977                   "ld %C0,X+"    CR_TAB
3978                   "ld %D0,X"     CR_TAB
3979                   "sbiw r26,%o1+3");
3980         }
3981       if (reg_dest == reg_base)
3982         return *l=5, ("ldd %D0,%D1"          CR_TAB
3983                       "ldd %C0,%C1"          CR_TAB
3984                       "ldd __tmp_reg__,%B1"  CR_TAB
3985                       "ldd %A0,%A1"          CR_TAB
3986                       "mov %B0,__tmp_reg__");
3987       else if (reg_dest == reg_base - 2)
3988         return *l=5, ("ldd %A0,%A1"          CR_TAB
3989                       "ldd %B0,%B1"          CR_TAB
3990                       "ldd __tmp_reg__,%C1"  CR_TAB
3991                       "ldd %D0,%D1"          CR_TAB
3992                       "mov %C0,__tmp_reg__");
3993       return *l=4, ("ldd %A0,%A1" CR_TAB
3994                     "ldd %B0,%B1" CR_TAB
3995                     "ldd %C0,%C1" CR_TAB
3996                     "ldd %D0,%D1");
3997     }
3998   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3999     return *l=4, ("ld %D0,%1" CR_TAB
4000                   "ld %C0,%1" CR_TAB
4001                   "ld %B0,%1" CR_TAB
4002                   "ld %A0,%1");
4003   else if (GET_CODE (base) == POST_INC) /* (R++) */
4004     return *l=4, ("ld %A0,%1" CR_TAB
4005                   "ld %B0,%1" CR_TAB
4006                   "ld %C0,%1" CR_TAB
4007                   "ld %D0,%1");
4008   else if (CONSTANT_ADDRESS_P (base))
4009     {
4010       if (io_address_operand (base, SImode))
4011         {
4012           *l = 4;
4013           return ("in %A0,%i1"   CR_TAB
4014                   "in %B0,%i1+1" CR_TAB
4015                   "in %C0,%i1+2" CR_TAB
4016                   "in %D0,%i1+3");
4017         }
4018       else
4019         {
4020           *l = AVR_TINY ? 4 : 8;
4021           return ("lds %A0,%m1"   CR_TAB
4022                   "lds %B0,%m1+1" CR_TAB
4023                   "lds %C0,%m1+2" CR_TAB
4024                   "lds %D0,%m1+3");
4025         }
4026     }
4027
4028   fatal_insn ("unknown move insn:",insn);
4029   return "";
4030 }
4031
4032 static const char*
4033 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
4034 {
4035   rtx dest = op[0];
4036   rtx src = op[1];
4037   rtx base = XEXP (dest, 0);
4038   int reg_base = true_regnum (base);
4039   int reg_src = true_regnum (src);
4040
4041   if (reg_base == reg_src)
4042     {
4043           /* "ld r26,-X" is undefined */
4044       if (reg_unused_after (insn, base))
4045         {
4046           return *l = 7, ("mov __tmp_reg__, %B1"  CR_TAB
4047                           "st %0,%A1"             CR_TAB
4048                           TINY_ADIW (%E0, %F0, 1) CR_TAB
4049                           "st %0+,__tmp_reg__"    CR_TAB
4050                           "st %0+,%C1"            CR_TAB
4051                           "st %0+,%D1");
4052         }
4053       else
4054         {
4055           return *l = 9, ("mov __tmp_reg__, %B1"  CR_TAB
4056                           "st %0,%A1"             CR_TAB
4057                           TINY_ADIW (%E0, %F0, 1) CR_TAB
4058                           "st %0+,__tmp_reg__"    CR_TAB
4059                           "st %0+,%C1"            CR_TAB
4060                           "st %0+,%D1"            CR_TAB
4061                           TINY_SBIW (%E0, %F0, 3));
4062         }
4063     }
4064   else if (reg_base == reg_src + 2)
4065     {
4066       if (reg_unused_after (insn, base))
4067         return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
4068                         "mov __tmp_reg__,%D1"  CR_TAB
4069                         "st %0+,%A1"           CR_TAB
4070                         "st %0+,%B1"           CR_TAB
4071                         "st %0+,__zero_reg__"  CR_TAB
4072                         "st %0,__tmp_reg__"    CR_TAB
4073                         "clr __zero_reg__");
4074       else
4075         return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
4076                         "mov __tmp_reg__,%D1"  CR_TAB
4077                         "st %0+,%A1"           CR_TAB
4078                         "st %0+,%B1"           CR_TAB
4079                         "st %0+,__zero_reg__"  CR_TAB
4080                         "st %0,__tmp_reg__"    CR_TAB
4081                         "clr __zero_reg__"     CR_TAB
4082                         TINY_SBIW (%E0, %F0, 3));
4083     }
4084
4085   return *l = 6, ("st %0+,%A1" CR_TAB
4086                   "st %0+,%B1" CR_TAB
4087                   "st %0+,%C1" CR_TAB
4088                   "st %0,%D1"  CR_TAB
4089                   TINY_SBIW (%E0, %F0, 3));
4090 }
4091
4092 static const char*
4093 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
4094 {
4095   rtx dest = op[0];
4096   rtx src = op[1];
4097   rtx base = XEXP (dest, 0);
4098   int reg_base = REGNO (XEXP (base, 0));
4099   int reg_src =true_regnum (src);
4100
4101   if (reg_base == reg_src)
4102     {
4103       *l = 11;
4104       return ("mov __tmp_reg__,%A2"        CR_TAB
4105               "mov __zero_reg__,%B2"       CR_TAB
4106               TINY_ADIW (%I0, %J0, %o0)    CR_TAB
4107               "st %b0+,__tmp_reg__"        CR_TAB
4108               "st %b0+,__zero_reg__"       CR_TAB
4109               "st %b0+,%C2"                CR_TAB
4110               "st %b0,%D2"                 CR_TAB
4111               "clr __zero_reg__"           CR_TAB
4112               TINY_SBIW (%I0, %J0, %o0+3));
4113     }
4114   else if (reg_src == reg_base - 2)
4115     {
4116       *l = 11;
4117       return ("mov __tmp_reg__,%C2"         CR_TAB
4118               "mov __zero_reg__,%D2"        CR_TAB
4119               TINY_ADIW (%I0, %J0, %o0)     CR_TAB
4120               "st %b0+,%A0"                 CR_TAB
4121               "st %b0+,%B0"                 CR_TAB
4122               "st %b0+,__tmp_reg__"         CR_TAB
4123               "st %b0,__zero_reg__"         CR_TAB
4124               "clr __zero_reg__"            CR_TAB
4125               TINY_SBIW (%I0, %J0, %o0+3));
4126     }
4127   *l = 8;
4128   return (TINY_ADIW (%I0, %J0, %o0)     CR_TAB
4129           "st %b0+,%A1"                 CR_TAB
4130           "st %b0+,%B1"                 CR_TAB
4131           "st %b0+,%C1"                 CR_TAB
4132           "st %b0,%D1"                  CR_TAB
4133           TINY_SBIW (%I0, %J0, %o0+3));
4134 }
4135
4136 static const char*
4137 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
4138 {
4139   rtx dest = op[0];
4140   rtx src = op[1];
4141   rtx base = XEXP (dest, 0);
4142   int reg_base = true_regnum (base);
4143   int reg_src = true_regnum (src);
4144   int tmp;
4145
4146   if (!l)
4147     l = &tmp;
4148
4149   if (CONSTANT_ADDRESS_P (base))
4150     {
4151       if (io_address_operand (base, SImode))
4152         {
4153           return *l=4,("out %i0, %A1"  CR_TAB
4154                        "out %i0+1,%B1" CR_TAB
4155                        "out %i0+2,%C1" CR_TAB
4156                        "out %i0+3,%D1");
4157         }
4158       else
4159         {
4160           *l = AVR_TINY ? 4 : 8;
4161           return ("sts %m0,%A1"   CR_TAB
4162                   "sts %m0+1,%B1" CR_TAB
4163                   "sts %m0+2,%C1" CR_TAB
4164                   "sts %m0+3,%D1");
4165         }
4166     }
4167
4168   if (reg_base > 0)                 /* (r) */
4169     {
4170       if (AVR_TINY)
4171         return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
4172
4173       if (reg_base == REG_X)                /* (R26) */
4174         {
4175           if (reg_src == REG_X)
4176             {
4177               /* "st X+,r26" is undefined */
4178               if (reg_unused_after (insn, base))
4179                 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
4180                               "st X,r26"            CR_TAB
4181                               "adiw r26,1"          CR_TAB
4182                               "st X+,__tmp_reg__"   CR_TAB
4183                               "st X+,r28"           CR_TAB
4184                               "st X,r29");
4185               else
4186                 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
4187                               "st X,r26"            CR_TAB
4188                               "adiw r26,1"          CR_TAB
4189                               "st X+,__tmp_reg__"   CR_TAB
4190                               "st X+,r28"           CR_TAB
4191                               "st X,r29"            CR_TAB
4192                               "sbiw r26,3");
4193             }
4194           else if (reg_base == reg_src + 2)
4195             {
4196               if (reg_unused_after (insn, base))
4197                 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
4198                               "mov __tmp_reg__,%D1"  CR_TAB
4199                               "st %0+,%A1"           CR_TAB
4200                               "st %0+,%B1"           CR_TAB
4201                               "st %0+,__zero_reg__"  CR_TAB
4202                               "st %0,__tmp_reg__"    CR_TAB
4203                               "clr __zero_reg__");
4204               else
4205                 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
4206                               "mov __tmp_reg__,%D1"  CR_TAB
4207                               "st %0+,%A1"           CR_TAB
4208                               "st %0+,%B1"           CR_TAB
4209                               "st %0+,__zero_reg__"  CR_TAB
4210                               "st %0,__tmp_reg__"    CR_TAB
4211                               "clr __zero_reg__"     CR_TAB
4212                               "sbiw r26,3");
4213             }
4214           return *l=5, ("st %0+,%A1" CR_TAB
4215                         "st %0+,%B1" CR_TAB
4216                         "st %0+,%C1" CR_TAB
4217                         "st %0,%D1"  CR_TAB
4218                         "sbiw r26,3");
4219         }
4220       else
4221         return *l=4, ("st %0,%A1"    CR_TAB
4222                       "std %0+1,%B1" CR_TAB
4223                       "std %0+2,%C1" CR_TAB
4224                       "std %0+3,%D1");
4225     }
4226   else if (GET_CODE (base) == PLUS) /* (R + i) */
4227     {
4228       int disp = INTVAL (XEXP (base, 1));
4229
4230       if (AVR_TINY)
4231         return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
4232
4233       reg_base = REGNO (XEXP (base, 0));
4234       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4235         {
4236           if (reg_base != REG_Y)
4237             fatal_insn ("incorrect insn:",insn);
4238
4239           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4240             return *l = 6, ("adiw r28,%o0-60" CR_TAB
4241                             "std Y+60,%A1"    CR_TAB
4242                             "std Y+61,%B1"    CR_TAB
4243                             "std Y+62,%C1"    CR_TAB
4244                             "std Y+63,%D1"    CR_TAB
4245                             "sbiw r28,%o0-60");
4246
4247           return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
4248                           "sbci r29,hi8(-%o0)" CR_TAB
4249                           "st Y,%A1"           CR_TAB
4250                           "std Y+1,%B1"        CR_TAB
4251                           "std Y+2,%C1"        CR_TAB
4252                           "std Y+3,%D1"        CR_TAB
4253                           "subi r28,lo8(%o0)"  CR_TAB
4254                           "sbci r29,hi8(%o0)");
4255         }
4256       if (reg_base == REG_X)
4257         {
4258           /* (X + d) = R */
4259           if (reg_src == REG_X)
4260             {
4261               *l = 9;
4262               return ("mov __tmp_reg__,r26"  CR_TAB
4263                       "mov __zero_reg__,r27" CR_TAB
4264                       "adiw r26,%o0"         CR_TAB
4265                       "st X+,__tmp_reg__"    CR_TAB
4266                       "st X+,__zero_reg__"   CR_TAB
4267                       "st X+,r28"            CR_TAB
4268                       "st X,r29"             CR_TAB
4269                       "clr __zero_reg__"     CR_TAB
4270                       "sbiw r26,%o0+3");
4271             }
4272           else if (reg_src == REG_X - 2)
4273             {
4274               *l = 9;
4275               return ("mov __tmp_reg__,r26"  CR_TAB
4276                       "mov __zero_reg__,r27" CR_TAB
4277                       "adiw r26,%o0"         CR_TAB
4278                       "st X+,r24"            CR_TAB
4279                       "st X+,r25"            CR_TAB
4280                       "st X+,__tmp_reg__"    CR_TAB
4281                       "st X,__zero_reg__"    CR_TAB
4282                       "clr __zero_reg__"     CR_TAB
4283                       "sbiw r26,%o0+3");
4284             }
4285           *l = 6;
4286           return ("adiw r26,%o0" CR_TAB
4287                   "st X+,%A1"    CR_TAB
4288                   "st X+,%B1"    CR_TAB
4289                   "st X+,%C1"    CR_TAB
4290                   "st X,%D1"     CR_TAB
4291                   "sbiw r26,%o0+3");
4292         }
4293       return *l=4, ("std %A0,%A1" CR_TAB
4294                     "std %B0,%B1" CR_TAB
4295                     "std %C0,%C1" CR_TAB
4296                     "std %D0,%D1");
4297     }
4298   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4299     return *l=4, ("st %0,%D1" CR_TAB
4300                   "st %0,%C1" CR_TAB
4301                   "st %0,%B1" CR_TAB
4302                   "st %0,%A1");
4303   else if (GET_CODE (base) == POST_INC) /* (R++) */
4304     return *l=4, ("st %0,%A1" CR_TAB
4305                   "st %0,%B1" CR_TAB
4306                   "st %0,%C1" CR_TAB
4307                   "st %0,%D1");
4308   fatal_insn ("unknown move insn:",insn);
4309   return "";
4310 }
4311
4312 const char *
4313 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
4314 {
4315   int dummy;
4316   rtx dest = operands[0];
4317   rtx src = operands[1];
4318   int *real_l = l;
4319
4320   if (avr_mem_flash_p (src)
4321       || avr_mem_flash_p (dest))
4322     {
4323       return avr_out_lpm (insn, operands, real_l);
4324     }
4325
4326   if (!l)
4327     l = &dummy;
4328
4329   gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
4330   if (REG_P (dest))
4331     {
4332       if (REG_P (src)) /* mov r,r */
4333         {
4334           if (true_regnum (dest) > true_regnum (src))
4335             {
4336               if (AVR_HAVE_MOVW)
4337                 {
4338                   *l = 2;
4339                   return ("movw %C0,%C1" CR_TAB
4340                           "movw %A0,%A1");
4341                 }
4342               *l = 4;
4343               return ("mov %D0,%D1" CR_TAB
4344                       "mov %C0,%C1" CR_TAB
4345                       "mov %B0,%B1" CR_TAB
4346                       "mov %A0,%A1");
4347             }
4348           else
4349             {
4350               if (AVR_HAVE_MOVW)
4351                 {
4352                   *l = 2;
4353                   return ("movw %A0,%A1" CR_TAB
4354                           "movw %C0,%C1");
4355                 }
4356               *l = 4;
4357               return ("mov %A0,%A1" CR_TAB
4358                       "mov %B0,%B1" CR_TAB
4359                       "mov %C0,%C1" CR_TAB
4360                       "mov %D0,%D1");
4361             }
4362         }
4363       else if (CONSTANT_P (src))
4364         {
4365           return output_reload_insisf (operands, NULL_RTX, real_l);
4366         }
4367       else if (MEM_P (src))
4368         return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
4369     }
4370   else if (MEM_P (dest))
4371     {
4372       const char *templ;
4373
4374       if (src == CONST0_RTX (GET_MODE (dest)))
4375           operands[1] = zero_reg_rtx;
4376
4377       templ = out_movsi_mr_r (insn, operands, real_l);
4378
4379       if (!real_l)
4380         output_asm_insn (templ, operands);
4381
4382       operands[1] = src;
4383       return "";
4384     }
4385   fatal_insn ("invalid insn:", insn);
4386   return "";
4387 }
4388
4389
4390 /* Handle loads of 24-bit types from memory to register.  */
4391
4392 static const char*
4393 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4394 {
4395   rtx dest = op[0];
4396   rtx src = op[1];
4397   rtx base = XEXP (src, 0);
4398   int reg_dest = true_regnum (dest);
4399   int reg_base = true_regnum (base);
4400
4401   if (reg_base == reg_dest)
4402     {
4403       return avr_asm_len (TINY_ADIW (%E1, %F1, 2)   CR_TAB
4404                           "ld %C0,%1"               CR_TAB
4405                           "ld __tmp_reg__,-%1"      CR_TAB
4406                           TINY_SBIW (%E1, %F1, 1)   CR_TAB
4407                           "ld %A0,%1"               CR_TAB
4408                           "mov %B0,__tmp_reg__", op, plen, -8);
4409     }
4410   else
4411     {
4412       avr_asm_len ("ld %A0,%1+"  CR_TAB
4413                    "ld %B0,%1+"  CR_TAB
4414                    "ld %C0,%1", op, plen, -3);
4415
4416       if (reg_dest != reg_base - 2 &&
4417           !reg_unused_after (insn, base))
4418         {
4419           avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
4420         }
4421       return "";
4422     }
4423 }
4424
4425 static const char*
4426 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4427 {
4428   rtx dest = op[0];
4429   rtx src = op[1];
4430   rtx base = XEXP (src, 0);
4431   int reg_dest = true_regnum (dest);
4432   int reg_base = true_regnum (base);
4433
4434   reg_base = true_regnum (XEXP (base, 0));
4435   if (reg_base == reg_dest)
4436     {
4437       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
4438                           "ld %C0,%b1"                CR_TAB
4439                           "ld __tmp_reg__,-%b1"       CR_TAB
4440                           TINY_SBIW (%I1, %J1, 1)     CR_TAB
4441                           "ld %A0,%b1"                CR_TAB
4442                           "mov %B0,__tmp_reg__", op, plen, -8);
4443    }
4444   else
4445     {
4446       avr_asm_len (TINY_ADIW (%I1, %J1, %o1)   CR_TAB
4447                           "ld %A0,%b1+"              CR_TAB
4448                           "ld %B0,%b1+"              CR_TAB
4449                           "ld %C0,%b1", op, plen, -5);
4450
4451       if (reg_dest != (reg_base - 2)
4452           && !reg_unused_after (insn, XEXP (base, 0)))
4453           avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
4454
4455       return "";
4456     }
4457 }
4458
4459 static const char*
4460 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
4461 {
4462   rtx dest = op[0];
4463   rtx src = op[1];
4464   rtx base = XEXP (src, 0);
4465   int reg_dest = true_regnum (dest);
4466   int reg_base = true_regnum (base);
4467
4468   if (reg_base > 0)
4469     {
4470       if (AVR_TINY)
4471         return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
4472
4473       if (reg_base == REG_X)        /* (R26) */
4474         {
4475           if (reg_dest == REG_X)
4476             /* "ld r26,-X" is undefined */
4477             return avr_asm_len ("adiw r26,2"        CR_TAB
4478                                 "ld r28,X"          CR_TAB
4479                                 "ld __tmp_reg__,-X" CR_TAB
4480                                 "sbiw r26,1"        CR_TAB
4481                                 "ld r26,X"          CR_TAB
4482                                 "mov r27,__tmp_reg__", op, plen, -6);
4483           else
4484             {
4485               avr_asm_len ("ld %A0,X+" CR_TAB
4486                            "ld %B0,X+" CR_TAB
4487                            "ld %C0,X", op, plen, -3);
4488
4489               if (reg_dest != REG_X - 2
4490                   && !reg_unused_after (insn, base))
4491                 {
4492                   avr_asm_len ("sbiw r26,2", op, plen, 1);
4493                 }
4494
4495               return "";
4496             }
4497         }
4498       else /* reg_base != REG_X */
4499         {
4500           if (reg_dest == reg_base)
4501             return avr_asm_len ("ldd %C0,%1+2"          CR_TAB
4502                                 "ldd __tmp_reg__,%1+1"  CR_TAB
4503                                 "ld  %A0,%1"            CR_TAB
4504                                 "mov %B0,__tmp_reg__", op, plen, -4);
4505           else
4506             return avr_asm_len ("ld  %A0,%1"    CR_TAB
4507                                 "ldd %B0,%1+1"  CR_TAB
4508                                 "ldd %C0,%1+2", op, plen, -3);
4509         }
4510     }
4511   else if (GET_CODE (base) == PLUS) /* (R + i) */
4512     {
4513       int disp = INTVAL (XEXP (base, 1));
4514
4515       if (AVR_TINY)
4516         return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
4517
4518       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
4519         {
4520           if (REGNO (XEXP (base, 0)) != REG_Y)
4521             fatal_insn ("incorrect insn:",insn);
4522
4523           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4524             return avr_asm_len ("adiw r28,%o1-61" CR_TAB
4525                                 "ldd %A0,Y+61"    CR_TAB
4526                                 "ldd %B0,Y+62"    CR_TAB
4527                                 "ldd %C0,Y+63"    CR_TAB
4528                                 "sbiw r28,%o1-61", op, plen, -5);
4529
4530           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4531                               "sbci r29,hi8(-%o1)" CR_TAB
4532                               "ld  %A0,Y"           CR_TAB
4533                               "ldd %B0,Y+1"        CR_TAB
4534                               "ldd %C0,Y+2"        CR_TAB
4535                               "subi r28,lo8(%o1)"  CR_TAB
4536                               "sbci r29,hi8(%o1)", op, plen, -7);
4537         }
4538
4539       reg_base = true_regnum (XEXP (base, 0));
4540       if (reg_base == REG_X)
4541         {
4542           /* R = (X + d) */
4543           if (reg_dest == REG_X)
4544             {
4545               /* "ld r26,-X" is undefined */
4546               return avr_asm_len ("adiw r26,%o1+2"     CR_TAB
4547                                   "ld  r28,X"          CR_TAB
4548                                   "ld  __tmp_reg__,-X" CR_TAB
4549                                   "sbiw r26,1"         CR_TAB
4550                                   "ld  r26,X"          CR_TAB
4551                                   "mov r27,__tmp_reg__", op, plen, -6);
4552             }
4553
4554           avr_asm_len ("adiw r26,%o1" CR_TAB
4555                        "ld %A0,X+"    CR_TAB
4556                        "ld %B0,X+"    CR_TAB
4557                        "ld %C0,X", op, plen, -4);
4558
4559           if (reg_dest != REG_W
4560               && !reg_unused_after (insn, XEXP (base, 0)))
4561             avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
4562
4563           return "";
4564         }
4565
4566       if (reg_dest == reg_base)
4567         return avr_asm_len ("ldd %C0,%C1" CR_TAB
4568                             "ldd __tmp_reg__,%B1"  CR_TAB
4569                             "ldd %A0,%A1" CR_TAB
4570                             "mov %B0,__tmp_reg__", op, plen, -4);
4571
4572         return avr_asm_len ("ldd %A0,%A1" CR_TAB
4573                             "ldd %B0,%B1" CR_TAB
4574                             "ldd %C0,%C1", op, plen, -3);
4575     }
4576   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4577     return avr_asm_len ("ld %C0,%1" CR_TAB
4578                         "ld %B0,%1" CR_TAB
4579                         "ld %A0,%1", op, plen, -3);
4580   else if (GET_CODE (base) == POST_INC) /* (R++) */
4581     return avr_asm_len ("ld %A0,%1" CR_TAB
4582                         "ld %B0,%1" CR_TAB
4583                         "ld %C0,%1", op, plen, -3);
4584
4585   else if (CONSTANT_ADDRESS_P (base))
4586     {
4587       int n_words = AVR_TINY ? 3 : 6;
4588       return avr_asm_len ("lds %A0,%m1" CR_TAB
4589                           "lds %B0,%m1+1" CR_TAB
4590                           "lds %C0,%m1+2", op, plen , -n_words);
4591     }
4592
4593   fatal_insn ("unknown move insn:",insn);
4594   return "";
4595 }
4596
4597
4598 static const char*
4599 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4600 {
4601   rtx dest = op[0];
4602   rtx src = op[1];
4603   rtx base = XEXP (dest, 0);
4604   int reg_base = true_regnum (base);
4605   int reg_src = true_regnum (src);
4606
4607   if (reg_base == reg_src)
4608     {
4609       avr_asm_len ("st %0,%A1"              CR_TAB
4610                    "mov __tmp_reg__,%B1"    CR_TAB
4611                    TINY_ADIW (%E0, %F0, 1)  CR_TAB /* st X+, r27 is undefined */
4612                    "st %0+,__tmp_reg__"     CR_TAB
4613                    "st %0,%C1", op, plen, -6);
4614
4615     }
4616   else if (reg_src == reg_base - 2)
4617     {
4618       avr_asm_len ("st %0,%A1"              CR_TAB
4619                    "mov __tmp_reg__,%C1"    CR_TAB
4620                    TINY_ADIW (%E0, %F0, 1)  CR_TAB
4621                    "st %0+,%B1"             CR_TAB
4622                    "st %0,__tmp_reg__", op, plen, 6);
4623     }
4624   else
4625     {
4626       avr_asm_len ("st %0+,%A1"  CR_TAB
4627                    "st %0+,%B1" CR_TAB
4628                    "st %0,%C1", op, plen, -3);
4629     }
4630
4631   if (!reg_unused_after (insn, base))
4632     avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
4633
4634   return "";
4635 }
4636
4637 static const char*
4638 avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
4639 {
4640   rtx dest = op[0];
4641   rtx src = op[1];
4642   rtx base = XEXP (dest, 0);
4643   int reg_base = REGNO (XEXP (base, 0));
4644   int reg_src = true_regnum (src);
4645
4646   if (reg_src == reg_base)
4647     {
4648       return avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
4649                           "mov __zero_reg__,%B1"         CR_TAB
4650                           TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4651                           "st %b0+,__tmp_reg__"          CR_TAB
4652                           "st %b0+,__zero_reg__"         CR_TAB
4653                           "st %b0,%C1"                   CR_TAB
4654                           "clr __zero_reg__"             CR_TAB
4655                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -10);
4656     }
4657   else if (reg_src == reg_base - 2)
4658     {
4659       return avr_asm_len ("mov __tmp_reg__,%C1"          CR_TAB
4660                           TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4661                           "st %b0+,%A1"                  CR_TAB
4662                           "st %b0+,%B1"                  CR_TAB
4663                           "st %b0,__tmp_reg__"           CR_TAB
4664                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -8);
4665     }
4666
4667   return avr_asm_len (TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4668                           "st %b0+,%A1"                  CR_TAB
4669                           "st %b0+,%B1"                  CR_TAB
4670                           "st %b0,%C1"                   CR_TAB
4671                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -7);
4672 }
4673
4674 /* Handle store of 24-bit type from register or zero to memory.  */
4675
4676 static const char*
4677 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
4678 {
4679   rtx dest = op[0];
4680   rtx src = op[1];
4681   rtx base = XEXP (dest, 0);
4682   int reg_base = true_regnum (base);
4683
4684   if (CONSTANT_ADDRESS_P (base))
4685     {
4686       int n_words = AVR_TINY ? 3 : 6;
4687       return avr_asm_len ("sts %m0,%A1"   CR_TAB
4688                           "sts %m0+1,%B1" CR_TAB
4689                           "sts %m0+2,%C1", op, plen, -n_words);
4690     }
4691
4692   if (reg_base > 0)                 /* (r) */
4693     {
4694       if (AVR_TINY)
4695         return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
4696
4697       if (reg_base == REG_X)        /* (R26) */
4698         {
4699           gcc_assert (!reg_overlap_mentioned_p (base, src));
4700
4701           avr_asm_len ("st %0+,%A1"  CR_TAB
4702                        "st %0+,%B1" CR_TAB
4703                        "st %0,%C1", op, plen, -3);
4704
4705           if (!reg_unused_after (insn, base))
4706             avr_asm_len ("sbiw r26,2", op, plen, 1);
4707
4708           return "";
4709         }
4710       else
4711         return avr_asm_len ("st %0,%A1"    CR_TAB
4712                             "std %0+1,%B1" CR_TAB
4713                             "std %0+2,%C1", op, plen, -3);
4714     }
4715   else if (GET_CODE (base) == PLUS) /* (R + i) */
4716     {
4717       int disp = INTVAL (XEXP (base, 1));
4718
4719       if (AVR_TINY)
4720         return avr_out_store_psi_reg_disp_tiny (op, plen);
4721
4722       reg_base = REGNO (XEXP (base, 0));
4723
4724       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4725         {
4726           if (reg_base != REG_Y)
4727             fatal_insn ("incorrect insn:",insn);
4728
4729           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4730             return avr_asm_len ("adiw r28,%o0-61" CR_TAB
4731                                 "std Y+61,%A1"    CR_TAB
4732                                 "std Y+62,%B1"    CR_TAB
4733                                 "std Y+63,%C1"    CR_TAB
4734                                 "sbiw r28,%o0-61", op, plen, -5);
4735
4736           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4737                               "sbci r29,hi8(-%o0)" CR_TAB
4738                               "st Y,%A1"           CR_TAB
4739                               "std Y+1,%B1"        CR_TAB
4740                               "std Y+2,%C1"        CR_TAB
4741                               "subi r28,lo8(%o0)"  CR_TAB
4742                               "sbci r29,hi8(%o0)", op, plen, -7);
4743         }
4744       if (reg_base == REG_X)
4745         {
4746           /* (X + d) = R */
4747           gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
4748
4749           avr_asm_len ("adiw r26,%o0" CR_TAB
4750                        "st X+,%A1"    CR_TAB
4751                        "st X+,%B1"    CR_TAB
4752                        "st X,%C1", op, plen, -4);
4753
4754           if (!reg_unused_after (insn, XEXP (base, 0)))
4755             avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4756
4757           return "";
4758         }
4759
4760       return avr_asm_len ("std %A0,%A1" CR_TAB
4761                           "std %B0,%B1" CR_TAB
4762                           "std %C0,%C1", op, plen, -3);
4763     }
4764   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4765     return avr_asm_len ("st %0,%C1" CR_TAB
4766                         "st %0,%B1" CR_TAB
4767                         "st %0,%A1", op, plen, -3);
4768   else if (GET_CODE (base) == POST_INC) /* (R++) */
4769     return avr_asm_len ("st %0,%A1" CR_TAB
4770                         "st %0,%B1" CR_TAB
4771                         "st %0,%C1", op, plen, -3);
4772
4773   fatal_insn ("unknown move insn:",insn);
4774   return "";
4775 }
4776
4777
4778 /* Move around 24-bit stuff.  */
4779
4780 const char *
4781 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
4782 {
4783   rtx dest = op[0];
4784   rtx src = op[1];
4785
4786   if (avr_mem_flash_p (src)
4787       || avr_mem_flash_p (dest))
4788     {
4789       return avr_out_lpm (insn, op, plen);
4790     }
4791
4792   if (register_operand (dest, VOIDmode))
4793     {
4794       if (register_operand (src, VOIDmode)) /* mov r,r */
4795         {
4796           if (true_regnum (dest) > true_regnum (src))
4797             {
4798               avr_asm_len ("mov %C0,%C1", op, plen, -1);
4799
4800               if (AVR_HAVE_MOVW)
4801                 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4802               else
4803                 return avr_asm_len ("mov %B0,%B1"  CR_TAB
4804                                     "mov %A0,%A1", op, plen, 2);
4805             }
4806           else
4807             {
4808               if (AVR_HAVE_MOVW)
4809                 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4810               else
4811                 avr_asm_len ("mov %A0,%A1"  CR_TAB
4812                              "mov %B0,%B1", op, plen, -2);
4813
4814               return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4815             }
4816         }
4817       else if (CONSTANT_P (src))
4818         {
4819           return avr_out_reload_inpsi (op, NULL_RTX, plen);
4820         }
4821       else if (MEM_P (src))
4822         return avr_out_load_psi (insn, op, plen); /* mov r,m */
4823     }
4824   else if (MEM_P (dest))
4825     {
4826       rtx xop[2];
4827
4828       xop[0] = dest;
4829       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4830
4831       return avr_out_store_psi (insn, xop, plen);
4832     }
4833
4834   fatal_insn ("invalid insn:", insn);
4835   return "";
4836 }
4837
4838 static const char*
4839 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4840 {
4841   rtx dest = op[0];
4842   rtx src = op[1];
4843   rtx x = XEXP (dest, 0);
4844
4845   if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4846     {
4847       avr_asm_len ("mov __tmp_reg__,%1"      CR_TAB
4848                    TINY_ADIW (%I0, %J0, %o0) CR_TAB
4849                    "st %b0,__tmp_reg__", op, plen, -4);
4850     }
4851     else
4852     {
4853       avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4854           "st %b0,%1" , op, plen, -3);
4855     }
4856
4857   if (!reg_unused_after (insn, XEXP (x,0)))
4858       avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
4859
4860   return "";
4861 }
4862
4863 static const char*
4864 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
4865 {
4866   rtx dest = op[0];
4867   rtx src = op[1];
4868   rtx x = XEXP (dest, 0);
4869
4870   if (CONSTANT_ADDRESS_P (x))
4871     {
4872       int n_words = AVR_TINY ? 1 : 2;
4873       return optimize > 0 && io_address_operand (x, QImode)
4874         ? avr_asm_len ("out %i0,%1", op, plen, -1)
4875         : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
4876     }
4877   else if (GET_CODE (x) == PLUS
4878            && REG_P (XEXP (x, 0))
4879            && CONST_INT_P (XEXP (x, 1)))
4880     {
4881       /* memory access by reg+disp */
4882
4883       int disp = INTVAL (XEXP (x, 1));
4884
4885       if (AVR_TINY)
4886         return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
4887
4888       if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4889         {
4890           if (REGNO (XEXP (x, 0)) != REG_Y)
4891             fatal_insn ("incorrect insn:",insn);
4892
4893           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4894             return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4895                                 "std Y+63,%1"     CR_TAB
4896                                 "sbiw r28,%o0-63", op, plen, -3);
4897
4898           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4899                               "sbci r29,hi8(-%o0)" CR_TAB
4900                               "st Y,%1"            CR_TAB
4901                               "subi r28,lo8(%o0)"  CR_TAB
4902                               "sbci r29,hi8(%o0)", op, plen, -5);
4903         }
4904       else if (REGNO (XEXP (x,0)) == REG_X)
4905         {
4906           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4907             {
4908               avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4909                            "adiw r26,%o0"       CR_TAB
4910                            "st X,__tmp_reg__", op, plen, -3);
4911             }
4912           else
4913             {
4914               avr_asm_len ("adiw r26,%o0" CR_TAB
4915                            "st X,%1", op, plen, -2);
4916             }
4917
4918           if (!reg_unused_after (insn, XEXP (x,0)))
4919             avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4920
4921           return "";
4922         }
4923
4924       return avr_asm_len ("std %0,%1", op, plen, -1);
4925     }
4926
4927   return avr_asm_len ("st %0,%1", op, plen, -1);
4928 }
4929
4930
4931 /* Helper for the next function for XMEGA.  It does the same
4932    but with low byte first.  */
4933
4934 static const char*
4935 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
4936 {
4937   rtx dest = op[0];
4938   rtx src = op[1];
4939   rtx base = XEXP (dest, 0);
4940   int reg_base = true_regnum (base);
4941   int reg_src = true_regnum (src);
4942
4943   /* "volatile" forces writing low byte first, even if less efficient,
4944      for correct operation with 16-bit I/O registers like SP.  */
4945   int mem_volatile_p = MEM_VOLATILE_P (dest);
4946
4947   if (CONSTANT_ADDRESS_P (base))
4948     {
4949       int n_words = AVR_TINY ? 2 : 4;
4950       return optimize > 0 && io_address_operand (base, HImode)
4951         ? avr_asm_len ("out %i0,%A1" CR_TAB
4952                        "out %i0+1,%B1", op, plen, -2)
4953
4954         : avr_asm_len ("sts %m0,%A1" CR_TAB
4955                        "sts %m0+1,%B1", op, plen, -n_words);
4956     }
4957
4958   if (reg_base > 0)
4959     {
4960       if (reg_base != REG_X)
4961         return avr_asm_len ("st %0,%A1" CR_TAB
4962                             "std %0+1,%B1", op, plen, -2);
4963
4964       if (reg_src == REG_X)
4965         /* "st X+,r26" and "st -X,r26" are undefined.  */
4966         avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4967                      "st X,r26"            CR_TAB
4968                      "adiw r26,1"          CR_TAB
4969                      "st X,__tmp_reg__", op, plen, -4);
4970       else
4971         avr_asm_len ("st X+,%A1" CR_TAB
4972                      "st X,%B1", op, plen, -2);
4973
4974       return reg_unused_after (insn, base)
4975         ? ""
4976         : avr_asm_len ("sbiw r26,1", op, plen, 1);
4977     }
4978   else if (GET_CODE (base) == PLUS)
4979     {
4980       int disp = INTVAL (XEXP (base, 1));
4981       reg_base = REGNO (XEXP (base, 0));
4982       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4983         {
4984           if (reg_base != REG_Y)
4985             fatal_insn ("incorrect insn:",insn);
4986
4987           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
4988             ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
4989                            "std Y+62,%A1"    CR_TAB
4990                            "std Y+63,%B1"    CR_TAB
4991                            "sbiw r28,%o0-62", op, plen, -4)
4992
4993             : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4994                            "sbci r29,hi8(-%o0)" CR_TAB
4995                            "st Y,%A1"           CR_TAB
4996                            "std Y+1,%B1"        CR_TAB
4997                            "subi r28,lo8(%o0)"  CR_TAB
4998                            "sbci r29,hi8(%o0)", op, plen, -6);
4999         }
5000
5001       if (reg_base != REG_X)
5002         return avr_asm_len ("std %A0,%A1" CR_TAB
5003                             "std %B0,%B1", op, plen, -2);
5004       /* (X + d) = R */
5005       return reg_src == REG_X
5006         ? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
5007                        "mov __zero_reg__,r27" CR_TAB
5008                        "adiw r26,%o0"         CR_TAB
5009                        "st X+,__tmp_reg__"    CR_TAB
5010                        "st X,__zero_reg__"    CR_TAB
5011                        "clr __zero_reg__"     CR_TAB
5012                        "sbiw r26,%o0+1", op, plen, -7)
5013
5014         : avr_asm_len ("adiw r26,%o0" CR_TAB
5015                        "st X+,%A1"    CR_TAB
5016                        "st X,%B1"     CR_TAB
5017                        "sbiw r26,%o0+1", op, plen, -4);
5018     }
5019   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5020     {
5021       if (!mem_volatile_p)
5022         return avr_asm_len ("st %0,%B1" CR_TAB
5023                             "st %0,%A1", op, plen, -2);
5024
5025       return REGNO (XEXP (base, 0)) == REG_X
5026         ? avr_asm_len ("sbiw r26,2"  CR_TAB
5027                        "st X+,%A1"   CR_TAB
5028                        "st X,%B1"    CR_TAB
5029                        "sbiw r26,1", op, plen, -4)
5030
5031         : avr_asm_len ("sbiw %r0,2"  CR_TAB
5032                        "st %p0,%A1"  CR_TAB
5033                        "std %p0+1,%B1", op, plen, -3);
5034     }
5035   else if (GET_CODE (base) == POST_INC) /* (R++) */
5036     {
5037       return avr_asm_len ("st %0,%A1"  CR_TAB
5038                           "st %0,%B1", op, plen, -2);
5039
5040     }
5041   fatal_insn ("unknown move insn:",insn);
5042   return "";
5043 }
5044
5045 static const char*
5046 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
5047 {
5048   rtx dest = op[0];
5049   rtx src = op[1];
5050   rtx base = XEXP (dest, 0);
5051   int reg_base = true_regnum (base);
5052   int reg_src = true_regnum (src);
5053   int mem_volatile_p = MEM_VOLATILE_P (dest);
5054
5055   if (reg_base == reg_src)
5056     {
5057       return !mem_volatile_p && reg_unused_after (insn, src)
5058         ? avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
5059                        "st %0,%A1"             CR_TAB
5060                        TINY_ADIW (%E0, %F0, 1) CR_TAB
5061                        "st %0,__tmp_reg__", op, plen, -5)
5062         : avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
5063                        TINY_ADIW (%E0, %F0, 1) CR_TAB
5064                        "st %0,__tmp_reg__"      CR_TAB
5065                        TINY_SBIW (%E0, %F0, 1) CR_TAB
5066                        "st %0, %A1", op, plen, -7);
5067     }
5068
5069   return !mem_volatile_p && reg_unused_after (insn, base)
5070       ? avr_asm_len ("st %0+,%A1" CR_TAB
5071                      "st %0,%B1", op, plen, -2)
5072       : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
5073                      "st %0,%B1"             CR_TAB
5074                      "st -%0,%A1", op, plen, -4);
5075 }
5076
5077 static const char*
5078 avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
5079 {
5080   rtx dest = op[0];
5081   rtx src = op[1];
5082   rtx base = XEXP (dest, 0);
5083   int reg_base = REGNO (XEXP (base, 0));
5084   int reg_src = true_regnum (src);
5085
5086   return reg_src == reg_base
5087         ? avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
5088                        "mov __zero_reg__,%B1"         CR_TAB
5089                        TINY_ADIW (%I0, %J0, %o0+1)    CR_TAB
5090                        "st %b0,__zero_reg__"          CR_TAB
5091                        "st -%b0,__tmp_reg__"          CR_TAB
5092                        "clr __zero_reg__"             CR_TAB
5093                        TINY_SBIW (%I0, %J0, %o0), op, plen, -9)
5094
5095         : avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5096                        "st %b0,%B1"                CR_TAB
5097                        "st -%b0,%A1"               CR_TAB
5098                        TINY_SBIW (%I0, %J0, %o0), op, plen, -6);
5099 }
5100
5101 static const char*
5102 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
5103 {
5104   return avr_asm_len (TINY_ADIW (%I0, %J0, 1)  CR_TAB
5105                       "st %p0,%B1"    CR_TAB
5106                       "st -%p0,%A1"   CR_TAB
5107                       TINY_ADIW (%I0, %J0, 2), op, plen, -6);
5108 }
5109
5110 static const char*
5111 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
5112 {
5113   rtx dest = op[0];
5114   rtx src = op[1];
5115   rtx base = XEXP (dest, 0);
5116   int reg_base = true_regnum (base);
5117   int reg_src = true_regnum (src);
5118   int mem_volatile_p;
5119
5120   /* "volatile" forces writing high-byte first (no-xmega) resp.
5121      low-byte first (xmega) even if less efficient, for correct
5122      operation with 16-bit I/O registers like.  */
5123
5124   if (AVR_XMEGA)
5125     return avr_out_movhi_mr_r_xmega (insn, op, plen);
5126
5127   mem_volatile_p = MEM_VOLATILE_P (dest);
5128
5129   if (CONSTANT_ADDRESS_P (base))
5130     {
5131       int n_words = AVR_TINY ? 2 : 4;
5132       return optimize > 0 && io_address_operand (base, HImode)
5133         ? avr_asm_len ("out %i0+1,%B1" CR_TAB
5134                        "out %i0,%A1", op, plen, -2)
5135
5136         : avr_asm_len ("sts %m0+1,%B1" CR_TAB
5137                        "sts %m0,%A1", op, plen, -n_words);
5138     }
5139
5140   if (reg_base > 0)
5141     {
5142       if (AVR_TINY)
5143         return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
5144
5145       if (reg_base != REG_X)
5146         return avr_asm_len ("std %0+1,%B1" CR_TAB
5147                             "st %0,%A1", op, plen, -2);
5148
5149       if (reg_src == REG_X)
5150         /* "st X+,r26" and "st -X,r26" are undefined.  */
5151         return !mem_volatile_p && reg_unused_after (insn, src)
5152           ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5153                          "st X,r26"            CR_TAB
5154                          "adiw r26,1"          CR_TAB
5155                          "st X,__tmp_reg__", op, plen, -4)
5156
5157           : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5158                          "adiw r26,1"          CR_TAB
5159                          "st X,__tmp_reg__"    CR_TAB
5160                          "sbiw r26,1"          CR_TAB
5161                          "st X,r26", op, plen, -5);
5162
5163       return !mem_volatile_p && reg_unused_after (insn, base)
5164         ? avr_asm_len ("st X+,%A1" CR_TAB
5165                        "st X,%B1", op, plen, -2)
5166         : avr_asm_len ("adiw r26,1" CR_TAB
5167                        "st X,%B1"   CR_TAB
5168                        "st -X,%A1", op, plen, -3);
5169     }
5170   else if (GET_CODE (base) == PLUS)
5171     {
5172       int disp = INTVAL (XEXP (base, 1));
5173
5174       if (AVR_TINY)
5175         return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
5176
5177       reg_base = REGNO (XEXP (base, 0));
5178       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5179         {
5180           if (reg_base != REG_Y)
5181             fatal_insn ("incorrect insn:",insn);
5182
5183           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5184             ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5185                            "std Y+63,%B1"    CR_TAB
5186                            "std Y+62,%A1"    CR_TAB
5187                            "sbiw r28,%o0-62", op, plen, -4)
5188
5189             : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5190                            "sbci r29,hi8(-%o0)" CR_TAB
5191                            "std Y+1,%B1"        CR_TAB
5192                            "st Y,%A1"           CR_TAB
5193                            "subi r28,lo8(%o0)"  CR_TAB
5194                            "sbci r29,hi8(%o0)", op, plen, -6);
5195         }
5196
5197       if (reg_base != REG_X)
5198         return avr_asm_len ("std %B0,%B1" CR_TAB
5199                             "std %A0,%A1", op, plen, -2);
5200       /* (X + d) = R */
5201       return reg_src == REG_X
5202         ? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
5203                        "mov __zero_reg__,r27" CR_TAB
5204                        "adiw r26,%o0+1"       CR_TAB
5205                        "st X,__zero_reg__"    CR_TAB
5206                        "st -X,__tmp_reg__"    CR_TAB
5207                        "clr __zero_reg__"     CR_TAB
5208                        "sbiw r26,%o0", op, plen, -7)
5209
5210         : avr_asm_len ("adiw r26,%o0+1" CR_TAB
5211                        "st X,%B1"       CR_TAB
5212                        "st -X,%A1"      CR_TAB
5213                        "sbiw r26,%o0", op, plen, -4);
5214     }
5215   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5216     {
5217       return avr_asm_len ("st %0,%B1" CR_TAB
5218                           "st %0,%A1", op, plen, -2);
5219     }
5220   else if (GET_CODE (base) == POST_INC) /* (R++) */
5221     {
5222       if (!mem_volatile_p)
5223         return avr_asm_len ("st %0,%A1"  CR_TAB
5224                             "st %0,%B1", op, plen, -2);
5225
5226       if (AVR_TINY)
5227         return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
5228
5229       return REGNO (XEXP (base, 0)) == REG_X
5230         ? avr_asm_len ("adiw r26,1"  CR_TAB
5231                        "st X,%B1"    CR_TAB
5232                        "st -X,%A1"   CR_TAB
5233                        "adiw r26,2", op, plen, -4)
5234
5235         : avr_asm_len ("std %p0+1,%B1" CR_TAB
5236                        "st %p0,%A1"    CR_TAB
5237                        "adiw %r0,2", op, plen, -3);
5238     }
5239   fatal_insn ("unknown move insn:",insn);
5240   return "";
5241 }
5242
5243 /* Return 1 if frame pointer for current function required.  */
5244
5245 static bool
5246 avr_frame_pointer_required_p (void)
5247 {
5248   return (cfun->calls_alloca
5249           || cfun->calls_setjmp
5250           || cfun->has_nonlocal_label
5251           || crtl->args.info.nregs == 0
5252           || get_frame_size () > 0);
5253 }
5254
5255 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
5256
5257 static RTX_CODE
5258 compare_condition (rtx_insn *insn)
5259 {
5260   rtx_insn *next = next_real_insn (insn);
5261
5262   if (next && JUMP_P (next))
5263     {
5264       rtx pat = PATTERN (next);
5265       rtx src = SET_SRC (pat);
5266
5267       if (IF_THEN_ELSE == GET_CODE (src))
5268         return GET_CODE (XEXP (src, 0));
5269     }
5270
5271   return UNKNOWN;
5272 }
5273
5274
5275 /* Returns true iff INSN is a tst insn that only tests the sign.  */
5276
5277 static bool
5278 compare_sign_p (rtx_insn *insn)
5279 {
5280   RTX_CODE cond = compare_condition (insn);
5281   return (cond == GE || cond == LT);
5282 }
5283
5284
5285 /* Returns true iff the next insn is a JUMP_INSN with a condition
5286    that needs to be swapped (GT, GTU, LE, LEU).  */
5287
5288 static bool
5289 compare_diff_p (rtx_insn *insn)
5290 {
5291   RTX_CODE cond = compare_condition (insn);
5292   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
5293 }
5294
5295 /* Returns true iff INSN is a compare insn with the EQ or NE condition.  */
5296
5297 static bool
5298 compare_eq_p (rtx_insn *insn)
5299 {
5300   RTX_CODE cond = compare_condition (insn);
5301   return (cond == EQ || cond == NE);
5302 }
5303
5304
5305 /* Output compare instruction
5306
5307       compare (XOP[0], XOP[1])
5308
5309    for a register XOP[0] and a compile-time constant XOP[1].  Return "".
5310    XOP[2] is an 8-bit scratch register as needed.
5311
5312    PLEN == NULL:  Output instructions.
5313    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
5314                   Don't output anything.  */
5315
5316 const char*
5317 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
5318 {
5319   /* Register to compare and value to compare against. */
5320   rtx xreg = xop[0];
5321   rtx xval = xop[1];
5322
5323   /* MODE of the comparison.  */
5324   machine_mode mode;
5325
5326   /* Number of bytes to operate on.  */
5327   int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
5328
5329   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
5330   int clobber_val = -1;
5331
5332   /* Map fixed mode operands to integer operands with the same binary
5333      representation.  They are easier to handle in the remainder.  */
5334
5335   if (CONST_FIXED_P (xval))
5336     {
5337       xreg = avr_to_int_mode (xop[0]);
5338       xval = avr_to_int_mode (xop[1]);
5339     }
5340
5341   mode = GET_MODE (xreg);
5342
5343   gcc_assert (REG_P (xreg));
5344   gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
5345               || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
5346
5347   if (plen)
5348     *plen = 0;
5349
5350   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
5351      against 0 by ORing the bytes.  This is one instruction shorter.
5352      Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
5353      and therefore don't use this.  */
5354
5355   if (!test_hard_reg_class (LD_REGS, xreg)
5356       && compare_eq_p (insn)
5357       && reg_unused_after (insn, xreg))
5358     {
5359       if (xval == const1_rtx)
5360         {
5361           avr_asm_len ("dec %A0" CR_TAB
5362                        "or %A0,%B0", xop, plen, 2);
5363
5364           if (n_bytes >= 3)
5365             avr_asm_len ("or %A0,%C0", xop, plen, 1);
5366
5367           if (n_bytes >= 4)
5368             avr_asm_len ("or %A0,%D0", xop, plen, 1);
5369
5370           return "";
5371         }
5372       else if (xval == constm1_rtx)
5373         {
5374           if (n_bytes >= 4)
5375             avr_asm_len ("and %A0,%D0", xop, plen, 1);
5376
5377           if (n_bytes >= 3)
5378             avr_asm_len ("and %A0,%C0", xop, plen, 1);
5379
5380           return avr_asm_len ("and %A0,%B0" CR_TAB
5381                               "com %A0", xop, plen, 2);
5382         }
5383     }
5384
5385   for (i = 0; i < n_bytes; i++)
5386     {
5387       /* We compare byte-wise.  */
5388       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
5389       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5390
5391       /* 8-bit value to compare with this byte.  */
5392       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5393
5394       /* Registers R16..R31 can operate with immediate.  */
5395       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5396
5397       xop[0] = reg8;
5398       xop[1] = gen_int_mode (val8, QImode);
5399
5400       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
5401
5402       if (i == 0
5403           && test_hard_reg_class (ADDW_REGS, reg8))
5404         {
5405           int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
5406
5407           if (IN_RANGE (val16, 0, 63)
5408               && (val8 == 0
5409                   || reg_unused_after (insn, xreg)))
5410             {
5411               if (AVR_TINY)
5412                 avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
5413               else
5414                 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
5415
5416               i++;
5417               continue;
5418             }
5419
5420           if (n_bytes == 2
5421               && IN_RANGE (val16, -63, -1)
5422               && compare_eq_p (insn)
5423               && reg_unused_after (insn, xreg))
5424             {
5425               return AVR_TINY
5426                   ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
5427                   : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
5428             }
5429         }
5430
5431       /* Comparing against 0 is easy.  */
5432
5433       if (val8 == 0)
5434         {
5435           avr_asm_len (i == 0
5436                        ? "cp %0,__zero_reg__"
5437                        : "cpc %0,__zero_reg__", xop, plen, 1);
5438           continue;
5439         }
5440
5441       /* Upper registers can compare and subtract-with-carry immediates.
5442          Notice that compare instructions do the same as respective subtract
5443          instruction; the only difference is that comparisons don't write
5444          the result back to the target register.  */
5445
5446       if (ld_reg_p)
5447         {
5448           if (i == 0)
5449             {
5450               avr_asm_len ("cpi %0,%1", xop, plen, 1);
5451               continue;
5452             }
5453           else if (reg_unused_after (insn, xreg))
5454             {
5455               avr_asm_len ("sbci %0,%1", xop, plen, 1);
5456               continue;
5457             }
5458         }
5459
5460       /* Must load the value into the scratch register.  */
5461
5462       gcc_assert (REG_P (xop[2]));
5463
5464       if (clobber_val != (int) val8)
5465         avr_asm_len ("ldi %2,%1", xop, plen, 1);
5466       clobber_val = (int) val8;
5467
5468       avr_asm_len (i == 0
5469                    ? "cp %0,%2"
5470                    : "cpc %0,%2", xop, plen, 1);
5471     }
5472
5473   return "";
5474 }
5475
5476
5477 /* Prepare operands of compare_const_di2 to be used with avr_out_compare.  */
5478
5479 const char*
5480 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
5481 {
5482   rtx xop[3];
5483
5484   xop[0] = gen_rtx_REG (DImode, 18);
5485   xop[1] = op[0];
5486   xop[2] = op[1];
5487
5488   return avr_out_compare (insn, xop, plen);
5489 }
5490
5491 /* Output test instruction for HImode.  */
5492
5493 const char*
5494 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
5495 {
5496   if (compare_sign_p (insn))
5497     {
5498       avr_asm_len ("tst %B0", op, plen, -1);
5499     }
5500   else if (reg_unused_after (insn, op[0])
5501            && compare_eq_p (insn))
5502     {
5503       /* Faster than sbiw if we can clobber the operand.  */
5504       avr_asm_len ("or %A0,%B0", op, plen, -1);
5505     }
5506   else
5507     {
5508       avr_out_compare (insn, op, plen);
5509     }
5510
5511   return "";
5512 }
5513
5514
5515 /* Output test instruction for PSImode.  */
5516
5517 const char*
5518 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
5519 {
5520   if (compare_sign_p (insn))
5521     {
5522       avr_asm_len ("tst %C0", op, plen, -1);
5523     }
5524   else if (reg_unused_after (insn, op[0])
5525            && compare_eq_p (insn))
5526     {
5527       /* Faster than sbiw if we can clobber the operand.  */
5528       avr_asm_len ("or %A0,%B0" CR_TAB
5529                    "or %A0,%C0", op, plen, -2);
5530     }
5531   else
5532     {
5533       avr_out_compare (insn, op, plen);
5534     }
5535
5536   return "";
5537 }
5538
5539
5540 /* Output test instruction for SImode.  */
5541
5542 const char*
5543 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
5544 {
5545   if (compare_sign_p (insn))
5546     {
5547       avr_asm_len ("tst %D0", op, plen, -1);
5548     }
5549   else if (reg_unused_after (insn, op[0])
5550            && compare_eq_p (insn))
5551     {
5552       /* Faster than sbiw if we can clobber the operand.  */
5553       avr_asm_len ("or %A0,%B0" CR_TAB
5554                    "or %A0,%C0" CR_TAB
5555                    "or %A0,%D0", op, plen, -3);
5556     }
5557   else
5558     {
5559       avr_out_compare (insn, op, plen);
5560     }
5561
5562   return "";
5563 }
5564
5565
5566 /* Generate asm equivalent for various shifts.  This only handles cases
5567    that are not already carefully hand-optimized in ?sh??i3_out.
5568
5569    OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
5570    OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
5571    OPERANDS[3] is a QImode scratch register from LD regs if
5572                available and SCRATCH, otherwise (no scratch available)
5573
5574    TEMPL is an assembler template that shifts by one position.
5575    T_LEN is the length of this template.  */
5576
5577 void
5578 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
5579                     int *plen, int t_len)
5580 {
5581   bool second_label = true;
5582   bool saved_in_tmp = false;
5583   bool use_zero_reg = false;
5584   rtx op[5];
5585
5586   op[0] = operands[0];
5587   op[1] = operands[1];
5588   op[2] = operands[2];
5589   op[3] = operands[3];
5590
5591   if (plen)
5592     *plen = 0;
5593
5594   if (CONST_INT_P (operands[2]))
5595     {
5596       bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
5597                       && REG_P (operands[3]));
5598       int count = INTVAL (operands[2]);
5599       int max_len = 10;  /* If larger than this, always use a loop.  */
5600
5601       if (count <= 0)
5602           return;
5603
5604       if (count < 8 && !scratch)
5605         use_zero_reg = true;
5606
5607       if (optimize_size)
5608         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
5609
5610       if (t_len * count <= max_len)
5611         {
5612           /* Output shifts inline with no loop - faster.  */
5613
5614           while (count-- > 0)
5615             avr_asm_len (templ, op, plen, t_len);
5616
5617           return;
5618         }
5619
5620       if (scratch)
5621         {
5622           avr_asm_len ("ldi %3,%2", op, plen, 1);
5623         }
5624       else if (use_zero_reg)
5625         {
5626           /* Hack to save one word: use __zero_reg__ as loop counter.
5627              Set one bit, then shift in a loop until it is 0 again.  */
5628
5629           op[3] = zero_reg_rtx;
5630
5631           avr_asm_len ("set" CR_TAB
5632                        "bld %3,%2-1", op, plen, 2);
5633         }
5634       else
5635         {
5636           /* No scratch register available, use one from LD_REGS (saved in
5637              __tmp_reg__) that doesn't overlap with registers to shift.  */
5638
5639           op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
5640           op[4] = tmp_reg_rtx;
5641           saved_in_tmp = true;
5642
5643           avr_asm_len ("mov %4,%3" CR_TAB
5644                        "ldi %3,%2", op, plen, 2);
5645         }
5646
5647       second_label = false;
5648     }
5649   else if (MEM_P (op[2]))
5650     {
5651       rtx op_mov[2];
5652
5653       op_mov[0] = op[3] = tmp_reg_rtx;
5654       op_mov[1] = op[2];
5655
5656       out_movqi_r_mr (insn, op_mov, plen);
5657     }
5658   else if (register_operand (op[2], QImode))
5659     {
5660       op[3] = op[2];
5661
5662       if (!reg_unused_after (insn, op[2])
5663           || reg_overlap_mentioned_p (op[0], op[2]))
5664         {
5665           op[3] = tmp_reg_rtx;
5666           avr_asm_len ("mov %3,%2", op, plen, 1);
5667         }
5668     }
5669   else
5670     fatal_insn ("bad shift insn:", insn);
5671
5672   if (second_label)
5673       avr_asm_len ("rjmp 2f", op, plen, 1);
5674
5675   avr_asm_len ("1:", op, plen, 0);
5676   avr_asm_len (templ, op, plen, t_len);
5677
5678   if (second_label)
5679     avr_asm_len ("2:", op, plen, 0);
5680
5681   avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
5682   avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
5683
5684   if (saved_in_tmp)
5685     avr_asm_len ("mov %3,%4", op, plen, 1);
5686 }
5687
5688
5689 /* 8bit shift left ((char)x << i)   */
5690
5691 const char *
5692 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
5693 {
5694   if (GET_CODE (operands[2]) == CONST_INT)
5695     {
5696       int k;
5697
5698       if (!len)
5699         len = &k;
5700
5701       switch (INTVAL (operands[2]))
5702         {
5703         default:
5704           if (INTVAL (operands[2]) < 8)
5705             break;
5706
5707           *len = 1;
5708           return "clr %0";
5709
5710         case 1:
5711           *len = 1;
5712           return "lsl %0";
5713
5714         case 2:
5715           *len = 2;
5716           return ("lsl %0" CR_TAB
5717                   "lsl %0");
5718
5719         case 3:
5720           *len = 3;
5721           return ("lsl %0" CR_TAB
5722                   "lsl %0" CR_TAB
5723                   "lsl %0");
5724
5725         case 4:
5726           if (test_hard_reg_class (LD_REGS, operands[0]))
5727             {
5728               *len = 2;
5729               return ("swap %0" CR_TAB
5730                       "andi %0,0xf0");
5731             }
5732           *len = 4;
5733           return ("lsl %0" CR_TAB
5734                   "lsl %0" CR_TAB
5735                   "lsl %0" CR_TAB
5736                   "lsl %0");
5737
5738         case 5:
5739           if (test_hard_reg_class (LD_REGS, operands[0]))
5740             {
5741               *len = 3;
5742               return ("swap %0" CR_TAB
5743                       "lsl %0"  CR_TAB
5744                       "andi %0,0xe0");
5745             }
5746           *len = 5;
5747           return ("lsl %0" CR_TAB
5748                   "lsl %0" CR_TAB
5749                   "lsl %0" CR_TAB
5750                   "lsl %0" CR_TAB
5751                   "lsl %0");
5752
5753         case 6:
5754           if (test_hard_reg_class (LD_REGS, operands[0]))
5755             {
5756               *len = 4;
5757               return ("swap %0" CR_TAB
5758                       "lsl %0"  CR_TAB
5759                       "lsl %0"  CR_TAB
5760                       "andi %0,0xc0");
5761             }
5762           *len = 6;
5763           return ("lsl %0" CR_TAB
5764                   "lsl %0" CR_TAB
5765                   "lsl %0" CR_TAB
5766                   "lsl %0" CR_TAB
5767                   "lsl %0" CR_TAB
5768                   "lsl %0");
5769
5770         case 7:
5771           *len = 3;
5772           return ("ror %0" CR_TAB
5773                   "clr %0" CR_TAB
5774                   "ror %0");
5775         }
5776     }
5777   else if (CONSTANT_P (operands[2]))
5778     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
5779
5780   out_shift_with_cnt ("lsl %0",
5781                       insn, operands, len, 1);
5782   return "";
5783 }
5784
5785
5786 /* 16bit shift left ((short)x << i)   */
5787
5788 const char *
5789 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
5790 {
5791   if (GET_CODE (operands[2]) == CONST_INT)
5792     {
5793       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5794       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5795       int k;
5796       int *t = len;
5797
5798       if (!len)
5799         len = &k;
5800
5801       switch (INTVAL (operands[2]))
5802         {
5803         default:
5804           if (INTVAL (operands[2]) < 16)
5805             break;
5806
5807           *len = 2;
5808           return ("clr %B0" CR_TAB
5809                   "clr %A0");
5810
5811         case 4:
5812           if (optimize_size && scratch)
5813             break;  /* 5 */
5814           if (ldi_ok)
5815             {
5816               *len = 6;
5817               return ("swap %A0"      CR_TAB
5818                       "swap %B0"      CR_TAB
5819                       "andi %B0,0xf0" CR_TAB
5820                       "eor %B0,%A0"   CR_TAB
5821                       "andi %A0,0xf0" CR_TAB
5822                       "eor %B0,%A0");
5823             }
5824           if (scratch)
5825             {
5826               *len = 7;
5827               return ("swap %A0"    CR_TAB
5828                       "swap %B0"    CR_TAB
5829                       "ldi %3,0xf0" CR_TAB
5830                       "and %B0,%3"      CR_TAB
5831                       "eor %B0,%A0" CR_TAB
5832                       "and %A0,%3"      CR_TAB
5833                       "eor %B0,%A0");
5834             }
5835           break;  /* optimize_size ? 6 : 8 */
5836
5837         case 5:
5838           if (optimize_size)
5839             break;  /* scratch ? 5 : 6 */
5840           if (ldi_ok)
5841             {
5842               *len = 8;
5843               return ("lsl %A0"       CR_TAB
5844                       "rol %B0"       CR_TAB
5845                       "swap %A0"      CR_TAB
5846                       "swap %B0"      CR_TAB
5847                       "andi %B0,0xf0" CR_TAB
5848                       "eor %B0,%A0"   CR_TAB
5849                       "andi %A0,0xf0" CR_TAB
5850                       "eor %B0,%A0");
5851             }
5852           if (scratch)
5853             {
5854               *len = 9;
5855               return ("lsl %A0"     CR_TAB
5856                       "rol %B0"     CR_TAB
5857                       "swap %A0"    CR_TAB
5858                       "swap %B0"    CR_TAB
5859                       "ldi %3,0xf0" CR_TAB
5860                       "and %B0,%3"      CR_TAB
5861                       "eor %B0,%A0" CR_TAB
5862                       "and %A0,%3"      CR_TAB
5863                       "eor %B0,%A0");
5864             }
5865           break;  /* 10 */
5866
5867         case 6:
5868           if (optimize_size)
5869             break;  /* scratch ? 5 : 6 */
5870           *len = 9;
5871           return ("clr __tmp_reg__" CR_TAB
5872                   "lsr %B0"         CR_TAB
5873                   "ror %A0"         CR_TAB
5874                   "ror __tmp_reg__" CR_TAB
5875                   "lsr %B0"         CR_TAB
5876                   "ror %A0"         CR_TAB
5877                   "ror __tmp_reg__" CR_TAB
5878                   "mov %B0,%A0"     CR_TAB
5879                   "mov %A0,__tmp_reg__");
5880
5881         case 7:
5882           *len = 5;
5883           return ("lsr %B0"     CR_TAB
5884                   "mov %B0,%A0" CR_TAB
5885                   "clr %A0"     CR_TAB
5886                   "ror %B0"     CR_TAB
5887                   "ror %A0");
5888
5889         case 8:
5890           return *len = 2, ("mov %B0,%A1" CR_TAB
5891                             "clr %A0");
5892
5893         case 9:
5894           *len = 3;
5895           return ("mov %B0,%A0" CR_TAB
5896                   "clr %A0"     CR_TAB
5897                   "lsl %B0");
5898
5899         case 10:
5900           *len = 4;
5901           return ("mov %B0,%A0" CR_TAB
5902                   "clr %A0"     CR_TAB
5903                   "lsl %B0"     CR_TAB
5904                   "lsl %B0");
5905
5906         case 11:
5907           *len = 5;
5908           return ("mov %B0,%A0" CR_TAB
5909                   "clr %A0"     CR_TAB
5910                   "lsl %B0"     CR_TAB
5911                   "lsl %B0"     CR_TAB
5912                   "lsl %B0");
5913
5914         case 12:
5915           if (ldi_ok)
5916             {
5917               *len = 4;
5918               return ("mov %B0,%A0" CR_TAB
5919                       "clr %A0"     CR_TAB
5920                       "swap %B0"    CR_TAB
5921                       "andi %B0,0xf0");
5922             }
5923           if (scratch)
5924             {
5925               *len = 5;
5926               return ("mov %B0,%A0" CR_TAB
5927                       "clr %A0"     CR_TAB
5928                       "swap %B0"    CR_TAB
5929                       "ldi %3,0xf0" CR_TAB
5930                       "and %B0,%3");
5931             }
5932           *len = 6;
5933           return ("mov %B0,%A0" CR_TAB
5934                   "clr %A0"     CR_TAB
5935                   "lsl %B0"     CR_TAB
5936                   "lsl %B0"     CR_TAB
5937                   "lsl %B0"     CR_TAB
5938                   "lsl %B0");
5939
5940         case 13:
5941           if (ldi_ok)
5942             {
5943               *len = 5;
5944               return ("mov %B0,%A0" CR_TAB
5945                       "clr %A0"     CR_TAB
5946                       "swap %B0"    CR_TAB
5947                       "lsl %B0"     CR_TAB
5948                       "andi %B0,0xe0");
5949             }
5950           if (AVR_HAVE_MUL && scratch)
5951             {
5952               *len = 5;
5953               return ("ldi %3,0x20" CR_TAB
5954                       "mul %A0,%3"  CR_TAB
5955                       "mov %B0,r0"  CR_TAB
5956                       "clr %A0"     CR_TAB
5957                       "clr __zero_reg__");
5958             }
5959           if (optimize_size && scratch)
5960             break;  /* 5 */
5961           if (scratch)
5962             {
5963               *len = 6;
5964               return ("mov %B0,%A0" CR_TAB
5965                       "clr %A0"     CR_TAB
5966                       "swap %B0"    CR_TAB
5967                       "lsl %B0"     CR_TAB
5968                       "ldi %3,0xe0" CR_TAB
5969                       "and %B0,%3");
5970             }
5971           if (AVR_HAVE_MUL)
5972             {
5973               *len = 6;
5974               return ("set"            CR_TAB
5975                       "bld r1,5"   CR_TAB
5976                       "mul %A0,r1" CR_TAB
5977                       "mov %B0,r0" CR_TAB
5978                       "clr %A0"    CR_TAB
5979                       "clr __zero_reg__");
5980             }
5981           *len = 7;
5982           return ("mov %B0,%A0" CR_TAB
5983                   "clr %A0"     CR_TAB
5984                   "lsl %B0"     CR_TAB
5985                   "lsl %B0"     CR_TAB
5986                   "lsl %B0"     CR_TAB
5987                   "lsl %B0"     CR_TAB
5988                   "lsl %B0");
5989
5990         case 14:
5991           if (AVR_HAVE_MUL && ldi_ok)
5992             {
5993               *len = 5;
5994               return ("ldi %B0,0x40" CR_TAB
5995                       "mul %A0,%B0"  CR_TAB
5996                       "mov %B0,r0"   CR_TAB
5997                       "clr %A0"      CR_TAB
5998                       "clr __zero_reg__");
5999             }
6000           if (AVR_HAVE_MUL && scratch)
6001             {
6002               *len = 5;
6003               return ("ldi %3,0x40" CR_TAB
6004                       "mul %A0,%3"  CR_TAB
6005                       "mov %B0,r0"  CR_TAB
6006                       "clr %A0"     CR_TAB
6007                       "clr __zero_reg__");
6008             }
6009           if (optimize_size && ldi_ok)
6010             {
6011               *len = 5;
6012               return ("mov %B0,%A0" CR_TAB
6013                       "ldi %A0,6" "\n1:\t"
6014                       "lsl %B0"     CR_TAB
6015                       "dec %A0"     CR_TAB
6016                       "brne 1b");
6017             }
6018           if (optimize_size && scratch)
6019             break;  /* 5 */
6020           *len = 6;
6021           return ("clr %B0" CR_TAB
6022                   "lsr %A0" CR_TAB
6023                   "ror %B0" CR_TAB
6024                   "lsr %A0" CR_TAB
6025                   "ror %B0" CR_TAB
6026                   "clr %A0");
6027
6028         case 15:
6029           *len = 4;
6030           return ("clr %B0" CR_TAB
6031                   "lsr %A0" CR_TAB
6032                   "ror %B0" CR_TAB
6033                   "clr %A0");
6034         }
6035       len = t;
6036     }
6037   out_shift_with_cnt ("lsl %A0" CR_TAB
6038                       "rol %B0", insn, operands, len, 2);
6039   return "";
6040 }
6041
6042
6043 /* 24-bit shift left */
6044
6045 const char*
6046 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
6047 {
6048   if (plen)
6049     *plen = 0;
6050
6051   if (CONST_INT_P (op[2]))
6052     {
6053       switch (INTVAL (op[2]))
6054         {
6055         default:
6056           if (INTVAL (op[2]) < 24)
6057             break;
6058
6059           return avr_asm_len ("clr %A0" CR_TAB
6060                               "clr %B0" CR_TAB
6061                               "clr %C0", op, plen, 3);
6062
6063         case 8:
6064           {
6065             int reg0 = REGNO (op[0]);
6066             int reg1 = REGNO (op[1]);
6067
6068             if (reg0 >= reg1)
6069               return avr_asm_len ("mov %C0,%B1"  CR_TAB
6070                                   "mov %B0,%A1"  CR_TAB
6071                                   "clr %A0", op, plen, 3);
6072             else
6073               return avr_asm_len ("clr %A0"      CR_TAB
6074                                   "mov %B0,%A1"  CR_TAB
6075                                   "mov %C0,%B1", op, plen, 3);
6076           }
6077
6078         case 16:
6079           {
6080             int reg0 = REGNO (op[0]);
6081             int reg1 = REGNO (op[1]);
6082
6083             if (reg0 + 2 != reg1)
6084               avr_asm_len ("mov %C0,%A0", op, plen, 1);
6085
6086             return avr_asm_len ("clr %B0"  CR_TAB
6087                                 "clr %A0", op, plen, 2);
6088           }
6089
6090         case 23:
6091           return avr_asm_len ("clr %C0" CR_TAB
6092                               "lsr %A0" CR_TAB
6093                               "ror %C0" CR_TAB
6094                               "clr %B0" CR_TAB
6095                               "clr %A0", op, plen, 5);
6096         }
6097     }
6098
6099   out_shift_with_cnt ("lsl %A0" CR_TAB
6100                       "rol %B0" CR_TAB
6101                       "rol %C0", insn, op, plen, 3);
6102   return "";
6103 }
6104
6105
6106 /* 32bit shift left ((long)x << i)   */
6107
6108 const char *
6109 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
6110 {
6111   if (GET_CODE (operands[2]) == CONST_INT)
6112     {
6113       int k;
6114       int *t = len;
6115
6116       if (!len)
6117         len = &k;
6118
6119       switch (INTVAL (operands[2]))
6120         {
6121         default:
6122           if (INTVAL (operands[2]) < 32)
6123             break;
6124
6125           if (AVR_HAVE_MOVW)
6126             return *len = 3, ("clr %D0" CR_TAB
6127                               "clr %C0" CR_TAB
6128                               "movw %A0,%C0");
6129           *len = 4;
6130           return ("clr %D0" CR_TAB
6131                   "clr %C0" CR_TAB
6132                   "clr %B0" CR_TAB
6133                   "clr %A0");
6134
6135         case 8:
6136           {
6137             int reg0 = true_regnum (operands[0]);
6138             int reg1 = true_regnum (operands[1]);
6139             *len = 4;
6140             if (reg0 >= reg1)
6141               return ("mov %D0,%C1"  CR_TAB
6142                       "mov %C0,%B1"  CR_TAB
6143                       "mov %B0,%A1"  CR_TAB
6144                       "clr %A0");
6145             else
6146               return ("clr %A0"      CR_TAB
6147                       "mov %B0,%A1"  CR_TAB
6148                       "mov %C0,%B1"  CR_TAB
6149                       "mov %D0,%C1");
6150           }
6151
6152         case 16:
6153           {
6154             int reg0 = true_regnum (operands[0]);
6155             int reg1 = true_regnum (operands[1]);
6156             if (reg0 + 2 == reg1)
6157               return *len = 2, ("clr %B0"      CR_TAB
6158                                 "clr %A0");
6159             if (AVR_HAVE_MOVW)
6160               return *len = 3, ("movw %C0,%A1" CR_TAB
6161                                 "clr %B0"      CR_TAB
6162                                 "clr %A0");
6163             else
6164               return *len = 4, ("mov %C0,%A1"  CR_TAB
6165                                 "mov %D0,%B1"  CR_TAB
6166                                 "clr %B0"      CR_TAB
6167                                 "clr %A0");
6168           }
6169
6170         case 24:
6171           *len = 4;
6172           return ("mov %D0,%A1"  CR_TAB
6173                   "clr %C0"      CR_TAB
6174                   "clr %B0"      CR_TAB
6175                   "clr %A0");
6176
6177         case 31:
6178           *len = 6;
6179           return ("clr %D0" CR_TAB
6180                   "lsr %A0" CR_TAB
6181                   "ror %D0" CR_TAB
6182                   "clr %C0" CR_TAB
6183                   "clr %B0" CR_TAB
6184                   "clr %A0");
6185         }
6186       len = t;
6187     }
6188   out_shift_with_cnt ("lsl %A0" CR_TAB
6189                       "rol %B0" CR_TAB
6190                       "rol %C0" CR_TAB
6191                       "rol %D0", insn, operands, len, 4);
6192   return "";
6193 }
6194
6195 /* 8bit arithmetic shift right  ((signed char)x >> i) */
6196
6197 const char *
6198 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6199 {
6200   if (GET_CODE (operands[2]) == CONST_INT)
6201     {
6202       int k;
6203
6204       if (!len)
6205         len = &k;
6206
6207       switch (INTVAL (operands[2]))
6208         {
6209         case 1:
6210           *len = 1;
6211           return "asr %0";
6212
6213         case 2:
6214           *len = 2;
6215           return ("asr %0" CR_TAB
6216                   "asr %0");
6217
6218         case 3:
6219           *len = 3;
6220           return ("asr %0" CR_TAB
6221                   "asr %0" CR_TAB
6222                   "asr %0");
6223
6224         case 4:
6225           *len = 4;
6226           return ("asr %0" CR_TAB
6227                   "asr %0" CR_TAB
6228                   "asr %0" CR_TAB
6229                   "asr %0");
6230
6231         case 5:
6232           *len = 5;
6233           return ("asr %0" CR_TAB
6234                   "asr %0" CR_TAB
6235                   "asr %0" CR_TAB
6236                   "asr %0" CR_TAB
6237                   "asr %0");
6238
6239         case 6:
6240           *len = 4;
6241           return ("bst %0,6"  CR_TAB
6242                   "lsl %0"    CR_TAB
6243                   "sbc %0,%0" CR_TAB
6244                   "bld %0,0");
6245
6246         default:
6247           if (INTVAL (operands[2]) < 8)
6248             break;
6249
6250           /* fall through */
6251
6252         case 7:
6253           *len = 2;
6254           return ("lsl %0" CR_TAB
6255                   "sbc %0,%0");
6256         }
6257     }
6258   else if (CONSTANT_P (operands[2]))
6259     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
6260
6261   out_shift_with_cnt ("asr %0",
6262                       insn, operands, len, 1);
6263   return "";
6264 }
6265
6266
6267 /* 16bit arithmetic shift right  ((signed short)x >> i) */
6268
6269 const char *
6270 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6271 {
6272   if (GET_CODE (operands[2]) == CONST_INT)
6273     {
6274       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6275       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6276       int k;
6277       int *t = len;
6278
6279       if (!len)
6280         len = &k;
6281
6282       switch (INTVAL (operands[2]))
6283         {
6284         case 4:
6285         case 5:
6286           /* XXX try to optimize this too? */
6287           break;
6288
6289         case 6:
6290           if (optimize_size)
6291             break;  /* scratch ? 5 : 6 */
6292           *len = 8;
6293           return ("mov __tmp_reg__,%A0" CR_TAB
6294                   "mov %A0,%B0"         CR_TAB
6295                   "lsl __tmp_reg__"     CR_TAB
6296                   "rol %A0"             CR_TAB
6297                   "sbc %B0,%B0"         CR_TAB
6298                   "lsl __tmp_reg__"     CR_TAB
6299                   "rol %A0"             CR_TAB
6300                   "rol %B0");
6301
6302         case 7:
6303           *len = 4;
6304           return ("lsl %A0"     CR_TAB
6305                   "mov %A0,%B0" CR_TAB
6306                   "rol %A0"     CR_TAB
6307                   "sbc %B0,%B0");
6308
6309         case 8:
6310           {
6311             int reg0 = true_regnum (operands[0]);
6312             int reg1 = true_regnum (operands[1]);
6313
6314             if (reg0 == reg1)
6315               return *len = 3, ("mov %A0,%B0" CR_TAB
6316                                 "lsl %B0"     CR_TAB
6317                                 "sbc %B0,%B0");
6318             else
6319               return *len = 4, ("mov %A0,%B1" CR_TAB
6320                                 "clr %B0"     CR_TAB
6321                                 "sbrc %A0,7"  CR_TAB
6322                                 "dec %B0");
6323           }
6324
6325         case 9:
6326           *len = 4;
6327           return ("mov %A0,%B0" CR_TAB
6328                   "lsl %B0"      CR_TAB
6329                   "sbc %B0,%B0" CR_TAB
6330                   "asr %A0");
6331
6332         case 10:
6333           *len = 5;
6334           return ("mov %A0,%B0" CR_TAB
6335                   "lsl %B0"     CR_TAB
6336                   "sbc %B0,%B0" CR_TAB
6337                   "asr %A0"     CR_TAB
6338                   "asr %A0");
6339
6340         case 11:
6341           if (AVR_HAVE_MUL && ldi_ok)
6342             {
6343               *len = 5;
6344               return ("ldi %A0,0x20" CR_TAB
6345                       "muls %B0,%A0" CR_TAB
6346                       "mov %A0,r1"   CR_TAB
6347                       "sbc %B0,%B0"  CR_TAB
6348                       "clr __zero_reg__");
6349             }
6350           if (optimize_size && scratch)
6351             break;  /* 5 */
6352           *len = 6;
6353           return ("mov %A0,%B0" CR_TAB
6354                   "lsl %B0"     CR_TAB
6355                   "sbc %B0,%B0" CR_TAB
6356                   "asr %A0"     CR_TAB
6357                   "asr %A0"     CR_TAB
6358                   "asr %A0");
6359
6360         case 12:
6361           if (AVR_HAVE_MUL && ldi_ok)
6362             {
6363               *len = 5;
6364               return ("ldi %A0,0x10" CR_TAB
6365                       "muls %B0,%A0" CR_TAB
6366                       "mov %A0,r1"   CR_TAB
6367                       "sbc %B0,%B0"  CR_TAB
6368                       "clr __zero_reg__");
6369             }
6370           if (optimize_size && scratch)
6371             break;  /* 5 */
6372           *len = 7;
6373           return ("mov %A0,%B0" CR_TAB
6374                   "lsl %B0"     CR_TAB
6375                   "sbc %B0,%B0" CR_TAB
6376                   "asr %A0"     CR_TAB
6377                   "asr %A0"     CR_TAB
6378                   "asr %A0"     CR_TAB
6379                   "asr %A0");
6380
6381         case 13:
6382           if (AVR_HAVE_MUL && ldi_ok)
6383             {
6384               *len = 5;
6385               return ("ldi %A0,0x08" CR_TAB
6386                       "muls %B0,%A0" CR_TAB
6387                       "mov %A0,r1"   CR_TAB
6388                       "sbc %B0,%B0"  CR_TAB
6389                       "clr __zero_reg__");
6390             }
6391           if (optimize_size)
6392             break;  /* scratch ? 5 : 7 */
6393           *len = 8;
6394           return ("mov %A0,%B0" CR_TAB
6395                   "lsl %B0"     CR_TAB
6396                   "sbc %B0,%B0" CR_TAB
6397                   "asr %A0"     CR_TAB
6398                   "asr %A0"     CR_TAB
6399                   "asr %A0"     CR_TAB
6400                   "asr %A0"     CR_TAB
6401                   "asr %A0");
6402
6403         case 14:
6404           *len = 5;
6405           return ("lsl %B0"     CR_TAB
6406                   "sbc %A0,%A0" CR_TAB
6407                   "lsl %B0"     CR_TAB
6408                   "mov %B0,%A0" CR_TAB
6409                   "rol %A0");
6410
6411         default:
6412           if (INTVAL (operands[2]) < 16)
6413             break;
6414
6415           /* fall through */
6416
6417         case 15:
6418           return *len = 3, ("lsl %B0"     CR_TAB
6419                             "sbc %A0,%A0" CR_TAB
6420                             "mov %B0,%A0");
6421         }
6422       len = t;
6423     }
6424   out_shift_with_cnt ("asr %B0" CR_TAB
6425                       "ror %A0", insn, operands, len, 2);
6426   return "";
6427 }
6428
6429
6430 /* 24-bit arithmetic shift right */
6431
6432 const char*
6433 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6434 {
6435   int dest = REGNO (op[0]);
6436   int src = REGNO (op[1]);
6437
6438   if (CONST_INT_P (op[2]))
6439     {
6440       if (plen)
6441         *plen = 0;
6442
6443       switch (INTVAL (op[2]))
6444         {
6445         case 8:
6446           if (dest <= src)
6447             return avr_asm_len ("mov %A0,%B1" CR_TAB
6448                                 "mov %B0,%C1" CR_TAB
6449                                 "clr %C0"     CR_TAB
6450                                 "sbrc %B0,7"  CR_TAB
6451                                 "dec %C0", op, plen, 5);
6452           else
6453             return avr_asm_len ("clr %C0"     CR_TAB
6454                                 "sbrc %C1,7"  CR_TAB
6455                                 "dec %C0"     CR_TAB
6456                                 "mov %B0,%C1" CR_TAB
6457                                 "mov %A0,%B1", op, plen, 5);
6458
6459         case 16:
6460           if (dest != src + 2)
6461             avr_asm_len ("mov %A0,%C1", op, plen, 1);
6462
6463           return avr_asm_len ("clr %B0"     CR_TAB
6464                               "sbrc %A0,7"  CR_TAB
6465                               "com %B0"     CR_TAB
6466                               "mov %C0,%B0", op, plen, 4);
6467
6468         default:
6469           if (INTVAL (op[2]) < 24)
6470             break;
6471
6472           /* fall through */
6473
6474         case 23:
6475           return avr_asm_len ("lsl %C0"     CR_TAB
6476                               "sbc %A0,%A0" CR_TAB
6477                               "mov %B0,%A0" CR_TAB
6478                               "mov %C0,%A0", op, plen, 4);
6479         } /* switch */
6480     }
6481
6482   out_shift_with_cnt ("asr %C0" CR_TAB
6483                       "ror %B0" CR_TAB
6484                       "ror %A0", insn, op, plen, 3);
6485   return "";
6486 }
6487
6488
6489 /* 32-bit arithmetic shift right  ((signed long)x >> i) */
6490
6491 const char *
6492 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6493 {
6494   if (GET_CODE (operands[2]) == CONST_INT)
6495     {
6496       int k;
6497       int *t = len;
6498
6499       if (!len)
6500         len = &k;
6501
6502       switch (INTVAL (operands[2]))
6503         {
6504         case 8:
6505           {
6506             int reg0 = true_regnum (operands[0]);
6507             int reg1 = true_regnum (operands[1]);
6508             *len=6;
6509             if (reg0 <= reg1)
6510               return ("mov %A0,%B1" CR_TAB
6511                       "mov %B0,%C1" CR_TAB
6512                       "mov %C0,%D1" CR_TAB
6513                       "clr %D0"     CR_TAB
6514                       "sbrc %C0,7"  CR_TAB
6515                       "dec %D0");
6516             else
6517               return ("clr %D0"     CR_TAB
6518                       "sbrc %D1,7"  CR_TAB
6519                       "dec %D0"     CR_TAB
6520                       "mov %C0,%D1" CR_TAB
6521                       "mov %B0,%C1" CR_TAB
6522                       "mov %A0,%B1");
6523           }
6524
6525         case 16:
6526           {
6527             int reg0 = true_regnum (operands[0]);
6528             int reg1 = true_regnum (operands[1]);
6529
6530             if (reg0 == reg1 + 2)
6531               return *len = 4, ("clr %D0"     CR_TAB
6532                                 "sbrc %B0,7"  CR_TAB
6533                                 "com %D0"     CR_TAB
6534                                 "mov %C0,%D0");
6535             if (AVR_HAVE_MOVW)
6536               return *len = 5, ("movw %A0,%C1" CR_TAB
6537                                 "clr %D0"      CR_TAB
6538                                 "sbrc %B0,7"   CR_TAB
6539                                 "com %D0"      CR_TAB
6540                                 "mov %C0,%D0");
6541             else
6542               return *len = 6, ("mov %B0,%D1" CR_TAB
6543                                 "mov %A0,%C1" CR_TAB
6544                                 "clr %D0"     CR_TAB
6545                                 "sbrc %B0,7"  CR_TAB
6546                                 "com %D0"     CR_TAB
6547                                 "mov %C0,%D0");
6548           }
6549
6550         case 24:
6551           return *len = 6, ("mov %A0,%D1" CR_TAB
6552                             "clr %D0"     CR_TAB
6553                             "sbrc %A0,7"  CR_TAB
6554                             "com %D0"     CR_TAB
6555                             "mov %B0,%D0" CR_TAB
6556                             "mov %C0,%D0");
6557
6558         default:
6559           if (INTVAL (operands[2]) < 32)
6560             break;
6561
6562           /* fall through */
6563
6564         case 31:
6565           if (AVR_HAVE_MOVW)
6566             return *len = 4, ("lsl %D0"     CR_TAB
6567                               "sbc %A0,%A0" CR_TAB
6568                               "mov %B0,%A0" CR_TAB
6569                               "movw %C0,%A0");
6570           else
6571             return *len = 5, ("lsl %D0"     CR_TAB
6572                               "sbc %A0,%A0" CR_TAB
6573                               "mov %B0,%A0" CR_TAB
6574                               "mov %C0,%A0" CR_TAB
6575                               "mov %D0,%A0");
6576         }
6577       len = t;
6578     }
6579   out_shift_with_cnt ("asr %D0" CR_TAB
6580                       "ror %C0" CR_TAB
6581                       "ror %B0" CR_TAB
6582                       "ror %A0", insn, operands, len, 4);
6583   return "";
6584 }
6585
6586 /* 8-bit logic shift right ((unsigned char)x >> i) */
6587
6588 const char *
6589 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6590 {
6591   if (GET_CODE (operands[2]) == CONST_INT)
6592     {
6593       int k;
6594
6595       if (!len)
6596         len = &k;
6597
6598       switch (INTVAL (operands[2]))
6599         {
6600         default:
6601           if (INTVAL (operands[2]) < 8)
6602             break;
6603
6604           *len = 1;
6605           return "clr %0";
6606
6607         case 1:
6608           *len = 1;
6609           return "lsr %0";
6610
6611         case 2:
6612           *len = 2;
6613           return ("lsr %0" CR_TAB
6614                   "lsr %0");
6615         case 3:
6616           *len = 3;
6617           return ("lsr %0" CR_TAB
6618                   "lsr %0" CR_TAB
6619                   "lsr %0");
6620
6621         case 4:
6622           if (test_hard_reg_class (LD_REGS, operands[0]))
6623             {
6624               *len=2;
6625               return ("swap %0" CR_TAB
6626                       "andi %0,0x0f");
6627             }
6628           *len = 4;
6629           return ("lsr %0" CR_TAB
6630                   "lsr %0" CR_TAB
6631                   "lsr %0" CR_TAB
6632                   "lsr %0");
6633
6634         case 5:
6635           if (test_hard_reg_class (LD_REGS, operands[0]))
6636             {
6637               *len = 3;
6638               return ("swap %0" CR_TAB
6639                       "lsr %0"  CR_TAB
6640                       "andi %0,0x7");
6641             }
6642           *len = 5;
6643           return ("lsr %0" CR_TAB
6644                   "lsr %0" CR_TAB
6645                   "lsr %0" CR_TAB
6646                   "lsr %0" CR_TAB
6647                   "lsr %0");
6648
6649         case 6:
6650           if (test_hard_reg_class (LD_REGS, operands[0]))
6651             {
6652               *len = 4;
6653               return ("swap %0" CR_TAB
6654                       "lsr %0"  CR_TAB
6655                       "lsr %0"  CR_TAB
6656                       "andi %0,0x3");
6657             }
6658           *len = 6;
6659           return ("lsr %0" CR_TAB
6660                   "lsr %0" CR_TAB
6661                   "lsr %0" CR_TAB
6662                   "lsr %0" CR_TAB
6663                   "lsr %0" CR_TAB
6664                   "lsr %0");
6665
6666         case 7:
6667           *len = 3;
6668           return ("rol %0" CR_TAB
6669                   "clr %0" CR_TAB
6670                   "rol %0");
6671         }
6672     }
6673   else if (CONSTANT_P (operands[2]))
6674     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
6675
6676   out_shift_with_cnt ("lsr %0",
6677                       insn, operands, len, 1);
6678   return "";
6679 }
6680
6681 /* 16-bit logic shift right ((unsigned short)x >> i) */
6682
6683 const char *
6684 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6685 {
6686   if (GET_CODE (operands[2]) == CONST_INT)
6687     {
6688       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6689       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6690       int k;
6691       int *t = len;
6692
6693       if (!len)
6694         len = &k;
6695
6696       switch (INTVAL (operands[2]))
6697         {
6698         default:
6699           if (INTVAL (operands[2]) < 16)
6700             break;
6701
6702           *len = 2;
6703           return ("clr %B0" CR_TAB
6704                   "clr %A0");
6705
6706         case 4:
6707           if (optimize_size && scratch)
6708             break;  /* 5 */
6709           if (ldi_ok)
6710             {
6711               *len = 6;
6712               return ("swap %B0"      CR_TAB
6713                       "swap %A0"      CR_TAB
6714                       "andi %A0,0x0f" CR_TAB
6715                       "eor %A0,%B0"   CR_TAB
6716                       "andi %B0,0x0f" CR_TAB
6717                       "eor %A0,%B0");
6718             }
6719           if (scratch)
6720             {
6721               *len = 7;
6722               return ("swap %B0"    CR_TAB
6723                       "swap %A0"    CR_TAB
6724                       "ldi %3,0x0f" CR_TAB
6725                       "and %A0,%3"      CR_TAB
6726                       "eor %A0,%B0" CR_TAB
6727                       "and %B0,%3"      CR_TAB
6728                       "eor %A0,%B0");
6729             }
6730           break;  /* optimize_size ? 6 : 8 */
6731
6732         case 5:
6733           if (optimize_size)
6734             break;  /* scratch ? 5 : 6 */
6735           if (ldi_ok)
6736             {
6737               *len = 8;
6738               return ("lsr %B0"       CR_TAB
6739                       "ror %A0"       CR_TAB
6740                       "swap %B0"      CR_TAB
6741                       "swap %A0"      CR_TAB
6742                       "andi %A0,0x0f" CR_TAB
6743                       "eor %A0,%B0"   CR_TAB
6744                       "andi %B0,0x0f" CR_TAB
6745                       "eor %A0,%B0");
6746             }
6747           if (scratch)
6748             {
6749               *len = 9;
6750               return ("lsr %B0"     CR_TAB
6751                       "ror %A0"     CR_TAB
6752                       "swap %B0"    CR_TAB
6753                       "swap %A0"    CR_TAB
6754                       "ldi %3,0x0f" CR_TAB
6755                       "and %A0,%3"      CR_TAB
6756                       "eor %A0,%B0" CR_TAB
6757                       "and %B0,%3"      CR_TAB
6758                       "eor %A0,%B0");
6759             }
6760           break;  /* 10 */
6761
6762         case 6:
6763           if (optimize_size)
6764             break;  /* scratch ? 5 : 6 */
6765           *len = 9;
6766           return ("clr __tmp_reg__" CR_TAB
6767                   "lsl %A0"         CR_TAB
6768                   "rol %B0"         CR_TAB
6769                   "rol __tmp_reg__" CR_TAB
6770                   "lsl %A0"         CR_TAB
6771                   "rol %B0"         CR_TAB
6772                   "rol __tmp_reg__" CR_TAB
6773                   "mov %A0,%B0"     CR_TAB
6774                   "mov %B0,__tmp_reg__");
6775
6776         case 7:
6777           *len = 5;
6778           return ("lsl %A0"     CR_TAB
6779                   "mov %A0,%B0" CR_TAB
6780                   "rol %A0"     CR_TAB
6781                   "sbc %B0,%B0" CR_TAB
6782                   "neg %B0");
6783
6784         case 8:
6785           return *len = 2, ("mov %A0,%B1" CR_TAB
6786                             "clr %B0");
6787
6788         case 9:
6789           *len = 3;
6790           return ("mov %A0,%B0" CR_TAB
6791                   "clr %B0"     CR_TAB
6792                   "lsr %A0");
6793
6794         case 10:
6795           *len = 4;
6796           return ("mov %A0,%B0" CR_TAB
6797                   "clr %B0"     CR_TAB
6798                   "lsr %A0"     CR_TAB
6799                   "lsr %A0");
6800
6801         case 11:
6802           *len = 5;
6803           return ("mov %A0,%B0" CR_TAB
6804                   "clr %B0"     CR_TAB
6805                   "lsr %A0"     CR_TAB
6806                   "lsr %A0"     CR_TAB
6807                   "lsr %A0");
6808
6809         case 12:
6810           if (ldi_ok)
6811             {
6812               *len = 4;
6813               return ("mov %A0,%B0" CR_TAB
6814                       "clr %B0"     CR_TAB
6815                       "swap %A0"    CR_TAB
6816                       "andi %A0,0x0f");
6817             }
6818           if (scratch)
6819             {
6820               *len = 5;
6821               return ("mov %A0,%B0" CR_TAB
6822                       "clr %B0"     CR_TAB
6823                       "swap %A0"    CR_TAB
6824                       "ldi %3,0x0f" CR_TAB
6825                       "and %A0,%3");
6826             }
6827           *len = 6;
6828           return ("mov %A0,%B0" CR_TAB
6829                   "clr %B0"     CR_TAB
6830                   "lsr %A0"     CR_TAB
6831                   "lsr %A0"     CR_TAB
6832                   "lsr %A0"     CR_TAB
6833                   "lsr %A0");
6834
6835         case 13:
6836           if (ldi_ok)
6837             {
6838               *len = 5;
6839               return ("mov %A0,%B0" CR_TAB
6840                       "clr %B0"     CR_TAB
6841                       "swap %A0"    CR_TAB
6842                       "lsr %A0"     CR_TAB
6843                       "andi %A0,0x07");
6844             }
6845           if (AVR_HAVE_MUL && scratch)
6846             {
6847               *len = 5;
6848               return ("ldi %3,0x08" CR_TAB
6849                       "mul %B0,%3"  CR_TAB
6850                       "mov %A0,r1"  CR_TAB
6851                       "clr %B0"     CR_TAB
6852                       "clr __zero_reg__");
6853             }
6854           if (optimize_size && scratch)
6855             break;  /* 5 */
6856           if (scratch)
6857             {
6858               *len = 6;
6859               return ("mov %A0,%B0" CR_TAB
6860                       "clr %B0"     CR_TAB
6861                       "swap %A0"    CR_TAB
6862                       "lsr %A0"     CR_TAB
6863                       "ldi %3,0x07" CR_TAB
6864                       "and %A0,%3");
6865             }
6866           if (AVR_HAVE_MUL)
6867             {
6868               *len = 6;
6869               return ("set"            CR_TAB
6870                       "bld r1,3"   CR_TAB
6871                       "mul %B0,r1" CR_TAB
6872                       "mov %A0,r1" CR_TAB
6873                       "clr %B0"    CR_TAB
6874                       "clr __zero_reg__");
6875             }
6876           *len = 7;
6877           return ("mov %A0,%B0" CR_TAB
6878                   "clr %B0"     CR_TAB
6879                   "lsr %A0"     CR_TAB
6880                   "lsr %A0"     CR_TAB
6881                   "lsr %A0"     CR_TAB
6882                   "lsr %A0"     CR_TAB
6883                   "lsr %A0");
6884
6885         case 14:
6886           if (AVR_HAVE_MUL && ldi_ok)
6887             {
6888               *len = 5;
6889               return ("ldi %A0,0x04" CR_TAB
6890                       "mul %B0,%A0"  CR_TAB
6891                       "mov %A0,r1"   CR_TAB
6892                       "clr %B0"      CR_TAB
6893                       "clr __zero_reg__");
6894             }
6895           if (AVR_HAVE_MUL && scratch)
6896             {
6897               *len = 5;
6898               return ("ldi %3,0x04" CR_TAB
6899                       "mul %B0,%3"  CR_TAB
6900                       "mov %A0,r1"  CR_TAB
6901                       "clr %B0"     CR_TAB
6902                       "clr __zero_reg__");
6903             }
6904           if (optimize_size && ldi_ok)
6905             {
6906               *len = 5;
6907               return ("mov %A0,%B0" CR_TAB
6908                       "ldi %B0,6" "\n1:\t"
6909                       "lsr %A0"     CR_TAB
6910                       "dec %B0"     CR_TAB
6911                       "brne 1b");
6912             }
6913           if (optimize_size && scratch)
6914             break;  /* 5 */
6915           *len = 6;
6916           return ("clr %A0" CR_TAB
6917                   "lsl %B0" CR_TAB
6918                   "rol %A0" CR_TAB
6919                   "lsl %B0" CR_TAB
6920                   "rol %A0" CR_TAB
6921                   "clr %B0");
6922
6923         case 15:
6924           *len = 4;
6925           return ("clr %A0" CR_TAB
6926                   "lsl %B0" CR_TAB
6927                   "rol %A0" CR_TAB
6928                   "clr %B0");
6929         }
6930       len = t;
6931     }
6932   out_shift_with_cnt ("lsr %B0" CR_TAB
6933                       "ror %A0", insn, operands, len, 2);
6934   return "";
6935 }
6936
6937
6938 /* 24-bit logic shift right */
6939
6940 const char*
6941 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6942 {
6943   int dest = REGNO (op[0]);
6944   int src = REGNO (op[1]);
6945
6946   if (CONST_INT_P (op[2]))
6947     {
6948       if (plen)
6949         *plen = 0;
6950
6951       switch (INTVAL (op[2]))
6952         {
6953         case 8:
6954           if (dest <= src)
6955             return avr_asm_len ("mov %A0,%B1" CR_TAB
6956                                 "mov %B0,%C1" CR_TAB
6957                                 "clr %C0", op, plen, 3);
6958           else
6959             return avr_asm_len ("clr %C0"     CR_TAB
6960                                 "mov %B0,%C1" CR_TAB
6961                                 "mov %A0,%B1", op, plen, 3);
6962
6963         case 16:
6964           if (dest != src + 2)
6965             avr_asm_len ("mov %A0,%C1", op, plen, 1);
6966
6967           return avr_asm_len ("clr %B0"  CR_TAB
6968                               "clr %C0", op, plen, 2);
6969
6970         default:
6971           if (INTVAL (op[2]) < 24)
6972             break;
6973
6974           /* fall through */
6975
6976         case 23:
6977           return avr_asm_len ("clr %A0"    CR_TAB
6978                               "sbrc %C0,7" CR_TAB
6979                               "inc %A0"    CR_TAB
6980                               "clr %B0"    CR_TAB
6981                               "clr %C0", op, plen, 5);
6982         } /* switch */
6983     }
6984
6985   out_shift_with_cnt ("lsr %C0" CR_TAB
6986                       "ror %B0" CR_TAB
6987                       "ror %A0", insn, op, plen, 3);
6988   return "";
6989 }
6990
6991
6992 /* 32-bit logic shift right ((unsigned int)x >> i) */
6993
6994 const char *
6995 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6996 {
6997   if (GET_CODE (operands[2]) == CONST_INT)
6998     {
6999       int k;
7000       int *t = len;
7001
7002       if (!len)
7003         len = &k;
7004
7005       switch (INTVAL (operands[2]))
7006         {
7007         default:
7008           if (INTVAL (operands[2]) < 32)
7009             break;
7010
7011           if (AVR_HAVE_MOVW)
7012             return *len = 3, ("clr %D0" CR_TAB
7013                               "clr %C0" CR_TAB
7014                               "movw %A0,%C0");
7015           *len = 4;
7016           return ("clr %D0" CR_TAB
7017                   "clr %C0" CR_TAB
7018                   "clr %B0" CR_TAB
7019                   "clr %A0");
7020
7021         case 8:
7022           {
7023             int reg0 = true_regnum (operands[0]);
7024             int reg1 = true_regnum (operands[1]);
7025             *len = 4;
7026             if (reg0 <= reg1)
7027               return ("mov %A0,%B1" CR_TAB
7028                       "mov %B0,%C1" CR_TAB
7029                       "mov %C0,%D1" CR_TAB
7030                       "clr %D0");
7031             else
7032               return ("clr %D0"     CR_TAB
7033                       "mov %C0,%D1" CR_TAB
7034                       "mov %B0,%C1" CR_TAB
7035                       "mov %A0,%B1");
7036           }
7037
7038         case 16:
7039           {
7040             int reg0 = true_regnum (operands[0]);
7041             int reg1 = true_regnum (operands[1]);
7042
7043             if (reg0 == reg1 + 2)
7044               return *len = 2, ("clr %C0"     CR_TAB
7045                                 "clr %D0");
7046             if (AVR_HAVE_MOVW)
7047               return *len = 3, ("movw %A0,%C1" CR_TAB
7048                                 "clr %C0"      CR_TAB
7049                                 "clr %D0");
7050             else
7051               return *len = 4, ("mov %B0,%D1" CR_TAB
7052                                 "mov %A0,%C1" CR_TAB
7053                                 "clr %C0"     CR_TAB
7054                                 "clr %D0");
7055           }
7056
7057         case 24:
7058           return *len = 4, ("mov %A0,%D1" CR_TAB
7059                             "clr %B0"     CR_TAB
7060                             "clr %C0"     CR_TAB
7061                             "clr %D0");
7062
7063         case 31:
7064           *len = 6;
7065           return ("clr %A0"    CR_TAB
7066                   "sbrc %D0,7" CR_TAB
7067                   "inc %A0"    CR_TAB
7068                   "clr %B0"    CR_TAB
7069                   "clr %C0"    CR_TAB
7070                   "clr %D0");
7071         }
7072       len = t;
7073     }
7074   out_shift_with_cnt ("lsr %D0" CR_TAB
7075                       "ror %C0" CR_TAB
7076                       "ror %B0" CR_TAB
7077                       "ror %A0", insn, operands, len, 4);
7078   return "";
7079 }
7080
7081
7082 /* Output addition of register XOP[0] and compile time constant XOP[2].
7083    CODE == PLUS:  perform addition by using ADD instructions or
7084    CODE == MINUS: perform addition by using SUB instructions:
7085
7086       XOP[0] = XOP[0] + XOP[2]
7087
7088    Or perform addition/subtraction with register XOP[2] depending on CODE:
7089
7090       XOP[0] = XOP[0] +/- XOP[2]
7091
7092    If PLEN == NULL, print assembler instructions to perform the operation;
7093    otherwise, set *PLEN to the length of the instruction sequence (in words)
7094    printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register or NULL_RTX.
7095    Set *PCC to effect on cc0 according to respective CC_* insn attribute.
7096
7097    CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
7098    CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
7099    If  CODE_SAT != UNKNOWN  then SIGN contains the sign of the summand resp.
7100    the subtrahend in the original insn, provided it is a compile time constant.
7101    In all other cases, SIGN is 0.
7102
7103    If OUT_LABEL is true, print the final 0: label which is needed for
7104    saturated addition / subtraction.  The only case where OUT_LABEL = false
7105    is useful is for saturated addition / subtraction performed during
7106    fixed-point rounding, cf. `avr_out_round'.  */
7107
7108 static void
7109 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
7110                 enum rtx_code code_sat, int sign, bool out_label)
7111 {
7112   /* MODE of the operation.  */
7113   machine_mode mode = GET_MODE (xop[0]);
7114
7115   /* INT_MODE of the same size.  */
7116   machine_mode imode = int_mode_for_mode (mode);
7117
7118   /* Number of bytes to operate on.  */
7119   int i, n_bytes = GET_MODE_SIZE (mode);
7120
7121   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
7122   int clobber_val = -1;
7123
7124   /* op[0]: 8-bit destination register
7125      op[1]: 8-bit const int
7126      op[2]: 8-bit scratch register */
7127   rtx op[3];
7128
7129   /* Started the operation?  Before starting the operation we may skip
7130      adding 0.  This is no more true after the operation started because
7131      carry must be taken into account.  */
7132   bool started = false;
7133
7134   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
7135   rtx xval = xop[2];
7136
7137   /* Output a BRVC instruction.  Only needed with saturation.  */
7138   bool out_brvc = true;
7139
7140   if (plen)
7141     *plen = 0;
7142
7143   if (REG_P (xop[2]))
7144     {
7145       *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
7146
7147       for (i = 0; i < n_bytes; i++)
7148         {
7149           /* We operate byte-wise on the destination.  */
7150           op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
7151           op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
7152
7153           if (i == 0)
7154             avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
7155                          op, plen, 1);
7156           else
7157             avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
7158                          op, plen, 1);
7159         }
7160
7161       if (reg_overlap_mentioned_p (xop[0], xop[2]))
7162         {
7163           gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
7164
7165           if (MINUS == code)
7166             return;
7167         }
7168
7169       goto saturate;
7170     }
7171
7172   /* Except in the case of ADIW with 16-bit register (see below)
7173      addition does not set cc0 in a usable way.  */
7174
7175   *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
7176
7177   if (CONST_FIXED_P (xval))
7178     xval = avr_to_int_mode (xval);
7179
7180   /* Adding/Subtracting zero is a no-op.  */
7181
7182   if (xval == const0_rtx)
7183     {
7184       *pcc = CC_NONE;
7185       return;
7186     }
7187
7188   if (MINUS == code)
7189     xval = simplify_unary_operation (NEG, imode, xval, imode);
7190
7191   op[2] = xop[3];
7192
7193   if (SS_PLUS == code_sat && MINUS == code
7194       && sign < 0
7195       && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
7196                   & GET_MODE_MASK (QImode)))
7197     {
7198       /* We compute x + 0x80 by means of SUB instructions.  We negated the
7199          constant subtrahend above and are left with  x - (-128)  so that we
7200          need something like SUBI r,128 which does not exist because SUBI sets
7201          V according to the sign of the subtrahend.  Notice the only case
7202          where this must be done is when NEG overflowed in case [2s] because
7203          the V computation needs the right sign of the subtrahend.  */
7204
7205       rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7206
7207       avr_asm_len ("subi %0,128" CR_TAB
7208                    "brmi 0f", &msb, plen, 2);
7209       out_brvc = false;
7210
7211       goto saturate;
7212     }
7213
7214   for (i = 0; i < n_bytes; i++)
7215     {
7216       /* We operate byte-wise on the destination.  */
7217       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7218       rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
7219
7220       /* 8-bit value to operate with this byte. */
7221       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7222
7223       /* Registers R16..R31 can operate with immediate.  */
7224       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7225
7226       op[0] = reg8;
7227       op[1] = gen_int_mode (val8, QImode);
7228
7229       /* To get usable cc0 no low-bytes must have been skipped.  */
7230
7231       if (i && !started)
7232         *pcc = CC_CLOBBER;
7233
7234       if (!started
7235           && i % 2 == 0
7236           && i + 2 <= n_bytes
7237           && test_hard_reg_class (ADDW_REGS, reg8))
7238         {
7239           rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
7240           unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
7241
7242           /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
7243              i.e. operate word-wise.  */
7244
7245           if (val16 < 64)
7246             {
7247               if (val16 != 0)
7248                 {
7249                   started = true;
7250                   avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
7251                                op, plen, 1);
7252
7253                   if (n_bytes == 2 && PLUS == code)
7254                     *pcc = CC_SET_CZN;
7255                 }
7256
7257               i++;
7258               continue;
7259             }
7260         }
7261
7262       if (val8 == 0)
7263         {
7264           if (started)
7265             avr_asm_len (code == PLUS
7266                          ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
7267                          op, plen, 1);
7268           continue;
7269         }
7270       else if ((val8 == 1 || val8 == 0xff)
7271                && UNKNOWN == code_sat
7272                && !started
7273                && i == n_bytes - 1)
7274         {
7275           avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
7276                        op, plen, 1);
7277           *pcc = CC_CLOBBER;
7278           break;
7279         }
7280
7281       switch (code)
7282         {
7283         case PLUS:
7284
7285           gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
7286
7287           if (plen != NULL && UNKNOWN != code_sat)
7288             {
7289               /* This belongs to the x + 0x80 corner case.  The code with
7290                  ADD instruction is not smaller, thus make this case
7291                  expensive so that the caller won't pick it.  */
7292
7293               *plen += 10;
7294               break;
7295             }
7296
7297           if (clobber_val != (int) val8)
7298             avr_asm_len ("ldi %2,%1", op, plen, 1);
7299           clobber_val = (int) val8;
7300
7301           avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
7302
7303           break; /* PLUS */
7304
7305         case MINUS:
7306
7307           if (ld_reg_p)
7308             avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
7309           else
7310             {
7311               gcc_assert (plen != NULL || REG_P (op[2]));
7312
7313               if (clobber_val != (int) val8)
7314                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7315               clobber_val = (int) val8;
7316
7317               avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
7318             }
7319
7320           break; /* MINUS */
7321
7322         default:
7323           /* Unknown code */
7324           gcc_unreachable();
7325         }
7326
7327       started = true;
7328
7329     } /* for all sub-bytes */
7330
7331  saturate:
7332
7333   if (UNKNOWN == code_sat)
7334     return;
7335
7336   *pcc = (int) CC_CLOBBER;
7337
7338   /* Vanilla addition/subtraction is done.  We are left with saturation.
7339
7340      We have to compute  A = A <op> B  where  A  is a register and
7341      B is a register or a non-zero compile time constant CONST.
7342      A is register class "r" if unsigned && B is REG.  Otherwise, A is in "d".
7343      B stands for the original operand $2 in INSN.  In the case of B = CONST,
7344      SIGN in { -1, 1 } is the sign of B.  Otherwise, SIGN is 0.
7345
7346      CODE is the instruction flavor we use in the asm sequence to perform <op>.
7347
7348
7349      unsigned
7350      operation        |  code |  sat if  |    b is      | sat value |  case
7351      -----------------+-------+----------+--------------+-----------+-------
7352      +  as  a + b     |  add  |  C == 1  |  const, reg  | u+ = 0xff |  [1u]
7353      +  as  a - (-b)  |  sub  |  C == 0  |  const       | u+ = 0xff |  [2u]
7354      -  as  a - b     |  sub  |  C == 1  |  const, reg  | u- = 0    |  [3u]
7355      -  as  a + (-b)  |  add  |  C == 0  |  const       | u- = 0    |  [4u]
7356
7357
7358      signed
7359      operation        |  code |  sat if  |    b is      | sat value |  case
7360      -----------------+-------+----------+--------------+-----------+-------
7361      +  as  a + b     |  add  |  V == 1  |  const, reg  | s+        |  [1s]
7362      +  as  a - (-b)  |  sub  |  V == 1  |  const       | s+        |  [2s]
7363      -  as  a - b     |  sub  |  V == 1  |  const, reg  | s-        |  [3s]
7364      -  as  a + (-b)  |  add  |  V == 1  |  const       | s-        |  [4s]
7365
7366      s+  =  b < 0  ?  -0x80 :  0x7f
7367      s-  =  b < 0  ?   0x7f : -0x80
7368
7369      The cases a - b actually perform  a - (-(-b))  if B is CONST.
7370   */
7371
7372   op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7373   op[1] = n_bytes > 1
7374     ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
7375     : NULL_RTX;
7376
7377   bool need_copy = true;
7378   int len_call = 1 + AVR_HAVE_JMP_CALL;
7379
7380   switch (code_sat)
7381     {
7382     default:
7383       gcc_unreachable();
7384
7385     case SS_PLUS:
7386     case SS_MINUS:
7387
7388       if (out_brvc)
7389         avr_asm_len ("brvc 0f", op, plen, 1);
7390
7391       if (reg_overlap_mentioned_p (xop[0], xop[2]))
7392         {
7393           /* [1s,reg] */
7394
7395           if (n_bytes == 1)
7396             avr_asm_len ("ldi %0,0x7f" CR_TAB
7397                          "adc %0,__zero_reg__", op, plen, 2);
7398           else
7399             avr_asm_len ("ldi %0,0x7f" CR_TAB
7400                          "ldi %1,0xff" CR_TAB
7401                          "adc %1,__zero_reg__" CR_TAB
7402                          "adc %0,__zero_reg__", op, plen, 4);
7403         }
7404       else if (sign == 0 && PLUS == code)
7405         {
7406           /* [1s,reg] */
7407
7408           op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7409
7410           if (n_bytes == 1)
7411             avr_asm_len ("ldi %0,0x80" CR_TAB
7412                          "sbrs %2,7"   CR_TAB
7413                          "dec %0", op, plen, 3);
7414           else
7415             avr_asm_len ("ldi %0,0x80" CR_TAB
7416                          "cp %2,%0"    CR_TAB
7417                          "sbc %1,%1"   CR_TAB
7418                          "sbci %0,0", op, plen, 4);
7419         }
7420       else if (sign == 0 && MINUS == code)
7421         {
7422           /* [3s,reg] */
7423
7424           op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7425
7426           if (n_bytes == 1)
7427             avr_asm_len ("ldi %0,0x7f" CR_TAB
7428                          "sbrs %2,7"   CR_TAB
7429                          "inc %0", op, plen, 3);
7430           else
7431             avr_asm_len ("ldi %0,0x7f" CR_TAB
7432                          "cp %0,%2"    CR_TAB
7433                          "sbc %1,%1"   CR_TAB
7434                          "sbci %0,-1", op, plen, 4);
7435         }
7436       else if ((sign < 0) ^ (SS_MINUS == code_sat))
7437         {
7438           /* [1s,const,B < 0] [2s,B < 0] */
7439           /* [3s,const,B > 0] [4s,B > 0] */
7440
7441           if (n_bytes == 8)
7442             {
7443               avr_asm_len ("%~call __clr_8", op, plen, len_call);
7444               need_copy = false;
7445             }
7446
7447           avr_asm_len ("ldi %0,0x80", op, plen, 1);
7448           if (n_bytes > 1 && need_copy)
7449             avr_asm_len ("clr %1", op, plen, 1);
7450         }
7451       else if ((sign > 0) ^ (SS_MINUS == code_sat))
7452         {
7453           /* [1s,const,B > 0] [2s,B > 0] */
7454           /* [3s,const,B < 0] [4s,B < 0] */
7455
7456           if (n_bytes == 8)
7457             {
7458               avr_asm_len ("sec" CR_TAB
7459                            "%~call __sbc_8", op, plen, 1 + len_call);
7460               need_copy = false;
7461             }
7462
7463           avr_asm_len ("ldi %0,0x7f", op, plen, 1);
7464           if (n_bytes > 1 && need_copy)
7465             avr_asm_len ("ldi %1,0xff", op, plen, 1);
7466         }
7467       else
7468         gcc_unreachable();
7469
7470       break;
7471
7472     case US_PLUS:
7473       /* [1u] : [2u] */
7474
7475       avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
7476
7477       if (n_bytes == 8)
7478         {
7479           if (MINUS == code)
7480             avr_asm_len ("sec", op, plen, 1);
7481           avr_asm_len ("%~call __sbc_8", op, plen, len_call);
7482
7483           need_copy = false;
7484         }
7485       else
7486         {
7487           if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
7488             avr_asm_len ("sec" CR_TAB
7489                          "sbc %0,%0", op, plen, 2);
7490           else
7491             avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
7492                          op, plen, 1);
7493         }
7494       break; /* US_PLUS */
7495
7496     case US_MINUS:
7497       /* [4u] : [3u] */
7498
7499       avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
7500
7501       if (n_bytes == 8)
7502         {
7503           avr_asm_len ("%~call __clr_8", op, plen, len_call);
7504           need_copy = false;
7505         }
7506       else
7507         avr_asm_len ("clr %0", op, plen, 1);
7508
7509       break;
7510     }
7511
7512   /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
7513      Now copy the right value to the LSBs.  */
7514
7515   if (need_copy && n_bytes > 1)
7516     {
7517       if (US_MINUS == code_sat || US_PLUS == code_sat)
7518         {
7519           avr_asm_len ("mov %1,%0", op, plen, 1);
7520
7521           if (n_bytes > 2)
7522             {
7523               op[0] = xop[0];
7524               if (AVR_HAVE_MOVW)
7525                 avr_asm_len ("movw %0,%1", op, plen, 1);
7526               else
7527                 avr_asm_len ("mov %A0,%1" CR_TAB
7528                              "mov %B0,%1", op, plen, 2);
7529             }
7530         }
7531       else if (n_bytes > 2)
7532         {
7533           op[0] = xop[0];
7534           avr_asm_len ("mov %A0,%1" CR_TAB
7535                        "mov %B0,%1", op, plen, 2);
7536         }
7537     }
7538
7539   if (need_copy && n_bytes == 8)
7540     {
7541       if (AVR_HAVE_MOVW)
7542         avr_asm_len ("movw %r0+2,%0" CR_TAB
7543                      "movw %r0+4,%0", xop, plen, 2);
7544       else
7545         avr_asm_len ("mov %r0+2,%0" CR_TAB
7546                      "mov %r0+3,%0" CR_TAB
7547                      "mov %r0+4,%0" CR_TAB
7548                      "mov %r0+5,%0", xop, plen, 4);
7549     }
7550
7551   if (out_label)
7552     avr_asm_len ("0:", op, plen, 0);
7553 }
7554
7555
7556 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
7557    is ont a compile-time constant:
7558
7559       XOP[0] = XOP[0] +/- XOP[2]
7560
7561    This is a helper for the function below.  The only insns that need this
7562    are additions/subtraction for pointer modes, i.e. HImode and PSImode.  */
7563
7564 static const char*
7565 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
7566 {
7567   machine_mode mode = GET_MODE (xop[0]);
7568
7569   /* Only pointer modes want to add symbols.  */
7570
7571   gcc_assert (mode == HImode || mode == PSImode);
7572
7573   *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
7574
7575   avr_asm_len (PLUS == code
7576                ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
7577                : "subi %A0,lo8(%2)"    CR_TAB "sbci %B0,hi8(%2)",
7578                xop, plen, -2);
7579
7580   if (PSImode == mode)
7581     avr_asm_len (PLUS == code
7582                  ? "sbci %C0,hlo8(-(%2))"
7583                  : "sbci %C0,hlo8(%2)", xop, plen, 1);
7584   return "";
7585 }
7586
7587
7588 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
7589
7590    INSN is a single_set insn or an insn pattern with a binary operation as
7591    SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
7592
7593    XOP are the operands of INSN.  In the case of 64-bit operations with
7594    constant XOP[] has just one element:  The summand/subtrahend in XOP[0].
7595    The non-saturating insns up to 32 bits may or may not supply a "d" class
7596    scratch as XOP[3].
7597
7598    If PLEN == NULL output the instructions.
7599    If PLEN != NULL set *PLEN to the length of the sequence in words.
7600
7601    PCC is a pointer to store the instructions' effect on cc0.
7602    PCC may be NULL.
7603
7604    PLEN and PCC default to NULL.
7605
7606    OUT_LABEL defaults to TRUE.  For a description, see AVR_OUT_PLUS_1.
7607
7608    Return ""  */
7609
7610 const char*
7611 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
7612 {
7613   int cc_plus, cc_minus, cc_dummy;
7614   int len_plus, len_minus;
7615   rtx op[4];
7616   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7617   rtx xdest = SET_DEST (xpattern);
7618   machine_mode mode = GET_MODE (xdest);
7619   machine_mode imode = int_mode_for_mode (mode);
7620   int n_bytes = GET_MODE_SIZE (mode);
7621   enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
7622   enum rtx_code code
7623     = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
7624        ? PLUS : MINUS);
7625
7626   if (!pcc)
7627     pcc = &cc_dummy;
7628
7629   /* PLUS and MINUS don't saturate:  Use modular wrap-around.  */
7630
7631   if (PLUS == code_sat || MINUS == code_sat)
7632     code_sat = UNKNOWN;
7633
7634   if (n_bytes <= 4 && REG_P (xop[2]))
7635     {
7636       avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
7637       return "";
7638     }
7639
7640   if (8 == n_bytes)
7641     {
7642       op[0] = gen_rtx_REG (DImode, ACC_A);
7643       op[1] = gen_rtx_REG (DImode, ACC_A);
7644       op[2] = avr_to_int_mode (xop[0]);
7645     }
7646   else
7647     {
7648       if (!REG_P (xop[2])
7649           && !CONST_INT_P (xop[2])
7650           && !CONST_FIXED_P (xop[2]))
7651         {
7652           return avr_out_plus_symbol (xop, code, plen, pcc);
7653         }
7654
7655       op[0] = avr_to_int_mode (xop[0]);
7656       op[1] = avr_to_int_mode (xop[1]);
7657       op[2] = avr_to_int_mode (xop[2]);
7658     }
7659
7660   /* Saturations and 64-bit operations don't have a clobber operand.
7661      For the other cases, the caller will provide a proper XOP[3].  */
7662
7663   xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
7664   op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
7665
7666   /* Saturation will need the sign of the original operand.  */
7667
7668   rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
7669   int sign = INTVAL (xmsb) < 0 ? -1 : 1;
7670
7671   /* If we subtract and the subtrahend is a constant, then negate it
7672      so that avr_out_plus_1 can be used.  */
7673
7674   if (MINUS == code)
7675     op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
7676
7677   /* Work out the shortest sequence.  */
7678
7679   avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
7680   avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
7681
7682   if (plen)
7683     {
7684       *plen = (len_minus <= len_plus) ? len_minus : len_plus;
7685       *pcc  = (len_minus <= len_plus) ? cc_minus : cc_plus;
7686     }
7687   else if (len_minus <= len_plus)
7688     avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
7689   else
7690     avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
7691
7692   return "";
7693 }
7694
7695
7696 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
7697    time constant XOP[2]:
7698
7699       XOP[0] = XOP[0] <op> XOP[2]
7700
7701    and return "".  If PLEN == NULL, print assembler instructions to perform the
7702    operation; otherwise, set *PLEN to the length of the instruction sequence
7703    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
7704    register or SCRATCH if no clobber register is needed for the operation.
7705    INSN is an INSN_P or a pattern of an insn.  */
7706
7707 const char*
7708 avr_out_bitop (rtx insn, rtx *xop, int *plen)
7709 {
7710   /* CODE and MODE of the operation.  */
7711   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7712   enum rtx_code code = GET_CODE (SET_SRC (xpattern));
7713   machine_mode mode = GET_MODE (xop[0]);
7714
7715   /* Number of bytes to operate on.  */
7716   int i, n_bytes = GET_MODE_SIZE (mode);
7717
7718   /* Value of T-flag (0 or 1) or -1 if unknow.  */
7719   int set_t = -1;
7720
7721   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
7722   int clobber_val = -1;
7723
7724   /* op[0]: 8-bit destination register
7725      op[1]: 8-bit const int
7726      op[2]: 8-bit clobber register or SCRATCH
7727      op[3]: 8-bit register containing 0xff or NULL_RTX  */
7728   rtx op[4];
7729
7730   op[2] = xop[3];
7731   op[3] = NULL_RTX;
7732
7733   if (plen)
7734     *plen = 0;
7735
7736   for (i = 0; i < n_bytes; i++)
7737     {
7738       /* We operate byte-wise on the destination.  */
7739       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7740       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
7741
7742       /* 8-bit value to operate with this byte. */
7743       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7744
7745       /* Number of bits set in the current byte of the constant.  */
7746       int pop8 = avr_popcount (val8);
7747
7748       /* Registers R16..R31 can operate with immediate.  */
7749       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7750
7751       op[0] = reg8;
7752       op[1] = GEN_INT (val8);
7753
7754       switch (code)
7755         {
7756         case IOR:
7757
7758           if (0 == pop8)
7759             continue;
7760           else if (ld_reg_p)
7761             avr_asm_len ("ori %0,%1", op, plen, 1);
7762           else if (1 == pop8)
7763             {
7764               if (set_t != 1)
7765                 avr_asm_len ("set", op, plen, 1);
7766               set_t = 1;
7767
7768               op[1] = GEN_INT (exact_log2 (val8));
7769               avr_asm_len ("bld %0,%1", op, plen, 1);
7770             }
7771           else if (8 == pop8)
7772             {
7773               if (op[3] != NULL_RTX)
7774                 avr_asm_len ("mov %0,%3", op, plen, 1);
7775               else
7776                 avr_asm_len ("clr %0" CR_TAB
7777                              "dec %0", op, plen, 2);
7778
7779               op[3] = op[0];
7780             }
7781           else
7782             {
7783               if (clobber_val != (int) val8)
7784                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7785               clobber_val = (int) val8;
7786
7787               avr_asm_len ("or %0,%2", op, plen, 1);
7788             }
7789
7790           continue; /* IOR */
7791
7792         case AND:
7793
7794           if (8 == pop8)
7795             continue;
7796           else if (0 == pop8)
7797             avr_asm_len ("clr %0", op, plen, 1);
7798           else if (ld_reg_p)
7799             avr_asm_len ("andi %0,%1", op, plen, 1);
7800           else if (7 == pop8)
7801             {
7802               if (set_t != 0)
7803                 avr_asm_len ("clt", op, plen, 1);
7804               set_t = 0;
7805
7806               op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
7807               avr_asm_len ("bld %0,%1", op, plen, 1);
7808             }
7809           else
7810             {
7811               if (clobber_val != (int) val8)
7812                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7813               clobber_val = (int) val8;
7814
7815               avr_asm_len ("and %0,%2", op, plen, 1);
7816             }
7817
7818           continue; /* AND */
7819
7820         case XOR:
7821
7822           if (0 == pop8)
7823             continue;
7824           else if (8 == pop8)
7825             avr_asm_len ("com %0", op, plen, 1);
7826           else if (ld_reg_p && val8 == (1 << 7))
7827             avr_asm_len ("subi %0,%1", op, plen, 1);
7828           else
7829             {
7830               if (clobber_val != (int) val8)
7831                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7832               clobber_val = (int) val8;
7833
7834               avr_asm_len ("eor %0,%2", op, plen, 1);
7835             }
7836
7837           continue; /* XOR */
7838
7839         default:
7840           /* Unknown rtx_code */
7841           gcc_unreachable();
7842         }
7843     } /* for all sub-bytes */
7844
7845   return "";
7846 }
7847
7848
7849 /* Output sign extension from XOP[1] to XOP[0] and return "".
7850    If PLEN == NULL, print assembler instructions to perform the operation;
7851    otherwise, set *PLEN to the length of the instruction sequence (in words)
7852    as printed with PLEN == NULL.  */
7853
7854 const char*
7855 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
7856 {
7857   // Size in bytes of source resp. destination operand.
7858   unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
7859   unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
7860   rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
7861
7862   if (plen)
7863     *plen = 0;
7864
7865   // Copy destination to source
7866
7867   if (REGNO (xop[0]) != REGNO (xop[1]))
7868     {
7869       gcc_assert (n_src <= 2);
7870
7871       if (n_src == 2)
7872         avr_asm_len (AVR_HAVE_MOVW
7873                      ? "movw %0,%1"
7874                      : "mov %B0,%B1", xop, plen, 1);
7875       if (n_src == 1 || !AVR_HAVE_MOVW)
7876         avr_asm_len ("mov %A0,%A1", xop, plen, 1);
7877     }
7878
7879   // Set Carry to the sign bit MSB.7...
7880
7881   if (REGNO (xop[0]) == REGNO (xop[1])
7882       || !reg_unused_after (insn, r_msb))
7883     {
7884       avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
7885       r_msb = tmp_reg_rtx;
7886     }
7887   
7888   avr_asm_len ("lsl %0", &r_msb, plen, 1);
7889                    
7890   // ...and propagate it to all the new sign bits
7891
7892   for (unsigned n = n_src; n < n_dest; n++)
7893     avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
7894
7895   return "";
7896 }
7897
7898
7899 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
7900    PLEN != NULL: Set *PLEN to the length of that sequence.
7901    Return "".  */
7902
7903 const char*
7904 avr_out_addto_sp (rtx *op, int *plen)
7905 {
7906   int pc_len = AVR_2_BYTE_PC ? 2 : 3;
7907   int addend = INTVAL (op[0]);
7908
7909   if (plen)
7910     *plen = 0;
7911
7912   if (addend < 0)
7913     {
7914       if (flag_verbose_asm || flag_print_asm_name)
7915         avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7916
7917       while (addend <= -pc_len)
7918         {
7919           addend += pc_len;
7920           avr_asm_len ("rcall .", op, plen, 1);
7921         }
7922
7923       while (addend++ < 0)
7924         avr_asm_len ("push __zero_reg__", op, plen, 1);
7925     }
7926   else if (addend > 0)
7927     {
7928       if (flag_verbose_asm || flag_print_asm_name)
7929         avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7930
7931       while (addend-- > 0)
7932         avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7933     }
7934
7935   return "";
7936 }
7937
7938
7939 /* Outputs instructions needed for fixed point type conversion.
7940    This includes converting between any fixed point type, as well
7941    as converting to any integer type.  Conversion between integer
7942    types is not supported.
7943
7944    Converting signed fractional types requires a bit shift if converting
7945    to or from any unsigned fractional type because the decimal place is
7946    shifted by 1 bit.  When the destination is a signed fractional, the sign
7947    is stored in either the carry or T bit.  */
7948
7949 const char*
7950 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
7951 {
7952   size_t i;
7953   rtx xop[6];
7954   RTX_CODE shift = UNKNOWN;
7955   bool sign_in_carry = false;
7956   bool msb_in_carry = false;
7957   bool lsb_in_tmp_reg = false;
7958   bool lsb_in_carry = false;
7959   bool frac_rounded = false;
7960   const char *code_ashift = "lsl %0";
7961
7962
7963 #define MAY_CLOBBER(RR)                                                 \
7964   /* Shorthand used below.  */                                          \
7965   ((sign_bytes                                                          \
7966     && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb))  \
7967    || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb))             \
7968    || (reg_unused_after (insn, all_regs_rtx[RR])                        \
7969        && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7970
7971   struct
7972   {
7973     /* bytes       : Length of operand in bytes.
7974        ibyte       : Length of integral part in bytes.
7975        fbyte, fbit : Length of fractional part in bytes, bits.  */
7976
7977     bool sbit;
7978     unsigned fbit, bytes, ibyte, fbyte;
7979     unsigned regno, regno_msb;
7980   } dest, src, *val[2] = { &dest, &src };
7981
7982   if (plen)
7983     *plen = 0;
7984
7985   /* Step 0:  Determine information on source and destination operand we
7986      ======   will need in the remainder.  */
7987
7988   for (i = 0; i < sizeof (val) / sizeof (*val); i++)
7989     {
7990       machine_mode mode;
7991
7992       xop[i] = operands[i];
7993
7994       mode = GET_MODE (xop[i]);
7995
7996       val[i]->bytes = GET_MODE_SIZE (mode);
7997       val[i]->regno = REGNO (xop[i]);
7998       val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
7999
8000       if (SCALAR_INT_MODE_P (mode))
8001         {
8002           val[i]->sbit = intsigned;
8003           val[i]->fbit = 0;
8004         }
8005       else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8006         {
8007           val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
8008           val[i]->fbit = GET_MODE_FBIT (mode);
8009         }
8010       else
8011         fatal_insn ("unsupported fixed-point conversion", insn);
8012
8013       val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
8014       val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
8015     }
8016
8017   // Byte offset of the decimal point taking into account different place
8018   // of the decimal point in input and output and different register numbers
8019   // of input and output.
8020   int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
8021
8022   // Number of destination bytes that will come from sign / zero extension.
8023   int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
8024
8025   // Number of bytes at the low end to be filled with zeros.
8026   int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
8027
8028   // Do we have a 16-Bit register that is cleared?
8029   rtx clrw = NULL_RTX;
8030
8031   bool sign_extend = src.sbit && sign_bytes;
8032
8033   if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
8034     shift = ASHIFT;
8035   else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
8036     shift = ASHIFTRT;
8037   else if (dest.fbit % 8 == src.fbit % 8)
8038     shift = UNKNOWN;
8039   else
8040     gcc_unreachable();
8041
8042   /* If we need to round the fraction part, we might need to save/round it
8043      before clobbering any of it in Step 1.  Also, we might want to do
8044      the rounding now to make use of LD_REGS.  */
8045   if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8046       && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8047       && !TARGET_FRACT_CONV_TRUNC)
8048     {
8049       bool overlap
8050         = (src.regno <=
8051            (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
8052            && dest.regno - offset -1 >= dest.regno);
8053       unsigned s0 = dest.regno - offset -1;
8054       bool use_src = true;
8055       unsigned sn;
8056       unsigned copied_msb = src.regno_msb;
8057       bool have_carry = false;
8058
8059       if (src.ibyte > dest.ibyte)
8060         copied_msb -= src.ibyte - dest.ibyte;
8061
8062       for (sn = s0; sn <= copied_msb; sn++)
8063         if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
8064             && !reg_unused_after (insn, all_regs_rtx[sn]))
8065           use_src = false;
8066       if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
8067         {
8068           avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8069                        &all_regs_rtx[src.regno_msb], plen, 2);
8070           sn = src.regno;
8071           if (sn < s0)
8072             {
8073               if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
8074                 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
8075               else
8076                 avr_asm_len ("sec" CR_TAB
8077                              "cpc %0,__zero_reg__",
8078                              &all_regs_rtx[sn], plen, 2);
8079               have_carry = true;
8080             }
8081           while (++sn < s0)
8082             avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8083
8084           avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
8085                        &all_regs_rtx[s0], plen, 1);
8086           for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8087             avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
8088           avr_asm_len ("\n0:", NULL, plen, 0);
8089           frac_rounded = true;
8090         }
8091       else if (use_src && overlap)
8092         {
8093           avr_asm_len ("clr __tmp_reg__" CR_TAB
8094                        "sbrc %1,0"       CR_TAB
8095                        "dec __tmp_reg__", xop, plen, 1);
8096           sn = src.regno;
8097           if (sn < s0)
8098             {
8099               avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8100               have_carry = true;
8101             }
8102
8103           while (++sn < s0)
8104             avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8105
8106           if (have_carry)
8107             avr_asm_len ("clt"                CR_TAB
8108                          "bld __tmp_reg__,7"  CR_TAB
8109                          "adc %0,__tmp_reg__",
8110                          &all_regs_rtx[s0], plen, 1);
8111           else
8112             avr_asm_len ("lsr __tmp_reg" CR_TAB
8113                          "add %0,__tmp_reg__",
8114                          &all_regs_rtx[s0], plen, 2);
8115           for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8116             avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8117           frac_rounded = true;
8118         }
8119       else if (overlap)
8120         {
8121           bool use_src
8122             = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
8123                && (IN_RANGE (s0, dest.regno, dest.regno_msb)
8124                    || reg_unused_after (insn, all_regs_rtx[s0])));
8125           xop[2] = all_regs_rtx[s0];
8126           unsigned sn = src.regno;
8127           if (!use_src || sn == s0)
8128             avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8129           /* We need to consider to-be-discarded bits
8130              if the value is negative.  */
8131           if (sn < s0)
8132             {
8133               avr_asm_len ("tst %0" CR_TAB
8134                            "brpl 0f",
8135                            &all_regs_rtx[src.regno_msb], plen, 2);
8136               /* Test to-be-discarded bytes for any nozero bits.
8137                  ??? Could use OR or SBIW to test two registers at once.  */
8138               if (sn < s0)
8139                 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8140
8141               while (++sn < s0)
8142                 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8143               /* Set bit 0 in __tmp_reg__ if any of the lower bits was set.  */
8144               if (use_src)
8145                 avr_asm_len ("breq 0f" CR_TAB
8146                              "ori %2,1"
8147                              "\n0:\t" "mov __tmp_reg__,%2",
8148                              xop, plen, 3);
8149               else
8150                 avr_asm_len ("breq 0f" CR_TAB
8151                              "set"     CR_TAB
8152                              "bld __tmp_reg__,0\n0:",
8153                              xop, plen, 3);
8154             }
8155           lsb_in_tmp_reg = true;
8156         }
8157     }
8158
8159   /* Step 1:  Clear bytes at the low end and copy payload bits from source
8160      ======   to destination.  */
8161
8162   int step = offset < 0 ? 1 : -1;
8163   unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
8164
8165   // We cleared at least that number of registers.
8166   int clr_n = 0;
8167
8168   for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
8169     {
8170       // Next regno of destination is needed for MOVW
8171       unsigned d1 = d0 + step;
8172
8173       // Current and next regno of source
8174       signed s0 = d0 - offset;
8175       signed s1 = s0 + step;
8176
8177       // Must current resp. next regno be CLRed?  This applies to the low
8178       // bytes of the destination that have no associated source bytes.
8179       bool clr0 = s0 < (signed) src.regno;
8180       bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
8181
8182       // First gather what code to emit (if any) and additional step to
8183       // apply if a MOVW is in use.  xop[2] is destination rtx and xop[3]
8184       // is the source rtx for the current loop iteration.
8185       const char *code = NULL;
8186       int stepw = 0;
8187
8188       if (clr0)
8189         {
8190           if (AVR_HAVE_MOVW && clr1 && clrw)
8191             {
8192               xop[2] = all_regs_rtx[d0 & ~1];
8193               xop[3] = clrw;
8194               code = "movw %2,%3";
8195               stepw = step;
8196             }
8197           else
8198             {
8199               xop[2] = all_regs_rtx[d0];
8200               code = "clr %2";
8201
8202               if (++clr_n >= 2
8203                   && !clrw
8204                   && d0 % 2 == (step > 0))
8205                 {
8206                   clrw = all_regs_rtx[d0 & ~1];
8207                 }
8208             }
8209         }
8210       else if (offset && s0 <= (signed) src.regno_msb)
8211         {
8212           int movw = AVR_HAVE_MOVW && offset % 2 == 0
8213             && d0 % 2 == (offset > 0)
8214             && d1 <= dest.regno_msb && d1 >= dest.regno
8215             && s1 <= (signed) src.regno_msb  && s1 >= (signed) src.regno;
8216
8217           xop[2] = all_regs_rtx[d0 & ~movw];
8218           xop[3] = all_regs_rtx[s0 & ~movw];
8219           code = movw ? "movw %2,%3" : "mov %2,%3";
8220           stepw = step * movw;
8221         }
8222
8223       if (code)
8224         {
8225           if (sign_extend && shift != ASHIFT && !sign_in_carry
8226               && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
8227             {
8228               /* We are going to override the sign bit.  If we sign-extend,
8229                  store the sign in the Carry flag.  This is not needed if
8230                  the destination will be ASHIFT in the remainder because
8231                  the ASHIFT will set Carry without extra instruction.  */
8232
8233               avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
8234               sign_in_carry = true;
8235             }
8236
8237           unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
8238
8239           if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8240               && src.ibyte > dest.ibyte
8241               && (d0 == src_msb || d0 + stepw == src_msb))
8242             {
8243               /* We are going to override the MSB.  If we shift right,
8244                  store the MSB in the Carry flag.  This is only needed if
8245                  we don't sign-extend becaue with sign-extension the MSB
8246                  (the sign) will be produced by the sign extension.  */
8247
8248               avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
8249               msb_in_carry = true;
8250             }
8251
8252           unsigned src_lsb = dest.regno - offset -1;
8253
8254           if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
8255               && !lsb_in_tmp_reg
8256               && (d0 == src_lsb || d0 + stepw == src_lsb))
8257             {
8258               /* We are going to override the new LSB; store it into carry.  */
8259
8260               avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
8261               code_ashift = "rol %0";
8262               lsb_in_carry = true;
8263             }
8264
8265           avr_asm_len (code, xop, plen, 1);
8266           d0 += stepw;
8267         }
8268     }
8269
8270   /* Step 2:  Shift destination left by 1 bit position.  This might be needed
8271      ======   for signed input and unsigned output.  */
8272
8273   if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
8274     {
8275       unsigned s0 = dest.regno - offset -1;
8276
8277       /* n1169 4.1.4 says:
8278          "Conversions from a fixed-point to an integer type round toward zero."
8279          Hence, converting a fract type to integer only gives a non-zero result
8280          for -1.  */
8281       if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8282           && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
8283           && !TARGET_FRACT_CONV_TRUNC)
8284         {
8285           gcc_assert (s0 == src.regno_msb);
8286           /* Check if the input is -1.  We do that by checking if negating
8287              the input causes an integer overflow.  */
8288           unsigned sn = src.regno;
8289           avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8290           while (sn <= s0)
8291             avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8292
8293           /* Overflow goes with set carry.  Clear carry otherwise.  */
8294           avr_asm_len ("brvs 0f" CR_TAB
8295                        "clc\n0:", NULL, plen, 2);
8296         }
8297       /* Likewise, when converting from accumulator types to integer, we
8298          need to round up negative values.  */
8299       else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8300                && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8301                && !TARGET_FRACT_CONV_TRUNC
8302                && !frac_rounded)
8303         {
8304           bool have_carry = false;
8305
8306           xop[2] = all_regs_rtx[s0];
8307           if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
8308             avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8309           avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8310                        &all_regs_rtx[src.regno_msb], plen, 2);
8311           if (!lsb_in_tmp_reg)
8312             {
8313               unsigned sn = src.regno;
8314               if (sn < s0)
8315                 {
8316                   avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
8317                                plen, 1);
8318                   have_carry = true;
8319                 }
8320               while (++sn < s0)
8321                 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
8322               lsb_in_tmp_reg = !MAY_CLOBBER (s0);
8323             }
8324           /* Add in C and the rounding value 127.  */
8325           /* If the destination msb is a sign byte, and in LD_REGS,
8326              grab it as a temporary.  */
8327           if (sign_bytes
8328               && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
8329                                     dest.regno_msb))
8330             {
8331               xop[3] = all_regs_rtx[dest.regno_msb];
8332               avr_asm_len ("ldi %3,127", xop, plen, 1);
8333               avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
8334                            : have_carry ? "adc %2,%3"
8335                            : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
8336                            : "add %2,%3"),
8337                            xop, plen, 1);
8338             }
8339           else
8340             {
8341               /* Fall back to use __zero_reg__ as a temporary.  */
8342               avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
8343               if (have_carry)
8344                 avr_asm_len ("clt" CR_TAB
8345                              "bld __zero_reg__,7", NULL, plen, 2);
8346               else
8347                 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
8348               avr_asm_len (have_carry && lsb_in_tmp_reg
8349                            ? "adc __tmp_reg__,__zero_reg__"
8350                            : have_carry ? "adc %2,__zero_reg__"
8351                            : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
8352                            : "add %2,__zero_reg__",
8353                            xop, plen, 1);
8354               avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
8355             }
8356
8357           for (d0 = dest.regno + zero_bytes;
8358                d0 <= dest.regno_msb - sign_bytes; d0++)
8359             avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
8360
8361           avr_asm_len (lsb_in_tmp_reg
8362                        ? "\n0:\t" "lsl __tmp_reg__"
8363                        : "\n0:\t" "lsl %2",
8364                        xop, plen, 1);
8365         }
8366       else if (MAY_CLOBBER (s0))
8367         avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8368       else
8369         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8370                      "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8371
8372       code_ashift = "rol %0";
8373       lsb_in_carry = true;
8374     }
8375
8376   if (shift == ASHIFT)
8377     {
8378       for (d0 = dest.regno + zero_bytes;
8379            d0 <= dest.regno_msb - sign_bytes; d0++)
8380         {
8381           avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
8382           code_ashift = "rol %0";
8383         }
8384
8385       lsb_in_carry = false;
8386       sign_in_carry = true;
8387     }
8388
8389   /* Step 4a:  Store MSB in carry if we don't already have it or will produce
8390      =======   it in sign-extension below.  */
8391
8392   if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8393       && src.ibyte > dest.ibyte)
8394     {
8395       unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
8396
8397       if (MAY_CLOBBER (s0))
8398         avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
8399       else
8400         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8401                      "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8402
8403       msb_in_carry = true;
8404     }
8405
8406   /* Step 3:  Sign-extend or zero-extend the destination as needed.
8407      ======   */
8408
8409   if (sign_extend && !sign_in_carry)
8410     {
8411       unsigned s0 = src.regno_msb;
8412
8413       if (MAY_CLOBBER (s0))
8414         avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8415       else
8416         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8417                      "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8418
8419       sign_in_carry = true;
8420   }
8421
8422   gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
8423
8424   unsigned copies = 0;
8425   rtx movw = sign_extend ? NULL_RTX : clrw;
8426
8427   for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
8428     {
8429       if (AVR_HAVE_MOVW && movw
8430           && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
8431         {
8432           xop[2] = all_regs_rtx[d0];
8433           xop[3] = movw;
8434           avr_asm_len ("movw %2,%3", xop, plen, 1);
8435           d0++;
8436         }
8437       else
8438         {
8439           avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
8440                        &all_regs_rtx[d0], plen, 1);
8441
8442           if (++copies >= 2 && !movw && d0 % 2 == 1)
8443             movw = all_regs_rtx[d0-1];
8444         }
8445     } /* for */
8446
8447
8448   /* Step 4:  Right shift the destination.  This might be needed for
8449      ======   conversions from unsigned to signed.  */
8450
8451   if (shift == ASHIFTRT)
8452     {
8453       const char *code_ashiftrt = "lsr %0";
8454
8455       if (sign_extend || msb_in_carry)
8456         code_ashiftrt = "ror %0";
8457
8458       if (src.sbit && src.ibyte == dest.ibyte)
8459         code_ashiftrt = "asr %0";
8460
8461       for (d0 = dest.regno_msb - sign_bytes;
8462            d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
8463         {
8464           avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
8465           code_ashiftrt = "ror %0";
8466         }
8467     }
8468
8469 #undef MAY_CLOBBER
8470
8471   return "";
8472 }
8473
8474
8475 /* Output fixed-point rounding.  XOP[0] = XOP[1] is the operand to round.
8476    XOP[2] is the rounding point, a CONST_INT.  The function prints the
8477    instruction sequence if PLEN = NULL and computes the length in words
8478    of the sequence if PLEN != NULL.  Most of this function deals with
8479    preparing operands for calls to `avr_out_plus' and `avr_out_bitop'.  */
8480
8481 const char*
8482 avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
8483 {
8484   machine_mode mode = GET_MODE (xop[0]);
8485   machine_mode imode = int_mode_for_mode (mode);
8486   // The smallest fractional bit not cleared by the rounding is 2^(-RP).
8487   int fbit = (int) GET_MODE_FBIT (mode);
8488   double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
8489   wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
8490                                          GET_MODE_PRECISION (imode));
8491   // Lengths of PLUS and AND parts.
8492   int len_add = 0, *plen_add = plen ? &len_add : NULL;
8493   int len_and = 0, *plen_and = plen ? &len_and : NULL;
8494
8495   // Add-Saturate  1/2 * 2^(-RP).  Don't print the label "0:" when printing
8496   // the saturated addition so that we can emit the "rjmp 1f" before the
8497   // "0:" below.
8498
8499   rtx xadd = const_fixed_from_double_int (i_add, mode);
8500   rtx xpattern, xsrc, op[4];
8501
8502   xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
8503     ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
8504     : gen_rtx_US_PLUS (mode, xop[1], xadd);
8505   xpattern = gen_rtx_SET (xop[0], xsrc);
8506
8507   op[0] = xop[0];
8508   op[1] = xop[1];
8509   op[2] = xadd;
8510   avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
8511
8512   avr_asm_len ("rjmp 1f" CR_TAB
8513                "0:", NULL, plen_add, 1);
8514
8515   // Keep  all bits from RP and higher:   ... 2^(-RP)
8516   // Clear all bits from RP+1 and lower:              2^(-RP-1) ...
8517   // Rounding point                           ^^^^^^^
8518   // Added above                                      ^^^^^^^^^
8519   rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
8520   rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
8521
8522   xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
8523
8524   op[0] = xreg;
8525   op[1] = xreg;
8526   op[2] = xmask;
8527   op[3] = gen_rtx_SCRATCH (QImode);
8528   avr_out_bitop (xpattern, op, plen_and);
8529   avr_asm_len ("1:", NULL, plen, 0);
8530
8531   if (plen)
8532     *plen = len_add + len_and;
8533
8534   return "";
8535 }
8536
8537
8538 /* Create RTL split patterns for byte sized rotate expressions.  This
8539   produces a series of move instructions and considers overlap situations.
8540   Overlapping non-HImode operands need a scratch register.  */
8541
8542 bool
8543 avr_rotate_bytes (rtx operands[])
8544 {
8545     int i, j;
8546     machine_mode mode = GET_MODE (operands[0]);
8547     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
8548     bool same_reg = rtx_equal_p (operands[0], operands[1]);
8549     int num = INTVAL (operands[2]);
8550     rtx scratch = operands[3];
8551     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
8552        Word move if no scratch is needed, otherwise use size of scratch.  */
8553     machine_mode move_mode = QImode;
8554     int move_size, offset, size;
8555
8556     if (num & 0xf)
8557       move_mode = QImode;
8558     else if ((mode == SImode && !same_reg) || !overlapped)
8559       move_mode = HImode;
8560     else
8561       move_mode = GET_MODE (scratch);
8562
8563     /* Force DI rotate to use QI moves since other DI moves are currently split
8564        into QI moves so forward propagation works better.  */
8565     if (mode == DImode)
8566       move_mode = QImode;
8567     /* Make scratch smaller if needed.  */
8568     if (SCRATCH != GET_CODE (scratch)
8569         && HImode == GET_MODE (scratch)
8570         && QImode == move_mode)
8571       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
8572
8573     move_size = GET_MODE_SIZE (move_mode);
8574     /* Number of bytes/words to rotate.  */
8575     offset = (num  >> 3) / move_size;
8576     /* Number of moves needed.  */
8577     size = GET_MODE_SIZE (mode) / move_size;
8578     /* Himode byte swap is special case to avoid a scratch register.  */
8579     if (mode == HImode && same_reg)
8580       {
8581         /* HImode byte swap, using xor.  This is as quick as using scratch.  */
8582         rtx src, dst;
8583         src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
8584         dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
8585         if (!rtx_equal_p (dst, src))
8586           {
8587              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8588              emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
8589              emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8590           }
8591       }
8592     else
8593       {
8594 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
8595         /* Create linked list of moves to determine move order.  */
8596         struct {
8597           rtx src, dst;
8598           int links;
8599         } move[MAX_SIZE + 8];
8600         int blocked, moves;
8601
8602         gcc_assert (size <= MAX_SIZE);
8603         /* Generate list of subreg moves.  */
8604         for (i = 0; i < size; i++)
8605           {
8606             int from = i;
8607             int to = (from + offset) % size;
8608             move[i].src = simplify_gen_subreg (move_mode, operands[1],
8609                                                mode, from * move_size);
8610             move[i].dst = simplify_gen_subreg (move_mode, operands[0],
8611                                                mode, to * move_size);
8612             move[i].links = -1;
8613           }
8614         /* Mark dependence where a dst of one move is the src of another move.
8615            The first move is a conflict as it must wait until second is
8616            performed.  We ignore moves to self - we catch this later.  */
8617         if (overlapped)
8618           for (i = 0; i < size; i++)
8619             if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
8620               for (j = 0; j < size; j++)
8621                 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
8622                   {
8623                     /* The dst of move i is the src of move j.  */
8624                     move[i].links = j;
8625                     break;
8626                   }
8627
8628         blocked = -1;
8629         moves = 0;
8630         /* Go through move list and perform non-conflicting moves.  As each
8631            non-overlapping move is made, it may remove other conflicts
8632            so the process is repeated until no conflicts remain.  */
8633         do
8634           {
8635             blocked = -1;
8636             moves = 0;
8637             /* Emit move where dst is not also a src or we have used that
8638                src already.  */
8639             for (i = 0; i < size; i++)
8640               if (move[i].src != NULL_RTX)
8641                 {
8642                   if (move[i].links == -1
8643                       || move[move[i].links].src == NULL_RTX)
8644                     {
8645                       moves++;
8646                       /* Ignore NOP moves to self.  */
8647                       if (!rtx_equal_p (move[i].dst, move[i].src))
8648                         emit_move_insn (move[i].dst, move[i].src);
8649
8650                       /* Remove  conflict from list.  */
8651                       move[i].src = NULL_RTX;
8652                     }
8653                   else
8654                     blocked = i;
8655                 }
8656
8657             /* Check for deadlock. This is when no moves occurred and we have
8658                at least one blocked move.  */
8659             if (moves == 0 && blocked != -1)
8660               {
8661                 /* Need to use scratch register to break deadlock.
8662                    Add move to put dst of blocked move into scratch.
8663                    When this move occurs, it will break chain deadlock.
8664                    The scratch register is substituted for real move.  */
8665
8666                 gcc_assert (SCRATCH != GET_CODE (scratch));
8667
8668                 move[size].src = move[blocked].dst;
8669                 move[size].dst =  scratch;
8670                 /* Scratch move is never blocked.  */
8671                 move[size].links = -1;
8672                 /* Make sure we have valid link.  */
8673                 gcc_assert (move[blocked].links != -1);
8674                 /* Replace src of  blocking move with scratch reg.  */
8675                 move[move[blocked].links].src = scratch;
8676                 /* Make dependent on scratch move occurring.  */
8677                 move[blocked].links = size;
8678                 size=size+1;
8679               }
8680           }
8681         while (blocked != -1);
8682       }
8683     return true;
8684 }
8685
8686
8687 /* Worker function for `ADJUST_INSN_LENGTH'.  */
8688 /* Modifies the length assigned to instruction INSN
8689    LEN is the initially computed length of the insn.  */
8690
8691 int
8692 avr_adjust_insn_length (rtx_insn *insn, int len)
8693 {
8694   rtx *op = recog_data.operand;
8695   enum attr_adjust_len adjust_len;
8696
8697   /* Some complex insns don't need length adjustment and therefore
8698      the length need not/must not be adjusted for these insns.
8699      It is easier to state this in an insn attribute "adjust_len" than
8700      to clutter up code here...  */
8701
8702   if (!NONDEBUG_INSN_P (insn)
8703       || -1 == recog_memoized (insn))
8704     {
8705       return len;
8706     }
8707
8708   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
8709
8710   adjust_len = get_attr_adjust_len (insn);
8711
8712   if (adjust_len == ADJUST_LEN_NO)
8713     {
8714       /* Nothing to adjust: The length from attribute "length" is fine.
8715          This is the default.  */
8716
8717       return len;
8718     }
8719
8720   /* Extract insn's operands.  */
8721
8722   extract_constrain_insn_cached (insn);
8723
8724   /* Dispatch to right function.  */
8725
8726   switch (adjust_len)
8727     {
8728     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
8729     case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
8730     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
8731
8732     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
8733
8734     case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
8735     case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
8736
8737     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
8738     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
8739     case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
8740     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
8741     case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
8742     case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
8743     case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
8744     case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
8745
8746     case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
8747     case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
8748     case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
8749
8750     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
8751     case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
8752     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
8753     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
8754     case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
8755
8756     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
8757     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
8758     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
8759
8760     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
8761     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
8762     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
8763
8764     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
8765     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
8766     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
8767
8768     case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
8769     case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
8770     case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
8771
8772     case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
8773
8774     case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
8775
8776     default:
8777       gcc_unreachable();
8778     }
8779
8780   return len;
8781 }
8782
8783 /* Return nonzero if register REG dead after INSN.  */
8784
8785 int
8786 reg_unused_after (rtx_insn *insn, rtx reg)
8787 {
8788   return (dead_or_set_p (insn, reg)
8789           || (REG_P(reg) && _reg_unused_after (insn, reg)));
8790 }
8791
8792 /* Return nonzero if REG is not used after INSN.
8793    We assume REG is a reload reg, and therefore does
8794    not live past labels.  It may live past calls or jumps though.  */
8795
8796 int
8797 _reg_unused_after (rtx_insn *insn, rtx reg)
8798 {
8799   enum rtx_code code;
8800   rtx set;
8801
8802   /* If the reg is set by this instruction, then it is safe for our
8803      case.  Disregard the case where this is a store to memory, since
8804      we are checking a register used in the store address.  */
8805   set = single_set (insn);
8806   if (set && GET_CODE (SET_DEST (set)) != MEM
8807       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8808     return 1;
8809
8810   while ((insn = NEXT_INSN (insn)))
8811     {
8812       rtx set;
8813       code = GET_CODE (insn);
8814
8815 #if 0
8816       /* If this is a label that existed before reload, then the register
8817          if dead here.  However, if this is a label added by reorg, then
8818          the register may still be live here.  We can't tell the difference,
8819          so we just ignore labels completely.  */
8820       if (code == CODE_LABEL)
8821         return 1;
8822       /* else */
8823 #endif
8824
8825       if (!INSN_P (insn))
8826         continue;
8827
8828       if (code == JUMP_INSN)
8829         return 0;
8830
8831       /* If this is a sequence, we must handle them all at once.
8832          We could have for instance a call that sets the target register,
8833          and an insn in a delay slot that uses the register.  In this case,
8834          we must return 0.  */
8835       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
8836         {
8837           rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
8838           int i;
8839           int retval = 0;
8840
8841           for (i = 0; i < seq->len (); i++)
8842             {
8843               rtx_insn *this_insn = seq->insn (i);
8844               rtx set = single_set (this_insn);
8845
8846               if (CALL_P (this_insn))
8847                 code = CALL_INSN;
8848               else if (JUMP_P (this_insn))
8849                 {
8850                   if (INSN_ANNULLED_BRANCH_P (this_insn))
8851                     return 0;
8852                   code = JUMP_INSN;
8853                 }
8854
8855               if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8856                 return 0;
8857               if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8858                 {
8859                   if (GET_CODE (SET_DEST (set)) != MEM)
8860                     retval = 1;
8861                   else
8862                     return 0;
8863                 }
8864               if (set == 0
8865                   && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
8866                 return 0;
8867             }
8868           if (retval == 1)
8869             return 1;
8870           else if (code == JUMP_INSN)
8871             return 0;
8872         }
8873
8874       if (code == CALL_INSN)
8875         {
8876           rtx tem;
8877           for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
8878             if (GET_CODE (XEXP (tem, 0)) == USE
8879                 && REG_P (XEXP (XEXP (tem, 0), 0))
8880                 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
8881               return 0;
8882           if (call_used_regs[REGNO (reg)])
8883             return 1;
8884         }
8885
8886       set = single_set (insn);
8887
8888       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8889         return 0;
8890       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8891         return GET_CODE (SET_DEST (set)) != MEM;
8892       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
8893         return 0;
8894     }
8895   return 1;
8896 }
8897
8898
8899 /* Implement `TARGET_ASM_INTEGER'.  */
8900 /* Target hook for assembling integer objects.  The AVR version needs
8901    special handling for references to certain labels.  */
8902
8903 static bool
8904 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
8905 {
8906   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
8907       && text_segment_operand (x, VOIDmode))
8908     {
8909       fputs ("\t.word\tgs(", asm_out_file);
8910       output_addr_const (asm_out_file, x);
8911       fputs (")\n", asm_out_file);
8912
8913       return true;
8914     }
8915   else if (GET_MODE (x) == PSImode)
8916     {
8917       /* This needs binutils 2.23+, see PR binutils/13503  */
8918
8919       fputs ("\t.byte\tlo8(", asm_out_file);
8920       output_addr_const (asm_out_file, x);
8921       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8922
8923       fputs ("\t.byte\thi8(", asm_out_file);
8924       output_addr_const (asm_out_file, x);
8925       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8926
8927       fputs ("\t.byte\thh8(", asm_out_file);
8928       output_addr_const (asm_out_file, x);
8929       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8930
8931       return true;
8932     }
8933   else if (CONST_FIXED_P (x))
8934     {
8935       unsigned n;
8936
8937       /* varasm fails to handle big fixed modes that don't fit in hwi.  */
8938
8939       for (n = 0; n < size; n++)
8940         {
8941           rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
8942           default_assemble_integer (xn, 1, aligned_p);
8943         }
8944
8945       return true;
8946     }
8947
8948   return default_assemble_integer (x, size, aligned_p);
8949 }
8950
8951
8952 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'.  */
8953 /* Return value is nonzero if pseudos that have been
8954    assigned to registers of class CLASS would likely be spilled
8955    because registers of CLASS are needed for spill registers.  */
8956
8957 static bool
8958 avr_class_likely_spilled_p (reg_class_t c)
8959 {
8960   return (c != ALL_REGS &&
8961            (AVR_TINY ? 1 : c != ADDW_REGS));
8962 }
8963
8964
8965 /* Valid attributes:
8966    progmem   -  Put data to program memory.
8967    signal    -  Make a function to be hardware interrupt.
8968                 After function prologue interrupts remain disabled.
8969    interrupt -  Make a function to be hardware interrupt. Before function
8970                 prologue interrupts are enabled by means of SEI.
8971    naked     -  Don't generate function prologue/epilogue and RET
8972                 instruction.  */
8973
8974 /* Handle a "progmem" attribute; arguments as in
8975    struct attribute_spec.handler.  */
8976
8977 static tree
8978 avr_handle_progmem_attribute (tree *node, tree name,
8979                               tree args ATTRIBUTE_UNUSED,
8980                               int flags ATTRIBUTE_UNUSED,
8981                               bool *no_add_attrs)
8982 {
8983   if (DECL_P (*node))
8984     {
8985       if (TREE_CODE (*node) == TYPE_DECL)
8986         {
8987           /* This is really a decl attribute, not a type attribute,
8988              but try to handle it for GCC 3.0 backwards compatibility.  */
8989
8990           tree type = TREE_TYPE (*node);
8991           tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
8992           tree newtype = build_type_attribute_variant (type, attr);
8993
8994           TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
8995           TREE_TYPE (*node) = newtype;
8996           *no_add_attrs = true;
8997         }
8998       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
8999         {
9000           *no_add_attrs = false;
9001         }
9002       else
9003         {
9004           warning (OPT_Wattributes, "%qE attribute ignored",
9005                    name);
9006           *no_add_attrs = true;
9007         }
9008     }
9009
9010   return NULL_TREE;
9011 }
9012
9013 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
9014    struct attribute_spec.handler.  */
9015
9016 static tree
9017 avr_handle_fndecl_attribute (tree *node, tree name,
9018                              tree args ATTRIBUTE_UNUSED,
9019                              int flags ATTRIBUTE_UNUSED,
9020                              bool *no_add_attrs)
9021 {
9022   if (TREE_CODE (*node) != FUNCTION_DECL)
9023     {
9024       warning (OPT_Wattributes, "%qE attribute only applies to functions",
9025                name);
9026       *no_add_attrs = true;
9027     }
9028
9029   return NULL_TREE;
9030 }
9031
9032 static tree
9033 avr_handle_fntype_attribute (tree *node, tree name,
9034                              tree args ATTRIBUTE_UNUSED,
9035                              int flags ATTRIBUTE_UNUSED,
9036                              bool *no_add_attrs)
9037 {
9038   if (TREE_CODE (*node) != FUNCTION_TYPE)
9039     {
9040       warning (OPT_Wattributes, "%qE attribute only applies to functions",
9041                name);
9042       *no_add_attrs = true;
9043     }
9044
9045   return NULL_TREE;
9046 }
9047
9048 static tree
9049 avr_handle_addr_attribute (tree *node, tree name, tree args,
9050                            int flags ATTRIBUTE_UNUSED, bool *no_add)
9051 {
9052   bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0);
9053   location_t loc = DECL_SOURCE_LOCATION (*node);
9054
9055   if (TREE_CODE (*node) != VAR_DECL)
9056     {
9057       warning_at (loc, 0, "%qE attribute only applies to variables", name);
9058       *no_add = true;
9059     }
9060
9061   if (args != NULL_TREE)
9062     {
9063       if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
9064         TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
9065       tree arg = TREE_VALUE (args);
9066       if (TREE_CODE (arg) != INTEGER_CST)
9067         {
9068           warning (0, "%qE attribute allows only an integer constant argument",
9069                    name);
9070           *no_add = true;
9071         }
9072       else if (io_p
9073                && (!tree_fits_shwi_p (arg)
9074                    || !(strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
9075                         ? low_io_address_operand : io_address_operand)
9076                          (GEN_INT (TREE_INT_CST_LOW (arg)), QImode)))
9077         {
9078           warning_at (loc, 0, "%qE attribute address out of range", name);
9079           *no_add = true;
9080         }
9081       else
9082         {
9083           tree attribs = DECL_ATTRIBUTES (*node);
9084           const char *names[] = { "io", "io_low", "address", NULL } ;
9085           for (const char **p = names; *p; p++)
9086             {
9087               tree other = lookup_attribute (*p, attribs);
9088               if (other && TREE_VALUE (other))
9089                 {
9090                   warning_at (loc, 0,
9091                               "both %s and %qE attribute provide address",
9092                               *p, name);
9093                   *no_add = true;
9094                   break;
9095                 }
9096             }
9097         }
9098     }
9099
9100   if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
9101     warning_at (loc, 0, "%qE attribute on non-volatile variable", name);
9102
9103   return NULL_TREE;
9104 }
9105
9106 rtx
9107 avr_eval_addr_attrib (rtx x)
9108 {
9109   if (GET_CODE (x) == SYMBOL_REF
9110       && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
9111     {
9112       tree decl = SYMBOL_REF_DECL (x);
9113       tree attr = NULL_TREE;
9114
9115       if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
9116         {
9117           attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
9118          if (!attr || !TREE_VALUE (attr))
9119            attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
9120           gcc_assert (attr);
9121         }
9122       if (!attr || !TREE_VALUE (attr))
9123         attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
9124       gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
9125       return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
9126     }
9127   return x;
9128 }
9129
9130
9131 /* AVR attributes.  */
9132 static const struct attribute_spec
9133 avr_attribute_table[] =
9134 {
9135   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
9136        affects_type_identity } */
9137   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
9138     false },
9139   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
9140     false },
9141   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
9142     false },
9143   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
9144     false },
9145   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
9146     false },
9147   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
9148     false },
9149   { "io",        0, 1, false, false, false,  avr_handle_addr_attribute,
9150     false },
9151   { "io_low",    0, 1, false, false, false,  avr_handle_addr_attribute,
9152     false },
9153   { "address",   1, 1, false, false, false,  avr_handle_addr_attribute,
9154     false },
9155   { NULL,        0, 0, false, false, false, NULL, false }
9156 };
9157
9158
9159 /* Look if DECL shall be placed in program memory space by
9160    means of attribute `progmem' or some address-space qualifier.
9161    Return non-zero if DECL is data that must end up in Flash and
9162    zero if the data lives in RAM (.bss, .data, .rodata, ...).
9163
9164    Return 2   if DECL is located in 24-bit flash address-space
9165    Return 1   if DECL is located in 16-bit flash address-space
9166    Return -1  if attribute `progmem' occurs in DECL or ATTRIBUTES
9167    Return 0   otherwise  */
9168
9169 int
9170 avr_progmem_p (tree decl, tree attributes)
9171 {
9172   tree a;
9173
9174   if (TREE_CODE (decl) != VAR_DECL)
9175     return 0;
9176
9177   if (avr_decl_memx_p (decl))
9178     return 2;
9179
9180   if (avr_decl_flash_p (decl))
9181     return 1;
9182
9183   if (NULL_TREE
9184       != lookup_attribute ("progmem", attributes))
9185     return -1;
9186
9187   a = decl;
9188
9189   do
9190     a = TREE_TYPE(a);
9191   while (TREE_CODE (a) == ARRAY_TYPE);
9192
9193   if (a == error_mark_node)
9194     return 0;
9195
9196   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
9197     return -1;
9198
9199   return 0;
9200 }
9201
9202
9203 /* Scan type TYP for pointer references to address space ASn.
9204    Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
9205    the AS are also declared to be CONST.
9206    Otherwise, return the respective address space, i.e. a value != 0.  */
9207
9208 static addr_space_t
9209 avr_nonconst_pointer_addrspace (tree typ)
9210 {
9211   while (ARRAY_TYPE == TREE_CODE (typ))
9212     typ = TREE_TYPE (typ);
9213
9214   if (POINTER_TYPE_P (typ))
9215     {
9216       addr_space_t as;
9217       tree target = TREE_TYPE (typ);
9218
9219       /* Pointer to function: Test the function's return type.  */
9220
9221       if (FUNCTION_TYPE == TREE_CODE (target))
9222         return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
9223
9224       /* "Ordinary" pointers... */
9225
9226       while (TREE_CODE (target) == ARRAY_TYPE)
9227         target = TREE_TYPE (target);
9228
9229       /* Pointers to non-generic address space must be const.
9230          Refuse address spaces outside the device's flash.  */
9231
9232       as = TYPE_ADDR_SPACE (target);
9233
9234       if (!ADDR_SPACE_GENERIC_P (as)
9235           && (!TYPE_READONLY (target)
9236               || avr_addrspace[as].segment >= avr_n_flash
9237               /* Also refuse __memx address space if we can't support it.  */
9238               || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
9239         {
9240           return as;
9241         }
9242
9243       /* Scan pointer's target type.  */
9244
9245       return avr_nonconst_pointer_addrspace (target);
9246     }
9247
9248   return ADDR_SPACE_GENERIC;
9249 }
9250
9251
9252 /* Sanity check NODE so that all pointers targeting non-generic address spaces
9253    go along with CONST qualifier.  Writing to these address spaces should
9254    be detected and complained about as early as possible.  */
9255
9256 static bool
9257 avr_pgm_check_var_decl (tree node)
9258 {
9259   const char *reason = NULL;
9260
9261   addr_space_t as = ADDR_SPACE_GENERIC;
9262
9263   gcc_assert (as == 0);
9264
9265   if (avr_log.progmem)
9266     avr_edump ("%?: %t\n", node);
9267
9268   switch (TREE_CODE (node))
9269     {
9270     default:
9271       break;
9272
9273     case VAR_DECL:
9274       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9275         reason = "variable";
9276       break;
9277
9278     case PARM_DECL:
9279       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9280         reason = "function parameter";
9281       break;
9282
9283     case FIELD_DECL:
9284       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9285         reason = "structure field";
9286       break;
9287
9288     case FUNCTION_DECL:
9289       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
9290           as)
9291         reason = "return type of function";
9292       break;
9293
9294     case POINTER_TYPE:
9295       if (as = avr_nonconst_pointer_addrspace (node), as)
9296         reason = "pointer";
9297       break;
9298     }
9299
9300   if (reason)
9301     {
9302       if (avr_addrspace[as].segment >= avr_n_flash)
9303         {
9304           if (TYPE_P (node))
9305             error ("%qT uses address space %qs beyond flash of %d KiB",
9306                    node, avr_addrspace[as].name, 64 * avr_n_flash);
9307           else
9308             error ("%s %q+D uses address space %qs beyond flash of %d KiB",
9309                    reason, node, avr_addrspace[as].name, 64 * avr_n_flash);
9310         }
9311       else
9312         {
9313           if (TYPE_P (node))
9314             error ("pointer targeting address space %qs must be const in %qT",
9315                    avr_addrspace[as].name, node);
9316           else
9317             error ("pointer targeting address space %qs must be const"
9318                    " in %s %q+D",
9319                    avr_addrspace[as].name, reason, node);
9320         }
9321     }
9322
9323   return reason == NULL;
9324 }
9325
9326
9327 /* Add the section attribute if the variable is in progmem.  */
9328
9329 static void
9330 avr_insert_attributes (tree node, tree *attributes)
9331 {
9332   avr_pgm_check_var_decl (node);
9333
9334   if (TREE_CODE (node) == VAR_DECL
9335       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
9336       && avr_progmem_p (node, *attributes))
9337     {
9338       addr_space_t as;
9339       tree node0 = node;
9340
9341       /* For C++, we have to peel arrays in order to get correct
9342          determination of readonlyness.  */
9343
9344       do
9345         node0 = TREE_TYPE (node0);
9346       while (TREE_CODE (node0) == ARRAY_TYPE);
9347
9348       if (error_mark_node == node0)
9349         return;
9350
9351       as = TYPE_ADDR_SPACE (TREE_TYPE (node));
9352
9353       if (avr_addrspace[as].segment >= avr_n_flash)
9354         {
9355           error ("variable %q+D located in address space %qs beyond flash "
9356                  "of %d KiB", node, avr_addrspace[as].name, 64 * avr_n_flash);
9357         }
9358       else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
9359         {
9360           error ("variable %q+D located in address space %qs"
9361                  " which is not supported for architecture %qs",
9362                  node, avr_addrspace[as].name, avr_arch->name);
9363         }
9364
9365       if (!TYPE_READONLY (node0)
9366           && !TREE_READONLY (node))
9367         {
9368           const char *reason = "__attribute__((progmem))";
9369
9370           if (!ADDR_SPACE_GENERIC_P (as))
9371             reason = avr_addrspace[as].name;
9372
9373           if (avr_log.progmem)
9374             avr_edump ("\n%?: %t\n%t\n", node, node0);
9375
9376           error ("variable %q+D must be const in order to be put into"
9377                  " read-only section by means of %qs", node, reason);
9378         }
9379     }
9380 }
9381
9382
9383 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
9384 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
9385 /* Track need of __do_clear_bss.  */
9386
9387 void
9388 avr_asm_output_aligned_decl_common (FILE * stream,
9389                                     tree decl,
9390                                     const char *name,
9391                                     unsigned HOST_WIDE_INT size,
9392                                     unsigned int align, bool local_p)
9393 {
9394   rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9395   rtx symbol;
9396
9397   if (mem != NULL_RTX && MEM_P (mem)
9398       && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9399       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9400     {
9401
9402       if (!local_p)
9403         {
9404           fprintf (stream, "\t.globl\t");
9405           assemble_name (stream, name);
9406           fprintf (stream, "\n");
9407         }
9408       if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
9409         {
9410           assemble_name (stream, name);
9411           fprintf (stream, " = %ld\n",
9412                    (long) INTVAL (avr_eval_addr_attrib (symbol)));
9413         }
9414       else if (local_p)
9415         error_at (DECL_SOURCE_LOCATION (decl),
9416                   "static IO declaration for %q+D needs an address", decl);
9417       return;
9418     }
9419
9420   /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
9421      There is no need to trigger __do_clear_bss code for them.  */
9422
9423   if (!STR_PREFIX_P (name, "__gnu_lto"))
9424     avr_need_clear_bss_p = true;
9425
9426   if (local_p)
9427     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
9428   else
9429     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
9430 }
9431
9432 void
9433 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
9434                                 unsigned HOST_WIDE_INT size, int align,
9435                                 void (*default_func)
9436                                   (FILE *, tree, const char *,
9437                                    unsigned HOST_WIDE_INT, int))
9438 {
9439   rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9440   rtx symbol;
9441
9442   if (mem != NULL_RTX && MEM_P (mem)
9443       && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9444       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9445     {
9446       if (!(SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS))
9447         error_at (DECL_SOURCE_LOCATION (decl),
9448                   "IO definition for %q+D needs an address", decl);
9449       avr_asm_output_aligned_decl_common (file, decl, name, size, align, false);
9450     }
9451   else
9452     default_func (file, decl, name, size, align);
9453 }
9454
9455
9456 /* Unnamed section callback for data_section
9457    to track need of __do_copy_data.  */
9458
9459 static void
9460 avr_output_data_section_asm_op (const void *data)
9461 {
9462   avr_need_copy_data_p = true;
9463
9464   /* Dispatch to default.  */
9465   output_section_asm_op (data);
9466 }
9467
9468
9469 /* Unnamed section callback for bss_section
9470    to track need of __do_clear_bss.  */
9471
9472 static void
9473 avr_output_bss_section_asm_op (const void *data)
9474 {
9475   avr_need_clear_bss_p = true;
9476
9477   /* Dispatch to default.  */
9478   output_section_asm_op (data);
9479 }
9480
9481
9482 /* Unnamed section callback for progmem*.data sections.  */
9483
9484 static void
9485 avr_output_progmem_section_asm_op (const void *data)
9486 {
9487   fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
9488            (const char*) data);
9489 }
9490
9491
9492 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
9493
9494 static void
9495 avr_asm_init_sections (void)
9496 {
9497   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
9498      resp. `avr_need_copy_data_p'.  */
9499
9500   readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
9501   data_section->unnamed.callback = avr_output_data_section_asm_op;
9502   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
9503 }
9504
9505
9506 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
9507 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
9508
9509 static void
9510 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
9511 {
9512   if (flags & AVR_SECTION_PROGMEM)
9513     {
9514       addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
9515       const char *old_prefix = ".rodata";
9516       const char *new_prefix = avr_addrspace[as].section_name;
9517
9518       if (STR_PREFIX_P (name, old_prefix))
9519         {
9520           const char *sname = ACONCAT ((new_prefix,
9521                                         name + strlen (old_prefix), NULL));
9522           default_elf_asm_named_section (sname, flags, decl);
9523           return;
9524         }
9525
9526       default_elf_asm_named_section (new_prefix, flags, decl);
9527       return;
9528     }
9529
9530   if (!avr_need_copy_data_p)
9531     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
9532                             || STR_PREFIX_P (name, ".rodata")
9533                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
9534
9535   if (!avr_need_clear_bss_p)
9536     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
9537
9538   default_elf_asm_named_section (name, flags, decl);
9539 }
9540
9541
9542 /* Implement `TARGET_SECTION_TYPE_FLAGS'.  */
9543
9544 static unsigned int
9545 avr_section_type_flags (tree decl, const char *name, int reloc)
9546 {
9547   unsigned int flags = default_section_type_flags (decl, name, reloc);
9548
9549   if (STR_PREFIX_P (name, ".noinit"))
9550     {
9551       if (decl && TREE_CODE (decl) == VAR_DECL
9552           && DECL_INITIAL (decl) == NULL_TREE)
9553         flags |= SECTION_BSS;  /* @nobits */
9554       else
9555         warning (0, "only uninitialized variables can be placed in the "
9556                  ".noinit section");
9557     }
9558
9559   if (decl && DECL_P (decl)
9560       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9561     {
9562       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9563
9564       /* Attribute progmem puts data in generic address space.
9565          Set section flags as if it was in __flash to get the right
9566          section prefix in the remainder.  */
9567
9568       if (ADDR_SPACE_GENERIC_P (as))
9569         as = ADDR_SPACE_FLASH;
9570
9571       flags |= as * SECTION_MACH_DEP;
9572       flags &= ~SECTION_WRITE;
9573       flags &= ~SECTION_BSS;
9574     }
9575
9576   return flags;
9577 }
9578
9579
9580 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
9581
9582 static void
9583 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
9584 {
9585   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
9586      readily available, see PR34734.  So we postpone the warning
9587      about uninitialized data in program memory section until here.  */
9588
9589   if (new_decl_p
9590       && decl && DECL_P (decl)
9591       && NULL_TREE == DECL_INITIAL (decl)
9592       && !DECL_EXTERNAL (decl)
9593       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9594     {
9595       warning (OPT_Wuninitialized,
9596                "uninitialized variable %q+D put into "
9597                "program memory area", decl);
9598     }
9599
9600   default_encode_section_info (decl, rtl, new_decl_p);
9601
9602   if (decl && DECL_P (decl)
9603       && TREE_CODE (decl) != FUNCTION_DECL
9604       && MEM_P (rtl)
9605       && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
9606    {
9607       rtx sym = XEXP (rtl, 0);
9608       tree type = TREE_TYPE (decl);
9609       tree attr = DECL_ATTRIBUTES (decl);
9610       if (type == error_mark_node)
9611         return;
9612
9613       addr_space_t as = TYPE_ADDR_SPACE (type);
9614
9615       /* PSTR strings are in generic space but located in flash:
9616          patch address space.  */
9617
9618       if (-1 == avr_progmem_p (decl, attr))
9619         as = ADDR_SPACE_FLASH;
9620
9621       AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
9622
9623       tree io_low_attr = lookup_attribute ("io_low", attr);
9624       tree io_attr = lookup_attribute ("io", attr);
9625       tree addr_attr;
9626       if (io_low_attr
9627           && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
9628         addr_attr = io_attr;
9629       else if (io_attr
9630                && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
9631         addr_attr = io_attr;
9632       else
9633         addr_attr = lookup_attribute ("address", attr);
9634       if (io_low_attr
9635           || (io_attr && addr_attr
9636               && low_io_address_operand
9637                   (GEN_INT (TREE_INT_CST_LOW
9638                             (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
9639         SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
9640       if (io_attr || io_low_attr)
9641         SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
9642       /* If we have an (io) address attribute specification, but the variable
9643          is external, treat the address as only a tentative definition
9644          to be used to determine if an io port is in the lower range, but
9645          don't use the exact value for constant propagation.  */
9646       if (addr_attr && !DECL_EXTERNAL (decl))
9647         SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
9648     }
9649 }
9650
9651
9652 /* Implement `TARGET_ASM_SELECT_SECTION' */
9653
9654 static section *
9655 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
9656 {
9657   section * sect = default_elf_select_section (decl, reloc, align);
9658
9659   if (decl && DECL_P (decl)
9660       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9661     {
9662       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9663
9664       /* __progmem__ goes in generic space but shall be allocated to
9665          .progmem.data  */
9666
9667       if (ADDR_SPACE_GENERIC_P (as))
9668         as = ADDR_SPACE_FLASH;
9669
9670       if (sect->common.flags & SECTION_NAMED)
9671         {
9672           const char * name = sect->named.name;
9673           const char * old_prefix = ".rodata";
9674           const char * new_prefix = avr_addrspace[as].section_name;
9675
9676           if (STR_PREFIX_P (name, old_prefix))
9677             {
9678               const char *sname = ACONCAT ((new_prefix,
9679                                             name + strlen (old_prefix), NULL));
9680               return get_section (sname,
9681                                   sect->common.flags & ~SECTION_DECLARED,
9682                                   sect->named.decl);
9683             }
9684         }
9685
9686       if (!progmem_section[as])
9687         {
9688           progmem_section[as]
9689             = get_unnamed_section (0, avr_output_progmem_section_asm_op,
9690                                    avr_addrspace[as].section_name);
9691         }
9692
9693       return progmem_section[as];
9694     }
9695
9696   return sect;
9697 }
9698
9699 /* Implement `TARGET_ASM_FILE_START'.  */
9700 /* Outputs some text at the start of each assembler file.  */
9701
9702 static void
9703 avr_file_start (void)
9704 {
9705   int sfr_offset = avr_arch->sfr_offset;
9706
9707   if (avr_arch->asm_only)
9708     error ("architecture %qs supported for assembler only", avr_mmcu);
9709
9710   default_file_start ();
9711
9712   /* Print I/O addresses of some SFRs used with IN and OUT.  */
9713
9714   if (AVR_HAVE_SPH)
9715     fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
9716
9717   fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
9718   fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
9719   if (AVR_HAVE_RAMPZ)
9720     fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
9721   if (AVR_HAVE_RAMPY)
9722     fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
9723   if (AVR_HAVE_RAMPX)
9724     fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
9725   if (AVR_HAVE_RAMPD)
9726     fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
9727   if (AVR_XMEGA || AVR_TINY)
9728     fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
9729   fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
9730   fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
9731 }
9732
9733
9734 /* Implement `TARGET_ASM_FILE_END'.  */
9735 /* Outputs to the stdio stream FILE some
9736    appropriate text to go at the end of an assembler file.  */
9737
9738 static void
9739 avr_file_end (void)
9740 {
9741   /* Output these only if there is anything in the
9742      .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
9743      input section(s) - some code size can be saved by not
9744      linking in the initialization code from libgcc if resp.
9745      sections are empty, see PR18145.  */
9746
9747   if (avr_need_copy_data_p)
9748     fputs (".global __do_copy_data\n", asm_out_file);
9749
9750   if (avr_need_clear_bss_p)
9751     fputs (".global __do_clear_bss\n", asm_out_file);
9752 }
9753
9754
9755 /* Worker function for `ADJUST_REG_ALLOC_ORDER'.  */
9756 /* Choose the order in which to allocate hard registers for
9757    pseudo-registers local to a basic block.
9758
9759    Store the desired register order in the array `reg_alloc_order'.
9760    Element 0 should be the register to allocate first; element 1, the
9761    next register; and so on.  */
9762
9763 void
9764 avr_adjust_reg_alloc_order (void)
9765 {
9766   unsigned int i;
9767   static const int order_0[] =
9768     {
9769       24, 25,
9770       18, 19, 20, 21, 22, 23,
9771       30, 31,
9772       26, 27, 28, 29,
9773       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9774       0, 1,
9775       32, 33, 34, 35
9776   };
9777   static const int tiny_order_0[] = {
9778     20, 21,
9779     22, 23,
9780     24, 25,
9781     30, 31,
9782     26, 27,
9783     28, 29,
9784     19, 18,
9785     16, 17,
9786     32, 33, 34, 35,
9787     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9788   };
9789   static const int order_1[] =
9790     {
9791       18, 19, 20, 21, 22, 23, 24, 25,
9792       30, 31,
9793       26, 27, 28, 29,
9794       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9795       0, 1,
9796       32, 33, 34, 35
9797   };
9798   static const int tiny_order_1[] = {
9799     22, 23,
9800     24, 25,
9801     30, 31,
9802     26, 27,
9803     28, 29,
9804     21, 20, 19, 18,
9805     16, 17,
9806     32, 33, 34, 35,
9807     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9808   };
9809   static const int order_2[] =
9810     {
9811       25, 24, 23, 22, 21, 20, 19, 18,
9812       30, 31,
9813       26, 27, 28, 29,
9814       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9815       1, 0,
9816       32, 33, 34, 35
9817   };
9818
9819   /* Select specific register allocation order.
9820      Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
9821      so different allocation order should be used.  */
9822
9823   const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
9824                       : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
9825                       : (AVR_TINY ? tiny_order_0 : order_0));
9826
9827   for (i = 0; i < ARRAY_SIZE (order_0); ++i)
9828       reg_alloc_order[i] = order[i];
9829 }
9830
9831
9832 /* Implement `TARGET_REGISTER_MOVE_COST' */
9833
9834 static int
9835 avr_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
9836                         reg_class_t from, reg_class_t to)
9837 {
9838   return (from == STACK_REG ? 6
9839           : to == STACK_REG ? 12
9840           : 2);
9841 }
9842
9843
9844 /* Implement `TARGET_MEMORY_MOVE_COST' */
9845
9846 static int
9847 avr_memory_move_cost (machine_mode mode,
9848                       reg_class_t rclass ATTRIBUTE_UNUSED,
9849                       bool in ATTRIBUTE_UNUSED)
9850 {
9851   return (mode == QImode ? 2
9852           : mode == HImode ? 4
9853           : mode == SImode ? 8
9854           : mode == SFmode ? 8
9855           : 16);
9856 }
9857
9858
9859 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
9860    cost of an RTX operand given its context.  X is the rtx of the
9861    operand, MODE is its mode, and OUTER is the rtx_code of this
9862    operand's parent operator.  */
9863
9864 static int
9865 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
9866                       int opno, bool speed)
9867 {
9868   enum rtx_code code = GET_CODE (x);
9869   int total;
9870
9871   switch (code)
9872     {
9873     case REG:
9874     case SUBREG:
9875       return 0;
9876
9877     case CONST_INT:
9878     case CONST_FIXED:
9879     case CONST_DOUBLE:
9880       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
9881
9882     default:
9883       break;
9884     }
9885
9886   total = 0;
9887   avr_rtx_costs (x, mode, outer, opno, &total, speed);
9888   return total;
9889 }
9890
9891 /* Worker function for AVR backend's rtx_cost function.
9892    X is rtx expression whose cost is to be calculated.
9893    Return true if the complete cost has been computed.
9894    Return false if subexpressions should be scanned.
9895    In either case, *TOTAL contains the cost result.  */
9896
9897 static bool
9898 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
9899                  int opno ATTRIBUTE_UNUSED, int *total, bool speed)
9900 {
9901   enum rtx_code code = GET_CODE (x);
9902   HOST_WIDE_INT val;
9903
9904   switch (code)
9905     {
9906     case CONST_INT:
9907     case CONST_FIXED:
9908     case CONST_DOUBLE:
9909     case SYMBOL_REF:
9910     case CONST:
9911     case LABEL_REF:
9912       /* Immediate constants are as cheap as registers.  */
9913       *total = 0;
9914       return true;
9915
9916     case MEM:
9917       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9918       return true;
9919
9920     case NEG:
9921       switch (mode)
9922         {
9923         case QImode:
9924         case SFmode:
9925           *total = COSTS_N_INSNS (1);
9926           break;
9927
9928         case HImode:
9929         case PSImode:
9930         case SImode:
9931           *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
9932           break;
9933
9934         default:
9935           return false;
9936         }
9937       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9938       return true;
9939
9940     case ABS:
9941       switch (mode)
9942         {
9943         case QImode:
9944         case SFmode:
9945           *total = COSTS_N_INSNS (1);
9946           break;
9947
9948         default:
9949           return false;
9950         }
9951       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9952       return true;
9953
9954     case NOT:
9955       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9956       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
9957       return true;
9958
9959     case ZERO_EXTEND:
9960       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
9961                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9962       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9963                                       code, 0, speed);
9964       return true;
9965
9966     case SIGN_EXTEND:
9967       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
9968                               - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
9969       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
9970                                       code, 0, speed);
9971       return true;
9972
9973     case PLUS:
9974       switch (mode)
9975         {
9976         case QImode:
9977           if (AVR_HAVE_MUL
9978               && MULT == GET_CODE (XEXP (x, 0))
9979               && register_operand (XEXP (x, 1), QImode))
9980             {
9981               /* multiply-add */
9982               *total = COSTS_N_INSNS (speed ? 4 : 3);
9983               /* multiply-add with constant: will be split and load constant. */
9984               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
9985                 *total = COSTS_N_INSNS (1) + *total;
9986               return true;
9987             }
9988           *total = COSTS_N_INSNS (1);
9989           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
9990             *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
9991           break;
9992
9993         case HImode:
9994           if (AVR_HAVE_MUL
9995               && (MULT == GET_CODE (XEXP (x, 0))
9996                   || ASHIFT == GET_CODE (XEXP (x, 0)))
9997               && register_operand (XEXP (x, 1), HImode)
9998               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
9999                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
10000             {
10001               /* multiply-add */
10002               *total = COSTS_N_INSNS (speed ? 5 : 4);
10003               /* multiply-add with constant: will be split and load constant. */
10004               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10005                 *total = COSTS_N_INSNS (1) + *total;
10006               return true;
10007             }
10008           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10009             {
10010               *total = COSTS_N_INSNS (2);
10011               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10012                                               speed);
10013             }
10014           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10015             *total = COSTS_N_INSNS (1);
10016           else
10017             *total = COSTS_N_INSNS (2);
10018           break;
10019
10020         case PSImode:
10021           if (!CONST_INT_P (XEXP (x, 1)))
10022             {
10023               *total = COSTS_N_INSNS (3);
10024               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10025                                               speed);
10026             }
10027           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10028             *total = COSTS_N_INSNS (2);
10029           else
10030             *total = COSTS_N_INSNS (3);
10031           break;
10032
10033         case SImode:
10034           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10035             {
10036               *total = COSTS_N_INSNS (4);
10037               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10038                                               speed);
10039             }
10040           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10041             *total = COSTS_N_INSNS (1);
10042           else
10043             *total = COSTS_N_INSNS (4);
10044           break;
10045
10046         default:
10047           return false;
10048         }
10049       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10050       return true;
10051
10052     case MINUS:
10053       if (AVR_HAVE_MUL
10054           && QImode == mode
10055           && register_operand (XEXP (x, 0), QImode)
10056           && MULT == GET_CODE (XEXP (x, 1)))
10057         {
10058           /* multiply-sub */
10059           *total = COSTS_N_INSNS (speed ? 4 : 3);
10060           /* multiply-sub with constant: will be split and load constant. */
10061           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10062             *total = COSTS_N_INSNS (1) + *total;
10063           return true;
10064         }
10065       if (AVR_HAVE_MUL
10066           && HImode == mode
10067           && register_operand (XEXP (x, 0), HImode)
10068           && (MULT == GET_CODE (XEXP (x, 1))
10069               || ASHIFT == GET_CODE (XEXP (x, 1)))
10070           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
10071               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
10072         {
10073           /* multiply-sub */
10074           *total = COSTS_N_INSNS (speed ? 5 : 4);
10075           /* multiply-sub with constant: will be split and load constant. */
10076           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10077             *total = COSTS_N_INSNS (1) + *total;
10078           return true;
10079         }
10080       /* FALLTHRU */
10081     case AND:
10082     case IOR:
10083       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10084       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10085       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10086         *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10087       return true;
10088
10089     case XOR:
10090       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10091       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10092       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10093       return true;
10094
10095     case MULT:
10096       switch (mode)
10097         {
10098         case QImode:
10099           if (AVR_HAVE_MUL)
10100             *total = COSTS_N_INSNS (!speed ? 3 : 4);
10101           else if (!speed)
10102             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10103           else
10104             return false;
10105           break;
10106
10107         case HImode:
10108           if (AVR_HAVE_MUL)
10109             {
10110               rtx op0 = XEXP (x, 0);
10111               rtx op1 = XEXP (x, 1);
10112               enum rtx_code code0 = GET_CODE (op0);
10113               enum rtx_code code1 = GET_CODE (op1);
10114               bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
10115               bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
10116
10117               if (ex0
10118                   && (u8_operand (op1, HImode)
10119                       || s8_operand (op1, HImode)))
10120                 {
10121                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
10122                   return true;
10123                 }
10124               if (ex0
10125                   && register_operand (op1, HImode))
10126                 {
10127                   *total = COSTS_N_INSNS (!speed ? 5 : 8);
10128                   return true;
10129                 }
10130               else if (ex0 || ex1)
10131                 {
10132                   *total = COSTS_N_INSNS (!speed ? 3 : 5);
10133                   return true;
10134                 }
10135               else if (register_operand (op0, HImode)
10136                        && (u8_operand (op1, HImode)
10137                            || s8_operand (op1, HImode)))
10138                 {
10139                   *total = COSTS_N_INSNS (!speed ? 6 : 9);
10140                   return true;
10141                 }
10142               else
10143                 *total = COSTS_N_INSNS (!speed ? 7 : 10);
10144             }
10145           else if (!speed)
10146             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10147           else
10148             return false;
10149           break;
10150
10151         case PSImode:
10152           if (!speed)
10153             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10154           else
10155             *total = 10;
10156           break;
10157
10158         case SImode:
10159         case DImode:
10160           if (AVR_HAVE_MUL)
10161             {
10162               if (!speed)
10163                 {
10164                   /* Add some additional costs besides CALL like moves etc.  */
10165
10166                   *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10167                 }
10168               else
10169                 {
10170                   /* Just a rough estimate.  Even with -O2 we don't want bulky
10171                      code expanded inline.  */
10172
10173                   *total = COSTS_N_INSNS (25);
10174                 }
10175             }
10176           else
10177             {
10178               if (speed)
10179                 *total = COSTS_N_INSNS (300);
10180               else
10181                 /* Add some additional costs besides CALL like moves etc.  */
10182                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10183             }
10184
10185            if (mode == DImode)
10186              *total *= 2;
10187
10188            return true;
10189
10190         default:
10191           return false;
10192         }
10193       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10194       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10195       return true;
10196
10197     case DIV:
10198     case MOD:
10199     case UDIV:
10200     case UMOD:
10201       if (!speed)
10202         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10203       else
10204         *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
10205       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10206       /* For div/mod with const-int divisor we have at least the cost of
10207          loading the divisor. */
10208       if (CONST_INT_P (XEXP (x, 1)))
10209         *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
10210       /* Add some overall penaly for clobbering and moving around registers */
10211       *total += COSTS_N_INSNS (2);
10212       return true;
10213
10214     case ROTATE:
10215       switch (mode)
10216         {
10217         case QImode:
10218           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
10219             *total = COSTS_N_INSNS (1);
10220
10221           break;
10222
10223         case HImode:
10224           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
10225             *total = COSTS_N_INSNS (3);
10226
10227           break;
10228
10229         case SImode:
10230           if (CONST_INT_P (XEXP (x, 1)))
10231             switch (INTVAL (XEXP (x, 1)))
10232               {
10233               case 8:
10234               case 24:
10235                 *total = COSTS_N_INSNS (5);
10236                 break;
10237               case 16:
10238                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
10239                 break;
10240               }
10241           break;
10242
10243         default:
10244           return false;
10245         }
10246       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10247       return true;
10248
10249     case ASHIFT:
10250       switch (mode)
10251         {
10252         case QImode:
10253           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10254             {
10255               *total = COSTS_N_INSNS (!speed ? 4 : 17);
10256               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10257                                               speed);
10258             }
10259           else
10260             {
10261               val = INTVAL (XEXP (x, 1));
10262               if (val == 7)
10263                 *total = COSTS_N_INSNS (3);
10264               else if (val >= 0 && val <= 7)
10265                 *total = COSTS_N_INSNS (val);
10266               else
10267                 *total = COSTS_N_INSNS (1);
10268             }
10269           break;
10270
10271         case HImode:
10272           if (AVR_HAVE_MUL)
10273             {
10274               if (const_2_to_7_operand (XEXP (x, 1), HImode)
10275                   && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
10276                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
10277                 {
10278                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
10279                   return true;
10280                 }
10281             }
10282
10283           if (const1_rtx == (XEXP (x, 1))
10284               && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
10285             {
10286               *total = COSTS_N_INSNS (2);
10287               return true;
10288             }
10289
10290           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10291             {
10292               *total = COSTS_N_INSNS (!speed ? 5 : 41);
10293               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10294                                               speed);
10295             }
10296           else
10297             switch (INTVAL (XEXP (x, 1)))
10298               {
10299               case 0:
10300                 *total = 0;
10301                 break;
10302               case 1:
10303               case 8:
10304                 *total = COSTS_N_INSNS (2);
10305                 break;
10306               case 9:
10307                 *total = COSTS_N_INSNS (3);
10308                 break;
10309               case 2:
10310               case 3:
10311               case 10:
10312               case 15:
10313                 *total = COSTS_N_INSNS (4);
10314                 break;
10315               case 7:
10316               case 11:
10317               case 12:
10318                 *total = COSTS_N_INSNS (5);
10319                 break;
10320               case 4:
10321                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10322                 break;
10323               case 6:
10324                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10325                 break;
10326               case 5:
10327                 *total = COSTS_N_INSNS (!speed ? 5 : 10);
10328                 break;
10329               default:
10330                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10331                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10332                                                 speed);
10333               }
10334           break;
10335
10336         case PSImode:
10337           if (!CONST_INT_P (XEXP (x, 1)))
10338             {
10339               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10340             }
10341           else
10342             switch (INTVAL (XEXP (x, 1)))
10343               {
10344               case 0:
10345                 *total = 0;
10346                 break;
10347               case 1:
10348               case 8:
10349               case 16:
10350                 *total = COSTS_N_INSNS (3);
10351                 break;
10352               case 23:
10353                 *total = COSTS_N_INSNS (5);
10354                 break;
10355               default:
10356                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10357                 break;
10358               }
10359           break;
10360
10361         case SImode:
10362           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10363             {
10364               *total = COSTS_N_INSNS (!speed ? 7 : 113);
10365               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10366                                               speed);
10367             }
10368           else
10369             switch (INTVAL (XEXP (x, 1)))
10370               {
10371               case 0:
10372                 *total = 0;
10373                 break;
10374               case 24:
10375                 *total = COSTS_N_INSNS (3);
10376                 break;
10377               case 1:
10378               case 8:
10379               case 16:
10380                 *total = COSTS_N_INSNS (4);
10381                 break;
10382               case 31:
10383                 *total = COSTS_N_INSNS (6);
10384                 break;
10385               case 2:
10386                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10387                 break;
10388               default:
10389                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10390                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10391                                                 speed);
10392               }
10393           break;
10394
10395         default:
10396           return false;
10397         }
10398       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10399       return true;
10400
10401     case ASHIFTRT:
10402       switch (mode)
10403         {
10404         case QImode:
10405           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10406             {
10407               *total = COSTS_N_INSNS (!speed ? 4 : 17);
10408               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10409                                               speed);
10410             }
10411           else
10412             {
10413               val = INTVAL (XEXP (x, 1));
10414               if (val == 6)
10415                 *total = COSTS_N_INSNS (4);
10416               else if (val == 7)
10417                 *total = COSTS_N_INSNS (2);
10418               else if (val >= 0 && val <= 7)
10419                 *total = COSTS_N_INSNS (val);
10420               else
10421                 *total = COSTS_N_INSNS (1);
10422             }
10423           break;
10424
10425         case HImode:
10426           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10427             {
10428               *total = COSTS_N_INSNS (!speed ? 5 : 41);
10429               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10430                                               speed);
10431             }
10432           else
10433             switch (INTVAL (XEXP (x, 1)))
10434               {
10435               case 0:
10436                 *total = 0;
10437                 break;
10438               case 1:
10439                 *total = COSTS_N_INSNS (2);
10440                 break;
10441               case 15:
10442                 *total = COSTS_N_INSNS (3);
10443                 break;
10444               case 2:
10445               case 7:
10446               case 8:
10447               case 9:
10448                 *total = COSTS_N_INSNS (4);
10449                 break;
10450               case 10:
10451               case 14:
10452                 *total = COSTS_N_INSNS (5);
10453                 break;
10454               case 11:
10455                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10456                 break;
10457               case 12:
10458                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10459                 break;
10460               case 6:
10461               case 13:
10462                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10463                 break;
10464               default:
10465                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10466                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10467                                                 speed);
10468               }
10469           break;
10470
10471         case PSImode:
10472           if (!CONST_INT_P (XEXP (x, 1)))
10473             {
10474               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10475             }
10476           else
10477             switch (INTVAL (XEXP (x, 1)))
10478               {
10479               case 0:
10480                 *total = 0;
10481                 break;
10482               case 1:
10483                 *total = COSTS_N_INSNS (3);
10484                 break;
10485               case 16:
10486               case 8:
10487                 *total = COSTS_N_INSNS (5);
10488                 break;
10489               case 23:
10490                 *total = COSTS_N_INSNS (4);
10491                 break;
10492               default:
10493                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10494                 break;
10495               }
10496           break;
10497
10498         case SImode:
10499           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10500             {
10501               *total = COSTS_N_INSNS (!speed ? 7 : 113);
10502               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10503                                               speed);
10504             }
10505           else
10506             switch (INTVAL (XEXP (x, 1)))
10507               {
10508               case 0:
10509                 *total = 0;
10510                 break;
10511               case 1:
10512                 *total = COSTS_N_INSNS (4);
10513                 break;
10514               case 8:
10515               case 16:
10516               case 24:
10517                 *total = COSTS_N_INSNS (6);
10518                 break;
10519               case 2:
10520                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10521                 break;
10522               case 31:
10523                 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
10524                 break;
10525               default:
10526                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10527                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10528                                                 speed);
10529               }
10530           break;
10531
10532         default:
10533           return false;
10534         }
10535       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10536       return true;
10537
10538     case LSHIFTRT:
10539       switch (mode)
10540         {
10541         case QImode:
10542           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10543             {
10544               *total = COSTS_N_INSNS (!speed ? 4 : 17);
10545               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10546                                               speed);
10547             }
10548           else
10549             {
10550               val = INTVAL (XEXP (x, 1));
10551               if (val == 7)
10552                 *total = COSTS_N_INSNS (3);
10553               else if (val >= 0 && val <= 7)
10554                 *total = COSTS_N_INSNS (val);
10555               else
10556                 *total = COSTS_N_INSNS (1);
10557             }
10558           break;
10559
10560         case HImode:
10561           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10562             {
10563               *total = COSTS_N_INSNS (!speed ? 5 : 41);
10564               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10565                                               speed);
10566             }
10567           else
10568             switch (INTVAL (XEXP (x, 1)))
10569               {
10570               case 0:
10571                 *total = 0;
10572                 break;
10573               case 1:
10574               case 8:
10575                 *total = COSTS_N_INSNS (2);
10576                 break;
10577               case 9:
10578                 *total = COSTS_N_INSNS (3);
10579                 break;
10580               case 2:
10581               case 10:
10582               case 15:
10583                 *total = COSTS_N_INSNS (4);
10584                 break;
10585               case 7:
10586               case 11:
10587                 *total = COSTS_N_INSNS (5);
10588                 break;
10589               case 3:
10590               case 12:
10591               case 13:
10592               case 14:
10593                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10594                 break;
10595               case 4:
10596                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10597                 break;
10598               case 5:
10599               case 6:
10600                 *total = COSTS_N_INSNS (!speed ? 5 : 9);
10601                 break;
10602               default:
10603                 *total = COSTS_N_INSNS (!speed ? 5 : 41);
10604                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10605                                                 speed);
10606               }
10607           break;
10608
10609         case PSImode:
10610           if (!CONST_INT_P (XEXP (x, 1)))
10611             {
10612               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10613             }
10614           else
10615             switch (INTVAL (XEXP (x, 1)))
10616               {
10617               case 0:
10618                 *total = 0;
10619                 break;
10620               case 1:
10621               case 8:
10622               case 16:
10623                 *total = COSTS_N_INSNS (3);
10624                 break;
10625               case 23:
10626                 *total = COSTS_N_INSNS (5);
10627                 break;
10628               default:
10629                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10630                 break;
10631               }
10632           break;
10633
10634         case SImode:
10635           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10636             {
10637               *total = COSTS_N_INSNS (!speed ? 7 : 113);
10638               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10639                                               speed);
10640             }
10641           else
10642             switch (INTVAL (XEXP (x, 1)))
10643               {
10644               case 0:
10645                 *total = 0;
10646                 break;
10647               case 1:
10648                 *total = COSTS_N_INSNS (4);
10649                 break;
10650               case 2:
10651                 *total = COSTS_N_INSNS (!speed ? 7 : 8);
10652                 break;
10653               case 8:
10654               case 16:
10655               case 24:
10656                 *total = COSTS_N_INSNS (4);
10657                 break;
10658               case 31:
10659                 *total = COSTS_N_INSNS (6);
10660                 break;
10661               default:
10662                 *total = COSTS_N_INSNS (!speed ? 7 : 113);
10663                 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10664                                                 speed);
10665               }
10666           break;
10667
10668         default:
10669           return false;
10670         }
10671       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10672       return true;
10673
10674     case COMPARE:
10675       switch (GET_MODE (XEXP (x, 0)))
10676         {
10677         case QImode:
10678           *total = COSTS_N_INSNS (1);
10679           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10680             *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
10681                                             1, speed);
10682           break;
10683
10684         case HImode:
10685           *total = COSTS_N_INSNS (2);
10686           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10687             *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
10688                                             1, speed);
10689           else if (INTVAL (XEXP (x, 1)) != 0)
10690             *total += COSTS_N_INSNS (1);
10691           break;
10692
10693         case PSImode:
10694           *total = COSTS_N_INSNS (3);
10695           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
10696             *total += COSTS_N_INSNS (2);
10697           break;
10698
10699         case SImode:
10700           *total = COSTS_N_INSNS (4);
10701           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10702             *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
10703                                             1, speed);
10704           else if (INTVAL (XEXP (x, 1)) != 0)
10705             *total += COSTS_N_INSNS (3);
10706           break;
10707
10708         default:
10709           return false;
10710         }
10711       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10712                                       code, 0, speed);
10713       return true;
10714
10715     case TRUNCATE:
10716       if (AVR_HAVE_MUL
10717           && LSHIFTRT == GET_CODE (XEXP (x, 0))
10718           && MULT == GET_CODE (XEXP (XEXP (x, 0), 0))
10719           && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10720         {
10721           if (QImode == mode || HImode == mode)
10722             {
10723               *total = COSTS_N_INSNS (2);
10724               return true;
10725             }
10726         }
10727       break;
10728
10729     default:
10730       break;
10731     }
10732   return false;
10733 }
10734
10735
10736 /* Implement `TARGET_RTX_COSTS'.  */
10737
10738 static bool
10739 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
10740                int opno, int *total, bool speed)
10741 {
10742   bool done = avr_rtx_costs_1 (x, mode, outer_code,
10743                                opno, total, speed);
10744
10745   if (avr_log.rtx_costs)
10746     {
10747       avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
10748                  done, speed ? "speed" : "size", *total, outer_code, x);
10749     }
10750
10751   return done;
10752 }
10753
10754
10755 /* Implement `TARGET_ADDRESS_COST'.  */
10756
10757 static int
10758 avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
10759                   addr_space_t as ATTRIBUTE_UNUSED,
10760                   bool speed ATTRIBUTE_UNUSED)
10761 {
10762   int cost = 4;
10763
10764   if (GET_CODE (x) == PLUS
10765       && CONST_INT_P (XEXP (x, 1))
10766       && (REG_P (XEXP (x, 0))
10767           || GET_CODE (XEXP (x, 0)) == SUBREG))
10768     {
10769       if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
10770         cost = 18;
10771     }
10772   else if (CONSTANT_ADDRESS_P (x))
10773     {
10774       if (optimize > 0
10775           && io_address_operand (x, QImode))
10776         cost = 2;
10777     }
10778
10779   if (avr_log.address_cost)
10780     avr_edump ("\n%?: %d = %r\n", cost, x);
10781
10782   return cost;
10783 }
10784
10785 /* Test for extra memory constraint 'Q'.
10786    It's a memory address based on Y or Z pointer with valid displacement.  */
10787
10788 int
10789 extra_constraint_Q (rtx x)
10790 {
10791   int ok = 0;
10792
10793   if (GET_CODE (XEXP (x,0)) == PLUS
10794       && REG_P (XEXP (XEXP (x,0), 0))
10795       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
10796       && (INTVAL (XEXP (XEXP (x,0), 1))
10797           <= MAX_LD_OFFSET (GET_MODE (x))))
10798     {
10799       rtx xx = XEXP (XEXP (x,0), 0);
10800       int regno = REGNO (xx);
10801
10802       ok = (/* allocate pseudos */
10803             regno >= FIRST_PSEUDO_REGISTER
10804             /* strictly check */
10805             || regno == REG_Z || regno == REG_Y
10806             /* XXX frame & arg pointer checks */
10807             || xx == frame_pointer_rtx
10808             || xx == arg_pointer_rtx);
10809
10810       if (avr_log.constraints)
10811         avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
10812                    ok, reload_completed, reload_in_progress, x);
10813     }
10814
10815   return ok;
10816 }
10817
10818 /* Convert condition code CONDITION to the valid AVR condition code.  */
10819
10820 RTX_CODE
10821 avr_normalize_condition (RTX_CODE condition)
10822 {
10823   switch (condition)
10824     {
10825     case GT:
10826       return GE;
10827     case GTU:
10828       return GEU;
10829     case LE:
10830       return LT;
10831     case LEU:
10832       return LTU;
10833     default:
10834       gcc_unreachable ();
10835     }
10836 }
10837
10838 /* Helper function for `avr_reorg'.  */
10839
10840 static rtx
10841 avr_compare_pattern (rtx_insn *insn)
10842 {
10843   rtx pattern = single_set (insn);
10844
10845   if (pattern
10846       && NONJUMP_INSN_P (insn)
10847       && SET_DEST (pattern) == cc0_rtx
10848       && GET_CODE (SET_SRC (pattern)) == COMPARE)
10849     {
10850       machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
10851       machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
10852
10853       /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
10854          They must not be swapped, thus skip them.  */
10855
10856       if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
10857           && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
10858         return pattern;
10859     }
10860
10861   return NULL_RTX;
10862 }
10863
10864 /* Helper function for `avr_reorg'.  */
10865
10866 /* Expansion of switch/case decision trees leads to code like
10867
10868        cc0 = compare (Reg, Num)
10869        if (cc0 == 0)
10870          goto L1
10871
10872        cc0 = compare (Reg, Num)
10873        if (cc0 > 0)
10874          goto L2
10875
10876    The second comparison is superfluous and can be deleted.
10877    The second jump condition can be transformed from a
10878    "difficult" one to a "simple" one because "cc0 > 0" and
10879    "cc0 >= 0" will have the same effect here.
10880
10881    This function relies on the way switch/case is being expaned
10882    as binary decision tree.  For example code see PR 49903.
10883
10884    Return TRUE if optimization performed.
10885    Return FALSE if nothing changed.
10886
10887    INSN1 is a comparison, i.e. avr_compare_pattern != 0.
10888
10889    We don't want to do this in text peephole because it is
10890    tedious to work out jump offsets there and the second comparison
10891    might have been transormed by `avr_reorg'.
10892
10893    RTL peephole won't do because peephole2 does not scan across
10894    basic blocks.  */
10895
10896 static bool
10897 avr_reorg_remove_redundant_compare (rtx_insn *insn1)
10898 {
10899   rtx comp1, ifelse1, xcond1;
10900   rtx_insn *branch1;
10901   rtx comp2, ifelse2, xcond2;
10902   rtx_insn *branch2, *insn2;
10903   enum rtx_code code;
10904   rtx_insn *jump;
10905   rtx target, cond;
10906
10907   /* Look out for:  compare1 - branch1 - compare2 - branch2  */
10908
10909   branch1 = next_nonnote_nondebug_insn (insn1);
10910   if (!branch1 || !JUMP_P (branch1))
10911     return false;
10912
10913   insn2 = next_nonnote_nondebug_insn (branch1);
10914   if (!insn2 || !avr_compare_pattern (insn2))
10915     return false;
10916
10917   branch2 = next_nonnote_nondebug_insn (insn2);
10918   if (!branch2 || !JUMP_P (branch2))
10919     return false;
10920
10921   comp1 = avr_compare_pattern (insn1);
10922   comp2 = avr_compare_pattern (insn2);
10923   xcond1 = single_set (branch1);
10924   xcond2 = single_set (branch2);
10925
10926   if (!comp1 || !comp2
10927       || !rtx_equal_p (comp1, comp2)
10928       || !xcond1 || SET_DEST (xcond1) != pc_rtx
10929       || !xcond2 || SET_DEST (xcond2) != pc_rtx
10930       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
10931       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
10932     {
10933       return false;
10934     }
10935
10936   comp1 = SET_SRC (comp1);
10937   ifelse1 = SET_SRC (xcond1);
10938   ifelse2 = SET_SRC (xcond2);
10939
10940   /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE.  */
10941
10942   if (EQ != GET_CODE (XEXP (ifelse1, 0))
10943       || !REG_P (XEXP (comp1, 0))
10944       || !CONST_INT_P (XEXP (comp1, 1))
10945       || XEXP (ifelse1, 2) != pc_rtx
10946       || XEXP (ifelse2, 2) != pc_rtx
10947       || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
10948       || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
10949       || !COMPARISON_P (XEXP (ifelse2, 0))
10950       || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
10951       || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
10952       || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
10953       || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
10954     {
10955       return false;
10956     }
10957
10958   /* We filtered the insn sequence to look like
10959
10960         (set (cc0)
10961              (compare (reg:M N)
10962                       (const_int VAL)))
10963         (set (pc)
10964              (if_then_else (eq (cc0)
10965                                (const_int 0))
10966                            (label_ref L1)
10967                            (pc)))
10968
10969         (set (cc0)
10970              (compare (reg:M N)
10971                       (const_int VAL)))
10972         (set (pc)
10973              (if_then_else (CODE (cc0)
10974                                  (const_int 0))
10975                            (label_ref L2)
10976                            (pc)))
10977   */
10978
10979   code = GET_CODE (XEXP (ifelse2, 0));
10980
10981   /* Map GT/GTU to GE/GEU which is easier for AVR.
10982      The first two instructions compare/branch on EQ
10983      so we may replace the difficult
10984
10985         if (x == VAL)   goto L1;
10986         if (x > VAL)    goto L2;
10987
10988      with easy
10989
10990          if (x == VAL)   goto L1;
10991          if (x >= VAL)   goto L2;
10992
10993      Similarly, replace LE/LEU by LT/LTU.  */
10994
10995   switch (code)
10996     {
10997     case EQ:
10998     case LT:  case LTU:
10999     case GE:  case GEU:
11000       break;
11001
11002     case LE:  case LEU:
11003     case GT:  case GTU:
11004       code = avr_normalize_condition (code);
11005       break;
11006
11007     default:
11008       return false;
11009     }
11010
11011   /* Wrap the branches into UNSPECs so they won't be changed or
11012      optimized in the remainder.  */
11013
11014   target = XEXP (XEXP (ifelse1, 1), 0);
11015   cond = XEXP (ifelse1, 0);
11016   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
11017
11018   JUMP_LABEL (jump) = JUMP_LABEL (branch1);
11019
11020   target = XEXP (XEXP (ifelse2, 1), 0);
11021   cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
11022   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
11023
11024   JUMP_LABEL (jump) = JUMP_LABEL (branch2);
11025
11026   /* The comparisons in insn1 and insn2 are exactly the same;
11027      insn2 is superfluous so delete it.  */
11028
11029   delete_insn (insn2);
11030   delete_insn (branch1);
11031   delete_insn (branch2);
11032
11033   return true;
11034 }
11035
11036
11037 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
11038 /* Optimize conditional jumps.  */
11039
11040 static void
11041 avr_reorg (void)
11042 {
11043   rtx_insn *insn = get_insns();
11044
11045   for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
11046     {
11047       rtx pattern = avr_compare_pattern (insn);
11048
11049       if (!pattern)
11050         continue;
11051
11052       if (optimize
11053           && avr_reorg_remove_redundant_compare (insn))
11054         {
11055           continue;
11056         }
11057
11058       if (compare_diff_p (insn))
11059         {
11060           /* Now we work under compare insn with difficult branch.  */
11061
11062           rtx_insn *next = next_real_insn (insn);
11063           rtx pat = PATTERN (next);
11064
11065           pattern = SET_SRC (pattern);
11066
11067           if (true_regnum (XEXP (pattern, 0)) >= 0
11068               && true_regnum (XEXP (pattern, 1)) >= 0)
11069             {
11070               rtx x = XEXP (pattern, 0);
11071               rtx src = SET_SRC (pat);
11072               rtx t = XEXP (src,0);
11073               PUT_CODE (t, swap_condition (GET_CODE (t)));
11074               XEXP (pattern, 0) = XEXP (pattern, 1);
11075               XEXP (pattern, 1) = x;
11076               INSN_CODE (next) = -1;
11077             }
11078           else if (true_regnum (XEXP (pattern, 0)) >= 0
11079                    && XEXP (pattern, 1) == const0_rtx)
11080             {
11081               /* This is a tst insn, we can reverse it.  */
11082               rtx src = SET_SRC (pat);
11083               rtx t = XEXP (src,0);
11084
11085               PUT_CODE (t, swap_condition (GET_CODE (t)));
11086               XEXP (pattern, 1) = XEXP (pattern, 0);
11087               XEXP (pattern, 0) = const0_rtx;
11088               INSN_CODE (next) = -1;
11089               INSN_CODE (insn) = -1;
11090             }
11091           else if (true_regnum (XEXP (pattern, 0)) >= 0
11092                    && CONST_INT_P (XEXP (pattern, 1)))
11093             {
11094               rtx x = XEXP (pattern, 1);
11095               rtx src = SET_SRC (pat);
11096               rtx t = XEXP (src,0);
11097               machine_mode mode = GET_MODE (XEXP (pattern, 0));
11098
11099               if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
11100                 {
11101                   XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
11102                   PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
11103                   INSN_CODE (next) = -1;
11104                   INSN_CODE (insn) = -1;
11105                 }
11106             }
11107         }
11108     }
11109 }
11110
11111 /* Returns register number for function return value.*/
11112
11113 static inline unsigned int
11114 avr_ret_register (void)
11115 {
11116   return 24;
11117 }
11118
11119
11120 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'.  */
11121
11122 static bool
11123 avr_function_value_regno_p (const unsigned int regno)
11124 {
11125   return (regno == avr_ret_register ());
11126 }
11127
11128
11129 /* Implement `TARGET_LIBCALL_VALUE'.  */
11130 /* Create an RTX representing the place where a
11131    library function returns a value of mode MODE.  */
11132
11133 static rtx
11134 avr_libcall_value (machine_mode mode,
11135                    const_rtx func ATTRIBUTE_UNUSED)
11136 {
11137   int offs = GET_MODE_SIZE (mode);
11138
11139   if (offs <= 4)
11140     offs = (offs + 1) & ~1;
11141
11142   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
11143 }
11144
11145
11146 /* Implement `TARGET_FUNCTION_VALUE'.  */
11147 /* Create an RTX representing the place where a
11148    function returns a value of data type VALTYPE.  */
11149
11150 static rtx
11151 avr_function_value (const_tree type,
11152                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
11153                     bool outgoing ATTRIBUTE_UNUSED)
11154 {
11155   unsigned int offs;
11156
11157   if (TYPE_MODE (type) != BLKmode)
11158     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
11159
11160   offs = int_size_in_bytes (type);
11161   if (offs < 2)
11162     offs = 2;
11163   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
11164     offs = GET_MODE_SIZE (SImode);
11165   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
11166     offs = GET_MODE_SIZE (DImode);
11167
11168   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
11169 }
11170
11171 int
11172 test_hard_reg_class (enum reg_class rclass, rtx x)
11173 {
11174   int regno = true_regnum (x);
11175   if (regno < 0)
11176     return 0;
11177
11178   if (TEST_HARD_REG_CLASS (rclass, regno))
11179     return 1;
11180
11181   return 0;
11182 }
11183
11184
11185 /* Helper for jump_over_one_insn_p:  Test if INSN is a 2-word instruction
11186    and thus is suitable to be skipped by CPSE, SBRC, etc.  */
11187
11188 static bool
11189 avr_2word_insn_p (rtx_insn *insn)
11190 {
11191   if (TARGET_SKIP_BUG
11192       || !insn
11193       || 2 != get_attr_length (insn))
11194     {
11195       return false;
11196     }
11197
11198   switch (INSN_CODE (insn))
11199     {
11200     default:
11201       return false;
11202
11203     case CODE_FOR_movqi_insn:
11204     case CODE_FOR_movuqq_insn:
11205     case CODE_FOR_movqq_insn:
11206       {
11207         rtx set  = single_set (insn);
11208         rtx src  = SET_SRC (set);
11209         rtx dest = SET_DEST (set);
11210
11211         /* Factor out LDS and STS from movqi_insn.  */
11212
11213         if (MEM_P (dest)
11214             && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
11215           {
11216             return CONSTANT_ADDRESS_P (XEXP (dest, 0));
11217           }
11218         else if (REG_P (dest)
11219                  && MEM_P (src))
11220           {
11221             return CONSTANT_ADDRESS_P (XEXP (src, 0));
11222           }
11223
11224         return false;
11225       }
11226
11227     case CODE_FOR_call_insn:
11228     case CODE_FOR_call_value_insn:
11229       return true;
11230     }
11231 }
11232
11233
11234 int
11235 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
11236 {
11237   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
11238                       ? XEXP (dest, 0)
11239                       : dest);
11240   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
11241   int dest_addr = INSN_ADDRESSES (uid);
11242   int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
11243
11244   return (jump_offset == 1
11245           || (jump_offset == 2
11246               && avr_2word_insn_p (next_active_insn (insn))));
11247 }
11248
11249
11250 /* Worker function for `HARD_REGNO_MODE_OK'.  */
11251 /* Returns 1 if a value of mode MODE can be stored starting with hard
11252    register number REGNO.  On the enhanced core, anything larger than
11253    1 byte must start in even numbered register for "movw" to work
11254    (this way we don't have to check for odd registers everywhere).  */
11255
11256 int
11257 avr_hard_regno_mode_ok (int regno, machine_mode mode)
11258 {
11259   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
11260         Disallowing QI et al. in these regs might lead to code like
11261             (set (subreg:QI (reg:HI 28) n) ...)
11262         which will result in wrong code because reload does not
11263         handle SUBREGs of hard regsisters like this.
11264         This could be fixed in reload.  However, it appears
11265         that fixing reload is not wanted by reload people.  */
11266
11267   /* Any GENERAL_REGS register can hold 8-bit values.  */
11268
11269   if (GET_MODE_SIZE (mode) == 1)
11270     return 1;
11271
11272   /* FIXME: Ideally, the following test is not needed.
11273         However, it turned out that it can reduce the number
11274         of spill fails.  AVR and it's poor endowment with
11275         address registers is extreme stress test for reload.  */
11276
11277   if (GET_MODE_SIZE (mode) >= 4
11278       && regno >= REG_X)
11279     return 0;
11280
11281   /* All modes larger than 8 bits should start in an even register.  */
11282
11283   return !(regno & 1);
11284 }
11285
11286
11287 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'.  */
11288
11289 int
11290 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
11291 {
11292   /* FIXME: This hook gets called with MODE:REGNO combinations that don't
11293         represent valid hard registers like, e.g. HI:29.  Returning TRUE
11294         for such registers can lead to performance degradation as mentioned
11295         in PR53595.  Thus, report invalid hard registers as FALSE.  */
11296
11297   if (!avr_hard_regno_mode_ok (regno, mode))
11298     return 0;
11299
11300   /* Return true if any of the following boundaries is crossed:
11301      17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30.  */
11302
11303   return ((regno <= LAST_CALLEE_SAVED_REG &&
11304            regno + GET_MODE_SIZE (mode) > (LAST_CALLEE_SAVED_REG + 1))
11305           || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
11306           || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
11307 }
11308
11309
11310 /* Implement `MODE_CODE_BASE_REG_CLASS'.  */
11311
11312 enum reg_class
11313 avr_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
11314                               addr_space_t as, RTX_CODE outer_code,
11315                               RTX_CODE index_code ATTRIBUTE_UNUSED)
11316 {
11317   if (!ADDR_SPACE_GENERIC_P (as))
11318     {
11319       return POINTER_Z_REGS;
11320     }
11321
11322   if (!avr_strict_X)
11323     return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
11324
11325   return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
11326 }
11327
11328
11329 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'.  */
11330
11331 bool
11332 avr_regno_mode_code_ok_for_base_p (int regno,
11333                                    machine_mode mode ATTRIBUTE_UNUSED,
11334                                    addr_space_t as ATTRIBUTE_UNUSED,
11335                                    RTX_CODE outer_code,
11336                                    RTX_CODE index_code ATTRIBUTE_UNUSED)
11337 {
11338   bool ok = false;
11339
11340   if (!ADDR_SPACE_GENERIC_P (as))
11341     {
11342       if (regno < FIRST_PSEUDO_REGISTER
11343           && regno == REG_Z)
11344         {
11345           return true;
11346         }
11347
11348       if (reg_renumber)
11349         {
11350           regno = reg_renumber[regno];
11351
11352           if (regno == REG_Z)
11353             {
11354               return true;
11355             }
11356         }
11357
11358       return false;
11359     }
11360
11361   if (regno < FIRST_PSEUDO_REGISTER
11362       && (regno == REG_X
11363           || regno == REG_Y
11364           || regno == REG_Z
11365           || regno == ARG_POINTER_REGNUM))
11366     {
11367       ok = true;
11368     }
11369   else if (reg_renumber)
11370     {
11371       regno = reg_renumber[regno];
11372
11373       if (regno == REG_X
11374           || regno == REG_Y
11375           || regno == REG_Z
11376           || regno == ARG_POINTER_REGNUM)
11377         {
11378           ok = true;
11379         }
11380     }
11381
11382   if (avr_strict_X
11383       && PLUS == outer_code
11384       && regno == REG_X)
11385     {
11386       ok = false;
11387     }
11388
11389   return ok;
11390 }
11391
11392
11393 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
11394 /* Set 32-bit register OP[0] to compile-time constant OP[1].
11395    CLOBBER_REG is a QI clobber register or NULL_RTX.
11396    LEN == NULL: output instructions.
11397    LEN != NULL: set *LEN to the length of the instruction sequence
11398                 (in words) printed with LEN = NULL.
11399    If CLEAR_P is true, OP[0] had been cleard to Zero already.
11400    If CLEAR_P is false, nothing is known about OP[0].
11401
11402    The effect on cc0 is as follows:
11403
11404    Load 0 to any register except ZERO_REG : NONE
11405    Load ld register with any value        : NONE
11406    Anything else:                         : CLOBBER  */
11407
11408 static void
11409 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
11410 {
11411   rtx src = op[1];
11412   rtx dest = op[0];
11413   rtx xval, xdest[4];
11414   int ival[4];
11415   int clobber_val = 1234;
11416   bool cooked_clobber_p = false;
11417   bool set_p = false;
11418   machine_mode mode = GET_MODE (dest);
11419   int n, n_bytes = GET_MODE_SIZE (mode);
11420
11421   gcc_assert (REG_P (dest)
11422               && CONSTANT_P (src));
11423
11424   if (len)
11425     *len = 0;
11426
11427   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
11428      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
11429
11430   if (REGNO (dest) < 16
11431       && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
11432     {
11433       clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
11434     }
11435
11436   /* We might need a clobber reg but don't have one.  Look at the value to
11437      be loaded more closely.  A clobber is only needed if it is a symbol
11438      or contains a byte that is neither 0, -1 or a power of 2.  */
11439
11440   if (NULL_RTX == clobber_reg
11441       && !test_hard_reg_class (LD_REGS, dest)
11442       && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
11443           || !avr_popcount_each_byte (src, n_bytes,
11444                                       (1 << 0) | (1 << 1) | (1 << 8))))
11445     {
11446       /* We have no clobber register but need one.  Cook one up.
11447          That's cheaper than loading from constant pool.  */
11448
11449       cooked_clobber_p = true;
11450       clobber_reg = all_regs_rtx[REG_Z + 1];
11451       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
11452     }
11453
11454   /* Now start filling DEST from LSB to MSB.  */
11455
11456   for (n = 0; n < n_bytes; n++)
11457     {
11458       int ldreg_p;
11459       bool done_byte = false;
11460       int j;
11461       rtx xop[3];
11462
11463       /* Crop the n-th destination byte.  */
11464
11465       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
11466       ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
11467
11468       if (!CONST_INT_P (src)
11469           && !CONST_FIXED_P (src)
11470           && !CONST_DOUBLE_P (src))
11471         {
11472           static const char* const asm_code[][2] =
11473             {
11474               { "ldi %2,lo8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,lo8(%1)"  },
11475               { "ldi %2,hi8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,hi8(%1)"  },
11476               { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hlo8(%1)" },
11477               { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hhi8(%1)" }
11478             };
11479
11480           xop[0] = xdest[n];
11481           xop[1] = src;
11482           xop[2] = clobber_reg;
11483
11484           avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
11485
11486           continue;
11487         }
11488
11489       /* Crop the n-th source byte.  */
11490
11491       xval = simplify_gen_subreg (QImode, src, mode, n);
11492       ival[n] = INTVAL (xval);
11493
11494       /* Look if we can reuse the low word by means of MOVW.  */
11495
11496       if (n == 2
11497           && n_bytes >= 4
11498           && AVR_HAVE_MOVW)
11499         {
11500           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
11501           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
11502
11503           if (INTVAL (lo16) == INTVAL (hi16))
11504             {
11505               if (0 != INTVAL (lo16)
11506                   || !clear_p)
11507                 {
11508                   avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
11509                 }
11510
11511               break;
11512             }
11513         }
11514
11515       /* Don't use CLR so that cc0 is set as expected.  */
11516
11517       if (ival[n] == 0)
11518         {
11519           if (!clear_p)
11520             avr_asm_len (ldreg_p ? "ldi %0,0"
11521                          : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
11522                          : "mov %0,__zero_reg__",
11523                          &xdest[n], len, 1);
11524           continue;
11525         }
11526
11527       if (clobber_val == ival[n]
11528           && REGNO (clobber_reg) == REGNO (xdest[n]))
11529         {
11530           continue;
11531         }
11532
11533       /* LD_REGS can use LDI to move a constant value */
11534
11535       if (ldreg_p)
11536         {
11537           xop[0] = xdest[n];
11538           xop[1] = xval;
11539           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
11540           continue;
11541         }
11542
11543       /* Try to reuse value already loaded in some lower byte. */
11544
11545       for (j = 0; j < n; j++)
11546         if (ival[j] == ival[n])
11547           {
11548             xop[0] = xdest[n];
11549             xop[1] = xdest[j];
11550
11551             avr_asm_len ("mov %0,%1", xop, len, 1);
11552             done_byte = true;
11553             break;
11554           }
11555
11556       if (done_byte)
11557         continue;
11558
11559       /* Need no clobber reg for -1: Use CLR/DEC */
11560
11561       if (-1 == ival[n])
11562         {
11563           if (!clear_p)
11564             avr_asm_len ("clr %0", &xdest[n], len, 1);
11565
11566           avr_asm_len ("dec %0", &xdest[n], len, 1);
11567           continue;
11568         }
11569       else if (1 == ival[n])
11570         {
11571           if (!clear_p)
11572             avr_asm_len ("clr %0", &xdest[n], len, 1);
11573
11574           avr_asm_len ("inc %0", &xdest[n], len, 1);
11575           continue;
11576         }
11577
11578       /* Use T flag or INC to manage powers of 2 if we have
11579          no clobber reg.  */
11580
11581       if (NULL_RTX == clobber_reg
11582           && single_one_operand (xval, QImode))
11583         {
11584           xop[0] = xdest[n];
11585           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
11586
11587           gcc_assert (constm1_rtx != xop[1]);
11588
11589           if (!set_p)
11590             {
11591               set_p = true;
11592               avr_asm_len ("set", xop, len, 1);
11593             }
11594
11595           if (!clear_p)
11596             avr_asm_len ("clr %0", xop, len, 1);
11597
11598           avr_asm_len ("bld %0,%1", xop, len, 1);
11599           continue;
11600         }
11601
11602       /* We actually need the LD_REGS clobber reg.  */
11603
11604       gcc_assert (NULL_RTX != clobber_reg);
11605
11606       xop[0] = xdest[n];
11607       xop[1] = xval;
11608       xop[2] = clobber_reg;
11609       clobber_val = ival[n];
11610
11611       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
11612                    "mov %0,%2", xop, len, 2);
11613     }
11614
11615   /* If we cooked up a clobber reg above, restore it.  */
11616
11617   if (cooked_clobber_p)
11618     {
11619       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
11620     }
11621 }
11622
11623
11624 /* Reload the constant OP[1] into the HI register OP[0].
11625    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11626    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
11627    need a clobber reg or have to cook one up.
11628
11629    PLEN == NULL: Output instructions.
11630    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
11631                  by the insns printed.
11632
11633    Return "".  */
11634
11635 const char*
11636 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
11637 {
11638   output_reload_in_const (op, clobber_reg, plen, false);
11639   return "";
11640 }
11641
11642
11643 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
11644    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11645    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
11646    need a clobber reg or have to cook one up.
11647
11648    LEN == NULL: Output instructions.
11649
11650    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
11651                 by the insns printed.
11652
11653    Return "".  */
11654
11655 const char *
11656 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
11657 {
11658   if (AVR_HAVE_MOVW
11659       && !test_hard_reg_class (LD_REGS, op[0])
11660       && (CONST_INT_P (op[1])
11661           || CONST_FIXED_P (op[1])
11662           || CONST_DOUBLE_P (op[1])))
11663     {
11664       int len_clr, len_noclr;
11665
11666       /* In some cases it is better to clear the destination beforehand, e.g.
11667
11668              CLR R2   CLR R3   MOVW R4,R2   INC R2
11669
11670          is shorther than
11671
11672              CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
11673
11674          We find it too tedious to work that out in the print function.
11675          Instead, we call the print function twice to get the lengths of
11676          both methods and use the shortest one.  */
11677
11678       output_reload_in_const (op, clobber_reg, &len_clr, true);
11679       output_reload_in_const (op, clobber_reg, &len_noclr, false);
11680
11681       if (len_noclr - len_clr == 4)
11682         {
11683           /* Default needs 4 CLR instructions: clear register beforehand.  */
11684
11685           avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
11686                        "mov %B0,__zero_reg__" CR_TAB
11687                        "movw %C0,%A0", &op[0], len, 3);
11688
11689           output_reload_in_const (op, clobber_reg, len, true);
11690
11691           if (len)
11692             *len += 3;
11693
11694           return "";
11695         }
11696     }
11697
11698   /* Default: destination not pre-cleared.  */
11699
11700   output_reload_in_const (op, clobber_reg, len, false);
11701   return "";
11702 }
11703
11704 const char*
11705 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
11706 {
11707   output_reload_in_const (op, clobber_reg, len, false);
11708   return "";
11709 }
11710
11711
11712 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'.  */
11713
11714 void
11715 avr_output_addr_vec_elt (FILE *stream, int value)
11716 {
11717   if (AVR_HAVE_JMP_CALL)
11718     fprintf (stream, "\t.word gs(.L%d)\n", value);
11719   else
11720     fprintf (stream, "\trjmp .L%d\n", value);
11721 }
11722
11723 static void
11724 avr_conditional_register_usage(void)
11725 {
11726   if (AVR_TINY)
11727     {
11728       unsigned int i;
11729
11730       const int tiny_reg_alloc_order[] = {
11731         24, 25,
11732         22, 23,
11733         30, 31,
11734         26, 27,
11735         28, 29,
11736         21, 20, 19, 18,
11737         16, 17,
11738         32, 33, 34, 35,
11739         15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
11740       };
11741
11742       /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
11743          - R0-R15 are not available in Tiny Core devices
11744          - R16 and R17 are fixed registers.  */
11745
11746       for (i = 0;  i <= 17;  i++)
11747         {
11748           fixed_regs[i] = 1;
11749           call_used_regs[i] = 1;
11750         }
11751
11752       /* Set R18 to R21 as callee saved registers
11753          - R18, R19, R20 and R21 are the callee saved registers in
11754            Tiny Core devices  */
11755
11756       for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++)
11757         {
11758           call_used_regs[i] = 0;
11759         }
11760
11761       /* Update register allocation order for Tiny Core devices */
11762
11763       for (i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
11764         {
11765           reg_alloc_order[i] = tiny_reg_alloc_order[i];
11766         }
11767
11768       CLEAR_HARD_REG_SET (reg_class_contents[(int) ADDW_REGS]);
11769       CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
11770     }
11771 }
11772
11773 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'.  */
11774 /* Returns true if SCRATCH are safe to be allocated as a scratch
11775    registers (for a define_peephole2) in the current function.  */
11776
11777 static bool
11778 avr_hard_regno_scratch_ok (unsigned int regno)
11779 {
11780   /* Interrupt functions can only use registers that have already been saved
11781      by the prologue, even if they would normally be call-clobbered.  */
11782
11783   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11784       && !df_regs_ever_live_p (regno))
11785     return false;
11786
11787   /* Don't allow hard registers that might be part of the frame pointer.
11788      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11789      and don't care for a frame pointer that spans more than one register.  */
11790
11791   if ((!reload_completed || frame_pointer_needed)
11792       && (regno == REG_Y || regno == REG_Y + 1))
11793     {
11794       return false;
11795     }
11796
11797   return true;
11798 }
11799
11800
11801 /* Worker function for `HARD_REGNO_RENAME_OK'.  */
11802 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
11803
11804 int
11805 avr_hard_regno_rename_ok (unsigned int old_reg,
11806                           unsigned int new_reg)
11807 {
11808   /* Interrupt functions can only use registers that have already been
11809      saved by the prologue, even if they would normally be
11810      call-clobbered.  */
11811
11812   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11813       && !df_regs_ever_live_p (new_reg))
11814     return 0;
11815
11816   /* Don't allow hard registers that might be part of the frame pointer.
11817      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11818      and don't care for a frame pointer that spans more than one register.  */
11819
11820   if ((!reload_completed || frame_pointer_needed)
11821       && (old_reg == REG_Y || old_reg == REG_Y + 1
11822           || new_reg == REG_Y || new_reg == REG_Y + 1))
11823     {
11824       return 0;
11825     }
11826
11827   return 1;
11828 }
11829
11830 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
11831    or memory location in the I/O space (QImode only).
11832
11833    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
11834    Operand 1: register operand to test, or CONST_INT memory address.
11835    Operand 2: bit number.
11836    Operand 3: label to jump to if the test is true.  */
11837
11838 const char*
11839 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
11840 {
11841   enum rtx_code comp = GET_CODE (operands[0]);
11842   bool long_jump = get_attr_length (insn) >= 4;
11843   bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
11844
11845   if (comp == GE)
11846     comp = EQ;
11847   else if (comp == LT)
11848     comp = NE;
11849
11850   if (reverse)
11851     comp = reverse_condition (comp);
11852
11853   switch (GET_CODE (operands[1]))
11854     {
11855     default:
11856       gcc_unreachable();
11857
11858     case CONST_INT:
11859     case CONST:
11860     case SYMBOL_REF:
11861
11862       if (low_io_address_operand (operands[1], QImode))
11863         {
11864           if (comp == EQ)
11865             output_asm_insn ("sbis %i1,%2", operands);
11866           else
11867             output_asm_insn ("sbic %i1,%2", operands);
11868         }
11869       else
11870         {
11871           gcc_assert (io_address_operand (operands[1], QImode));
11872           output_asm_insn ("in __tmp_reg__,%i1", operands);
11873           if (comp == EQ)
11874             output_asm_insn ("sbrs __tmp_reg__,%2", operands);
11875           else
11876             output_asm_insn ("sbrc __tmp_reg__,%2", operands);
11877         }
11878
11879       break; /* CONST_INT */
11880
11881     case REG:
11882
11883       if (comp == EQ)
11884         output_asm_insn ("sbrs %T1%T2", operands);
11885       else
11886         output_asm_insn ("sbrc %T1%T2", operands);
11887
11888       break; /* REG */
11889     }        /* switch */
11890
11891   if (long_jump)
11892     return ("rjmp .+4" CR_TAB
11893             "jmp %x3");
11894
11895   if (!reverse)
11896     return "rjmp %x3";
11897
11898   return "";
11899 }
11900
11901 /* Worker function for `TARGET_ASM_CONSTRUCTOR'.  */
11902
11903 static void
11904 avr_asm_out_ctor (rtx symbol, int priority)
11905 {
11906   fputs ("\t.global __do_global_ctors\n", asm_out_file);
11907   default_ctor_section_asm_out_constructor (symbol, priority);
11908 }
11909
11910
11911 /* Worker function for `TARGET_ASM_DESTRUCTOR'.  */
11912
11913 static void
11914 avr_asm_out_dtor (rtx symbol, int priority)
11915 {
11916   fputs ("\t.global __do_global_dtors\n", asm_out_file);
11917   default_dtor_section_asm_out_destructor (symbol, priority);
11918 }
11919
11920
11921 /* Worker function for `TARGET_RETURN_IN_MEMORY'.  */
11922
11923 static bool
11924 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
11925 {
11926   HOST_WIDE_INT size = int_size_in_bytes (type);
11927   HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
11928
11929   /* In avr, there are 8 return registers. But, for Tiny Core
11930      (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
11931      Return true if size is unknown or greater than the limit.  */
11932
11933   if (size == -1 || size > ret_size_limit)
11934     {
11935       return true;
11936     }
11937   else
11938     {
11939       return false;
11940     }
11941 }
11942
11943
11944 /* Implement `CASE_VALUES_THRESHOLD'.  */
11945 /* Supply the default for --param case-values-threshold=0  */
11946
11947 static unsigned int
11948 avr_case_values_threshold (void)
11949 {
11950   /* The exact break-even point between a jump table and an if-else tree
11951      depends on several factors not available here like, e.g. if 8-bit
11952      comparisons can be used in the if-else tree or not, on the
11953      range of the case values, if the case value can be reused, on the
11954      register allocation, etc.  '7' appears to be a good choice.  */
11955
11956   return 7;
11957 }
11958
11959
11960 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'.  */
11961
11962 static machine_mode
11963 avr_addr_space_address_mode (addr_space_t as)
11964 {
11965   return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
11966 }
11967
11968
11969 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'.  */
11970
11971 static machine_mode
11972 avr_addr_space_pointer_mode (addr_space_t as)
11973 {
11974   return avr_addr_space_address_mode (as);
11975 }
11976
11977
11978 /* Helper for following function.  */
11979
11980 static bool
11981 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
11982 {
11983   gcc_assert (REG_P (reg));
11984
11985   if (strict)
11986     {
11987       return REGNO (reg) == REG_Z;
11988     }
11989
11990   /* Avoid combine to propagate hard regs.  */
11991
11992   if (can_create_pseudo_p()
11993       && REGNO (reg) < REG_Z)
11994     {
11995       return false;
11996     }
11997
11998   return true;
11999 }
12000
12001
12002 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'.  */
12003
12004 static bool
12005 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
12006                                      bool strict, addr_space_t as)
12007 {
12008   bool ok = false;
12009
12010   switch (as)
12011     {
12012     default:
12013       gcc_unreachable();
12014
12015     case ADDR_SPACE_GENERIC:
12016       return avr_legitimate_address_p (mode, x, strict);
12017
12018     case ADDR_SPACE_FLASH:
12019     case ADDR_SPACE_FLASH1:
12020     case ADDR_SPACE_FLASH2:
12021     case ADDR_SPACE_FLASH3:
12022     case ADDR_SPACE_FLASH4:
12023     case ADDR_SPACE_FLASH5:
12024
12025       switch (GET_CODE (x))
12026         {
12027         case REG:
12028           ok = avr_reg_ok_for_pgm_addr (x, strict);
12029           break;
12030
12031         case POST_INC:
12032           ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
12033           break;
12034
12035         default:
12036           break;
12037         }
12038
12039       break; /* FLASH */
12040
12041     case ADDR_SPACE_MEMX:
12042       if (REG_P (x))
12043         ok = (!strict
12044               && can_create_pseudo_p());
12045
12046       if (LO_SUM == GET_CODE (x))
12047         {
12048           rtx hi = XEXP (x, 0);
12049           rtx lo = XEXP (x, 1);
12050
12051           ok = (REG_P (hi)
12052                 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
12053                 && REG_P (lo)
12054                 && REGNO (lo) == REG_Z);
12055         }
12056
12057       break; /* MEMX */
12058     }
12059
12060   if (avr_log.legitimate_address_p)
12061     {
12062       avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
12063                  "reload_completed=%d reload_in_progress=%d %s:",
12064                  ok, mode, strict, reload_completed, reload_in_progress,
12065                  reg_renumber ? "(reg_renumber)" : "");
12066
12067       if (GET_CODE (x) == PLUS
12068           && REG_P (XEXP (x, 0))
12069           && CONST_INT_P (XEXP (x, 1))
12070           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
12071           && reg_renumber)
12072         {
12073           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
12074                      true_regnum (XEXP (x, 0)));
12075         }
12076
12077       avr_edump ("\n%r\n", x);
12078     }
12079
12080   return ok;
12081 }
12082
12083
12084 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'.  */
12085
12086 static rtx
12087 avr_addr_space_legitimize_address (rtx x, rtx old_x,
12088                                    machine_mode mode, addr_space_t as)
12089 {
12090   if (ADDR_SPACE_GENERIC_P (as))
12091     return avr_legitimize_address (x, old_x, mode);
12092
12093   if (avr_log.legitimize_address)
12094     {
12095       avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
12096     }
12097
12098   return old_x;
12099 }
12100
12101
12102 /* Implement `TARGET_ADDR_SPACE_CONVERT'.  */
12103
12104 static rtx
12105 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
12106 {
12107   addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
12108   addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
12109
12110   if (avr_log.progmem)
12111     avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
12112                src, type_from, type_to);
12113
12114   /* Up-casting from 16-bit to 24-bit pointer.  */
12115
12116   if (as_from != ADDR_SPACE_MEMX
12117       && as_to == ADDR_SPACE_MEMX)
12118     {
12119       int msb;
12120       rtx sym = src;
12121       rtx reg = gen_reg_rtx (PSImode);
12122
12123       while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
12124         sym = XEXP (sym, 0);
12125
12126       /* Look at symbol flags:  avr_encode_section_info set the flags
12127          also if attribute progmem was seen so that we get the right
12128          promotion for, e.g. PSTR-like strings that reside in generic space
12129          but are located in flash.  In that case we patch the incoming
12130          address space.  */
12131
12132       if (SYMBOL_REF == GET_CODE (sym)
12133           && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
12134         {
12135           as_from = ADDR_SPACE_FLASH;
12136         }
12137
12138       /* Linearize memory: RAM has bit 23 set.  */
12139
12140       msb = ADDR_SPACE_GENERIC_P (as_from)
12141         ? 0x80
12142         : avr_addrspace[as_from].segment;
12143
12144       src = force_reg (Pmode, src);
12145
12146       emit_insn (msb == 0
12147                  ? gen_zero_extendhipsi2 (reg, src)
12148                  : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
12149
12150       return reg;
12151     }
12152
12153   /* Down-casting from 24-bit to 16-bit throws away the high byte.  */
12154
12155   if (as_from == ADDR_SPACE_MEMX
12156       && as_to != ADDR_SPACE_MEMX)
12157     {
12158       rtx new_src = gen_reg_rtx (Pmode);
12159
12160       src = force_reg (PSImode, src);
12161
12162       emit_move_insn (new_src,
12163                       simplify_gen_subreg (Pmode, src, PSImode, 0));
12164       return new_src;
12165     }
12166
12167   return src;
12168 }
12169
12170
12171 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
12172
12173 static bool
12174 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
12175                          addr_space_t superset ATTRIBUTE_UNUSED)
12176 {
12177   /* Allow any kind of pointer mess.  */
12178
12179   return true;
12180 }
12181
12182
12183 /* Implement `TARGET_CONVERT_TO_TYPE'.  */
12184
12185 static tree
12186 avr_convert_to_type (tree type, tree expr)
12187 {
12188   /* Print a diagnose for pointer conversion that changes the address
12189      space of the pointer target to a non-enclosing address space,
12190      provided -Waddr-space-convert is on.
12191
12192      FIXME: Filter out cases where the target object is known to
12193             be located in the right memory, like in
12194
12195                 (const __flash*) PSTR ("text")
12196
12197             Also try to distinguish between explicit casts requested by
12198             the user and implicit casts like
12199
12200                 void f (const __flash char*);
12201
12202                 void g (const char *p)
12203                 {
12204                     f ((const __flash*) p);
12205                 }
12206
12207             under the assumption that an explicit casts means that the user
12208             knows what he is doing, e.g. interface with PSTR or old style
12209             code with progmem and pgm_read_xxx.
12210   */
12211
12212   if (avr_warn_addr_space_convert
12213       && expr != error_mark_node
12214       && POINTER_TYPE_P (type)
12215       && POINTER_TYPE_P (TREE_TYPE (expr)))
12216     {
12217       addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
12218       addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
12219
12220       if (avr_log.progmem)
12221         avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
12222
12223       if (as_new != ADDR_SPACE_MEMX
12224           && as_new != as_old)
12225         {
12226           location_t loc = EXPR_LOCATION (expr);
12227           const char *name_old = avr_addrspace[as_old].name;
12228           const char *name_new = avr_addrspace[as_new].name;
12229
12230           warning (OPT_Waddr_space_convert,
12231                    "conversion from address space %qs to address space %qs",
12232                    ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
12233                    ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
12234
12235           return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
12236         }
12237     }
12238
12239   return NULL_TREE;
12240 }
12241
12242
12243 /* PR63633: The middle-end might come up with hard regs as input operands.
12244
12245    RMASK is a bit mask representing a subset of hard registers R0...R31:
12246    Rn is an element of that set iff bit n of RMASK is set.
12247    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
12248    OP[n] has to be fixed; otherwise OP[n] is left alone.
12249
12250    For each element of OPMASK which is a hard register overlapping RMASK,
12251    replace OP[n] with a newly created pseudo register
12252
12253    HREG == 0:  Also emit a move insn that copies the contents of that
12254                hard register into the new pseudo.
12255
12256    HREG != 0:  Also set HREG[n] to the hard register.  */
12257
12258 static void
12259 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
12260 {
12261   for (; opmask; opmask >>= 1, op++)
12262     {
12263       rtx reg = *op;
12264
12265       if (hreg)
12266         *hreg = NULL_RTX;
12267
12268       if ((opmask & 1)
12269           && REG_P (reg)
12270           && REGNO (reg) < FIRST_PSEUDO_REGISTER
12271           // This hard-reg overlaps other prohibited hard regs?
12272           && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
12273         {
12274           *op = gen_reg_rtx (GET_MODE (reg));
12275           if (hreg == NULL)
12276             emit_move_insn (*op, reg);
12277           else
12278             *hreg = reg;
12279         }
12280
12281       if (hreg)
12282         hreg++;
12283     }
12284 }
12285
12286
12287 void
12288 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
12289 {
12290   avr_fix_operands (op, NULL, opmask, rmask);
12291 }
12292
12293
12294 /* Helper for the function below:  If bit n of MASK is set and
12295    HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
12296    Otherwise do nothing for that n.  Return TRUE.  */
12297
12298 static bool
12299 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
12300 {
12301   for (; mask; mask >>= 1, op++, hreg++)
12302     if ((mask & 1)
12303         && *hreg)
12304       emit_move_insn (*hreg, *op);
12305
12306   return true;
12307 }
12308
12309
12310 /* PR63633: The middle-end might come up with hard regs as output operands.
12311
12312    GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
12313    RMASK is a bit mask representing a subset of hard registers R0...R31:
12314    Rn is an element of that set iff bit n of RMASK is set.
12315    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
12316    OP[n] has to be fixed; otherwise OP[n] is left alone.
12317
12318    Emit the insn sequence as generated by GEN() with all elements of OPMASK
12319    which are hard registers overlapping RMASK replaced by newly created
12320    pseudo registers.  After the sequence has been emitted, emit insns that
12321    move the contents of respective pseudos to their hard regs.  */
12322
12323 bool
12324 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
12325                        unsigned opmask, unsigned rmask)
12326 {
12327   const int n = 3;
12328   rtx hreg[n];
12329
12330   /* It is letigimate for GEN to call this function, and in order not to
12331      get self-recursive we use the following static kludge.  This is the
12332      only way not to duplicate all expanders and to avoid ugly and
12333      hard-to-maintain C-code instead of the much more appreciated RTL
12334      representation as supplied by define_expand.  */
12335   static bool lock = false;
12336
12337   gcc_assert (opmask < (1u << n));
12338
12339   if (lock)
12340     return false;
12341
12342   avr_fix_operands (op, hreg, opmask, rmask);
12343
12344   lock = true;
12345   emit_insn (gen (op[0], op[1], op[2]));
12346   lock = false;
12347
12348   return avr_move_fixed_operands (op, hreg, opmask);
12349 }
12350
12351
12352 /* Worker function for movmemhi expander.
12353    XOP[0]  Destination as MEM:BLK
12354    XOP[1]  Source      "     "
12355    XOP[2]  # Bytes to copy
12356
12357    Return TRUE  if the expansion is accomplished.
12358    Return FALSE if the operand compination is not supported.  */
12359
12360 bool
12361 avr_emit_movmemhi (rtx *xop)
12362 {
12363   HOST_WIDE_INT count;
12364   machine_mode loop_mode;
12365   addr_space_t as = MEM_ADDR_SPACE (xop[1]);
12366   rtx loop_reg, addr1, a_src, a_dest, insn, xas;
12367   rtx a_hi8 = NULL_RTX;
12368
12369   if (avr_mem_flash_p (xop[0]))
12370     return false;
12371
12372   if (!CONST_INT_P (xop[2]))
12373     return false;
12374
12375   count = INTVAL (xop[2]);
12376   if (count <= 0)
12377     return false;
12378
12379   a_src  = XEXP (xop[1], 0);
12380   a_dest = XEXP (xop[0], 0);
12381
12382   if (PSImode == GET_MODE (a_src))
12383     {
12384       gcc_assert (as == ADDR_SPACE_MEMX);
12385
12386       loop_mode = (count < 0x100) ? QImode : HImode;
12387       loop_reg = gen_rtx_REG (loop_mode, 24);
12388       emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
12389
12390       addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
12391       a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
12392     }
12393   else
12394     {
12395       int segment = avr_addrspace[as].segment;
12396
12397       if (segment
12398           && avr_n_flash > 1)
12399         {
12400           a_hi8 = GEN_INT (segment);
12401           emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
12402         }
12403       else if (!ADDR_SPACE_GENERIC_P (as))
12404         {
12405           as = ADDR_SPACE_FLASH;
12406         }
12407
12408       addr1 = a_src;
12409
12410       loop_mode = (count <= 0x100) ? QImode : HImode;
12411       loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
12412     }
12413
12414   xas = GEN_INT (as);
12415
12416   /* FIXME: Register allocator might come up with spill fails if it is left
12417         on its own.  Thus, we allocate the pointer registers by hand:
12418         Z = source address
12419         X = destination address  */
12420
12421   emit_move_insn (lpm_addr_reg_rtx, addr1);
12422   emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
12423
12424   /* FIXME: Register allocator does a bad job and might spill address
12425         register(s) inside the loop leading to additional move instruction
12426         to/from stack which could clobber tmp_reg.  Thus, do *not* emit
12427         load and store as separate insns.  Instead, we perform the copy
12428         by means of one monolithic insn.  */
12429
12430   gcc_assert (TMP_REGNO == LPM_REGNO);
12431
12432   if (as != ADDR_SPACE_MEMX)
12433     {
12434       /* Load instruction ([E]LPM or LD) is known at compile time:
12435          Do the copy-loop inline.  */
12436
12437       rtx (*fun) (rtx, rtx, rtx)
12438         = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
12439
12440       insn = fun (xas, loop_reg, loop_reg);
12441     }
12442   else
12443     {
12444       rtx (*fun) (rtx, rtx)
12445         = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
12446
12447       emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
12448
12449       insn = fun (xas, GEN_INT (avr_addr.rampz));
12450     }
12451
12452   set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
12453   emit_insn (insn);
12454
12455   return true;
12456 }
12457
12458
12459 /* Print assembler for movmem_qi, movmem_hi insns...
12460        $0     : Address Space
12461        $1, $2 : Loop register
12462        Z      : Source address
12463        X      : Destination address
12464 */
12465
12466 const char*
12467 avr_out_movmem (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
12468 {
12469   addr_space_t as = (addr_space_t) INTVAL (op[0]);
12470   machine_mode loop_mode = GET_MODE (op[1]);
12471   bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
12472   rtx xop[3];
12473
12474   if (plen)
12475     *plen = 0;
12476
12477   xop[0] = op[0];
12478   xop[1] = op[1];
12479   xop[2] = tmp_reg_rtx;
12480
12481   /* Loop label */
12482
12483   avr_asm_len ("0:", xop, plen, 0);
12484
12485   /* Load with post-increment */
12486
12487   switch (as)
12488     {
12489     default:
12490       gcc_unreachable();
12491
12492     case ADDR_SPACE_GENERIC:
12493
12494       avr_asm_len ("ld %2,Z+", xop, plen, 1);
12495       break;
12496
12497     case ADDR_SPACE_FLASH:
12498
12499       if (AVR_HAVE_LPMX)
12500         avr_asm_len ("lpm %2,Z+", xop, plen, 1);
12501       else
12502         avr_asm_len ("lpm" CR_TAB
12503                      "adiw r30,1", xop, plen, 2);
12504       break;
12505
12506     case ADDR_SPACE_FLASH1:
12507     case ADDR_SPACE_FLASH2:
12508     case ADDR_SPACE_FLASH3:
12509     case ADDR_SPACE_FLASH4:
12510     case ADDR_SPACE_FLASH5:
12511
12512       if (AVR_HAVE_ELPMX)
12513         avr_asm_len ("elpm %2,Z+", xop, plen, 1);
12514       else
12515         avr_asm_len ("elpm" CR_TAB
12516                      "adiw r30,1", xop, plen, 2);
12517       break;
12518     }
12519
12520   /* Store with post-increment */
12521
12522   avr_asm_len ("st X+,%2", xop, plen, 1);
12523
12524   /* Decrement loop-counter and set Z-flag */
12525
12526   if (QImode == loop_mode)
12527     {
12528       avr_asm_len ("dec %1", xop, plen, 1);
12529     }
12530   else if (sbiw_p)
12531     {
12532       avr_asm_len ("sbiw %1,1", xop, plen, 1);
12533     }
12534   else
12535     {
12536       avr_asm_len ("subi %A1,1" CR_TAB
12537                    "sbci %B1,0", xop, plen, 2);
12538     }
12539
12540   /* Loop until zero */
12541
12542   return avr_asm_len ("brne 0b", xop, plen, 1);
12543 }
12544
12545
12546 \f
12547 /* Helper for __builtin_avr_delay_cycles */
12548
12549 static rtx
12550 avr_mem_clobber (void)
12551 {
12552   rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12553   MEM_VOLATILE_P (mem) = 1;
12554   return mem;
12555 }
12556
12557 static void
12558 avr_expand_delay_cycles (rtx operands0)
12559 {
12560   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
12561   unsigned HOST_WIDE_INT cycles_used;
12562   unsigned HOST_WIDE_INT loop_count;
12563
12564   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
12565     {
12566       loop_count = ((cycles - 9) / 6) + 1;
12567       cycles_used = ((loop_count - 1) * 6) + 9;
12568       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
12569                                      avr_mem_clobber()));
12570       cycles -= cycles_used;
12571     }
12572
12573   if (IN_RANGE (cycles, 262145, 83886081))
12574     {
12575       loop_count = ((cycles - 7) / 5) + 1;
12576       if (loop_count > 0xFFFFFF)
12577         loop_count = 0xFFFFFF;
12578       cycles_used = ((loop_count - 1) * 5) + 7;
12579       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
12580                                      avr_mem_clobber()));
12581       cycles -= cycles_used;
12582     }
12583
12584   if (IN_RANGE (cycles, 768, 262144))
12585     {
12586       loop_count = ((cycles - 5) / 4) + 1;
12587       if (loop_count > 0xFFFF)
12588         loop_count = 0xFFFF;
12589       cycles_used = ((loop_count - 1) * 4) + 5;
12590       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
12591                                      avr_mem_clobber()));
12592       cycles -= cycles_used;
12593     }
12594
12595   if (IN_RANGE (cycles, 6, 767))
12596     {
12597       loop_count = cycles / 3;
12598       if (loop_count > 255)
12599         loop_count = 255;
12600       cycles_used = loop_count * 3;
12601       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
12602                                      avr_mem_clobber()));
12603       cycles -= cycles_used;
12604       }
12605
12606   while (cycles >= 2)
12607     {
12608       emit_insn (gen_nopv (GEN_INT(2)));
12609       cycles -= 2;
12610     }
12611
12612   if (cycles == 1)
12613     {
12614       emit_insn (gen_nopv (GEN_INT(1)));
12615       cycles--;
12616     }
12617 }
12618
12619
12620 /* Compute the image of x under f, i.e. perform   x --> f(x)    */
12621
12622 static int
12623 avr_map (unsigned int f, int x)
12624 {
12625   return x < 8 ? (f >> (4 * x)) & 0xf : 0;
12626 }
12627
12628
12629 /* Return some metrics of map A.  */
12630
12631 enum
12632   {
12633     /* Number of fixed points in { 0 ... 7 } */
12634     MAP_FIXED_0_7,
12635
12636     /* Size of preimage of non-fixed points in { 0 ... 7 } */
12637     MAP_NONFIXED_0_7,
12638
12639     /* Mask representing the fixed points in { 0 ... 7 } */
12640     MAP_MASK_FIXED_0_7,
12641
12642     /* Size of the preimage of { 0 ... 7 } */
12643     MAP_PREIMAGE_0_7,
12644
12645     /* Mask that represents the preimage of { f } */
12646     MAP_MASK_PREIMAGE_F
12647   };
12648
12649 static unsigned
12650 avr_map_metric (unsigned int a, int mode)
12651 {
12652   unsigned i, metric = 0;
12653
12654   for (i = 0; i < 8; i++)
12655     {
12656       unsigned ai = avr_map (a, i);
12657
12658       if (mode == MAP_FIXED_0_7)
12659         metric += ai == i;
12660       else if (mode == MAP_NONFIXED_0_7)
12661         metric += ai < 8 && ai != i;
12662       else if (mode == MAP_MASK_FIXED_0_7)
12663         metric |= ((unsigned) (ai == i)) << i;
12664       else if (mode == MAP_PREIMAGE_0_7)
12665         metric += ai < 8;
12666       else if (mode == MAP_MASK_PREIMAGE_F)
12667         metric |= ((unsigned) (ai == 0xf)) << i;
12668       else
12669         gcc_unreachable();
12670     }
12671
12672   return metric;
12673 }
12674
12675
12676 /* Return true if IVAL has a 0xf in its hexadecimal representation
12677    and false, otherwise.  Only nibbles 0..7 are taken into account.
12678    Used as constraint helper for C0f and Cxf.  */
12679
12680 bool
12681 avr_has_nibble_0xf (rtx ival)
12682 {
12683   unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
12684   return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12685 }
12686
12687
12688 /* We have a set of bits that are mapped by a function F.
12689    Try to decompose F by means of a second function G so that
12690
12691       F = F o G^-1 o G
12692
12693    and
12694
12695       cost (F o G^-1) + cost (G)  <  cost (F)
12696
12697    Example:  Suppose builtin insert_bits supplies us with the map
12698    F = 0x3210ffff.  Instead of doing 4 bit insertions to get the high
12699    nibble of the result, we can just as well rotate the bits before inserting
12700    them and use the map 0x7654ffff which is cheaper than the original map.
12701    For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff.  */
12702
12703 typedef struct
12704 {
12705   /* tree code of binary function G */
12706   enum tree_code code;
12707
12708   /* The constant second argument of G */
12709   int arg;
12710
12711   /* G^-1, the inverse of G (*, arg) */
12712   unsigned ginv;
12713
12714   /* The cost of appplying G (*, arg) */
12715   int cost;
12716
12717   /* The composition F o G^-1 (*, arg) for some function F */
12718   unsigned int map;
12719
12720   /* For debug purpose only */
12721   const char *str;
12722 } avr_map_op_t;
12723
12724 static const avr_map_op_t avr_map_op[] =
12725   {
12726     { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
12727     { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
12728     { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
12729     { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
12730     { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
12731     { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
12732     { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
12733     { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
12734     { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
12735     { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
12736     { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
12737     { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
12738     { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
12739     { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
12740     { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
12741   };
12742
12743
12744 /* Try to decompose F as F = (F o G^-1) o G as described above.
12745    The result is a struct representing F o G^-1 and G.
12746    If result.cost < 0 then such a decomposition does not exist.  */
12747
12748 static avr_map_op_t
12749 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
12750 {
12751   int i;
12752   bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
12753   avr_map_op_t f_ginv = *g;
12754   unsigned int ginv = g->ginv;
12755
12756   f_ginv.cost = -1;
12757
12758   /* Step 1:  Computing F o G^-1  */
12759
12760   for (i = 7; i >= 0; i--)
12761     {
12762       int x = avr_map (f, i);
12763
12764       if (x <= 7)
12765         {
12766           x = avr_map (ginv, x);
12767
12768           /* The bit is no element of the image of G: no avail (cost = -1)  */
12769
12770           if (x > 7)
12771             return f_ginv;
12772         }
12773
12774       f_ginv.map = (f_ginv.map << 4) + x;
12775     }
12776
12777   /* Step 2:  Compute the cost of the operations.
12778      The overall cost of doing an operation prior to the insertion is
12779       the cost of the insertion plus the cost of the operation.  */
12780
12781   /* Step 2a:  Compute cost of F o G^-1  */
12782
12783   if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
12784     {
12785       /* The mapping consists only of fixed points and can be folded
12786          to AND/OR logic in the remainder.  Reasonable cost is 3. */
12787
12788       f_ginv.cost = 2 + (val_used_p && !val_const_p);
12789     }
12790   else
12791     {
12792       rtx xop[4];
12793
12794       /* Get the cost of the insn by calling the output worker with some
12795          fake values.  Mimic effect of reloading xop[3]: Unused operands
12796          are mapped to 0 and used operands are reloaded to xop[0].  */
12797
12798       xop[0] = all_regs_rtx[24];
12799       xop[1] = gen_int_mode (f_ginv.map, SImode);
12800       xop[2] = all_regs_rtx[25];
12801       xop[3] = val_used_p ? xop[0] : const0_rtx;
12802
12803       avr_out_insert_bits (xop, &f_ginv.cost);
12804
12805       f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
12806     }
12807
12808   /* Step 2b:  Add cost of G  */
12809
12810   f_ginv.cost += g->cost;
12811
12812   if (avr_log.builtin)
12813     avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
12814
12815   return f_ginv;
12816 }
12817
12818
12819 /* Insert bits from XOP[1] into XOP[0] according to MAP.
12820    XOP[0] and XOP[1] don't overlap.
12821    If FIXP_P = true:  Move all bits according to MAP using BLD/BST sequences.
12822    If FIXP_P = false: Just move the bit if its position in the destination
12823    is different to its source position.  */
12824
12825 static void
12826 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
12827 {
12828   int bit_dest, b;
12829
12830   /* T-flag contains this bit of the source, i.e. of XOP[1]  */
12831   int t_bit_src = -1;
12832
12833   /* We order the operations according to the requested source bit b.  */
12834
12835   for (b = 0; b < 8; b++)
12836     for (bit_dest = 0; bit_dest < 8; bit_dest++)
12837       {
12838         int bit_src = avr_map (map, bit_dest);
12839
12840         if (b != bit_src
12841             || bit_src >= 8
12842             /* Same position: No need to copy as requested by FIXP_P.  */
12843             || (bit_dest == bit_src && !fixp_p))
12844           continue;
12845
12846         if (t_bit_src != bit_src)
12847           {
12848             /* Source bit is not yet in T: Store it to T.  */
12849
12850             t_bit_src = bit_src;
12851
12852             xop[3] = GEN_INT (bit_src);
12853             avr_asm_len ("bst %T1%T3", xop, plen, 1);
12854           }
12855
12856         /* Load destination bit with T.  */
12857
12858         xop[3] = GEN_INT (bit_dest);
12859         avr_asm_len ("bld %T0%T3", xop, plen, 1);
12860       }
12861 }
12862
12863
12864 /* PLEN == 0: Print assembler code for `insert_bits'.
12865    PLEN != 0: Compute code length in bytes.
12866
12867    OP[0]:  Result
12868    OP[1]:  The mapping composed of nibbles. If nibble no. N is
12869            0:   Bit N of result is copied from bit OP[2].0
12870            ...  ...
12871            7:   Bit N of result is copied from bit OP[2].7
12872            0xf: Bit N of result is copied from bit OP[3].N
12873    OP[2]:  Bits to be inserted
12874    OP[3]:  Target value  */
12875
12876 const char*
12877 avr_out_insert_bits (rtx *op, int *plen)
12878 {
12879   unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
12880   unsigned mask_fixed;
12881   bool fixp_p = true;
12882   rtx xop[4];
12883
12884   xop[0] = op[0];
12885   xop[1] = op[2];
12886   xop[2] = op[3];
12887
12888   gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
12889
12890   if (plen)
12891     *plen = 0;
12892   else if (flag_print_asm_name)
12893     fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
12894
12895   /* If MAP has fixed points it might be better to initialize the result
12896      with the bits to be inserted instead of moving all bits by hand.  */
12897
12898   mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
12899
12900   if (REGNO (xop[0]) == REGNO (xop[1]))
12901     {
12902       /* Avoid early-clobber conflicts */
12903
12904       avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
12905       xop[1] = tmp_reg_rtx;
12906       fixp_p = false;
12907     }
12908
12909   if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12910     {
12911       /* XOP[2] is used and reloaded to XOP[0] already */
12912
12913       int n_fix = 0, n_nofix = 0;
12914
12915       gcc_assert (REG_P (xop[2]));
12916
12917       /* Get the code size of the bit insertions; once with all bits
12918          moved and once with fixed points omitted.  */
12919
12920       avr_move_bits (xop, map, true, &n_fix);
12921       avr_move_bits (xop, map, false, &n_nofix);
12922
12923       if (fixp_p && n_fix - n_nofix > 3)
12924         {
12925           xop[3] = gen_int_mode (~mask_fixed, QImode);
12926
12927           avr_asm_len ("eor %0,%1"   CR_TAB
12928                        "andi %0,%3"  CR_TAB
12929                        "eor %0,%1", xop, plen, 3);
12930           fixp_p = false;
12931         }
12932     }
12933   else
12934     {
12935       /* XOP[2] is unused */
12936
12937       if (fixp_p && mask_fixed)
12938         {
12939           avr_asm_len ("mov %0,%1", xop, plen, 1);
12940           fixp_p = false;
12941         }
12942     }
12943
12944   /* Move/insert remaining bits.  */
12945
12946   avr_move_bits (xop, map, fixp_p, plen);
12947
12948   return "";
12949 }
12950
12951
12952 /* IDs for all the AVR builtins.  */
12953
12954 enum avr_builtin_id
12955   {
12956 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
12957     AVR_BUILTIN_ ## NAME,
12958 #include "builtins.def"
12959 #undef DEF_BUILTIN
12960
12961     AVR_BUILTIN_COUNT
12962   };
12963
12964 struct GTY(()) avr_builtin_description
12965 {
12966   enum insn_code icode;
12967   int n_args;
12968   tree fndecl;
12969 };
12970
12971
12972 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
12973    that a built-in's ID can be used to access the built-in by means of
12974    avr_bdesc[ID]  */
12975
12976 static GTY(()) struct avr_builtin_description
12977 avr_bdesc[AVR_BUILTIN_COUNT] =
12978   {
12979 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME)         \
12980     { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
12981 #include "builtins.def"
12982 #undef DEF_BUILTIN
12983   };
12984
12985
12986 /* Implement `TARGET_BUILTIN_DECL'.  */
12987
12988 static tree
12989 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
12990 {
12991   if (id < AVR_BUILTIN_COUNT)
12992     return avr_bdesc[id].fndecl;
12993
12994   return error_mark_node;
12995 }
12996
12997
12998 static void
12999 avr_init_builtin_int24 (void)
13000 {
13001   tree int24_type  = make_signed_type (GET_MODE_BITSIZE (PSImode));
13002   tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
13003
13004   lang_hooks.types.register_builtin_type (int24_type, "__int24");
13005   lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
13006 }
13007
13008
13009 /* Implement `TARGET_INIT_BUILTINS' */
13010 /* Set up all builtin functions for this target.  */
13011
13012 static void
13013 avr_init_builtins (void)
13014 {
13015   tree void_ftype_void
13016     = build_function_type_list (void_type_node, NULL_TREE);
13017   tree uchar_ftype_uchar
13018     = build_function_type_list (unsigned_char_type_node,
13019                                 unsigned_char_type_node,
13020                                 NULL_TREE);
13021   tree uint_ftype_uchar_uchar
13022     = build_function_type_list (unsigned_type_node,
13023                                 unsigned_char_type_node,
13024                                 unsigned_char_type_node,
13025                                 NULL_TREE);
13026   tree int_ftype_char_char
13027     = build_function_type_list (integer_type_node,
13028                                 char_type_node,
13029                                 char_type_node,
13030                                 NULL_TREE);
13031   tree int_ftype_char_uchar
13032     = build_function_type_list (integer_type_node,
13033                                 char_type_node,
13034                                 unsigned_char_type_node,
13035                                 NULL_TREE);
13036   tree void_ftype_ulong
13037     = build_function_type_list (void_type_node,
13038                                 long_unsigned_type_node,
13039                                 NULL_TREE);
13040
13041   tree uchar_ftype_ulong_uchar_uchar
13042     = build_function_type_list (unsigned_char_type_node,
13043                                 long_unsigned_type_node,
13044                                 unsigned_char_type_node,
13045                                 unsigned_char_type_node,
13046                                 NULL_TREE);
13047
13048   tree const_memx_void_node
13049     = build_qualified_type (void_type_node,
13050                             TYPE_QUAL_CONST
13051                             | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
13052
13053   tree const_memx_ptr_type_node
13054     = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
13055
13056   tree char_ftype_const_memx_ptr
13057     = build_function_type_list (char_type_node,
13058                                 const_memx_ptr_type_node,
13059                                 NULL);
13060
13061 #define ITYP(T)                                                         \
13062   lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
13063
13064 #define FX_FTYPE_FX(fx)                                                 \
13065   tree fx##r_ftype_##fx##r                                              \
13066     = build_function_type_list (node_##fx##r, node_##fx##r, NULL);      \
13067   tree fx##k_ftype_##fx##k                                              \
13068     = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
13069
13070 #define FX_FTYPE_FX_INT(fx)                                             \
13071   tree fx##r_ftype_##fx##r_int                                          \
13072     = build_function_type_list (node_##fx##r, node_##fx##r,             \
13073                                 integer_type_node, NULL);               \
13074   tree fx##k_ftype_##fx##k_int                                          \
13075     = build_function_type_list (node_##fx##k, node_##fx##k,             \
13076                                 integer_type_node, NULL)
13077
13078 #define INT_FTYPE_FX(fx)                                                \
13079   tree int_ftype_##fx##r                                                \
13080     = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
13081   tree int_ftype_##fx##k                                                \
13082     = build_function_type_list (integer_type_node, node_##fx##k, NULL)
13083
13084 #define INTX_FTYPE_FX(fx)                                               \
13085   tree int##fx##r_ftype_##fx##r                                         \
13086     = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
13087   tree int##fx##k_ftype_##fx##k                                         \
13088     = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
13089
13090 #define FX_FTYPE_INTX(fx)                                               \
13091   tree fx##r_ftype_int##fx##r                                           \
13092     = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
13093   tree fx##k_ftype_int##fx##k                                           \
13094     = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
13095
13096   tree node_hr = short_fract_type_node;
13097   tree node_nr = fract_type_node;
13098   tree node_lr = long_fract_type_node;
13099   tree node_llr = long_long_fract_type_node;
13100
13101   tree node_uhr = unsigned_short_fract_type_node;
13102   tree node_unr = unsigned_fract_type_node;
13103   tree node_ulr = unsigned_long_fract_type_node;
13104   tree node_ullr = unsigned_long_long_fract_type_node;
13105
13106   tree node_hk = short_accum_type_node;
13107   tree node_nk = accum_type_node;
13108   tree node_lk = long_accum_type_node;
13109   tree node_llk = long_long_accum_type_node;
13110
13111   tree node_uhk = unsigned_short_accum_type_node;
13112   tree node_unk = unsigned_accum_type_node;
13113   tree node_ulk = unsigned_long_accum_type_node;
13114   tree node_ullk = unsigned_long_long_accum_type_node;
13115
13116
13117   /* For absfx builtins.  */
13118
13119   FX_FTYPE_FX (h);
13120   FX_FTYPE_FX (n);
13121   FX_FTYPE_FX (l);
13122   FX_FTYPE_FX (ll);
13123
13124   /* For roundfx builtins.  */
13125
13126   FX_FTYPE_FX_INT (h);
13127   FX_FTYPE_FX_INT (n);
13128   FX_FTYPE_FX_INT (l);
13129   FX_FTYPE_FX_INT (ll);
13130
13131   FX_FTYPE_FX_INT (uh);
13132   FX_FTYPE_FX_INT (un);
13133   FX_FTYPE_FX_INT (ul);
13134   FX_FTYPE_FX_INT (ull);
13135
13136   /* For countlsfx builtins.  */
13137
13138   INT_FTYPE_FX (h);
13139   INT_FTYPE_FX (n);
13140   INT_FTYPE_FX (l);
13141   INT_FTYPE_FX (ll);
13142
13143   INT_FTYPE_FX (uh);
13144   INT_FTYPE_FX (un);
13145   INT_FTYPE_FX (ul);
13146   INT_FTYPE_FX (ull);
13147
13148   /* For bitsfx builtins.  */
13149
13150   INTX_FTYPE_FX (h);
13151   INTX_FTYPE_FX (n);
13152   INTX_FTYPE_FX (l);
13153   INTX_FTYPE_FX (ll);
13154
13155   INTX_FTYPE_FX (uh);
13156   INTX_FTYPE_FX (un);
13157   INTX_FTYPE_FX (ul);
13158   INTX_FTYPE_FX (ull);
13159
13160   /* For fxbits builtins.  */
13161
13162   FX_FTYPE_INTX (h);
13163   FX_FTYPE_INTX (n);
13164   FX_FTYPE_INTX (l);
13165   FX_FTYPE_INTX (ll);
13166
13167   FX_FTYPE_INTX (uh);
13168   FX_FTYPE_INTX (un);
13169   FX_FTYPE_INTX (ul);
13170   FX_FTYPE_INTX (ull);
13171
13172
13173 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)                  \
13174   {                                                                     \
13175     int id = AVR_BUILTIN_ ## NAME;                                      \
13176     const char *Name = "__builtin_avr_" #NAME;                          \
13177     char *name = (char*) alloca (1 + strlen (Name));                    \
13178                                                                         \
13179     gcc_assert (id < AVR_BUILTIN_COUNT);                                \
13180     avr_bdesc[id].fndecl                                                \
13181       = add_builtin_function (avr_tolower (name, Name), TYPE, id,       \
13182                               BUILT_IN_MD, LIBNAME, NULL_TREE);         \
13183   }
13184 #include "builtins.def"
13185 #undef DEF_BUILTIN
13186
13187   avr_init_builtin_int24 ();
13188 }
13189
13190
13191 /* Subroutine of avr_expand_builtin to expand vanilla builtins
13192    with non-void result and 1 ... 3 arguments.  */
13193
13194 static rtx
13195 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
13196 {
13197   rtx pat, xop[3];
13198   int n, n_args = call_expr_nargs (exp);
13199   machine_mode tmode = insn_data[icode].operand[0].mode;
13200
13201   gcc_assert (n_args >= 1 && n_args <= 3);
13202
13203   if (target == NULL_RTX
13204       || GET_MODE (target) != tmode
13205       || !insn_data[icode].operand[0].predicate (target, tmode))
13206     {
13207       target = gen_reg_rtx (tmode);
13208     }
13209
13210   for (n = 0; n < n_args; n++)
13211     {
13212       tree arg = CALL_EXPR_ARG (exp, n);
13213       rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13214       machine_mode opmode = GET_MODE (op);
13215       machine_mode mode = insn_data[icode].operand[n+1].mode;
13216
13217       if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
13218         {
13219           opmode = HImode;
13220           op = gen_lowpart (HImode, op);
13221         }
13222
13223       /* In case the insn wants input operands in modes different from
13224          the result, abort.  */
13225
13226       gcc_assert (opmode == mode || opmode == VOIDmode);
13227
13228       if (!insn_data[icode].operand[n+1].predicate (op, mode))
13229         op = copy_to_mode_reg (mode, op);
13230
13231       xop[n] = op;
13232     }
13233
13234   switch (n_args)
13235     {
13236     case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
13237     case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
13238     case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
13239
13240     default:
13241       gcc_unreachable();
13242     }
13243
13244   if (pat == NULL_RTX)
13245     return NULL_RTX;
13246
13247   emit_insn (pat);
13248
13249   return target;
13250 }
13251
13252
13253 /* Implement `TARGET_EXPAND_BUILTIN'.  */
13254 /* Expand an expression EXP that calls a built-in function,
13255    with result going to TARGET if that's convenient
13256    (and in mode MODE if that's convenient).
13257    SUBTARGET may be used as the target for computing one of EXP's operands.
13258    IGNORE is nonzero if the value is to be ignored.  */
13259
13260 static rtx
13261 avr_expand_builtin (tree exp, rtx target,
13262                     rtx subtarget ATTRIBUTE_UNUSED,
13263                     machine_mode mode ATTRIBUTE_UNUSED,
13264                     int ignore)
13265 {
13266   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
13267   const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
13268   unsigned int id = DECL_FUNCTION_CODE (fndecl);
13269   const struct avr_builtin_description *d = &avr_bdesc[id];
13270   tree arg0;
13271   rtx op0;
13272
13273   gcc_assert (id < AVR_BUILTIN_COUNT);
13274
13275   switch (id)
13276     {
13277     case AVR_BUILTIN_NOP:
13278       emit_insn (gen_nopv (GEN_INT(1)));
13279       return 0;
13280
13281     case AVR_BUILTIN_DELAY_CYCLES:
13282       {
13283         arg0 = CALL_EXPR_ARG (exp, 0);
13284         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13285
13286         if (!CONST_INT_P (op0))
13287           error ("%s expects a compile time integer constant", bname);
13288         else
13289           avr_expand_delay_cycles (op0);
13290
13291         return NULL_RTX;
13292       }
13293
13294     case AVR_BUILTIN_INSERT_BITS:
13295       {
13296         arg0 = CALL_EXPR_ARG (exp, 0);
13297         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13298
13299         if (!CONST_INT_P (op0))
13300           {
13301             error ("%s expects a compile time long integer constant"
13302                    " as first argument", bname);
13303             return target;
13304           }
13305
13306         break;
13307       }
13308
13309     case AVR_BUILTIN_ROUNDHR:   case AVR_BUILTIN_ROUNDUHR:
13310     case AVR_BUILTIN_ROUNDR:    case AVR_BUILTIN_ROUNDUR:
13311     case AVR_BUILTIN_ROUNDLR:   case AVR_BUILTIN_ROUNDULR:
13312     case AVR_BUILTIN_ROUNDLLR:  case AVR_BUILTIN_ROUNDULLR:
13313
13314     case AVR_BUILTIN_ROUNDHK:   case AVR_BUILTIN_ROUNDUHK:
13315     case AVR_BUILTIN_ROUNDK:    case AVR_BUILTIN_ROUNDUK:
13316     case AVR_BUILTIN_ROUNDLK:   case AVR_BUILTIN_ROUNDULK:
13317     case AVR_BUILTIN_ROUNDLLK:  case AVR_BUILTIN_ROUNDULLK:
13318
13319       /* Warn about odd rounding.  Rounding points >= FBIT will have
13320          no effect.  */
13321
13322       if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
13323         break;
13324
13325       int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
13326
13327       if (rbit >= (int) GET_MODE_FBIT (mode))
13328         {
13329           warning (OPT_Wextra, "rounding to %d bits has no effect for "
13330                    "fixed-point value with %d fractional bits",
13331                    rbit, GET_MODE_FBIT (mode));
13332
13333           return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
13334                               EXPAND_NORMAL);
13335         }
13336       else if (rbit <= - (int) GET_MODE_IBIT (mode))
13337         {
13338           warning (0, "rounding result will always be 0");
13339           return CONST0_RTX (mode);
13340         }
13341
13342       /* The rounding points RP satisfies now:  -IBIT < RP < FBIT.
13343
13344          TR 18037 only specifies results for  RP > 0.  However, the
13345          remaining cases of  -IBIT < RP <= 0  can easily be supported
13346          without any additional overhead.  */
13347
13348       break; /* round */
13349     }
13350
13351   /* No fold found and no insn:  Call support function from libgcc.  */
13352
13353   if (d->icode == CODE_FOR_nothing
13354       && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
13355     {
13356       return expand_call (exp, target, ignore);
13357     }
13358
13359   /* No special treatment needed: vanilla expand.  */
13360
13361   gcc_assert (d->icode != CODE_FOR_nothing);
13362   gcc_assert (d->n_args == call_expr_nargs (exp));
13363
13364   if (d->n_args == 0)
13365     {
13366       emit_insn ((GEN_FCN (d->icode)) (target));
13367       return NULL_RTX;
13368     }
13369
13370   return avr_default_expand_builtin (d->icode, exp, target);
13371 }
13372
13373
13374 /* Helper for `avr_fold_builtin' that folds  absfx (FIXED_CST).  */
13375
13376 static tree
13377 avr_fold_absfx (tree tval)
13378 {
13379   if (FIXED_CST != TREE_CODE (tval))
13380     return NULL_TREE;
13381
13382   /* Our fixed-points have no padding:  Use double_int payload directly.  */
13383
13384   FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
13385   unsigned int bits = GET_MODE_BITSIZE (fval.mode);
13386   double_int ival = fval.data.sext (bits);
13387
13388   if (!ival.is_negative())
13389     return tval;
13390
13391   /* ISO/IEC TR 18037, 7.18a.6.2:  The absfx functions are saturating.  */
13392
13393   fval.data = (ival == double_int::min_value (bits, false).sext (bits))
13394     ? double_int::max_value (bits, false)
13395     : -ival;
13396
13397   return build_fixed (TREE_TYPE (tval), fval);
13398 }
13399
13400
13401 /* Implement `TARGET_FOLD_BUILTIN'.  */
13402
13403 static tree
13404 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
13405                   bool ignore ATTRIBUTE_UNUSED)
13406 {
13407   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13408   tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
13409
13410   if (!optimize)
13411     return NULL_TREE;
13412
13413   switch (fcode)
13414     {
13415     default:
13416       break;
13417
13418     case AVR_BUILTIN_SWAP:
13419       {
13420         return fold_build2 (LROTATE_EXPR, val_type, arg[0],
13421                             build_int_cst (val_type, 4));
13422       }
13423
13424     case AVR_BUILTIN_ABSHR:
13425     case AVR_BUILTIN_ABSR:
13426     case AVR_BUILTIN_ABSLR:
13427     case AVR_BUILTIN_ABSLLR:
13428
13429     case AVR_BUILTIN_ABSHK:
13430     case AVR_BUILTIN_ABSK:
13431     case AVR_BUILTIN_ABSLK:
13432     case AVR_BUILTIN_ABSLLK:
13433       /* GCC is not good with folding ABS for fixed-point.  Do it by hand.  */
13434
13435       return avr_fold_absfx (arg[0]);
13436
13437     case AVR_BUILTIN_BITSHR:    case AVR_BUILTIN_HRBITS:
13438     case AVR_BUILTIN_BITSHK:    case AVR_BUILTIN_HKBITS:
13439     case AVR_BUILTIN_BITSUHR:   case AVR_BUILTIN_UHRBITS:
13440     case AVR_BUILTIN_BITSUHK:   case AVR_BUILTIN_UHKBITS:
13441
13442     case AVR_BUILTIN_BITSR:     case AVR_BUILTIN_RBITS:
13443     case AVR_BUILTIN_BITSK:     case AVR_BUILTIN_KBITS:
13444     case AVR_BUILTIN_BITSUR:    case AVR_BUILTIN_URBITS:
13445     case AVR_BUILTIN_BITSUK:    case AVR_BUILTIN_UKBITS:
13446
13447     case AVR_BUILTIN_BITSLR:    case AVR_BUILTIN_LRBITS:
13448     case AVR_BUILTIN_BITSLK:    case AVR_BUILTIN_LKBITS:
13449     case AVR_BUILTIN_BITSULR:   case AVR_BUILTIN_ULRBITS:
13450     case AVR_BUILTIN_BITSULK:   case AVR_BUILTIN_ULKBITS:
13451
13452     case AVR_BUILTIN_BITSLLR:   case AVR_BUILTIN_LLRBITS:
13453     case AVR_BUILTIN_BITSLLK:   case AVR_BUILTIN_LLKBITS:
13454     case AVR_BUILTIN_BITSULLR:  case AVR_BUILTIN_ULLRBITS:
13455     case AVR_BUILTIN_BITSULLK:  case AVR_BUILTIN_ULLKBITS:
13456
13457       gcc_assert (TYPE_PRECISION (val_type)
13458                   == TYPE_PRECISION (TREE_TYPE (arg[0])));
13459
13460       return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
13461
13462     case AVR_BUILTIN_INSERT_BITS:
13463       {
13464         tree tbits = arg[1];
13465         tree tval = arg[2];
13466         tree tmap;
13467         tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
13468         unsigned int map;
13469         bool changed = false;
13470         unsigned i;
13471         avr_map_op_t best_g;
13472
13473         if (TREE_CODE (arg[0]) != INTEGER_CST)
13474           {
13475             /* No constant as first argument: Don't fold this and run into
13476                error in avr_expand_builtin.  */
13477
13478             break;
13479           }
13480
13481         tmap = wide_int_to_tree (map_type, arg[0]);
13482         map = TREE_INT_CST_LOW (tmap);
13483
13484         if (TREE_CODE (tval) != INTEGER_CST
13485             && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
13486           {
13487             /* There are no F in the map, i.e. 3rd operand is unused.
13488                Replace that argument with some constant to render
13489                respective input unused.  */
13490
13491             tval = build_int_cst (val_type, 0);
13492             changed = true;
13493           }
13494
13495         if (TREE_CODE (tbits) != INTEGER_CST
13496             && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
13497           {
13498             /* Similar for the bits to be inserted. If they are unused,
13499                we can just as well pass 0.  */
13500
13501             tbits = build_int_cst (val_type, 0);
13502           }
13503
13504         if (TREE_CODE (tbits) == INTEGER_CST)
13505           {
13506             /* Inserting bits known at compile time is easy and can be
13507                performed by AND and OR with appropriate masks.  */
13508
13509             int bits = TREE_INT_CST_LOW (tbits);
13510             int mask_ior = 0, mask_and = 0xff;
13511
13512             for (i = 0; i < 8; i++)
13513               {
13514                 int mi = avr_map (map, i);
13515
13516                 if (mi < 8)
13517                   {
13518                     if (bits & (1 << mi))     mask_ior |=  (1 << i);
13519                     else                      mask_and &= ~(1 << i);
13520                   }
13521               }
13522
13523             tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
13524                                 build_int_cst (val_type, mask_ior));
13525             return fold_build2 (BIT_AND_EXPR, val_type, tval,
13526                                 build_int_cst (val_type, mask_and));
13527           }
13528
13529         if (changed)
13530           return build_call_expr (fndecl, 3, tmap, tbits, tval);
13531
13532         /* If bits don't change their position we can use vanilla logic
13533            to merge the two arguments.  */
13534
13535         if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
13536           {
13537             int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
13538             tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
13539
13540             tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
13541             tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
13542             return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
13543           }
13544
13545         /* Try to decomposing map to reduce overall cost.  */
13546
13547         if (avr_log.builtin)
13548           avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
13549
13550         best_g = avr_map_op[0];
13551         best_g.cost = 1000;
13552
13553         for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
13554           {
13555             avr_map_op_t g
13556               = avr_map_decompose (map, avr_map_op + i,
13557                                    TREE_CODE (tval) == INTEGER_CST);
13558
13559             if (g.cost >= 0 && g.cost < best_g.cost)
13560               best_g = g;
13561           }
13562
13563         if (avr_log.builtin)
13564           avr_edump ("\n");
13565
13566         if (best_g.arg == 0)
13567           /* No optimization found */
13568           break;
13569
13570         /* Apply operation G to the 2nd argument.  */
13571
13572         if (avr_log.builtin)
13573           avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
13574                      best_g.str, best_g.arg, best_g.map, best_g.cost);
13575
13576         /* Do right-shifts arithmetically: They copy the MSB instead of
13577            shifting in a non-usable value (0) as with logic right-shift.  */
13578
13579         tbits = fold_convert (signed_char_type_node, tbits);
13580         tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
13581                              build_int_cst (val_type, best_g.arg));
13582         tbits = fold_convert (val_type, tbits);
13583
13584         /* Use map o G^-1 instead of original map to undo the effect of G.  */
13585
13586         tmap = wide_int_to_tree (map_type, best_g.map);
13587
13588         return build_call_expr (fndecl, 3, tmap, tbits, tval);
13589       } /* AVR_BUILTIN_INSERT_BITS */
13590     }
13591
13592   return NULL_TREE;
13593 }
13594
13595 \f
13596
13597 /* Initialize the GCC target structure.  */
13598
13599 #undef  TARGET_ASM_ALIGNED_HI_OP
13600 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13601 #undef  TARGET_ASM_ALIGNED_SI_OP
13602 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
13603 #undef  TARGET_ASM_UNALIGNED_HI_OP
13604 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
13605 #undef  TARGET_ASM_UNALIGNED_SI_OP
13606 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
13607 #undef  TARGET_ASM_INTEGER
13608 #define TARGET_ASM_INTEGER avr_assemble_integer
13609 #undef  TARGET_ASM_FILE_START
13610 #define TARGET_ASM_FILE_START avr_file_start
13611 #undef  TARGET_ASM_FILE_END
13612 #define TARGET_ASM_FILE_END avr_file_end
13613
13614 #undef  TARGET_ASM_FUNCTION_END_PROLOGUE
13615 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
13616 #undef  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
13617 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
13618
13619 #undef  TARGET_FUNCTION_VALUE
13620 #define TARGET_FUNCTION_VALUE avr_function_value
13621 #undef  TARGET_LIBCALL_VALUE
13622 #define TARGET_LIBCALL_VALUE avr_libcall_value
13623 #undef  TARGET_FUNCTION_VALUE_REGNO_P
13624 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
13625
13626 #undef  TARGET_ATTRIBUTE_TABLE
13627 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
13628 #undef  TARGET_INSERT_ATTRIBUTES
13629 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
13630 #undef  TARGET_SECTION_TYPE_FLAGS
13631 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
13632
13633 #undef  TARGET_ASM_NAMED_SECTION
13634 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
13635 #undef  TARGET_ASM_INIT_SECTIONS
13636 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
13637 #undef  TARGET_ENCODE_SECTION_INFO
13638 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
13639 #undef  TARGET_ASM_SELECT_SECTION
13640 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
13641
13642 #undef  TARGET_REGISTER_MOVE_COST
13643 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
13644 #undef  TARGET_MEMORY_MOVE_COST
13645 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
13646 #undef  TARGET_RTX_COSTS
13647 #define TARGET_RTX_COSTS avr_rtx_costs
13648 #undef  TARGET_ADDRESS_COST
13649 #define TARGET_ADDRESS_COST avr_address_cost
13650 #undef  TARGET_MACHINE_DEPENDENT_REORG
13651 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
13652 #undef  TARGET_FUNCTION_ARG
13653 #define TARGET_FUNCTION_ARG avr_function_arg
13654 #undef  TARGET_FUNCTION_ARG_ADVANCE
13655 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
13656
13657 #undef  TARGET_SET_CURRENT_FUNCTION
13658 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
13659
13660 #undef  TARGET_RETURN_IN_MEMORY
13661 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
13662
13663 #undef  TARGET_STRICT_ARGUMENT_NAMING
13664 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13665
13666 #undef  TARGET_BUILTIN_SETJMP_FRAME_VALUE
13667 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
13668
13669 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13670 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
13671
13672 #undef  TARGET_HARD_REGNO_SCRATCH_OK
13673 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
13674 #undef  TARGET_CASE_VALUES_THRESHOLD
13675 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
13676
13677 #undef  TARGET_FRAME_POINTER_REQUIRED
13678 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
13679 #undef  TARGET_CAN_ELIMINATE
13680 #define TARGET_CAN_ELIMINATE avr_can_eliminate
13681
13682 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
13683 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
13684
13685 #undef TARGET_WARN_FUNC_RETURN
13686 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
13687
13688 #undef  TARGET_CLASS_LIKELY_SPILLED_P
13689 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
13690
13691 #undef  TARGET_OPTION_OVERRIDE
13692 #define TARGET_OPTION_OVERRIDE avr_option_override
13693
13694 #undef  TARGET_CANNOT_MODIFY_JUMPS_P
13695 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
13696
13697 #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
13698 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
13699
13700 #undef  TARGET_INIT_BUILTINS
13701 #define TARGET_INIT_BUILTINS avr_init_builtins
13702
13703 #undef  TARGET_BUILTIN_DECL
13704 #define TARGET_BUILTIN_DECL avr_builtin_decl
13705
13706 #undef  TARGET_EXPAND_BUILTIN
13707 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
13708
13709 #undef  TARGET_FOLD_BUILTIN
13710 #define TARGET_FOLD_BUILTIN avr_fold_builtin
13711
13712 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
13713 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
13714
13715 #undef  TARGET_BUILD_BUILTIN_VA_LIST
13716 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
13717
13718 #undef  TARGET_FIXED_POINT_SUPPORTED_P
13719 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
13720
13721 #undef  TARGET_CONVERT_TO_TYPE
13722 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
13723
13724 #undef  TARGET_ADDR_SPACE_SUBSET_P
13725 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
13726
13727 #undef  TARGET_ADDR_SPACE_CONVERT
13728 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
13729
13730 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
13731 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
13732
13733 #undef  TARGET_ADDR_SPACE_POINTER_MODE
13734 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
13735
13736 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
13737 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P  \
13738   avr_addr_space_legitimate_address_p
13739
13740 #undef  TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
13741 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
13742
13743 #undef  TARGET_MODE_DEPENDENT_ADDRESS_P
13744 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
13745
13746 #undef  TARGET_SECONDARY_RELOAD
13747 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
13748
13749 #undef  TARGET_PRINT_OPERAND
13750 #define TARGET_PRINT_OPERAND avr_print_operand
13751 #undef  TARGET_PRINT_OPERAND_ADDRESS
13752 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
13753 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
13754 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
13755
13756 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
13757 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
13758   avr_use_by_pieces_infrastructure_p
13759
13760 struct gcc_target targetm = TARGET_INITIALIZER;
13761
13762 \f
13763 #include "gt-avr.h"