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 "intl.h"
24 #include "coretypes.h"
25 #include "backend.h"
26 #include "target.h"
27 #include "rtl.h"
28 #include "tree.h"
29 #include "cgraph.h"
30 #include "c-family/c-common.h"
31 #include "cfghooks.h"
32 #include "df.h"
33 #include "tm_p.h"
34 #include "optabs.h"
35 #include "regs.h"
36 #include "emit-rtl.h"
37 #include "recog.h"
38 #include "conditions.h"
39 #include "insn-attr.h"
40 #include "reload.h"
41 #include "varasm.h"
42 #include "calls.h"
43 #include "stor-layout.h"
44 #include "output.h"
45 #include "explow.h"
46 #include "expr.h"
47 #include "langhooks.h"
48 #include "cfgrtl.h"
49 #include "params.h"
50 #include "builtins.h"
51 #include "context.h"
52 #include "tree-pass.h"
53 
54 /* This file should be included last.  */
55 #include "target-def.h"
56 
57 /* Maximal allowed offset for an address in the LD command */
58 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
59 
60 /* Return true if STR starts with PREFIX and false, otherwise.  */
61 #define STR_PREFIX_P(STR,PREFIX) (0 == strncmp (STR, PREFIX, strlen (PREFIX)))
62 
63 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
64    address space where data is to be located.
65    As the only non-generic address spaces are all located in flash,
66    this can be used to test if data shall go into some .progmem* section.
67    This must be the rightmost field of machine dependent section flags.  */
68 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
69 
70 /* Similar 4-bit region for SYMBOL_REF_FLAGS.  */
71 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
72 
73 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
74    Set address-space AS in SYMBOL_REF_FLAGS of SYM  */
75 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS)                       \
76   do {                                                          \
77     SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM;         \
78     SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP;      \
79   } while (0)
80 
81 /* Read address-space from SYMBOL_REF_FLAGS of SYM  */
82 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM)                          \
83   ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM)           \
84    / SYMBOL_FLAG_MACH_DEP)
85 
86 #define TINY_ADIW(REG1, REG2, I)                                \
87     "subi " #REG1 ",lo8(-(" #I "))" CR_TAB                      \
88     "sbci " #REG2 ",hi8(-(" #I "))"
89 
90 #define TINY_SBIW(REG1, REG2, I)                                \
91     "subi " #REG1 ",lo8((" #I "))" CR_TAB                       \
92     "sbci " #REG2 ",hi8((" #I "))"
93 
94 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
95 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
96 
97 /* Known address spaces.  The order must be the same as in the respective
98    enum from avr.h (or designated initialized must be used).  */
99 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
100 {
101   { ADDR_SPACE_RAM,  0, 2, "", 0, NULL },
102   { ADDR_SPACE_FLASH,  1, 2, "__flash",   0, ".progmem.data" },
103   { ADDR_SPACE_FLASH1, 1, 2, "__flash1",  1, ".progmem1.data" },
104   { ADDR_SPACE_FLASH2, 1, 2, "__flash2",  2, ".progmem2.data" },
105   { ADDR_SPACE_FLASH3, 1, 2, "__flash3",  3, ".progmem3.data" },
106   { ADDR_SPACE_FLASH4, 1, 2, "__flash4",  4, ".progmem4.data" },
107   { ADDR_SPACE_FLASH5, 1, 2, "__flash5",  5, ".progmem5.data" },
108   { ADDR_SPACE_MEMX, 1, 3, "__memx",  0, ".progmemx.data" },
109 };
110 
111 
112 /* Holding RAM addresses of some SFRs used by the compiler and that
113    are unique over all devices in an architecture like 'avr4'.  */
114 
115 typedef struct
116 {
117   /* SREG: The processor status */
118   int sreg;
119 
120   /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
121   int ccp;
122   int rampd;
123   int rampx;
124   int rampy;
125 
126   /* RAMPZ: The high byte of 24-bit address used with ELPM */
127   int rampz;
128 
129   /* SP: The stack pointer and its low and high byte */
130   int sp_l;
131   int sp_h;
132 } avr_addr_t;
133 
134 static avr_addr_t avr_addr;
135 
136 
137 /* Prototypes for local helper functions.  */
138 
139 static const char* out_movqi_r_mr (rtx_insn *, rtx[], int*);
140 static const char* out_movhi_r_mr (rtx_insn *, rtx[], int*);
141 static const char* out_movsi_r_mr (rtx_insn *, rtx[], int*);
142 static const char* out_movqi_mr_r (rtx_insn *, rtx[], int*);
143 static const char* out_movhi_mr_r (rtx_insn *, rtx[], int*);
144 static const char* out_movsi_mr_r (rtx_insn *, rtx[], int*);
145 
146 static int get_sequence_length (rtx_insn *insns);
147 static int sequent_regs_live (void);
148 static const char *ptrreg_to_str (int);
149 static const char *cond_string (enum rtx_code);
150 static int avr_num_arg_regs (machine_mode, const_tree);
151 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
152                                  int, bool);
153 static void output_reload_in_const (rtx*, rtx, int*, bool);
154 static struct machine_function * avr_init_machine_status (void);
155 
156 
157 /* Prototypes for hook implementors if needed before their implementation.  */
158 
159 static bool avr_rtx_costs (rtx, machine_mode, int, int, int*, bool);
160 
161 
162 /* Allocate registers from r25 to r8 for parameters for function calls.  */
163 #define FIRST_CUM_REG 26
164 
165 /* Last call saved register */
166 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? 19 : 17)
167 
168 /* Implicit target register of LPM instruction (R0) */
169 extern GTY(()) rtx lpm_reg_rtx;
170 rtx lpm_reg_rtx;
171 
172 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
173 extern GTY(()) rtx lpm_addr_reg_rtx;
174 rtx lpm_addr_reg_rtx;
175 
176 /* Temporary register RTX (reg:QI TMP_REGNO) */
177 extern GTY(()) rtx tmp_reg_rtx;
178 rtx tmp_reg_rtx;
179 
180 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
181 extern GTY(()) rtx zero_reg_rtx;
182 rtx zero_reg_rtx;
183 
184 /* RTXs for all general purpose registers as QImode */
185 extern GTY(()) rtx all_regs_rtx[32];
186 rtx all_regs_rtx[32];
187 
188 /* SREG, the processor status */
189 extern GTY(()) rtx sreg_rtx;
190 rtx sreg_rtx;
191 
192 /* RAMP* special function registers */
193 extern GTY(()) rtx rampd_rtx;
194 extern GTY(()) rtx rampx_rtx;
195 extern GTY(()) rtx rampy_rtx;
196 extern GTY(()) rtx rampz_rtx;
197 rtx rampd_rtx;
198 rtx rampx_rtx;
199 rtx rampy_rtx;
200 rtx rampz_rtx;
201 
202 /* RTX containing the strings "" and "e", respectively */
203 static GTY(()) rtx xstring_empty;
204 static GTY(()) rtx xstring_e;
205 
206 /* Current architecture.  */
207 const avr_arch_t *avr_arch;
208 
209 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
210    or to address space __flash* or __memx.  Only used as singletons inside
211    avr_asm_select_section, but it must not be local there because of GTY.  */
212 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
213 
214 /* Condition for insns/expanders from avr-dimode.md.  */
215 bool avr_have_dimode = true;
216 
217 /* To track if code will use .bss and/or .data.  */
218 bool avr_need_clear_bss_p = false;
219 bool avr_need_copy_data_p = false;
220 
221 
222 /* Transform UP into lowercase and write the result to LO.
223    You must provide enough space for LO.  Return LO.  */
224 
225 static char*
avr_tolower(char * lo,const char * up)226 avr_tolower (char *lo, const char *up)
227 {
228   char *lo0 = lo;
229 
230   for (; *up; up++, lo++)
231     *lo = TOLOWER (*up);
232 
233   *lo = '\0';
234 
235   return lo0;
236 }
237 
238 
239 /* Custom function to count number of set bits.  */
240 
241 static inline int
avr_popcount(unsigned int val)242 avr_popcount (unsigned int val)
243 {
244   int pop = 0;
245 
246   while (val)
247     {
248       val &= val-1;
249       pop++;
250     }
251 
252   return pop;
253 }
254 
255 
256 /* Constraint helper function.  XVAL is a CONST_INT or a CONST_DOUBLE.
257    Return true if the least significant N_BYTES bytes of XVAL all have a
258    popcount in POP_MASK and false, otherwise.  POP_MASK represents a subset
259    of integers which contains an integer N iff bit N of POP_MASK is set.  */
260 
261 bool
avr_popcount_each_byte(rtx xval,int n_bytes,int pop_mask)262 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
263 {
264   int i;
265 
266   machine_mode mode = GET_MODE (xval);
267 
268   if (VOIDmode == mode)
269     mode = SImode;
270 
271   for (i = 0; i < n_bytes; i++)
272     {
273       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
274       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
275 
276       if (0 == (pop_mask & (1 << avr_popcount (val8))))
277         return false;
278     }
279 
280   return true;
281 }
282 
283 
284 /* Access some RTX as INT_MODE.  If X is a CONST_FIXED we can get
285    the bit representation of X by "casting" it to CONST_INT.  */
286 
287 rtx
avr_to_int_mode(rtx x)288 avr_to_int_mode (rtx x)
289 {
290   machine_mode mode = GET_MODE (x);
291 
292   return VOIDmode == mode
293     ? x
294     : simplify_gen_subreg (int_mode_for_mode (mode), x, mode, 0);
295 }
296 
297 
298 static const pass_data avr_pass_data_recompute_notes =
299 {
300   RTL_PASS,      // type
301   "",            // name (will be patched)
302   OPTGROUP_NONE, // optinfo_flags
303   TV_DF_SCAN,    // tv_id
304   0,             // properties_required
305   0,             // properties_provided
306   0,             // properties_destroyed
307   0,             // todo_flags_start
308   TODO_df_finish | TODO_df_verify // todo_flags_finish
309 };
310 
311 
312 class avr_pass_recompute_notes : public rtl_opt_pass
313 {
314 public:
avr_pass_recompute_notes(gcc::context * ctxt,const char * name)315   avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
316     : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
317   {
318     this->name = name;
319   }
320 
execute(function *)321   virtual unsigned int execute (function*)
322   {
323     df_note_add_problem ();
324     df_analyze ();
325 
326     return 0;
327   }
328 }; // avr_pass_recompute_notes
329 
330 
331 static void
avr_register_passes(void)332 avr_register_passes (void)
333 {
334   /* This avr-specific pass (re)computes insn notes, in particular REG_DEAD
335      notes which are used by `avr.c::reg_unused_after' and branch offset
336      computations.  These notes must be correct, i.e. there must be no
337      dangling REG_DEAD notes; otherwise wrong code might result, cf. PR64331.
338 
339      DF needs (correct) CFG, hence right before free_cfg is the last
340      opportunity to rectify notes.  */
341 
342   register_pass (new avr_pass_recompute_notes (g, "avr-notes-free-cfg"),
343                  PASS_POS_INSERT_BEFORE, "*free_cfg", 1);
344 }
345 
346 
347 /* Set `avr_arch' as specified by `-mmcu='.
348    Return true on success.  */
349 
350 static bool
avr_set_core_architecture(void)351 avr_set_core_architecture (void)
352 {
353   /* Search for mcu core architecture.  */
354 
355   if (!avr_mmcu)
356     avr_mmcu = AVR_MMCU_DEFAULT;
357 
358   avr_arch = &avr_arch_types[0];
359 
360   for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
361     {
362       if (NULL == mcu->name)
363         {
364           /* Reached the end of `avr_mcu_types'.  This should actually never
365              happen as options are provided by device-specs.  It could be a
366              typo in a device-specs or calling the compiler proper directly
367              with -mmcu=<device>. */
368 
369           error ("unknown core architecture %qs specified with %qs",
370                  avr_mmcu, "-mmcu=");
371           avr_inform_core_architectures ();
372           break;
373         }
374       else if (0 == strcmp (mcu->name, avr_mmcu)
375                // Is this a proper architecture ?
376                && NULL == mcu->macro)
377         {
378           avr_arch = &avr_arch_types[mcu->arch_id];
379           if (avr_n_flash < 0)
380             avr_n_flash = mcu->n_flash;
381 
382           return true;
383         }
384     }
385 
386   return false;
387 }
388 
389 
390 /* Implement `TARGET_OPTION_OVERRIDE'.  */
391 
392 static void
avr_option_override(void)393 avr_option_override (void)
394 {
395   /* Disable -fdelete-null-pointer-checks option for AVR target.
396      This option compiler assumes that dereferencing of a null pointer
397      would halt the program.  For AVR this assumption is not true and
398      programs can safely dereference null pointers.  Changes made by this
399      option may not work properly for AVR.  So disable this option. */
400 
401   flag_delete_null_pointer_checks = 0;
402 
403   /* caller-save.c looks for call-clobbered hard registers that are assigned
404      to pseudos that cross calls and tries so save-restore them around calls
405      in order to reduce the number of stack slots needed.
406 
407      This might lead to situations where reload is no more able to cope
408      with the challenge of AVR's very few address registers and fails to
409      perform the requested spills.  */
410 
411   if (avr_strict_X)
412     flag_caller_saves = 0;
413 
414   /* Allow optimizer to introduce store data races. This used to be the
415      default - it was changed because bigger targets did not see any
416      performance decrease. For the AVR though, disallowing data races
417      introduces additional code in LIM and increases reg pressure.  */
418 
419   maybe_set_param_value (PARAM_ALLOW_STORE_DATA_RACES, 1,
420       global_options.x_param_values,
421       global_options_set.x_param_values);
422 
423   /* Unwind tables currently require a frame pointer for correctness,
424      see toplev.c:process_options().  */
425 
426   if ((flag_unwind_tables
427        || flag_non_call_exceptions
428        || flag_asynchronous_unwind_tables)
429       && !ACCUMULATE_OUTGOING_ARGS)
430     {
431       flag_omit_frame_pointer = 0;
432     }
433 
434   if (flag_pic == 1)
435     warning (OPT_fpic, "-fpic is not supported");
436   if (flag_pic == 2)
437     warning (OPT_fPIC, "-fPIC is not supported");
438   if (flag_pie == 1)
439     warning (OPT_fpie, "-fpie is not supported");
440   if (flag_pie == 2)
441     warning (OPT_fPIE, "-fPIE is not supported");
442 
443   if (!avr_set_core_architecture())
444     return;
445 
446   /* RAM addresses of some SFRs common to all devices in respective arch. */
447 
448   /* SREG: Status Register containing flags like I (global IRQ) */
449   avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
450 
451   /* RAMPZ: Address' high part when loading via ELPM */
452   avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
453 
454   avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
455   avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
456   avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
457   avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
458 
459   /* SP: Stack Pointer (SP_H:SP_L) */
460   avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
461   avr_addr.sp_h = avr_addr.sp_l + 1;
462 
463   init_machine_status = avr_init_machine_status;
464 
465   avr_log_set_avr_log();
466 
467   /* Register some avr-specific pass(es).  There is no canonical place for
468      pass registration.  This function is convenient.  */
469 
470   avr_register_passes ();
471 }
472 
473 /* Function to set up the backend function structure.  */
474 
475 static struct machine_function *
avr_init_machine_status(void)476 avr_init_machine_status (void)
477 {
478   return ggc_cleared_alloc<machine_function> ();
479 }
480 
481 
482 /* Implement `INIT_EXPANDERS'.  */
483 /* The function works like a singleton.  */
484 
485 void
avr_init_expanders(void)486 avr_init_expanders (void)
487 {
488   int regno;
489 
490   for (regno = 0; regno < 32; regno ++)
491     all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
492 
493   lpm_reg_rtx  = all_regs_rtx[LPM_REGNO];
494   tmp_reg_rtx  = all_regs_rtx[AVR_TMP_REGNO];
495   zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
496 
497   lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
498 
499   sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
500   rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
501   rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
502   rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
503   rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
504 
505   xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
506   xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
507 
508   /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
509      to be present */
510   if (AVR_TINY)
511     avr_have_dimode = false;
512 }
513 
514 
515 /* Implement `REGNO_REG_CLASS'.  */
516 /* Return register class for register R.  */
517 
518 enum reg_class
avr_regno_reg_class(int r)519 avr_regno_reg_class (int r)
520 {
521   static const enum reg_class reg_class_tab[] =
522     {
523       R0_REG,
524       /* r1 - r15 */
525       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
526       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
527       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
528       NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
529       /* r16 - r23 */
530       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
531       SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
532       /* r24, r25 */
533       ADDW_REGS, ADDW_REGS,
534       /* X: r26, 27 */
535       POINTER_X_REGS, POINTER_X_REGS,
536       /* Y: r28, r29 */
537       POINTER_Y_REGS, POINTER_Y_REGS,
538       /* Z: r30, r31 */
539       POINTER_Z_REGS, POINTER_Z_REGS,
540       /* SP: SPL, SPH */
541       STACK_REG, STACK_REG
542     };
543 
544   if (r <= 33)
545     return reg_class_tab[r];
546 
547   return ALL_REGS;
548 }
549 
550 
551 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'.  */
552 
553 static bool
avr_scalar_mode_supported_p(machine_mode mode)554 avr_scalar_mode_supported_p (machine_mode mode)
555 {
556   if (ALL_FIXED_POINT_MODE_P (mode))
557     return true;
558 
559   if (PSImode == mode)
560     return true;
561 
562   return default_scalar_mode_supported_p (mode);
563 }
564 
565 
566 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise.  */
567 
568 static bool
avr_decl_flash_p(tree decl)569 avr_decl_flash_p (tree decl)
570 {
571   if (TREE_CODE (decl) != VAR_DECL
572       || TREE_TYPE (decl) == error_mark_node)
573     {
574       return false;
575     }
576 
577   return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
578 }
579 
580 
581 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
582    address space and FALSE, otherwise.  */
583 
584 static bool
avr_decl_memx_p(tree decl)585 avr_decl_memx_p (tree decl)
586 {
587   if (TREE_CODE (decl) != VAR_DECL
588       || TREE_TYPE (decl) == error_mark_node)
589     {
590       return false;
591     }
592 
593   return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
594 }
595 
596 
597 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise.  */
598 
599 bool
avr_mem_flash_p(rtx x)600 avr_mem_flash_p (rtx x)
601 {
602   return (MEM_P (x)
603           && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
604 }
605 
606 
607 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
608    address space and FALSE, otherwise.  */
609 
610 bool
avr_mem_memx_p(rtx x)611 avr_mem_memx_p (rtx x)
612 {
613   return (MEM_P (x)
614           && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
615 }
616 
617 
618 /* A helper for the subsequent function attribute used to dig for
619    attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
620 
621 static inline int
avr_lookup_function_attribute1(const_tree func,const char * name)622 avr_lookup_function_attribute1 (const_tree func, const char *name)
623 {
624   if (FUNCTION_DECL == TREE_CODE (func))
625     {
626       if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
627         {
628           return true;
629         }
630 
631       func = TREE_TYPE (func);
632     }
633 
634   gcc_assert (TREE_CODE (func) == FUNCTION_TYPE
635               || TREE_CODE (func) == METHOD_TYPE);
636 
637   return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
638 }
639 
640 /* Return nonzero if FUNC is a naked function.  */
641 
642 static int
avr_naked_function_p(tree func)643 avr_naked_function_p (tree func)
644 {
645   return avr_lookup_function_attribute1 (func, "naked");
646 }
647 
648 /* Return nonzero if FUNC is an interrupt function as specified
649    by the "interrupt" attribute.  */
650 
651 static int
avr_interrupt_function_p(tree func)652 avr_interrupt_function_p (tree func)
653 {
654   return avr_lookup_function_attribute1 (func, "interrupt");
655 }
656 
657 /* Return nonzero if FUNC is a signal function as specified
658    by the "signal" attribute.  */
659 
660 static int
avr_signal_function_p(tree func)661 avr_signal_function_p (tree func)
662 {
663   return avr_lookup_function_attribute1 (func, "signal");
664 }
665 
666 /* Return nonzero if FUNC is an OS_task function.  */
667 
668 static int
avr_OS_task_function_p(tree func)669 avr_OS_task_function_p (tree func)
670 {
671   return avr_lookup_function_attribute1 (func, "OS_task");
672 }
673 
674 /* Return nonzero if FUNC is an OS_main function.  */
675 
676 static int
avr_OS_main_function_p(tree func)677 avr_OS_main_function_p (tree func)
678 {
679   return avr_lookup_function_attribute1 (func, "OS_main");
680 }
681 
682 
683 /* Implement `TARGET_SET_CURRENT_FUNCTION'.  */
684 /* Sanity cheching for above function attributes.  */
685 
686 static void
avr_set_current_function(tree decl)687 avr_set_current_function (tree decl)
688 {
689   location_t loc;
690   const char *isr;
691 
692   if (decl == NULL_TREE
693       || current_function_decl == NULL_TREE
694       || current_function_decl == error_mark_node
695       || ! cfun->machine
696       || cfun->machine->attributes_checked_p)
697     return;
698 
699   loc = DECL_SOURCE_LOCATION (decl);
700 
701   cfun->machine->is_naked = avr_naked_function_p (decl);
702   cfun->machine->is_signal = avr_signal_function_p (decl);
703   cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
704   cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
705   cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
706 
707   isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
708 
709   /* Too much attributes make no sense as they request conflicting features. */
710 
711   if (cfun->machine->is_OS_task + cfun->machine->is_OS_main
712       + (cfun->machine->is_signal || cfun->machine->is_interrupt) > 1)
713     error_at (loc, "function attributes %qs, %qs and %qs are mutually"
714                " exclusive", "OS_task", "OS_main", isr);
715 
716   /* 'naked' will hide effects of 'OS_task' and 'OS_main'.  */
717 
718   if (cfun->machine->is_naked
719       && (cfun->machine->is_OS_task || cfun->machine->is_OS_main))
720     warning_at (loc, OPT_Wattributes, "function attributes %qs and %qs have"
721                 " no effect on %qs function", "OS_task", "OS_main", "naked");
722 
723   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
724     {
725       tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
726       tree ret = TREE_TYPE (TREE_TYPE (decl));
727       const char *name;
728 
729       name = DECL_ASSEMBLER_NAME_SET_P (decl)
730         ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
731         : IDENTIFIER_POINTER (DECL_NAME (decl));
732 
733       /* Skip a leading '*' that might still prefix the assembler name,
734          e.g. in non-LTO runs.  */
735 
736       name = default_strip_name_encoding (name);
737 
738       /* Interrupt handlers must be  void __vector (void)  functions.  */
739 
740       if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
741         error_at (loc, "%qs function cannot have arguments", isr);
742 
743       if (TREE_CODE (ret) != VOID_TYPE)
744         error_at (loc, "%qs function cannot return a value", isr);
745 
746 #if defined WITH_AVRLIBC
747       /* Silently ignore 'signal' if 'interrupt' is present.  AVR-LibC startet
748          using this when it switched from SIGNAL and INTERRUPT to ISR.  */
749 
750       if (cfun->machine->is_interrupt)
751         cfun->machine->is_signal = 0;
752 
753       /* If the function has the 'signal' or 'interrupt' attribute, ensure
754          that the name of the function is "__vector_NN" so as to catch
755          when the user misspells the vector name.  */
756 
757       if (!STR_PREFIX_P (name, "__vector"))
758         warning_at (loc, OPT_Wmisspelled_isr, "%qs appears to be a misspelled "
759                     "%qs handler, missing %<__vector%> prefix", name, isr);
760 #endif // AVR-LibC naming conventions
761     }
762 
763 #if defined WITH_AVRLIBC
764   // Common problem is using "ISR" without first including avr/interrupt.h.
765   const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
766   name = default_strip_name_encoding (name);
767   if (0 == strcmp ("ISR", name)
768       || 0 == strcmp ("INTERRUPT", name)
769       || 0 == strcmp ("SIGNAL", name))
770     {
771       warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier"
772                   " in AVR-LibC.  Consider %<#include <avr/interrupt.h>%>"
773                   " before using the %qs macro", name, name);
774     }
775 #endif // AVR-LibC naming conventions
776 
777   /* Don't print the above diagnostics more than once.  */
778 
779   cfun->machine->attributes_checked_p = 1;
780 }
781 
782 
783 /* Implement `ACCUMULATE_OUTGOING_ARGS'.  */
784 
785 int
avr_accumulate_outgoing_args(void)786 avr_accumulate_outgoing_args (void)
787 {
788   if (!cfun)
789     return TARGET_ACCUMULATE_OUTGOING_ARGS;
790 
791   /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
792         what offset is correct.  In some cases it is relative to
793         virtual_outgoing_args_rtx and in others it is relative to
794         virtual_stack_vars_rtx.  For example code see
795             gcc.c-torture/execute/built-in-setjmp.c
796             gcc.c-torture/execute/builtins/sprintf-chk.c   */
797 
798   return (TARGET_ACCUMULATE_OUTGOING_ARGS
799           && !(cfun->calls_setjmp
800                || cfun->has_nonlocal_label));
801 }
802 
803 
804 /* Report contribution of accumulated outgoing arguments to stack size.  */
805 
806 static inline int
avr_outgoing_args_size(void)807 avr_outgoing_args_size (void)
808 {
809   return ACCUMULATE_OUTGOING_ARGS ? crtl->outgoing_args_size : 0;
810 }
811 
812 
813 /* Implement `STARTING_FRAME_OFFSET'.  */
814 /* This is the offset from the frame pointer register to the first stack slot
815    that contains a variable living in the frame.  */
816 
817 int
avr_starting_frame_offset(void)818 avr_starting_frame_offset (void)
819 {
820   return 1 + avr_outgoing_args_size ();
821 }
822 
823 
824 /* Return the number of hard registers to push/pop in the prologue/epilogue
825    of the current function, and optionally store these registers in SET.  */
826 
827 static int
avr_regs_to_save(HARD_REG_SET * set)828 avr_regs_to_save (HARD_REG_SET *set)
829 {
830   int reg, count;
831   int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
832 
833   if (set)
834     CLEAR_HARD_REG_SET (*set);
835   count = 0;
836 
837   /* No need to save any registers if the function never returns or
838      has the "OS_task" or "OS_main" attribute.  */
839 
840   if (TREE_THIS_VOLATILE (current_function_decl)
841       || cfun->machine->is_OS_task
842       || cfun->machine->is_OS_main)
843     return 0;
844 
845   for (reg = 0; reg < 32; reg++)
846     {
847       /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
848          any global register variables.  */
849 
850       if (fixed_regs[reg])
851         continue;
852 
853       if ((int_or_sig_p && !crtl->is_leaf && call_used_regs[reg])
854           || (df_regs_ever_live_p (reg)
855               && (int_or_sig_p || !call_used_regs[reg])
856               /* Don't record frame pointer registers here.  They are treated
857                  indivitually in prologue.  */
858               && !(frame_pointer_needed
859                    && (reg == REG_Y || reg == (REG_Y+1)))))
860         {
861           if (set)
862             SET_HARD_REG_BIT (*set, reg);
863           count++;
864         }
865     }
866   return count;
867 }
868 
869 
870 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
871 
872 static bool
avr_allocate_stack_slots_for_args(void)873 avr_allocate_stack_slots_for_args (void)
874 {
875   return !cfun->machine->is_naked;
876 }
877 
878 
879 /* Return true if register FROM can be eliminated via register TO.  */
880 
881 static bool
avr_can_eliminate(const int from ATTRIBUTE_UNUSED,const int to)882 avr_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
883 {
884   return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
885           || !frame_pointer_needed);
886 }
887 
888 
889 /* Implement `TARGET_WARN_FUNC_RETURN'.  */
890 
891 static bool
avr_warn_func_return(tree decl)892 avr_warn_func_return (tree decl)
893 {
894   /* Naked functions are implemented entirely in assembly, including the
895      return sequence, so suppress warnings about this.  */
896 
897   return !avr_naked_function_p (decl);
898 }
899 
900 /* Compute offset between arg_pointer and frame_pointer.  */
901 
902 int
avr_initial_elimination_offset(int from,int to)903 avr_initial_elimination_offset (int from, int to)
904 {
905   if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
906     return 0;
907   else
908     {
909       int offset = frame_pointer_needed ? 2 : 0;
910       int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
911 
912       offset += avr_regs_to_save (NULL);
913       return (get_frame_size () + avr_outgoing_args_size()
914               + avr_pc_size + 1 + offset);
915     }
916 }
917 
918 
919 /* Helper for the function below.  */
920 
921 static void
avr_adjust_type_node(tree * node,machine_mode mode,int sat_p)922 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
923 {
924   *node = make_node (FIXED_POINT_TYPE);
925   TYPE_SATURATING (*node) = sat_p;
926   TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
927   TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
928   TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
929   TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
930   TYPE_ALIGN (*node) = 8;
931   SET_TYPE_MODE (*node, mode);
932 
933   layout_type (*node);
934 }
935 
936 
937 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'.  */
938 
939 static tree
avr_build_builtin_va_list(void)940 avr_build_builtin_va_list (void)
941 {
942   /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
943      This is more appropriate for the 8-bit machine AVR than 128-bit modes.
944      The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
945      which is auto-generated by genmodes, but the compiler assigns [U]DAmode
946      to the long long accum modes instead of the desired [U]TAmode.
947 
948      Fix this now, right after node setup in tree.c:build_common_tree_nodes().
949      This must run before c-cppbuiltin.c:builtin_define_fixed_point_constants()
950      which built-in defines macros like __ULLACCUM_FBIT__ that are used by
951      libgcc to detect IBIT and FBIT.  */
952 
953   avr_adjust_type_node (&ta_type_node, TAmode, 0);
954   avr_adjust_type_node (&uta_type_node, UTAmode, 0);
955   avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
956   avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
957 
958   unsigned_long_long_accum_type_node = uta_type_node;
959   long_long_accum_type_node = ta_type_node;
960   sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
961   sat_long_long_accum_type_node = sat_ta_type_node;
962 
963   /* Dispatch to the default handler.  */
964 
965   return std_build_builtin_va_list ();
966 }
967 
968 
969 /* Implement `TARGET_BUILTIN_SETJMP_FRAME_VALUE'.  */
970 /* Actual start of frame is virtual_stack_vars_rtx this is offset from
971    frame pointer by +STARTING_FRAME_OFFSET.
972    Using saved frame = virtual_stack_vars_rtx - STARTING_FRAME_OFFSET
973    avoids creating add/sub of offset in nonlocal goto and setjmp.  */
974 
975 static rtx
avr_builtin_setjmp_frame_value(void)976 avr_builtin_setjmp_frame_value (void)
977 {
978   rtx xval = gen_reg_rtx (Pmode);
979   emit_insn (gen_subhi3 (xval, virtual_stack_vars_rtx,
980                          gen_int_mode (STARTING_FRAME_OFFSET, Pmode)));
981   return xval;
982 }
983 
984 
985 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
986    This is return address of function.  */
987 
988 rtx
avr_return_addr_rtx(int count,rtx tem)989 avr_return_addr_rtx (int count, rtx tem)
990 {
991   rtx r;
992 
993   /* Can only return this function's return address. Others not supported.  */
994   if (count)
995      return NULL;
996 
997   if (AVR_3_BYTE_PC)
998     {
999       r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
1000       warning (0, "%<builtin_return_address%> contains only 2 bytes"
1001                " of address");
1002     }
1003   else
1004     r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
1005 
1006   r = gen_rtx_PLUS (Pmode, tem, r);
1007   r = gen_frame_mem (Pmode, memory_address (Pmode, r));
1008   r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
1009   return  r;
1010 }
1011 
1012 /* Return 1 if the function epilogue is just a single "ret".  */
1013 
1014 int
avr_simple_epilogue(void)1015 avr_simple_epilogue (void)
1016 {
1017   return (! frame_pointer_needed
1018           && get_frame_size () == 0
1019           && avr_outgoing_args_size() == 0
1020           && avr_regs_to_save (NULL) == 0
1021           && ! cfun->machine->is_interrupt
1022           && ! cfun->machine->is_signal
1023           && ! cfun->machine->is_naked
1024           && ! TREE_THIS_VOLATILE (current_function_decl));
1025 }
1026 
1027 /* This function checks sequence of live registers.  */
1028 
1029 static int
sequent_regs_live(void)1030 sequent_regs_live (void)
1031 {
1032   int reg;
1033   int live_seq = 0;
1034   int cur_seq = 0;
1035 
1036   for (reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
1037     {
1038       if (fixed_regs[reg])
1039         {
1040           /* Don't recognize sequences that contain global register
1041              variables.  */
1042 
1043           if (live_seq != 0)
1044             return 0;
1045           else
1046             continue;
1047         }
1048 
1049       if (!call_used_regs[reg])
1050         {
1051           if (df_regs_ever_live_p (reg))
1052             {
1053               ++live_seq;
1054               ++cur_seq;
1055             }
1056           else
1057             cur_seq = 0;
1058         }
1059     }
1060 
1061   if (!frame_pointer_needed)
1062     {
1063       if (df_regs_ever_live_p (REG_Y))
1064         {
1065           ++live_seq;
1066           ++cur_seq;
1067         }
1068       else
1069         cur_seq = 0;
1070 
1071       if (df_regs_ever_live_p (REG_Y+1))
1072         {
1073           ++live_seq;
1074           ++cur_seq;
1075         }
1076       else
1077         cur_seq = 0;
1078     }
1079   else
1080     {
1081       cur_seq += 2;
1082       live_seq += 2;
1083     }
1084   return (cur_seq == live_seq) ? live_seq : 0;
1085 }
1086 
1087 /* Obtain the length sequence of insns.  */
1088 
1089 int
get_sequence_length(rtx_insn * insns)1090 get_sequence_length (rtx_insn *insns)
1091 {
1092   rtx_insn *insn;
1093   int length;
1094 
1095   for (insn = insns, length = 0; insn; insn = NEXT_INSN (insn))
1096     length += get_attr_length (insn);
1097 
1098   return length;
1099 }
1100 
1101 
1102 /*  Implement `INCOMING_RETURN_ADDR_RTX'.  */
1103 
1104 rtx
avr_incoming_return_addr_rtx(void)1105 avr_incoming_return_addr_rtx (void)
1106 {
1107   /* The return address is at the top of the stack.  Note that the push
1108      was via post-decrement, which means the actual address is off by one.  */
1109   return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
1110 }
1111 
1112 /*  Helper for expand_prologue.  Emit a push of a byte register.  */
1113 
1114 static void
emit_push_byte(unsigned regno,bool frame_related_p)1115 emit_push_byte (unsigned regno, bool frame_related_p)
1116 {
1117   rtx mem, reg;
1118   rtx_insn *insn;
1119 
1120   mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
1121   mem = gen_frame_mem (QImode, mem);
1122   reg = gen_rtx_REG (QImode, regno);
1123 
1124   insn = emit_insn (gen_rtx_SET (mem, reg));
1125   if (frame_related_p)
1126     RTX_FRAME_RELATED_P (insn) = 1;
1127 
1128   cfun->machine->stack_usage++;
1129 }
1130 
1131 
1132 /*  Helper for expand_prologue.  Emit a push of a SFR via tmp_reg.
1133     SFR is a MEM representing the memory location of the SFR.
1134     If CLR_P then clear the SFR after the push using zero_reg.  */
1135 
1136 static void
emit_push_sfr(rtx sfr,bool frame_related_p,bool clr_p)1137 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p)
1138 {
1139   rtx_insn *insn;
1140 
1141   gcc_assert (MEM_P (sfr));
1142 
1143   /* IN __tmp_reg__, IO(SFR) */
1144   insn = emit_move_insn (tmp_reg_rtx, sfr);
1145   if (frame_related_p)
1146     RTX_FRAME_RELATED_P (insn) = 1;
1147 
1148   /* PUSH __tmp_reg__ */
1149   emit_push_byte (AVR_TMP_REGNO, frame_related_p);
1150 
1151   if (clr_p)
1152     {
1153       /* OUT IO(SFR), __zero_reg__ */
1154       insn = emit_move_insn (sfr, const0_rtx);
1155       if (frame_related_p)
1156         RTX_FRAME_RELATED_P (insn) = 1;
1157     }
1158 }
1159 
1160 static void
avr_prologue_setup_frame(HOST_WIDE_INT size,HARD_REG_SET set)1161 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
1162 {
1163   rtx_insn *insn;
1164   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1165   int live_seq = sequent_regs_live ();
1166 
1167   HOST_WIDE_INT size_max
1168     = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
1169 
1170   bool minimize = (TARGET_CALL_PROLOGUES
1171                    && size < size_max
1172                    && live_seq
1173                    && !isr_p
1174                    && !cfun->machine->is_OS_task
1175                    && !cfun->machine->is_OS_main
1176                    && !AVR_TINY);
1177 
1178   if (minimize
1179       && (frame_pointer_needed
1180           || avr_outgoing_args_size() > 8
1181           || (AVR_2_BYTE_PC && live_seq > 6)
1182           || live_seq > 7))
1183     {
1184       rtx pattern;
1185       int first_reg, reg, offset;
1186 
1187       emit_move_insn (gen_rtx_REG (HImode, REG_X),
1188                       gen_int_mode (size, HImode));
1189 
1190       pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
1191                                          gen_int_mode (live_seq+size, HImode));
1192       insn = emit_insn (pattern);
1193       RTX_FRAME_RELATED_P (insn) = 1;
1194 
1195       /* Describe the effect of the unspec_volatile call to prologue_saves.
1196          Note that this formulation assumes that add_reg_note pushes the
1197          notes to the front.  Thus we build them in the reverse order of
1198          how we want dwarf2out to process them.  */
1199 
1200       /* The function does always set frame_pointer_rtx, but whether that
1201          is going to be permanent in the function is frame_pointer_needed.  */
1202 
1203       add_reg_note (insn, REG_CFA_ADJUST_CFA,
1204                     gen_rtx_SET ((frame_pointer_needed
1205 				  ? frame_pointer_rtx
1206 				  : stack_pointer_rtx),
1207                                  plus_constant (Pmode, stack_pointer_rtx,
1208                                                 -(size + live_seq))));
1209 
1210       /* Note that live_seq always contains r28+r29, but the other
1211          registers to be saved are all below 18.  */
1212 
1213       first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
1214 
1215       for (reg = 29, offset = -live_seq + 1;
1216            reg >= first_reg;
1217            reg = (reg == 28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
1218         {
1219           rtx m, r;
1220 
1221           m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
1222                                                   offset));
1223           r = gen_rtx_REG (QImode, reg);
1224           add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
1225         }
1226 
1227       cfun->machine->stack_usage += size + live_seq;
1228     }
1229   else /* !minimize */
1230     {
1231       int reg;
1232 
1233       for (reg = 0; reg < 32; ++reg)
1234         if (TEST_HARD_REG_BIT (set, reg))
1235           emit_push_byte (reg, true);
1236 
1237       if (frame_pointer_needed
1238           && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
1239         {
1240           /* Push frame pointer.  Always be consistent about the
1241              ordering of pushes -- epilogue_restores expects the
1242              register pair to be pushed low byte first.  */
1243 
1244           emit_push_byte (REG_Y, true);
1245           emit_push_byte (REG_Y + 1, true);
1246         }
1247 
1248       if (frame_pointer_needed
1249           && size == 0)
1250         {
1251           insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1252           RTX_FRAME_RELATED_P (insn) = 1;
1253         }
1254 
1255       if (size != 0)
1256         {
1257           /*  Creating a frame can be done by direct manipulation of the
1258               stack or via the frame pointer. These two methods are:
1259                   fp =  sp
1260                   fp -= size
1261                   sp =  fp
1262               or
1263                   sp -= size
1264                   fp =  sp    (*)
1265               the optimum method depends on function type, stack and
1266               frame size.  To avoid a complex logic, both methods are
1267               tested and shortest is selected.
1268 
1269               There is also the case where SIZE != 0 and no frame pointer is
1270               needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
1271               In that case, insn (*) is not needed in that case.
1272               We use the X register as scratch. This is save because in X
1273               is call-clobbered.
1274                  In an interrupt routine, the case of SIZE != 0 together with
1275               !frame_pointer_needed can only occur if the function is not a
1276               leaf function and thus X has already been saved.  */
1277 
1278           int irq_state = -1;
1279           HOST_WIDE_INT size_cfa = size, neg_size;
1280           rtx_insn *fp_plus_insns;
1281           rtx fp, my_fp;
1282 
1283           gcc_assert (frame_pointer_needed
1284                       || !isr_p
1285                       || !crtl->is_leaf);
1286 
1287           fp = my_fp = (frame_pointer_needed
1288                         ? frame_pointer_rtx
1289                         : gen_rtx_REG (Pmode, REG_X));
1290 
1291           if (AVR_HAVE_8BIT_SP)
1292             {
1293               /* The high byte (r29) does not change:
1294                  Prefer SUBI (1 cycle) over SBIW (2 cycles, same size).  */
1295 
1296               my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1297             }
1298 
1299           /* Cut down size and avoid size = 0 so that we don't run
1300              into ICE like PR52488 in the remainder.  */
1301 
1302           if (size > size_max)
1303             {
1304               /* Don't error so that insane code from newlib still compiles
1305                  and does not break building newlib.  As PR51345 is implemented
1306                  now, there are multilib variants with -msp8.
1307 
1308                  If user wants sanity checks he can use -Wstack-usage=
1309                  or similar options.
1310 
1311                  For CFA we emit the original, non-saturated size so that
1312                  the generic machinery is aware of the real stack usage and
1313                  will print the above diagnostic as expected.  */
1314 
1315               size = size_max;
1316             }
1317 
1318           size = trunc_int_for_mode (size, GET_MODE (my_fp));
1319           neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
1320 
1321           /************  Method 1: Adjust frame pointer  ************/
1322 
1323           start_sequence ();
1324 
1325           /* Normally, the dwarf2out frame-related-expr interpreter does
1326              not expect to have the CFA change once the frame pointer is
1327              set up.  Thus, we avoid marking the move insn below and
1328              instead indicate that the entire operation is complete after
1329              the frame pointer subtraction is done.  */
1330 
1331           insn = emit_move_insn (fp, stack_pointer_rtx);
1332           if (frame_pointer_needed)
1333             {
1334               RTX_FRAME_RELATED_P (insn) = 1;
1335               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1336                             gen_rtx_SET (fp, stack_pointer_rtx));
1337             }
1338 
1339           insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
1340                                                        my_fp, neg_size));
1341 
1342           if (frame_pointer_needed)
1343             {
1344               RTX_FRAME_RELATED_P (insn) = 1;
1345               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1346                             gen_rtx_SET (fp, plus_constant (Pmode, fp,
1347 							    -size_cfa)));
1348             }
1349 
1350           /* Copy to stack pointer.  Note that since we've already
1351              changed the CFA to the frame pointer this operation
1352              need not be annotated if frame pointer is needed.
1353              Always move through unspec, see PR50063.
1354              For meaning of irq_state see movhi_sp_r insn.  */
1355 
1356           if (cfun->machine->is_interrupt)
1357             irq_state = 1;
1358 
1359           if (TARGET_NO_INTERRUPTS
1360               || cfun->machine->is_signal
1361               || cfun->machine->is_OS_main)
1362             irq_state = 0;
1363 
1364           if (AVR_HAVE_8BIT_SP)
1365             irq_state = 2;
1366 
1367           insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
1368                                             fp, GEN_INT (irq_state)));
1369           if (!frame_pointer_needed)
1370             {
1371               RTX_FRAME_RELATED_P (insn) = 1;
1372               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1373                             gen_rtx_SET (stack_pointer_rtx,
1374                                          plus_constant (Pmode,
1375                                                         stack_pointer_rtx,
1376                                                         -size_cfa)));
1377             }
1378 
1379           fp_plus_insns = get_insns ();
1380           end_sequence ();
1381 
1382           /************  Method 2: Adjust Stack pointer  ************/
1383 
1384           /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
1385              can only handle specific offsets.  */
1386 
1387           if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode))
1388             {
1389               rtx_insn *sp_plus_insns;
1390 
1391               start_sequence ();
1392 
1393               insn = emit_move_insn (stack_pointer_rtx,
1394                                      plus_constant (Pmode, stack_pointer_rtx,
1395                                                     -size));
1396               RTX_FRAME_RELATED_P (insn) = 1;
1397               add_reg_note (insn, REG_CFA_ADJUST_CFA,
1398                             gen_rtx_SET (stack_pointer_rtx,
1399                                          plus_constant (Pmode,
1400                                                         stack_pointer_rtx,
1401                                                         -size_cfa)));
1402               if (frame_pointer_needed)
1403                 {
1404                   insn = emit_move_insn (fp, stack_pointer_rtx);
1405                   RTX_FRAME_RELATED_P (insn) = 1;
1406                 }
1407 
1408               sp_plus_insns = get_insns ();
1409               end_sequence ();
1410 
1411               /************ Use shortest method  ************/
1412 
1413               emit_insn (get_sequence_length (sp_plus_insns)
1414                          < get_sequence_length (fp_plus_insns)
1415                          ? sp_plus_insns
1416                          : fp_plus_insns);
1417             }
1418           else
1419             {
1420               emit_insn (fp_plus_insns);
1421             }
1422 
1423           cfun->machine->stack_usage += size_cfa;
1424         } /* !minimize && size != 0 */
1425     } /* !minimize */
1426 }
1427 
1428 
1429 /*  Output function prologue.  */
1430 
1431 void
avr_expand_prologue(void)1432 avr_expand_prologue (void)
1433 {
1434   HARD_REG_SET set;
1435   HOST_WIDE_INT size;
1436 
1437   size = get_frame_size() + avr_outgoing_args_size();
1438 
1439   cfun->machine->stack_usage = 0;
1440 
1441   /* Prologue: naked.  */
1442   if (cfun->machine->is_naked)
1443     {
1444       return;
1445     }
1446 
1447   avr_regs_to_save (&set);
1448 
1449   if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1450     {
1451       /* Enable interrupts.  */
1452       if (cfun->machine->is_interrupt)
1453         emit_insn (gen_enable_interrupt ());
1454 
1455       /* Push zero reg.  */
1456       emit_push_byte (AVR_ZERO_REGNO, true);
1457 
1458       /* Push tmp reg.  */
1459       emit_push_byte (AVR_TMP_REGNO, true);
1460 
1461       /* Push SREG.  */
1462       /* ??? There's no dwarf2 column reserved for SREG.  */
1463       emit_push_sfr (sreg_rtx, false, false /* clr */);
1464 
1465       /* Clear zero reg.  */
1466       emit_move_insn (zero_reg_rtx, const0_rtx);
1467 
1468       /* Prevent any attempt to delete the setting of ZERO_REG!  */
1469       emit_use (zero_reg_rtx);
1470 
1471       /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
1472          ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z.  */
1473 
1474       if (AVR_HAVE_RAMPD)
1475         emit_push_sfr (rampd_rtx, false /* frame-related */, true /* clr */);
1476 
1477       if (AVR_HAVE_RAMPX
1478           && TEST_HARD_REG_BIT (set, REG_X)
1479           && TEST_HARD_REG_BIT (set, REG_X + 1))
1480         {
1481           emit_push_sfr (rampx_rtx, false /* frame-related */, true /* clr */);
1482         }
1483 
1484       if (AVR_HAVE_RAMPY
1485           && (frame_pointer_needed
1486               || (TEST_HARD_REG_BIT (set, REG_Y)
1487                   && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1488         {
1489           emit_push_sfr (rampy_rtx, false /* frame-related */, true /* clr */);
1490         }
1491 
1492       if (AVR_HAVE_RAMPZ
1493           && TEST_HARD_REG_BIT (set, REG_Z)
1494           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1495         {
1496           emit_push_sfr (rampz_rtx, false /* frame-related */, AVR_HAVE_RAMPD);
1497         }
1498     }  /* is_interrupt is_signal */
1499 
1500   avr_prologue_setup_frame (size, set);
1501 
1502   if (flag_stack_usage_info)
1503     current_function_static_stack_size = cfun->machine->stack_usage;
1504 }
1505 
1506 
1507 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'.  */
1508 /* Output summary at end of function prologue.  */
1509 
1510 static void
avr_asm_function_end_prologue(FILE * file)1511 avr_asm_function_end_prologue (FILE *file)
1512 {
1513   if (cfun->machine->is_naked)
1514     {
1515       fputs ("/* prologue: naked */\n", file);
1516     }
1517   else
1518     {
1519       if (cfun->machine->is_interrupt)
1520         {
1521           fputs ("/* prologue: Interrupt */\n", file);
1522         }
1523       else if (cfun->machine->is_signal)
1524         {
1525           fputs ("/* prologue: Signal */\n", file);
1526         }
1527       else
1528         fputs ("/* prologue: function */\n", file);
1529     }
1530 
1531   if (ACCUMULATE_OUTGOING_ARGS)
1532     fprintf (file, "/* outgoing args size = %d */\n",
1533              avr_outgoing_args_size());
1534 
1535   fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
1536                  get_frame_size());
1537   fprintf (file, "/* stack size = %d */\n",
1538                  cfun->machine->stack_usage);
1539   /* Create symbol stack offset here so all functions have it. Add 1 to stack
1540      usage for offset so that SP + .L__stack_offset = return address.  */
1541   fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
1542 }
1543 
1544 
1545 /* Implement `EPILOGUE_USES'.  */
1546 
1547 int
avr_epilogue_uses(int regno ATTRIBUTE_UNUSED)1548 avr_epilogue_uses (int regno ATTRIBUTE_UNUSED)
1549 {
1550   if (reload_completed
1551       && cfun->machine
1552       && (cfun->machine->is_interrupt || cfun->machine->is_signal))
1553     return 1;
1554   return 0;
1555 }
1556 
1557 /*  Helper for avr_expand_epilogue.  Emit a pop of a byte register.  */
1558 
1559 static void
emit_pop_byte(unsigned regno)1560 emit_pop_byte (unsigned regno)
1561 {
1562   rtx mem, reg;
1563 
1564   mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
1565   mem = gen_frame_mem (QImode, mem);
1566   reg = gen_rtx_REG (QImode, regno);
1567 
1568   emit_insn (gen_rtx_SET (reg, mem));
1569 }
1570 
1571 /*  Output RTL epilogue.  */
1572 
1573 void
avr_expand_epilogue(bool sibcall_p)1574 avr_expand_epilogue (bool sibcall_p)
1575 {
1576   int reg;
1577   int live_seq;
1578   HARD_REG_SET set;
1579   int minimize;
1580   HOST_WIDE_INT size;
1581   bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1582 
1583   size = get_frame_size() + avr_outgoing_args_size();
1584 
1585   /* epilogue: naked  */
1586   if (cfun->machine->is_naked)
1587     {
1588       gcc_assert (!sibcall_p);
1589 
1590       emit_jump_insn (gen_return ());
1591       return;
1592     }
1593 
1594   avr_regs_to_save (&set);
1595   live_seq = sequent_regs_live ();
1596 
1597   minimize = (TARGET_CALL_PROLOGUES
1598               && live_seq
1599               && !isr_p
1600               && !cfun->machine->is_OS_task
1601               && !cfun->machine->is_OS_main
1602               && !AVR_TINY);
1603 
1604   if (minimize
1605       && (live_seq > 4
1606           || frame_pointer_needed
1607           || size))
1608     {
1609       /*  Get rid of frame.  */
1610 
1611       if (!frame_pointer_needed)
1612         {
1613           emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1614         }
1615 
1616       if (size)
1617         {
1618           emit_move_insn (frame_pointer_rtx,
1619                           plus_constant (Pmode, frame_pointer_rtx, size));
1620         }
1621 
1622       emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
1623       return;
1624     }
1625 
1626   if (size)
1627     {
1628       /* Try two methods to adjust stack and select shortest.  */
1629 
1630       int irq_state = -1;
1631       rtx fp, my_fp;
1632       rtx_insn *fp_plus_insns;
1633       HOST_WIDE_INT size_max;
1634 
1635       gcc_assert (frame_pointer_needed
1636                   || !isr_p
1637                   || !crtl->is_leaf);
1638 
1639       fp = my_fp = (frame_pointer_needed
1640                     ? frame_pointer_rtx
1641                     : gen_rtx_REG (Pmode, REG_X));
1642 
1643       if (AVR_HAVE_8BIT_SP)
1644         {
1645           /* The high byte (r29) does not change:
1646              Prefer SUBI (1 cycle) over SBIW (2 cycles).  */
1647 
1648           my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
1649         }
1650 
1651       /* For rationale see comment in prologue generation.  */
1652 
1653       size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
1654       if (size > size_max)
1655         size = size_max;
1656       size = trunc_int_for_mode (size, GET_MODE (my_fp));
1657 
1658       /********** Method 1: Adjust fp register  **********/
1659 
1660       start_sequence ();
1661 
1662       if (!frame_pointer_needed)
1663         emit_move_insn (fp, stack_pointer_rtx);
1664 
1665       emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
1666 
1667       /* Copy to stack pointer.  */
1668 
1669       if (TARGET_NO_INTERRUPTS)
1670         irq_state = 0;
1671 
1672       if (AVR_HAVE_8BIT_SP)
1673         irq_state = 2;
1674 
1675       emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
1676                                  GEN_INT (irq_state)));
1677 
1678       fp_plus_insns = get_insns ();
1679       end_sequence ();
1680 
1681       /********** Method 2: Adjust Stack pointer  **********/
1682 
1683       if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
1684         {
1685           rtx_insn *sp_plus_insns;
1686 
1687           start_sequence ();
1688 
1689           emit_move_insn (stack_pointer_rtx,
1690                           plus_constant (Pmode, stack_pointer_rtx, size));
1691 
1692           sp_plus_insns = get_insns ();
1693           end_sequence ();
1694 
1695           /************ Use shortest method  ************/
1696 
1697           emit_insn (get_sequence_length (sp_plus_insns)
1698                      < get_sequence_length (fp_plus_insns)
1699                      ? sp_plus_insns
1700                      : fp_plus_insns);
1701         }
1702       else
1703         emit_insn (fp_plus_insns);
1704     } /* size != 0 */
1705 
1706   if (frame_pointer_needed
1707       && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
1708     {
1709       /* Restore previous frame_pointer.  See avr_expand_prologue for
1710          rationale for not using pophi.  */
1711 
1712       emit_pop_byte (REG_Y + 1);
1713       emit_pop_byte (REG_Y);
1714     }
1715 
1716   /* Restore used registers.  */
1717 
1718   for (reg = 31; reg >= 0; --reg)
1719     if (TEST_HARD_REG_BIT (set, reg))
1720       emit_pop_byte (reg);
1721 
1722   if (isr_p)
1723     {
1724       /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
1725          The conditions to restore them must be tha same as in prologue.  */
1726 
1727       if (AVR_HAVE_RAMPZ
1728           && TEST_HARD_REG_BIT (set, REG_Z)
1729           && TEST_HARD_REG_BIT (set, REG_Z + 1))
1730         {
1731           emit_pop_byte (TMP_REGNO);
1732           emit_move_insn (rampz_rtx, tmp_reg_rtx);
1733         }
1734 
1735       if (AVR_HAVE_RAMPY
1736           && (frame_pointer_needed
1737               || (TEST_HARD_REG_BIT (set, REG_Y)
1738                   && TEST_HARD_REG_BIT (set, REG_Y + 1))))
1739         {
1740           emit_pop_byte (TMP_REGNO);
1741           emit_move_insn (rampy_rtx, tmp_reg_rtx);
1742         }
1743 
1744       if (AVR_HAVE_RAMPX
1745           && TEST_HARD_REG_BIT (set, REG_X)
1746           && TEST_HARD_REG_BIT (set, REG_X + 1))
1747         {
1748           emit_pop_byte (TMP_REGNO);
1749           emit_move_insn (rampx_rtx, tmp_reg_rtx);
1750         }
1751 
1752       if (AVR_HAVE_RAMPD)
1753         {
1754           emit_pop_byte (TMP_REGNO);
1755           emit_move_insn (rampd_rtx, tmp_reg_rtx);
1756         }
1757 
1758       /* Restore SREG using tmp_reg as scratch.  */
1759 
1760       emit_pop_byte (AVR_TMP_REGNO);
1761       emit_move_insn (sreg_rtx, tmp_reg_rtx);
1762 
1763       /* Restore tmp REG.  */
1764       emit_pop_byte (AVR_TMP_REGNO);
1765 
1766       /* Restore zero REG.  */
1767       emit_pop_byte (AVR_ZERO_REGNO);
1768     }
1769 
1770   if (!sibcall_p)
1771     emit_jump_insn (gen_return ());
1772 }
1773 
1774 
1775 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'.  */
1776 
1777 static void
avr_asm_function_begin_epilogue(FILE * file)1778 avr_asm_function_begin_epilogue (FILE *file)
1779 {
1780   fprintf (file, "/* epilogue start */\n");
1781 }
1782 
1783 
1784 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'.  */
1785 
1786 static bool
avr_cannot_modify_jumps_p(void)1787 avr_cannot_modify_jumps_p (void)
1788 {
1789 
1790   /* Naked Functions must not have any instructions after
1791      their epilogue, see PR42240 */
1792 
1793   if (reload_completed
1794       && cfun->machine
1795       && cfun->machine->is_naked)
1796     {
1797       return true;
1798     }
1799 
1800   return false;
1801 }
1802 
1803 
1804 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'.  */
1805 
1806 static bool
avr_mode_dependent_address_p(const_rtx addr ATTRIBUTE_UNUSED,addr_space_t as)1807 avr_mode_dependent_address_p (const_rtx addr ATTRIBUTE_UNUSED, addr_space_t as)
1808 {
1809   /* FIXME:  Non-generic addresses are not mode-dependent in themselves.
1810        This hook just serves to hack around PR rtl-optimization/52543 by
1811        claiming that non-generic addresses were mode-dependent so that
1812        lower-subreg.c will skip these addresses.  lower-subreg.c sets up fake
1813        RTXes to probe SET and MEM costs and assumes that MEM is always in the
1814        generic address space which is not true.  */
1815 
1816   return !ADDR_SPACE_GENERIC_P (as);
1817 }
1818 
1819 
1820 /* Helper function for `avr_legitimate_address_p'.  */
1821 
1822 static inline bool
avr_reg_ok_for_addr_p(rtx reg,addr_space_t as,RTX_CODE outer_code,bool strict)1823 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
1824                        RTX_CODE outer_code, bool strict)
1825 {
1826   return (REG_P (reg)
1827           && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
1828                                                  as, outer_code, UNKNOWN)
1829               || (!strict
1830                   && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
1831 }
1832 
1833 
1834 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
1835    machine for a memory operand of mode MODE.  */
1836 
1837 static bool
avr_legitimate_address_p(machine_mode mode,rtx x,bool strict)1838 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
1839 {
1840   bool ok = CONSTANT_ADDRESS_P (x);
1841 
1842   switch (GET_CODE (x))
1843     {
1844     case REG:
1845       ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
1846                                   MEM, strict);
1847 
1848       if (strict
1849           && GET_MODE_SIZE (mode) > 4
1850           && REG_X == REGNO (x))
1851         {
1852           ok = false;
1853         }
1854       break;
1855 
1856     case POST_INC:
1857     case PRE_DEC:
1858       ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
1859                                   GET_CODE (x), strict);
1860       break;
1861 
1862     case PLUS:
1863       {
1864         rtx reg = XEXP (x, 0);
1865         rtx op1 = XEXP (x, 1);
1866 
1867         if (REG_P (reg)
1868             && CONST_INT_P (op1)
1869             && INTVAL (op1) >= 0)
1870           {
1871             bool fit = IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode));
1872 
1873             if (fit)
1874               {
1875                 ok = (! strict
1876                       || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
1877                                                 PLUS, strict));
1878 
1879                 if (reg == frame_pointer_rtx
1880                     || reg == arg_pointer_rtx)
1881                   {
1882                     ok = true;
1883                   }
1884               }
1885             else if (frame_pointer_needed
1886                      && reg == frame_pointer_rtx)
1887               {
1888                 ok = true;
1889               }
1890           }
1891       }
1892       break;
1893 
1894     default:
1895       break;
1896     }
1897 
1898   if (AVR_TINY
1899       && CONSTANT_ADDRESS_P (x))
1900     {
1901       /* avrtiny's load / store instructions only cover addresses 0..0xbf:
1902          IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf.  */
1903 
1904       ok = (CONST_INT_P (x)
1905             && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)));
1906     }
1907 
1908   if (avr_log.legitimate_address_p)
1909     {
1910       avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
1911                  "reload_completed=%d reload_in_progress=%d %s:",
1912                  ok, mode, strict, reload_completed, reload_in_progress,
1913                  reg_renumber ? "(reg_renumber)" : "");
1914 
1915       if (GET_CODE (x) == PLUS
1916           && REG_P (XEXP (x, 0))
1917           && CONST_INT_P (XEXP (x, 1))
1918           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
1919           && reg_renumber)
1920         {
1921           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
1922                      true_regnum (XEXP (x, 0)));
1923         }
1924 
1925       avr_edump ("\n%r\n", x);
1926     }
1927 
1928   return ok;
1929 }
1930 
1931 
1932 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
1933    now only a helper for avr_addr_space_legitimize_address.  */
1934 /* Attempts to replace X with a valid
1935    memory address for an operand of mode MODE  */
1936 
1937 static rtx
avr_legitimize_address(rtx x,rtx oldx,machine_mode mode)1938 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
1939 {
1940   bool big_offset_p = false;
1941 
1942   x = oldx;
1943 
1944   if (GET_CODE (oldx) == PLUS
1945       && REG_P (XEXP (oldx, 0)))
1946     {
1947       if (REG_P (XEXP (oldx, 1)))
1948         x = force_reg (GET_MODE (oldx), oldx);
1949       else if (CONST_INT_P (XEXP (oldx, 1)))
1950         {
1951           int offs = INTVAL (XEXP (oldx, 1));
1952           if (frame_pointer_rtx != XEXP (oldx, 0)
1953               && offs > MAX_LD_OFFSET (mode))
1954             {
1955               big_offset_p = true;
1956               x = force_reg (GET_MODE (oldx), oldx);
1957             }
1958         }
1959     }
1960 
1961   if (avr_log.legitimize_address)
1962     {
1963       avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
1964 
1965       if (x != oldx)
1966         avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
1967     }
1968 
1969   return x;
1970 }
1971 
1972 
1973 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'.  */
1974 /* This will allow register R26/27 to be used where it is no worse than normal
1975    base pointers R28/29 or R30/31.  For example, if base offset is greater
1976    than 63 bytes or for R++ or --R addressing.  */
1977 
1978 rtx
avr_legitimize_reload_address(rtx * px,machine_mode mode,int opnum,int type,int addr_type,int ind_levels ATTRIBUTE_UNUSED,rtx (* mk_memloc)(rtx,int))1979 avr_legitimize_reload_address (rtx *px, machine_mode mode,
1980                                int opnum, int type, int addr_type,
1981                                int ind_levels ATTRIBUTE_UNUSED,
1982                                rtx (*mk_memloc)(rtx,int))
1983 {
1984   rtx x = *px;
1985 
1986   if (avr_log.legitimize_reload_address)
1987     avr_edump ("\n%?:%m %r\n", mode, x);
1988 
1989   if (1 && (GET_CODE (x) == POST_INC
1990             || GET_CODE (x) == PRE_DEC))
1991     {
1992       push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
1993                    POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
1994                    opnum, RELOAD_OTHER);
1995 
1996       if (avr_log.legitimize_reload_address)
1997         avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
1998                    POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
1999 
2000       return x;
2001     }
2002 
2003   if (GET_CODE (x) == PLUS
2004       && REG_P (XEXP (x, 0))
2005       && 0 == reg_equiv_constant (REGNO (XEXP (x, 0)))
2006       && CONST_INT_P (XEXP (x, 1))
2007       && INTVAL (XEXP (x, 1)) >= 1)
2008     {
2009       bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
2010 
2011       if (fit)
2012         {
2013           if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
2014             {
2015               int regno = REGNO (XEXP (x, 0));
2016               rtx mem = mk_memloc (x, regno);
2017 
2018               push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
2019                            POINTER_REGS, Pmode, VOIDmode, 0, 0,
2020                            1, (enum reload_type) addr_type);
2021 
2022               if (avr_log.legitimize_reload_address)
2023                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2024                            POINTER_REGS, XEXP (mem, 0), NULL_RTX);
2025 
2026               push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
2027                            BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2028                            opnum, (enum reload_type) type);
2029 
2030               if (avr_log.legitimize_reload_address)
2031                 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
2032                            BASE_POINTER_REGS, mem, NULL_RTX);
2033 
2034               return x;
2035             }
2036         }
2037       else if (! (frame_pointer_needed
2038                   && XEXP (x, 0) == frame_pointer_rtx))
2039         {
2040           push_reload (x, NULL_RTX, px, NULL,
2041                        POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
2042                        opnum, (enum reload_type) type);
2043 
2044           if (avr_log.legitimize_reload_address)
2045             avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
2046                        POINTER_REGS, x, NULL_RTX);
2047 
2048           return x;
2049         }
2050     }
2051 
2052   return NULL_RTX;
2053 }
2054 
2055 
2056 /* Implement `TARGET_SECONDARY_RELOAD' */
2057 
2058 static reg_class_t
avr_secondary_reload(bool in_p,rtx x,reg_class_t reload_class ATTRIBUTE_UNUSED,machine_mode mode,secondary_reload_info * sri)2059 avr_secondary_reload (bool in_p, rtx x,
2060                       reg_class_t reload_class ATTRIBUTE_UNUSED,
2061                       machine_mode mode, secondary_reload_info *sri)
2062 {
2063   if (in_p
2064       && MEM_P (x)
2065       && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x))
2066       && ADDR_SPACE_MEMX != MEM_ADDR_SPACE (x))
2067     {
2068       /* For the non-generic 16-bit spaces we need a d-class scratch.  */
2069 
2070       switch (mode)
2071         {
2072         default:
2073           gcc_unreachable();
2074 
2075         case QImode:  sri->icode = CODE_FOR_reload_inqi; break;
2076         case QQmode:  sri->icode = CODE_FOR_reload_inqq; break;
2077         case UQQmode: sri->icode = CODE_FOR_reload_inuqq; break;
2078 
2079         case HImode:  sri->icode = CODE_FOR_reload_inhi; break;
2080         case HQmode:  sri->icode = CODE_FOR_reload_inhq; break;
2081         case HAmode:  sri->icode = CODE_FOR_reload_inha; break;
2082         case UHQmode: sri->icode = CODE_FOR_reload_inuhq; break;
2083         case UHAmode: sri->icode = CODE_FOR_reload_inuha; break;
2084 
2085         case PSImode: sri->icode = CODE_FOR_reload_inpsi; break;
2086 
2087         case SImode:  sri->icode = CODE_FOR_reload_insi; break;
2088         case SFmode:  sri->icode = CODE_FOR_reload_insf; break;
2089         case SQmode:  sri->icode = CODE_FOR_reload_insq; break;
2090         case SAmode:  sri->icode = CODE_FOR_reload_insa; break;
2091         case USQmode: sri->icode = CODE_FOR_reload_inusq; break;
2092         case USAmode: sri->icode = CODE_FOR_reload_inusa; break;
2093         }
2094     }
2095 
2096   return NO_REGS;
2097 }
2098 
2099 
2100 /* Helper function to print assembler resp. track instruction
2101    sequence lengths.  Always return "".
2102 
2103    If PLEN == NULL:
2104        Output assembler code from template TPL with operands supplied
2105        by OPERANDS.  This is just forwarding to output_asm_insn.
2106 
2107    If PLEN != NULL:
2108        If N_WORDS >= 0  Add N_WORDS to *PLEN.
2109        If N_WORDS < 0   Set *PLEN to -N_WORDS.
2110        Don't output anything.
2111 */
2112 
2113 static const char*
avr_asm_len(const char * tpl,rtx * operands,int * plen,int n_words)2114 avr_asm_len (const char* tpl, rtx* operands, int* plen, int n_words)
2115 {
2116   if (NULL == plen)
2117     {
2118       output_asm_insn (tpl, operands);
2119     }
2120   else
2121     {
2122       if (n_words < 0)
2123         *plen = -n_words;
2124       else
2125         *plen += n_words;
2126     }
2127 
2128   return "";
2129 }
2130 
2131 
2132 /* Return a pointer register name as a string.  */
2133 
2134 static const char*
ptrreg_to_str(int regno)2135 ptrreg_to_str (int regno)
2136 {
2137   switch (regno)
2138     {
2139     case REG_X: return "X";
2140     case REG_Y: return "Y";
2141     case REG_Z: return "Z";
2142     default:
2143       output_operand_lossage ("address operand requires constraint for"
2144                               " X, Y, or Z register");
2145     }
2146   return NULL;
2147 }
2148 
2149 /* Return the condition name as a string.
2150    Used in conditional jump constructing  */
2151 
2152 static const char*
cond_string(enum rtx_code code)2153 cond_string (enum rtx_code code)
2154 {
2155   switch (code)
2156     {
2157     case NE:
2158       return "ne";
2159     case EQ:
2160       return "eq";
2161     case GE:
2162       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2163         return "pl";
2164       else
2165         return "ge";
2166     case LT:
2167       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2168         return "mi";
2169       else
2170         return "lt";
2171     case GEU:
2172       return "sh";
2173     case LTU:
2174       return "lo";
2175     default:
2176       gcc_unreachable ();
2177     }
2178 
2179   return "";
2180 }
2181 
2182 
2183 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'.  */
2184 /* Output ADDR to FILE as address.  */
2185 
2186 static void
avr_print_operand_address(FILE * file,machine_mode,rtx addr)2187 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
2188 {
2189   switch (GET_CODE (addr))
2190     {
2191     case REG:
2192       fprintf (file, ptrreg_to_str (REGNO (addr)));
2193       break;
2194 
2195     case PRE_DEC:
2196       fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2197       break;
2198 
2199     case POST_INC:
2200       fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
2201       break;
2202 
2203     default:
2204       if (CONSTANT_ADDRESS_P (addr)
2205           && text_segment_operand (addr, VOIDmode))
2206         {
2207           rtx x = addr;
2208           if (GET_CODE (x) == CONST)
2209             x = XEXP (x, 0);
2210           if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x,1)) == CONST_INT)
2211             {
2212               /* Assembler gs() will implant word address.  Make offset
2213                  a byte offset inside gs() for assembler.  This is
2214                  needed because the more logical (constant+gs(sym)) is not
2215                  accepted by gas.  For 128K and smaller devices this is ok.
2216                  For large devices it will create a trampoline to offset
2217                  from symbol which may not be what the user really wanted.  */
2218 
2219               fprintf (file, "gs(");
2220               output_addr_const (file, XEXP (x,0));
2221               fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
2222                        2 * INTVAL (XEXP (x, 1)));
2223               if (AVR_3_BYTE_PC)
2224                 if (warning (0, "pointer offset from symbol maybe incorrect"))
2225                   {
2226                     output_addr_const (stderr, addr);
2227                     fprintf(stderr,"\n");
2228                   }
2229             }
2230           else
2231             {
2232               fprintf (file, "gs(");
2233               output_addr_const (file, addr);
2234               fprintf (file, ")");
2235             }
2236         }
2237       else
2238         output_addr_const (file, addr);
2239     }
2240 }
2241 
2242 
2243 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'.  */
2244 
2245 static bool
avr_print_operand_punct_valid_p(unsigned char code)2246 avr_print_operand_punct_valid_p (unsigned char code)
2247 {
2248   return code == '~' || code == '!';
2249 }
2250 
2251 
2252 /* Implement `TARGET_PRINT_OPERAND'.  */
2253 /* Output X as assembler operand to file FILE.
2254    For a description of supported %-codes, see top of avr.md.  */
2255 
2256 static void
avr_print_operand(FILE * file,rtx x,int code)2257 avr_print_operand (FILE *file, rtx x, int code)
2258 {
2259   int abcd = 0, ef = 0, ij = 0;
2260 
2261   if (code >= 'A' && code <= 'D')
2262     abcd = code - 'A';
2263   else if (code == 'E' || code == 'F')
2264     ef = code - 'E';
2265   else if (code == 'I' || code == 'J')
2266     ij = code - 'I';
2267 
2268   if (code == '~')
2269     {
2270       if (!AVR_HAVE_JMP_CALL)
2271         fputc ('r', file);
2272     }
2273   else if (code == '!')
2274     {
2275       if (AVR_HAVE_EIJMP_EICALL)
2276         fputc ('e', file);
2277     }
2278   else if (code == 't'
2279            || code == 'T')
2280     {
2281       static int t_regno = -1;
2282       static int t_nbits = -1;
2283 
2284       if (REG_P (x) && t_regno < 0 && code == 'T')
2285         {
2286           t_regno = REGNO (x);
2287           t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
2288         }
2289       else if (CONST_INT_P (x) && t_regno >= 0
2290                && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
2291         {
2292           int bpos = INTVAL (x);
2293 
2294           fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
2295           if (code == 'T')
2296             fprintf (file, ",%d", bpos % 8);
2297 
2298           t_regno = -1;
2299         }
2300       else
2301         fatal_insn ("operands to %T/%t must be reg + const_int:", x);
2302     }
2303   else if (code == 'E' || code == 'F')
2304     {
2305       rtx op = XEXP(x, 0);
2306       fprintf (file, reg_names[REGNO (op) + ef]);
2307     }
2308   else if (code == 'I' || code == 'J')
2309     {
2310       rtx op = XEXP(XEXP(x, 0), 0);
2311       fprintf (file, reg_names[REGNO (op) + ij]);
2312     }
2313   else if (REG_P (x))
2314     {
2315       if (x == zero_reg_rtx)
2316         fprintf (file, "__zero_reg__");
2317       else if (code == 'r' && REGNO (x) < 32)
2318         fprintf (file, "%d", (int) REGNO (x));
2319       else
2320         fprintf (file, reg_names[REGNO (x) + abcd]);
2321     }
2322   else if (CONST_INT_P (x))
2323     {
2324       HOST_WIDE_INT ival = INTVAL (x);
2325 
2326       if ('i' != code)
2327         fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
2328       else if (low_io_address_operand (x, VOIDmode)
2329                || high_io_address_operand (x, VOIDmode))
2330         {
2331           if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
2332             fprintf (file, "__RAMPZ__");
2333           else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
2334             fprintf (file, "__RAMPY__");
2335           else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
2336             fprintf (file, "__RAMPX__");
2337           else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
2338             fprintf (file, "__RAMPD__");
2339           else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
2340             fprintf (file, "__CCP__");
2341           else if (ival == avr_addr.sreg)   fprintf (file, "__SREG__");
2342           else if (ival == avr_addr.sp_l)   fprintf (file, "__SP_L__");
2343           else if (ival == avr_addr.sp_h)   fprintf (file, "__SP_H__");
2344           else
2345             {
2346               fprintf (file, HOST_WIDE_INT_PRINT_HEX,
2347                        ival - avr_arch->sfr_offset);
2348             }
2349         }
2350       else
2351         fatal_insn ("bad address, not an I/O address:", x);
2352     }
2353   else if (MEM_P (x))
2354     {
2355       rtx addr = XEXP (x, 0);
2356 
2357       if (code == 'm')
2358         {
2359           if (!CONSTANT_P (addr))
2360             fatal_insn ("bad address, not a constant:", addr);
2361           /* Assembler template with m-code is data - not progmem section */
2362           if (text_segment_operand (addr, VOIDmode))
2363             if (warning (0, "accessing data memory with"
2364                          " program memory address"))
2365               {
2366                 output_addr_const (stderr, addr);
2367                 fprintf(stderr,"\n");
2368               }
2369           output_addr_const (file, addr);
2370         }
2371       else if (code == 'i')
2372         {
2373           avr_print_operand (file, addr, 'i');
2374         }
2375       else if (code == 'o')
2376         {
2377           if (GET_CODE (addr) != PLUS)
2378             fatal_insn ("bad address, not (reg+disp):", addr);
2379 
2380           avr_print_operand (file, XEXP (addr, 1), 0);
2381         }
2382       else if (code == 'b')
2383         {
2384           if (GET_CODE (addr) != PLUS)
2385                fatal_insn ("bad address, not (reg+disp):", addr);
2386 
2387           avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2388         }
2389       else if (code == 'p' || code == 'r')
2390         {
2391           if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
2392             fatal_insn ("bad address, not post_inc or pre_dec:", addr);
2393 
2394           if (code == 'p')
2395 	    /* X, Y, Z */
2396             avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
2397           else
2398             avr_print_operand (file, XEXP (addr, 0), 0);  /* r26, r28, r30 */
2399         }
2400       else if (GET_CODE (addr) == PLUS)
2401         {
2402           avr_print_operand_address (file, VOIDmode, XEXP (addr,0));
2403           if (REGNO (XEXP (addr, 0)) == REG_X)
2404             fatal_insn ("internal compiler error.  Bad address:"
2405                         ,addr);
2406           fputc ('+', file);
2407           avr_print_operand (file, XEXP (addr,1), code);
2408         }
2409       else
2410         avr_print_operand_address (file, VOIDmode, addr);
2411     }
2412   else if (code == 'i')
2413     {
2414       if (GET_CODE (x) == SYMBOL_REF && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
2415 	avr_print_operand_address
2416 	  (file, VOIDmode, plus_constant (HImode, x, -avr_arch->sfr_offset));
2417       else
2418 	fatal_insn ("bad address, not an I/O address:", x);
2419     }
2420   else if (code == 'x')
2421     {
2422       /* Constant progmem address - like used in jmp or call */
2423       if (0 == text_segment_operand (x, VOIDmode))
2424         if (warning (0, "accessing program memory"
2425                      " with data memory address"))
2426           {
2427             output_addr_const (stderr, x);
2428             fprintf(stderr,"\n");
2429           }
2430       /* Use normal symbol for direct address no linker trampoline needed */
2431       output_addr_const (file, x);
2432     }
2433   else if (CONST_FIXED_P (x))
2434     {
2435       HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
2436       if (code != 0)
2437         output_operand_lossage ("Unsupported code '%c' for fixed-point:",
2438                                 code);
2439       fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
2440     }
2441   else if (GET_CODE (x) == CONST_DOUBLE)
2442     {
2443       long val;
2444       if (GET_MODE (x) != SFmode)
2445         fatal_insn ("internal compiler error.  Unknown mode:", x);
2446       REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
2447       fprintf (file, "0x%lx", val);
2448     }
2449   else if (GET_CODE (x) == CONST_STRING)
2450     fputs (XSTR (x, 0), file);
2451   else if (code == 'j')
2452     fputs (cond_string (GET_CODE (x)), file);
2453   else if (code == 'k')
2454     fputs (cond_string (reverse_condition (GET_CODE (x))), file);
2455   else
2456     avr_print_operand_address (file, VOIDmode, x);
2457 }
2458 
2459 
2460 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P.  */
2461 
2462 /* Prefer sequence of loads/stores for moves of size upto
2463    two - two pairs of load/store instructions are always better
2464    than the 5 instruction sequence for a loop (1 instruction
2465    for loop counter setup, and 4 for the body of the loop). */
2466 
2467 static bool
avr_use_by_pieces_infrastructure_p(unsigned HOST_WIDE_INT size,unsigned int align ATTRIBUTE_UNUSED,enum by_pieces_operation op,bool speed_p)2468 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
2469 				     unsigned int align ATTRIBUTE_UNUSED,
2470 				     enum by_pieces_operation op,
2471 				     bool speed_p)
2472 {
2473 
2474   if (op != MOVE_BY_PIECES || (speed_p && (size > (MOVE_MAX_PIECES))))
2475     return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
2476 
2477   return size <= (MOVE_MAX_PIECES);
2478 }
2479 
2480 
2481 /* Worker function for `NOTICE_UPDATE_CC'.  */
2482 /* Update the condition code in the INSN.  */
2483 
2484 void
avr_notice_update_cc(rtx body ATTRIBUTE_UNUSED,rtx_insn * insn)2485 avr_notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx_insn *insn)
2486 {
2487   rtx set;
2488   enum attr_cc cc = get_attr_cc (insn);
2489 
2490   switch (cc)
2491     {
2492     default:
2493       break;
2494 
2495     case CC_PLUS:
2496     case CC_LDI:
2497       {
2498         rtx *op = recog_data.operand;
2499         int len_dummy, icc;
2500 
2501         /* Extract insn's operands.  */
2502         extract_constrain_insn_cached (insn);
2503 
2504         switch (cc)
2505           {
2506           default:
2507             gcc_unreachable();
2508 
2509           case CC_PLUS:
2510             avr_out_plus (insn, op, &len_dummy, &icc);
2511             cc = (enum attr_cc) icc;
2512             break;
2513 
2514           case CC_LDI:
2515 
2516             cc = (op[1] == CONST0_RTX (GET_MODE (op[0]))
2517                   && reg_overlap_mentioned_p (op[0], zero_reg_rtx))
2518               /* Loading zero-reg with 0 uses CLR and thus clobbers cc0.  */
2519               ? CC_CLOBBER
2520               /* Any other "r,rL" combination does not alter cc0.  */
2521               : CC_NONE;
2522 
2523             break;
2524           } /* inner switch */
2525 
2526         break;
2527       }
2528     } /* outer swicth */
2529 
2530   switch (cc)
2531     {
2532     default:
2533       /* Special values like CC_OUT_PLUS from above have been
2534          mapped to "standard" CC_* values so we never come here.  */
2535 
2536       gcc_unreachable();
2537       break;
2538 
2539     case CC_NONE:
2540       /* Insn does not affect CC at all, but it might set some registers
2541          that are stored in cc_status.  If such a register is affected by
2542          the current insn, for example by means of a SET or a CLOBBER,
2543          then we must reset cc_status; cf. PR77326.
2544 
2545          Unfortunately, set_of cannot be used as reg_overlap_mentioned_p
2546          will abort on COMPARE (which might be found in cc_status.value1/2).
2547          Thus work out the registers set by the insn and regs mentioned
2548          in cc_status.value1/2.  */
2549 
2550       if (cc_status.value1
2551           || cc_status.value2)
2552         {
2553           HARD_REG_SET regs_used;
2554           HARD_REG_SET regs_set;
2555           CLEAR_HARD_REG_SET (regs_used);
2556 
2557           if (cc_status.value1
2558               && !CONSTANT_P (cc_status.value1))
2559             {
2560               find_all_hard_regs (cc_status.value1, &regs_used);
2561             }
2562 
2563           if (cc_status.value2
2564               && !CONSTANT_P (cc_status.value2))
2565             {
2566               find_all_hard_regs (cc_status.value2, &regs_used);
2567             }
2568 
2569           find_all_hard_reg_sets (insn, &regs_set, false);
2570 
2571           if (hard_reg_set_intersect_p (regs_used, regs_set))
2572             {
2573               CC_STATUS_INIT;
2574             }
2575         }
2576 
2577       break; // CC_NONE
2578 
2579     case CC_SET_N:
2580       CC_STATUS_INIT;
2581       break;
2582 
2583     case CC_SET_ZN:
2584       set = single_set (insn);
2585       CC_STATUS_INIT;
2586       if (set)
2587         {
2588           cc_status.flags |= CC_NO_OVERFLOW;
2589           cc_status.value1 = SET_DEST (set);
2590         }
2591       break;
2592 
2593     case CC_SET_VZN:
2594       /* Insn like INC, DEC, NEG that set Z,N,V.  We currently don't make use
2595          of this combination, cf. also PR61055.  */
2596       CC_STATUS_INIT;
2597       break;
2598 
2599     case CC_SET_CZN:
2600       /* Insn sets the Z,N,C flags of CC to recog_operand[0].
2601          The V flag may or may not be known but that's ok because
2602          alter_cond will change tests to use EQ/NE.  */
2603       set = single_set (insn);
2604       CC_STATUS_INIT;
2605       if (set)
2606         {
2607           cc_status.value1 = SET_DEST (set);
2608           cc_status.flags |= CC_OVERFLOW_UNUSABLE;
2609         }
2610       break;
2611 
2612     case CC_COMPARE:
2613       set = single_set (insn);
2614       CC_STATUS_INIT;
2615       if (set)
2616         cc_status.value1 = SET_SRC (set);
2617       break;
2618 
2619     case CC_CLOBBER:
2620       /* Insn doesn't leave CC in a usable state.  */
2621       CC_STATUS_INIT;
2622       break;
2623     }
2624 }
2625 
2626 /* Choose mode for jump insn:
2627    1 - relative jump in range -63 <= x <= 62 ;
2628    2 - relative jump in range -2046 <= x <= 2045 ;
2629    3 - absolute jump (only for ATmega[16]03).  */
2630 
2631 int
avr_jump_mode(rtx x,rtx_insn * insn)2632 avr_jump_mode (rtx x, rtx_insn *insn)
2633 {
2634   int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
2635                                             ? XEXP (x, 0) : x));
2636   int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
2637   int jump_distance = cur_addr - dest_addr;
2638 
2639   if (-63 <= jump_distance && jump_distance <= 62)
2640     return 1;
2641   else if (-2046 <= jump_distance && jump_distance <= 2045)
2642     return 2;
2643   else if (AVR_HAVE_JMP_CALL)
2644     return 3;
2645 
2646   return 2;
2647 }
2648 
2649 /* Return an AVR condition jump commands.
2650    X is a comparison RTX.
2651    LEN is a number returned by avr_jump_mode function.
2652    If REVERSE nonzero then condition code in X must be reversed.  */
2653 
2654 const char*
ret_cond_branch(rtx x,int len,int reverse)2655 ret_cond_branch (rtx x, int len, int reverse)
2656 {
2657   RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
2658 
2659   switch (cond)
2660     {
2661     case GT:
2662       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2663 	return (len == 1 ? ("breq .+2" CR_TAB
2664 			    "brpl %0") :
2665 		len == 2 ? ("breq .+4" CR_TAB
2666 			    "brmi .+2" CR_TAB
2667 			    "rjmp %0") :
2668 		("breq .+6" CR_TAB
2669 		 "brmi .+4" CR_TAB
2670 		 "jmp %0"));
2671 
2672       else
2673 	return (len == 1 ? ("breq .+2" CR_TAB
2674 			    "brge %0") :
2675 		len == 2 ? ("breq .+4" CR_TAB
2676 			    "brlt .+2" CR_TAB
2677 			    "rjmp %0") :
2678 		("breq .+6" CR_TAB
2679 		 "brlt .+4" CR_TAB
2680 		 "jmp %0"));
2681     case GTU:
2682       return (len == 1 ? ("breq .+2" CR_TAB
2683                           "brsh %0") :
2684               len == 2 ? ("breq .+4" CR_TAB
2685                           "brlo .+2" CR_TAB
2686                           "rjmp %0") :
2687               ("breq .+6" CR_TAB
2688                "brlo .+4" CR_TAB
2689                "jmp %0"));
2690     case LE:
2691       if (cc_prev_status.flags & CC_OVERFLOW_UNUSABLE)
2692 	return (len == 1 ? ("breq %0" CR_TAB
2693 			    "brmi %0") :
2694 		len == 2 ? ("breq .+2" CR_TAB
2695 			    "brpl .+2" CR_TAB
2696 			    "rjmp %0") :
2697 		("breq .+2" CR_TAB
2698 		 "brpl .+4" CR_TAB
2699 		 "jmp %0"));
2700       else
2701 	return (len == 1 ? ("breq %0" CR_TAB
2702 			    "brlt %0") :
2703 		len == 2 ? ("breq .+2" CR_TAB
2704 			    "brge .+2" CR_TAB
2705 			    "rjmp %0") :
2706 		("breq .+2" CR_TAB
2707 		 "brge .+4" CR_TAB
2708 		 "jmp %0"));
2709     case LEU:
2710       return (len == 1 ? ("breq %0" CR_TAB
2711                           "brlo %0") :
2712               len == 2 ? ("breq .+2" CR_TAB
2713                           "brsh .+2" CR_TAB
2714 			  "rjmp %0") :
2715               ("breq .+2" CR_TAB
2716                "brsh .+4" CR_TAB
2717 	       "jmp %0"));
2718     default:
2719       if (reverse)
2720 	{
2721 	  switch (len)
2722 	    {
2723 	    case 1:
2724 	      return "br%k1 %0";
2725 	    case 2:
2726 	      return ("br%j1 .+2" CR_TAB
2727 		      "rjmp %0");
2728 	    default:
2729 	      return ("br%j1 .+4" CR_TAB
2730 		      "jmp %0");
2731 	    }
2732 	}
2733       else
2734         {
2735           switch (len)
2736             {
2737             case 1:
2738               return "br%j1 %0";
2739             case 2:
2740               return ("br%k1 .+2" CR_TAB
2741                       "rjmp %0");
2742             default:
2743               return ("br%k1 .+4" CR_TAB
2744                       "jmp %0");
2745             }
2746         }
2747     }
2748   return "";
2749 }
2750 
2751 
2752 /* Worker function for `FINAL_PRESCAN_INSN'.  */
2753 /* Output insn cost for next insn.  */
2754 
2755 void
avr_final_prescan_insn(rtx_insn * insn,rtx * operand ATTRIBUTE_UNUSED,int num_operands ATTRIBUTE_UNUSED)2756 avr_final_prescan_insn (rtx_insn *insn, rtx *operand ATTRIBUTE_UNUSED,
2757                         int num_operands ATTRIBUTE_UNUSED)
2758 {
2759   if (avr_log.rtx_costs)
2760     {
2761       rtx set = single_set (insn);
2762 
2763       if (set)
2764         fprintf (asm_out_file, "/* DEBUG: cost = %d.  */\n",
2765                  set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
2766 			       optimize_insn_for_speed_p ()));
2767       else
2768         fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d.  */\n",
2769                  rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
2770                            optimize_insn_for_speed_p()));
2771     }
2772 }
2773 
2774 /* Return 0 if undefined, 1 if always true or always false.  */
2775 
2776 int
avr_simplify_comparison_p(machine_mode mode,RTX_CODE op,rtx x)2777 avr_simplify_comparison_p (machine_mode mode, RTX_CODE op, rtx x)
2778 {
2779   unsigned int max = (mode == QImode ? 0xff :
2780                       mode == HImode ? 0xffff :
2781                       mode == PSImode ? 0xffffff :
2782                       mode == SImode ? 0xffffffff : 0);
2783   if (max && op && CONST_INT_P (x))
2784     {
2785       if (unsigned_condition (op) != op)
2786         max >>= 1;
2787 
2788       if (max != (INTVAL (x) & max)
2789           && INTVAL (x) != 0xff)
2790         return 1;
2791     }
2792   return 0;
2793 }
2794 
2795 
2796 /* Worker function for `FUNCTION_ARG_REGNO_P'.  */
2797 /* Returns nonzero if REGNO is the number of a hard
2798    register in which function arguments are sometimes passed.  */
2799 
2800 int
avr_function_arg_regno_p(int r)2801 avr_function_arg_regno_p(int r)
2802 {
2803   return (AVR_TINY ? r >= 20 && r <= 25 : r >= 8 && r <= 25);
2804 }
2805 
2806 
2807 /* Worker function for `INIT_CUMULATIVE_ARGS'.  */
2808 /* Initializing the variable cum for the state at the beginning
2809    of the argument list.  */
2810 
2811 void
avr_init_cumulative_args(CUMULATIVE_ARGS * cum,tree fntype,rtx libname,tree fndecl ATTRIBUTE_UNUSED)2812 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
2813                           tree fndecl ATTRIBUTE_UNUSED)
2814 {
2815   cum->nregs = AVR_TINY ? 6 : 18;
2816   cum->regno = FIRST_CUM_REG;
2817   if (!libname && stdarg_p (fntype))
2818     cum->nregs = 0;
2819 
2820   /* Assume the calle may be tail called */
2821 
2822   cfun->machine->sibcall_fails = 0;
2823 }
2824 
2825 /* Returns the number of registers to allocate for a function argument.  */
2826 
2827 static int
avr_num_arg_regs(machine_mode mode,const_tree type)2828 avr_num_arg_regs (machine_mode mode, const_tree type)
2829 {
2830   int size;
2831 
2832   if (mode == BLKmode)
2833     size = int_size_in_bytes (type);
2834   else
2835     size = GET_MODE_SIZE (mode);
2836 
2837   /* Align all function arguments to start in even-numbered registers.
2838      Odd-sized arguments leave holes above them.  */
2839 
2840   return (size + 1) & ~1;
2841 }
2842 
2843 
2844 /* Implement `TARGET_FUNCTION_ARG'.  */
2845 /* Controls whether a function argument is passed
2846    in a register, and which register.  */
2847 
2848 static rtx
avr_function_arg(cumulative_args_t cum_v,machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)2849 avr_function_arg (cumulative_args_t cum_v, machine_mode mode,
2850                   const_tree type, bool named ATTRIBUTE_UNUSED)
2851 {
2852   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2853   int bytes = avr_num_arg_regs (mode, type);
2854 
2855   if (cum->nregs && bytes <= cum->nregs)
2856     return gen_rtx_REG (mode, cum->regno - bytes);
2857 
2858   return NULL_RTX;
2859 }
2860 
2861 
2862 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'.  */
2863 /* Update the summarizer variable CUM to advance past an argument
2864    in the argument list.  */
2865 
2866 static void
avr_function_arg_advance(cumulative_args_t cum_v,machine_mode mode,const_tree type,bool named ATTRIBUTE_UNUSED)2867 avr_function_arg_advance (cumulative_args_t cum_v, machine_mode mode,
2868                           const_tree type, bool named ATTRIBUTE_UNUSED)
2869 {
2870   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2871   int bytes = avr_num_arg_regs (mode, type);
2872 
2873   cum->nregs -= bytes;
2874   cum->regno -= bytes;
2875 
2876   /* A parameter is being passed in a call-saved register.  As the original
2877      contents of these regs has to be restored before leaving the function,
2878      a function must not pass arguments in call-saved regs in order to get
2879      tail-called.  */
2880 
2881   if (cum->regno >= 8
2882       && cum->nregs >= 0
2883       && !call_used_regs[cum->regno])
2884     {
2885       /* FIXME: We ship info on failing tail-call in struct machine_function.
2886          This uses internals of calls.c:expand_call() and the way args_so_far
2887          is used.  targetm.function_ok_for_sibcall() needs to be extended to
2888          pass &args_so_far, too.  At present, CUMULATIVE_ARGS is target
2889          dependent so that such an extension is not wanted.  */
2890 
2891       cfun->machine->sibcall_fails = 1;
2892     }
2893 
2894   /* Test if all registers needed by the ABI are actually available.  If the
2895      user has fixed a GPR needed to pass an argument, an (implicit) function
2896      call will clobber that fixed register.  See PR45099 for an example.  */
2897 
2898   if (cum->regno >= 8
2899       && cum->nregs >= 0)
2900     {
2901       int regno;
2902 
2903       for (regno = cum->regno; regno < cum->regno + bytes; regno++)
2904         if (fixed_regs[regno])
2905           warning (0, "fixed register %s used to pass parameter to function",
2906                    reg_names[regno]);
2907     }
2908 
2909   if (cum->nregs <= 0)
2910     {
2911       cum->nregs = 0;
2912       cum->regno = FIRST_CUM_REG;
2913     }
2914 }
2915 
2916 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
2917 /* Decide whether we can make a sibling call to a function.  DECL is the
2918    declaration of the function being targeted by the call and EXP is the
2919    CALL_EXPR representing the call.  */
2920 
2921 static bool
avr_function_ok_for_sibcall(tree decl_callee,tree exp_callee)2922 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
2923 {
2924   tree fntype_callee;
2925 
2926   /* Tail-calling must fail if callee-saved regs are used to pass
2927      function args.  We must not tail-call when `epilogue_restores'
2928      is used.  Unfortunately, we cannot tell at this point if that
2929      actually will happen or not, and we cannot step back from
2930      tail-calling.  Thus, we inhibit tail-calling with -mcall-prologues.  */
2931 
2932   if (cfun->machine->sibcall_fails
2933       || TARGET_CALL_PROLOGUES)
2934     {
2935       return false;
2936     }
2937 
2938   fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
2939 
2940   if (decl_callee)
2941     {
2942       decl_callee = TREE_TYPE (decl_callee);
2943     }
2944   else
2945     {
2946       decl_callee = fntype_callee;
2947 
2948       while (FUNCTION_TYPE != TREE_CODE (decl_callee)
2949              && METHOD_TYPE != TREE_CODE (decl_callee))
2950         {
2951           decl_callee = TREE_TYPE (decl_callee);
2952         }
2953     }
2954 
2955   /* Ensure that caller and callee have compatible epilogues */
2956 
2957   if (cfun->machine->is_interrupt
2958       || cfun->machine->is_signal
2959       || cfun->machine->is_naked
2960       || avr_naked_function_p (decl_callee)
2961       /* FIXME: For OS_task and OS_main, this might be over-conservative.  */
2962       || (avr_OS_task_function_p (decl_callee)
2963           != cfun->machine->is_OS_task)
2964       || (avr_OS_main_function_p (decl_callee)
2965           != cfun->machine->is_OS_main))
2966     {
2967       return false;
2968     }
2969 
2970   return true;
2971 }
2972 
2973 /***********************************************************************
2974   Functions for outputting various mov's for a various modes
2975 ************************************************************************/
2976 
2977 /* Return true if a value of mode MODE is read from flash by
2978    __load_* function from libgcc.  */
2979 
2980 bool
avr_load_libgcc_p(rtx op)2981 avr_load_libgcc_p (rtx op)
2982 {
2983   machine_mode mode = GET_MODE (op);
2984   int n_bytes = GET_MODE_SIZE (mode);
2985 
2986   return (n_bytes > 2
2987           && !AVR_HAVE_LPMX
2988           && avr_mem_flash_p (op));
2989 }
2990 
2991 /* Return true if a value of mode MODE is read by __xload_* function.  */
2992 
2993 bool
avr_xload_libgcc_p(machine_mode mode)2994 avr_xload_libgcc_p (machine_mode mode)
2995 {
2996   int n_bytes = GET_MODE_SIZE (mode);
2997 
2998   return (n_bytes > 1
2999           || avr_n_flash > 1);
3000 }
3001 
3002 
3003 /* Fixme: This is a hack because secondary reloads don't works as expected.
3004 
3005    Find an unused d-register to be used as scratch in INSN.
3006    EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
3007    is a register, skip all possible return values that overlap EXCLUDE.
3008    The policy for the returned register is similar to that of
3009    `reg_unused_after', i.e. the returned register may overlap the SET_DEST
3010    of INSN.
3011 
3012    Return a QImode d-register or NULL_RTX if nothing found.  */
3013 
3014 static rtx
avr_find_unused_d_reg(rtx_insn * insn,rtx exclude)3015 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
3016 {
3017   int regno;
3018   bool isr_p = (avr_interrupt_function_p (current_function_decl)
3019                 || avr_signal_function_p (current_function_decl));
3020 
3021   for (regno = 16; regno < 32; regno++)
3022     {
3023       rtx reg = all_regs_rtx[regno];
3024 
3025       if ((exclude
3026            && reg_overlap_mentioned_p (exclude, reg))
3027           || fixed_regs[regno])
3028         {
3029           continue;
3030         }
3031 
3032       /* Try non-live register */
3033 
3034       if (!df_regs_ever_live_p (regno)
3035           && (TREE_THIS_VOLATILE (current_function_decl)
3036               || cfun->machine->is_OS_task
3037               || cfun->machine->is_OS_main
3038               || (!isr_p && call_used_regs[regno])))
3039         {
3040           return reg;
3041         }
3042 
3043       /* Any live register can be used if it is unused after.
3044          Prologue/epilogue will care for it as needed.  */
3045 
3046       if (df_regs_ever_live_p (regno)
3047           && reg_unused_after (insn, reg))
3048         {
3049           return reg;
3050         }
3051     }
3052 
3053   return NULL_RTX;
3054 }
3055 
3056 
3057 /* Helper function for the next function in the case where only restricted
3058    version of LPM instruction is available.  */
3059 
3060 static const char*
avr_out_lpm_no_lpmx(rtx_insn * insn,rtx * xop,int * plen)3061 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
3062 {
3063   rtx dest = xop[0];
3064   rtx addr = xop[1];
3065   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3066   int regno_dest;
3067 
3068   regno_dest = REGNO (dest);
3069 
3070   /* The implicit target register of LPM.  */
3071   xop[3] = lpm_reg_rtx;
3072 
3073   switch (GET_CODE (addr))
3074     {
3075     default:
3076       gcc_unreachable();
3077 
3078     case REG:
3079 
3080       gcc_assert (REG_Z == REGNO (addr));
3081 
3082       switch (n_bytes)
3083         {
3084         default:
3085           gcc_unreachable();
3086 
3087         case 1:
3088           avr_asm_len ("%4lpm", xop, plen, 1);
3089 
3090           if (regno_dest != LPM_REGNO)
3091             avr_asm_len ("mov %0,%3", xop, plen, 1);
3092 
3093           return "";
3094 
3095         case 2:
3096           if (REGNO (dest) == REG_Z)
3097             return avr_asm_len ("%4lpm"      CR_TAB
3098                                 "push %3"    CR_TAB
3099                                 "adiw %2,1"  CR_TAB
3100                                 "%4lpm"      CR_TAB
3101                                 "mov %B0,%3" CR_TAB
3102                                 "pop %A0", xop, plen, 6);
3103 
3104           avr_asm_len ("%4lpm"      CR_TAB
3105                        "mov %A0,%3" CR_TAB
3106                        "adiw %2,1"  CR_TAB
3107                        "%4lpm"      CR_TAB
3108                        "mov %B0,%3", xop, plen, 5);
3109 
3110           if (!reg_unused_after (insn, addr))
3111             avr_asm_len ("sbiw %2,1", xop, plen, 1);
3112 
3113           break; /* 2 */
3114         }
3115 
3116       break; /* REG */
3117 
3118     case POST_INC:
3119 
3120       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3121                   && n_bytes <= 4);
3122 
3123       if (regno_dest == LPM_REGNO)
3124         avr_asm_len ("%4lpm"      CR_TAB
3125                      "adiw %2,1", xop, plen, 2);
3126       else
3127         avr_asm_len ("%4lpm"      CR_TAB
3128                      "mov %A0,%3" CR_TAB
3129                      "adiw %2,1", xop, plen, 3);
3130 
3131       if (n_bytes >= 2)
3132         avr_asm_len ("%4lpm"      CR_TAB
3133                      "mov %B0,%3" CR_TAB
3134                      "adiw %2,1", xop, plen, 3);
3135 
3136       if (n_bytes >= 3)
3137         avr_asm_len ("%4lpm"      CR_TAB
3138                      "mov %C0,%3" CR_TAB
3139                      "adiw %2,1", xop, plen, 3);
3140 
3141       if (n_bytes >= 4)
3142         avr_asm_len ("%4lpm"      CR_TAB
3143                      "mov %D0,%3" CR_TAB
3144                      "adiw %2,1", xop, plen, 3);
3145 
3146       break; /* POST_INC */
3147 
3148     } /* switch CODE (addr) */
3149 
3150   return "";
3151 }
3152 
3153 
3154 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
3155    OP[1] in AS1 to register OP[0].
3156    If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
3157    Return "".  */
3158 
3159 const char*
avr_out_lpm(rtx_insn * insn,rtx * op,int * plen)3160 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
3161 {
3162   rtx xop[7];
3163   rtx dest = op[0];
3164   rtx src = SET_SRC (single_set (insn));
3165   rtx addr;
3166   int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
3167   int segment;
3168   RTX_CODE code;
3169   addr_space_t as = MEM_ADDR_SPACE (src);
3170 
3171   if (plen)
3172     *plen = 0;
3173 
3174   if (MEM_P (dest))
3175     {
3176       warning (0, "writing to address space %qs not supported",
3177                avr_addrspace[MEM_ADDR_SPACE (dest)].name);
3178 
3179       return "";
3180     }
3181 
3182   addr = XEXP (src, 0);
3183   code = GET_CODE (addr);
3184 
3185   gcc_assert (REG_P (dest));
3186   gcc_assert (REG == code || POST_INC == code);
3187 
3188   xop[0] = dest;
3189   xop[1] = addr;
3190   xop[2] = lpm_addr_reg_rtx;
3191   xop[4] = xstring_empty;
3192   xop[5] = tmp_reg_rtx;
3193   xop[6] = XEXP (rampz_rtx, 0);
3194 
3195   segment = avr_addrspace[as].segment;
3196 
3197   /* Set RAMPZ as needed.  */
3198 
3199   if (segment)
3200     {
3201       xop[4] = GEN_INT (segment);
3202       xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
3203 
3204       if (xop[3] != NULL_RTX)
3205         {
3206           avr_asm_len ("ldi %3,%4" CR_TAB
3207                        "out %i6,%3", xop, plen, 2);
3208         }
3209       else if (segment == 1)
3210         {
3211           avr_asm_len ("clr %5" CR_TAB
3212                        "inc %5" CR_TAB
3213                        "out %i6,%5", xop, plen, 3);
3214         }
3215       else
3216         {
3217           avr_asm_len ("mov %5,%2"         CR_TAB
3218                        "ldi %2,%4"         CR_TAB
3219                        "out %i6,%2"  CR_TAB
3220                        "mov %2,%5", xop, plen, 4);
3221         }
3222 
3223       xop[4] = xstring_e;
3224 
3225       if (!AVR_HAVE_ELPMX)
3226         return avr_out_lpm_no_lpmx (insn, xop, plen);
3227     }
3228   else if (!AVR_HAVE_LPMX)
3229     {
3230       return avr_out_lpm_no_lpmx (insn, xop, plen);
3231     }
3232 
3233   /* We have [E]LPMX: Output reading from Flash the comfortable way.  */
3234 
3235   switch (GET_CODE (addr))
3236     {
3237     default:
3238       gcc_unreachable();
3239 
3240     case REG:
3241 
3242       gcc_assert (REG_Z == REGNO (addr));
3243 
3244       switch (n_bytes)
3245         {
3246         default:
3247           gcc_unreachable();
3248 
3249         case 1:
3250           return avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
3251 
3252         case 2:
3253           if (REGNO (dest) == REG_Z)
3254             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3255                                 "%4lpm %B0,%a2" CR_TAB
3256                                 "mov %A0,%5", xop, plen, 3);
3257           else
3258             {
3259               avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3260                            "%4lpm %B0,%a2", xop, plen, 2);
3261 
3262               if (!reg_unused_after (insn, addr))
3263                 avr_asm_len ("sbiw %2,1", xop, plen, 1);
3264             }
3265 
3266           break; /* 2 */
3267 
3268         case 3:
3269 
3270           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3271                        "%4lpm %B0,%a2+" CR_TAB
3272                        "%4lpm %C0,%a2", xop, plen, 3);
3273 
3274           if (!reg_unused_after (insn, addr))
3275             avr_asm_len ("sbiw %2,2", xop, plen, 1);
3276 
3277           break; /* 3 */
3278 
3279         case 4:
3280 
3281           avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
3282                        "%4lpm %B0,%a2+", xop, plen, 2);
3283 
3284           if (REGNO (dest) == REG_Z - 2)
3285             return avr_asm_len ("%4lpm %5,%a2+" CR_TAB
3286                                 "%4lpm %C0,%a2"          CR_TAB
3287                                 "mov %D0,%5", xop, plen, 3);
3288           else
3289             {
3290               avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
3291                            "%4lpm %D0,%a2", xop, plen, 2);
3292 
3293               if (!reg_unused_after (insn, addr))
3294                 avr_asm_len ("sbiw %2,3", xop, plen, 1);
3295             }
3296 
3297           break; /* 4 */
3298         } /* n_bytes */
3299 
3300       break; /* REG */
3301 
3302     case POST_INC:
3303 
3304       gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
3305                   && n_bytes <= 4);
3306 
3307       avr_asm_len                    ("%4lpm %A0,%a2+", xop, plen, 1);
3308       if (n_bytes >= 2)  avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
3309       if (n_bytes >= 3)  avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
3310       if (n_bytes >= 4)  avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
3311 
3312       break; /* POST_INC */
3313 
3314     } /* switch CODE (addr) */
3315 
3316   if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
3317     {
3318       /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM.  */
3319 
3320       xop[0] = zero_reg_rtx;
3321       avr_asm_len ("out %i6,%0", xop, plen, 1);
3322     }
3323 
3324   return "";
3325 }
3326 
3327 
3328 /* Worker function for xload_8 insn.  */
3329 
3330 const char*
avr_out_xload(rtx_insn * insn ATTRIBUTE_UNUSED,rtx * op,int * plen)3331 avr_out_xload (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
3332 {
3333   rtx xop[4];
3334 
3335   xop[0] = op[0];
3336   xop[1] = op[1];
3337   xop[2] = lpm_addr_reg_rtx;
3338   xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
3339 
3340   avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
3341 
3342   avr_asm_len ("sbrc %1,7" CR_TAB
3343                "ld %3,%a2", xop, plen, 2);
3344 
3345   if (REGNO (xop[0]) != REGNO (xop[3]))
3346     avr_asm_len ("mov %0,%3", xop, plen, 1);
3347 
3348   return "";
3349 }
3350 
3351 
3352 const char*
output_movqi(rtx_insn * insn,rtx operands[],int * plen)3353 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
3354 {
3355   rtx dest = operands[0];
3356   rtx src = operands[1];
3357 
3358   if (avr_mem_flash_p (src)
3359       || avr_mem_flash_p (dest))
3360     {
3361       return avr_out_lpm (insn, operands, plen);
3362     }
3363 
3364   gcc_assert (1 == GET_MODE_SIZE (GET_MODE (dest)));
3365 
3366   if (REG_P (dest))
3367     {
3368       if (REG_P (src)) /* mov r,r */
3369         {
3370           if (test_hard_reg_class (STACK_REG, dest))
3371             return avr_asm_len ("out %0,%1", operands, plen, -1);
3372           else if (test_hard_reg_class (STACK_REG, src))
3373             return avr_asm_len ("in %0,%1", operands, plen, -1);
3374 
3375           return avr_asm_len ("mov %0,%1", operands, plen, -1);
3376         }
3377       else if (CONSTANT_P (src))
3378         {
3379           output_reload_in_const (operands, NULL_RTX, plen, false);
3380           return "";
3381         }
3382       else if (MEM_P (src))
3383         return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
3384     }
3385   else if (MEM_P (dest))
3386     {
3387       rtx xop[2];
3388 
3389       xop[0] = dest;
3390       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3391 
3392       return out_movqi_mr_r (insn, xop, plen);
3393     }
3394 
3395   return "";
3396 }
3397 
3398 
3399 const char *
output_movhi(rtx_insn * insn,rtx xop[],int * plen)3400 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
3401 {
3402   rtx dest = xop[0];
3403   rtx src = xop[1];
3404 
3405   gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
3406 
3407   if (avr_mem_flash_p (src)
3408       || avr_mem_flash_p (dest))
3409     {
3410       return avr_out_lpm (insn, xop, plen);
3411     }
3412 
3413   gcc_assert (2 == GET_MODE_SIZE (GET_MODE (dest)));
3414 
3415   if (REG_P (dest))
3416     {
3417       if (REG_P (src)) /* mov r,r */
3418         {
3419           if (test_hard_reg_class (STACK_REG, dest))
3420             {
3421               if (AVR_HAVE_8BIT_SP)
3422                 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
3423 
3424               if (AVR_XMEGA)
3425                 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
3426                                     "out __SP_H__,%B1", xop, plen, -2);
3427 
3428               /* Use simple load of SP if no interrupts are  used.  */
3429 
3430               return TARGET_NO_INTERRUPTS
3431                 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
3432                                "out __SP_L__,%A1", xop, plen, -2)
3433                 : avr_asm_len ("in __tmp_reg__,__SREG__"  CR_TAB
3434                                "cli"                      CR_TAB
3435                                "out __SP_H__,%B1"         CR_TAB
3436                                "out __SREG__,__tmp_reg__" CR_TAB
3437                                "out __SP_L__,%A1", xop, plen, -5);
3438             }
3439           else if (test_hard_reg_class (STACK_REG, src))
3440             {
3441               return !AVR_HAVE_SPH
3442                 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
3443                                "clr %B0", xop, plen, -2)
3444 
3445                 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
3446                                "in %B0,__SP_H__", xop, plen, -2);
3447             }
3448 
3449           return AVR_HAVE_MOVW
3450             ? avr_asm_len ("movw %0,%1", xop, plen, -1)
3451 
3452             : avr_asm_len ("mov %A0,%A1" CR_TAB
3453                            "mov %B0,%B1", xop, plen, -2);
3454         } /* REG_P (src) */
3455       else if (CONSTANT_P (src))
3456         {
3457           return output_reload_inhi (xop, NULL, plen);
3458         }
3459       else if (MEM_P (src))
3460         {
3461           return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
3462         }
3463     }
3464   else if (MEM_P (dest))
3465     {
3466       rtx xop[2];
3467 
3468       xop[0] = dest;
3469       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
3470 
3471       return out_movhi_mr_r (insn, xop, plen);
3472     }
3473 
3474   fatal_insn ("invalid insn:", insn);
3475 
3476   return "";
3477 }
3478 
3479 
3480 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
3481 
3482 static const char*
avr_out_movqi_r_mr_reg_disp_tiny(rtx_insn * insn,rtx op[],int * plen)3483 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
3484 {
3485   rtx dest = op[0];
3486   rtx src = op[1];
3487   rtx x = XEXP (src, 0);
3488 
3489   avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3490                "ld %0,%b1" , op, plen, -3);
3491 
3492   if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3493       && !reg_unused_after (insn, XEXP (x,0)))
3494     avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
3495 
3496   return "";
3497 }
3498 
3499 static const char*
out_movqi_r_mr(rtx_insn * insn,rtx op[],int * plen)3500 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3501 {
3502   rtx dest = op[0];
3503   rtx src = op[1];
3504   rtx x = XEXP (src, 0);
3505 
3506   if (CONSTANT_ADDRESS_P (x))
3507     {
3508       int n_words = AVR_TINY ? 1 : 2;
3509       return io_address_operand (x, QImode)
3510         ? avr_asm_len ("in %0,%i1", op, plen, -1)
3511         : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
3512     }
3513 
3514   if (GET_CODE (x) == PLUS
3515            && REG_P (XEXP (x, 0))
3516            && CONST_INT_P (XEXP (x, 1)))
3517     {
3518       /* memory access by reg+disp */
3519 
3520       int disp = INTVAL (XEXP (x, 1));
3521 
3522       if (AVR_TINY)
3523         return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
3524 
3525       if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
3526         {
3527           if (REGNO (XEXP (x, 0)) != REG_Y)
3528             fatal_insn ("incorrect insn:",insn);
3529 
3530           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3531             return avr_asm_len ("adiw r28,%o1-63" CR_TAB
3532                                 "ldd %0,Y+63"     CR_TAB
3533                                 "sbiw r28,%o1-63", op, plen, -3);
3534 
3535           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3536                               "sbci r29,hi8(-%o1)" CR_TAB
3537                               "ld %0,Y"            CR_TAB
3538                               "subi r28,lo8(%o1)"  CR_TAB
3539                               "sbci r29,hi8(%o1)", op, plen, -5);
3540         }
3541       else if (REGNO (XEXP (x, 0)) == REG_X)
3542         {
3543           /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
3544              it but I have this situation with extremal optimizing options.  */
3545 
3546           avr_asm_len ("adiw r26,%o1" CR_TAB
3547                        "ld %0,X", op, plen, -2);
3548 
3549           if (!reg_overlap_mentioned_p (dest, XEXP (x,0))
3550               && !reg_unused_after (insn, XEXP (x,0)))
3551             {
3552               avr_asm_len ("sbiw r26,%o1", op, plen, 1);
3553             }
3554 
3555           return "";
3556         }
3557 
3558       return avr_asm_len ("ldd %0,%1", op, plen, -1);
3559     }
3560 
3561   return avr_asm_len ("ld %0,%1", op, plen, -1);
3562 }
3563 
3564 
3565 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3566 
3567 static const char*
avr_out_movhi_r_mr_reg_no_disp_tiny(rtx op[],int * plen)3568 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx op[], int *plen)
3569 {
3570   rtx dest = op[0];
3571   rtx src = op[1];
3572   rtx base = XEXP (src, 0);
3573 
3574   int reg_dest = true_regnum (dest);
3575   int reg_base = true_regnum (base);
3576 
3577   if (reg_dest == reg_base)         /* R = (R) */
3578     return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3579 			"ld %B0,%1"          CR_TAB
3580 			"mov %A0,__tmp_reg__", op, plen, -3);
3581 
3582   return avr_asm_len ("ld %A0,%1"             CR_TAB
3583                       TINY_ADIW (%E1, %F1, 1) CR_TAB
3584                       "ld %B0,%1"             CR_TAB
3585                       TINY_SBIW (%E1, %F1, 1), op, plen, -6);
3586 }
3587 
3588 
3589 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3590 
3591 static const char*
avr_out_movhi_r_mr_reg_disp_tiny(rtx op[],int * plen)3592 avr_out_movhi_r_mr_reg_disp_tiny (rtx op[], int *plen)
3593 {
3594   rtx dest = op[0];
3595   rtx src = op[1];
3596   rtx base = XEXP (src, 0);
3597 
3598   int reg_dest = true_regnum (dest);
3599   int reg_base = true_regnum (XEXP (base, 0));
3600 
3601   if (reg_base == reg_dest)
3602     {
3603       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3604                           "ld __tmp_reg__,%b1+"     CR_TAB
3605                           "ld %B0,%b1"              CR_TAB
3606                           "mov %A0,__tmp_reg__", op, plen, -5);
3607     }
3608   else
3609     {
3610       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3611                           "ld %A0,%b1+"             CR_TAB
3612                           "ld %B0,%b1"              CR_TAB
3613                           TINY_SBIW (%I1, %J1, %o1+1), op, plen, -6);
3614     }
3615 }
3616 
3617 
3618 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
3619 
3620 static const char*
avr_out_movhi_r_mr_pre_dec_tiny(rtx_insn * insn,rtx op[],int * plen)3621 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
3622 {
3623   int mem_volatile_p = 0;
3624   rtx dest = op[0];
3625   rtx src = op[1];
3626   rtx base = XEXP (src, 0);
3627 
3628   /* "volatile" forces reading low byte first, even if less efficient,
3629      for correct operation with 16-bit I/O registers.  */
3630   mem_volatile_p = MEM_VOLATILE_P (src);
3631 
3632   if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3633     fatal_insn ("incorrect insn:", insn);
3634 
3635   if (!mem_volatile_p)
3636     return avr_asm_len ("ld %B0,%1" CR_TAB
3637                         "ld %A0,%1", op, plen, -2);
3638 
3639   return avr_asm_len (TINY_SBIW (%I1, %J1, 2)  CR_TAB
3640                       "ld %A0,%p1+"            CR_TAB
3641                       "ld %B0,%p1"             CR_TAB
3642                       TINY_SBIW (%I1, %J1, 1), op, plen, -6);
3643 }
3644 
3645 
3646 static const char*
out_movhi_r_mr(rtx_insn * insn,rtx op[],int * plen)3647 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
3648 {
3649   rtx dest = op[0];
3650   rtx src = op[1];
3651   rtx base = XEXP (src, 0);
3652   int reg_dest = true_regnum (dest);
3653   int reg_base = true_regnum (base);
3654   /* "volatile" forces reading low byte first, even if less efficient,
3655      for correct operation with 16-bit I/O registers.  */
3656   int mem_volatile_p = MEM_VOLATILE_P (src);
3657 
3658   if (reg_base > 0)
3659     {
3660       if (AVR_TINY)
3661         return avr_out_movhi_r_mr_reg_no_disp_tiny (op, plen);
3662 
3663       if (reg_dest == reg_base)         /* R = (R) */
3664         return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
3665                             "ld %B0,%1"          CR_TAB
3666                             "mov %A0,__tmp_reg__", op, plen, -3);
3667 
3668       if (reg_base != REG_X)
3669         return avr_asm_len ("ld %A0,%1" CR_TAB
3670                             "ldd %B0,%1+1", op, plen, -2);
3671 
3672       avr_asm_len ("ld %A0,X+" CR_TAB
3673                    "ld %B0,X", op, plen, -2);
3674 
3675       if (!reg_unused_after (insn, base))
3676         avr_asm_len ("sbiw r26,1", op, plen, 1);
3677 
3678       return "";
3679     }
3680   else if (GET_CODE (base) == PLUS) /* (R + i) */
3681     {
3682       int disp = INTVAL (XEXP (base, 1));
3683       int reg_base = true_regnum (XEXP (base, 0));
3684 
3685       if (AVR_TINY)
3686         return avr_out_movhi_r_mr_reg_disp_tiny (op, plen);
3687 
3688       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3689         {
3690           if (REGNO (XEXP (base, 0)) != REG_Y)
3691             fatal_insn ("incorrect insn:",insn);
3692 
3693           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
3694             ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
3695                            "ldd %A0,Y+62"    CR_TAB
3696                            "ldd %B0,Y+63"    CR_TAB
3697                            "sbiw r28,%o1-62", op, plen, -4)
3698 
3699               : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
3700                            "sbci r29,hi8(-%o1)" CR_TAB
3701                            "ld %A0,Y"           CR_TAB
3702                            "ldd %B0,Y+1"        CR_TAB
3703                            "subi r28,lo8(%o1)"  CR_TAB
3704                            "sbci r29,hi8(%o1)", op, plen, -6);
3705         }
3706 
3707       /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
3708          it but I have this situation with extremal
3709          optimization options.  */
3710 
3711       if (reg_base == REG_X)
3712         return reg_base == reg_dest
3713           ? avr_asm_len ("adiw r26,%o1"      CR_TAB
3714                          "ld __tmp_reg__,X+" CR_TAB
3715                          "ld %B0,X"          CR_TAB
3716                          "mov %A0,__tmp_reg__", op, plen, -4)
3717 
3718           : avr_asm_len ("adiw r26,%o1" CR_TAB
3719                          "ld %A0,X+"    CR_TAB
3720                          "ld %B0,X"     CR_TAB
3721                          "sbiw r26,%o1+1", op, plen, -4);
3722 
3723       return reg_base == reg_dest
3724         ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
3725                        "ldd %B0,%B1"         CR_TAB
3726                        "mov %A0,__tmp_reg__", op, plen, -3)
3727 
3728         : avr_asm_len ("ldd %A0,%A1" CR_TAB
3729                        "ldd %B0,%B1", op, plen, -2);
3730     }
3731   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
3732     {
3733       if (AVR_TINY)
3734 	return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
3735 
3736       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3737         fatal_insn ("incorrect insn:", insn);
3738 
3739       if (!mem_volatile_p)
3740         return avr_asm_len ("ld %B0,%1" CR_TAB
3741                             "ld %A0,%1", op, plen, -2);
3742 
3743       return REGNO (XEXP (base, 0)) == REG_X
3744         ? avr_asm_len ("sbiw r26,2"  CR_TAB
3745                        "ld %A0,X+"   CR_TAB
3746                        "ld %B0,X"    CR_TAB
3747                        "sbiw r26,1", op, plen, -4)
3748 
3749         : avr_asm_len ("sbiw %r1,2"  CR_TAB
3750                        "ld %A0,%p1"  CR_TAB
3751                        "ldd %B0,%p1+1", op, plen, -3);
3752     }
3753   else if (GET_CODE (base) == POST_INC) /* (R++) */
3754     {
3755       if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
3756         fatal_insn ("incorrect insn:", insn);
3757 
3758       return avr_asm_len ("ld %A0,%1"  CR_TAB
3759                           "ld %B0,%1", op, plen, -2);
3760     }
3761   else if (CONSTANT_ADDRESS_P (base))
3762     {
3763       int n_words = AVR_TINY ? 2 : 4;
3764       return io_address_operand (base, HImode)
3765         ? avr_asm_len ("in %A0,%i1" CR_TAB
3766                        "in %B0,%i1+1", op, plen, -2)
3767 
3768         : avr_asm_len ("lds %A0,%m1" CR_TAB
3769                        "lds %B0,%m1+1", op, plen, -n_words);
3770     }
3771 
3772   fatal_insn ("unknown move insn:",insn);
3773   return "";
3774 }
3775 
3776 static const char*
avr_out_movsi_r_mr_reg_no_disp_tiny(rtx_insn * insn,rtx op[],int * l)3777 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3778 {
3779   rtx dest = op[0];
3780   rtx src = op[1];
3781   rtx base = XEXP (src, 0);
3782   int reg_dest = true_regnum (dest);
3783   int reg_base = true_regnum (base);
3784 
3785   if (reg_dest == reg_base)
3786     {
3787       /* "ld r26,-X" is undefined */
3788       return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
3789 		      "ld %D0,%1"             CR_TAB
3790 		      "ld %C0,-%1"            CR_TAB
3791 		      "ld __tmp_reg__,-%1"    CR_TAB
3792 		      TINY_SBIW (%E1, %F1, 1) CR_TAB
3793 		      "ld %A0,%1"             CR_TAB
3794 		      "mov %B0,__tmp_reg__");
3795     }
3796   else if (reg_dest == reg_base - 2)
3797     {
3798       return *l = 5, ("ld %A0,%1+"            CR_TAB
3799 		      "ld %B0,%1+"            CR_TAB
3800 		      "ld __tmp_reg__,%1+"    CR_TAB
3801 		      "ld %D0,%1"             CR_TAB
3802 		      "mov %C0,__tmp_reg__");
3803     }
3804   else if (reg_unused_after (insn, base))
3805     {
3806       return *l = 4, ("ld %A0,%1+"    CR_TAB
3807 		      "ld %B0,%1+"    CR_TAB
3808 		      "ld %C0,%1+"    CR_TAB
3809 		      "ld %D0,%1");
3810     }
3811   else
3812     {
3813       return *l = 6, ("ld %A0,%1+"    CR_TAB
3814 		      "ld %B0,%1+"    CR_TAB
3815 		      "ld %C0,%1+"    CR_TAB
3816 		      "ld %D0,%1"     CR_TAB
3817 		      TINY_SBIW (%E1, %F1, 3));
3818     }
3819 }
3820 
3821 
3822 static const char*
avr_out_movsi_r_mr_reg_disp_tiny(rtx_insn * insn,rtx op[],int * l)3823 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
3824 {
3825   rtx dest = op[0];
3826   rtx src = op[1];
3827   rtx base = XEXP (src, 0);
3828   int reg_dest = true_regnum (dest);
3829   int reg_base = true_regnum (XEXP (base, 0));
3830 
3831   if (reg_dest == reg_base)
3832     {
3833       /* "ld r26,-X" is undefined */
3834       return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
3835                       "ld %D0,%b1"                CR_TAB
3836                       "ld %C0,-%b1"               CR_TAB
3837                       "ld __tmp_reg__,-%b1"       CR_TAB
3838                       TINY_SBIW (%I1, %J1, 1)     CR_TAB
3839                       "ld %A0,%b1"                CR_TAB
3840                       "mov %B0,__tmp_reg__");
3841     }
3842   else if (reg_dest == reg_base - 2)
3843     {
3844       return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3845                       "ld %A0,%b1+"             CR_TAB
3846                       "ld %B0,%b1+"             CR_TAB
3847                       "ld __tmp_reg__,%b1+"     CR_TAB
3848                       "ld %D0,%b1"              CR_TAB
3849                       "mov %C0,__tmp_reg__");
3850     }
3851   else if (reg_unused_after (insn, XEXP (base, 0)))
3852     {
3853       return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
3854                       "ld %A0,%b1+"             CR_TAB
3855                       "ld %B0,%b1+"             CR_TAB
3856                       "ld %C0,%b1+"             CR_TAB
3857                       "ld %D0,%b1");
3858     }
3859   else
3860     {
3861       return *l = 8, (TINY_ADIW (%I1, %J1, %o1)  CR_TAB
3862                       "ld %A0,%b1+"              CR_TAB
3863                       "ld %B0,%b1+"              CR_TAB
3864                       "ld %C0,%b1+"              CR_TAB
3865                       "ld %D0,%b1"               CR_TAB
3866                       TINY_SBIW (%I1, %J1, %o1+3));
3867     }
3868 }
3869 
3870 static const char*
out_movsi_r_mr(rtx_insn * insn,rtx op[],int * l)3871 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
3872 {
3873   rtx dest = op[0];
3874   rtx src = op[1];
3875   rtx base = XEXP (src, 0);
3876   int reg_dest = true_regnum (dest);
3877   int reg_base = true_regnum (base);
3878   int tmp;
3879 
3880   if (!l)
3881     l = &tmp;
3882 
3883   if (reg_base > 0)
3884     {
3885       if (AVR_TINY)
3886         return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
3887 
3888       if (reg_base == REG_X)        /* (R26) */
3889         {
3890           if (reg_dest == REG_X)
3891 	    /* "ld r26,-X" is undefined */
3892 	    return *l=7, ("adiw r26,3"        CR_TAB
3893 			  "ld r29,X"          CR_TAB
3894 			  "ld r28,-X"         CR_TAB
3895 			  "ld __tmp_reg__,-X" CR_TAB
3896 			  "sbiw r26,1"        CR_TAB
3897 			  "ld r26,X"          CR_TAB
3898 			  "mov r27,__tmp_reg__");
3899           else if (reg_dest == REG_X - 2)
3900             return *l=5, ("ld %A0,X+"          CR_TAB
3901                           "ld %B0,X+"          CR_TAB
3902                           "ld __tmp_reg__,X+"  CR_TAB
3903                           "ld %D0,X"           CR_TAB
3904                           "mov %C0,__tmp_reg__");
3905           else if (reg_unused_after (insn, base))
3906             return  *l=4, ("ld %A0,X+"  CR_TAB
3907                            "ld %B0,X+" CR_TAB
3908                            "ld %C0,X+" CR_TAB
3909                            "ld %D0,X");
3910           else
3911             return  *l=5, ("ld %A0,X+"  CR_TAB
3912                            "ld %B0,X+" CR_TAB
3913                            "ld %C0,X+" CR_TAB
3914                            "ld %D0,X"  CR_TAB
3915                            "sbiw r26,3");
3916         }
3917       else
3918         {
3919           if (reg_dest == reg_base)
3920             return *l=5, ("ldd %D0,%1+3" CR_TAB
3921                           "ldd %C0,%1+2" CR_TAB
3922                           "ldd __tmp_reg__,%1+1"  CR_TAB
3923                           "ld %A0,%1"  CR_TAB
3924                           "mov %B0,__tmp_reg__");
3925           else if (reg_base == reg_dest + 2)
3926             return *l=5, ("ld %A0,%1"             CR_TAB
3927                           "ldd %B0,%1+1"          CR_TAB
3928                           "ldd __tmp_reg__,%1+2"  CR_TAB
3929                           "ldd %D0,%1+3"          CR_TAB
3930                           "mov %C0,__tmp_reg__");
3931           else
3932             return *l=4, ("ld %A0,%1"    CR_TAB
3933                           "ldd %B0,%1+1" CR_TAB
3934                           "ldd %C0,%1+2" CR_TAB
3935                           "ldd %D0,%1+3");
3936         }
3937     }
3938   else if (GET_CODE (base) == PLUS) /* (R + i) */
3939     {
3940       int disp = INTVAL (XEXP (base, 1));
3941 
3942       if (AVR_TINY)
3943         return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
3944 
3945       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
3946 	{
3947 	  if (REGNO (XEXP (base, 0)) != REG_Y)
3948 	    fatal_insn ("incorrect insn:",insn);
3949 
3950 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
3951 	    return *l = 6, ("adiw r28,%o1-60" CR_TAB
3952 			    "ldd %A0,Y+60"    CR_TAB
3953 			    "ldd %B0,Y+61"    CR_TAB
3954 			    "ldd %C0,Y+62"    CR_TAB
3955 			    "ldd %D0,Y+63"    CR_TAB
3956 			    "sbiw r28,%o1-60");
3957 
3958 	  return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
3959 			  "sbci r29,hi8(-%o1)" CR_TAB
3960 			  "ld %A0,Y"           CR_TAB
3961 			  "ldd %B0,Y+1"        CR_TAB
3962 			  "ldd %C0,Y+2"        CR_TAB
3963 			  "ldd %D0,Y+3"        CR_TAB
3964 			  "subi r28,lo8(%o1)"  CR_TAB
3965 			  "sbci r29,hi8(%o1)");
3966 	}
3967 
3968       reg_base = true_regnum (XEXP (base, 0));
3969       if (reg_base == REG_X)
3970 	{
3971 	  /* R = (X + d) */
3972 	  if (reg_dest == REG_X)
3973 	    {
3974 	      *l = 7;
3975 	      /* "ld r26,-X" is undefined */
3976 	      return ("adiw r26,%o1+3"    CR_TAB
3977 		      "ld r29,X"          CR_TAB
3978 		      "ld r28,-X"         CR_TAB
3979 		      "ld __tmp_reg__,-X" CR_TAB
3980 		      "sbiw r26,1"        CR_TAB
3981 		      "ld r26,X"          CR_TAB
3982 		      "mov r27,__tmp_reg__");
3983 	    }
3984 	  *l = 6;
3985 	  if (reg_dest == REG_X - 2)
3986 	    return ("adiw r26,%o1"      CR_TAB
3987 		    "ld r24,X+"         CR_TAB
3988 		    "ld r25,X+"         CR_TAB
3989 		    "ld __tmp_reg__,X+" CR_TAB
3990 		    "ld r27,X"          CR_TAB
3991 		    "mov r26,__tmp_reg__");
3992 
3993 	  return ("adiw r26,%o1" CR_TAB
3994 		  "ld %A0,X+"    CR_TAB
3995 		  "ld %B0,X+"    CR_TAB
3996 		  "ld %C0,X+"    CR_TAB
3997 		  "ld %D0,X"     CR_TAB
3998 		  "sbiw r26,%o1+3");
3999 	}
4000       if (reg_dest == reg_base)
4001         return *l=5, ("ldd %D0,%D1"          CR_TAB
4002                       "ldd %C0,%C1"          CR_TAB
4003                       "ldd __tmp_reg__,%B1"  CR_TAB
4004                       "ldd %A0,%A1"          CR_TAB
4005                       "mov %B0,__tmp_reg__");
4006       else if (reg_dest == reg_base - 2)
4007         return *l=5, ("ldd %A0,%A1"          CR_TAB
4008                       "ldd %B0,%B1"          CR_TAB
4009                       "ldd __tmp_reg__,%C1"  CR_TAB
4010                       "ldd %D0,%D1"          CR_TAB
4011                       "mov %C0,__tmp_reg__");
4012       return *l=4, ("ldd %A0,%A1" CR_TAB
4013                     "ldd %B0,%B1" CR_TAB
4014                     "ldd %C0,%C1" CR_TAB
4015                     "ldd %D0,%D1");
4016     }
4017   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4018     return *l=4, ("ld %D0,%1" CR_TAB
4019 		  "ld %C0,%1" CR_TAB
4020 		  "ld %B0,%1" CR_TAB
4021 		  "ld %A0,%1");
4022   else if (GET_CODE (base) == POST_INC) /* (R++) */
4023     return *l=4, ("ld %A0,%1" CR_TAB
4024 		  "ld %B0,%1" CR_TAB
4025 		  "ld %C0,%1" CR_TAB
4026 		  "ld %D0,%1");
4027   else if (CONSTANT_ADDRESS_P (base))
4028     {
4029       if (io_address_operand (base, SImode))
4030         {
4031           *l = 4;
4032           return ("in %A0,%i1"   CR_TAB
4033                   "in %B0,%i1+1" CR_TAB
4034                   "in %C0,%i1+2" CR_TAB
4035                   "in %D0,%i1+3");
4036         }
4037       else
4038         {
4039           *l = AVR_TINY ? 4 : 8;
4040           return ("lds %A0,%m1"   CR_TAB
4041                   "lds %B0,%m1+1" CR_TAB
4042                   "lds %C0,%m1+2" CR_TAB
4043                   "lds %D0,%m1+3");
4044         }
4045     }
4046 
4047   fatal_insn ("unknown move insn:",insn);
4048   return "";
4049 }
4050 
4051 static const char*
avr_out_movsi_mr_r_reg_no_disp_tiny(rtx_insn * insn,rtx op[],int * l)4052 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
4053 {
4054   rtx dest = op[0];
4055   rtx src = op[1];
4056   rtx base = XEXP (dest, 0);
4057   int reg_base = true_regnum (base);
4058   int reg_src = true_regnum (src);
4059 
4060   if (reg_base == reg_src)
4061     {
4062 	  /* "ld r26,-X" is undefined */
4063       if (reg_unused_after (insn, base))
4064         {
4065           return *l = 7, ("mov __tmp_reg__, %B1"  CR_TAB
4066 			  "st %0,%A1"             CR_TAB
4067 			  TINY_ADIW (%E0, %F0, 1) CR_TAB
4068 			  "st %0+,__tmp_reg__"    CR_TAB
4069 			  "st %0+,%C1"            CR_TAB
4070 			  "st %0+,%D1");
4071         }
4072       else
4073         {
4074           return *l = 9, ("mov __tmp_reg__, %B1"  CR_TAB
4075 			  "st %0,%A1"             CR_TAB
4076 			  TINY_ADIW (%E0, %F0, 1) CR_TAB
4077 			  "st %0+,__tmp_reg__"    CR_TAB
4078 			  "st %0+,%C1"            CR_TAB
4079 			  "st %0+,%D1"            CR_TAB
4080 			  TINY_SBIW (%E0, %F0, 3));
4081         }
4082     }
4083   else if (reg_base == reg_src + 2)
4084     {
4085       if (reg_unused_after (insn, base))
4086 	return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
4087                         "mov __tmp_reg__,%D1"  CR_TAB
4088                         "st %0+,%A1"           CR_TAB
4089                         "st %0+,%B1"           CR_TAB
4090                         "st %0+,__zero_reg__"  CR_TAB
4091                         "st %0,__tmp_reg__"    CR_TAB
4092                         "clr __zero_reg__");
4093       else
4094 	return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
4095 			"mov __tmp_reg__,%D1"  CR_TAB
4096 			"st %0+,%A1"           CR_TAB
4097 			"st %0+,%B1"           CR_TAB
4098 			"st %0+,__zero_reg__"  CR_TAB
4099 			"st %0,__tmp_reg__"    CR_TAB
4100 			"clr __zero_reg__"     CR_TAB
4101 			TINY_SBIW (%E0, %F0, 3));
4102     }
4103 
4104   return *l = 6, ("st %0+,%A1" CR_TAB
4105 		  "st %0+,%B1" CR_TAB
4106 		  "st %0+,%C1" CR_TAB
4107 		  "st %0,%D1"  CR_TAB
4108 		  TINY_SBIW (%E0, %F0, 3));
4109 }
4110 
4111 static const char*
avr_out_movsi_mr_r_reg_disp_tiny(rtx op[],int * l)4112 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
4113 {
4114   rtx dest = op[0];
4115   rtx src = op[1];
4116   rtx base = XEXP (dest, 0);
4117   int reg_base = REGNO (XEXP (base, 0));
4118   int reg_src =true_regnum (src);
4119 
4120   if (reg_base == reg_src)
4121     {
4122       *l = 11;
4123       return ("mov __tmp_reg__,%A2"        CR_TAB
4124               "mov __zero_reg__,%B2"       CR_TAB
4125               TINY_ADIW (%I0, %J0, %o0)    CR_TAB
4126               "st %b0+,__tmp_reg__"        CR_TAB
4127               "st %b0+,__zero_reg__"       CR_TAB
4128               "st %b0+,%C2"                CR_TAB
4129               "st %b0,%D2"                 CR_TAB
4130               "clr __zero_reg__"           CR_TAB
4131               TINY_SBIW (%I0, %J0, %o0+3));
4132     }
4133   else if (reg_src == reg_base - 2)
4134     {
4135       *l = 11;
4136       return ("mov __tmp_reg__,%C2"         CR_TAB
4137               "mov __zero_reg__,%D2"        CR_TAB
4138               TINY_ADIW (%I0, %J0, %o0)     CR_TAB
4139               "st %b0+,%A0"                 CR_TAB
4140               "st %b0+,%B0"                 CR_TAB
4141               "st %b0+,__tmp_reg__"         CR_TAB
4142               "st %b0,__zero_reg__"         CR_TAB
4143               "clr __zero_reg__"            CR_TAB
4144               TINY_SBIW (%I0, %J0, %o0+3));
4145     }
4146   *l = 8;
4147   return (TINY_ADIW (%I0, %J0, %o0)     CR_TAB
4148           "st %b0+,%A1"                 CR_TAB
4149           "st %b0+,%B1"                 CR_TAB
4150           "st %b0+,%C1"                 CR_TAB
4151           "st %b0,%D1"                  CR_TAB
4152           TINY_SBIW (%I0, %J0, %o0+3));
4153 }
4154 
4155 static const char*
out_movsi_mr_r(rtx_insn * insn,rtx op[],int * l)4156 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
4157 {
4158   rtx dest = op[0];
4159   rtx src = op[1];
4160   rtx base = XEXP (dest, 0);
4161   int reg_base = true_regnum (base);
4162   int reg_src = true_regnum (src);
4163   int tmp;
4164 
4165   if (!l)
4166     l = &tmp;
4167 
4168   if (CONSTANT_ADDRESS_P (base))
4169     {
4170       if (io_address_operand (base, SImode))
4171         {
4172           return *l=4,("out %i0, %A1"  CR_TAB
4173                        "out %i0+1,%B1" CR_TAB
4174                        "out %i0+2,%C1" CR_TAB
4175                        "out %i0+3,%D1");
4176         }
4177       else
4178         {
4179           *l = AVR_TINY ? 4 : 8;
4180           return ("sts %m0,%A1"   CR_TAB
4181                   "sts %m0+1,%B1" CR_TAB
4182                   "sts %m0+2,%C1" CR_TAB
4183                   "sts %m0+3,%D1");
4184         }
4185     }
4186 
4187   if (reg_base > 0)                 /* (r) */
4188     {
4189       if (AVR_TINY)
4190         return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
4191 
4192       if (reg_base == REG_X)                /* (R26) */
4193         {
4194           if (reg_src == REG_X)
4195             {
4196 	      /* "st X+,r26" is undefined */
4197               if (reg_unused_after (insn, base))
4198 		return *l=6, ("mov __tmp_reg__,r27" CR_TAB
4199 			      "st X,r26"            CR_TAB
4200 			      "adiw r26,1"          CR_TAB
4201 			      "st X+,__tmp_reg__"   CR_TAB
4202 			      "st X+,r28"           CR_TAB
4203 			      "st X,r29");
4204               else
4205                 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
4206 			      "st X,r26"            CR_TAB
4207 			      "adiw r26,1"          CR_TAB
4208 			      "st X+,__tmp_reg__"   CR_TAB
4209 			      "st X+,r28"           CR_TAB
4210 			      "st X,r29"            CR_TAB
4211 			      "sbiw r26,3");
4212             }
4213           else if (reg_base == reg_src + 2)
4214             {
4215               if (reg_unused_after (insn, base))
4216                 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
4217                               "mov __tmp_reg__,%D1"  CR_TAB
4218                               "st %0+,%A1"           CR_TAB
4219                               "st %0+,%B1"           CR_TAB
4220                               "st %0+,__zero_reg__"  CR_TAB
4221                               "st %0,__tmp_reg__"    CR_TAB
4222                               "clr __zero_reg__");
4223               else
4224                 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
4225                               "mov __tmp_reg__,%D1"  CR_TAB
4226                               "st %0+,%A1"           CR_TAB
4227                               "st %0+,%B1"           CR_TAB
4228                               "st %0+,__zero_reg__"  CR_TAB
4229                               "st %0,__tmp_reg__"    CR_TAB
4230                               "clr __zero_reg__"     CR_TAB
4231                               "sbiw r26,3");
4232             }
4233           return *l=5, ("st %0+,%A1" CR_TAB
4234                         "st %0+,%B1" CR_TAB
4235                         "st %0+,%C1" CR_TAB
4236                         "st %0,%D1"  CR_TAB
4237                         "sbiw r26,3");
4238         }
4239       else
4240         return *l=4, ("st %0,%A1"    CR_TAB
4241 		      "std %0+1,%B1" CR_TAB
4242 		      "std %0+2,%C1" CR_TAB
4243 		      "std %0+3,%D1");
4244     }
4245   else if (GET_CODE (base) == PLUS) /* (R + i) */
4246     {
4247       int disp = INTVAL (XEXP (base, 1));
4248 
4249       if (AVR_TINY)
4250         return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
4251 
4252       reg_base = REGNO (XEXP (base, 0));
4253       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4254 	{
4255 	  if (reg_base != REG_Y)
4256 	    fatal_insn ("incorrect insn:",insn);
4257 
4258 	  if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4259 	    return *l = 6, ("adiw r28,%o0-60" CR_TAB
4260 			    "std Y+60,%A1"    CR_TAB
4261 			    "std Y+61,%B1"    CR_TAB
4262 			    "std Y+62,%C1"    CR_TAB
4263 			    "std Y+63,%D1"    CR_TAB
4264 			    "sbiw r28,%o0-60");
4265 
4266 	  return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
4267 			  "sbci r29,hi8(-%o0)" CR_TAB
4268 			  "st Y,%A1"           CR_TAB
4269 			  "std Y+1,%B1"        CR_TAB
4270 			  "std Y+2,%C1"        CR_TAB
4271 			  "std Y+3,%D1"        CR_TAB
4272 			  "subi r28,lo8(%o0)"  CR_TAB
4273 			  "sbci r29,hi8(%o0)");
4274 	}
4275       if (reg_base == REG_X)
4276 	{
4277 	  /* (X + d) = R */
4278 	  if (reg_src == REG_X)
4279 	    {
4280 	      *l = 9;
4281 	      return ("mov __tmp_reg__,r26"  CR_TAB
4282 		      "mov __zero_reg__,r27" CR_TAB
4283 		      "adiw r26,%o0"         CR_TAB
4284 		      "st X+,__tmp_reg__"    CR_TAB
4285 		      "st X+,__zero_reg__"   CR_TAB
4286 		      "st X+,r28"            CR_TAB
4287 		      "st X,r29"             CR_TAB
4288 		      "clr __zero_reg__"     CR_TAB
4289 		      "sbiw r26,%o0+3");
4290 	    }
4291 	  else if (reg_src == REG_X - 2)
4292 	    {
4293 	      *l = 9;
4294 	      return ("mov __tmp_reg__,r26"  CR_TAB
4295 		      "mov __zero_reg__,r27" CR_TAB
4296 		      "adiw r26,%o0"         CR_TAB
4297 		      "st X+,r24"            CR_TAB
4298 		      "st X+,r25"            CR_TAB
4299 		      "st X+,__tmp_reg__"    CR_TAB
4300 		      "st X,__zero_reg__"    CR_TAB
4301 		      "clr __zero_reg__"     CR_TAB
4302 		      "sbiw r26,%o0+3");
4303 	    }
4304 	  *l = 6;
4305 	  return ("adiw r26,%o0" CR_TAB
4306 		  "st X+,%A1"    CR_TAB
4307 		  "st X+,%B1"    CR_TAB
4308 		  "st X+,%C1"    CR_TAB
4309 		  "st X,%D1"     CR_TAB
4310 		  "sbiw r26,%o0+3");
4311 	}
4312       return *l=4, ("std %A0,%A1" CR_TAB
4313 		    "std %B0,%B1" CR_TAB
4314 		    "std %C0,%C1" CR_TAB
4315 		    "std %D0,%D1");
4316     }
4317   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4318     return *l=4, ("st %0,%D1" CR_TAB
4319 		  "st %0,%C1" CR_TAB
4320 		  "st %0,%B1" CR_TAB
4321 		  "st %0,%A1");
4322   else if (GET_CODE (base) == POST_INC) /* (R++) */
4323     return *l=4, ("st %0,%A1" CR_TAB
4324 		  "st %0,%B1" CR_TAB
4325 		  "st %0,%C1" CR_TAB
4326 		  "st %0,%D1");
4327   fatal_insn ("unknown move insn:",insn);
4328   return "";
4329 }
4330 
4331 const char *
output_movsisf(rtx_insn * insn,rtx operands[],int * l)4332 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
4333 {
4334   int dummy;
4335   rtx dest = operands[0];
4336   rtx src = operands[1];
4337   int *real_l = l;
4338 
4339   if (avr_mem_flash_p (src)
4340       || avr_mem_flash_p (dest))
4341     {
4342       return avr_out_lpm (insn, operands, real_l);
4343     }
4344 
4345   if (!l)
4346     l = &dummy;
4347 
4348   gcc_assert (4 == GET_MODE_SIZE (GET_MODE (dest)));
4349   if (REG_P (dest))
4350     {
4351       if (REG_P (src)) /* mov r,r */
4352 	{
4353 	  if (true_regnum (dest) > true_regnum (src))
4354 	    {
4355 	      if (AVR_HAVE_MOVW)
4356 		{
4357 		  *l = 2;
4358 		  return ("movw %C0,%C1" CR_TAB
4359 			  "movw %A0,%A1");
4360 		}
4361 	      *l = 4;
4362 	      return ("mov %D0,%D1" CR_TAB
4363 		      "mov %C0,%C1" CR_TAB
4364 		      "mov %B0,%B1" CR_TAB
4365 		      "mov %A0,%A1");
4366 	    }
4367 	  else
4368 	    {
4369 	      if (AVR_HAVE_MOVW)
4370 		{
4371 		  *l = 2;
4372 		  return ("movw %A0,%A1" CR_TAB
4373 			  "movw %C0,%C1");
4374 		}
4375 	      *l = 4;
4376 	      return ("mov %A0,%A1" CR_TAB
4377 		      "mov %B0,%B1" CR_TAB
4378 		      "mov %C0,%C1" CR_TAB
4379 		      "mov %D0,%D1");
4380 	    }
4381 	}
4382       else if (CONSTANT_P (src))
4383 	{
4384           return output_reload_insisf (operands, NULL_RTX, real_l);
4385         }
4386       else if (MEM_P (src))
4387 	return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
4388     }
4389   else if (MEM_P (dest))
4390     {
4391       const char *templ;
4392 
4393       if (src == CONST0_RTX (GET_MODE (dest)))
4394 	  operands[1] = zero_reg_rtx;
4395 
4396       templ = out_movsi_mr_r (insn, operands, real_l);
4397 
4398       if (!real_l)
4399 	output_asm_insn (templ, operands);
4400 
4401       operands[1] = src;
4402       return "";
4403     }
4404   fatal_insn ("invalid insn:", insn);
4405   return "";
4406 }
4407 
4408 
4409 /* Handle loads of 24-bit types from memory to register.  */
4410 
4411 static const char*
avr_out_load_psi_reg_no_disp_tiny(rtx_insn * insn,rtx * op,int * plen)4412 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4413 {
4414   rtx dest = op[0];
4415   rtx src = op[1];
4416   rtx base = XEXP (src, 0);
4417   int reg_dest = true_regnum (dest);
4418   int reg_base = true_regnum (base);
4419 
4420   if (reg_base == reg_dest)
4421     {
4422       return avr_asm_len (TINY_ADIW (%E1, %F1, 2)   CR_TAB
4423                           "ld %C0,%1"               CR_TAB
4424                           "ld __tmp_reg__,-%1"      CR_TAB
4425                           TINY_SBIW (%E1, %F1, 1)   CR_TAB
4426                           "ld %A0,%1"               CR_TAB
4427                           "mov %B0,__tmp_reg__", op, plen, -8);
4428     }
4429   else
4430     {
4431       avr_asm_len ("ld %A0,%1+"  CR_TAB
4432 		   "ld %B0,%1+"  CR_TAB
4433 		   "ld %C0,%1", op, plen, -3);
4434 
4435       if (reg_dest != reg_base - 2 &&
4436           !reg_unused_after (insn, base))
4437         {
4438           avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
4439         }
4440       return "";
4441     }
4442 }
4443 
4444 static const char*
avr_out_load_psi_reg_disp_tiny(rtx_insn * insn,rtx * op,int * plen)4445 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4446 {
4447   rtx dest = op[0];
4448   rtx src = op[1];
4449   rtx base = XEXP (src, 0);
4450   int reg_dest = true_regnum (dest);
4451   int reg_base = true_regnum (base);
4452 
4453   reg_base = true_regnum (XEXP (base, 0));
4454   if (reg_base == reg_dest)
4455     {
4456       return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
4457                           "ld %C0,%b1"                CR_TAB
4458                           "ld __tmp_reg__,-%b1"       CR_TAB
4459                           TINY_SBIW (%I1, %J1, 1)     CR_TAB
4460                           "ld %A0,%b1"                CR_TAB
4461                           "mov %B0,__tmp_reg__", op, plen, -8);
4462    }
4463   else
4464     {
4465       avr_asm_len (TINY_ADIW (%I1, %J1, %o1)   CR_TAB
4466                           "ld %A0,%b1+"              CR_TAB
4467                           "ld %B0,%b1+"              CR_TAB
4468                           "ld %C0,%b1", op, plen, -5);
4469 
4470       if (reg_dest != (reg_base - 2)
4471           && !reg_unused_after (insn, XEXP (base, 0)))
4472           avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
4473 
4474       return "";
4475     }
4476 }
4477 
4478 static const char*
avr_out_load_psi(rtx_insn * insn,rtx * op,int * plen)4479 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
4480 {
4481   rtx dest = op[0];
4482   rtx src = op[1];
4483   rtx base = XEXP (src, 0);
4484   int reg_dest = true_regnum (dest);
4485   int reg_base = true_regnum (base);
4486 
4487   if (reg_base > 0)
4488     {
4489       if (AVR_TINY)
4490         return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
4491 
4492       if (reg_base == REG_X)        /* (R26) */
4493         {
4494           if (reg_dest == REG_X)
4495             /* "ld r26,-X" is undefined */
4496             return avr_asm_len ("adiw r26,2"        CR_TAB
4497                                 "ld r28,X"          CR_TAB
4498                                 "ld __tmp_reg__,-X" CR_TAB
4499                                 "sbiw r26,1"        CR_TAB
4500                                 "ld r26,X"          CR_TAB
4501                                 "mov r27,__tmp_reg__", op, plen, -6);
4502           else
4503             {
4504               avr_asm_len ("ld %A0,X+" CR_TAB
4505                            "ld %B0,X+" CR_TAB
4506                            "ld %C0,X", op, plen, -3);
4507 
4508               if (reg_dest != REG_X - 2
4509                   && !reg_unused_after (insn, base))
4510                 {
4511                   avr_asm_len ("sbiw r26,2", op, plen, 1);
4512                 }
4513 
4514               return "";
4515             }
4516         }
4517       else /* reg_base != REG_X */
4518         {
4519           if (reg_dest == reg_base)
4520             return avr_asm_len ("ldd %C0,%1+2"          CR_TAB
4521                                 "ldd __tmp_reg__,%1+1"  CR_TAB
4522                                 "ld  %A0,%1"            CR_TAB
4523                                 "mov %B0,__tmp_reg__", op, plen, -4);
4524           else
4525             return avr_asm_len ("ld  %A0,%1"    CR_TAB
4526                                 "ldd %B0,%1+1"  CR_TAB
4527                                 "ldd %C0,%1+2", op, plen, -3);
4528         }
4529     }
4530   else if (GET_CODE (base) == PLUS) /* (R + i) */
4531     {
4532       int disp = INTVAL (XEXP (base, 1));
4533 
4534       if (AVR_TINY)
4535         return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
4536 
4537       if (disp > MAX_LD_OFFSET (GET_MODE (src)))
4538         {
4539           if (REGNO (XEXP (base, 0)) != REG_Y)
4540             fatal_insn ("incorrect insn:",insn);
4541 
4542           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4543             return avr_asm_len ("adiw r28,%o1-61" CR_TAB
4544                                 "ldd %A0,Y+61"    CR_TAB
4545                                 "ldd %B0,Y+62"    CR_TAB
4546                                 "ldd %C0,Y+63"    CR_TAB
4547                                 "sbiw r28,%o1-61", op, plen, -5);
4548 
4549           return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4550                               "sbci r29,hi8(-%o1)" CR_TAB
4551                               "ld  %A0,Y"           CR_TAB
4552                               "ldd %B0,Y+1"        CR_TAB
4553                               "ldd %C0,Y+2"        CR_TAB
4554                               "subi r28,lo8(%o1)"  CR_TAB
4555                               "sbci r29,hi8(%o1)", op, plen, -7);
4556         }
4557 
4558       reg_base = true_regnum (XEXP (base, 0));
4559       if (reg_base == REG_X)
4560         {
4561           /* R = (X + d) */
4562           if (reg_dest == REG_X)
4563             {
4564               /* "ld r26,-X" is undefined */
4565               return avr_asm_len ("adiw r26,%o1+2"     CR_TAB
4566                                   "ld  r28,X"          CR_TAB
4567                                   "ld  __tmp_reg__,-X" CR_TAB
4568                                   "sbiw r26,1"         CR_TAB
4569                                   "ld  r26,X"          CR_TAB
4570                                   "mov r27,__tmp_reg__", op, plen, -6);
4571             }
4572 
4573           avr_asm_len ("adiw r26,%o1" CR_TAB
4574                        "ld %A0,X+"    CR_TAB
4575                        "ld %B0,X+"    CR_TAB
4576                        "ld %C0,X", op, plen, -4);
4577 
4578           if (reg_dest != REG_W
4579               && !reg_unused_after (insn, XEXP (base, 0)))
4580             avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
4581 
4582           return "";
4583         }
4584 
4585       if (reg_dest == reg_base)
4586         return avr_asm_len ("ldd %C0,%C1" CR_TAB
4587                             "ldd __tmp_reg__,%B1"  CR_TAB
4588                             "ldd %A0,%A1" CR_TAB
4589                             "mov %B0,__tmp_reg__", op, plen, -4);
4590 
4591         return avr_asm_len ("ldd %A0,%A1" CR_TAB
4592                             "ldd %B0,%B1" CR_TAB
4593                             "ldd %C0,%C1", op, plen, -3);
4594     }
4595   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4596     return avr_asm_len ("ld %C0,%1" CR_TAB
4597                         "ld %B0,%1" CR_TAB
4598                         "ld %A0,%1", op, plen, -3);
4599   else if (GET_CODE (base) == POST_INC) /* (R++) */
4600     return avr_asm_len ("ld %A0,%1" CR_TAB
4601                         "ld %B0,%1" CR_TAB
4602                         "ld %C0,%1", op, plen, -3);
4603 
4604   else if (CONSTANT_ADDRESS_P (base))
4605     {
4606       int n_words = AVR_TINY ? 3 : 6;
4607       return avr_asm_len ("lds %A0,%m1" CR_TAB
4608                           "lds %B0,%m1+1" CR_TAB
4609                           "lds %C0,%m1+2", op, plen , -n_words);
4610     }
4611 
4612   fatal_insn ("unknown move insn:",insn);
4613   return "";
4614 }
4615 
4616 
4617 static const char*
avr_out_store_psi_reg_no_disp_tiny(rtx_insn * insn,rtx * op,int * plen)4618 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
4619 {
4620   rtx dest = op[0];
4621   rtx src = op[1];
4622   rtx base = XEXP (dest, 0);
4623   int reg_base = true_regnum (base);
4624   int reg_src = true_regnum (src);
4625 
4626   if (reg_base == reg_src)
4627     {
4628       avr_asm_len ("st %0,%A1"              CR_TAB
4629                    "mov __tmp_reg__,%B1"    CR_TAB
4630                    TINY_ADIW (%E0, %F0, 1)  CR_TAB /* st X+, r27 is undefined */
4631                    "st %0+,__tmp_reg__"     CR_TAB
4632                    "st %0,%C1", op, plen, -6);
4633 
4634     }
4635   else if (reg_src == reg_base - 2)
4636     {
4637       avr_asm_len ("st %0,%A1"              CR_TAB
4638                    "mov __tmp_reg__,%C1"    CR_TAB
4639                    TINY_ADIW (%E0, %F0, 1)  CR_TAB
4640                    "st %0+,%B1"             CR_TAB
4641                    "st %0,__tmp_reg__", op, plen, 6);
4642     }
4643   else
4644     {
4645       avr_asm_len ("st %0+,%A1"  CR_TAB
4646                    "st %0+,%B1" CR_TAB
4647                    "st %0,%C1", op, plen, -3);
4648     }
4649 
4650   if (!reg_unused_after (insn, base))
4651     avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
4652 
4653   return "";
4654 }
4655 
4656 static const char*
avr_out_store_psi_reg_disp_tiny(rtx * op,int * plen)4657 avr_out_store_psi_reg_disp_tiny (rtx *op, int *plen)
4658 {
4659   rtx dest = op[0];
4660   rtx src = op[1];
4661   rtx base = XEXP (dest, 0);
4662   int reg_base = REGNO (XEXP (base, 0));
4663   int reg_src = true_regnum (src);
4664 
4665   if (reg_src == reg_base)
4666     {
4667       return avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
4668                           "mov __zero_reg__,%B1"         CR_TAB
4669                           TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4670                           "st %b0+,__tmp_reg__"          CR_TAB
4671                           "st %b0+,__zero_reg__"         CR_TAB
4672                           "st %b0,%C1"                   CR_TAB
4673                           "clr __zero_reg__"             CR_TAB
4674                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -10);
4675     }
4676   else if (reg_src == reg_base - 2)
4677     {
4678       return avr_asm_len ("mov __tmp_reg__,%C1"          CR_TAB
4679                           TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4680                           "st %b0+,%A1"                  CR_TAB
4681                           "st %b0+,%B1"                  CR_TAB
4682                           "st %b0,__tmp_reg__"           CR_TAB
4683                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -8);
4684     }
4685 
4686   return avr_asm_len (TINY_ADIW (%I0, %J0, %o0)      CR_TAB
4687                           "st %b0+,%A1"                  CR_TAB
4688                           "st %b0+,%B1"                  CR_TAB
4689                           "st %b0,%C1"                   CR_TAB
4690                           TINY_SBIW (%I0, %J0, %o0+2), op, plen, -7);
4691 }
4692 
4693 /* Handle store of 24-bit type from register or zero to memory.  */
4694 
4695 static const char*
avr_out_store_psi(rtx_insn * insn,rtx * op,int * plen)4696 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
4697 {
4698   rtx dest = op[0];
4699   rtx src = op[1];
4700   rtx base = XEXP (dest, 0);
4701   int reg_base = true_regnum (base);
4702 
4703   if (CONSTANT_ADDRESS_P (base))
4704     {
4705       int n_words = AVR_TINY ? 3 : 6;
4706       return avr_asm_len ("sts %m0,%A1"   CR_TAB
4707                           "sts %m0+1,%B1" CR_TAB
4708                           "sts %m0+2,%C1", op, plen, -n_words);
4709     }
4710 
4711   if (reg_base > 0)                 /* (r) */
4712     {
4713       if (AVR_TINY)
4714         return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
4715 
4716       if (reg_base == REG_X)        /* (R26) */
4717         {
4718           gcc_assert (!reg_overlap_mentioned_p (base, src));
4719 
4720           avr_asm_len ("st %0+,%A1"  CR_TAB
4721                        "st %0+,%B1" CR_TAB
4722                        "st %0,%C1", op, plen, -3);
4723 
4724           if (!reg_unused_after (insn, base))
4725             avr_asm_len ("sbiw r26,2", op, plen, 1);
4726 
4727           return "";
4728         }
4729       else
4730         return avr_asm_len ("st %0,%A1"    CR_TAB
4731                             "std %0+1,%B1" CR_TAB
4732                             "std %0+2,%C1", op, plen, -3);
4733     }
4734   else if (GET_CODE (base) == PLUS) /* (R + i) */
4735     {
4736       int disp = INTVAL (XEXP (base, 1));
4737 
4738       if (AVR_TINY)
4739         return avr_out_store_psi_reg_disp_tiny (op, plen);
4740 
4741       reg_base = REGNO (XEXP (base, 0));
4742 
4743       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
4744         {
4745           if (reg_base != REG_Y)
4746             fatal_insn ("incorrect insn:",insn);
4747 
4748           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4749             return avr_asm_len ("adiw r28,%o0-61" CR_TAB
4750                                 "std Y+61,%A1"    CR_TAB
4751                                 "std Y+62,%B1"    CR_TAB
4752                                 "std Y+63,%C1"    CR_TAB
4753                                 "sbiw r28,%o0-61", op, plen, -5);
4754 
4755           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4756                               "sbci r29,hi8(-%o0)" CR_TAB
4757                               "st Y,%A1"           CR_TAB
4758                               "std Y+1,%B1"        CR_TAB
4759                               "std Y+2,%C1"        CR_TAB
4760                               "subi r28,lo8(%o0)"  CR_TAB
4761                               "sbci r29,hi8(%o0)", op, plen, -7);
4762         }
4763       if (reg_base == REG_X)
4764         {
4765           /* (X + d) = R */
4766           gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
4767 
4768           avr_asm_len ("adiw r26,%o0" CR_TAB
4769                        "st X+,%A1"    CR_TAB
4770                        "st X+,%B1"    CR_TAB
4771                        "st X,%C1", op, plen, -4);
4772 
4773           if (!reg_unused_after (insn, XEXP (base, 0)))
4774             avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
4775 
4776           return "";
4777         }
4778 
4779       return avr_asm_len ("std %A0,%A1" CR_TAB
4780                           "std %B0,%B1" CR_TAB
4781                           "std %C0,%C1", op, plen, -3);
4782     }
4783   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
4784     return avr_asm_len ("st %0,%C1" CR_TAB
4785                         "st %0,%B1" CR_TAB
4786                         "st %0,%A1", op, plen, -3);
4787   else if (GET_CODE (base) == POST_INC) /* (R++) */
4788     return avr_asm_len ("st %0,%A1" CR_TAB
4789                         "st %0,%B1" CR_TAB
4790                         "st %0,%C1", op, plen, -3);
4791 
4792   fatal_insn ("unknown move insn:",insn);
4793   return "";
4794 }
4795 
4796 
4797 /* Move around 24-bit stuff.  */
4798 
4799 const char *
avr_out_movpsi(rtx_insn * insn,rtx * op,int * plen)4800 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
4801 {
4802   rtx dest = op[0];
4803   rtx src = op[1];
4804 
4805   if (avr_mem_flash_p (src)
4806       || avr_mem_flash_p (dest))
4807     {
4808       return avr_out_lpm (insn, op, plen);
4809     }
4810 
4811   if (register_operand (dest, VOIDmode))
4812     {
4813       if (register_operand (src, VOIDmode)) /* mov r,r */
4814         {
4815           if (true_regnum (dest) > true_regnum (src))
4816             {
4817               avr_asm_len ("mov %C0,%C1", op, plen, -1);
4818 
4819               if (AVR_HAVE_MOVW)
4820                 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
4821               else
4822                 return avr_asm_len ("mov %B0,%B1"  CR_TAB
4823                                     "mov %A0,%A1", op, plen, 2);
4824             }
4825           else
4826             {
4827               if (AVR_HAVE_MOVW)
4828                 avr_asm_len ("movw %A0,%A1", op, plen, -1);
4829               else
4830                 avr_asm_len ("mov %A0,%A1"  CR_TAB
4831                              "mov %B0,%B1", op, plen, -2);
4832 
4833               return avr_asm_len ("mov %C0,%C1", op, plen, 1);
4834             }
4835         }
4836       else if (CONSTANT_P (src))
4837         {
4838           return avr_out_reload_inpsi (op, NULL_RTX, plen);
4839         }
4840       else if (MEM_P (src))
4841         return avr_out_load_psi (insn, op, plen); /* mov r,m */
4842     }
4843   else if (MEM_P (dest))
4844     {
4845       rtx xop[2];
4846 
4847       xop[0] = dest;
4848       xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4849 
4850       return avr_out_store_psi (insn, xop, plen);
4851     }
4852 
4853   fatal_insn ("invalid insn:", insn);
4854   return "";
4855 }
4856 
4857 static const char*
avr_out_movqi_mr_r_reg_disp_tiny(rtx_insn * insn,rtx op[],int * plen)4858 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4859 {
4860   rtx dest = op[0];
4861   rtx src = op[1];
4862   rtx x = XEXP (dest, 0);
4863 
4864   if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4865     {
4866       avr_asm_len ("mov __tmp_reg__,%1"      CR_TAB
4867                    TINY_ADIW (%I0, %J0, %o0) CR_TAB
4868                    "st %b0,__tmp_reg__", op, plen, -4);
4869     }
4870     else
4871     {
4872       avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
4873           "st %b0,%1" , op, plen, -3);
4874     }
4875 
4876   if (!reg_unused_after (insn, XEXP (x,0)))
4877       avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
4878 
4879   return "";
4880 }
4881 
4882 static const char*
out_movqi_mr_r(rtx_insn * insn,rtx op[],int * plen)4883 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
4884 {
4885   rtx dest = op[0];
4886   rtx src = op[1];
4887   rtx x = XEXP (dest, 0);
4888 
4889   if (CONSTANT_ADDRESS_P (x))
4890     {
4891       int n_words = AVR_TINY ? 1 : 2;
4892       return io_address_operand (x, QImode)
4893         ? avr_asm_len ("out %i0,%1", op, plen, -1)
4894         : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
4895     }
4896   else if (GET_CODE (x) == PLUS
4897            && REG_P (XEXP (x, 0))
4898            && CONST_INT_P (XEXP (x, 1)))
4899     {
4900       /* memory access by reg+disp */
4901 
4902       int disp = INTVAL (XEXP (x, 1));
4903 
4904       if (AVR_TINY)
4905         return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
4906 
4907       if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
4908         {
4909           if (REGNO (XEXP (x, 0)) != REG_Y)
4910             fatal_insn ("incorrect insn:",insn);
4911 
4912           if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
4913             return avr_asm_len ("adiw r28,%o0-63" CR_TAB
4914                                 "std Y+63,%1"     CR_TAB
4915                                 "sbiw r28,%o0-63", op, plen, -3);
4916 
4917           return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
4918                               "sbci r29,hi8(-%o0)" CR_TAB
4919                               "st Y,%1"            CR_TAB
4920                               "subi r28,lo8(%o0)"  CR_TAB
4921                               "sbci r29,hi8(%o0)", op, plen, -5);
4922         }
4923       else if (REGNO (XEXP (x,0)) == REG_X)
4924         {
4925           if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
4926             {
4927               avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
4928                            "adiw r26,%o0"       CR_TAB
4929                            "st X,__tmp_reg__", op, plen, -3);
4930             }
4931           else
4932             {
4933               avr_asm_len ("adiw r26,%o0" CR_TAB
4934                            "st X,%1", op, plen, -2);
4935             }
4936 
4937           if (!reg_unused_after (insn, XEXP (x,0)))
4938             avr_asm_len ("sbiw r26,%o0", op, plen, 1);
4939 
4940           return "";
4941         }
4942 
4943       return avr_asm_len ("std %0,%1", op, plen, -1);
4944     }
4945 
4946   return avr_asm_len ("st %0,%1", op, plen, -1);
4947 }
4948 
4949 
4950 /* Helper for the next function for XMEGA.  It does the same
4951    but with low byte first.  */
4952 
4953 static const char*
avr_out_movhi_mr_r_xmega(rtx_insn * insn,rtx op[],int * plen)4954 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
4955 {
4956   rtx dest = op[0];
4957   rtx src = op[1];
4958   rtx base = XEXP (dest, 0);
4959   int reg_base = true_regnum (base);
4960   int reg_src = true_regnum (src);
4961 
4962   /* "volatile" forces writing low byte first, even if less efficient,
4963      for correct operation with 16-bit I/O registers like SP.  */
4964   int mem_volatile_p = MEM_VOLATILE_P (dest);
4965 
4966   if (CONSTANT_ADDRESS_P (base))
4967     {
4968       return io_address_operand (base, HImode)
4969         ? avr_asm_len ("out %i0,%A1" CR_TAB
4970                        "out %i0+1,%B1", op, plen, -2)
4971 
4972         : avr_asm_len ("sts %m0,%A1" CR_TAB
4973                        "sts %m0+1,%B1", op, plen, -4);
4974     }
4975 
4976   if (reg_base > 0)
4977     {
4978       if (reg_base != REG_X)
4979         return avr_asm_len ("st %0,%A1" CR_TAB
4980                             "std %0+1,%B1", op, plen, -2);
4981 
4982       if (reg_src == REG_X)
4983         /* "st X+,r26" and "st -X,r26" are undefined.  */
4984         avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
4985                      "st X,r26"            CR_TAB
4986                      "adiw r26,1"          CR_TAB
4987                      "st X,__tmp_reg__", op, plen, -4);
4988       else
4989         avr_asm_len ("st X+,%A1" CR_TAB
4990                      "st X,%B1", op, plen, -2);
4991 
4992       return reg_unused_after (insn, base)
4993         ? ""
4994         : avr_asm_len ("sbiw r26,1", op, plen, 1);
4995     }
4996   else if (GET_CODE (base) == PLUS)
4997     {
4998       int disp = INTVAL (XEXP (base, 1));
4999       reg_base = REGNO (XEXP (base, 0));
5000       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5001         {
5002           if (reg_base != REG_Y)
5003             fatal_insn ("incorrect insn:",insn);
5004 
5005           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5006             ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5007                            "std Y+62,%A1"    CR_TAB
5008                            "std Y+63,%B1"    CR_TAB
5009                            "sbiw r28,%o0-62", op, plen, -4)
5010 
5011             : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5012                            "sbci r29,hi8(-%o0)" CR_TAB
5013                            "st Y,%A1"           CR_TAB
5014                            "std Y+1,%B1"        CR_TAB
5015                            "subi r28,lo8(%o0)"  CR_TAB
5016                            "sbci r29,hi8(%o0)", op, plen, -6);
5017         }
5018 
5019       if (reg_base != REG_X)
5020         return avr_asm_len ("std %A0,%A1" CR_TAB
5021                             "std %B0,%B1", op, plen, -2);
5022       /* (X + d) = R */
5023       return reg_src == REG_X
5024         ? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
5025                        "mov __zero_reg__,r27" CR_TAB
5026                        "adiw r26,%o0"         CR_TAB
5027                        "st X+,__tmp_reg__"    CR_TAB
5028                        "st X,__zero_reg__"    CR_TAB
5029                        "clr __zero_reg__"     CR_TAB
5030                        "sbiw r26,%o0+1", op, plen, -7)
5031 
5032         : avr_asm_len ("adiw r26,%o0" CR_TAB
5033                        "st X+,%A1"    CR_TAB
5034                        "st X,%B1"     CR_TAB
5035                        "sbiw r26,%o0+1", op, plen, -4);
5036     }
5037   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5038     {
5039       if (!mem_volatile_p)
5040         return avr_asm_len ("st %0,%B1" CR_TAB
5041                             "st %0,%A1", op, plen, -2);
5042 
5043       return REGNO (XEXP (base, 0)) == REG_X
5044         ? avr_asm_len ("sbiw r26,2"  CR_TAB
5045                        "st X+,%A1"   CR_TAB
5046                        "st X,%B1"    CR_TAB
5047                        "sbiw r26,1", op, plen, -4)
5048 
5049         : avr_asm_len ("sbiw %r0,2"  CR_TAB
5050                        "st %p0,%A1"  CR_TAB
5051                        "std %p0+1,%B1", op, plen, -3);
5052     }
5053   else if (GET_CODE (base) == POST_INC) /* (R++) */
5054     {
5055       return avr_asm_len ("st %0,%A1"  CR_TAB
5056                           "st %0,%B1", op, plen, -2);
5057 
5058     }
5059   fatal_insn ("unknown move insn:",insn);
5060   return "";
5061 }
5062 
5063 static const char*
avr_out_movhi_mr_r_reg_no_disp_tiny(rtx_insn * insn,rtx op[],int * plen)5064 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
5065 {
5066   rtx dest = op[0];
5067   rtx src = op[1];
5068   rtx base = XEXP (dest, 0);
5069   int reg_base = true_regnum (base);
5070   int reg_src = true_regnum (src);
5071   int mem_volatile_p = MEM_VOLATILE_P (dest);
5072 
5073   if (reg_base == reg_src)
5074     {
5075       return !mem_volatile_p && reg_unused_after (insn, src)
5076         ? avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
5077                        "st %0,%A1"             CR_TAB
5078                        TINY_ADIW (%E0, %F0, 1) CR_TAB
5079                        "st %0,__tmp_reg__", op, plen, -5)
5080         : avr_asm_len ("mov __tmp_reg__,%B1"   CR_TAB
5081                        TINY_ADIW (%E0, %F0, 1) CR_TAB
5082                        "st %0,__tmp_reg__"      CR_TAB
5083                        TINY_SBIW (%E0, %F0, 1) CR_TAB
5084                        "st %0, %A1", op, plen, -7);
5085     }
5086 
5087   return !mem_volatile_p && reg_unused_after (insn, base)
5088       ? avr_asm_len ("st %0+,%A1" CR_TAB
5089                      "st %0,%B1", op, plen, -2)
5090       : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
5091                      "st %0,%B1"             CR_TAB
5092                      "st -%0,%A1", op, plen, -4);
5093 }
5094 
5095 static const char*
avr_out_movhi_mr_r_reg_disp_tiny(rtx op[],int * plen)5096 avr_out_movhi_mr_r_reg_disp_tiny (rtx op[], int *plen)
5097 {
5098   rtx dest = op[0];
5099   rtx src = op[1];
5100   rtx base = XEXP (dest, 0);
5101   int reg_base = REGNO (XEXP (base, 0));
5102   int reg_src = true_regnum (src);
5103 
5104   return reg_src == reg_base
5105         ? avr_asm_len ("mov __tmp_reg__,%A1"          CR_TAB
5106                        "mov __zero_reg__,%B1"         CR_TAB
5107                        TINY_ADIW (%I0, %J0, %o0+1)    CR_TAB
5108                        "st %b0,__zero_reg__"          CR_TAB
5109                        "st -%b0,__tmp_reg__"          CR_TAB
5110                        "clr __zero_reg__"             CR_TAB
5111                        TINY_SBIW (%I0, %J0, %o0), op, plen, -9)
5112 
5113         : avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
5114                        "st %b0,%B1"                CR_TAB
5115                        "st -%b0,%A1"               CR_TAB
5116                        TINY_SBIW (%I0, %J0, %o0), op, plen, -6);
5117 }
5118 
5119 static const char*
avr_out_movhi_mr_r_post_inc_tiny(rtx op[],int * plen)5120 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
5121 {
5122   return avr_asm_len (TINY_ADIW (%I0, %J0, 1)  CR_TAB
5123                       "st %p0,%B1"    CR_TAB
5124                       "st -%p0,%A1"   CR_TAB
5125                       TINY_ADIW (%I0, %J0, 2), op, plen, -6);
5126 }
5127 
5128 static const char*
out_movhi_mr_r(rtx_insn * insn,rtx op[],int * plen)5129 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
5130 {
5131   rtx dest = op[0];
5132   rtx src = op[1];
5133   rtx base = XEXP (dest, 0);
5134   int reg_base = true_regnum (base);
5135   int reg_src = true_regnum (src);
5136   int mem_volatile_p;
5137 
5138   /* "volatile" forces writing high-byte first (no-xmega) resp.
5139      low-byte first (xmega) even if less efficient, for correct
5140      operation with 16-bit I/O registers like.  */
5141 
5142   if (AVR_XMEGA)
5143     return avr_out_movhi_mr_r_xmega (insn, op, plen);
5144 
5145   mem_volatile_p = MEM_VOLATILE_P (dest);
5146 
5147   if (CONSTANT_ADDRESS_P (base))
5148     {
5149       int n_words = AVR_TINY ? 2 : 4;
5150       return io_address_operand (base, HImode)
5151         ? avr_asm_len ("out %i0+1,%B1" CR_TAB
5152                        "out %i0,%A1", op, plen, -2)
5153 
5154         : avr_asm_len ("sts %m0+1,%B1" CR_TAB
5155                        "sts %m0,%A1", op, plen, -n_words);
5156     }
5157 
5158   if (reg_base > 0)
5159     {
5160       if (AVR_TINY)
5161         return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
5162 
5163       if (reg_base != REG_X)
5164         return avr_asm_len ("std %0+1,%B1" CR_TAB
5165                             "st %0,%A1", op, plen, -2);
5166 
5167       if (reg_src == REG_X)
5168         /* "st X+,r26" and "st -X,r26" are undefined.  */
5169         return !mem_volatile_p && reg_unused_after (insn, src)
5170           ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5171                          "st X,r26"            CR_TAB
5172                          "adiw r26,1"          CR_TAB
5173                          "st X,__tmp_reg__", op, plen, -4)
5174 
5175           : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
5176                          "adiw r26,1"          CR_TAB
5177                          "st X,__tmp_reg__"    CR_TAB
5178                          "sbiw r26,1"          CR_TAB
5179                          "st X,r26", op, plen, -5);
5180 
5181       return !mem_volatile_p && reg_unused_after (insn, base)
5182         ? avr_asm_len ("st X+,%A1" CR_TAB
5183                        "st X,%B1", op, plen, -2)
5184         : avr_asm_len ("adiw r26,1" CR_TAB
5185                        "st X,%B1"   CR_TAB
5186                        "st -X,%A1", op, plen, -3);
5187     }
5188   else if (GET_CODE (base) == PLUS)
5189     {
5190       int disp = INTVAL (XEXP (base, 1));
5191 
5192       if (AVR_TINY)
5193         return avr_out_movhi_mr_r_reg_disp_tiny (op, plen);
5194 
5195       reg_base = REGNO (XEXP (base, 0));
5196       if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5197         {
5198           if (reg_base != REG_Y)
5199             fatal_insn ("incorrect insn:",insn);
5200 
5201           return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
5202             ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
5203                            "std Y+63,%B1"    CR_TAB
5204                            "std Y+62,%A1"    CR_TAB
5205                            "sbiw r28,%o0-62", op, plen, -4)
5206 
5207             : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
5208                            "sbci r29,hi8(-%o0)" CR_TAB
5209                            "std Y+1,%B1"        CR_TAB
5210                            "st Y,%A1"           CR_TAB
5211                            "subi r28,lo8(%o0)"  CR_TAB
5212                            "sbci r29,hi8(%o0)", op, plen, -6);
5213         }
5214 
5215       if (reg_base != REG_X)
5216         return avr_asm_len ("std %B0,%B1" CR_TAB
5217                             "std %A0,%A1", op, plen, -2);
5218       /* (X + d) = R */
5219       return reg_src == REG_X
5220         ? avr_asm_len ("mov __tmp_reg__,r26"  CR_TAB
5221                        "mov __zero_reg__,r27" CR_TAB
5222                        "adiw r26,%o0+1"       CR_TAB
5223                        "st X,__zero_reg__"    CR_TAB
5224                        "st -X,__tmp_reg__"    CR_TAB
5225                        "clr __zero_reg__"     CR_TAB
5226                        "sbiw r26,%o0", op, plen, -7)
5227 
5228         : avr_asm_len ("adiw r26,%o0+1" CR_TAB
5229                        "st X,%B1"       CR_TAB
5230                        "st -X,%A1"      CR_TAB
5231                        "sbiw r26,%o0", op, plen, -4);
5232     }
5233   else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5234     {
5235       return avr_asm_len ("st %0,%B1" CR_TAB
5236                           "st %0,%A1", op, plen, -2);
5237     }
5238   else if (GET_CODE (base) == POST_INC) /* (R++) */
5239     {
5240       if (!mem_volatile_p)
5241         return avr_asm_len ("st %0,%A1"  CR_TAB
5242                             "st %0,%B1", op, plen, -2);
5243 
5244       if (AVR_TINY)
5245         return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
5246 
5247       return REGNO (XEXP (base, 0)) == REG_X
5248         ? avr_asm_len ("adiw r26,1"  CR_TAB
5249                        "st X,%B1"    CR_TAB
5250                        "st -X,%A1"   CR_TAB
5251                        "adiw r26,2", op, plen, -4)
5252 
5253         : avr_asm_len ("std %p0+1,%B1" CR_TAB
5254                        "st %p0,%A1"    CR_TAB
5255                        "adiw %r0,2", op, plen, -3);
5256     }
5257   fatal_insn ("unknown move insn:",insn);
5258   return "";
5259 }
5260 
5261 /* Return 1 if frame pointer for current function required.  */
5262 
5263 static bool
avr_frame_pointer_required_p(void)5264 avr_frame_pointer_required_p (void)
5265 {
5266   return (cfun->calls_alloca
5267           || cfun->calls_setjmp
5268           || cfun->has_nonlocal_label
5269           || crtl->args.info.nregs == 0
5270           || get_frame_size () > 0);
5271 }
5272 
5273 /* Returns the condition of compare insn INSN, or UNKNOWN.  */
5274 
5275 static RTX_CODE
compare_condition(rtx_insn * insn)5276 compare_condition (rtx_insn *insn)
5277 {
5278   rtx_insn *next = next_real_insn (insn);
5279 
5280   if (next && JUMP_P (next))
5281     {
5282       rtx pat = PATTERN (next);
5283       rtx src = SET_SRC (pat);
5284 
5285       if (IF_THEN_ELSE == GET_CODE (src))
5286         return GET_CODE (XEXP (src, 0));
5287     }
5288 
5289   return UNKNOWN;
5290 }
5291 
5292 
5293 /* Returns true iff INSN is a tst insn that only tests the sign.  */
5294 
5295 static bool
compare_sign_p(rtx_insn * insn)5296 compare_sign_p (rtx_insn *insn)
5297 {
5298   RTX_CODE cond = compare_condition (insn);
5299   return (cond == GE || cond == LT);
5300 }
5301 
5302 
5303 /* Returns true iff the next insn is a JUMP_INSN with a condition
5304    that needs to be swapped (GT, GTU, LE, LEU).  */
5305 
5306 static bool
compare_diff_p(rtx_insn * insn)5307 compare_diff_p (rtx_insn *insn)
5308 {
5309   RTX_CODE cond = compare_condition (insn);
5310   return (cond == GT || cond == GTU || cond == LE || cond == LEU) ? cond : 0;
5311 }
5312 
5313 /* Returns true iff INSN is a compare insn with the EQ or NE condition.  */
5314 
5315 static bool
compare_eq_p(rtx_insn * insn)5316 compare_eq_p (rtx_insn *insn)
5317 {
5318   RTX_CODE cond = compare_condition (insn);
5319   return (cond == EQ || cond == NE);
5320 }
5321 
5322 
5323 /* Output compare instruction
5324 
5325       compare (XOP[0], XOP[1])
5326 
5327    for a register XOP[0] and a compile-time constant XOP[1].  Return "".
5328    XOP[2] is an 8-bit scratch register as needed.
5329 
5330    PLEN == NULL:  Output instructions.
5331    PLEN != NULL:  Set *PLEN to the length (in words) of the sequence.
5332                   Don't output anything.  */
5333 
5334 const char*
avr_out_compare(rtx_insn * insn,rtx * xop,int * plen)5335 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
5336 {
5337   /* Register to compare and value to compare against. */
5338   rtx xreg = xop[0];
5339   rtx xval = xop[1];
5340 
5341   /* MODE of the comparison.  */
5342   machine_mode mode;
5343 
5344   /* Number of bytes to operate on.  */
5345   int i, n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
5346 
5347   /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown.  */
5348   int clobber_val = -1;
5349 
5350   /* Map fixed mode operands to integer operands with the same binary
5351      representation.  They are easier to handle in the remainder.  */
5352 
5353   if (CONST_FIXED_P (xval))
5354     {
5355       xreg = avr_to_int_mode (xop[0]);
5356       xval = avr_to_int_mode (xop[1]);
5357     }
5358 
5359   mode = GET_MODE (xreg);
5360 
5361   gcc_assert (REG_P (xreg));
5362   gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
5363               || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
5364 
5365   if (plen)
5366     *plen = 0;
5367 
5368   /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
5369      against 0 by ORing the bytes.  This is one instruction shorter.
5370      Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
5371      and therefore don't use this.  */
5372 
5373   if (!test_hard_reg_class (LD_REGS, xreg)
5374       && compare_eq_p (insn)
5375       && reg_unused_after (insn, xreg))
5376     {
5377       if (xval == const1_rtx)
5378         {
5379           avr_asm_len ("dec %A0" CR_TAB
5380                        "or %A0,%B0", xop, plen, 2);
5381 
5382           if (n_bytes >= 3)
5383             avr_asm_len ("or %A0,%C0", xop, plen, 1);
5384 
5385           if (n_bytes >= 4)
5386             avr_asm_len ("or %A0,%D0", xop, plen, 1);
5387 
5388           return "";
5389         }
5390       else if (xval == constm1_rtx)
5391         {
5392           if (n_bytes >= 4)
5393             avr_asm_len ("and %A0,%D0", xop, plen, 1);
5394 
5395           if (n_bytes >= 3)
5396             avr_asm_len ("and %A0,%C0", xop, plen, 1);
5397 
5398           return avr_asm_len ("and %A0,%B0" CR_TAB
5399                               "com %A0", xop, plen, 2);
5400         }
5401     }
5402 
5403   for (i = 0; i < n_bytes; i++)
5404     {
5405       /* We compare byte-wise.  */
5406       rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
5407       rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
5408 
5409       /* 8-bit value to compare with this byte.  */
5410       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
5411 
5412       /* Registers R16..R31 can operate with immediate.  */
5413       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
5414 
5415       xop[0] = reg8;
5416       xop[1] = gen_int_mode (val8, QImode);
5417 
5418       /* Word registers >= R24 can use SBIW/ADIW with 0..63.  */
5419 
5420       if (i == 0
5421           && test_hard_reg_class (ADDW_REGS, reg8))
5422         {
5423           int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
5424 
5425           if (IN_RANGE (val16, 0, 63)
5426               && (val8 == 0
5427                   || reg_unused_after (insn, xreg)))
5428             {
5429               if (AVR_TINY)
5430                 avr_asm_len (TINY_SBIW (%A0, %B0, %1), xop, plen, 2);
5431               else
5432                 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
5433 
5434               i++;
5435               continue;
5436             }
5437 
5438           if (n_bytes == 2
5439               && IN_RANGE (val16, -63, -1)
5440               && compare_eq_p (insn)
5441               && reg_unused_after (insn, xreg))
5442             {
5443               return AVR_TINY
5444                   ? avr_asm_len (TINY_ADIW (%A0, %B0, %n1), xop, plen, 2)
5445                   : avr_asm_len ("adiw %0,%n1", xop, plen, 1);
5446             }
5447         }
5448 
5449       /* Comparing against 0 is easy.  */
5450 
5451       if (val8 == 0)
5452         {
5453           avr_asm_len (i == 0
5454                        ? "cp %0,__zero_reg__"
5455                        : "cpc %0,__zero_reg__", xop, plen, 1);
5456           continue;
5457         }
5458 
5459       /* Upper registers can compare and subtract-with-carry immediates.
5460          Notice that compare instructions do the same as respective subtract
5461          instruction; the only difference is that comparisons don't write
5462          the result back to the target register.  */
5463 
5464       if (ld_reg_p)
5465         {
5466           if (i == 0)
5467             {
5468               avr_asm_len ("cpi %0,%1", xop, plen, 1);
5469               continue;
5470             }
5471           else if (reg_unused_after (insn, xreg))
5472             {
5473               avr_asm_len ("sbci %0,%1", xop, plen, 1);
5474               continue;
5475             }
5476         }
5477 
5478       /* Must load the value into the scratch register.  */
5479 
5480       gcc_assert (REG_P (xop[2]));
5481 
5482       if (clobber_val != (int) val8)
5483         avr_asm_len ("ldi %2,%1", xop, plen, 1);
5484       clobber_val = (int) val8;
5485 
5486       avr_asm_len (i == 0
5487                    ? "cp %0,%2"
5488                    : "cpc %0,%2", xop, plen, 1);
5489     }
5490 
5491   return "";
5492 }
5493 
5494 
5495 /* Prepare operands of compare_const_di2 to be used with avr_out_compare.  */
5496 
5497 const char*
avr_out_compare64(rtx_insn * insn,rtx * op,int * plen)5498 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
5499 {
5500   rtx xop[3];
5501 
5502   xop[0] = gen_rtx_REG (DImode, 18);
5503   xop[1] = op[0];
5504   xop[2] = op[1];
5505 
5506   return avr_out_compare (insn, xop, plen);
5507 }
5508 
5509 /* Output test instruction for HImode.  */
5510 
5511 const char*
avr_out_tsthi(rtx_insn * insn,rtx * op,int * plen)5512 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
5513 {
5514   if (compare_sign_p (insn))
5515     {
5516       avr_asm_len ("tst %B0", op, plen, -1);
5517     }
5518   else if (reg_unused_after (insn, op[0])
5519            && compare_eq_p (insn))
5520     {
5521       /* Faster than sbiw if we can clobber the operand.  */
5522       avr_asm_len ("or %A0,%B0", op, plen, -1);
5523     }
5524   else
5525     {
5526       avr_out_compare (insn, op, plen);
5527     }
5528 
5529   return "";
5530 }
5531 
5532 
5533 /* Output test instruction for PSImode.  */
5534 
5535 const char*
avr_out_tstpsi(rtx_insn * insn,rtx * op,int * plen)5536 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
5537 {
5538   if (compare_sign_p (insn))
5539     {
5540       avr_asm_len ("tst %C0", op, plen, -1);
5541     }
5542   else if (reg_unused_after (insn, op[0])
5543            && compare_eq_p (insn))
5544     {
5545       /* Faster than sbiw if we can clobber the operand.  */
5546       avr_asm_len ("or %A0,%B0" CR_TAB
5547                    "or %A0,%C0", op, plen, -2);
5548     }
5549   else
5550     {
5551       avr_out_compare (insn, op, plen);
5552     }
5553 
5554   return "";
5555 }
5556 
5557 
5558 /* Output test instruction for SImode.  */
5559 
5560 const char*
avr_out_tstsi(rtx_insn * insn,rtx * op,int * plen)5561 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
5562 {
5563   if (compare_sign_p (insn))
5564     {
5565       avr_asm_len ("tst %D0", op, plen, -1);
5566     }
5567   else if (reg_unused_after (insn, op[0])
5568            && compare_eq_p (insn))
5569     {
5570       /* Faster than sbiw if we can clobber the operand.  */
5571       avr_asm_len ("or %A0,%B0" CR_TAB
5572                    "or %A0,%C0" CR_TAB
5573                    "or %A0,%D0", op, plen, -3);
5574     }
5575   else
5576     {
5577       avr_out_compare (insn, op, plen);
5578     }
5579 
5580   return "";
5581 }
5582 
5583 
5584 /* Generate asm equivalent for various shifts.  This only handles cases
5585    that are not already carefully hand-optimized in ?sh??i3_out.
5586 
5587    OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
5588    OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
5589    OPERANDS[3] is a QImode scratch register from LD regs if
5590                available and SCRATCH, otherwise (no scratch available)
5591 
5592    TEMPL is an assembler template that shifts by one position.
5593    T_LEN is the length of this template.  */
5594 
5595 void
out_shift_with_cnt(const char * templ,rtx_insn * insn,rtx operands[],int * plen,int t_len)5596 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
5597 		    int *plen, int t_len)
5598 {
5599   bool second_label = true;
5600   bool saved_in_tmp = false;
5601   bool use_zero_reg = false;
5602   rtx op[5];
5603 
5604   op[0] = operands[0];
5605   op[1] = operands[1];
5606   op[2] = operands[2];
5607   op[3] = operands[3];
5608 
5609   if (plen)
5610     *plen = 0;
5611 
5612   if (CONST_INT_P (operands[2]))
5613     {
5614       bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
5615                       && REG_P (operands[3]));
5616       int count = INTVAL (operands[2]);
5617       int max_len = 10;  /* If larger than this, always use a loop.  */
5618 
5619       if (count <= 0)
5620           return;
5621 
5622       if (count < 8 && !scratch)
5623         use_zero_reg = true;
5624 
5625       if (optimize_size)
5626         max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
5627 
5628       if (t_len * count <= max_len)
5629         {
5630           /* Output shifts inline with no loop - faster.  */
5631 
5632           while (count-- > 0)
5633             avr_asm_len (templ, op, plen, t_len);
5634 
5635           return;
5636         }
5637 
5638       if (scratch)
5639         {
5640           avr_asm_len ("ldi %3,%2", op, plen, 1);
5641         }
5642       else if (use_zero_reg)
5643         {
5644           /* Hack to save one word: use __zero_reg__ as loop counter.
5645              Set one bit, then shift in a loop until it is 0 again.  */
5646 
5647           op[3] = zero_reg_rtx;
5648 
5649           avr_asm_len ("set" CR_TAB
5650                        "bld %3,%2-1", op, plen, 2);
5651         }
5652       else
5653         {
5654           /* No scratch register available, use one from LD_REGS (saved in
5655              __tmp_reg__) that doesn't overlap with registers to shift.  */
5656 
5657           op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + 16];
5658           op[4] = tmp_reg_rtx;
5659           saved_in_tmp = true;
5660 
5661           avr_asm_len ("mov %4,%3" CR_TAB
5662                        "ldi %3,%2", op, plen, 2);
5663         }
5664 
5665       second_label = false;
5666     }
5667   else if (MEM_P (op[2]))
5668     {
5669       rtx op_mov[2];
5670 
5671       op_mov[0] = op[3] = tmp_reg_rtx;
5672       op_mov[1] = op[2];
5673 
5674       out_movqi_r_mr (insn, op_mov, plen);
5675     }
5676   else if (register_operand (op[2], QImode))
5677     {
5678       op[3] = op[2];
5679 
5680       if (!reg_unused_after (insn, op[2])
5681           || reg_overlap_mentioned_p (op[0], op[2]))
5682         {
5683           op[3] = tmp_reg_rtx;
5684           avr_asm_len ("mov %3,%2", op, plen, 1);
5685         }
5686     }
5687   else
5688     fatal_insn ("bad shift insn:", insn);
5689 
5690   if (second_label)
5691       avr_asm_len ("rjmp 2f", op, plen, 1);
5692 
5693   avr_asm_len ("1:", op, plen, 0);
5694   avr_asm_len (templ, op, plen, t_len);
5695 
5696   if (second_label)
5697     avr_asm_len ("2:", op, plen, 0);
5698 
5699   avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
5700   avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
5701 
5702   if (saved_in_tmp)
5703     avr_asm_len ("mov %3,%4", op, plen, 1);
5704 }
5705 
5706 
5707 /* 8bit shift left ((char)x << i)   */
5708 
5709 const char *
ashlqi3_out(rtx_insn * insn,rtx operands[],int * len)5710 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
5711 {
5712   if (GET_CODE (operands[2]) == CONST_INT)
5713     {
5714       int k;
5715 
5716       if (!len)
5717 	len = &k;
5718 
5719       switch (INTVAL (operands[2]))
5720 	{
5721 	default:
5722 	  if (INTVAL (operands[2]) < 8)
5723 	    break;
5724 
5725 	  *len = 1;
5726 	  return "clr %0";
5727 
5728 	case 1:
5729 	  *len = 1;
5730 	  return "lsl %0";
5731 
5732 	case 2:
5733 	  *len = 2;
5734 	  return ("lsl %0" CR_TAB
5735 		  "lsl %0");
5736 
5737 	case 3:
5738 	  *len = 3;
5739 	  return ("lsl %0" CR_TAB
5740 		  "lsl %0" CR_TAB
5741 		  "lsl %0");
5742 
5743 	case 4:
5744 	  if (test_hard_reg_class (LD_REGS, operands[0]))
5745 	    {
5746 	      *len = 2;
5747 	      return ("swap %0" CR_TAB
5748 		      "andi %0,0xf0");
5749 	    }
5750 	  *len = 4;
5751 	  return ("lsl %0" CR_TAB
5752 		  "lsl %0" CR_TAB
5753 		  "lsl %0" CR_TAB
5754 		  "lsl %0");
5755 
5756 	case 5:
5757 	  if (test_hard_reg_class (LD_REGS, operands[0]))
5758 	    {
5759 	      *len = 3;
5760 	      return ("swap %0" CR_TAB
5761 		      "lsl %0"  CR_TAB
5762 		      "andi %0,0xe0");
5763 	    }
5764 	  *len = 5;
5765 	  return ("lsl %0" CR_TAB
5766 		  "lsl %0" CR_TAB
5767 		  "lsl %0" CR_TAB
5768 		  "lsl %0" CR_TAB
5769 		  "lsl %0");
5770 
5771 	case 6:
5772 	  if (test_hard_reg_class (LD_REGS, operands[0]))
5773 	    {
5774 	      *len = 4;
5775 	      return ("swap %0" CR_TAB
5776 		      "lsl %0"  CR_TAB
5777 		      "lsl %0"  CR_TAB
5778 		      "andi %0,0xc0");
5779 	    }
5780 	  *len = 6;
5781 	  return ("lsl %0" CR_TAB
5782 		  "lsl %0" CR_TAB
5783 		  "lsl %0" CR_TAB
5784 		  "lsl %0" CR_TAB
5785 		  "lsl %0" CR_TAB
5786 		  "lsl %0");
5787 
5788 	case 7:
5789 	  *len = 3;
5790 	  return ("ror %0" CR_TAB
5791 		  "clr %0" CR_TAB
5792 		  "ror %0");
5793 	}
5794     }
5795   else if (CONSTANT_P (operands[2]))
5796     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
5797 
5798   out_shift_with_cnt ("lsl %0",
5799                       insn, operands, len, 1);
5800   return "";
5801 }
5802 
5803 
5804 /* 16bit shift left ((short)x << i)   */
5805 
5806 const char *
ashlhi3_out(rtx_insn * insn,rtx operands[],int * len)5807 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
5808 {
5809   if (GET_CODE (operands[2]) == CONST_INT)
5810     {
5811       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
5812       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
5813       int k;
5814       int *t = len;
5815 
5816       if (!len)
5817 	len = &k;
5818 
5819       switch (INTVAL (operands[2]))
5820 	{
5821 	default:
5822 	  if (INTVAL (operands[2]) < 16)
5823 	    break;
5824 
5825 	  *len = 2;
5826 	  return ("clr %B0" CR_TAB
5827 		  "clr %A0");
5828 
5829 	case 4:
5830 	  if (optimize_size && scratch)
5831 	    break;  /* 5 */
5832 	  if (ldi_ok)
5833 	    {
5834 	      *len = 6;
5835 	      return ("swap %A0"      CR_TAB
5836 		      "swap %B0"      CR_TAB
5837 		      "andi %B0,0xf0" CR_TAB
5838 		      "eor %B0,%A0"   CR_TAB
5839 		      "andi %A0,0xf0" CR_TAB
5840 		      "eor %B0,%A0");
5841 	    }
5842 	  if (scratch)
5843 	    {
5844 	      *len = 7;
5845 	      return ("swap %A0"    CR_TAB
5846 		      "swap %B0"    CR_TAB
5847 		      "ldi %3,0xf0" CR_TAB
5848 		      "and %B0,%3"      CR_TAB
5849 		      "eor %B0,%A0" CR_TAB
5850 		      "and %A0,%3"      CR_TAB
5851 		      "eor %B0,%A0");
5852 	    }
5853 	  break;  /* optimize_size ? 6 : 8 */
5854 
5855 	case 5:
5856 	  if (optimize_size)
5857 	    break;  /* scratch ? 5 : 6 */
5858 	  if (ldi_ok)
5859 	    {
5860 	      *len = 8;
5861 	      return ("lsl %A0"       CR_TAB
5862 		      "rol %B0"       CR_TAB
5863 		      "swap %A0"      CR_TAB
5864 		      "swap %B0"      CR_TAB
5865 		      "andi %B0,0xf0" CR_TAB
5866 		      "eor %B0,%A0"   CR_TAB
5867 		      "andi %A0,0xf0" CR_TAB
5868 		      "eor %B0,%A0");
5869 	    }
5870 	  if (scratch)
5871 	    {
5872 	      *len = 9;
5873 	      return ("lsl %A0"     CR_TAB
5874 		      "rol %B0"     CR_TAB
5875 		      "swap %A0"    CR_TAB
5876 		      "swap %B0"    CR_TAB
5877 		      "ldi %3,0xf0" CR_TAB
5878 		      "and %B0,%3"      CR_TAB
5879 		      "eor %B0,%A0" CR_TAB
5880 		      "and %A0,%3"      CR_TAB
5881 		      "eor %B0,%A0");
5882 	    }
5883 	  break;  /* 10 */
5884 
5885 	case 6:
5886 	  if (optimize_size)
5887 	    break;  /* scratch ? 5 : 6 */
5888 	  *len = 9;
5889 	  return ("clr __tmp_reg__" CR_TAB
5890 		  "lsr %B0"         CR_TAB
5891 		  "ror %A0"         CR_TAB
5892 		  "ror __tmp_reg__" CR_TAB
5893 		  "lsr %B0"         CR_TAB
5894 		  "ror %A0"         CR_TAB
5895 		  "ror __tmp_reg__" CR_TAB
5896 		  "mov %B0,%A0"     CR_TAB
5897 		  "mov %A0,__tmp_reg__");
5898 
5899 	case 7:
5900 	  *len = 5;
5901 	  return ("lsr %B0"     CR_TAB
5902 		  "mov %B0,%A0" CR_TAB
5903 		  "clr %A0"     CR_TAB
5904 		  "ror %B0"     CR_TAB
5905 		  "ror %A0");
5906 
5907 	case 8:
5908 	  return *len = 2, ("mov %B0,%A1" CR_TAB
5909 			    "clr %A0");
5910 
5911 	case 9:
5912 	  *len = 3;
5913 	  return ("mov %B0,%A0" CR_TAB
5914 		  "clr %A0"     CR_TAB
5915 		  "lsl %B0");
5916 
5917 	case 10:
5918 	  *len = 4;
5919 	  return ("mov %B0,%A0" CR_TAB
5920 		  "clr %A0"     CR_TAB
5921 		  "lsl %B0"     CR_TAB
5922 		  "lsl %B0");
5923 
5924 	case 11:
5925 	  *len = 5;
5926 	  return ("mov %B0,%A0" CR_TAB
5927 		  "clr %A0"     CR_TAB
5928 		  "lsl %B0"     CR_TAB
5929 		  "lsl %B0"     CR_TAB
5930 		  "lsl %B0");
5931 
5932 	case 12:
5933 	  if (ldi_ok)
5934 	    {
5935 	      *len = 4;
5936 	      return ("mov %B0,%A0" CR_TAB
5937 		      "clr %A0"     CR_TAB
5938 		      "swap %B0"    CR_TAB
5939 		      "andi %B0,0xf0");
5940 	    }
5941 	  if (scratch)
5942 	    {
5943 	      *len = 5;
5944 	      return ("mov %B0,%A0" CR_TAB
5945 		      "clr %A0"     CR_TAB
5946 		      "swap %B0"    CR_TAB
5947 		      "ldi %3,0xf0" CR_TAB
5948 		      "and %B0,%3");
5949 	    }
5950 	  *len = 6;
5951 	  return ("mov %B0,%A0" CR_TAB
5952 		  "clr %A0"     CR_TAB
5953 		  "lsl %B0"     CR_TAB
5954 		  "lsl %B0"     CR_TAB
5955 		  "lsl %B0"     CR_TAB
5956 		  "lsl %B0");
5957 
5958 	case 13:
5959 	  if (ldi_ok)
5960 	    {
5961 	      *len = 5;
5962 	      return ("mov %B0,%A0" CR_TAB
5963 		      "clr %A0"     CR_TAB
5964 		      "swap %B0"    CR_TAB
5965 		      "lsl %B0"     CR_TAB
5966 		      "andi %B0,0xe0");
5967 	    }
5968 	  if (AVR_HAVE_MUL && scratch)
5969 	    {
5970 	      *len = 5;
5971 	      return ("ldi %3,0x20" CR_TAB
5972 		      "mul %A0,%3"  CR_TAB
5973 		      "mov %B0,r0"  CR_TAB
5974 		      "clr %A0"     CR_TAB
5975 		      "clr __zero_reg__");
5976 	    }
5977 	  if (optimize_size && scratch)
5978 	    break;  /* 5 */
5979 	  if (scratch)
5980 	    {
5981 	      *len = 6;
5982 	      return ("mov %B0,%A0" CR_TAB
5983 		      "clr %A0"     CR_TAB
5984 		      "swap %B0"    CR_TAB
5985 		      "lsl %B0"     CR_TAB
5986 		      "ldi %3,0xe0" CR_TAB
5987 		      "and %B0,%3");
5988 	    }
5989 	  if (AVR_HAVE_MUL)
5990 	    {
5991 	      *len = 6;
5992 	      return ("set"            CR_TAB
5993 		      "bld r1,5"   CR_TAB
5994 		      "mul %A0,r1" CR_TAB
5995 		      "mov %B0,r0" CR_TAB
5996 		      "clr %A0"    CR_TAB
5997 		      "clr __zero_reg__");
5998 	    }
5999 	  *len = 7;
6000 	  return ("mov %B0,%A0" CR_TAB
6001 		  "clr %A0"     CR_TAB
6002 		  "lsl %B0"     CR_TAB
6003 		  "lsl %B0"     CR_TAB
6004 		  "lsl %B0"     CR_TAB
6005 		  "lsl %B0"     CR_TAB
6006 		  "lsl %B0");
6007 
6008 	case 14:
6009 	  if (AVR_HAVE_MUL && ldi_ok)
6010 	    {
6011 	      *len = 5;
6012 	      return ("ldi %B0,0x40" CR_TAB
6013 		      "mul %A0,%B0"  CR_TAB
6014 		      "mov %B0,r0"   CR_TAB
6015 		      "clr %A0"      CR_TAB
6016 		      "clr __zero_reg__");
6017 	    }
6018 	  if (AVR_HAVE_MUL && scratch)
6019 	    {
6020 	      *len = 5;
6021 	      return ("ldi %3,0x40" CR_TAB
6022 		      "mul %A0,%3"  CR_TAB
6023 		      "mov %B0,r0"  CR_TAB
6024 		      "clr %A0"     CR_TAB
6025 		      "clr __zero_reg__");
6026 	    }
6027 	  if (optimize_size && ldi_ok)
6028 	    {
6029 	      *len = 5;
6030 	      return ("mov %B0,%A0" CR_TAB
6031 		      "ldi %A0,6" "\n1:\t"
6032 		      "lsl %B0"     CR_TAB
6033 		      "dec %A0"     CR_TAB
6034 		      "brne 1b");
6035 	    }
6036 	  if (optimize_size && scratch)
6037 	    break;  /* 5 */
6038 	  *len = 6;
6039 	  return ("clr %B0" CR_TAB
6040 		  "lsr %A0" CR_TAB
6041 		  "ror %B0" CR_TAB
6042 		  "lsr %A0" CR_TAB
6043 		  "ror %B0" CR_TAB
6044 		  "clr %A0");
6045 
6046 	case 15:
6047 	  *len = 4;
6048 	  return ("clr %B0" CR_TAB
6049 		  "lsr %A0" CR_TAB
6050 		  "ror %B0" CR_TAB
6051 		  "clr %A0");
6052 	}
6053       len = t;
6054     }
6055   out_shift_with_cnt ("lsl %A0" CR_TAB
6056                       "rol %B0", insn, operands, len, 2);
6057   return "";
6058 }
6059 
6060 
6061 /* 24-bit shift left */
6062 
6063 const char*
avr_out_ashlpsi3(rtx_insn * insn,rtx * op,int * plen)6064 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
6065 {
6066   if (plen)
6067     *plen = 0;
6068 
6069   if (CONST_INT_P (op[2]))
6070     {
6071       switch (INTVAL (op[2]))
6072         {
6073         default:
6074           if (INTVAL (op[2]) < 24)
6075             break;
6076 
6077           return avr_asm_len ("clr %A0" CR_TAB
6078                               "clr %B0" CR_TAB
6079                               "clr %C0", op, plen, 3);
6080 
6081         case 8:
6082           {
6083             int reg0 = REGNO (op[0]);
6084             int reg1 = REGNO (op[1]);
6085 
6086             if (reg0 >= reg1)
6087               return avr_asm_len ("mov %C0,%B1"  CR_TAB
6088                                   "mov %B0,%A1"  CR_TAB
6089                                   "clr %A0", op, plen, 3);
6090             else
6091               return avr_asm_len ("clr %A0"      CR_TAB
6092                                   "mov %B0,%A1"  CR_TAB
6093                                   "mov %C0,%B1", op, plen, 3);
6094           }
6095 
6096         case 16:
6097           {
6098             int reg0 = REGNO (op[0]);
6099             int reg1 = REGNO (op[1]);
6100 
6101             if (reg0 + 2 != reg1)
6102               avr_asm_len ("mov %C0,%A0", op, plen, 1);
6103 
6104             return avr_asm_len ("clr %B0"  CR_TAB
6105                                 "clr %A0", op, plen, 2);
6106           }
6107 
6108         case 23:
6109           return avr_asm_len ("clr %C0" CR_TAB
6110                               "lsr %A0" CR_TAB
6111                               "ror %C0" CR_TAB
6112                               "clr %B0" CR_TAB
6113                               "clr %A0", op, plen, 5);
6114         }
6115     }
6116 
6117   out_shift_with_cnt ("lsl %A0" CR_TAB
6118                       "rol %B0" CR_TAB
6119                       "rol %C0", insn, op, plen, 3);
6120   return "";
6121 }
6122 
6123 
6124 /* 32bit shift left ((long)x << i)   */
6125 
6126 const char *
ashlsi3_out(rtx_insn * insn,rtx operands[],int * len)6127 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
6128 {
6129   if (GET_CODE (operands[2]) == CONST_INT)
6130     {
6131       int k;
6132       int *t = len;
6133 
6134       if (!len)
6135 	len = &k;
6136 
6137       switch (INTVAL (operands[2]))
6138 	{
6139 	default:
6140 	  if (INTVAL (operands[2]) < 32)
6141 	    break;
6142 
6143 	  if (AVR_HAVE_MOVW)
6144 	    return *len = 3, ("clr %D0" CR_TAB
6145 			      "clr %C0" CR_TAB
6146 			      "movw %A0,%C0");
6147 	  *len = 4;
6148 	  return ("clr %D0" CR_TAB
6149 		  "clr %C0" CR_TAB
6150 		  "clr %B0" CR_TAB
6151 		  "clr %A0");
6152 
6153 	case 8:
6154 	  {
6155 	    int reg0 = true_regnum (operands[0]);
6156 	    int reg1 = true_regnum (operands[1]);
6157 	    *len = 4;
6158 	    if (reg0 >= reg1)
6159 	      return ("mov %D0,%C1"  CR_TAB
6160 		      "mov %C0,%B1"  CR_TAB
6161 		      "mov %B0,%A1"  CR_TAB
6162 		      "clr %A0");
6163 	    else
6164 	      return ("clr %A0"      CR_TAB
6165 		      "mov %B0,%A1"  CR_TAB
6166 		      "mov %C0,%B1"  CR_TAB
6167 		      "mov %D0,%C1");
6168 	  }
6169 
6170 	case 16:
6171 	  {
6172 	    int reg0 = true_regnum (operands[0]);
6173 	    int reg1 = true_regnum (operands[1]);
6174 	    if (reg0 + 2 == reg1)
6175 	      return *len = 2, ("clr %B0"      CR_TAB
6176 				"clr %A0");
6177 	    if (AVR_HAVE_MOVW)
6178 	      return *len = 3, ("movw %C0,%A1" CR_TAB
6179 				"clr %B0"      CR_TAB
6180 				"clr %A0");
6181 	    else
6182 	      return *len = 4, ("mov %C0,%A1"  CR_TAB
6183 				"mov %D0,%B1"  CR_TAB
6184 				"clr %B0"      CR_TAB
6185 				"clr %A0");
6186 	  }
6187 
6188 	case 24:
6189 	  *len = 4;
6190 	  return ("mov %D0,%A1"  CR_TAB
6191 		  "clr %C0"      CR_TAB
6192 		  "clr %B0"      CR_TAB
6193 		  "clr %A0");
6194 
6195 	case 31:
6196 	  *len = 6;
6197 	  return ("clr %D0" CR_TAB
6198 		  "lsr %A0" CR_TAB
6199 		  "ror %D0" CR_TAB
6200 		  "clr %C0" CR_TAB
6201 		  "clr %B0" CR_TAB
6202 		  "clr %A0");
6203 	}
6204       len = t;
6205     }
6206   out_shift_with_cnt ("lsl %A0" CR_TAB
6207                       "rol %B0" CR_TAB
6208                       "rol %C0" CR_TAB
6209                       "rol %D0", insn, operands, len, 4);
6210   return "";
6211 }
6212 
6213 /* 8bit arithmetic shift right  ((signed char)x >> i) */
6214 
6215 const char *
ashrqi3_out(rtx_insn * insn,rtx operands[],int * len)6216 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6217 {
6218   if (GET_CODE (operands[2]) == CONST_INT)
6219     {
6220       int k;
6221 
6222       if (!len)
6223 	len = &k;
6224 
6225       switch (INTVAL (operands[2]))
6226 	{
6227 	case 1:
6228 	  *len = 1;
6229 	  return "asr %0";
6230 
6231 	case 2:
6232 	  *len = 2;
6233 	  return ("asr %0" CR_TAB
6234 		  "asr %0");
6235 
6236 	case 3:
6237 	  *len = 3;
6238 	  return ("asr %0" CR_TAB
6239 		  "asr %0" CR_TAB
6240 		  "asr %0");
6241 
6242 	case 4:
6243 	  *len = 4;
6244 	  return ("asr %0" CR_TAB
6245 		  "asr %0" CR_TAB
6246 		  "asr %0" CR_TAB
6247 		  "asr %0");
6248 
6249 	case 5:
6250 	  *len = 5;
6251 	  return ("asr %0" CR_TAB
6252 		  "asr %0" CR_TAB
6253 		  "asr %0" CR_TAB
6254 		  "asr %0" CR_TAB
6255 		  "asr %0");
6256 
6257 	case 6:
6258 	  *len = 4;
6259 	  return ("bst %0,6"  CR_TAB
6260 		  "lsl %0"    CR_TAB
6261 		  "sbc %0,%0" CR_TAB
6262 		  "bld %0,0");
6263 
6264 	default:
6265 	  if (INTVAL (operands[2]) < 8)
6266 	    break;
6267 
6268 	  /* fall through */
6269 
6270 	case 7:
6271 	  *len = 2;
6272 	  return ("lsl %0" CR_TAB
6273 		  "sbc %0,%0");
6274 	}
6275     }
6276   else if (CONSTANT_P (operands[2]))
6277     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
6278 
6279   out_shift_with_cnt ("asr %0",
6280                       insn, operands, len, 1);
6281   return "";
6282 }
6283 
6284 
6285 /* 16bit arithmetic shift right  ((signed short)x >> i) */
6286 
6287 const char *
ashrhi3_out(rtx_insn * insn,rtx operands[],int * len)6288 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6289 {
6290   if (GET_CODE (operands[2]) == CONST_INT)
6291     {
6292       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6293       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6294       int k;
6295       int *t = len;
6296 
6297       if (!len)
6298 	len = &k;
6299 
6300       switch (INTVAL (operands[2]))
6301 	{
6302 	case 4:
6303 	case 5:
6304 	  /* XXX try to optimize this too? */
6305 	  break;
6306 
6307 	case 6:
6308 	  if (optimize_size)
6309 	    break;  /* scratch ? 5 : 6 */
6310 	  *len = 8;
6311 	  return ("mov __tmp_reg__,%A0" CR_TAB
6312 		  "mov %A0,%B0"         CR_TAB
6313 		  "lsl __tmp_reg__"     CR_TAB
6314 		  "rol %A0"             CR_TAB
6315 		  "sbc %B0,%B0"         CR_TAB
6316 		  "lsl __tmp_reg__"     CR_TAB
6317 		  "rol %A0"             CR_TAB
6318 		  "rol %B0");
6319 
6320 	case 7:
6321 	  *len = 4;
6322 	  return ("lsl %A0"     CR_TAB
6323 		  "mov %A0,%B0" CR_TAB
6324 		  "rol %A0"     CR_TAB
6325 		  "sbc %B0,%B0");
6326 
6327 	case 8:
6328 	  {
6329 	    int reg0 = true_regnum (operands[0]);
6330 	    int reg1 = true_regnum (operands[1]);
6331 
6332 	    if (reg0 == reg1)
6333 	      return *len = 3, ("mov %A0,%B0" CR_TAB
6334 				"lsl %B0"     CR_TAB
6335 				"sbc %B0,%B0");
6336 	    else
6337 	      return *len = 4, ("mov %A0,%B1" CR_TAB
6338 			        "clr %B0"     CR_TAB
6339 			        "sbrc %A0,7"  CR_TAB
6340 			        "dec %B0");
6341 	  }
6342 
6343 	case 9:
6344 	  *len = 4;
6345 	  return ("mov %A0,%B0" CR_TAB
6346 		  "lsl %B0"      CR_TAB
6347 		  "sbc %B0,%B0" CR_TAB
6348 		  "asr %A0");
6349 
6350 	case 10:
6351 	  *len = 5;
6352 	  return ("mov %A0,%B0" CR_TAB
6353 		  "lsl %B0"     CR_TAB
6354 		  "sbc %B0,%B0" CR_TAB
6355 		  "asr %A0"     CR_TAB
6356 		  "asr %A0");
6357 
6358 	case 11:
6359 	  if (AVR_HAVE_MUL && ldi_ok)
6360 	    {
6361 	      *len = 5;
6362 	      return ("ldi %A0,0x20" CR_TAB
6363 		      "muls %B0,%A0" CR_TAB
6364 		      "mov %A0,r1"   CR_TAB
6365 		      "sbc %B0,%B0"  CR_TAB
6366 		      "clr __zero_reg__");
6367 	    }
6368 	  if (optimize_size && scratch)
6369 	    break;  /* 5 */
6370 	  *len = 6;
6371 	  return ("mov %A0,%B0" CR_TAB
6372 		  "lsl %B0"     CR_TAB
6373 		  "sbc %B0,%B0" CR_TAB
6374 		  "asr %A0"     CR_TAB
6375 		  "asr %A0"     CR_TAB
6376 		  "asr %A0");
6377 
6378 	case 12:
6379 	  if (AVR_HAVE_MUL && ldi_ok)
6380 	    {
6381 	      *len = 5;
6382 	      return ("ldi %A0,0x10" CR_TAB
6383 		      "muls %B0,%A0" CR_TAB
6384 		      "mov %A0,r1"   CR_TAB
6385 		      "sbc %B0,%B0"  CR_TAB
6386 		      "clr __zero_reg__");
6387 	    }
6388 	  if (optimize_size && scratch)
6389 	    break;  /* 5 */
6390 	  *len = 7;
6391 	  return ("mov %A0,%B0" CR_TAB
6392 		  "lsl %B0"     CR_TAB
6393 		  "sbc %B0,%B0" CR_TAB
6394 		  "asr %A0"     CR_TAB
6395 		  "asr %A0"     CR_TAB
6396 		  "asr %A0"     CR_TAB
6397 		  "asr %A0");
6398 
6399 	case 13:
6400 	  if (AVR_HAVE_MUL && ldi_ok)
6401 	    {
6402 	      *len = 5;
6403 	      return ("ldi %A0,0x08" CR_TAB
6404 		      "muls %B0,%A0" CR_TAB
6405 		      "mov %A0,r1"   CR_TAB
6406 		      "sbc %B0,%B0"  CR_TAB
6407 		      "clr __zero_reg__");
6408 	    }
6409 	  if (optimize_size)
6410 	    break;  /* scratch ? 5 : 7 */
6411 	  *len = 8;
6412 	  return ("mov %A0,%B0" CR_TAB
6413 		  "lsl %B0"     CR_TAB
6414 		  "sbc %B0,%B0" CR_TAB
6415 		  "asr %A0"     CR_TAB
6416 		  "asr %A0"     CR_TAB
6417 		  "asr %A0"     CR_TAB
6418 		  "asr %A0"     CR_TAB
6419 		  "asr %A0");
6420 
6421 	case 14:
6422 	  *len = 5;
6423 	  return ("lsl %B0"     CR_TAB
6424 		  "sbc %A0,%A0" CR_TAB
6425 		  "lsl %B0"     CR_TAB
6426 		  "mov %B0,%A0" CR_TAB
6427 		  "rol %A0");
6428 
6429 	default:
6430 	  if (INTVAL (operands[2]) < 16)
6431 	    break;
6432 
6433 	  /* fall through */
6434 
6435 	case 15:
6436 	  return *len = 3, ("lsl %B0"     CR_TAB
6437 			    "sbc %A0,%A0" CR_TAB
6438 			    "mov %B0,%A0");
6439 	}
6440       len = t;
6441     }
6442   out_shift_with_cnt ("asr %B0" CR_TAB
6443                       "ror %A0", insn, operands, len, 2);
6444   return "";
6445 }
6446 
6447 
6448 /* 24-bit arithmetic shift right */
6449 
6450 const char*
avr_out_ashrpsi3(rtx_insn * insn,rtx * op,int * plen)6451 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6452 {
6453   int dest = REGNO (op[0]);
6454   int src = REGNO (op[1]);
6455 
6456   if (CONST_INT_P (op[2]))
6457     {
6458       if (plen)
6459         *plen = 0;
6460 
6461       switch (INTVAL (op[2]))
6462         {
6463         case 8:
6464           if (dest <= src)
6465             return avr_asm_len ("mov %A0,%B1" CR_TAB
6466                                 "mov %B0,%C1" CR_TAB
6467                                 "clr %C0"     CR_TAB
6468                                 "sbrc %B0,7"  CR_TAB
6469                                 "dec %C0", op, plen, 5);
6470           else
6471             return avr_asm_len ("clr %C0"     CR_TAB
6472                                 "sbrc %C1,7"  CR_TAB
6473                                 "dec %C0"     CR_TAB
6474                                 "mov %B0,%C1" CR_TAB
6475                                 "mov %A0,%B1", op, plen, 5);
6476 
6477         case 16:
6478           if (dest != src + 2)
6479             avr_asm_len ("mov %A0,%C1", op, plen, 1);
6480 
6481           return avr_asm_len ("clr %B0"     CR_TAB
6482                               "sbrc %A0,7"  CR_TAB
6483                               "com %B0"     CR_TAB
6484                               "mov %C0,%B0", op, plen, 4);
6485 
6486         default:
6487           if (INTVAL (op[2]) < 24)
6488             break;
6489 
6490           /* fall through */
6491 
6492         case 23:
6493           return avr_asm_len ("lsl %C0"     CR_TAB
6494                               "sbc %A0,%A0" CR_TAB
6495                               "mov %B0,%A0" CR_TAB
6496                               "mov %C0,%A0", op, plen, 4);
6497         } /* switch */
6498     }
6499 
6500   out_shift_with_cnt ("asr %C0" CR_TAB
6501                       "ror %B0" CR_TAB
6502                       "ror %A0", insn, op, plen, 3);
6503   return "";
6504 }
6505 
6506 
6507 /* 32-bit arithmetic shift right  ((signed long)x >> i) */
6508 
6509 const char *
ashrsi3_out(rtx_insn * insn,rtx operands[],int * len)6510 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
6511 {
6512   if (GET_CODE (operands[2]) == CONST_INT)
6513     {
6514       int k;
6515       int *t = len;
6516 
6517       if (!len)
6518 	len = &k;
6519 
6520       switch (INTVAL (operands[2]))
6521 	{
6522 	case 8:
6523 	  {
6524 	    int reg0 = true_regnum (operands[0]);
6525 	    int reg1 = true_regnum (operands[1]);
6526 	    *len=6;
6527 	    if (reg0 <= reg1)
6528 	      return ("mov %A0,%B1" CR_TAB
6529 		      "mov %B0,%C1" CR_TAB
6530 		      "mov %C0,%D1" CR_TAB
6531 		      "clr %D0"     CR_TAB
6532 		      "sbrc %C0,7"  CR_TAB
6533 		      "dec %D0");
6534 	    else
6535 	      return ("clr %D0"     CR_TAB
6536 		      "sbrc %D1,7"  CR_TAB
6537 		      "dec %D0"     CR_TAB
6538 		      "mov %C0,%D1" CR_TAB
6539 		      "mov %B0,%C1" CR_TAB
6540 		      "mov %A0,%B1");
6541 	  }
6542 
6543 	case 16:
6544 	  {
6545 	    int reg0 = true_regnum (operands[0]);
6546 	    int reg1 = true_regnum (operands[1]);
6547 
6548 	    if (reg0 == reg1 + 2)
6549 	      return *len = 4, ("clr %D0"     CR_TAB
6550 				"sbrc %B0,7"  CR_TAB
6551 				"com %D0"     CR_TAB
6552 				"mov %C0,%D0");
6553 	    if (AVR_HAVE_MOVW)
6554 	      return *len = 5, ("movw %A0,%C1" CR_TAB
6555 				"clr %D0"      CR_TAB
6556 				"sbrc %B0,7"   CR_TAB
6557 				"com %D0"      CR_TAB
6558 				"mov %C0,%D0");
6559 	    else
6560 	      return *len = 6, ("mov %B0,%D1" CR_TAB
6561 				"mov %A0,%C1" CR_TAB
6562 				"clr %D0"     CR_TAB
6563 				"sbrc %B0,7"  CR_TAB
6564 				"com %D0"     CR_TAB
6565 				"mov %C0,%D0");
6566 	  }
6567 
6568 	case 24:
6569 	  return *len = 6, ("mov %A0,%D1" CR_TAB
6570 			    "clr %D0"     CR_TAB
6571 			    "sbrc %A0,7"  CR_TAB
6572 			    "com %D0"     CR_TAB
6573 			    "mov %B0,%D0" CR_TAB
6574 			    "mov %C0,%D0");
6575 
6576 	default:
6577 	  if (INTVAL (operands[2]) < 32)
6578 	    break;
6579 
6580 	  /* fall through */
6581 
6582 	case 31:
6583 	  if (AVR_HAVE_MOVW)
6584 	    return *len = 4, ("lsl %D0"     CR_TAB
6585 			      "sbc %A0,%A0" CR_TAB
6586 			      "mov %B0,%A0" CR_TAB
6587 			      "movw %C0,%A0");
6588 	  else
6589 	    return *len = 5, ("lsl %D0"     CR_TAB
6590 			      "sbc %A0,%A0" CR_TAB
6591 			      "mov %B0,%A0" CR_TAB
6592 			      "mov %C0,%A0" CR_TAB
6593 			      "mov %D0,%A0");
6594 	}
6595       len = t;
6596     }
6597   out_shift_with_cnt ("asr %D0" CR_TAB
6598                       "ror %C0" CR_TAB
6599                       "ror %B0" CR_TAB
6600                       "ror %A0", insn, operands, len, 4);
6601   return "";
6602 }
6603 
6604 /* 8-bit logic shift right ((unsigned char)x >> i) */
6605 
6606 const char *
lshrqi3_out(rtx_insn * insn,rtx operands[],int * len)6607 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
6608 {
6609   if (GET_CODE (operands[2]) == CONST_INT)
6610     {
6611       int k;
6612 
6613       if (!len)
6614 	len = &k;
6615 
6616       switch (INTVAL (operands[2]))
6617 	{
6618 	default:
6619 	  if (INTVAL (operands[2]) < 8)
6620 	    break;
6621 
6622 	  *len = 1;
6623 	  return "clr %0";
6624 
6625 	case 1:
6626 	  *len = 1;
6627 	  return "lsr %0";
6628 
6629 	case 2:
6630 	  *len = 2;
6631 	  return ("lsr %0" CR_TAB
6632 		  "lsr %0");
6633 	case 3:
6634 	  *len = 3;
6635 	  return ("lsr %0" CR_TAB
6636 		  "lsr %0" CR_TAB
6637 		  "lsr %0");
6638 
6639 	case 4:
6640 	  if (test_hard_reg_class (LD_REGS, operands[0]))
6641 	    {
6642 	      *len=2;
6643 	      return ("swap %0" CR_TAB
6644 		      "andi %0,0x0f");
6645 	    }
6646 	  *len = 4;
6647 	  return ("lsr %0" CR_TAB
6648 		  "lsr %0" CR_TAB
6649 		  "lsr %0" CR_TAB
6650 		  "lsr %0");
6651 
6652 	case 5:
6653 	  if (test_hard_reg_class (LD_REGS, operands[0]))
6654 	    {
6655 	      *len = 3;
6656 	      return ("swap %0" CR_TAB
6657 		      "lsr %0"  CR_TAB
6658 		      "andi %0,0x7");
6659 	    }
6660 	  *len = 5;
6661 	  return ("lsr %0" CR_TAB
6662 		  "lsr %0" CR_TAB
6663 		  "lsr %0" CR_TAB
6664 		  "lsr %0" CR_TAB
6665 		  "lsr %0");
6666 
6667 	case 6:
6668 	  if (test_hard_reg_class (LD_REGS, operands[0]))
6669 	    {
6670 	      *len = 4;
6671 	      return ("swap %0" CR_TAB
6672 		      "lsr %0"  CR_TAB
6673 		      "lsr %0"  CR_TAB
6674 		      "andi %0,0x3");
6675 	    }
6676 	  *len = 6;
6677 	  return ("lsr %0" CR_TAB
6678 		  "lsr %0" CR_TAB
6679 		  "lsr %0" CR_TAB
6680 		  "lsr %0" CR_TAB
6681 		  "lsr %0" CR_TAB
6682 		  "lsr %0");
6683 
6684 	case 7:
6685 	  *len = 3;
6686 	  return ("rol %0" CR_TAB
6687 		  "clr %0" CR_TAB
6688 		  "rol %0");
6689 	}
6690     }
6691   else if (CONSTANT_P (operands[2]))
6692     fatal_insn ("internal compiler error.  Incorrect shift:", insn);
6693 
6694   out_shift_with_cnt ("lsr %0",
6695                       insn, operands, len, 1);
6696   return "";
6697 }
6698 
6699 /* 16-bit logic shift right ((unsigned short)x >> i) */
6700 
6701 const char *
lshrhi3_out(rtx_insn * insn,rtx operands[],int * len)6702 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
6703 {
6704   if (GET_CODE (operands[2]) == CONST_INT)
6705     {
6706       int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
6707       int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
6708       int k;
6709       int *t = len;
6710 
6711       if (!len)
6712 	len = &k;
6713 
6714       switch (INTVAL (operands[2]))
6715 	{
6716 	default:
6717 	  if (INTVAL (operands[2]) < 16)
6718 	    break;
6719 
6720 	  *len = 2;
6721 	  return ("clr %B0" CR_TAB
6722 		  "clr %A0");
6723 
6724 	case 4:
6725 	  if (optimize_size && scratch)
6726 	    break;  /* 5 */
6727 	  if (ldi_ok)
6728 	    {
6729 	      *len = 6;
6730 	      return ("swap %B0"      CR_TAB
6731 		      "swap %A0"      CR_TAB
6732 		      "andi %A0,0x0f" CR_TAB
6733 		      "eor %A0,%B0"   CR_TAB
6734 		      "andi %B0,0x0f" CR_TAB
6735 		      "eor %A0,%B0");
6736 	    }
6737 	  if (scratch)
6738 	    {
6739 	      *len = 7;
6740 	      return ("swap %B0"    CR_TAB
6741 		      "swap %A0"    CR_TAB
6742 		      "ldi %3,0x0f" CR_TAB
6743 		      "and %A0,%3"      CR_TAB
6744 		      "eor %A0,%B0" CR_TAB
6745 		      "and %B0,%3"      CR_TAB
6746 		      "eor %A0,%B0");
6747 	    }
6748 	  break;  /* optimize_size ? 6 : 8 */
6749 
6750 	case 5:
6751 	  if (optimize_size)
6752 	    break;  /* scratch ? 5 : 6 */
6753 	  if (ldi_ok)
6754 	    {
6755 	      *len = 8;
6756 	      return ("lsr %B0"       CR_TAB
6757 		      "ror %A0"       CR_TAB
6758 		      "swap %B0"      CR_TAB
6759 		      "swap %A0"      CR_TAB
6760 		      "andi %A0,0x0f" CR_TAB
6761 		      "eor %A0,%B0"   CR_TAB
6762 		      "andi %B0,0x0f" CR_TAB
6763 		      "eor %A0,%B0");
6764 	    }
6765 	  if (scratch)
6766 	    {
6767 	      *len = 9;
6768 	      return ("lsr %B0"     CR_TAB
6769 		      "ror %A0"     CR_TAB
6770 		      "swap %B0"    CR_TAB
6771 		      "swap %A0"    CR_TAB
6772 		      "ldi %3,0x0f" CR_TAB
6773 		      "and %A0,%3"      CR_TAB
6774 		      "eor %A0,%B0" CR_TAB
6775 		      "and %B0,%3"      CR_TAB
6776 		      "eor %A0,%B0");
6777 	    }
6778 	  break;  /* 10 */
6779 
6780 	case 6:
6781 	  if (optimize_size)
6782 	    break;  /* scratch ? 5 : 6 */
6783 	  *len = 9;
6784 	  return ("clr __tmp_reg__" CR_TAB
6785 		  "lsl %A0"         CR_TAB
6786 		  "rol %B0"         CR_TAB
6787 		  "rol __tmp_reg__" CR_TAB
6788 		  "lsl %A0"         CR_TAB
6789 		  "rol %B0"         CR_TAB
6790 		  "rol __tmp_reg__" CR_TAB
6791 		  "mov %A0,%B0"     CR_TAB
6792 		  "mov %B0,__tmp_reg__");
6793 
6794 	case 7:
6795 	  *len = 5;
6796 	  return ("lsl %A0"     CR_TAB
6797 		  "mov %A0,%B0" CR_TAB
6798 		  "rol %A0"     CR_TAB
6799 		  "sbc %B0,%B0" CR_TAB
6800 		  "neg %B0");
6801 
6802 	case 8:
6803 	  return *len = 2, ("mov %A0,%B1" CR_TAB
6804 			    "clr %B0");
6805 
6806 	case 9:
6807 	  *len = 3;
6808 	  return ("mov %A0,%B0" CR_TAB
6809 		  "clr %B0"     CR_TAB
6810 		  "lsr %A0");
6811 
6812 	case 10:
6813 	  *len = 4;
6814 	  return ("mov %A0,%B0" CR_TAB
6815 		  "clr %B0"     CR_TAB
6816 		  "lsr %A0"     CR_TAB
6817 		  "lsr %A0");
6818 
6819 	case 11:
6820 	  *len = 5;
6821 	  return ("mov %A0,%B0" CR_TAB
6822 		  "clr %B0"     CR_TAB
6823 		  "lsr %A0"     CR_TAB
6824 		  "lsr %A0"     CR_TAB
6825 		  "lsr %A0");
6826 
6827 	case 12:
6828 	  if (ldi_ok)
6829 	    {
6830 	      *len = 4;
6831 	      return ("mov %A0,%B0" CR_TAB
6832 		      "clr %B0"     CR_TAB
6833 		      "swap %A0"    CR_TAB
6834 		      "andi %A0,0x0f");
6835 	    }
6836 	  if (scratch)
6837 	    {
6838 	      *len = 5;
6839 	      return ("mov %A0,%B0" CR_TAB
6840 		      "clr %B0"     CR_TAB
6841 		      "swap %A0"    CR_TAB
6842 		      "ldi %3,0x0f" CR_TAB
6843 		      "and %A0,%3");
6844 	    }
6845 	  *len = 6;
6846 	  return ("mov %A0,%B0" CR_TAB
6847 		  "clr %B0"     CR_TAB
6848 		  "lsr %A0"     CR_TAB
6849 		  "lsr %A0"     CR_TAB
6850 		  "lsr %A0"     CR_TAB
6851 		  "lsr %A0");
6852 
6853 	case 13:
6854 	  if (ldi_ok)
6855 	    {
6856 	      *len = 5;
6857 	      return ("mov %A0,%B0" CR_TAB
6858 		      "clr %B0"     CR_TAB
6859 		      "swap %A0"    CR_TAB
6860 		      "lsr %A0"     CR_TAB
6861 		      "andi %A0,0x07");
6862 	    }
6863 	  if (AVR_HAVE_MUL && scratch)
6864 	    {
6865 	      *len = 5;
6866 	      return ("ldi %3,0x08" CR_TAB
6867 		      "mul %B0,%3"  CR_TAB
6868 		      "mov %A0,r1"  CR_TAB
6869 		      "clr %B0"     CR_TAB
6870 		      "clr __zero_reg__");
6871 	    }
6872 	  if (optimize_size && scratch)
6873 	    break;  /* 5 */
6874 	  if (scratch)
6875 	    {
6876 	      *len = 6;
6877 	      return ("mov %A0,%B0" CR_TAB
6878 		      "clr %B0"     CR_TAB
6879 		      "swap %A0"    CR_TAB
6880 		      "lsr %A0"     CR_TAB
6881 		      "ldi %3,0x07" CR_TAB
6882 		      "and %A0,%3");
6883 	    }
6884 	  if (AVR_HAVE_MUL)
6885 	    {
6886 	      *len = 6;
6887 	      return ("set"            CR_TAB
6888 		      "bld r1,3"   CR_TAB
6889 		      "mul %B0,r1" CR_TAB
6890 		      "mov %A0,r1" CR_TAB
6891 		      "clr %B0"    CR_TAB
6892 		      "clr __zero_reg__");
6893 	    }
6894 	  *len = 7;
6895 	  return ("mov %A0,%B0" CR_TAB
6896 		  "clr %B0"     CR_TAB
6897 		  "lsr %A0"     CR_TAB
6898 		  "lsr %A0"     CR_TAB
6899 		  "lsr %A0"     CR_TAB
6900 		  "lsr %A0"     CR_TAB
6901 		  "lsr %A0");
6902 
6903 	case 14:
6904 	  if (AVR_HAVE_MUL && ldi_ok)
6905 	    {
6906 	      *len = 5;
6907 	      return ("ldi %A0,0x04" CR_TAB
6908 		      "mul %B0,%A0"  CR_TAB
6909 		      "mov %A0,r1"   CR_TAB
6910 		      "clr %B0"      CR_TAB
6911 		      "clr __zero_reg__");
6912 	    }
6913 	  if (AVR_HAVE_MUL && scratch)
6914 	    {
6915 	      *len = 5;
6916 	      return ("ldi %3,0x04" CR_TAB
6917 		      "mul %B0,%3"  CR_TAB
6918 		      "mov %A0,r1"  CR_TAB
6919 		      "clr %B0"     CR_TAB
6920 		      "clr __zero_reg__");
6921 	    }
6922 	  if (optimize_size && ldi_ok)
6923 	    {
6924 	      *len = 5;
6925 	      return ("mov %A0,%B0" CR_TAB
6926 		      "ldi %B0,6" "\n1:\t"
6927 		      "lsr %A0"     CR_TAB
6928 		      "dec %B0"     CR_TAB
6929 		      "brne 1b");
6930 	    }
6931 	  if (optimize_size && scratch)
6932 	    break;  /* 5 */
6933 	  *len = 6;
6934 	  return ("clr %A0" CR_TAB
6935 		  "lsl %B0" CR_TAB
6936 		  "rol %A0" CR_TAB
6937 		  "lsl %B0" CR_TAB
6938 		  "rol %A0" CR_TAB
6939 		  "clr %B0");
6940 
6941 	case 15:
6942 	  *len = 4;
6943 	  return ("clr %A0" CR_TAB
6944 		  "lsl %B0" CR_TAB
6945 		  "rol %A0" CR_TAB
6946 		  "clr %B0");
6947 	}
6948       len = t;
6949     }
6950   out_shift_with_cnt ("lsr %B0" CR_TAB
6951                       "ror %A0", insn, operands, len, 2);
6952   return "";
6953 }
6954 
6955 
6956 /* 24-bit logic shift right */
6957 
6958 const char*
avr_out_lshrpsi3(rtx_insn * insn,rtx * op,int * plen)6959 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
6960 {
6961   int dest = REGNO (op[0]);
6962   int src = REGNO (op[1]);
6963 
6964   if (CONST_INT_P (op[2]))
6965     {
6966       if (plen)
6967         *plen = 0;
6968 
6969       switch (INTVAL (op[2]))
6970         {
6971         case 8:
6972           if (dest <= src)
6973             return avr_asm_len ("mov %A0,%B1" CR_TAB
6974                                 "mov %B0,%C1" CR_TAB
6975                                 "clr %C0", op, plen, 3);
6976           else
6977             return avr_asm_len ("clr %C0"     CR_TAB
6978                                 "mov %B0,%C1" CR_TAB
6979                                 "mov %A0,%B1", op, plen, 3);
6980 
6981         case 16:
6982           if (dest != src + 2)
6983             avr_asm_len ("mov %A0,%C1", op, plen, 1);
6984 
6985           return avr_asm_len ("clr %B0"  CR_TAB
6986                               "clr %C0", op, plen, 2);
6987 
6988         default:
6989           if (INTVAL (op[2]) < 24)
6990             break;
6991 
6992           /* fall through */
6993 
6994         case 23:
6995           return avr_asm_len ("clr %A0"    CR_TAB
6996                               "sbrc %C0,7" CR_TAB
6997                               "inc %A0"    CR_TAB
6998                               "clr %B0"    CR_TAB
6999                               "clr %C0", op, plen, 5);
7000         } /* switch */
7001     }
7002 
7003   out_shift_with_cnt ("lsr %C0" CR_TAB
7004                       "ror %B0" CR_TAB
7005                       "ror %A0", insn, op, plen, 3);
7006   return "";
7007 }
7008 
7009 
7010 /* 32-bit logic shift right ((unsigned int)x >> i) */
7011 
7012 const char *
lshrsi3_out(rtx_insn * insn,rtx operands[],int * len)7013 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
7014 {
7015   if (GET_CODE (operands[2]) == CONST_INT)
7016     {
7017       int k;
7018       int *t = len;
7019 
7020       if (!len)
7021 	len = &k;
7022 
7023       switch (INTVAL (operands[2]))
7024 	{
7025 	default:
7026 	  if (INTVAL (operands[2]) < 32)
7027 	    break;
7028 
7029 	  if (AVR_HAVE_MOVW)
7030 	    return *len = 3, ("clr %D0" CR_TAB
7031 			      "clr %C0" CR_TAB
7032 			      "movw %A0,%C0");
7033 	  *len = 4;
7034 	  return ("clr %D0" CR_TAB
7035 		  "clr %C0" CR_TAB
7036 		  "clr %B0" CR_TAB
7037 		  "clr %A0");
7038 
7039 	case 8:
7040 	  {
7041 	    int reg0 = true_regnum (operands[0]);
7042 	    int reg1 = true_regnum (operands[1]);
7043 	    *len = 4;
7044 	    if (reg0 <= reg1)
7045 	      return ("mov %A0,%B1" CR_TAB
7046 		      "mov %B0,%C1" CR_TAB
7047 		      "mov %C0,%D1" CR_TAB
7048 		      "clr %D0");
7049 	    else
7050 	      return ("clr %D0"     CR_TAB
7051 		      "mov %C0,%D1" CR_TAB
7052 		      "mov %B0,%C1" CR_TAB
7053 		      "mov %A0,%B1");
7054 	  }
7055 
7056 	case 16:
7057 	  {
7058 	    int reg0 = true_regnum (operands[0]);
7059 	    int reg1 = true_regnum (operands[1]);
7060 
7061 	    if (reg0 == reg1 + 2)
7062 	      return *len = 2, ("clr %C0"     CR_TAB
7063 				"clr %D0");
7064 	    if (AVR_HAVE_MOVW)
7065 	      return *len = 3, ("movw %A0,%C1" CR_TAB
7066 				"clr %C0"      CR_TAB
7067 				"clr %D0");
7068 	    else
7069 	      return *len = 4, ("mov %B0,%D1" CR_TAB
7070 				"mov %A0,%C1" CR_TAB
7071 				"clr %C0"     CR_TAB
7072 				"clr %D0");
7073 	  }
7074 
7075 	case 24:
7076 	  return *len = 4, ("mov %A0,%D1" CR_TAB
7077 			    "clr %B0"     CR_TAB
7078 			    "clr %C0"     CR_TAB
7079 			    "clr %D0");
7080 
7081 	case 31:
7082 	  *len = 6;
7083 	  return ("clr %A0"    CR_TAB
7084 		  "sbrc %D0,7" CR_TAB
7085 		  "inc %A0"    CR_TAB
7086 		  "clr %B0"    CR_TAB
7087 		  "clr %C0"    CR_TAB
7088 		  "clr %D0");
7089 	}
7090       len = t;
7091     }
7092   out_shift_with_cnt ("lsr %D0" CR_TAB
7093                       "ror %C0" CR_TAB
7094                       "ror %B0" CR_TAB
7095                       "ror %A0", insn, operands, len, 4);
7096   return "";
7097 }
7098 
7099 
7100 /* Output addition of register XOP[0] and compile time constant XOP[2].
7101    CODE == PLUS:  perform addition by using ADD instructions or
7102    CODE == MINUS: perform addition by using SUB instructions:
7103 
7104       XOP[0] = XOP[0] + XOP[2]
7105 
7106    Or perform addition/subtraction with register XOP[2] depending on CODE:
7107 
7108       XOP[0] = XOP[0] +/- XOP[2]
7109 
7110    If PLEN == NULL, print assembler instructions to perform the operation;
7111    otherwise, set *PLEN to the length of the instruction sequence (in words)
7112    printed with PLEN == NULL.  XOP[3] is an 8-bit scratch register or NULL_RTX.
7113    Set *PCC to effect on cc0 according to respective CC_* insn attribute.
7114 
7115    CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
7116    CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
7117    If  CODE_SAT != UNKNOWN  then SIGN contains the sign of the summand resp.
7118    the subtrahend in the original insn, provided it is a compile time constant.
7119    In all other cases, SIGN is 0.
7120 
7121    If OUT_LABEL is true, print the final 0: label which is needed for
7122    saturated addition / subtraction.  The only case where OUT_LABEL = false
7123    is useful is for saturated addition / subtraction performed during
7124    fixed-point rounding, cf. `avr_out_round'.  */
7125 
7126 static void
avr_out_plus_1(rtx * xop,int * plen,enum rtx_code code,int * pcc,enum rtx_code code_sat,int sign,bool out_label)7127 avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc,
7128                 enum rtx_code code_sat, int sign, bool out_label)
7129 {
7130   /* MODE of the operation.  */
7131   machine_mode mode = GET_MODE (xop[0]);
7132 
7133   /* INT_MODE of the same size.  */
7134   machine_mode imode = int_mode_for_mode (mode);
7135 
7136   /* Number of bytes to operate on.  */
7137   int i, n_bytes = GET_MODE_SIZE (mode);
7138 
7139   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
7140   int clobber_val = -1;
7141 
7142   /* op[0]: 8-bit destination register
7143      op[1]: 8-bit const int
7144      op[2]: 8-bit scratch register */
7145   rtx op[3];
7146 
7147   /* Started the operation?  Before starting the operation we may skip
7148      adding 0.  This is no more true after the operation started because
7149      carry must be taken into account.  */
7150   bool started = false;
7151 
7152   /* Value to add.  There are two ways to add VAL: R += VAL and R -= -VAL.  */
7153   rtx xval = xop[2];
7154 
7155   /* Output a BRVC instruction.  Only needed with saturation.  */
7156   bool out_brvc = true;
7157 
7158   if (plen)
7159     *plen = 0;
7160 
7161   if (REG_P (xop[2]))
7162     {
7163       *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_CLOBBER;
7164 
7165       for (i = 0; i < n_bytes; i++)
7166         {
7167           /* We operate byte-wise on the destination.  */
7168           op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
7169           op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
7170 
7171           if (i == 0)
7172             avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
7173                          op, plen, 1);
7174           else
7175             avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
7176                          op, plen, 1);
7177         }
7178 
7179       if (reg_overlap_mentioned_p (xop[0], xop[2]))
7180         {
7181           gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
7182 
7183           if (MINUS == code)
7184             return;
7185         }
7186 
7187       goto saturate;
7188     }
7189 
7190   /* Except in the case of ADIW with 16-bit register (see below)
7191      addition does not set cc0 in a usable way.  */
7192 
7193   *pcc = (MINUS == code) ? CC_SET_CZN : CC_CLOBBER;
7194 
7195   if (CONST_FIXED_P (xval))
7196     xval = avr_to_int_mode (xval);
7197 
7198   /* Adding/Subtracting zero is a no-op.  */
7199 
7200   if (xval == const0_rtx)
7201     {
7202       *pcc = CC_NONE;
7203       return;
7204     }
7205 
7206   if (MINUS == code)
7207     xval = simplify_unary_operation (NEG, imode, xval, imode);
7208 
7209   op[2] = xop[3];
7210 
7211   if (SS_PLUS == code_sat && MINUS == code
7212       && sign < 0
7213       && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
7214                   & GET_MODE_MASK (QImode)))
7215     {
7216       /* We compute x + 0x80 by means of SUB instructions.  We negated the
7217          constant subtrahend above and are left with  x - (-128)  so that we
7218          need something like SUBI r,128 which does not exist because SUBI sets
7219          V according to the sign of the subtrahend.  Notice the only case
7220          where this must be done is when NEG overflowed in case [2s] because
7221          the V computation needs the right sign of the subtrahend.  */
7222 
7223       rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7224 
7225       avr_asm_len ("subi %0,128" CR_TAB
7226                    "brmi 0f", &msb, plen, 2);
7227       out_brvc = false;
7228 
7229       goto saturate;
7230     }
7231 
7232   for (i = 0; i < n_bytes; i++)
7233     {
7234       /* We operate byte-wise on the destination.  */
7235       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7236       rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
7237 
7238       /* 8-bit value to operate with this byte. */
7239       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7240 
7241       /* Registers R16..R31 can operate with immediate.  */
7242       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7243 
7244       op[0] = reg8;
7245       op[1] = gen_int_mode (val8, QImode);
7246 
7247       /* To get usable cc0 no low-bytes must have been skipped.  */
7248 
7249       if (i && !started)
7250         *pcc = CC_CLOBBER;
7251 
7252       if (!started
7253           && i % 2 == 0
7254           && i + 2 <= n_bytes
7255           && test_hard_reg_class (ADDW_REGS, reg8))
7256         {
7257           rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
7258           unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
7259 
7260           /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
7261              i.e. operate word-wise.  */
7262 
7263           if (val16 < 64)
7264             {
7265               if (val16 != 0)
7266                 {
7267                   started = true;
7268                   avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
7269                                op, plen, 1);
7270 
7271                   if (n_bytes == 2 && PLUS == code)
7272                     *pcc = CC_SET_CZN;
7273                 }
7274 
7275               i++;
7276               continue;
7277             }
7278         }
7279 
7280       if (val8 == 0)
7281         {
7282           if (started)
7283             avr_asm_len (code == PLUS
7284                          ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
7285                          op, plen, 1);
7286           continue;
7287         }
7288       else if ((val8 == 1 || val8 == 0xff)
7289                && UNKNOWN == code_sat
7290                && !started
7291                && i == n_bytes - 1)
7292         {
7293           avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
7294                        op, plen, 1);
7295           *pcc = CC_CLOBBER;
7296           break;
7297         }
7298 
7299       switch (code)
7300         {
7301         case PLUS:
7302 
7303           gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
7304 
7305           if (plen != NULL && UNKNOWN != code_sat)
7306             {
7307               /* This belongs to the x + 0x80 corner case.  The code with
7308                  ADD instruction is not smaller, thus make this case
7309                  expensive so that the caller won't pick it.  */
7310 
7311               *plen += 10;
7312               break;
7313             }
7314 
7315           if (clobber_val != (int) val8)
7316             avr_asm_len ("ldi %2,%1", op, plen, 1);
7317           clobber_val = (int) val8;
7318 
7319           avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
7320 
7321           break; /* PLUS */
7322 
7323         case MINUS:
7324 
7325           if (ld_reg_p)
7326             avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
7327           else
7328             {
7329               gcc_assert (plen != NULL || REG_P (op[2]));
7330 
7331               if (clobber_val != (int) val8)
7332                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7333               clobber_val = (int) val8;
7334 
7335               avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
7336             }
7337 
7338           break; /* MINUS */
7339 
7340         default:
7341           /* Unknown code */
7342           gcc_unreachable();
7343         }
7344 
7345       started = true;
7346 
7347     } /* for all sub-bytes */
7348 
7349  saturate:
7350 
7351   if (UNKNOWN == code_sat)
7352     return;
7353 
7354   *pcc = (int) CC_CLOBBER;
7355 
7356   /* Vanilla addition/subtraction is done.  We are left with saturation.
7357 
7358      We have to compute  A = A <op> B  where  A  is a register and
7359      B is a register or a non-zero compile time constant CONST.
7360      A is register class "r" if unsigned && B is REG.  Otherwise, A is in "d".
7361      B stands for the original operand $2 in INSN.  In the case of B = CONST,
7362      SIGN in { -1, 1 } is the sign of B.  Otherwise, SIGN is 0.
7363 
7364      CODE is the instruction flavor we use in the asm sequence to perform <op>.
7365 
7366 
7367      unsigned
7368      operation        |  code |  sat if  |    b is      | sat value |  case
7369      -----------------+-------+----------+--------------+-----------+-------
7370      +  as  a + b     |  add  |  C == 1  |  const, reg  | u+ = 0xff |  [1u]
7371      +  as  a - (-b)  |  sub  |  C == 0  |  const       | u+ = 0xff |  [2u]
7372      -  as  a - b     |  sub  |  C == 1  |  const, reg  | u- = 0    |  [3u]
7373      -  as  a + (-b)  |  add  |  C == 0  |  const       | u- = 0    |  [4u]
7374 
7375 
7376      signed
7377      operation        |  code |  sat if  |    b is      | sat value |  case
7378      -----------------+-------+----------+--------------+-----------+-------
7379      +  as  a + b     |  add  |  V == 1  |  const, reg  | s+        |  [1s]
7380      +  as  a - (-b)  |  sub  |  V == 1  |  const       | s+        |  [2s]
7381      -  as  a - b     |  sub  |  V == 1  |  const, reg  | s-        |  [3s]
7382      -  as  a + (-b)  |  add  |  V == 1  |  const       | s-        |  [4s]
7383 
7384      s+  =  b < 0  ?  -0x80 :  0x7f
7385      s-  =  b < 0  ?   0x7f : -0x80
7386 
7387      The cases a - b actually perform  a - (-(-b))  if B is CONST.
7388   */
7389 
7390   op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
7391   op[1] = n_bytes > 1
7392     ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
7393     : NULL_RTX;
7394 
7395   bool need_copy = true;
7396   int len_call = 1 + AVR_HAVE_JMP_CALL;
7397 
7398   switch (code_sat)
7399     {
7400     default:
7401       gcc_unreachable();
7402 
7403     case SS_PLUS:
7404     case SS_MINUS:
7405 
7406       if (out_brvc)
7407         avr_asm_len ("brvc 0f", op, plen, 1);
7408 
7409       if (reg_overlap_mentioned_p (xop[0], xop[2]))
7410         {
7411           /* [1s,reg] */
7412 
7413           if (n_bytes == 1)
7414             avr_asm_len ("ldi %0,0x7f" CR_TAB
7415                          "adc %0,__zero_reg__", op, plen, 2);
7416           else
7417             avr_asm_len ("ldi %0,0x7f" CR_TAB
7418                          "ldi %1,0xff" CR_TAB
7419                          "adc %1,__zero_reg__" CR_TAB
7420                          "adc %0,__zero_reg__", op, plen, 4);
7421         }
7422       else if (sign == 0 && PLUS == code)
7423         {
7424           /* [1s,reg] */
7425 
7426           op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7427 
7428           if (n_bytes == 1)
7429             avr_asm_len ("ldi %0,0x80" CR_TAB
7430                          "sbrs %2,7"   CR_TAB
7431                          "dec %0", op, plen, 3);
7432           else
7433             avr_asm_len ("ldi %0,0x80" CR_TAB
7434                          "cp %2,%0"    CR_TAB
7435                          "sbc %1,%1"   CR_TAB
7436                          "sbci %0,0", op, plen, 4);
7437         }
7438       else if (sign == 0 && MINUS == code)
7439         {
7440           /* [3s,reg] */
7441 
7442           op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
7443 
7444           if (n_bytes == 1)
7445             avr_asm_len ("ldi %0,0x7f" CR_TAB
7446                          "sbrs %2,7"   CR_TAB
7447                          "inc %0", op, plen, 3);
7448           else
7449             avr_asm_len ("ldi %0,0x7f" CR_TAB
7450                          "cp %0,%2"    CR_TAB
7451                          "sbc %1,%1"   CR_TAB
7452                          "sbci %0,-1", op, plen, 4);
7453         }
7454       else if ((sign < 0) ^ (SS_MINUS == code_sat))
7455         {
7456           /* [1s,const,B < 0] [2s,B < 0] */
7457           /* [3s,const,B > 0] [4s,B > 0] */
7458 
7459           if (n_bytes == 8)
7460             {
7461               avr_asm_len ("%~call __clr_8", op, plen, len_call);
7462               need_copy = false;
7463             }
7464 
7465           avr_asm_len ("ldi %0,0x80", op, plen, 1);
7466           if (n_bytes > 1 && need_copy)
7467             avr_asm_len ("clr %1", op, plen, 1);
7468         }
7469       else if ((sign > 0) ^ (SS_MINUS == code_sat))
7470         {
7471           /* [1s,const,B > 0] [2s,B > 0] */
7472           /* [3s,const,B < 0] [4s,B < 0] */
7473 
7474           if (n_bytes == 8)
7475             {
7476               avr_asm_len ("sec" CR_TAB
7477                            "%~call __sbc_8", op, plen, 1 + len_call);
7478               need_copy = false;
7479             }
7480 
7481           avr_asm_len ("ldi %0,0x7f", op, plen, 1);
7482           if (n_bytes > 1 && need_copy)
7483             avr_asm_len ("ldi %1,0xff", op, plen, 1);
7484         }
7485       else
7486         gcc_unreachable();
7487 
7488       break;
7489 
7490     case US_PLUS:
7491       /* [1u] : [2u] */
7492 
7493       avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
7494 
7495       if (n_bytes == 8)
7496         {
7497           if (MINUS == code)
7498             avr_asm_len ("sec", op, plen, 1);
7499           avr_asm_len ("%~call __sbc_8", op, plen, len_call);
7500 
7501           need_copy = false;
7502         }
7503       else
7504         {
7505           if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
7506             avr_asm_len ("sec" CR_TAB
7507                          "sbc %0,%0", op, plen, 2);
7508           else
7509             avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
7510                          op, plen, 1);
7511         }
7512       break; /* US_PLUS */
7513 
7514     case US_MINUS:
7515       /* [4u] : [3u] */
7516 
7517       avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
7518 
7519       if (n_bytes == 8)
7520         {
7521           avr_asm_len ("%~call __clr_8", op, plen, len_call);
7522           need_copy = false;
7523         }
7524       else
7525         avr_asm_len ("clr %0", op, plen, 1);
7526 
7527       break;
7528     }
7529 
7530   /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
7531      Now copy the right value to the LSBs.  */
7532 
7533   if (need_copy && n_bytes > 1)
7534     {
7535       if (US_MINUS == code_sat || US_PLUS == code_sat)
7536         {
7537           avr_asm_len ("mov %1,%0", op, plen, 1);
7538 
7539           if (n_bytes > 2)
7540             {
7541               op[0] = xop[0];
7542               if (AVR_HAVE_MOVW)
7543                 avr_asm_len ("movw %0,%1", op, plen, 1);
7544               else
7545                 avr_asm_len ("mov %A0,%1" CR_TAB
7546                              "mov %B0,%1", op, plen, 2);
7547             }
7548         }
7549       else if (n_bytes > 2)
7550         {
7551           op[0] = xop[0];
7552           avr_asm_len ("mov %A0,%1" CR_TAB
7553                        "mov %B0,%1", op, plen, 2);
7554         }
7555     }
7556 
7557   if (need_copy && n_bytes == 8)
7558     {
7559       if (AVR_HAVE_MOVW)
7560         avr_asm_len ("movw %r0+2,%0" CR_TAB
7561                      "movw %r0+4,%0", xop, plen, 2);
7562       else
7563         avr_asm_len ("mov %r0+2,%0" CR_TAB
7564                      "mov %r0+3,%0" CR_TAB
7565                      "mov %r0+4,%0" CR_TAB
7566                      "mov %r0+5,%0", xop, plen, 4);
7567     }
7568 
7569   if (out_label)
7570     avr_asm_len ("0:", op, plen, 0);
7571 }
7572 
7573 
7574 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
7575    is ont a compile-time constant:
7576 
7577       XOP[0] = XOP[0] +/- XOP[2]
7578 
7579    This is a helper for the function below.  The only insns that need this
7580    are additions/subtraction for pointer modes, i.e. HImode and PSImode.  */
7581 
7582 static const char*
avr_out_plus_symbol(rtx * xop,enum rtx_code code,int * plen,int * pcc)7583 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen, int *pcc)
7584 {
7585   machine_mode mode = GET_MODE (xop[0]);
7586 
7587   /* Only pointer modes want to add symbols.  */
7588 
7589   gcc_assert (mode == HImode || mode == PSImode);
7590 
7591   *pcc = MINUS == code ? (int) CC_SET_CZN : (int) CC_SET_N;
7592 
7593   avr_asm_len (PLUS == code
7594                ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
7595                : "subi %A0,lo8(%2)"    CR_TAB "sbci %B0,hi8(%2)",
7596                xop, plen, -2);
7597 
7598   if (PSImode == mode)
7599     avr_asm_len (PLUS == code
7600                  ? "sbci %C0,hlo8(-(%2))"
7601                  : "sbci %C0,hlo8(%2)", xop, plen, 1);
7602   return "";
7603 }
7604 
7605 
7606 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
7607 
7608    INSN is a single_set insn or an insn pattern with a binary operation as
7609    SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
7610 
7611    XOP are the operands of INSN.  In the case of 64-bit operations with
7612    constant XOP[] has just one element:  The summand/subtrahend in XOP[0].
7613    The non-saturating insns up to 32 bits may or may not supply a "d" class
7614    scratch as XOP[3].
7615 
7616    If PLEN == NULL output the instructions.
7617    If PLEN != NULL set *PLEN to the length of the sequence in words.
7618 
7619    PCC is a pointer to store the instructions' effect on cc0.
7620    PCC may be NULL.
7621 
7622    PLEN and PCC default to NULL.
7623 
7624    OUT_LABEL defaults to TRUE.  For a description, see AVR_OUT_PLUS_1.
7625 
7626    Return ""  */
7627 
7628 const char*
avr_out_plus(rtx insn,rtx * xop,int * plen,int * pcc,bool out_label)7629 avr_out_plus (rtx insn, rtx *xop, int *plen, int *pcc, bool out_label)
7630 {
7631   int cc_plus, cc_minus, cc_dummy;
7632   int len_plus, len_minus;
7633   rtx op[4];
7634   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7635   rtx xdest = SET_DEST (xpattern);
7636   machine_mode mode = GET_MODE (xdest);
7637   machine_mode imode = int_mode_for_mode (mode);
7638   int n_bytes = GET_MODE_SIZE (mode);
7639   enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
7640   enum rtx_code code
7641     = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
7642        ? PLUS : MINUS);
7643 
7644   if (!pcc)
7645     pcc = &cc_dummy;
7646 
7647   /* PLUS and MINUS don't saturate:  Use modular wrap-around.  */
7648 
7649   if (PLUS == code_sat || MINUS == code_sat)
7650     code_sat = UNKNOWN;
7651 
7652   if (n_bytes <= 4 && REG_P (xop[2]))
7653     {
7654       avr_out_plus_1 (xop, plen, code, pcc, code_sat, 0, out_label);
7655       return "";
7656     }
7657 
7658   if (8 == n_bytes)
7659     {
7660       op[0] = gen_rtx_REG (DImode, ACC_A);
7661       op[1] = gen_rtx_REG (DImode, ACC_A);
7662       op[2] = avr_to_int_mode (xop[0]);
7663     }
7664   else
7665     {
7666       if (!REG_P (xop[2])
7667           && !CONST_INT_P (xop[2])
7668           && !CONST_FIXED_P (xop[2]))
7669         {
7670           return avr_out_plus_symbol (xop, code, plen, pcc);
7671         }
7672 
7673       op[0] = avr_to_int_mode (xop[0]);
7674       op[1] = avr_to_int_mode (xop[1]);
7675       op[2] = avr_to_int_mode (xop[2]);
7676     }
7677 
7678   /* Saturations and 64-bit operations don't have a clobber operand.
7679      For the other cases, the caller will provide a proper XOP[3].  */
7680 
7681   xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
7682   op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
7683 
7684   /* Saturation will need the sign of the original operand.  */
7685 
7686   rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
7687   int sign = INTVAL (xmsb) < 0 ? -1 : 1;
7688 
7689   /* If we subtract and the subtrahend is a constant, then negate it
7690      so that avr_out_plus_1 can be used.  */
7691 
7692   if (MINUS == code)
7693     op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
7694 
7695   /* Work out the shortest sequence.  */
7696 
7697   avr_out_plus_1 (op, &len_minus, MINUS, &cc_minus, code_sat, sign, out_label);
7698   avr_out_plus_1 (op, &len_plus, PLUS, &cc_plus, code_sat, sign, out_label);
7699 
7700   if (plen)
7701     {
7702       *plen = (len_minus <= len_plus) ? len_minus : len_plus;
7703       *pcc  = (len_minus <= len_plus) ? cc_minus : cc_plus;
7704     }
7705   else if (len_minus <= len_plus)
7706     avr_out_plus_1 (op, NULL, MINUS, pcc, code_sat, sign, out_label);
7707   else
7708     avr_out_plus_1 (op, NULL, PLUS, pcc, code_sat, sign, out_label);
7709 
7710   return "";
7711 }
7712 
7713 
7714 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
7715    time constant XOP[2]:
7716 
7717       XOP[0] = XOP[0] <op> XOP[2]
7718 
7719    and return "".  If PLEN == NULL, print assembler instructions to perform the
7720    operation; otherwise, set *PLEN to the length of the instruction sequence
7721    (in words) printed with PLEN == NULL.  XOP[3] is either an 8-bit clobber
7722    register or SCRATCH if no clobber register is needed for the operation.
7723    INSN is an INSN_P or a pattern of an insn.  */
7724 
7725 const char*
avr_out_bitop(rtx insn,rtx * xop,int * plen)7726 avr_out_bitop (rtx insn, rtx *xop, int *plen)
7727 {
7728   /* CODE and MODE of the operation.  */
7729   rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
7730   enum rtx_code code = GET_CODE (SET_SRC (xpattern));
7731   machine_mode mode = GET_MODE (xop[0]);
7732 
7733   /* Number of bytes to operate on.  */
7734   int i, n_bytes = GET_MODE_SIZE (mode);
7735 
7736   /* Value of T-flag (0 or 1) or -1 if unknow.  */
7737   int set_t = -1;
7738 
7739   /* Value (0..0xff) held in clobber register op[3] or -1 if unknown.  */
7740   int clobber_val = -1;
7741 
7742   /* op[0]: 8-bit destination register
7743      op[1]: 8-bit const int
7744      op[2]: 8-bit clobber register or SCRATCH
7745      op[3]: 8-bit register containing 0xff or NULL_RTX  */
7746   rtx op[4];
7747 
7748   op[2] = xop[3];
7749   op[3] = NULL_RTX;
7750 
7751   if (plen)
7752     *plen = 0;
7753 
7754   for (i = 0; i < n_bytes; i++)
7755     {
7756       /* We operate byte-wise on the destination.  */
7757       rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
7758       rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
7759 
7760       /* 8-bit value to operate with this byte. */
7761       unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7762 
7763       /* Number of bits set in the current byte of the constant.  */
7764       int pop8 = avr_popcount (val8);
7765 
7766       /* Registers R16..R31 can operate with immediate.  */
7767       bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7768 
7769       op[0] = reg8;
7770       op[1] = GEN_INT (val8);
7771 
7772       switch (code)
7773         {
7774         case IOR:
7775 
7776           if (0 == pop8)
7777             continue;
7778           else if (ld_reg_p)
7779             avr_asm_len ("ori %0,%1", op, plen, 1);
7780           else if (1 == pop8)
7781             {
7782               if (set_t != 1)
7783                 avr_asm_len ("set", op, plen, 1);
7784               set_t = 1;
7785 
7786               op[1] = GEN_INT (exact_log2 (val8));
7787               avr_asm_len ("bld %0,%1", op, plen, 1);
7788             }
7789           else if (8 == pop8)
7790             {
7791               if (op[3] != NULL_RTX)
7792                 avr_asm_len ("mov %0,%3", op, plen, 1);
7793               else
7794                 avr_asm_len ("clr %0" CR_TAB
7795                              "dec %0", op, plen, 2);
7796 
7797               op[3] = op[0];
7798             }
7799           else
7800             {
7801               if (clobber_val != (int) val8)
7802                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7803               clobber_val = (int) val8;
7804 
7805               avr_asm_len ("or %0,%2", op, plen, 1);
7806             }
7807 
7808           continue; /* IOR */
7809 
7810         case AND:
7811 
7812           if (8 == pop8)
7813             continue;
7814           else if (0 == pop8)
7815             avr_asm_len ("clr %0", op, plen, 1);
7816           else if (ld_reg_p)
7817             avr_asm_len ("andi %0,%1", op, plen, 1);
7818           else if (7 == pop8)
7819             {
7820               if (set_t != 0)
7821                 avr_asm_len ("clt", op, plen, 1);
7822               set_t = 0;
7823 
7824               op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
7825               avr_asm_len ("bld %0,%1", op, plen, 1);
7826             }
7827           else
7828             {
7829               if (clobber_val != (int) val8)
7830                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7831               clobber_val = (int) val8;
7832 
7833               avr_asm_len ("and %0,%2", op, plen, 1);
7834             }
7835 
7836           continue; /* AND */
7837 
7838         case XOR:
7839 
7840           if (0 == pop8)
7841             continue;
7842           else if (8 == pop8)
7843             avr_asm_len ("com %0", op, plen, 1);
7844           else if (ld_reg_p && val8 == (1 << 7))
7845             avr_asm_len ("subi %0,%1", op, plen, 1);
7846           else
7847             {
7848               if (clobber_val != (int) val8)
7849                 avr_asm_len ("ldi %2,%1", op, plen, 1);
7850               clobber_val = (int) val8;
7851 
7852               avr_asm_len ("eor %0,%2", op, plen, 1);
7853             }
7854 
7855           continue; /* XOR */
7856 
7857         default:
7858           /* Unknown rtx_code */
7859           gcc_unreachable();
7860         }
7861     } /* for all sub-bytes */
7862 
7863   return "";
7864 }
7865 
7866 
7867 /* Output sign extension from XOP[1] to XOP[0] and return "".
7868    If PLEN == NULL, print assembler instructions to perform the operation;
7869    otherwise, set *PLEN to the length of the instruction sequence (in words)
7870    as printed with PLEN == NULL.  */
7871 
7872 const char*
avr_out_sign_extend(rtx_insn * insn,rtx * xop,int * plen)7873 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
7874 {
7875   // Size in bytes of source resp. destination operand.
7876   unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
7877   unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
7878   rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
7879 
7880   if (plen)
7881     *plen = 0;
7882 
7883   // Copy destination to source
7884 
7885   if (REGNO (xop[0]) != REGNO (xop[1]))
7886     {
7887       gcc_assert (n_src <= 2);
7888 
7889       if (n_src == 2)
7890         avr_asm_len (AVR_HAVE_MOVW
7891                      ? "movw %0,%1"
7892                      : "mov %B0,%B1", xop, plen, 1);
7893       if (n_src == 1 || !AVR_HAVE_MOVW)
7894         avr_asm_len ("mov %A0,%A1", xop, plen, 1);
7895     }
7896 
7897   // Set Carry to the sign bit MSB.7...
7898 
7899   if (REGNO (xop[0]) == REGNO (xop[1])
7900       || !reg_unused_after (insn, r_msb))
7901     {
7902       avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
7903       r_msb = tmp_reg_rtx;
7904     }
7905 
7906   avr_asm_len ("lsl %0", &r_msb, plen, 1);
7907 
7908   // ...and propagate it to all the new sign bits
7909 
7910   for (unsigned n = n_src; n < n_dest; n++)
7911     avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
7912 
7913   return "";
7914 }
7915 
7916 
7917 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
7918    PLEN != NULL: Set *PLEN to the length of that sequence.
7919    Return "".  */
7920 
7921 const char*
avr_out_addto_sp(rtx * op,int * plen)7922 avr_out_addto_sp (rtx *op, int *plen)
7923 {
7924   int pc_len = AVR_2_BYTE_PC ? 2 : 3;
7925   int addend = INTVAL (op[0]);
7926 
7927   if (plen)
7928     *plen = 0;
7929 
7930   if (addend < 0)
7931     {
7932       if (flag_verbose_asm || flag_print_asm_name)
7933         avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
7934 
7935       while (addend <= -pc_len)
7936         {
7937           addend += pc_len;
7938           avr_asm_len ("rcall .", op, plen, 1);
7939         }
7940 
7941       while (addend++ < 0)
7942         avr_asm_len ("push __zero_reg__", op, plen, 1);
7943     }
7944   else if (addend > 0)
7945     {
7946       if (flag_verbose_asm || flag_print_asm_name)
7947         avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
7948 
7949       while (addend-- > 0)
7950         avr_asm_len ("pop __tmp_reg__", op, plen, 1);
7951     }
7952 
7953   return "";
7954 }
7955 
7956 
7957 /* Outputs instructions needed for fixed point type conversion.
7958    This includes converting between any fixed point type, as well
7959    as converting to any integer type.  Conversion between integer
7960    types is not supported.
7961 
7962    Converting signed fractional types requires a bit shift if converting
7963    to or from any unsigned fractional type because the decimal place is
7964    shifted by 1 bit.  When the destination is a signed fractional, the sign
7965    is stored in either the carry or T bit.  */
7966 
7967 const char*
avr_out_fract(rtx_insn * insn,rtx operands[],bool intsigned,int * plen)7968 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
7969 {
7970   size_t i;
7971   rtx xop[6];
7972   RTX_CODE shift = UNKNOWN;
7973   bool sign_in_carry = false;
7974   bool msb_in_carry = false;
7975   bool lsb_in_tmp_reg = false;
7976   bool lsb_in_carry = false;
7977   bool frac_rounded = false;
7978   const char *code_ashift = "lsl %0";
7979 
7980 
7981 #define MAY_CLOBBER(RR)                                                 \
7982   /* Shorthand used below.  */                                          \
7983   ((sign_bytes                                                          \
7984     && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb))  \
7985    || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb))		\
7986    || (reg_unused_after (insn, all_regs_rtx[RR])                        \
7987        && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
7988 
7989   struct
7990   {
7991     /* bytes       : Length of operand in bytes.
7992        ibyte       : Length of integral part in bytes.
7993        fbyte, fbit : Length of fractional part in bytes, bits.  */
7994 
7995     bool sbit;
7996     unsigned fbit, bytes, ibyte, fbyte;
7997     unsigned regno, regno_msb;
7998   } dest, src, *val[2] = { &dest, &src };
7999 
8000   if (plen)
8001     *plen = 0;
8002 
8003   /* Step 0:  Determine information on source and destination operand we
8004      ======   will need in the remainder.  */
8005 
8006   for (i = 0; i < sizeof (val) / sizeof (*val); i++)
8007     {
8008       machine_mode mode;
8009 
8010       xop[i] = operands[i];
8011 
8012       mode = GET_MODE (xop[i]);
8013 
8014       val[i]->bytes = GET_MODE_SIZE (mode);
8015       val[i]->regno = REGNO (xop[i]);
8016       val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
8017 
8018       if (SCALAR_INT_MODE_P (mode))
8019         {
8020           val[i]->sbit = intsigned;
8021           val[i]->fbit = 0;
8022         }
8023       else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
8024         {
8025           val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
8026           val[i]->fbit = GET_MODE_FBIT (mode);
8027         }
8028       else
8029         fatal_insn ("unsupported fixed-point conversion", insn);
8030 
8031       val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
8032       val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
8033     }
8034 
8035   // Byte offset of the decimal point taking into account different place
8036   // of the decimal point in input and output and different register numbers
8037   // of input and output.
8038   int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
8039 
8040   // Number of destination bytes that will come from sign / zero extension.
8041   int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
8042 
8043   // Number of bytes at the low end to be filled with zeros.
8044   int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
8045 
8046   // Do we have a 16-Bit register that is cleared?
8047   rtx clrw = NULL_RTX;
8048 
8049   bool sign_extend = src.sbit && sign_bytes;
8050 
8051   if (0 == dest.fbit % 8 && 7 == src.fbit % 8)
8052     shift = ASHIFT;
8053   else if (7 == dest.fbit % 8 && 0 == src.fbit % 8)
8054     shift = ASHIFTRT;
8055   else if (dest.fbit % 8 == src.fbit % 8)
8056     shift = UNKNOWN;
8057   else
8058     gcc_unreachable();
8059 
8060   /* If we need to round the fraction part, we might need to save/round it
8061      before clobbering any of it in Step 1.  Also, we might want to do
8062      the rounding now to make use of LD_REGS.  */
8063   if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8064       && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8065       && !TARGET_FRACT_CONV_TRUNC)
8066     {
8067       bool overlap
8068         = (src.regno <=
8069            (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
8070            && dest.regno - offset -1 >= dest.regno);
8071       unsigned s0 = dest.regno - offset -1;
8072       bool use_src = true;
8073       unsigned sn;
8074       unsigned copied_msb = src.regno_msb;
8075       bool have_carry = false;
8076 
8077       if (src.ibyte > dest.ibyte)
8078         copied_msb -= src.ibyte - dest.ibyte;
8079 
8080       for (sn = s0; sn <= copied_msb; sn++)
8081         if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
8082             && !reg_unused_after (insn, all_regs_rtx[sn]))
8083           use_src = false;
8084       if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
8085         {
8086           avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8087                        &all_regs_rtx[src.regno_msb], plen, 2);
8088           sn = src.regno;
8089           if (sn < s0)
8090             {
8091               if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
8092                 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
8093               else
8094                 avr_asm_len ("sec" CR_TAB
8095                              "cpc %0,__zero_reg__",
8096                              &all_regs_rtx[sn], plen, 2);
8097               have_carry = true;
8098             }
8099           while (++sn < s0)
8100             avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8101 
8102           avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
8103                        &all_regs_rtx[s0], plen, 1);
8104           for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8105             avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
8106           avr_asm_len ("\n0:", NULL, plen, 0);
8107           frac_rounded = true;
8108         }
8109       else if (use_src && overlap)
8110         {
8111           avr_asm_len ("clr __tmp_reg__" CR_TAB
8112                        "sbrc %1,0"       CR_TAB
8113                        "dec __tmp_reg__", xop, plen, 1);
8114           sn = src.regno;
8115           if (sn < s0)
8116             {
8117               avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8118               have_carry = true;
8119             }
8120 
8121           while (++sn < s0)
8122             avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
8123 
8124           if (have_carry)
8125             avr_asm_len ("clt"                CR_TAB
8126                          "bld __tmp_reg__,7"  CR_TAB
8127                          "adc %0,__tmp_reg__",
8128                          &all_regs_rtx[s0], plen, 1);
8129           else
8130             avr_asm_len ("lsr __tmp_reg" CR_TAB
8131                          "add %0,__tmp_reg__",
8132                          &all_regs_rtx[s0], plen, 2);
8133           for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
8134             avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8135           frac_rounded = true;
8136         }
8137       else if (overlap)
8138         {
8139           bool use_src
8140             = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
8141                && (IN_RANGE (s0, dest.regno, dest.regno_msb)
8142                    || reg_unused_after (insn, all_regs_rtx[s0])));
8143           xop[2] = all_regs_rtx[s0];
8144           unsigned sn = src.regno;
8145           if (!use_src || sn == s0)
8146             avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8147           /* We need to consider to-be-discarded bits
8148              if the value is negative.  */
8149           if (sn < s0)
8150             {
8151               avr_asm_len ("tst %0" CR_TAB
8152                            "brpl 0f",
8153                            &all_regs_rtx[src.regno_msb], plen, 2);
8154               /* Test to-be-discarded bytes for any nozero bits.
8155                  ??? Could use OR or SBIW to test two registers at once.  */
8156               if (sn < s0)
8157                 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8158 
8159               while (++sn < s0)
8160                 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
8161               /* Set bit 0 in __tmp_reg__ if any of the lower bits was set.  */
8162               if (use_src)
8163                 avr_asm_len ("breq 0f" CR_TAB
8164                              "ori %2,1"
8165                              "\n0:\t" "mov __tmp_reg__,%2",
8166                              xop, plen, 3);
8167               else
8168                 avr_asm_len ("breq 0f" CR_TAB
8169                              "set"     CR_TAB
8170                              "bld __tmp_reg__,0\n0:",
8171                              xop, plen, 3);
8172             }
8173           lsb_in_tmp_reg = true;
8174         }
8175     }
8176 
8177   /* Step 1:  Clear bytes at the low end and copy payload bits from source
8178      ======   to destination.  */
8179 
8180   int step = offset < 0 ? 1 : -1;
8181   unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
8182 
8183   // We cleared at least that number of registers.
8184   int clr_n = 0;
8185 
8186   for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
8187     {
8188       // Next regno of destination is needed for MOVW
8189       unsigned d1 = d0 + step;
8190 
8191       // Current and next regno of source
8192       signed s0 = d0 - offset;
8193       signed s1 = s0 + step;
8194 
8195       // Must current resp. next regno be CLRed?  This applies to the low
8196       // bytes of the destination that have no associated source bytes.
8197       bool clr0 = s0 < (signed) src.regno;
8198       bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
8199 
8200       // First gather what code to emit (if any) and additional step to
8201       // apply if a MOVW is in use.  xop[2] is destination rtx and xop[3]
8202       // is the source rtx for the current loop iteration.
8203       const char *code = NULL;
8204       int stepw = 0;
8205 
8206       if (clr0)
8207         {
8208           if (AVR_HAVE_MOVW && clr1 && clrw)
8209             {
8210               xop[2] = all_regs_rtx[d0 & ~1];
8211               xop[3] = clrw;
8212               code = "movw %2,%3";
8213               stepw = step;
8214             }
8215           else
8216             {
8217               xop[2] = all_regs_rtx[d0];
8218               code = "clr %2";
8219 
8220               if (++clr_n >= 2
8221                   && !clrw
8222                   && d0 % 2 == (step > 0))
8223                 {
8224                   clrw = all_regs_rtx[d0 & ~1];
8225                 }
8226             }
8227         }
8228       else if (offset && s0 <= (signed) src.regno_msb)
8229         {
8230           int movw = AVR_HAVE_MOVW && offset % 2 == 0
8231             && d0 % 2 == (offset > 0)
8232             && d1 <= dest.regno_msb && d1 >= dest.regno
8233             && s1 <= (signed) src.regno_msb  && s1 >= (signed) src.regno;
8234 
8235           xop[2] = all_regs_rtx[d0 & ~movw];
8236           xop[3] = all_regs_rtx[s0 & ~movw];
8237           code = movw ? "movw %2,%3" : "mov %2,%3";
8238           stepw = step * movw;
8239         }
8240 
8241       if (code)
8242         {
8243           if (sign_extend && shift != ASHIFT && !sign_in_carry
8244               && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
8245             {
8246               /* We are going to override the sign bit.  If we sign-extend,
8247                  store the sign in the Carry flag.  This is not needed if
8248                  the destination will be ASHIFT in the remainder because
8249                  the ASHIFT will set Carry without extra instruction.  */
8250 
8251               avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
8252               sign_in_carry = true;
8253             }
8254 
8255           unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
8256 
8257           if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8258               && src.ibyte > dest.ibyte
8259               && (d0 == src_msb || d0 + stepw == src_msb))
8260             {
8261               /* We are going to override the MSB.  If we shift right,
8262                  store the MSB in the Carry flag.  This is only needed if
8263                  we don't sign-extend becaue with sign-extension the MSB
8264                  (the sign) will be produced by the sign extension.  */
8265 
8266               avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
8267               msb_in_carry = true;
8268             }
8269 
8270           unsigned src_lsb = dest.regno - offset -1;
8271 
8272           if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
8273 	      && !lsb_in_tmp_reg
8274               && (d0 == src_lsb || d0 + stepw == src_lsb))
8275             {
8276               /* We are going to override the new LSB; store it into carry.  */
8277 
8278               avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
8279               code_ashift = "rol %0";
8280               lsb_in_carry = true;
8281             }
8282 
8283           avr_asm_len (code, xop, plen, 1);
8284           d0 += stepw;
8285         }
8286     }
8287 
8288   /* Step 2:  Shift destination left by 1 bit position.  This might be needed
8289      ======   for signed input and unsigned output.  */
8290 
8291   if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
8292     {
8293       unsigned s0 = dest.regno - offset -1;
8294 
8295       /* n1169 4.1.4 says:
8296 	 "Conversions from a fixed-point to an integer type round toward zero."
8297 	 Hence, converting a fract type to integer only gives a non-zero result
8298 	 for -1.  */
8299       if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8300 	  && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
8301 	  && !TARGET_FRACT_CONV_TRUNC)
8302 	{
8303 	  gcc_assert (s0 == src.regno_msb);
8304 	  /* Check if the input is -1.  We do that by checking if negating
8305 	     the input causes an integer overflow.  */
8306 	  unsigned sn = src.regno;
8307 	  avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8308 	  while (sn <= s0)
8309 	    avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
8310 
8311 	  /* Overflow goes with set carry.  Clear carry otherwise.  */
8312 	  avr_asm_len ("brvs 0f" CR_TAB
8313                        "clc\n0:", NULL, plen, 2);
8314 	}
8315       /* Likewise, when converting from accumulator types to integer, we
8316 	 need to round up negative values.  */
8317       else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
8318 	       && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
8319 	       && !TARGET_FRACT_CONV_TRUNC
8320 	       && !frac_rounded)
8321 	{
8322 	  bool have_carry = false;
8323 
8324 	  xop[2] = all_regs_rtx[s0];
8325 	  if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
8326 	    avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
8327 	  avr_asm_len ("tst %0" CR_TAB "brpl 0f",
8328 		       &all_regs_rtx[src.regno_msb], plen, 2);
8329 	  if (!lsb_in_tmp_reg)
8330 	    {
8331 	      unsigned sn = src.regno;
8332 	      if (sn < s0)
8333 		{
8334 		  avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
8335 			       plen, 1);
8336 		  have_carry = true;
8337 		}
8338 	      while (++sn < s0)
8339 		avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
8340 	      lsb_in_tmp_reg = !MAY_CLOBBER (s0);
8341 	    }
8342 	  /* Add in C and the rounding value 127.  */
8343 	  /* If the destination msb is a sign byte, and in LD_REGS,
8344 	     grab it as a temporary.  */
8345 	  if (sign_bytes
8346 	      && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
8347 				    dest.regno_msb))
8348 	    {
8349 	      xop[3] = all_regs_rtx[dest.regno_msb];
8350 	      avr_asm_len ("ldi %3,127", xop, plen, 1);
8351 	      avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
8352 			   : have_carry ? "adc %2,%3"
8353 			   : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
8354 			   : "add %2,%3"),
8355 			   xop, plen, 1);
8356 	    }
8357 	  else
8358 	    {
8359 	      /* Fall back to use __zero_reg__ as a temporary.  */
8360 	      avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
8361 	      if (have_carry)
8362 		avr_asm_len ("clt" CR_TAB
8363                              "bld __zero_reg__,7", NULL, plen, 2);
8364 	      else
8365 		avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
8366 	      avr_asm_len (have_carry && lsb_in_tmp_reg
8367                            ? "adc __tmp_reg__,__zero_reg__"
8368                            : have_carry ? "adc %2,__zero_reg__"
8369                            : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
8370                            : "add %2,__zero_reg__",
8371 			   xop, plen, 1);
8372 	      avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
8373 	    }
8374 
8375           for (d0 = dest.regno + zero_bytes;
8376 	       d0 <= dest.regno_msb - sign_bytes; d0++)
8377 	    avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
8378 
8379           avr_asm_len (lsb_in_tmp_reg
8380 		       ? "\n0:\t" "lsl __tmp_reg__"
8381                        : "\n0:\t" "lsl %2",
8382 		       xop, plen, 1);
8383 	}
8384       else if (MAY_CLOBBER (s0))
8385         avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8386       else
8387         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8388                      "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8389 
8390       code_ashift = "rol %0";
8391       lsb_in_carry = true;
8392     }
8393 
8394   if (shift == ASHIFT)
8395     {
8396       for (d0 = dest.regno + zero_bytes;
8397            d0 <= dest.regno_msb - sign_bytes; d0++)
8398         {
8399           avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
8400           code_ashift = "rol %0";
8401         }
8402 
8403       lsb_in_carry = false;
8404       sign_in_carry = true;
8405     }
8406 
8407   /* Step 4a:  Store MSB in carry if we don't already have it or will produce
8408      =======   it in sign-extension below.  */
8409 
8410   if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
8411       && src.ibyte > dest.ibyte)
8412     {
8413       unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
8414 
8415       if (MAY_CLOBBER (s0))
8416         avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
8417       else
8418         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8419                      "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8420 
8421       msb_in_carry = true;
8422     }
8423 
8424   /* Step 3:  Sign-extend or zero-extend the destination as needed.
8425      ======   */
8426 
8427   if (sign_extend && !sign_in_carry)
8428     {
8429       unsigned s0 = src.regno_msb;
8430 
8431       if (MAY_CLOBBER (s0))
8432         avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
8433       else
8434         avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
8435                      "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
8436 
8437       sign_in_carry = true;
8438   }
8439 
8440   gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
8441 
8442   unsigned copies = 0;
8443   rtx movw = sign_extend ? NULL_RTX : clrw;
8444 
8445   for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
8446     {
8447       if (AVR_HAVE_MOVW && movw
8448           && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
8449         {
8450           xop[2] = all_regs_rtx[d0];
8451           xop[3] = movw;
8452           avr_asm_len ("movw %2,%3", xop, plen, 1);
8453           d0++;
8454         }
8455       else
8456         {
8457           avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
8458                        &all_regs_rtx[d0], plen, 1);
8459 
8460           if (++copies >= 2 && !movw && d0 % 2 == 1)
8461             movw = all_regs_rtx[d0-1];
8462         }
8463     } /* for */
8464 
8465 
8466   /* Step 4:  Right shift the destination.  This might be needed for
8467      ======   conversions from unsigned to signed.  */
8468 
8469   if (shift == ASHIFTRT)
8470     {
8471       const char *code_ashiftrt = "lsr %0";
8472 
8473       if (sign_extend || msb_in_carry)
8474         code_ashiftrt = "ror %0";
8475 
8476       if (src.sbit && src.ibyte == dest.ibyte)
8477         code_ashiftrt = "asr %0";
8478 
8479       for (d0 = dest.regno_msb - sign_bytes;
8480            d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
8481         {
8482           avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
8483           code_ashiftrt = "ror %0";
8484         }
8485     }
8486 
8487 #undef MAY_CLOBBER
8488 
8489   return "";
8490 }
8491 
8492 
8493 /* Output fixed-point rounding.  XOP[0] = XOP[1] is the operand to round.
8494    XOP[2] is the rounding point, a CONST_INT.  The function prints the
8495    instruction sequence if PLEN = NULL and computes the length in words
8496    of the sequence if PLEN != NULL.  Most of this function deals with
8497    preparing operands for calls to `avr_out_plus' and `avr_out_bitop'.  */
8498 
8499 const char*
avr_out_round(rtx_insn * insn ATTRIBUTE_UNUSED,rtx * xop,int * plen)8500 avr_out_round (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *xop, int *plen)
8501 {
8502   machine_mode mode = GET_MODE (xop[0]);
8503   machine_mode imode = int_mode_for_mode (mode);
8504   // The smallest fractional bit not cleared by the rounding is 2^(-RP).
8505   int fbit = (int) GET_MODE_FBIT (mode);
8506   double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
8507   wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
8508 					 GET_MODE_PRECISION (imode));
8509   // Lengths of PLUS and AND parts.
8510   int len_add = 0, *plen_add = plen ? &len_add : NULL;
8511   int len_and = 0, *plen_and = plen ? &len_and : NULL;
8512 
8513   // Add-Saturate  1/2 * 2^(-RP).  Don't print the label "0:" when printing
8514   // the saturated addition so that we can emit the "rjmp 1f" before the
8515   // "0:" below.
8516 
8517   rtx xadd = const_fixed_from_double_int (i_add, mode);
8518   rtx xpattern, xsrc, op[4];
8519 
8520   xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
8521     ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
8522     : gen_rtx_US_PLUS (mode, xop[1], xadd);
8523   xpattern = gen_rtx_SET (xop[0], xsrc);
8524 
8525   op[0] = xop[0];
8526   op[1] = xop[1];
8527   op[2] = xadd;
8528   avr_out_plus (xpattern, op, plen_add, NULL, false /* Don't print "0:" */);
8529 
8530   avr_asm_len ("rjmp 1f" CR_TAB
8531                "0:", NULL, plen_add, 1);
8532 
8533   // Keep  all bits from RP and higher:   ... 2^(-RP)
8534   // Clear all bits from RP+1 and lower:              2^(-RP-1) ...
8535   // Rounding point                           ^^^^^^^
8536   // Added above                                      ^^^^^^^^^
8537   rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
8538   rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
8539 
8540   xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
8541 
8542   op[0] = xreg;
8543   op[1] = xreg;
8544   op[2] = xmask;
8545   op[3] = gen_rtx_SCRATCH (QImode);
8546   avr_out_bitop (xpattern, op, plen_and);
8547   avr_asm_len ("1:", NULL, plen, 0);
8548 
8549   if (plen)
8550     *plen = len_add + len_and;
8551 
8552   return "";
8553 }
8554 
8555 
8556 /* Create RTL split patterns for byte sized rotate expressions.  This
8557   produces a series of move instructions and considers overlap situations.
8558   Overlapping non-HImode operands need a scratch register.  */
8559 
8560 bool
avr_rotate_bytes(rtx operands[])8561 avr_rotate_bytes (rtx operands[])
8562 {
8563     int i, j;
8564     machine_mode mode = GET_MODE (operands[0]);
8565     bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
8566     bool same_reg = rtx_equal_p (operands[0], operands[1]);
8567     int num = INTVAL (operands[2]);
8568     rtx scratch = operands[3];
8569     /* Work out if byte or word move is needed.  Odd byte rotates need QImode.
8570        Word move if no scratch is needed, otherwise use size of scratch.  */
8571     machine_mode move_mode = QImode;
8572     int move_size, offset, size;
8573 
8574     if (num & 0xf)
8575       move_mode = QImode;
8576     else if ((mode == SImode && !same_reg) || !overlapped)
8577       move_mode = HImode;
8578     else
8579       move_mode = GET_MODE (scratch);
8580 
8581     /* Force DI rotate to use QI moves since other DI moves are currently split
8582        into QI moves so forward propagation works better.  */
8583     if (mode == DImode)
8584       move_mode = QImode;
8585     /* Make scratch smaller if needed.  */
8586     if (SCRATCH != GET_CODE (scratch)
8587         && HImode == GET_MODE (scratch)
8588         && QImode == move_mode)
8589       scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
8590 
8591     move_size = GET_MODE_SIZE (move_mode);
8592     /* Number of bytes/words to rotate.  */
8593     offset = (num  >> 3) / move_size;
8594     /* Number of moves needed.  */
8595     size = GET_MODE_SIZE (mode) / move_size;
8596     /* Himode byte swap is special case to avoid a scratch register.  */
8597     if (mode == HImode && same_reg)
8598       {
8599 	/* HImode byte swap, using xor.  This is as quick as using scratch.  */
8600 	rtx src, dst;
8601 	src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
8602 	dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
8603 	if (!rtx_equal_p (dst, src))
8604 	  {
8605 	     emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8606 	     emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
8607 	     emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
8608 	  }
8609       }
8610     else
8611       {
8612 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode)  */
8613 	/* Create linked list of moves to determine move order.  */
8614 	struct {
8615 	  rtx src, dst;
8616 	  int links;
8617 	} move[MAX_SIZE + 8];
8618 	int blocked, moves;
8619 
8620 	gcc_assert (size <= MAX_SIZE);
8621 	/* Generate list of subreg moves.  */
8622 	for (i = 0; i < size; i++)
8623           {
8624 	    int from = i;
8625 	    int to = (from + offset) % size;
8626 	    move[i].src = simplify_gen_subreg (move_mode, operands[1],
8627                                                mode, from * move_size);
8628 	    move[i].dst = simplify_gen_subreg (move_mode, operands[0],
8629                                                mode, to * move_size);
8630             move[i].links = -1;
8631           }
8632 	/* Mark dependence where a dst of one move is the src of another move.
8633 	   The first move is a conflict as it must wait until second is
8634 	   performed.  We ignore moves to self - we catch this later.  */
8635 	if (overlapped)
8636 	  for (i = 0; i < size; i++)
8637 	    if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
8638 	      for (j = 0; j < size; j++)
8639 		if (j != i && rtx_equal_p (move[j].src, move[i].dst))
8640 		  {
8641 		    /* The dst of move i is the src of move j.  */
8642 		    move[i].links = j;
8643 		    break;
8644 		  }
8645 
8646 	blocked = -1;
8647 	moves = 0;
8648 	/* Go through move list and perform non-conflicting moves.  As each
8649 	   non-overlapping move is made, it may remove other conflicts
8650 	   so the process is repeated until no conflicts remain.  */
8651 	do
8652 	  {
8653 	    blocked = -1;
8654 	    moves = 0;
8655 	    /* Emit move where dst is not also a src or we have used that
8656 	       src already.  */
8657 	    for (i = 0; i < size; i++)
8658 	      if (move[i].src != NULL_RTX)
8659 		{
8660 		  if (move[i].links == -1
8661 		      || move[move[i].links].src == NULL_RTX)
8662 		    {
8663 		      moves++;
8664 		      /* Ignore NOP moves to self.  */
8665 		      if (!rtx_equal_p (move[i].dst, move[i].src))
8666 			emit_move_insn (move[i].dst, move[i].src);
8667 
8668 		      /* Remove  conflict from list.  */
8669 		      move[i].src = NULL_RTX;
8670 		    }
8671 		  else
8672 		    blocked = i;
8673 		}
8674 
8675 	    /* Check for deadlock. This is when no moves occurred and we have
8676 	       at least one blocked move.  */
8677 	    if (moves == 0 && blocked != -1)
8678 	      {
8679 		/* Need to use scratch register to break deadlock.
8680 		   Add move to put dst of blocked move into scratch.
8681 		   When this move occurs, it will break chain deadlock.
8682 		   The scratch register is substituted for real move.  */
8683 
8684 		gcc_assert (SCRATCH != GET_CODE (scratch));
8685 
8686 		move[size].src = move[blocked].dst;
8687 		move[size].dst =  scratch;
8688 		/* Scratch move is never blocked.  */
8689 		move[size].links = -1;
8690 		/* Make sure we have valid link.  */
8691 		gcc_assert (move[blocked].links != -1);
8692 		/* Replace src of  blocking move with scratch reg.  */
8693 		move[move[blocked].links].src = scratch;
8694 		/* Make dependent on scratch move occurring.  */
8695 		move[blocked].links = size;
8696 		size=size+1;
8697 	      }
8698 	  }
8699 	while (blocked != -1);
8700       }
8701     return true;
8702 }
8703 
8704 
8705 /* Worker function for `ADJUST_INSN_LENGTH'.  */
8706 /* Modifies the length assigned to instruction INSN
8707    LEN is the initially computed length of the insn.  */
8708 
8709 int
avr_adjust_insn_length(rtx_insn * insn,int len)8710 avr_adjust_insn_length (rtx_insn *insn, int len)
8711 {
8712   rtx *op = recog_data.operand;
8713   enum attr_adjust_len adjust_len;
8714 
8715   /* Some complex insns don't need length adjustment and therefore
8716      the length need not/must not be adjusted for these insns.
8717      It is easier to state this in an insn attribute "adjust_len" than
8718      to clutter up code here...  */
8719 
8720   if (!NONDEBUG_INSN_P (insn)
8721       || -1 == recog_memoized (insn))
8722     {
8723       return len;
8724     }
8725 
8726   /* Read from insn attribute "adjust_len" if/how length is to be adjusted.  */
8727 
8728   adjust_len = get_attr_adjust_len (insn);
8729 
8730   if (adjust_len == ADJUST_LEN_NO)
8731     {
8732       /* Nothing to adjust: The length from attribute "length" is fine.
8733          This is the default.  */
8734 
8735       return len;
8736     }
8737 
8738   /* Extract insn's operands.  */
8739 
8740   extract_constrain_insn_cached (insn);
8741 
8742   /* Dispatch to right function.  */
8743 
8744   switch (adjust_len)
8745     {
8746     case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
8747     case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
8748     case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
8749 
8750     case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
8751 
8752     case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
8753     case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
8754 
8755     case ADJUST_LEN_MOV8:  output_movqi (insn, op, &len); break;
8756     case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
8757     case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
8758     case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
8759     case ADJUST_LEN_MOVMEM: avr_out_movmem (insn, op, &len); break;
8760     case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
8761     case ADJUST_LEN_LPM: avr_out_lpm (insn, op, &len); break;
8762     case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
8763 
8764     case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
8765     case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
8766     case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
8767 
8768     case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
8769     case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
8770     case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
8771     case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
8772     case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
8773 
8774     case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
8775     case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
8776     case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
8777 
8778     case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
8779     case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
8780     case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
8781 
8782     case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
8783     case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
8784     case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
8785 
8786     case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
8787     case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
8788     case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
8789 
8790     case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
8791 
8792     case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
8793 
8794     default:
8795       gcc_unreachable();
8796     }
8797 
8798   return len;
8799 }
8800 
8801 /* Return nonzero if register REG dead after INSN.  */
8802 
8803 int
reg_unused_after(rtx_insn * insn,rtx reg)8804 reg_unused_after (rtx_insn *insn, rtx reg)
8805 {
8806   return (dead_or_set_p (insn, reg)
8807 	  || (REG_P(reg) && _reg_unused_after (insn, reg)));
8808 }
8809 
8810 /* Return nonzero if REG is not used after INSN.
8811    We assume REG is a reload reg, and therefore does
8812    not live past labels.  It may live past calls or jumps though.  */
8813 
8814 int
_reg_unused_after(rtx_insn * insn,rtx reg)8815 _reg_unused_after (rtx_insn *insn, rtx reg)
8816 {
8817   enum rtx_code code;
8818   rtx set;
8819 
8820   /* If the reg is set by this instruction, then it is safe for our
8821      case.  Disregard the case where this is a store to memory, since
8822      we are checking a register used in the store address.  */
8823   set = single_set (insn);
8824   if (set && GET_CODE (SET_DEST (set)) != MEM
8825       && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8826     return 1;
8827 
8828   while ((insn = NEXT_INSN (insn)))
8829     {
8830       rtx set;
8831       code = GET_CODE (insn);
8832 
8833 #if 0
8834       /* If this is a label that existed before reload, then the register
8835 	 if dead here.  However, if this is a label added by reorg, then
8836 	 the register may still be live here.  We can't tell the difference,
8837 	 so we just ignore labels completely.  */
8838       if (code == CODE_LABEL)
8839 	return 1;
8840       /* else */
8841 #endif
8842 
8843       if (!INSN_P (insn))
8844 	continue;
8845 
8846       if (code == JUMP_INSN)
8847 	return 0;
8848 
8849       /* If this is a sequence, we must handle them all at once.
8850 	 We could have for instance a call that sets the target register,
8851 	 and an insn in a delay slot that uses the register.  In this case,
8852 	 we must return 0.  */
8853       else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
8854 	{
8855 	  rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
8856 	  int i;
8857 	  int retval = 0;
8858 
8859 	  for (i = 0; i < seq->len (); i++)
8860 	    {
8861 	      rtx_insn *this_insn = seq->insn (i);
8862 	      rtx set = single_set (this_insn);
8863 
8864 	      if (CALL_P (this_insn))
8865 		code = CALL_INSN;
8866 	      else if (JUMP_P (this_insn))
8867 		{
8868 		  if (INSN_ANNULLED_BRANCH_P (this_insn))
8869 		    return 0;
8870 		  code = JUMP_INSN;
8871 		}
8872 
8873 	      if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8874 		return 0;
8875 	      if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8876 		{
8877 		  if (GET_CODE (SET_DEST (set)) != MEM)
8878 		    retval = 1;
8879 		  else
8880 		    return 0;
8881 		}
8882 	      if (set == 0
8883 		  && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
8884 		return 0;
8885 	    }
8886 	  if (retval == 1)
8887 	    return 1;
8888 	  else if (code == JUMP_INSN)
8889 	    return 0;
8890 	}
8891 
8892       if (code == CALL_INSN)
8893 	{
8894 	  rtx tem;
8895 	  for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
8896 	    if (GET_CODE (XEXP (tem, 0)) == USE
8897 		&& REG_P (XEXP (XEXP (tem, 0), 0))
8898 		&& reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
8899 	      return 0;
8900 	  if (call_used_regs[REGNO (reg)])
8901 	    return 1;
8902 	}
8903 
8904       set = single_set (insn);
8905 
8906       if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
8907 	return 0;
8908       if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
8909 	return GET_CODE (SET_DEST (set)) != MEM;
8910       if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
8911 	return 0;
8912     }
8913   return 1;
8914 }
8915 
8916 
8917 /* Implement `TARGET_ASM_INTEGER'.  */
8918 /* Target hook for assembling integer objects.  The AVR version needs
8919    special handling for references to certain labels.  */
8920 
8921 static bool
avr_assemble_integer(rtx x,unsigned int size,int aligned_p)8922 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
8923 {
8924   if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
8925       && text_segment_operand (x, VOIDmode))
8926     {
8927       fputs ("\t.word\tgs(", asm_out_file);
8928       output_addr_const (asm_out_file, x);
8929       fputs (")\n", asm_out_file);
8930 
8931       return true;
8932     }
8933   else if (GET_MODE (x) == PSImode)
8934     {
8935       /* This needs binutils 2.23+, see PR binutils/13503  */
8936 
8937       fputs ("\t.byte\tlo8(", asm_out_file);
8938       output_addr_const (asm_out_file, x);
8939       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8940 
8941       fputs ("\t.byte\thi8(", asm_out_file);
8942       output_addr_const (asm_out_file, x);
8943       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8944 
8945       fputs ("\t.byte\thh8(", asm_out_file);
8946       output_addr_const (asm_out_file, x);
8947       fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
8948 
8949       return true;
8950     }
8951   else if (CONST_FIXED_P (x))
8952     {
8953       unsigned n;
8954 
8955       /* varasm fails to handle big fixed modes that don't fit in hwi.  */
8956 
8957       for (n = 0; n < size; n++)
8958         {
8959           rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
8960           default_assemble_integer (xn, 1, aligned_p);
8961         }
8962 
8963       return true;
8964     }
8965 
8966   return default_assemble_integer (x, size, aligned_p);
8967 }
8968 
8969 
8970 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'.  */
8971 /* Return value is nonzero if pseudos that have been
8972    assigned to registers of class CLASS would likely be spilled
8973    because registers of CLASS are needed for spill registers.  */
8974 
8975 static bool
avr_class_likely_spilled_p(reg_class_t c)8976 avr_class_likely_spilled_p (reg_class_t c)
8977 {
8978   return (c != ALL_REGS &&
8979            (AVR_TINY ? 1 : c != ADDW_REGS));
8980 }
8981 
8982 
8983 /* Valid attributes:
8984    progmem   -  Put data to program memory.
8985    signal    -  Make a function to be hardware interrupt.
8986                 After function prologue interrupts remain disabled.
8987    interrupt -  Make a function to be hardware interrupt. Before function
8988                 prologue interrupts are enabled by means of SEI.
8989    naked     -  Don't generate function prologue/epilogue and RET
8990                 instruction.  */
8991 
8992 /* Handle a "progmem" attribute; arguments as in
8993    struct attribute_spec.handler.  */
8994 
8995 static tree
avr_handle_progmem_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)8996 avr_handle_progmem_attribute (tree *node, tree name,
8997 			      tree args ATTRIBUTE_UNUSED,
8998 			      int flags ATTRIBUTE_UNUSED,
8999 			      bool *no_add_attrs)
9000 {
9001   if (DECL_P (*node))
9002     {
9003       if (TREE_CODE (*node) == TYPE_DECL)
9004 	{
9005 	  /* This is really a decl attribute, not a type attribute,
9006 	     but try to handle it for GCC 3.0 backwards compatibility.  */
9007 
9008 	  tree type = TREE_TYPE (*node);
9009 	  tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
9010 	  tree newtype = build_type_attribute_variant (type, attr);
9011 
9012 	  TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
9013 	  TREE_TYPE (*node) = newtype;
9014 	  *no_add_attrs = true;
9015 	}
9016       else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
9017 	{
9018           *no_add_attrs = false;
9019 	}
9020       else
9021 	{
9022 	  warning (OPT_Wattributes, "%qE attribute ignored",
9023 		   name);
9024 	  *no_add_attrs = true;
9025 	}
9026     }
9027 
9028   return NULL_TREE;
9029 }
9030 
9031 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
9032    struct attribute_spec.handler.  */
9033 
9034 static tree
avr_handle_fndecl_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)9035 avr_handle_fndecl_attribute (tree *node, tree name,
9036 			     tree args ATTRIBUTE_UNUSED,
9037 			     int flags ATTRIBUTE_UNUSED,
9038 			     bool *no_add_attrs)
9039 {
9040   if (TREE_CODE (*node) != FUNCTION_DECL)
9041     {
9042       warning (OPT_Wattributes, "%qE attribute only applies to functions",
9043 	       name);
9044       *no_add_attrs = true;
9045     }
9046 
9047   return NULL_TREE;
9048 }
9049 
9050 static tree
avr_handle_fntype_attribute(tree * node,tree name,tree args ATTRIBUTE_UNUSED,int flags ATTRIBUTE_UNUSED,bool * no_add_attrs)9051 avr_handle_fntype_attribute (tree *node, tree name,
9052                              tree args ATTRIBUTE_UNUSED,
9053                              int flags ATTRIBUTE_UNUSED,
9054                              bool *no_add_attrs)
9055 {
9056   if (TREE_CODE (*node) != FUNCTION_TYPE)
9057     {
9058       warning (OPT_Wattributes, "%qE attribute only applies to functions",
9059 	       name);
9060       *no_add_attrs = true;
9061     }
9062 
9063   return NULL_TREE;
9064 }
9065 
9066 static tree
avr_handle_addr_attribute(tree * node,tree name,tree args,int flags ATTRIBUTE_UNUSED,bool * no_add)9067 avr_handle_addr_attribute (tree *node, tree name, tree args,
9068 			   int flags ATTRIBUTE_UNUSED, bool *no_add)
9069 {
9070   bool io_p = (strncmp (IDENTIFIER_POINTER (name), "io", 2) == 0);
9071   location_t loc = DECL_SOURCE_LOCATION (*node);
9072 
9073   if (!VAR_P (*node))
9074     {
9075       warning_at (loc, OPT_Wattributes, "%qE attribute only applies to "
9076 		  "variables", name);
9077       *no_add = true;
9078       return NULL_TREE;
9079     }
9080 
9081   if (args != NULL_TREE)
9082     {
9083       if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
9084 	TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
9085       tree arg = TREE_VALUE (args);
9086       if (TREE_CODE (arg) != INTEGER_CST)
9087 	{
9088 	  warning_at (loc, OPT_Wattributes, "%qE attribute allows only an "
9089 		      "integer constant argument", name);
9090 	  *no_add = true;
9091 	}
9092       else if (io_p
9093 	       && (!tree_fits_shwi_p (arg)
9094 		   || !(strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
9095 			? low_io_address_operand : io_address_operand)
9096 			 (GEN_INT (TREE_INT_CST_LOW (arg)), QImode)))
9097 	{
9098 	  warning_at (loc, OPT_Wattributes, "%qE attribute address "
9099 		      "out of range", name);
9100 	  *no_add = true;
9101 	}
9102       else
9103 	{
9104 	  tree attribs = DECL_ATTRIBUTES (*node);
9105 	  const char *names[] = { "io", "io_low", "address", NULL };
9106 	  for (const char **p = names; *p; p++)
9107 	    {
9108 	      tree other = lookup_attribute (*p, attribs);
9109 	      if (other && TREE_VALUE (other))
9110 		{
9111 		  warning_at (loc, OPT_Wattributes,
9112 			      "both %s and %qE attribute provide address",
9113 			      *p, name);
9114 		  *no_add = true;
9115 		  break;
9116 		}
9117 	    }
9118 	}
9119     }
9120 
9121   if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
9122     warning_at (loc, OPT_Wattributes, "%qE attribute on non-volatile variable",
9123 		name);
9124 
9125   return NULL_TREE;
9126 }
9127 
9128 rtx
avr_eval_addr_attrib(rtx x)9129 avr_eval_addr_attrib (rtx x)
9130 {
9131   if (GET_CODE (x) == SYMBOL_REF
9132       && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
9133     {
9134       tree decl = SYMBOL_REF_DECL (x);
9135       tree attr = NULL_TREE;
9136 
9137       if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
9138 	{
9139 	  attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
9140          if (!attr || !TREE_VALUE (attr))
9141            attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
9142 	  gcc_assert (attr);
9143 	}
9144       if (!attr || !TREE_VALUE (attr))
9145 	attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
9146       gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
9147       return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
9148     }
9149   return x;
9150 }
9151 
9152 
9153 /* AVR attributes.  */
9154 static const struct attribute_spec
9155 avr_attribute_table[] =
9156 {
9157   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
9158        affects_type_identity } */
9159   { "progmem",   0, 0, false, false, false,  avr_handle_progmem_attribute,
9160     false },
9161   { "signal",    0, 0, true,  false, false,  avr_handle_fndecl_attribute,
9162     false },
9163   { "interrupt", 0, 0, true,  false, false,  avr_handle_fndecl_attribute,
9164     false },
9165   { "naked",     0, 0, false, true,  true,   avr_handle_fntype_attribute,
9166     false },
9167   { "OS_task",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
9168     false },
9169   { "OS_main",   0, 0, false, true,  true,   avr_handle_fntype_attribute,
9170     false },
9171   { "io",        0, 1, true, false, false,  avr_handle_addr_attribute,
9172     false },
9173   { "io_low",    0, 1, true, false, false,  avr_handle_addr_attribute,
9174     false },
9175   { "address",   1, 1, true, false, false,  avr_handle_addr_attribute,
9176     false },
9177   { NULL,        0, 0, false, false, false, NULL, false }
9178 };
9179 
9180 
9181 /* Look if DECL shall be placed in program memory space by
9182    means of attribute `progmem' or some address-space qualifier.
9183    Return non-zero if DECL is data that must end up in Flash and
9184    zero if the data lives in RAM (.bss, .data, .rodata, ...).
9185 
9186    Return 2   if DECL is located in 24-bit flash address-space
9187    Return 1   if DECL is located in 16-bit flash address-space
9188    Return -1  if attribute `progmem' occurs in DECL or ATTRIBUTES
9189    Return 0   otherwise  */
9190 
9191 int
avr_progmem_p(tree decl,tree attributes)9192 avr_progmem_p (tree decl, tree attributes)
9193 {
9194   tree a;
9195 
9196   if (TREE_CODE (decl) != VAR_DECL)
9197     return 0;
9198 
9199   if (avr_decl_memx_p (decl))
9200     return 2;
9201 
9202   if (avr_decl_flash_p (decl))
9203     return 1;
9204 
9205   if (NULL_TREE
9206       != lookup_attribute ("progmem", attributes))
9207     return -1;
9208 
9209   a = decl;
9210 
9211   do
9212     a = TREE_TYPE(a);
9213   while (TREE_CODE (a) == ARRAY_TYPE);
9214 
9215   if (a == error_mark_node)
9216     return 0;
9217 
9218   if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
9219     return -1;
9220 
9221   return 0;
9222 }
9223 
9224 
9225 /* Scan type TYP for pointer references to address space ASn.
9226    Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
9227    the AS are also declared to be CONST.
9228    Otherwise, return the respective address space, i.e. a value != 0.  */
9229 
9230 static addr_space_t
avr_nonconst_pointer_addrspace(tree typ)9231 avr_nonconst_pointer_addrspace (tree typ)
9232 {
9233   while (ARRAY_TYPE == TREE_CODE (typ))
9234     typ = TREE_TYPE (typ);
9235 
9236   if (POINTER_TYPE_P (typ))
9237     {
9238       addr_space_t as;
9239       tree target = TREE_TYPE (typ);
9240 
9241       /* Pointer to function: Test the function's return type.  */
9242 
9243       if (FUNCTION_TYPE == TREE_CODE (target))
9244         return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
9245 
9246       /* "Ordinary" pointers... */
9247 
9248       while (TREE_CODE (target) == ARRAY_TYPE)
9249         target = TREE_TYPE (target);
9250 
9251       /* Pointers to non-generic address space must be const.
9252          Refuse address spaces outside the device's flash.  */
9253 
9254       as = TYPE_ADDR_SPACE (target);
9255 
9256       if (!ADDR_SPACE_GENERIC_P (as)
9257           && (!TYPE_READONLY (target)
9258               || avr_addrspace[as].segment >= avr_n_flash
9259 	      /* Also refuse __memx address space if we can't support it.  */
9260 	      || (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)))
9261         {
9262           return as;
9263         }
9264 
9265       /* Scan pointer's target type.  */
9266 
9267       return avr_nonconst_pointer_addrspace (target);
9268     }
9269 
9270   return ADDR_SPACE_GENERIC;
9271 }
9272 
9273 
9274 /* Sanity check NODE so that all pointers targeting non-generic address spaces
9275    go along with CONST qualifier.  Writing to these address spaces should
9276    be detected and complained about as early as possible.  */
9277 
9278 static bool
avr_pgm_check_var_decl(tree node)9279 avr_pgm_check_var_decl (tree node)
9280 {
9281   const char *reason = NULL;
9282 
9283   addr_space_t as = ADDR_SPACE_GENERIC;
9284 
9285   gcc_assert (as == 0);
9286 
9287   if (avr_log.progmem)
9288     avr_edump ("%?: %t\n", node);
9289 
9290   switch (TREE_CODE (node))
9291     {
9292     default:
9293       break;
9294 
9295     case VAR_DECL:
9296       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9297         reason = _("variable");
9298       break;
9299 
9300     case PARM_DECL:
9301       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9302         reason = _("function parameter");
9303       break;
9304 
9305     case FIELD_DECL:
9306       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
9307         reason = _("structure field");
9308       break;
9309 
9310     case FUNCTION_DECL:
9311       if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
9312           as)
9313         reason = _("return type of function");
9314       break;
9315 
9316     case POINTER_TYPE:
9317       if (as = avr_nonconst_pointer_addrspace (node), as)
9318         reason = _("pointer");
9319       break;
9320     }
9321 
9322   if (reason)
9323     {
9324       if (avr_addrspace[as].segment >= avr_n_flash)
9325         {
9326           if (TYPE_P (node))
9327             error ("%qT uses address space %qs beyond flash of %d KiB",
9328                    node, avr_addrspace[as].name, 64 * avr_n_flash);
9329           else
9330             error ("%s %q+D uses address space %qs beyond flash of %d KiB",
9331                    reason, node, avr_addrspace[as].name, 64 * avr_n_flash);
9332         }
9333       else
9334         {
9335           if (TYPE_P (node))
9336             error ("pointer targeting address space %qs must be const in %qT",
9337                    avr_addrspace[as].name, node);
9338           else
9339             error ("pointer targeting address space %qs must be const"
9340                    " in %s %q+D",
9341                    avr_addrspace[as].name, reason, node);
9342         }
9343     }
9344 
9345   return reason == NULL;
9346 }
9347 
9348 
9349 /* Add the section attribute if the variable is in progmem.  */
9350 
9351 static void
avr_insert_attributes(tree node,tree * attributes)9352 avr_insert_attributes (tree node, tree *attributes)
9353 {
9354   avr_pgm_check_var_decl (node);
9355 
9356   if (TREE_CODE (node) == VAR_DECL
9357       && (TREE_STATIC (node) || DECL_EXTERNAL (node))
9358       && avr_progmem_p (node, *attributes))
9359     {
9360       addr_space_t as;
9361       tree node0 = node;
9362 
9363       /* For C++, we have to peel arrays in order to get correct
9364          determination of readonlyness.  */
9365 
9366       do
9367         node0 = TREE_TYPE (node0);
9368       while (TREE_CODE (node0) == ARRAY_TYPE);
9369 
9370       if (error_mark_node == node0)
9371         return;
9372 
9373       as = TYPE_ADDR_SPACE (TREE_TYPE (node));
9374 
9375       if (avr_addrspace[as].segment >= avr_n_flash)
9376         {
9377           error ("variable %q+D located in address space %qs beyond flash "
9378                  "of %d KiB", node, avr_addrspace[as].name, 64 * avr_n_flash);
9379         }
9380       else if (!AVR_HAVE_LPM && avr_addrspace[as].pointer_size > 2)
9381 	{
9382           error ("variable %q+D located in address space %qs"
9383                  " which is not supported for architecture %qs",
9384                  node, avr_addrspace[as].name, avr_arch->name);
9385 	}
9386 
9387       if (!TYPE_READONLY (node0)
9388           && !TREE_READONLY (node))
9389         {
9390           const char *reason = "__attribute__((progmem))";
9391 
9392           if (!ADDR_SPACE_GENERIC_P (as))
9393             reason = avr_addrspace[as].name;
9394 
9395           if (avr_log.progmem)
9396             avr_edump ("\n%?: %t\n%t\n", node, node0);
9397 
9398           error ("variable %q+D must be const in order to be put into"
9399                  " read-only section by means of %qs", node, reason);
9400         }
9401     }
9402 }
9403 
9404 
9405 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'.  */
9406 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'.  */
9407 /* Track need of __do_clear_bss.  */
9408 
9409 void
avr_asm_output_aligned_decl_common(FILE * stream,tree decl,const char * name,unsigned HOST_WIDE_INT size,unsigned int align,bool local_p)9410 avr_asm_output_aligned_decl_common (FILE * stream,
9411                                     tree decl,
9412                                     const char *name,
9413                                     unsigned HOST_WIDE_INT size,
9414                                     unsigned int align, bool local_p)
9415 {
9416   rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9417   rtx symbol;
9418 
9419   if (mem != NULL_RTX && MEM_P (mem)
9420       && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9421       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9422     {
9423 
9424       if (!local_p)
9425 	{
9426 	  fprintf (stream, "\t.globl\t");
9427 	  assemble_name (stream, name);
9428 	  fprintf (stream, "\n");
9429 	}
9430       if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
9431 	{
9432 	  assemble_name (stream, name);
9433 	  fprintf (stream, " = %ld\n",
9434 		   (long) INTVAL (avr_eval_addr_attrib (symbol)));
9435 	}
9436       else if (local_p)
9437 	error_at (DECL_SOURCE_LOCATION (decl),
9438 		  "static IO declaration for %q+D needs an address", decl);
9439       return;
9440     }
9441 
9442   /* __gnu_lto_v1 etc. are just markers for the linker injected by toplev.c.
9443      There is no need to trigger __do_clear_bss code for them.  */
9444 
9445   if (!STR_PREFIX_P (name, "__gnu_lto"))
9446     avr_need_clear_bss_p = true;
9447 
9448   if (local_p)
9449     ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
9450   else
9451     ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
9452 }
9453 
9454 void
avr_asm_asm_output_aligned_bss(FILE * file,tree decl,const char * name,unsigned HOST_WIDE_INT size,int align,void (* default_func)(FILE *,tree,const char *,unsigned HOST_WIDE_INT,int))9455 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
9456 				unsigned HOST_WIDE_INT size, int align,
9457 				void (*default_func)
9458 				  (FILE *, tree, const char *,
9459 				   unsigned HOST_WIDE_INT, int))
9460 {
9461   rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
9462   rtx symbol;
9463 
9464   if (mem != NULL_RTX && MEM_P (mem)
9465       && GET_CODE ((symbol = XEXP (mem, 0))) == SYMBOL_REF
9466       && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
9467     {
9468       if (!(SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS))
9469 	error_at (DECL_SOURCE_LOCATION (decl),
9470 		  "IO definition for %q+D needs an address", decl);
9471       avr_asm_output_aligned_decl_common (file, decl, name, size, align, false);
9472     }
9473   else
9474     default_func (file, decl, name, size, align);
9475 }
9476 
9477 
9478 /* Unnamed section callback for data_section
9479    to track need of __do_copy_data.  */
9480 
9481 static void
avr_output_data_section_asm_op(const void * data)9482 avr_output_data_section_asm_op (const void *data)
9483 {
9484   avr_need_copy_data_p = true;
9485 
9486   /* Dispatch to default.  */
9487   output_section_asm_op (data);
9488 }
9489 
9490 
9491 /* Unnamed section callback for bss_section
9492    to track need of __do_clear_bss.  */
9493 
9494 static void
avr_output_bss_section_asm_op(const void * data)9495 avr_output_bss_section_asm_op (const void *data)
9496 {
9497   avr_need_clear_bss_p = true;
9498 
9499   /* Dispatch to default.  */
9500   output_section_asm_op (data);
9501 }
9502 
9503 
9504 /* Unnamed section callback for progmem*.data sections.  */
9505 
9506 static void
avr_output_progmem_section_asm_op(const void * data)9507 avr_output_progmem_section_asm_op (const void *data)
9508 {
9509   fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n",
9510            (const char*) data);
9511 }
9512 
9513 
9514 /* Implement `TARGET_ASM_INIT_SECTIONS'.  */
9515 
9516 static void
avr_asm_init_sections(void)9517 avr_asm_init_sections (void)
9518 {
9519   /* Override section callbacks to keep track of `avr_need_clear_bss_p'
9520      resp. `avr_need_copy_data_p'.  */
9521 
9522   readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
9523   data_section->unnamed.callback = avr_output_data_section_asm_op;
9524   bss_section->unnamed.callback = avr_output_bss_section_asm_op;
9525 }
9526 
9527 
9528 /* Implement `TARGET_ASM_NAMED_SECTION'.  */
9529 /* Track need of __do_clear_bss, __do_copy_data for named sections.  */
9530 
9531 static void
avr_asm_named_section(const char * name,unsigned int flags,tree decl)9532 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
9533 {
9534   if (flags & AVR_SECTION_PROGMEM)
9535     {
9536       addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
9537       const char *old_prefix = ".rodata";
9538       const char *new_prefix = avr_addrspace[as].section_name;
9539 
9540       if (STR_PREFIX_P (name, old_prefix))
9541         {
9542           const char *sname = ACONCAT ((new_prefix,
9543                                         name + strlen (old_prefix), NULL));
9544           default_elf_asm_named_section (sname, flags, decl);
9545           return;
9546         }
9547 
9548       default_elf_asm_named_section (new_prefix, flags, decl);
9549       return;
9550     }
9551 
9552   if (!avr_need_copy_data_p)
9553     avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
9554                             || STR_PREFIX_P (name, ".rodata")
9555                             || STR_PREFIX_P (name, ".gnu.linkonce.d"));
9556 
9557   if (!avr_need_clear_bss_p)
9558     avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
9559 
9560   default_elf_asm_named_section (name, flags, decl);
9561 }
9562 
9563 
9564 /* Implement `TARGET_SECTION_TYPE_FLAGS'.  */
9565 
9566 static unsigned int
avr_section_type_flags(tree decl,const char * name,int reloc)9567 avr_section_type_flags (tree decl, const char *name, int reloc)
9568 {
9569   unsigned int flags = default_section_type_flags (decl, name, reloc);
9570 
9571   if (STR_PREFIX_P (name, ".noinit"))
9572     {
9573       if (decl && TREE_CODE (decl) == VAR_DECL
9574 	  && DECL_INITIAL (decl) == NULL_TREE)
9575 	flags |= SECTION_BSS;  /* @nobits */
9576       else
9577 	warning (0, "only uninitialized variables can be placed in the "
9578 		 ".noinit section");
9579     }
9580 
9581   if (decl && DECL_P (decl)
9582       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9583     {
9584       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9585 
9586       /* Attribute progmem puts data in generic address space.
9587          Set section flags as if it was in __flash to get the right
9588          section prefix in the remainder.  */
9589 
9590       if (ADDR_SPACE_GENERIC_P (as))
9591         as = ADDR_SPACE_FLASH;
9592 
9593       flags |= as * SECTION_MACH_DEP;
9594       flags &= ~SECTION_WRITE;
9595       flags &= ~SECTION_BSS;
9596     }
9597 
9598   return flags;
9599 }
9600 
9601 
9602 /* Implement `TARGET_ENCODE_SECTION_INFO'.  */
9603 
9604 static void
avr_encode_section_info(tree decl,rtx rtl,int new_decl_p)9605 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
9606 {
9607   /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
9608      readily available, see PR34734.  So we postpone the warning
9609      about uninitialized data in program memory section until here.  */
9610 
9611   if (new_decl_p
9612       && decl && DECL_P (decl)
9613       && !DECL_EXTERNAL (decl)
9614       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9615     {
9616       if (!TREE_READONLY (decl))
9617         {
9618           // This might happen with C++ if stuff needs constructing.
9619           error ("variable %q+D with dynamic initialization put "
9620                  "into program memory area", decl);
9621         }
9622       else if (NULL_TREE == DECL_INITIAL (decl))
9623         {
9624           // Don't warn for (implicit) aliases like in PR80462.
9625           tree asmname = DECL_ASSEMBLER_NAME (decl);
9626           varpool_node *node = varpool_node::get_for_asmname (asmname);
9627           bool alias_p = node && node->alias;
9628 
9629           if (!alias_p)
9630             warning (OPT_Wuninitialized, "uninitialized variable %q+D put "
9631                      "into program memory area", decl);
9632         }
9633     }
9634 
9635   default_encode_section_info (decl, rtl, new_decl_p);
9636 
9637   if (decl && DECL_P (decl)
9638       && TREE_CODE (decl) != FUNCTION_DECL
9639       && MEM_P (rtl)
9640       && SYMBOL_REF == GET_CODE (XEXP (rtl, 0)))
9641    {
9642       rtx sym = XEXP (rtl, 0);
9643       tree type = TREE_TYPE (decl);
9644       tree attr = DECL_ATTRIBUTES (decl);
9645       if (type == error_mark_node)
9646 	return;
9647 
9648       addr_space_t as = TYPE_ADDR_SPACE (type);
9649 
9650       /* PSTR strings are in generic space but located in flash:
9651          patch address space.  */
9652 
9653       if (-1 == avr_progmem_p (decl, attr))
9654         as = ADDR_SPACE_FLASH;
9655 
9656       AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
9657 
9658       tree io_low_attr = lookup_attribute ("io_low", attr);
9659       tree io_attr = lookup_attribute ("io", attr);
9660       tree addr_attr;
9661       if (io_low_attr
9662 	  && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
9663 	addr_attr = io_attr;
9664       else if (io_attr
9665 	       && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
9666 	addr_attr = io_attr;
9667       else
9668 	addr_attr = lookup_attribute ("address", attr);
9669       if (io_low_attr
9670 	  || (io_attr && addr_attr
9671               && low_io_address_operand
9672                   (GEN_INT (TREE_INT_CST_LOW
9673                             (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
9674 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
9675       if (io_attr || io_low_attr)
9676 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
9677       /* If we have an (io) address attribute specification, but the variable
9678 	 is external, treat the address as only a tentative definition
9679 	 to be used to determine if an io port is in the lower range, but
9680 	 don't use the exact value for constant propagation.  */
9681       if (addr_attr && !DECL_EXTERNAL (decl))
9682 	SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
9683     }
9684 }
9685 
9686 
9687 /* Implement `TARGET_ASM_SELECT_SECTION' */
9688 
9689 static section *
avr_asm_select_section(tree decl,int reloc,unsigned HOST_WIDE_INT align)9690 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
9691 {
9692   section * sect = default_elf_select_section (decl, reloc, align);
9693 
9694   if (decl && DECL_P (decl)
9695       && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
9696     {
9697       addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
9698 
9699       /* __progmem__ goes in generic space but shall be allocated to
9700          .progmem.data  */
9701 
9702       if (ADDR_SPACE_GENERIC_P (as))
9703         as = ADDR_SPACE_FLASH;
9704 
9705       if (sect->common.flags & SECTION_NAMED)
9706         {
9707           const char * name = sect->named.name;
9708           const char * old_prefix = ".rodata";
9709           const char * new_prefix = avr_addrspace[as].section_name;
9710 
9711           if (STR_PREFIX_P (name, old_prefix))
9712             {
9713               const char *sname = ACONCAT ((new_prefix,
9714                                             name + strlen (old_prefix), NULL));
9715               return get_section (sname,
9716                                   sect->common.flags & ~SECTION_DECLARED,
9717                                   sect->named.decl);
9718             }
9719         }
9720 
9721       if (!progmem_section[as])
9722         {
9723           progmem_section[as]
9724             = get_unnamed_section (0, avr_output_progmem_section_asm_op,
9725                                    avr_addrspace[as].section_name);
9726         }
9727 
9728       return progmem_section[as];
9729     }
9730 
9731   return sect;
9732 }
9733 
9734 /* Implement `TARGET_ASM_FILE_START'.  */
9735 /* Outputs some text at the start of each assembler file.  */
9736 
9737 static void
avr_file_start(void)9738 avr_file_start (void)
9739 {
9740   int sfr_offset = avr_arch->sfr_offset;
9741 
9742   if (avr_arch->asm_only)
9743     error ("architecture %qs supported for assembler only", avr_mmcu);
9744 
9745   default_file_start ();
9746 
9747   /* Print I/O addresses of some SFRs used with IN and OUT.  */
9748 
9749   if (AVR_HAVE_SPH)
9750     fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
9751 
9752   fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
9753   fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
9754   if (AVR_HAVE_RAMPZ)
9755     fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
9756   if (AVR_HAVE_RAMPY)
9757     fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
9758   if (AVR_HAVE_RAMPX)
9759     fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
9760   if (AVR_HAVE_RAMPD)
9761     fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
9762   if (AVR_XMEGA || AVR_TINY)
9763     fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
9764   fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
9765   fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
9766 }
9767 
9768 
9769 /* Implement `TARGET_ASM_FILE_END'.  */
9770 /* Outputs to the stdio stream FILE some
9771    appropriate text to go at the end of an assembler file.  */
9772 
9773 static void
avr_file_end(void)9774 avr_file_end (void)
9775 {
9776   /* Output these only if there is anything in the
9777      .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
9778      input section(s) - some code size can be saved by not
9779      linking in the initialization code from libgcc if resp.
9780      sections are empty, see PR18145.  */
9781 
9782   if (avr_need_copy_data_p)
9783     fputs (".global __do_copy_data\n", asm_out_file);
9784 
9785   if (avr_need_clear_bss_p)
9786     fputs (".global __do_clear_bss\n", asm_out_file);
9787 }
9788 
9789 
9790 /* Worker function for `ADJUST_REG_ALLOC_ORDER'.  */
9791 /* Choose the order in which to allocate hard registers for
9792    pseudo-registers local to a basic block.
9793 
9794    Store the desired register order in the array `reg_alloc_order'.
9795    Element 0 should be the register to allocate first; element 1, the
9796    next register; and so on.  */
9797 
9798 void
avr_adjust_reg_alloc_order(void)9799 avr_adjust_reg_alloc_order (void)
9800 {
9801   unsigned int i;
9802   static const int order_0[] =
9803     {
9804       24, 25,
9805       18, 19, 20, 21, 22, 23,
9806       30, 31,
9807       26, 27, 28, 29,
9808       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9809       0, 1,
9810       32, 33, 34, 35
9811   };
9812   static const int tiny_order_0[] = {
9813     20, 21,
9814     22, 23,
9815     24, 25,
9816     30, 31,
9817     26, 27,
9818     28, 29,
9819     19, 18,
9820     16, 17,
9821     32, 33, 34, 35,
9822     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9823   };
9824   static const int order_1[] =
9825     {
9826       18, 19, 20, 21, 22, 23, 24, 25,
9827       30, 31,
9828       26, 27, 28, 29,
9829       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9830       0, 1,
9831       32, 33, 34, 35
9832   };
9833   static const int tiny_order_1[] = {
9834     22, 23,
9835     24, 25,
9836     30, 31,
9837     26, 27,
9838     28, 29,
9839     21, 20, 19, 18,
9840     16, 17,
9841     32, 33, 34, 35,
9842     15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
9843   };
9844   static const int order_2[] =
9845     {
9846       25, 24, 23, 22, 21, 20, 19, 18,
9847       30, 31,
9848       26, 27, 28, 29,
9849       17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
9850       1, 0,
9851       32, 33, 34, 35
9852   };
9853 
9854   /* Select specific register allocation order.
9855      Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
9856      so different allocation order should be used.  */
9857 
9858   const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
9859                       : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
9860                       : (AVR_TINY ? tiny_order_0 : order_0));
9861 
9862   for (i = 0; i < ARRAY_SIZE (order_0); ++i)
9863       reg_alloc_order[i] = order[i];
9864 }
9865 
9866 
9867 /* Implement `TARGET_REGISTER_MOVE_COST' */
9868 
9869 static int
avr_register_move_cost(machine_mode mode ATTRIBUTE_UNUSED,reg_class_t from,reg_class_t to)9870 avr_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
9871                         reg_class_t from, reg_class_t to)
9872 {
9873   return (from == STACK_REG ? 6
9874           : to == STACK_REG ? 12
9875           : 2);
9876 }
9877 
9878 
9879 /* Implement `TARGET_MEMORY_MOVE_COST' */
9880 
9881 static int
avr_memory_move_cost(machine_mode mode,reg_class_t rclass ATTRIBUTE_UNUSED,bool in ATTRIBUTE_UNUSED)9882 avr_memory_move_cost (machine_mode mode,
9883                       reg_class_t rclass ATTRIBUTE_UNUSED,
9884                       bool in ATTRIBUTE_UNUSED)
9885 {
9886   return (mode == QImode ? 2
9887           : mode == HImode ? 4
9888           : mode == SImode ? 8
9889           : mode == SFmode ? 8
9890           : 16);
9891 }
9892 
9893 
9894 /* Cost for mul highpart.  X is a LSHIFTRT, i.e. the outer TRUNCATE is
9895    already stripped off.  */
9896 
9897 static int
avr_mul_highpart_cost(rtx x,int)9898 avr_mul_highpart_cost (rtx x, int)
9899 {
9900   if (AVR_HAVE_MUL
9901       && LSHIFTRT == GET_CODE (x)
9902       && MULT == GET_CODE (XEXP (x, 0))
9903       && CONST_INT_P (XEXP (x, 1)))
9904     {
9905       // This is the wider mode.
9906       machine_mode mode = GET_MODE (x);
9907 
9908       // The middle-end might still have PR81444, i.e. it is calling the cost
9909       // functions with strange modes.  Fix this now by also considering
9910       // PSImode (should actually be SImode instead).
9911       if (HImode == mode || PSImode == mode || SImode == mode)
9912         {
9913           return COSTS_N_INSNS (2);
9914         }
9915     }
9916 
9917   return 10000;
9918 }
9919 
9920 
9921 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
9922    cost of an RTX operand given its context.  X is the rtx of the
9923    operand, MODE is its mode, and OUTER is the rtx_code of this
9924    operand's parent operator.  */
9925 
9926 static int
avr_operand_rtx_cost(rtx x,machine_mode mode,enum rtx_code outer,int opno,bool speed)9927 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
9928 		      int opno, bool speed)
9929 {
9930   enum rtx_code code = GET_CODE (x);
9931   int total;
9932 
9933   switch (code)
9934     {
9935     case REG:
9936     case SUBREG:
9937       return 0;
9938 
9939     case CONST_INT:
9940     case CONST_FIXED:
9941     case CONST_DOUBLE:
9942       return COSTS_N_INSNS (GET_MODE_SIZE (mode));
9943 
9944     default:
9945       break;
9946     }
9947 
9948   total = 0;
9949   avr_rtx_costs (x, mode, outer, opno, &total, speed);
9950   return total;
9951 }
9952 
9953 /* Worker function for AVR backend's rtx_cost function.
9954    X is rtx expression whose cost is to be calculated.
9955    Return true if the complete cost has been computed.
9956    Return false if subexpressions should be scanned.
9957    In either case, *TOTAL contains the cost result.  */
9958 
9959 static bool
avr_rtx_costs_1(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed)9960 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
9961                  int opno ATTRIBUTE_UNUSED, int *total, bool speed)
9962 {
9963   enum rtx_code code = GET_CODE (x);
9964   HOST_WIDE_INT val;
9965 
9966   switch (code)
9967     {
9968     case CONST_INT:
9969     case CONST_FIXED:
9970     case CONST_DOUBLE:
9971     case SYMBOL_REF:
9972     case CONST:
9973     case LABEL_REF:
9974       /* Immediate constants are as cheap as registers.  */
9975       *total = 0;
9976       return true;
9977 
9978     case MEM:
9979       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
9980       return true;
9981 
9982     case NEG:
9983       switch (mode)
9984 	{
9985 	case QImode:
9986 	case SFmode:
9987 	  *total = COSTS_N_INSNS (1);
9988 	  break;
9989 
9990         case HImode:
9991         case PSImode:
9992         case SImode:
9993           *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
9994           break;
9995 
9996 	default:
9997 	  return false;
9998 	}
9999       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10000       return true;
10001 
10002     case ABS:
10003       switch (mode)
10004 	{
10005 	case QImode:
10006 	case SFmode:
10007 	  *total = COSTS_N_INSNS (1);
10008 	  break;
10009 
10010 	default:
10011 	  return false;
10012 	}
10013       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10014       return true;
10015 
10016     case NOT:
10017       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10018       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10019       return true;
10020 
10021     case ZERO_EXTEND:
10022       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
10023 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
10024       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10025 				      code, 0, speed);
10026       return true;
10027 
10028     case SIGN_EXTEND:
10029       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
10030 			      - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
10031       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10032 				      code, 0, speed);
10033       return true;
10034 
10035     case PLUS:
10036       switch (mode)
10037 	{
10038 	case QImode:
10039           if (AVR_HAVE_MUL
10040               && MULT == GET_CODE (XEXP (x, 0))
10041               && register_operand (XEXP (x, 1), QImode))
10042             {
10043               /* multiply-add */
10044               *total = COSTS_N_INSNS (speed ? 4 : 3);
10045               /* multiply-add with constant: will be split and load constant. */
10046               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10047                 *total = COSTS_N_INSNS (1) + *total;
10048               return true;
10049             }
10050 	  *total = COSTS_N_INSNS (1);
10051 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10052 	    *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10053 	  break;
10054 
10055 	case HImode:
10056           if (AVR_HAVE_MUL
10057               && (MULT == GET_CODE (XEXP (x, 0))
10058                   || ASHIFT == GET_CODE (XEXP (x, 0)))
10059               && register_operand (XEXP (x, 1), HImode)
10060               && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
10061                   || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
10062             {
10063               /* multiply-add */
10064               *total = COSTS_N_INSNS (speed ? 5 : 4);
10065               /* multiply-add with constant: will be split and load constant. */
10066               if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
10067                 *total = COSTS_N_INSNS (1) + *total;
10068               return true;
10069             }
10070 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10071 	    {
10072 	      *total = COSTS_N_INSNS (2);
10073 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10074 					      speed);
10075 	    }
10076 	  else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10077 	    *total = COSTS_N_INSNS (1);
10078 	  else
10079 	    *total = COSTS_N_INSNS (2);
10080 	  break;
10081 
10082         case PSImode:
10083           if (!CONST_INT_P (XEXP (x, 1)))
10084             {
10085               *total = COSTS_N_INSNS (3);
10086               *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10087                                               speed);
10088             }
10089           else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10090             *total = COSTS_N_INSNS (2);
10091           else
10092             *total = COSTS_N_INSNS (3);
10093           break;
10094 
10095 	case SImode:
10096 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10097 	    {
10098 	      *total = COSTS_N_INSNS (4);
10099 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10100 					      speed);
10101 	    }
10102 	  else if (INTVAL (XEXP (x, 1)) >= -63 && INTVAL (XEXP (x, 1)) <= 63)
10103 	    *total = COSTS_N_INSNS (1);
10104 	  else
10105 	    *total = COSTS_N_INSNS (4);
10106 	  break;
10107 
10108 	default:
10109 	  return false;
10110 	}
10111       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10112       return true;
10113 
10114     case MINUS:
10115       if (AVR_HAVE_MUL
10116           && QImode == mode
10117           && register_operand (XEXP (x, 0), QImode)
10118           && MULT == GET_CODE (XEXP (x, 1)))
10119         {
10120           /* multiply-sub */
10121           *total = COSTS_N_INSNS (speed ? 4 : 3);
10122           /* multiply-sub with constant: will be split and load constant. */
10123           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10124             *total = COSTS_N_INSNS (1) + *total;
10125           return true;
10126         }
10127       if (AVR_HAVE_MUL
10128           && HImode == mode
10129           && register_operand (XEXP (x, 0), HImode)
10130           && (MULT == GET_CODE (XEXP (x, 1))
10131               || ASHIFT == GET_CODE (XEXP (x, 1)))
10132           && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
10133               || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
10134         {
10135           /* multiply-sub */
10136           *total = COSTS_N_INSNS (speed ? 5 : 4);
10137           /* multiply-sub with constant: will be split and load constant. */
10138           if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
10139             *total = COSTS_N_INSNS (1) + *total;
10140           return true;
10141         }
10142       /* FALLTHRU */
10143     case AND:
10144     case IOR:
10145       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10146       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10147       if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10148 	*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10149       return true;
10150 
10151     case XOR:
10152       *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
10153       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10154       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10155       return true;
10156 
10157     case MULT:
10158       switch (mode)
10159 	{
10160 	case QImode:
10161 	  if (AVR_HAVE_MUL)
10162 	    *total = COSTS_N_INSNS (!speed ? 3 : 4);
10163 	  else if (!speed)
10164 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10165 	  else
10166 	    return false;
10167 	  break;
10168 
10169 	case HImode:
10170 	  if (AVR_HAVE_MUL)
10171             {
10172               rtx op0 = XEXP (x, 0);
10173               rtx op1 = XEXP (x, 1);
10174               enum rtx_code code0 = GET_CODE (op0);
10175               enum rtx_code code1 = GET_CODE (op1);
10176               bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
10177               bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
10178 
10179               if (ex0
10180                   && (u8_operand (op1, HImode)
10181                       || s8_operand (op1, HImode)))
10182                 {
10183                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
10184                   return true;
10185                 }
10186               if (ex0
10187                   && register_operand (op1, HImode))
10188                 {
10189                   *total = COSTS_N_INSNS (!speed ? 5 : 8);
10190                   return true;
10191                 }
10192               else if (ex0 || ex1)
10193                 {
10194                   *total = COSTS_N_INSNS (!speed ? 3 : 5);
10195                   return true;
10196                 }
10197               else if (register_operand (op0, HImode)
10198                        && (u8_operand (op1, HImode)
10199                            || s8_operand (op1, HImode)))
10200                 {
10201                   *total = COSTS_N_INSNS (!speed ? 6 : 9);
10202                   return true;
10203                 }
10204               else
10205                 *total = COSTS_N_INSNS (!speed ? 7 : 10);
10206             }
10207 	  else if (!speed)
10208 	    *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10209 	  else
10210 	    return false;
10211 	  break;
10212 
10213         case PSImode:
10214           if (!speed)
10215             *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10216           else
10217             *total = 10;
10218           break;
10219 
10220 	case SImode:
10221 	case DImode:
10222 	  if (AVR_HAVE_MUL)
10223             {
10224               if (!speed)
10225                 {
10226                   /* Add some additional costs besides CALL like moves etc.  */
10227 
10228                   *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10229                 }
10230               else
10231                 {
10232                   /* Just a rough estimate.  Even with -O2 we don't want bulky
10233                      code expanded inline.  */
10234 
10235                   *total = COSTS_N_INSNS (25);
10236                 }
10237             }
10238           else
10239             {
10240               if (speed)
10241                 *total = COSTS_N_INSNS (300);
10242               else
10243                 /* Add some additional costs besides CALL like moves etc.  */
10244                 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
10245             }
10246 
10247 	   if (mode == DImode)
10248 	     *total *= 2;
10249 
10250 	   return true;
10251 
10252 	default:
10253 	  return false;
10254 	}
10255       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10256       *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
10257       return true;
10258 
10259     case DIV:
10260     case MOD:
10261     case UDIV:
10262     case UMOD:
10263       if (!speed)
10264         *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
10265       else
10266         *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
10267       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10268       /* For div/mod with const-int divisor we have at least the cost of
10269          loading the divisor. */
10270       if (CONST_INT_P (XEXP (x, 1)))
10271         *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
10272       /* Add some overall penaly for clobbering and moving around registers */
10273       *total += COSTS_N_INSNS (2);
10274       return true;
10275 
10276     case ROTATE:
10277       switch (mode)
10278 	{
10279 	case QImode:
10280 	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
10281 	    *total = COSTS_N_INSNS (1);
10282 
10283 	  break;
10284 
10285 	case HImode:
10286 	  if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
10287 	    *total = COSTS_N_INSNS (3);
10288 
10289 	  break;
10290 
10291 	case SImode:
10292 	  if (CONST_INT_P (XEXP (x, 1)))
10293 	    switch (INTVAL (XEXP (x, 1)))
10294 	      {
10295 	      case 8:
10296 	      case 24:
10297 		*total = COSTS_N_INSNS (5);
10298 		break;
10299 	      case 16:
10300 		*total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
10301 		break;
10302 	      }
10303 	  break;
10304 
10305 	default:
10306 	  return false;
10307 	}
10308       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10309       return true;
10310 
10311     case ASHIFT:
10312       switch (mode)
10313 	{
10314 	case QImode:
10315 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10316 	    {
10317 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
10318 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10319 					      speed);
10320 	    }
10321 	  else
10322 	    {
10323 	      val = INTVAL (XEXP (x, 1));
10324 	      if (val == 7)
10325 		*total = COSTS_N_INSNS (3);
10326 	      else if (val >= 0 && val <= 7)
10327 		*total = COSTS_N_INSNS (val);
10328 	      else
10329 		*total = COSTS_N_INSNS (1);
10330 	    }
10331 	  break;
10332 
10333 	case HImode:
10334           if (AVR_HAVE_MUL)
10335             {
10336               if (const_2_to_7_operand (XEXP (x, 1), HImode)
10337                   && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
10338                       || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
10339                 {
10340                   *total = COSTS_N_INSNS (!speed ? 4 : 6);
10341                   return true;
10342                 }
10343             }
10344 
10345           if (const1_rtx == (XEXP (x, 1))
10346               && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
10347             {
10348               *total = COSTS_N_INSNS (2);
10349               return true;
10350             }
10351 
10352 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10353 	    {
10354 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
10355 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10356 					      speed);
10357 	    }
10358 	  else
10359 	    switch (INTVAL (XEXP (x, 1)))
10360 	      {
10361 	      case 0:
10362 		*total = 0;
10363 		break;
10364 	      case 1:
10365 	      case 8:
10366 		*total = COSTS_N_INSNS (2);
10367 		break;
10368 	      case 9:
10369 		*total = COSTS_N_INSNS (3);
10370 		break;
10371 	      case 2:
10372 	      case 3:
10373 	      case 10:
10374 	      case 15:
10375 		*total = COSTS_N_INSNS (4);
10376 		break;
10377 	      case 7:
10378 	      case 11:
10379 	      case 12:
10380 		*total = COSTS_N_INSNS (5);
10381 		break;
10382 	      case 4:
10383 		*total = COSTS_N_INSNS (!speed ? 5 : 8);
10384 		break;
10385 	      case 6:
10386 		*total = COSTS_N_INSNS (!speed ? 5 : 9);
10387 		break;
10388 	      case 5:
10389 		*total = COSTS_N_INSNS (!speed ? 5 : 10);
10390 		break;
10391 	      default:
10392 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
10393 	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10394 						speed);
10395 	      }
10396 	  break;
10397 
10398         case PSImode:
10399           if (!CONST_INT_P (XEXP (x, 1)))
10400             {
10401               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10402             }
10403           else
10404             switch (INTVAL (XEXP (x, 1)))
10405               {
10406               case 0:
10407                 *total = 0;
10408                 break;
10409               case 1:
10410               case 8:
10411               case 16:
10412                 *total = COSTS_N_INSNS (3);
10413                 break;
10414               case 23:
10415                 *total = COSTS_N_INSNS (5);
10416                 break;
10417               default:
10418                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10419                 break;
10420               }
10421           break;
10422 
10423 	case SImode:
10424 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10425 	    {
10426 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
10427 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10428 					      speed);
10429 	    }
10430 	  else
10431 	    switch (INTVAL (XEXP (x, 1)))
10432 	      {
10433 	      case 0:
10434 		*total = 0;
10435 		break;
10436 	      case 24:
10437 		*total = COSTS_N_INSNS (3);
10438 		break;
10439 	      case 1:
10440 	      case 8:
10441 	      case 16:
10442 		*total = COSTS_N_INSNS (4);
10443 		break;
10444 	      case 31:
10445 		*total = COSTS_N_INSNS (6);
10446 		break;
10447 	      case 2:
10448 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
10449 		break;
10450 	      default:
10451 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
10452 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10453 						speed);
10454 	      }
10455 	  break;
10456 
10457 	default:
10458 	  return false;
10459 	}
10460       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10461       return true;
10462 
10463     case ASHIFTRT:
10464       switch (mode)
10465 	{
10466 	case QImode:
10467 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10468 	    {
10469 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
10470 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10471 					      speed);
10472 	    }
10473 	  else
10474 	    {
10475 	      val = INTVAL (XEXP (x, 1));
10476 	      if (val == 6)
10477 		*total = COSTS_N_INSNS (4);
10478 	      else if (val == 7)
10479 		*total = COSTS_N_INSNS (2);
10480 	      else if (val >= 0 && val <= 7)
10481 		*total = COSTS_N_INSNS (val);
10482 	      else
10483 		*total = COSTS_N_INSNS (1);
10484 	    }
10485 	  break;
10486 
10487 	case HImode:
10488 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10489 	    {
10490 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
10491 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10492 					      speed);
10493 	    }
10494 	  else
10495 	    switch (INTVAL (XEXP (x, 1)))
10496 	      {
10497 	      case 0:
10498 		*total = 0;
10499 		break;
10500 	      case 1:
10501 		*total = COSTS_N_INSNS (2);
10502 		break;
10503 	      case 15:
10504 		*total = COSTS_N_INSNS (3);
10505 		break;
10506 	      case 2:
10507 	      case 7:
10508               case 8:
10509               case 9:
10510 		*total = COSTS_N_INSNS (4);
10511 		break;
10512               case 10:
10513 	      case 14:
10514 		*total = COSTS_N_INSNS (5);
10515 		break;
10516               case 11:
10517                 *total = COSTS_N_INSNS (!speed ? 5 : 6);
10518 		break;
10519               case 12:
10520                 *total = COSTS_N_INSNS (!speed ? 5 : 7);
10521 		break;
10522               case 6:
10523 	      case 13:
10524                 *total = COSTS_N_INSNS (!speed ? 5 : 8);
10525 		break;
10526 	      default:
10527 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
10528 	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10529 						speed);
10530 	      }
10531 	  break;
10532 
10533         case PSImode:
10534           if (!CONST_INT_P (XEXP (x, 1)))
10535             {
10536               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10537             }
10538           else
10539             switch (INTVAL (XEXP (x, 1)))
10540               {
10541               case 0:
10542                 *total = 0;
10543                 break;
10544               case 1:
10545                 *total = COSTS_N_INSNS (3);
10546                 break;
10547               case 16:
10548               case 8:
10549                 *total = COSTS_N_INSNS (5);
10550                 break;
10551               case 23:
10552                 *total = COSTS_N_INSNS (4);
10553                 break;
10554               default:
10555                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10556                 break;
10557               }
10558           break;
10559 
10560 	case SImode:
10561 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10562 	    {
10563 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
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 		*total = COSTS_N_INSNS (4);
10575 		break;
10576 	      case 8:
10577 	      case 16:
10578 	      case 24:
10579 		*total = COSTS_N_INSNS (6);
10580 		break;
10581 	      case 2:
10582 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
10583 		break;
10584 	      case 31:
10585 		*total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
10586 		break;
10587 	      default:
10588 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
10589 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10590 						speed);
10591 	      }
10592 	  break;
10593 
10594 	default:
10595 	  return false;
10596 	}
10597       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10598       return true;
10599 
10600     case LSHIFTRT:
10601       if (outer_code == TRUNCATE)
10602         {
10603           *total = avr_mul_highpart_cost (x, speed);
10604           return true;
10605         }
10606 
10607       switch (mode)
10608 	{
10609 	case QImode:
10610 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10611 	    {
10612 	      *total = COSTS_N_INSNS (!speed ? 4 : 17);
10613 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10614 					      speed);
10615 	    }
10616 	  else
10617 	    {
10618 	      val = INTVAL (XEXP (x, 1));
10619 	      if (val == 7)
10620 		*total = COSTS_N_INSNS (3);
10621 	      else if (val >= 0 && val <= 7)
10622 		*total = COSTS_N_INSNS (val);
10623 	      else
10624 		*total = COSTS_N_INSNS (1);
10625 	    }
10626 	  break;
10627 
10628 	case HImode:
10629 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10630 	    {
10631 	      *total = COSTS_N_INSNS (!speed ? 5 : 41);
10632 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10633 					      speed);
10634 	    }
10635 	  else
10636 	    switch (INTVAL (XEXP (x, 1)))
10637 	      {
10638 	      case 0:
10639 		*total = 0;
10640 		break;
10641 	      case 1:
10642 	      case 8:
10643 		*total = COSTS_N_INSNS (2);
10644 		break;
10645 	      case 9:
10646 		*total = COSTS_N_INSNS (3);
10647 		break;
10648 	      case 2:
10649 	      case 10:
10650 	      case 15:
10651 		*total = COSTS_N_INSNS (4);
10652 		break;
10653 	      case 7:
10654               case 11:
10655 		*total = COSTS_N_INSNS (5);
10656 		break;
10657 	      case 3:
10658 	      case 12:
10659 	      case 13:
10660 	      case 14:
10661 		*total = COSTS_N_INSNS (!speed ? 5 : 6);
10662 		break;
10663 	      case 4:
10664 		*total = COSTS_N_INSNS (!speed ? 5 : 7);
10665 		break;
10666 	      case 5:
10667 	      case 6:
10668 		*total = COSTS_N_INSNS (!speed ? 5 : 9);
10669 		break;
10670 	      default:
10671 	        *total = COSTS_N_INSNS (!speed ? 5 : 41);
10672 	        *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10673 						speed);
10674 	      }
10675 	  break;
10676 
10677         case PSImode:
10678           if (!CONST_INT_P (XEXP (x, 1)))
10679             {
10680               *total = COSTS_N_INSNS (!speed ? 6 : 73);
10681             }
10682           else
10683             switch (INTVAL (XEXP (x, 1)))
10684               {
10685               case 0:
10686                 *total = 0;
10687                 break;
10688               case 1:
10689               case 8:
10690               case 16:
10691                 *total = COSTS_N_INSNS (3);
10692                 break;
10693               case 23:
10694                 *total = COSTS_N_INSNS (5);
10695                 break;
10696               default:
10697                 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
10698                 break;
10699               }
10700           break;
10701 
10702 	case SImode:
10703 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10704 	    {
10705 	      *total = COSTS_N_INSNS (!speed ? 7 : 113);
10706 	      *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10707 					      speed);
10708 	    }
10709 	  else
10710 	    switch (INTVAL (XEXP (x, 1)))
10711 	      {
10712 	      case 0:
10713 		*total = 0;
10714 		break;
10715 	      case 1:
10716 		*total = COSTS_N_INSNS (4);
10717 		break;
10718 	      case 2:
10719 		*total = COSTS_N_INSNS (!speed ? 7 : 8);
10720 		break;
10721 	      case 8:
10722 	      case 16:
10723 	      case 24:
10724 		*total = COSTS_N_INSNS (4);
10725 		break;
10726 	      case 31:
10727 		*total = COSTS_N_INSNS (6);
10728 		break;
10729 	      default:
10730 		*total = COSTS_N_INSNS (!speed ? 7 : 113);
10731 		*total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
10732 						speed);
10733 	      }
10734 	  break;
10735 
10736 	default:
10737 	  return false;
10738 	}
10739       *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
10740       return true;
10741 
10742     case COMPARE:
10743       switch (GET_MODE (XEXP (x, 0)))
10744 	{
10745 	case QImode:
10746 	  *total = COSTS_N_INSNS (1);
10747 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10748 	    *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
10749 					    1, speed);
10750 	  break;
10751 
10752         case HImode:
10753 	  *total = COSTS_N_INSNS (2);
10754 	  if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10755             *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
10756 					    1, speed);
10757 	  else if (INTVAL (XEXP (x, 1)) != 0)
10758 	    *total += COSTS_N_INSNS (1);
10759           break;
10760 
10761         case PSImode:
10762           *total = COSTS_N_INSNS (3);
10763           if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
10764             *total += COSTS_N_INSNS (2);
10765           break;
10766 
10767         case SImode:
10768           *total = COSTS_N_INSNS (4);
10769           if (GET_CODE (XEXP (x, 1)) != CONST_INT)
10770             *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
10771 					    1, speed);
10772 	  else if (INTVAL (XEXP (x, 1)) != 0)
10773 	    *total += COSTS_N_INSNS (3);
10774           break;
10775 
10776 	default:
10777 	  return false;
10778 	}
10779       *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
10780 				      code, 0, speed);
10781       return true;
10782 
10783     case TRUNCATE:
10784       if (LSHIFTRT == GET_CODE (XEXP (x, 0)))
10785         {
10786           *total = avr_mul_highpart_cost (XEXP (x, 0), speed);
10787           return true;
10788         }
10789       break;
10790 
10791     default:
10792       break;
10793     }
10794   return false;
10795 }
10796 
10797 
10798 /* Implement `TARGET_RTX_COSTS'.  */
10799 
10800 static bool
avr_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno,int * total,bool speed)10801 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
10802 	       int opno, int *total, bool speed)
10803 {
10804   bool done = avr_rtx_costs_1 (x, mode, outer_code,
10805                                opno, total, speed);
10806 
10807   if (avr_log.rtx_costs)
10808     {
10809       avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
10810                  done, speed ? "speed" : "size", *total, outer_code, x);
10811     }
10812 
10813   return done;
10814 }
10815 
10816 
10817 /* Implement `TARGET_ADDRESS_COST'.  */
10818 
10819 static int
avr_address_cost(rtx x,machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,bool speed ATTRIBUTE_UNUSED)10820 avr_address_cost (rtx x, machine_mode mode ATTRIBUTE_UNUSED,
10821                   addr_space_t as ATTRIBUTE_UNUSED,
10822                   bool speed ATTRIBUTE_UNUSED)
10823 {
10824   int cost = 4;
10825 
10826   if (GET_CODE (x) == PLUS
10827       && CONST_INT_P (XEXP (x, 1))
10828       && (REG_P (XEXP (x, 0))
10829           || GET_CODE (XEXP (x, 0)) == SUBREG))
10830     {
10831       if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
10832         cost = 18;
10833     }
10834   else if (CONSTANT_ADDRESS_P (x))
10835     {
10836       if (io_address_operand (x, QImode))
10837         cost = 2;
10838     }
10839 
10840   if (avr_log.address_cost)
10841     avr_edump ("\n%?: %d = %r\n", cost, x);
10842 
10843   return cost;
10844 }
10845 
10846 /* Test for extra memory constraint 'Q'.
10847    It's a memory address based on Y or Z pointer with valid displacement.  */
10848 
10849 int
extra_constraint_Q(rtx x)10850 extra_constraint_Q (rtx x)
10851 {
10852   int ok = 0;
10853 
10854   if (GET_CODE (XEXP (x,0)) == PLUS
10855       && REG_P (XEXP (XEXP (x,0), 0))
10856       && GET_CODE (XEXP (XEXP (x,0), 1)) == CONST_INT
10857       && (INTVAL (XEXP (XEXP (x,0), 1))
10858 	  <= MAX_LD_OFFSET (GET_MODE (x))))
10859     {
10860       rtx xx = XEXP (XEXP (x,0), 0);
10861       int regno = REGNO (xx);
10862 
10863       ok = (/* allocate pseudos */
10864             regno >= FIRST_PSEUDO_REGISTER
10865             /* strictly check */
10866             || regno == REG_Z || regno == REG_Y
10867             /* XXX frame & arg pointer checks */
10868             || xx == frame_pointer_rtx
10869             || xx == arg_pointer_rtx);
10870 
10871       if (avr_log.constraints)
10872         avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
10873                    ok, reload_completed, reload_in_progress, x);
10874     }
10875 
10876   return ok;
10877 }
10878 
10879 /* Convert condition code CONDITION to the valid AVR condition code.  */
10880 
10881 RTX_CODE
avr_normalize_condition(RTX_CODE condition)10882 avr_normalize_condition (RTX_CODE condition)
10883 {
10884   switch (condition)
10885     {
10886     case GT:
10887       return GE;
10888     case GTU:
10889       return GEU;
10890     case LE:
10891       return LT;
10892     case LEU:
10893       return LTU;
10894     default:
10895       gcc_unreachable ();
10896     }
10897 }
10898 
10899 /* Helper function for `avr_reorg'.  */
10900 
10901 static rtx
avr_compare_pattern(rtx_insn * insn)10902 avr_compare_pattern (rtx_insn *insn)
10903 {
10904   rtx pattern = single_set (insn);
10905 
10906   if (pattern
10907       && NONJUMP_INSN_P (insn)
10908       && SET_DEST (pattern) == cc0_rtx
10909       && GET_CODE (SET_SRC (pattern)) == COMPARE)
10910     {
10911       machine_mode mode0 = GET_MODE (XEXP (SET_SRC (pattern), 0));
10912       machine_mode mode1 = GET_MODE (XEXP (SET_SRC (pattern), 1));
10913 
10914       /* The 64-bit comparisons have fixed operands ACC_A and ACC_B.
10915          They must not be swapped, thus skip them.  */
10916 
10917       if ((mode0 == VOIDmode || GET_MODE_SIZE (mode0) <= 4)
10918           && (mode1 == VOIDmode || GET_MODE_SIZE (mode1) <= 4))
10919         return pattern;
10920     }
10921 
10922   return NULL_RTX;
10923 }
10924 
10925 /* Helper function for `avr_reorg'.  */
10926 
10927 /* Expansion of switch/case decision trees leads to code like
10928 
10929        cc0 = compare (Reg, Num)
10930        if (cc0 == 0)
10931          goto L1
10932 
10933        cc0 = compare (Reg, Num)
10934        if (cc0 > 0)
10935          goto L2
10936 
10937    The second comparison is superfluous and can be deleted.
10938    The second jump condition can be transformed from a
10939    "difficult" one to a "simple" one because "cc0 > 0" and
10940    "cc0 >= 0" will have the same effect here.
10941 
10942    This function relies on the way switch/case is being expaned
10943    as binary decision tree.  For example code see PR 49903.
10944 
10945    Return TRUE if optimization performed.
10946    Return FALSE if nothing changed.
10947 
10948    INSN1 is a comparison, i.e. avr_compare_pattern != 0.
10949 
10950    We don't want to do this in text peephole because it is
10951    tedious to work out jump offsets there and the second comparison
10952    might have been transormed by `avr_reorg'.
10953 
10954    RTL peephole won't do because peephole2 does not scan across
10955    basic blocks.  */
10956 
10957 static bool
avr_reorg_remove_redundant_compare(rtx_insn * insn1)10958 avr_reorg_remove_redundant_compare (rtx_insn *insn1)
10959 {
10960   rtx comp1, ifelse1, xcond1;
10961   rtx_insn *branch1;
10962   rtx comp2, ifelse2, xcond2;
10963   rtx_insn *branch2, *insn2;
10964   enum rtx_code code;
10965   rtx_insn *jump;
10966   rtx target, cond;
10967 
10968   /* Look out for:  compare1 - branch1 - compare2 - branch2  */
10969 
10970   branch1 = next_nonnote_nondebug_insn (insn1);
10971   if (!branch1 || !JUMP_P (branch1))
10972     return false;
10973 
10974   insn2 = next_nonnote_nondebug_insn (branch1);
10975   if (!insn2 || !avr_compare_pattern (insn2))
10976     return false;
10977 
10978   branch2 = next_nonnote_nondebug_insn (insn2);
10979   if (!branch2 || !JUMP_P (branch2))
10980     return false;
10981 
10982   comp1 = avr_compare_pattern (insn1);
10983   comp2 = avr_compare_pattern (insn2);
10984   xcond1 = single_set (branch1);
10985   xcond2 = single_set (branch2);
10986 
10987   if (!comp1 || !comp2
10988       || !rtx_equal_p (comp1, comp2)
10989       || !xcond1 || SET_DEST (xcond1) != pc_rtx
10990       || !xcond2 || SET_DEST (xcond2) != pc_rtx
10991       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond1))
10992       || IF_THEN_ELSE != GET_CODE (SET_SRC (xcond2)))
10993     {
10994       return false;
10995     }
10996 
10997   comp1 = SET_SRC (comp1);
10998   ifelse1 = SET_SRC (xcond1);
10999   ifelse2 = SET_SRC (xcond2);
11000 
11001   /* comp<n> is COMPARE now and ifelse<n> is IF_THEN_ELSE.  */
11002 
11003   if (EQ != GET_CODE (XEXP (ifelse1, 0))
11004       || !REG_P (XEXP (comp1, 0))
11005       || !CONST_INT_P (XEXP (comp1, 1))
11006       || XEXP (ifelse1, 2) != pc_rtx
11007       || XEXP (ifelse2, 2) != pc_rtx
11008       || LABEL_REF != GET_CODE (XEXP (ifelse1, 1))
11009       || LABEL_REF != GET_CODE (XEXP (ifelse2, 1))
11010       || !COMPARISON_P (XEXP (ifelse2, 0))
11011       || cc0_rtx != XEXP (XEXP (ifelse1, 0), 0)
11012       || cc0_rtx != XEXP (XEXP (ifelse2, 0), 0)
11013       || const0_rtx != XEXP (XEXP (ifelse1, 0), 1)
11014       || const0_rtx != XEXP (XEXP (ifelse2, 0), 1))
11015     {
11016       return false;
11017     }
11018 
11019   /* We filtered the insn sequence to look like
11020 
11021         (set (cc0)
11022              (compare (reg:M N)
11023                       (const_int VAL)))
11024         (set (pc)
11025              (if_then_else (eq (cc0)
11026                                (const_int 0))
11027                            (label_ref L1)
11028                            (pc)))
11029 
11030         (set (cc0)
11031              (compare (reg:M N)
11032                       (const_int VAL)))
11033         (set (pc)
11034              (if_then_else (CODE (cc0)
11035                                  (const_int 0))
11036                            (label_ref L2)
11037                            (pc)))
11038   */
11039 
11040   code = GET_CODE (XEXP (ifelse2, 0));
11041 
11042   /* Map GT/GTU to GE/GEU which is easier for AVR.
11043      The first two instructions compare/branch on EQ
11044      so we may replace the difficult
11045 
11046         if (x == VAL)   goto L1;
11047         if (x > VAL)    goto L2;
11048 
11049      with easy
11050 
11051          if (x == VAL)   goto L1;
11052          if (x >= VAL)   goto L2;
11053 
11054      Similarly, replace LE/LEU by LT/LTU.  */
11055 
11056   switch (code)
11057     {
11058     case EQ:
11059     case LT:  case LTU:
11060     case GE:  case GEU:
11061       break;
11062 
11063     case LE:  case LEU:
11064     case GT:  case GTU:
11065       code = avr_normalize_condition (code);
11066       break;
11067 
11068     default:
11069       return false;
11070     }
11071 
11072   /* Wrap the branches into UNSPECs so they won't be changed or
11073      optimized in the remainder.  */
11074 
11075   target = XEXP (XEXP (ifelse1, 1), 0);
11076   cond = XEXP (ifelse1, 0);
11077   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn1);
11078 
11079   JUMP_LABEL (jump) = JUMP_LABEL (branch1);
11080 
11081   target = XEXP (XEXP (ifelse2, 1), 0);
11082   cond = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
11083   jump = emit_jump_insn_after (gen_branch_unspec (target, cond), insn2);
11084 
11085   JUMP_LABEL (jump) = JUMP_LABEL (branch2);
11086 
11087   /* The comparisons in insn1 and insn2 are exactly the same;
11088      insn2 is superfluous so delete it.  */
11089 
11090   delete_insn (insn2);
11091   delete_insn (branch1);
11092   delete_insn (branch2);
11093 
11094   return true;
11095 }
11096 
11097 
11098 /* Implement `TARGET_MACHINE_DEPENDENT_REORG'.  */
11099 /* Optimize conditional jumps.  */
11100 
11101 static void
avr_reorg(void)11102 avr_reorg (void)
11103 {
11104   rtx_insn *insn = get_insns();
11105 
11106   for (insn = next_real_insn (insn); insn; insn = next_real_insn (insn))
11107     {
11108       rtx pattern = avr_compare_pattern (insn);
11109 
11110       if (!pattern)
11111         continue;
11112 
11113       if (optimize
11114           && avr_reorg_remove_redundant_compare (insn))
11115         {
11116           continue;
11117         }
11118 
11119       if (compare_diff_p (insn))
11120 	{
11121           /* Now we work under compare insn with difficult branch.  */
11122 
11123 	  rtx_insn *next = next_real_insn (insn);
11124           rtx pat = PATTERN (next);
11125 
11126           pattern = SET_SRC (pattern);
11127 
11128           if (true_regnum (XEXP (pattern, 0)) >= 0
11129               && true_regnum (XEXP (pattern, 1)) >= 0)
11130             {
11131               rtx x = XEXP (pattern, 0);
11132               rtx src = SET_SRC (pat);
11133               rtx t = XEXP (src,0);
11134               PUT_CODE (t, swap_condition (GET_CODE (t)));
11135               XEXP (pattern, 0) = XEXP (pattern, 1);
11136               XEXP (pattern, 1) = x;
11137               INSN_CODE (next) = -1;
11138             }
11139           else if (true_regnum (XEXP (pattern, 0)) >= 0
11140                    && XEXP (pattern, 1) == const0_rtx)
11141             {
11142               /* This is a tst insn, we can reverse it.  */
11143               rtx src = SET_SRC (pat);
11144               rtx t = XEXP (src,0);
11145 
11146               PUT_CODE (t, swap_condition (GET_CODE (t)));
11147               XEXP (pattern, 1) = XEXP (pattern, 0);
11148               XEXP (pattern, 0) = const0_rtx;
11149               INSN_CODE (next) = -1;
11150               INSN_CODE (insn) = -1;
11151             }
11152           else if (true_regnum (XEXP (pattern, 0)) >= 0
11153                    && CONST_INT_P (XEXP (pattern, 1)))
11154             {
11155               rtx x = XEXP (pattern, 1);
11156               rtx src = SET_SRC (pat);
11157               rtx t = XEXP (src,0);
11158               machine_mode mode = GET_MODE (XEXP (pattern, 0));
11159 
11160               if (avr_simplify_comparison_p (mode, GET_CODE (t), x))
11161                 {
11162                   XEXP (pattern, 1) = gen_int_mode (INTVAL (x) + 1, mode);
11163                   PUT_CODE (t, avr_normalize_condition (GET_CODE (t)));
11164                   INSN_CODE (next) = -1;
11165                   INSN_CODE (insn) = -1;
11166                 }
11167             }
11168         }
11169     }
11170 }
11171 
11172 /* Returns register number for function return value.*/
11173 
11174 static inline unsigned int
avr_ret_register(void)11175 avr_ret_register (void)
11176 {
11177   return 24;
11178 }
11179 
11180 
11181 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'.  */
11182 
11183 static bool
avr_function_value_regno_p(const unsigned int regno)11184 avr_function_value_regno_p (const unsigned int regno)
11185 {
11186   return (regno == avr_ret_register ());
11187 }
11188 
11189 
11190 /* Implement `TARGET_LIBCALL_VALUE'.  */
11191 /* Create an RTX representing the place where a
11192    library function returns a value of mode MODE.  */
11193 
11194 static rtx
avr_libcall_value(machine_mode mode,const_rtx func ATTRIBUTE_UNUSED)11195 avr_libcall_value (machine_mode mode,
11196 		   const_rtx func ATTRIBUTE_UNUSED)
11197 {
11198   int offs = GET_MODE_SIZE (mode);
11199 
11200   if (offs <= 4)
11201     offs = (offs + 1) & ~1;
11202 
11203   return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
11204 }
11205 
11206 
11207 /* Implement `TARGET_FUNCTION_VALUE'.  */
11208 /* Create an RTX representing the place where a
11209    function returns a value of data type VALTYPE.  */
11210 
11211 static rtx
avr_function_value(const_tree type,const_tree fn_decl_or_type ATTRIBUTE_UNUSED,bool outgoing ATTRIBUTE_UNUSED)11212 avr_function_value (const_tree type,
11213                     const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
11214                     bool outgoing ATTRIBUTE_UNUSED)
11215 {
11216   unsigned int offs;
11217 
11218   if (TYPE_MODE (type) != BLKmode)
11219     return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
11220 
11221   offs = int_size_in_bytes (type);
11222   if (offs < 2)
11223     offs = 2;
11224   if (offs > 2 && offs < GET_MODE_SIZE (SImode))
11225     offs = GET_MODE_SIZE (SImode);
11226   else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
11227     offs = GET_MODE_SIZE (DImode);
11228 
11229   return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
11230 }
11231 
11232 int
test_hard_reg_class(enum reg_class rclass,rtx x)11233 test_hard_reg_class (enum reg_class rclass, rtx x)
11234 {
11235   int regno = true_regnum (x);
11236   if (regno < 0)
11237     return 0;
11238 
11239   if (TEST_HARD_REG_CLASS (rclass, regno))
11240     return 1;
11241 
11242   return 0;
11243 }
11244 
11245 
11246 /* Helper for jump_over_one_insn_p:  Test if INSN is a 2-word instruction
11247    and thus is suitable to be skipped by CPSE, SBRC, etc.  */
11248 
11249 static bool
avr_2word_insn_p(rtx_insn * insn)11250 avr_2word_insn_p (rtx_insn *insn)
11251 {
11252   if (TARGET_SKIP_BUG
11253       || !insn
11254       || 2 != get_attr_length (insn))
11255     {
11256       return false;
11257     }
11258 
11259   switch (INSN_CODE (insn))
11260     {
11261     default:
11262       return false;
11263 
11264     case CODE_FOR_movqi_insn:
11265     case CODE_FOR_movuqq_insn:
11266     case CODE_FOR_movqq_insn:
11267       {
11268         rtx set  = single_set (insn);
11269         rtx src  = SET_SRC (set);
11270         rtx dest = SET_DEST (set);
11271 
11272         /* Factor out LDS and STS from movqi_insn.  */
11273 
11274         if (MEM_P (dest)
11275             && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
11276           {
11277             return CONSTANT_ADDRESS_P (XEXP (dest, 0));
11278           }
11279         else if (REG_P (dest)
11280                  && MEM_P (src))
11281           {
11282             return CONSTANT_ADDRESS_P (XEXP (src, 0));
11283           }
11284 
11285         return false;
11286       }
11287 
11288     case CODE_FOR_call_insn:
11289     case CODE_FOR_call_value_insn:
11290       return true;
11291     }
11292 }
11293 
11294 
11295 int
jump_over_one_insn_p(rtx_insn * insn,rtx dest)11296 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
11297 {
11298   int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
11299 		      ? XEXP (dest, 0)
11300 		      : dest);
11301   int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
11302   int dest_addr = INSN_ADDRESSES (uid);
11303   int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
11304 
11305   return (jump_offset == 1
11306           || (jump_offset == 2
11307               && avr_2word_insn_p (next_active_insn (insn))));
11308 }
11309 
11310 
11311 /* Worker function for `HARD_REGNO_MODE_OK'.  */
11312 /* Returns 1 if a value of mode MODE can be stored starting with hard
11313    register number REGNO.  On the enhanced core, anything larger than
11314    1 byte must start in even numbered register for "movw" to work
11315    (this way we don't have to check for odd registers everywhere).  */
11316 
11317 int
avr_hard_regno_mode_ok(int regno,machine_mode mode)11318 avr_hard_regno_mode_ok (int regno, machine_mode mode)
11319 {
11320   /* NOTE: 8-bit values must not be disallowed for R28 or R29.
11321         Disallowing QI et al. in these regs might lead to code like
11322             (set (subreg:QI (reg:HI 28) n) ...)
11323         which will result in wrong code because reload does not
11324         handle SUBREGs of hard regsisters like this.
11325         This could be fixed in reload.  However, it appears
11326         that fixing reload is not wanted by reload people.  */
11327 
11328   /* Any GENERAL_REGS register can hold 8-bit values.  */
11329 
11330   if (GET_MODE_SIZE (mode) == 1)
11331     return 1;
11332 
11333   /* FIXME: Ideally, the following test is not needed.
11334         However, it turned out that it can reduce the number
11335         of spill fails.  AVR and it's poor endowment with
11336         address registers is extreme stress test for reload.  */
11337 
11338   if (GET_MODE_SIZE (mode) >= 4
11339       && regno >= REG_X)
11340     return 0;
11341 
11342   /* All modes larger than 8 bits should start in an even register.  */
11343 
11344   return !(regno & 1);
11345 }
11346 
11347 
11348 /* Implement `HARD_REGNO_CALL_PART_CLOBBERED'.  */
11349 
11350 int
avr_hard_regno_call_part_clobbered(unsigned regno,machine_mode mode)11351 avr_hard_regno_call_part_clobbered (unsigned regno, machine_mode mode)
11352 {
11353   /* FIXME: This hook gets called with MODE:REGNO combinations that don't
11354         represent valid hard registers like, e.g. HI:29.  Returning TRUE
11355         for such registers can lead to performance degradation as mentioned
11356         in PR53595.  Thus, report invalid hard registers as FALSE.  */
11357 
11358   if (!avr_hard_regno_mode_ok (regno, mode))
11359     return 0;
11360 
11361   /* Return true if any of the following boundaries is crossed:
11362      17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30.  */
11363 
11364   return ((regno <= LAST_CALLEE_SAVED_REG &&
11365            regno + GET_MODE_SIZE (mode) > (LAST_CALLEE_SAVED_REG + 1))
11366           || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
11367           || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
11368 }
11369 
11370 
11371 /* Implement `MODE_CODE_BASE_REG_CLASS'.  */
11372 
11373 enum reg_class
avr_mode_code_base_reg_class(machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as,RTX_CODE outer_code,RTX_CODE index_code ATTRIBUTE_UNUSED)11374 avr_mode_code_base_reg_class (machine_mode mode ATTRIBUTE_UNUSED,
11375                               addr_space_t as, RTX_CODE outer_code,
11376                               RTX_CODE index_code ATTRIBUTE_UNUSED)
11377 {
11378   if (!ADDR_SPACE_GENERIC_P (as))
11379     {
11380       return POINTER_Z_REGS;
11381     }
11382 
11383   if (!avr_strict_X)
11384     return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
11385 
11386   return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
11387 }
11388 
11389 
11390 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'.  */
11391 
11392 bool
avr_regno_mode_code_ok_for_base_p(int regno,machine_mode mode ATTRIBUTE_UNUSED,addr_space_t as ATTRIBUTE_UNUSED,RTX_CODE outer_code,RTX_CODE index_code ATTRIBUTE_UNUSED)11393 avr_regno_mode_code_ok_for_base_p (int regno,
11394                                    machine_mode mode ATTRIBUTE_UNUSED,
11395                                    addr_space_t as ATTRIBUTE_UNUSED,
11396                                    RTX_CODE outer_code,
11397                                    RTX_CODE index_code ATTRIBUTE_UNUSED)
11398 {
11399   bool ok = false;
11400 
11401   if (!ADDR_SPACE_GENERIC_P (as))
11402     {
11403       if (regno < FIRST_PSEUDO_REGISTER
11404           && regno == REG_Z)
11405         {
11406           return true;
11407         }
11408 
11409       if (reg_renumber)
11410         {
11411           regno = reg_renumber[regno];
11412 
11413           if (regno == REG_Z)
11414             {
11415               return true;
11416             }
11417         }
11418 
11419       return false;
11420     }
11421 
11422   if (regno < FIRST_PSEUDO_REGISTER
11423       && (regno == REG_X
11424           || regno == REG_Y
11425           || regno == REG_Z
11426           || regno == ARG_POINTER_REGNUM))
11427     {
11428       ok = true;
11429     }
11430   else if (reg_renumber)
11431     {
11432       regno = reg_renumber[regno];
11433 
11434       if (regno == REG_X
11435           || regno == REG_Y
11436           || regno == REG_Z
11437           || regno == ARG_POINTER_REGNUM)
11438         {
11439           ok = true;
11440         }
11441     }
11442 
11443   if (avr_strict_X
11444       && PLUS == outer_code
11445       && regno == REG_X)
11446     {
11447       ok = false;
11448     }
11449 
11450   return ok;
11451 }
11452 
11453 
11454 /* A helper for `output_reload_insisf' and `output_reload_inhi'.  */
11455 /* Set 32-bit register OP[0] to compile-time constant OP[1].
11456    CLOBBER_REG is a QI clobber register or NULL_RTX.
11457    LEN == NULL: output instructions.
11458    LEN != NULL: set *LEN to the length of the instruction sequence
11459                 (in words) printed with LEN = NULL.
11460    If CLEAR_P is true, OP[0] had been cleard to Zero already.
11461    If CLEAR_P is false, nothing is known about OP[0].
11462 
11463    The effect on cc0 is as follows:
11464 
11465    Load 0 to any register except ZERO_REG : NONE
11466    Load ld register with any value        : NONE
11467    Anything else:                         : CLOBBER  */
11468 
11469 static void
output_reload_in_const(rtx * op,rtx clobber_reg,int * len,bool clear_p)11470 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
11471 {
11472   rtx src = op[1];
11473   rtx dest = op[0];
11474   rtx xval, xdest[4];
11475   int ival[4];
11476   int clobber_val = 1234;
11477   bool cooked_clobber_p = false;
11478   bool set_p = false;
11479   machine_mode mode = GET_MODE (dest);
11480   int n, n_bytes = GET_MODE_SIZE (mode);
11481 
11482   gcc_assert (REG_P (dest)
11483               && CONSTANT_P (src));
11484 
11485   if (len)
11486     *len = 0;
11487 
11488   /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
11489      but has some subregs that are in LD_REGS.  Use the MSB (REG:QI 17).  */
11490 
11491   if (REGNO (dest) < 16
11492       && REGNO (dest) + GET_MODE_SIZE (mode) > 16)
11493     {
11494       clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
11495     }
11496 
11497   /* We might need a clobber reg but don't have one.  Look at the value to
11498      be loaded more closely.  A clobber is only needed if it is a symbol
11499      or contains a byte that is neither 0, -1 or a power of 2.  */
11500 
11501   if (NULL_RTX == clobber_reg
11502       && !test_hard_reg_class (LD_REGS, dest)
11503       && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
11504           || !avr_popcount_each_byte (src, n_bytes,
11505                                       (1 << 0) | (1 << 1) | (1 << 8))))
11506     {
11507       /* We have no clobber register but need one.  Cook one up.
11508          That's cheaper than loading from constant pool.  */
11509 
11510       cooked_clobber_p = true;
11511       clobber_reg = all_regs_rtx[REG_Z + 1];
11512       avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
11513     }
11514 
11515   /* Now start filling DEST from LSB to MSB.  */
11516 
11517   for (n = 0; n < n_bytes; n++)
11518     {
11519       int ldreg_p;
11520       bool done_byte = false;
11521       int j;
11522       rtx xop[3];
11523 
11524       /* Crop the n-th destination byte.  */
11525 
11526       xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
11527       ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
11528 
11529       if (!CONST_INT_P (src)
11530           && !CONST_FIXED_P (src)
11531           && !CONST_DOUBLE_P (src))
11532         {
11533           static const char* const asm_code[][2] =
11534             {
11535               { "ldi %2,lo8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,lo8(%1)"  },
11536               { "ldi %2,hi8(%1)"  CR_TAB "mov %0,%2",    "ldi %0,hi8(%1)"  },
11537               { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hlo8(%1)" },
11538               { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2",    "ldi %0,hhi8(%1)" }
11539             };
11540 
11541           xop[0] = xdest[n];
11542           xop[1] = src;
11543           xop[2] = clobber_reg;
11544 
11545           avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
11546 
11547           continue;
11548         }
11549 
11550       /* Crop the n-th source byte.  */
11551 
11552       xval = simplify_gen_subreg (QImode, src, mode, n);
11553       ival[n] = INTVAL (xval);
11554 
11555       /* Look if we can reuse the low word by means of MOVW.  */
11556 
11557       if (n == 2
11558           && n_bytes >= 4
11559           && AVR_HAVE_MOVW)
11560         {
11561           rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
11562           rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
11563 
11564           if (INTVAL (lo16) == INTVAL (hi16))
11565             {
11566               if (0 != INTVAL (lo16)
11567                   || !clear_p)
11568                 {
11569                   avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
11570                 }
11571 
11572               break;
11573             }
11574         }
11575 
11576       /* Don't use CLR so that cc0 is set as expected.  */
11577 
11578       if (ival[n] == 0)
11579         {
11580           if (!clear_p)
11581             avr_asm_len (ldreg_p ? "ldi %0,0"
11582                          : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
11583                          : "mov %0,__zero_reg__",
11584                          &xdest[n], len, 1);
11585           continue;
11586         }
11587 
11588       if (clobber_val == ival[n]
11589           && REGNO (clobber_reg) == REGNO (xdest[n]))
11590         {
11591           continue;
11592         }
11593 
11594       /* LD_REGS can use LDI to move a constant value */
11595 
11596       if (ldreg_p)
11597         {
11598           xop[0] = xdest[n];
11599           xop[1] = xval;
11600           avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
11601           continue;
11602         }
11603 
11604       /* Try to reuse value already loaded in some lower byte. */
11605 
11606       for (j = 0; j < n; j++)
11607         if (ival[j] == ival[n])
11608           {
11609             xop[0] = xdest[n];
11610             xop[1] = xdest[j];
11611 
11612             avr_asm_len ("mov %0,%1", xop, len, 1);
11613             done_byte = true;
11614             break;
11615           }
11616 
11617       if (done_byte)
11618         continue;
11619 
11620       /* Need no clobber reg for -1: Use CLR/DEC */
11621 
11622       if (-1 == ival[n])
11623         {
11624           if (!clear_p)
11625             avr_asm_len ("clr %0", &xdest[n], len, 1);
11626 
11627           avr_asm_len ("dec %0", &xdest[n], len, 1);
11628           continue;
11629         }
11630       else if (1 == ival[n])
11631         {
11632           if (!clear_p)
11633             avr_asm_len ("clr %0", &xdest[n], len, 1);
11634 
11635           avr_asm_len ("inc %0", &xdest[n], len, 1);
11636           continue;
11637         }
11638 
11639       /* Use T flag or INC to manage powers of 2 if we have
11640          no clobber reg.  */
11641 
11642       if (NULL_RTX == clobber_reg
11643           && single_one_operand (xval, QImode))
11644         {
11645           xop[0] = xdest[n];
11646           xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
11647 
11648           gcc_assert (constm1_rtx != xop[1]);
11649 
11650           if (!set_p)
11651             {
11652               set_p = true;
11653               avr_asm_len ("set", xop, len, 1);
11654             }
11655 
11656           if (!clear_p)
11657             avr_asm_len ("clr %0", xop, len, 1);
11658 
11659           avr_asm_len ("bld %0,%1", xop, len, 1);
11660           continue;
11661         }
11662 
11663       /* We actually need the LD_REGS clobber reg.  */
11664 
11665       gcc_assert (NULL_RTX != clobber_reg);
11666 
11667       xop[0] = xdest[n];
11668       xop[1] = xval;
11669       xop[2] = clobber_reg;
11670       clobber_val = ival[n];
11671 
11672       avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
11673                    "mov %0,%2", xop, len, 2);
11674     }
11675 
11676   /* If we cooked up a clobber reg above, restore it.  */
11677 
11678   if (cooked_clobber_p)
11679     {
11680       avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
11681     }
11682 }
11683 
11684 
11685 /* Reload the constant OP[1] into the HI register OP[0].
11686    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11687    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
11688    need a clobber reg or have to cook one up.
11689 
11690    PLEN == NULL: Output instructions.
11691    PLEN != NULL: Output nothing.  Set *PLEN to number of words occupied
11692                  by the insns printed.
11693 
11694    Return "".  */
11695 
11696 const char*
output_reload_inhi(rtx * op,rtx clobber_reg,int * plen)11697 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
11698 {
11699   output_reload_in_const (op, clobber_reg, plen, false);
11700   return "";
11701 }
11702 
11703 
11704 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
11705    CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
11706    into a NO_LD_REGS register.  If CLOBBER_REG is NULL_RTX we either don't
11707    need a clobber reg or have to cook one up.
11708 
11709    LEN == NULL: Output instructions.
11710 
11711    LEN != NULL: Output nothing.  Set *LEN to number of words occupied
11712                 by the insns printed.
11713 
11714    Return "".  */
11715 
11716 const char *
output_reload_insisf(rtx * op,rtx clobber_reg,int * len)11717 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
11718 {
11719   if (AVR_HAVE_MOVW
11720       && !test_hard_reg_class (LD_REGS, op[0])
11721       && (CONST_INT_P (op[1])
11722           || CONST_FIXED_P (op[1])
11723           || CONST_DOUBLE_P (op[1])))
11724     {
11725       int len_clr, len_noclr;
11726 
11727       /* In some cases it is better to clear the destination beforehand, e.g.
11728 
11729              CLR R2   CLR R3   MOVW R4,R2   INC R2
11730 
11731          is shorther than
11732 
11733              CLR R2   INC R2   CLR  R3      CLR R4   CLR R5
11734 
11735          We find it too tedious to work that out in the print function.
11736          Instead, we call the print function twice to get the lengths of
11737          both methods and use the shortest one.  */
11738 
11739       output_reload_in_const (op, clobber_reg, &len_clr, true);
11740       output_reload_in_const (op, clobber_reg, &len_noclr, false);
11741 
11742       if (len_noclr - len_clr == 4)
11743         {
11744           /* Default needs 4 CLR instructions: clear register beforehand.  */
11745 
11746           avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
11747                        "mov %B0,__zero_reg__" CR_TAB
11748                        "movw %C0,%A0", &op[0], len, 3);
11749 
11750           output_reload_in_const (op, clobber_reg, len, true);
11751 
11752           if (len)
11753             *len += 3;
11754 
11755           return "";
11756         }
11757     }
11758 
11759   /* Default: destination not pre-cleared.  */
11760 
11761   output_reload_in_const (op, clobber_reg, len, false);
11762   return "";
11763 }
11764 
11765 const char*
avr_out_reload_inpsi(rtx * op,rtx clobber_reg,int * len)11766 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
11767 {
11768   output_reload_in_const (op, clobber_reg, len, false);
11769   return "";
11770 }
11771 
11772 
11773 /* Worker function for `ASM_OUTPUT_ADDR_VEC_ELT'.  */
11774 
11775 void
avr_output_addr_vec_elt(FILE * stream,int value)11776 avr_output_addr_vec_elt (FILE *stream, int value)
11777 {
11778   if (AVR_HAVE_JMP_CALL)
11779     fprintf (stream, "\t.word gs(.L%d)\n", value);
11780   else
11781     fprintf (stream, "\trjmp .L%d\n", value);
11782 }
11783 
11784 static void
avr_conditional_register_usage(void)11785 avr_conditional_register_usage(void)
11786 {
11787   if (AVR_TINY)
11788     {
11789       unsigned int i;
11790 
11791       const int tiny_reg_alloc_order[] = {
11792         24, 25,
11793         22, 23,
11794         30, 31,
11795         26, 27,
11796         28, 29,
11797         21, 20, 19, 18,
11798         16, 17,
11799         32, 33, 34, 35,
11800         15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
11801       };
11802 
11803       /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
11804          - R0-R15 are not available in Tiny Core devices
11805          - R16 and R17 are fixed registers.  */
11806 
11807       for (i = 0;  i <= 17;  i++)
11808         {
11809           fixed_regs[i] = 1;
11810           call_used_regs[i] = 1;
11811         }
11812 
11813       /* Set R18 to R21 as callee saved registers
11814          - R18, R19, R20 and R21 are the callee saved registers in
11815            Tiny Core devices  */
11816 
11817       for (i = 18; i <= LAST_CALLEE_SAVED_REG; i++)
11818         {
11819           call_used_regs[i] = 0;
11820         }
11821 
11822       /* Update register allocation order for Tiny Core devices */
11823 
11824       for (i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
11825         {
11826           reg_alloc_order[i] = tiny_reg_alloc_order[i];
11827         }
11828 
11829       CLEAR_HARD_REG_SET (reg_class_contents[(int) ADDW_REGS]);
11830       CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
11831     }
11832 }
11833 
11834 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'.  */
11835 /* Returns true if SCRATCH are safe to be allocated as a scratch
11836    registers (for a define_peephole2) in the current function.  */
11837 
11838 static bool
avr_hard_regno_scratch_ok(unsigned int regno)11839 avr_hard_regno_scratch_ok (unsigned int regno)
11840 {
11841   /* Interrupt functions can only use registers that have already been saved
11842      by the prologue, even if they would normally be call-clobbered.  */
11843 
11844   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11845       && !df_regs_ever_live_p (regno))
11846     return false;
11847 
11848   /* Don't allow hard registers that might be part of the frame pointer.
11849      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11850      and don't care for a frame pointer that spans more than one register.  */
11851 
11852   if ((!reload_completed || frame_pointer_needed)
11853       && (regno == REG_Y || regno == REG_Y + 1))
11854     {
11855       return false;
11856     }
11857 
11858   return true;
11859 }
11860 
11861 
11862 /* Worker function for `HARD_REGNO_RENAME_OK'.  */
11863 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG.  */
11864 
11865 int
avr_hard_regno_rename_ok(unsigned int old_reg,unsigned int new_reg)11866 avr_hard_regno_rename_ok (unsigned int old_reg,
11867 			  unsigned int new_reg)
11868 {
11869   /* Interrupt functions can only use registers that have already been
11870      saved by the prologue, even if they would normally be
11871      call-clobbered.  */
11872 
11873   if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
11874       && !df_regs_ever_live_p (new_reg))
11875     return 0;
11876 
11877   /* Don't allow hard registers that might be part of the frame pointer.
11878      Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
11879      and don't care for a frame pointer that spans more than one register.  */
11880 
11881   if ((!reload_completed || frame_pointer_needed)
11882       && (old_reg == REG_Y || old_reg == REG_Y + 1
11883           || new_reg == REG_Y || new_reg == REG_Y + 1))
11884     {
11885       return 0;
11886     }
11887 
11888   return 1;
11889 }
11890 
11891 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
11892    or memory location in the I/O space (QImode only).
11893 
11894    Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
11895    Operand 1: register operand to test, or CONST_INT memory address.
11896    Operand 2: bit number.
11897    Operand 3: label to jump to if the test is true.  */
11898 
11899 const char*
avr_out_sbxx_branch(rtx_insn * insn,rtx operands[])11900 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
11901 {
11902   enum rtx_code comp = GET_CODE (operands[0]);
11903   bool long_jump = get_attr_length (insn) >= 4;
11904   bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
11905 
11906   if (comp == GE)
11907     comp = EQ;
11908   else if (comp == LT)
11909     comp = NE;
11910 
11911   if (reverse)
11912     comp = reverse_condition (comp);
11913 
11914   switch (GET_CODE (operands[1]))
11915     {
11916     default:
11917       gcc_unreachable();
11918 
11919     case CONST_INT:
11920     case CONST:
11921     case SYMBOL_REF:
11922 
11923       if (low_io_address_operand (operands[1], QImode))
11924         {
11925           if (comp == EQ)
11926             output_asm_insn ("sbis %i1,%2", operands);
11927           else
11928             output_asm_insn ("sbic %i1,%2", operands);
11929         }
11930       else
11931         {
11932 	  gcc_assert (io_address_operand (operands[1], QImode));
11933           output_asm_insn ("in __tmp_reg__,%i1", operands);
11934           if (comp == EQ)
11935             output_asm_insn ("sbrs __tmp_reg__,%2", operands);
11936           else
11937             output_asm_insn ("sbrc __tmp_reg__,%2", operands);
11938         }
11939 
11940       break; /* CONST_INT */
11941 
11942     case REG:
11943 
11944       if (comp == EQ)
11945         output_asm_insn ("sbrs %T1%T2", operands);
11946       else
11947         output_asm_insn ("sbrc %T1%T2", operands);
11948 
11949       break; /* REG */
11950     }        /* switch */
11951 
11952   if (long_jump)
11953     return ("rjmp .+4" CR_TAB
11954             "jmp %x3");
11955 
11956   if (!reverse)
11957     return "rjmp %x3";
11958 
11959   return "";
11960 }
11961 
11962 /* Worker function for `TARGET_ASM_CONSTRUCTOR'.  */
11963 
11964 static void
avr_asm_out_ctor(rtx symbol,int priority)11965 avr_asm_out_ctor (rtx symbol, int priority)
11966 {
11967   fputs ("\t.global __do_global_ctors\n", asm_out_file);
11968   default_ctor_section_asm_out_constructor (symbol, priority);
11969 }
11970 
11971 
11972 /* Worker function for `TARGET_ASM_DESTRUCTOR'.  */
11973 
11974 static void
avr_asm_out_dtor(rtx symbol,int priority)11975 avr_asm_out_dtor (rtx symbol, int priority)
11976 {
11977   fputs ("\t.global __do_global_dtors\n", asm_out_file);
11978   default_dtor_section_asm_out_destructor (symbol, priority);
11979 }
11980 
11981 
11982 /* Worker function for `TARGET_RETURN_IN_MEMORY'.  */
11983 
11984 static bool
avr_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)11985 avr_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
11986 {
11987   HOST_WIDE_INT size = int_size_in_bytes (type);
11988   HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
11989 
11990   /* In avr, there are 8 return registers. But, for Tiny Core
11991      (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
11992      Return true if size is unknown or greater than the limit.  */
11993 
11994   if (size == -1 || size > ret_size_limit)
11995     {
11996       return true;
11997     }
11998   else
11999     {
12000       return false;
12001     }
12002 }
12003 
12004 
12005 /* Implement `CASE_VALUES_THRESHOLD'.  */
12006 /* Supply the default for --param case-values-threshold=0  */
12007 
12008 static unsigned int
avr_case_values_threshold(void)12009 avr_case_values_threshold (void)
12010 {
12011   /* The exact break-even point between a jump table and an if-else tree
12012      depends on several factors not available here like, e.g. if 8-bit
12013      comparisons can be used in the if-else tree or not, on the
12014      range of the case values, if the case value can be reused, on the
12015      register allocation, etc.  '7' appears to be a good choice.  */
12016 
12017   return 7;
12018 }
12019 
12020 
12021 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'.  */
12022 
12023 static machine_mode
avr_addr_space_address_mode(addr_space_t as)12024 avr_addr_space_address_mode (addr_space_t as)
12025 {
12026   return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
12027 }
12028 
12029 
12030 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'.  */
12031 
12032 static machine_mode
avr_addr_space_pointer_mode(addr_space_t as)12033 avr_addr_space_pointer_mode (addr_space_t as)
12034 {
12035   return avr_addr_space_address_mode (as);
12036 }
12037 
12038 
12039 /* Helper for following function.  */
12040 
12041 static bool
avr_reg_ok_for_pgm_addr(rtx reg,bool strict)12042 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
12043 {
12044   gcc_assert (REG_P (reg));
12045 
12046   if (strict)
12047     {
12048       return REGNO (reg) == REG_Z;
12049     }
12050 
12051   /* Avoid combine to propagate hard regs.  */
12052 
12053   if (can_create_pseudo_p()
12054       && REGNO (reg) < REG_Z)
12055     {
12056       return false;
12057     }
12058 
12059   return true;
12060 }
12061 
12062 
12063 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'.  */
12064 
12065 static bool
avr_addr_space_legitimate_address_p(machine_mode mode,rtx x,bool strict,addr_space_t as)12066 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x,
12067                                      bool strict, addr_space_t as)
12068 {
12069   bool ok = false;
12070 
12071   switch (as)
12072     {
12073     default:
12074       gcc_unreachable();
12075 
12076     case ADDR_SPACE_GENERIC:
12077       return avr_legitimate_address_p (mode, x, strict);
12078 
12079     case ADDR_SPACE_FLASH:
12080     case ADDR_SPACE_FLASH1:
12081     case ADDR_SPACE_FLASH2:
12082     case ADDR_SPACE_FLASH3:
12083     case ADDR_SPACE_FLASH4:
12084     case ADDR_SPACE_FLASH5:
12085 
12086       switch (GET_CODE (x))
12087         {
12088         case REG:
12089           ok = avr_reg_ok_for_pgm_addr (x, strict);
12090           break;
12091 
12092         case POST_INC:
12093           ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
12094           break;
12095 
12096         default:
12097           break;
12098         }
12099 
12100       break; /* FLASH */
12101 
12102     case ADDR_SPACE_MEMX:
12103       if (REG_P (x))
12104         ok = (!strict
12105               && can_create_pseudo_p());
12106 
12107       if (LO_SUM == GET_CODE (x))
12108         {
12109           rtx hi = XEXP (x, 0);
12110           rtx lo = XEXP (x, 1);
12111 
12112           ok = (REG_P (hi)
12113                 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
12114                 && REG_P (lo)
12115                 && REGNO (lo) == REG_Z);
12116         }
12117 
12118       break; /* MEMX */
12119     }
12120 
12121   if (avr_log.legitimate_address_p)
12122     {
12123       avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
12124                  "reload_completed=%d reload_in_progress=%d %s:",
12125                  ok, mode, strict, reload_completed, reload_in_progress,
12126                  reg_renumber ? "(reg_renumber)" : "");
12127 
12128       if (GET_CODE (x) == PLUS
12129           && REG_P (XEXP (x, 0))
12130           && CONST_INT_P (XEXP (x, 1))
12131           && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
12132           && reg_renumber)
12133         {
12134           avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
12135                      true_regnum (XEXP (x, 0)));
12136         }
12137 
12138       avr_edump ("\n%r\n", x);
12139     }
12140 
12141   return ok;
12142 }
12143 
12144 
12145 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'.  */
12146 
12147 static rtx
avr_addr_space_legitimize_address(rtx x,rtx old_x,machine_mode mode,addr_space_t as)12148 avr_addr_space_legitimize_address (rtx x, rtx old_x,
12149                                    machine_mode mode, addr_space_t as)
12150 {
12151   if (ADDR_SPACE_GENERIC_P (as))
12152     return avr_legitimize_address (x, old_x, mode);
12153 
12154   if (avr_log.legitimize_address)
12155     {
12156       avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
12157     }
12158 
12159   return old_x;
12160 }
12161 
12162 
12163 /* Implement `TARGET_ADDR_SPACE_CONVERT'.  */
12164 
12165 static rtx
avr_addr_space_convert(rtx src,tree type_from,tree type_to)12166 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
12167 {
12168   addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
12169   addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
12170 
12171   if (avr_log.progmem)
12172     avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
12173                src, type_from, type_to);
12174 
12175   /* Up-casting from 16-bit to 24-bit pointer.  */
12176 
12177   if (as_from != ADDR_SPACE_MEMX
12178       && as_to == ADDR_SPACE_MEMX)
12179     {
12180       int msb;
12181       rtx sym = src;
12182       rtx reg = gen_reg_rtx (PSImode);
12183 
12184       while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
12185         sym = XEXP (sym, 0);
12186 
12187       /* Look at symbol flags:  avr_encode_section_info set the flags
12188          also if attribute progmem was seen so that we get the right
12189          promotion for, e.g. PSTR-like strings that reside in generic space
12190          but are located in flash.  In that case we patch the incoming
12191          address space.  */
12192 
12193       if (SYMBOL_REF == GET_CODE (sym)
12194           && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
12195         {
12196           as_from = ADDR_SPACE_FLASH;
12197         }
12198 
12199       /* Linearize memory: RAM has bit 23 set.  */
12200 
12201       msb = ADDR_SPACE_GENERIC_P (as_from)
12202         ? 0x80
12203         : avr_addrspace[as_from].segment;
12204 
12205       src = force_reg (Pmode, src);
12206 
12207       emit_insn (msb == 0
12208                  ? gen_zero_extendhipsi2 (reg, src)
12209                  : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
12210 
12211       return reg;
12212     }
12213 
12214   /* Down-casting from 24-bit to 16-bit throws away the high byte.  */
12215 
12216   if (as_from == ADDR_SPACE_MEMX
12217       && as_to != ADDR_SPACE_MEMX)
12218     {
12219       rtx new_src = gen_reg_rtx (Pmode);
12220 
12221       src = force_reg (PSImode, src);
12222 
12223       emit_move_insn (new_src,
12224                       simplify_gen_subreg (Pmode, src, PSImode, 0));
12225       return new_src;
12226     }
12227 
12228   return src;
12229 }
12230 
12231 
12232 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'.  */
12233 
12234 static bool
avr_addr_space_subset_p(addr_space_t subset ATTRIBUTE_UNUSED,addr_space_t superset ATTRIBUTE_UNUSED)12235 avr_addr_space_subset_p (addr_space_t subset ATTRIBUTE_UNUSED,
12236                          addr_space_t superset ATTRIBUTE_UNUSED)
12237 {
12238   /* Allow any kind of pointer mess.  */
12239 
12240   return true;
12241 }
12242 
12243 
12244 /* Implement `TARGET_CONVERT_TO_TYPE'.  */
12245 
12246 static tree
avr_convert_to_type(tree type,tree expr)12247 avr_convert_to_type (tree type, tree expr)
12248 {
12249   /* Print a diagnose for pointer conversion that changes the address
12250      space of the pointer target to a non-enclosing address space,
12251      provided -Waddr-space-convert is on.
12252 
12253      FIXME: Filter out cases where the target object is known to
12254             be located in the right memory, like in
12255 
12256                 (const __flash*) PSTR ("text")
12257 
12258             Also try to distinguish between explicit casts requested by
12259             the user and implicit casts like
12260 
12261                 void f (const __flash char*);
12262 
12263                 void g (const char *p)
12264                 {
12265                     f ((const __flash*) p);
12266                 }
12267 
12268             under the assumption that an explicit casts means that the user
12269             knows what he is doing, e.g. interface with PSTR or old style
12270             code with progmem and pgm_read_xxx.
12271   */
12272 
12273   if (avr_warn_addr_space_convert
12274       && expr != error_mark_node
12275       && POINTER_TYPE_P (type)
12276       && POINTER_TYPE_P (TREE_TYPE (expr)))
12277     {
12278       addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
12279       addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
12280 
12281       if (avr_log.progmem)
12282         avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
12283 
12284       if (as_new != ADDR_SPACE_MEMX
12285           && as_new != as_old)
12286         {
12287           location_t loc = EXPR_LOCATION (expr);
12288           const char *name_old = avr_addrspace[as_old].name;
12289           const char *name_new = avr_addrspace[as_new].name;
12290 
12291           warning (OPT_Waddr_space_convert,
12292                    "conversion from address space %qs to address space %qs",
12293                    ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
12294                    ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
12295 
12296           return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
12297         }
12298     }
12299 
12300   return NULL_TREE;
12301 }
12302 
12303 
12304 /* PR63633: The middle-end might come up with hard regs as input operands.
12305 
12306    RMASK is a bit mask representing a subset of hard registers R0...R31:
12307    Rn is an element of that set iff bit n of RMASK is set.
12308    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
12309    OP[n] has to be fixed; otherwise OP[n] is left alone.
12310 
12311    For each element of OPMASK which is a hard register overlapping RMASK,
12312    replace OP[n] with a newly created pseudo register
12313 
12314    HREG == 0:  Also emit a move insn that copies the contents of that
12315                hard register into the new pseudo.
12316 
12317    HREG != 0:  Also set HREG[n] to the hard register.  */
12318 
12319 static void
avr_fix_operands(rtx * op,rtx * hreg,unsigned opmask,unsigned rmask)12320 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
12321 {
12322   for (; opmask; opmask >>= 1, op++)
12323     {
12324       rtx reg = *op;
12325 
12326       if (hreg)
12327         *hreg = NULL_RTX;
12328 
12329       if ((opmask & 1)
12330           && REG_P (reg)
12331           && REGNO (reg) < FIRST_PSEUDO_REGISTER
12332           // This hard-reg overlaps other prohibited hard regs?
12333           && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
12334         {
12335           *op = gen_reg_rtx (GET_MODE (reg));
12336           if (hreg == NULL)
12337             emit_move_insn (*op, reg);
12338           else
12339             *hreg = reg;
12340         }
12341 
12342       if (hreg)
12343         hreg++;
12344     }
12345 }
12346 
12347 
12348 void
avr_fix_inputs(rtx * op,unsigned opmask,unsigned rmask)12349 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
12350 {
12351   avr_fix_operands (op, NULL, opmask, rmask);
12352 }
12353 
12354 
12355 /* Helper for the function below:  If bit n of MASK is set and
12356    HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
12357    Otherwise do nothing for that n.  Return TRUE.  */
12358 
12359 static bool
avr_move_fixed_operands(rtx * op,rtx * hreg,unsigned mask)12360 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
12361 {
12362   for (; mask; mask >>= 1, op++, hreg++)
12363     if ((mask & 1)
12364         && *hreg)
12365       emit_move_insn (*hreg, *op);
12366 
12367   return true;
12368 }
12369 
12370 
12371 /* PR63633: The middle-end might come up with hard regs as output operands.
12372 
12373    GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
12374    RMASK is a bit mask representing a subset of hard registers R0...R31:
12375    Rn is an element of that set iff bit n of RMASK is set.
12376    OPMASK describes a subset of OP[]:  If bit n of OPMASK is 1 then
12377    OP[n] has to be fixed; otherwise OP[n] is left alone.
12378 
12379    Emit the insn sequence as generated by GEN() with all elements of OPMASK
12380    which are hard registers overlapping RMASK replaced by newly created
12381    pseudo registers.  After the sequence has been emitted, emit insns that
12382    move the contents of respective pseudos to their hard regs.  */
12383 
12384 bool
avr_emit3_fix_outputs(rtx (* gen)(rtx,rtx,rtx),rtx * op,unsigned opmask,unsigned rmask)12385 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
12386                        unsigned opmask, unsigned rmask)
12387 {
12388   const int n = 3;
12389   rtx hreg[n];
12390 
12391   /* It is letigimate for GEN to call this function, and in order not to
12392      get self-recursive we use the following static kludge.  This is the
12393      only way not to duplicate all expanders and to avoid ugly and
12394      hard-to-maintain C-code instead of the much more appreciated RTL
12395      representation as supplied by define_expand.  */
12396   static bool lock = false;
12397 
12398   gcc_assert (opmask < (1u << n));
12399 
12400   if (lock)
12401     return false;
12402 
12403   avr_fix_operands (op, hreg, opmask, rmask);
12404 
12405   lock = true;
12406   emit_insn (gen (op[0], op[1], op[2]));
12407   lock = false;
12408 
12409   return avr_move_fixed_operands (op, hreg, opmask);
12410 }
12411 
12412 
12413 /* Worker function for movmemhi expander.
12414    XOP[0]  Destination as MEM:BLK
12415    XOP[1]  Source      "     "
12416    XOP[2]  # Bytes to copy
12417 
12418    Return TRUE  if the expansion is accomplished.
12419    Return FALSE if the operand compination is not supported.  */
12420 
12421 bool
avr_emit_movmemhi(rtx * xop)12422 avr_emit_movmemhi (rtx *xop)
12423 {
12424   HOST_WIDE_INT count;
12425   machine_mode loop_mode;
12426   addr_space_t as = MEM_ADDR_SPACE (xop[1]);
12427   rtx loop_reg, addr1, a_src, a_dest, insn, xas;
12428   rtx a_hi8 = NULL_RTX;
12429 
12430   if (avr_mem_flash_p (xop[0]))
12431     return false;
12432 
12433   if (!CONST_INT_P (xop[2]))
12434     return false;
12435 
12436   count = INTVAL (xop[2]);
12437   if (count <= 0)
12438     return false;
12439 
12440   a_src  = XEXP (xop[1], 0);
12441   a_dest = XEXP (xop[0], 0);
12442 
12443   if (PSImode == GET_MODE (a_src))
12444     {
12445       gcc_assert (as == ADDR_SPACE_MEMX);
12446 
12447       loop_mode = (count < 0x100) ? QImode : HImode;
12448       loop_reg = gen_rtx_REG (loop_mode, 24);
12449       emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
12450 
12451       addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
12452       a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
12453     }
12454   else
12455     {
12456       int segment = avr_addrspace[as].segment;
12457 
12458       if (segment
12459           && avr_n_flash > 1)
12460         {
12461           a_hi8 = GEN_INT (segment);
12462           emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
12463         }
12464       else if (!ADDR_SPACE_GENERIC_P (as))
12465         {
12466           as = ADDR_SPACE_FLASH;
12467         }
12468 
12469       addr1 = a_src;
12470 
12471       loop_mode = (count <= 0x100) ? QImode : HImode;
12472       loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
12473     }
12474 
12475   xas = GEN_INT (as);
12476 
12477   /* FIXME: Register allocator might come up with spill fails if it is left
12478         on its own.  Thus, we allocate the pointer registers by hand:
12479         Z = source address
12480         X = destination address  */
12481 
12482   emit_move_insn (lpm_addr_reg_rtx, addr1);
12483   emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
12484 
12485   /* FIXME: Register allocator does a bad job and might spill address
12486         register(s) inside the loop leading to additional move instruction
12487         to/from stack which could clobber tmp_reg.  Thus, do *not* emit
12488         load and store as separate insns.  Instead, we perform the copy
12489         by means of one monolithic insn.  */
12490 
12491   gcc_assert (TMP_REGNO == LPM_REGNO);
12492 
12493   if (as != ADDR_SPACE_MEMX)
12494     {
12495       /* Load instruction ([E]LPM or LD) is known at compile time:
12496          Do the copy-loop inline.  */
12497 
12498       rtx (*fun) (rtx, rtx, rtx)
12499         = QImode == loop_mode ? gen_movmem_qi : gen_movmem_hi;
12500 
12501       insn = fun (xas, loop_reg, loop_reg);
12502     }
12503   else
12504     {
12505       rtx (*fun) (rtx, rtx)
12506         = QImode == loop_mode ? gen_movmemx_qi : gen_movmemx_hi;
12507 
12508       emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
12509 
12510       insn = fun (xas, GEN_INT (avr_addr.rampz));
12511     }
12512 
12513   set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
12514   emit_insn (insn);
12515 
12516   return true;
12517 }
12518 
12519 
12520 /* Print assembler for movmem_qi, movmem_hi insns...
12521        $0     : Address Space
12522        $1, $2 : Loop register
12523        Z      : Source address
12524        X      : Destination address
12525 */
12526 
12527 const char*
avr_out_movmem(rtx_insn * insn ATTRIBUTE_UNUSED,rtx * op,int * plen)12528 avr_out_movmem (rtx_insn *insn ATTRIBUTE_UNUSED, rtx *op, int *plen)
12529 {
12530   addr_space_t as = (addr_space_t) INTVAL (op[0]);
12531   machine_mode loop_mode = GET_MODE (op[1]);
12532   bool sbiw_p = test_hard_reg_class (ADDW_REGS, op[1]);
12533   rtx xop[3];
12534 
12535   if (plen)
12536     *plen = 0;
12537 
12538   xop[0] = op[0];
12539   xop[1] = op[1];
12540   xop[2] = tmp_reg_rtx;
12541 
12542   /* Loop label */
12543 
12544   avr_asm_len ("0:", xop, plen, 0);
12545 
12546   /* Load with post-increment */
12547 
12548   switch (as)
12549     {
12550     default:
12551       gcc_unreachable();
12552 
12553     case ADDR_SPACE_GENERIC:
12554 
12555       avr_asm_len ("ld %2,Z+", xop, plen, 1);
12556       break;
12557 
12558     case ADDR_SPACE_FLASH:
12559 
12560       if (AVR_HAVE_LPMX)
12561         avr_asm_len ("lpm %2,Z+", xop, plen, 1);
12562       else
12563         avr_asm_len ("lpm" CR_TAB
12564                      "adiw r30,1", xop, plen, 2);
12565       break;
12566 
12567     case ADDR_SPACE_FLASH1:
12568     case ADDR_SPACE_FLASH2:
12569     case ADDR_SPACE_FLASH3:
12570     case ADDR_SPACE_FLASH4:
12571     case ADDR_SPACE_FLASH5:
12572 
12573       if (AVR_HAVE_ELPMX)
12574         avr_asm_len ("elpm %2,Z+", xop, plen, 1);
12575       else
12576         avr_asm_len ("elpm" CR_TAB
12577                      "adiw r30,1", xop, plen, 2);
12578       break;
12579     }
12580 
12581   /* Store with post-increment */
12582 
12583   avr_asm_len ("st X+,%2", xop, plen, 1);
12584 
12585   /* Decrement loop-counter and set Z-flag */
12586 
12587   if (QImode == loop_mode)
12588     {
12589       avr_asm_len ("dec %1", xop, plen, 1);
12590     }
12591   else if (sbiw_p)
12592     {
12593       avr_asm_len ("sbiw %1,1", xop, plen, 1);
12594     }
12595   else
12596     {
12597       avr_asm_len ("subi %A1,1" CR_TAB
12598                    "sbci %B1,0", xop, plen, 2);
12599     }
12600 
12601   /* Loop until zero */
12602 
12603   return avr_asm_len ("brne 0b", xop, plen, 1);
12604 }
12605 
12606 
12607 
12608 /* Helper for __builtin_avr_delay_cycles */
12609 
12610 static rtx
avr_mem_clobber(void)12611 avr_mem_clobber (void)
12612 {
12613   rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12614   MEM_VOLATILE_P (mem) = 1;
12615   return mem;
12616 }
12617 
12618 static void
avr_expand_delay_cycles(rtx operands0)12619 avr_expand_delay_cycles (rtx operands0)
12620 {
12621   unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
12622   unsigned HOST_WIDE_INT cycles_used;
12623   unsigned HOST_WIDE_INT loop_count;
12624 
12625   if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
12626     {
12627       loop_count = ((cycles - 9) / 6) + 1;
12628       cycles_used = ((loop_count - 1) * 6) + 9;
12629       emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
12630                                      avr_mem_clobber()));
12631       cycles -= cycles_used;
12632     }
12633 
12634   if (IN_RANGE (cycles, 262145, 83886081))
12635     {
12636       loop_count = ((cycles - 7) / 5) + 1;
12637       if (loop_count > 0xFFFFFF)
12638         loop_count = 0xFFFFFF;
12639       cycles_used = ((loop_count - 1) * 5) + 7;
12640       emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
12641                                      avr_mem_clobber()));
12642       cycles -= cycles_used;
12643     }
12644 
12645   if (IN_RANGE (cycles, 768, 262144))
12646     {
12647       loop_count = ((cycles - 5) / 4) + 1;
12648       if (loop_count > 0xFFFF)
12649         loop_count = 0xFFFF;
12650       cycles_used = ((loop_count - 1) * 4) + 5;
12651       emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
12652                                      avr_mem_clobber()));
12653       cycles -= cycles_used;
12654     }
12655 
12656   if (IN_RANGE (cycles, 6, 767))
12657     {
12658       loop_count = cycles / 3;
12659       if (loop_count > 255)
12660         loop_count = 255;
12661       cycles_used = loop_count * 3;
12662       emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
12663                                      avr_mem_clobber()));
12664       cycles -= cycles_used;
12665       }
12666 
12667   while (cycles >= 2)
12668     {
12669       emit_insn (gen_nopv (GEN_INT(2)));
12670       cycles -= 2;
12671     }
12672 
12673   if (cycles == 1)
12674     {
12675       emit_insn (gen_nopv (GEN_INT(1)));
12676       cycles--;
12677     }
12678 }
12679 
12680 
12681 /* Compute the image of x under f, i.e. perform   x --> f(x)    */
12682 
12683 static int
avr_map(unsigned int f,int x)12684 avr_map (unsigned int f, int x)
12685 {
12686   return x < 8 ? (f >> (4 * x)) & 0xf : 0;
12687 }
12688 
12689 
12690 /* Return some metrics of map A.  */
12691 
12692 enum
12693   {
12694     /* Number of fixed points in { 0 ... 7 } */
12695     MAP_FIXED_0_7,
12696 
12697     /* Size of preimage of non-fixed points in { 0 ... 7 } */
12698     MAP_NONFIXED_0_7,
12699 
12700     /* Mask representing the fixed points in { 0 ... 7 } */
12701     MAP_MASK_FIXED_0_7,
12702 
12703     /* Size of the preimage of { 0 ... 7 } */
12704     MAP_PREIMAGE_0_7,
12705 
12706     /* Mask that represents the preimage of { f } */
12707     MAP_MASK_PREIMAGE_F
12708   };
12709 
12710 static unsigned
avr_map_metric(unsigned int a,int mode)12711 avr_map_metric (unsigned int a, int mode)
12712 {
12713   unsigned i, metric = 0;
12714 
12715   for (i = 0; i < 8; i++)
12716     {
12717       unsigned ai = avr_map (a, i);
12718 
12719       if (mode == MAP_FIXED_0_7)
12720         metric += ai == i;
12721       else if (mode == MAP_NONFIXED_0_7)
12722         metric += ai < 8 && ai != i;
12723       else if (mode == MAP_MASK_FIXED_0_7)
12724         metric |= ((unsigned) (ai == i)) << i;
12725       else if (mode == MAP_PREIMAGE_0_7)
12726         metric += ai < 8;
12727       else if (mode == MAP_MASK_PREIMAGE_F)
12728         metric |= ((unsigned) (ai == 0xf)) << i;
12729       else
12730         gcc_unreachable();
12731     }
12732 
12733   return metric;
12734 }
12735 
12736 
12737 /* Return true if IVAL has a 0xf in its hexadecimal representation
12738    and false, otherwise.  Only nibbles 0..7 are taken into account.
12739    Used as constraint helper for C0f and Cxf.  */
12740 
12741 bool
avr_has_nibble_0xf(rtx ival)12742 avr_has_nibble_0xf (rtx ival)
12743 {
12744   unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
12745   return 0 != avr_map_metric (map, MAP_MASK_PREIMAGE_F);
12746 }
12747 
12748 
12749 /* We have a set of bits that are mapped by a function F.
12750    Try to decompose F by means of a second function G so that
12751 
12752       F = F o G^-1 o G
12753 
12754    and
12755 
12756       cost (F o G^-1) + cost (G)  <  cost (F)
12757 
12758    Example:  Suppose builtin insert_bits supplies us with the map
12759    F = 0x3210ffff.  Instead of doing 4 bit insertions to get the high
12760    nibble of the result, we can just as well rotate the bits before inserting
12761    them and use the map 0x7654ffff which is cheaper than the original map.
12762    For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff.  */
12763 
12764 typedef struct
12765 {
12766   /* tree code of binary function G */
12767   enum tree_code code;
12768 
12769   /* The constant second argument of G */
12770   int arg;
12771 
12772   /* G^-1, the inverse of G (*, arg) */
12773   unsigned ginv;
12774 
12775   /* The cost of appplying G (*, arg) */
12776   int cost;
12777 
12778   /* The composition F o G^-1 (*, arg) for some function F */
12779   unsigned int map;
12780 
12781   /* For debug purpose only */
12782   const char *str;
12783 } avr_map_op_t;
12784 
12785 static const avr_map_op_t avr_map_op[] =
12786   {
12787     { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
12788     { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
12789     { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
12790     { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
12791     { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
12792     { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
12793     { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
12794     { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
12795     { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
12796     { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
12797     { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
12798     { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
12799     { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
12800     { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
12801     { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
12802   };
12803 
12804 
12805 /* Try to decompose F as F = (F o G^-1) o G as described above.
12806    The result is a struct representing F o G^-1 and G.
12807    If result.cost < 0 then such a decomposition does not exist.  */
12808 
12809 static avr_map_op_t
avr_map_decompose(unsigned int f,const avr_map_op_t * g,bool val_const_p)12810 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
12811 {
12812   int i;
12813   bool val_used_p = 0 != avr_map_metric (f, MAP_MASK_PREIMAGE_F);
12814   avr_map_op_t f_ginv = *g;
12815   unsigned int ginv = g->ginv;
12816 
12817   f_ginv.cost = -1;
12818 
12819   /* Step 1:  Computing F o G^-1  */
12820 
12821   for (i = 7; i >= 0; i--)
12822     {
12823       int x = avr_map (f, i);
12824 
12825       if (x <= 7)
12826         {
12827           x = avr_map (ginv, x);
12828 
12829           /* The bit is no element of the image of G: no avail (cost = -1)  */
12830 
12831           if (x > 7)
12832             return f_ginv;
12833         }
12834 
12835       f_ginv.map = (f_ginv.map << 4) + x;
12836     }
12837 
12838   /* Step 2:  Compute the cost of the operations.
12839      The overall cost of doing an operation prior to the insertion is
12840       the cost of the insertion plus the cost of the operation.  */
12841 
12842   /* Step 2a:  Compute cost of F o G^-1  */
12843 
12844   if (0 == avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7))
12845     {
12846       /* The mapping consists only of fixed points and can be folded
12847          to AND/OR logic in the remainder.  Reasonable cost is 3. */
12848 
12849       f_ginv.cost = 2 + (val_used_p && !val_const_p);
12850     }
12851   else
12852     {
12853       rtx xop[4];
12854 
12855       /* Get the cost of the insn by calling the output worker with some
12856          fake values.  Mimic effect of reloading xop[3]: Unused operands
12857          are mapped to 0 and used operands are reloaded to xop[0].  */
12858 
12859       xop[0] = all_regs_rtx[24];
12860       xop[1] = gen_int_mode (f_ginv.map, SImode);
12861       xop[2] = all_regs_rtx[25];
12862       xop[3] = val_used_p ? xop[0] : const0_rtx;
12863 
12864       avr_out_insert_bits (xop, &f_ginv.cost);
12865 
12866       f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
12867     }
12868 
12869   /* Step 2b:  Add cost of G  */
12870 
12871   f_ginv.cost += g->cost;
12872 
12873   if (avr_log.builtin)
12874     avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
12875 
12876   return f_ginv;
12877 }
12878 
12879 
12880 /* Insert bits from XOP[1] into XOP[0] according to MAP.
12881    XOP[0] and XOP[1] don't overlap.
12882    If FIXP_P = true:  Move all bits according to MAP using BLD/BST sequences.
12883    If FIXP_P = false: Just move the bit if its position in the destination
12884    is different to its source position.  */
12885 
12886 static void
avr_move_bits(rtx * xop,unsigned int map,bool fixp_p,int * plen)12887 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
12888 {
12889   int bit_dest, b;
12890 
12891   /* T-flag contains this bit of the source, i.e. of XOP[1]  */
12892   int t_bit_src = -1;
12893 
12894   /* We order the operations according to the requested source bit b.  */
12895 
12896   for (b = 0; b < 8; b++)
12897     for (bit_dest = 0; bit_dest < 8; bit_dest++)
12898       {
12899         int bit_src = avr_map (map, bit_dest);
12900 
12901         if (b != bit_src
12902             || bit_src >= 8
12903             /* Same position: No need to copy as requested by FIXP_P.  */
12904             || (bit_dest == bit_src && !fixp_p))
12905           continue;
12906 
12907         if (t_bit_src != bit_src)
12908           {
12909             /* Source bit is not yet in T: Store it to T.  */
12910 
12911             t_bit_src = bit_src;
12912 
12913             xop[3] = GEN_INT (bit_src);
12914             avr_asm_len ("bst %T1%T3", xop, plen, 1);
12915           }
12916 
12917         /* Load destination bit with T.  */
12918 
12919         xop[3] = GEN_INT (bit_dest);
12920         avr_asm_len ("bld %T0%T3", xop, plen, 1);
12921       }
12922 }
12923 
12924 
12925 /* PLEN == 0: Print assembler code for `insert_bits'.
12926    PLEN != 0: Compute code length in bytes.
12927 
12928    OP[0]:  Result
12929    OP[1]:  The mapping composed of nibbles. If nibble no. N is
12930            0:   Bit N of result is copied from bit OP[2].0
12931            ...  ...
12932            7:   Bit N of result is copied from bit OP[2].7
12933            0xf: Bit N of result is copied from bit OP[3].N
12934    OP[2]:  Bits to be inserted
12935    OP[3]:  Target value  */
12936 
12937 const char*
avr_out_insert_bits(rtx * op,int * plen)12938 avr_out_insert_bits (rtx *op, int *plen)
12939 {
12940   unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
12941   unsigned mask_fixed;
12942   bool fixp_p = true;
12943   rtx xop[4];
12944 
12945   xop[0] = op[0];
12946   xop[1] = op[2];
12947   xop[2] = op[3];
12948 
12949   gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
12950 
12951   if (plen)
12952     *plen = 0;
12953   else if (flag_print_asm_name)
12954     fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
12955 
12956   /* If MAP has fixed points it might be better to initialize the result
12957      with the bits to be inserted instead of moving all bits by hand.  */
12958 
12959   mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
12960 
12961   if (REGNO (xop[0]) == REGNO (xop[1]))
12962     {
12963       /* Avoid early-clobber conflicts */
12964 
12965       avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
12966       xop[1] = tmp_reg_rtx;
12967       fixp_p = false;
12968     }
12969 
12970   if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
12971     {
12972       /* XOP[2] is used and reloaded to XOP[0] already */
12973 
12974       int n_fix = 0, n_nofix = 0;
12975 
12976       gcc_assert (REG_P (xop[2]));
12977 
12978       /* Get the code size of the bit insertions; once with all bits
12979          moved and once with fixed points omitted.  */
12980 
12981       avr_move_bits (xop, map, true, &n_fix);
12982       avr_move_bits (xop, map, false, &n_nofix);
12983 
12984       if (fixp_p && n_fix - n_nofix > 3)
12985         {
12986           xop[3] = gen_int_mode (~mask_fixed, QImode);
12987 
12988           avr_asm_len ("eor %0,%1"   CR_TAB
12989                        "andi %0,%3"  CR_TAB
12990                        "eor %0,%1", xop, plen, 3);
12991           fixp_p = false;
12992         }
12993     }
12994   else
12995     {
12996       /* XOP[2] is unused */
12997 
12998       if (fixp_p && mask_fixed)
12999         {
13000           avr_asm_len ("mov %0,%1", xop, plen, 1);
13001           fixp_p = false;
13002         }
13003     }
13004 
13005   /* Move/insert remaining bits.  */
13006 
13007   avr_move_bits (xop, map, fixp_p, plen);
13008 
13009   return "";
13010 }
13011 
13012 
13013 /* IDs for all the AVR builtins.  */
13014 
13015 enum avr_builtin_id
13016   {
13017 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)  \
13018     AVR_BUILTIN_ ## NAME,
13019 #include "builtins.def"
13020 #undef DEF_BUILTIN
13021 
13022     AVR_BUILTIN_COUNT
13023   };
13024 
13025 struct GTY(()) avr_builtin_description
13026 {
13027   enum insn_code icode;
13028   int n_args;
13029   tree fndecl;
13030 };
13031 
13032 
13033 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
13034    that a built-in's ID can be used to access the built-in by means of
13035    avr_bdesc[ID]  */
13036 
13037 static GTY(()) struct avr_builtin_description
13038 avr_bdesc[AVR_BUILTIN_COUNT] =
13039   {
13040 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME)         \
13041     { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
13042 #include "builtins.def"
13043 #undef DEF_BUILTIN
13044   };
13045 
13046 
13047 /* Implement `TARGET_BUILTIN_DECL'.  */
13048 
13049 static tree
avr_builtin_decl(unsigned id,bool initialize_p ATTRIBUTE_UNUSED)13050 avr_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
13051 {
13052   if (id < AVR_BUILTIN_COUNT)
13053     return avr_bdesc[id].fndecl;
13054 
13055   return error_mark_node;
13056 }
13057 
13058 
13059 static void
avr_init_builtin_int24(void)13060 avr_init_builtin_int24 (void)
13061 {
13062   tree int24_type  = make_signed_type (GET_MODE_BITSIZE (PSImode));
13063   tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
13064 
13065   lang_hooks.types.register_builtin_type (int24_type, "__int24");
13066   lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
13067 }
13068 
13069 
13070 /* Implement `TARGET_INIT_BUILTINS' */
13071 /* Set up all builtin functions for this target.  */
13072 
13073 static void
avr_init_builtins(void)13074 avr_init_builtins (void)
13075 {
13076   tree void_ftype_void
13077     = build_function_type_list (void_type_node, NULL_TREE);
13078   tree uchar_ftype_uchar
13079     = build_function_type_list (unsigned_char_type_node,
13080                                 unsigned_char_type_node,
13081                                 NULL_TREE);
13082   tree uint_ftype_uchar_uchar
13083     = build_function_type_list (unsigned_type_node,
13084                                 unsigned_char_type_node,
13085                                 unsigned_char_type_node,
13086                                 NULL_TREE);
13087   tree int_ftype_char_char
13088     = build_function_type_list (integer_type_node,
13089                                 char_type_node,
13090                                 char_type_node,
13091                                 NULL_TREE);
13092   tree int_ftype_char_uchar
13093     = build_function_type_list (integer_type_node,
13094                                 char_type_node,
13095                                 unsigned_char_type_node,
13096                                 NULL_TREE);
13097   tree void_ftype_ulong
13098     = build_function_type_list (void_type_node,
13099                                 long_unsigned_type_node,
13100                                 NULL_TREE);
13101 
13102   tree uchar_ftype_ulong_uchar_uchar
13103     = build_function_type_list (unsigned_char_type_node,
13104                                 long_unsigned_type_node,
13105                                 unsigned_char_type_node,
13106                                 unsigned_char_type_node,
13107                                 NULL_TREE);
13108 
13109   tree const_memx_void_node
13110     = build_qualified_type (void_type_node,
13111                             TYPE_QUAL_CONST
13112                             | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
13113 
13114   tree const_memx_ptr_type_node
13115     = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
13116 
13117   tree char_ftype_const_memx_ptr
13118     = build_function_type_list (char_type_node,
13119                                 const_memx_ptr_type_node,
13120                                 NULL);
13121 
13122 #define ITYP(T)                                                         \
13123   lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
13124 
13125 #define FX_FTYPE_FX(fx)                                                 \
13126   tree fx##r_ftype_##fx##r                                              \
13127     = build_function_type_list (node_##fx##r, node_##fx##r, NULL);      \
13128   tree fx##k_ftype_##fx##k                                              \
13129     = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
13130 
13131 #define FX_FTYPE_FX_INT(fx)                                             \
13132   tree fx##r_ftype_##fx##r_int                                          \
13133     = build_function_type_list (node_##fx##r, node_##fx##r,             \
13134                                 integer_type_node, NULL);               \
13135   tree fx##k_ftype_##fx##k_int                                          \
13136     = build_function_type_list (node_##fx##k, node_##fx##k,             \
13137                                 integer_type_node, NULL)
13138 
13139 #define INT_FTYPE_FX(fx)                                                \
13140   tree int_ftype_##fx##r                                                \
13141     = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
13142   tree int_ftype_##fx##k                                                \
13143     = build_function_type_list (integer_type_node, node_##fx##k, NULL)
13144 
13145 #define INTX_FTYPE_FX(fx)                                               \
13146   tree int##fx##r_ftype_##fx##r                                         \
13147     = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
13148   tree int##fx##k_ftype_##fx##k                                         \
13149     = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
13150 
13151 #define FX_FTYPE_INTX(fx)                                               \
13152   tree fx##r_ftype_int##fx##r                                           \
13153     = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
13154   tree fx##k_ftype_int##fx##k                                           \
13155     = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
13156 
13157   tree node_hr = short_fract_type_node;
13158   tree node_nr = fract_type_node;
13159   tree node_lr = long_fract_type_node;
13160   tree node_llr = long_long_fract_type_node;
13161 
13162   tree node_uhr = unsigned_short_fract_type_node;
13163   tree node_unr = unsigned_fract_type_node;
13164   tree node_ulr = unsigned_long_fract_type_node;
13165   tree node_ullr = unsigned_long_long_fract_type_node;
13166 
13167   tree node_hk = short_accum_type_node;
13168   tree node_nk = accum_type_node;
13169   tree node_lk = long_accum_type_node;
13170   tree node_llk = long_long_accum_type_node;
13171 
13172   tree node_uhk = unsigned_short_accum_type_node;
13173   tree node_unk = unsigned_accum_type_node;
13174   tree node_ulk = unsigned_long_accum_type_node;
13175   tree node_ullk = unsigned_long_long_accum_type_node;
13176 
13177 
13178   /* For absfx builtins.  */
13179 
13180   FX_FTYPE_FX (h);
13181   FX_FTYPE_FX (n);
13182   FX_FTYPE_FX (l);
13183   FX_FTYPE_FX (ll);
13184 
13185   /* For roundfx builtins.  */
13186 
13187   FX_FTYPE_FX_INT (h);
13188   FX_FTYPE_FX_INT (n);
13189   FX_FTYPE_FX_INT (l);
13190   FX_FTYPE_FX_INT (ll);
13191 
13192   FX_FTYPE_FX_INT (uh);
13193   FX_FTYPE_FX_INT (un);
13194   FX_FTYPE_FX_INT (ul);
13195   FX_FTYPE_FX_INT (ull);
13196 
13197   /* For countlsfx builtins.  */
13198 
13199   INT_FTYPE_FX (h);
13200   INT_FTYPE_FX (n);
13201   INT_FTYPE_FX (l);
13202   INT_FTYPE_FX (ll);
13203 
13204   INT_FTYPE_FX (uh);
13205   INT_FTYPE_FX (un);
13206   INT_FTYPE_FX (ul);
13207   INT_FTYPE_FX (ull);
13208 
13209   /* For bitsfx builtins.  */
13210 
13211   INTX_FTYPE_FX (h);
13212   INTX_FTYPE_FX (n);
13213   INTX_FTYPE_FX (l);
13214   INTX_FTYPE_FX (ll);
13215 
13216   INTX_FTYPE_FX (uh);
13217   INTX_FTYPE_FX (un);
13218   INTX_FTYPE_FX (ul);
13219   INTX_FTYPE_FX (ull);
13220 
13221   /* For fxbits builtins.  */
13222 
13223   FX_FTYPE_INTX (h);
13224   FX_FTYPE_INTX (n);
13225   FX_FTYPE_INTX (l);
13226   FX_FTYPE_INTX (ll);
13227 
13228   FX_FTYPE_INTX (uh);
13229   FX_FTYPE_INTX (un);
13230   FX_FTYPE_INTX (ul);
13231   FX_FTYPE_INTX (ull);
13232 
13233 
13234 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME)                  \
13235   {                                                                     \
13236     int id = AVR_BUILTIN_ ## NAME;                                      \
13237     const char *Name = "__builtin_avr_" #NAME;                          \
13238     char *name = (char*) alloca (1 + strlen (Name));                    \
13239                                                                         \
13240     gcc_assert (id < AVR_BUILTIN_COUNT);                                \
13241     avr_bdesc[id].fndecl                                                \
13242       = add_builtin_function (avr_tolower (name, Name), TYPE, id,       \
13243                               BUILT_IN_MD, LIBNAME, NULL_TREE);         \
13244   }
13245 #include "builtins.def"
13246 #undef DEF_BUILTIN
13247 
13248   avr_init_builtin_int24 ();
13249 }
13250 
13251 
13252 /* Subroutine of avr_expand_builtin to expand vanilla builtins
13253    with non-void result and 1 ... 3 arguments.  */
13254 
13255 static rtx
avr_default_expand_builtin(enum insn_code icode,tree exp,rtx target)13256 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
13257 {
13258   rtx pat, xop[3];
13259   int n, n_args = call_expr_nargs (exp);
13260   machine_mode tmode = insn_data[icode].operand[0].mode;
13261 
13262   gcc_assert (n_args >= 1 && n_args <= 3);
13263 
13264   if (target == NULL_RTX
13265       || GET_MODE (target) != tmode
13266       || !insn_data[icode].operand[0].predicate (target, tmode))
13267     {
13268       target = gen_reg_rtx (tmode);
13269     }
13270 
13271   for (n = 0; n < n_args; n++)
13272     {
13273       tree arg = CALL_EXPR_ARG (exp, n);
13274       rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13275       machine_mode opmode = GET_MODE (op);
13276       machine_mode mode = insn_data[icode].operand[n+1].mode;
13277 
13278       if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
13279         {
13280           opmode = HImode;
13281           op = gen_lowpart (HImode, op);
13282         }
13283 
13284       /* In case the insn wants input operands in modes different from
13285          the result, abort.  */
13286 
13287       gcc_assert (opmode == mode || opmode == VOIDmode);
13288 
13289       if (!insn_data[icode].operand[n+1].predicate (op, mode))
13290         op = copy_to_mode_reg (mode, op);
13291 
13292       xop[n] = op;
13293     }
13294 
13295   switch (n_args)
13296     {
13297     case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
13298     case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
13299     case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
13300 
13301     default:
13302       gcc_unreachable();
13303     }
13304 
13305   if (pat == NULL_RTX)
13306     return NULL_RTX;
13307 
13308   emit_insn (pat);
13309 
13310   return target;
13311 }
13312 
13313 
13314 /* Implement `TARGET_EXPAND_BUILTIN'.  */
13315 /* Expand an expression EXP that calls a built-in function,
13316    with result going to TARGET if that's convenient
13317    (and in mode MODE if that's convenient).
13318    SUBTARGET may be used as the target for computing one of EXP's operands.
13319    IGNORE is nonzero if the value is to be ignored.  */
13320 
13321 static rtx
avr_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,machine_mode mode ATTRIBUTE_UNUSED,int ignore)13322 avr_expand_builtin (tree exp, rtx target,
13323                     rtx subtarget ATTRIBUTE_UNUSED,
13324                     machine_mode mode ATTRIBUTE_UNUSED,
13325                     int ignore)
13326 {
13327   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
13328   const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
13329   unsigned int id = DECL_FUNCTION_CODE (fndecl);
13330   const struct avr_builtin_description *d = &avr_bdesc[id];
13331   tree arg0;
13332   rtx op0;
13333 
13334   gcc_assert (id < AVR_BUILTIN_COUNT);
13335 
13336   switch (id)
13337     {
13338     case AVR_BUILTIN_NOP:
13339       emit_insn (gen_nopv (GEN_INT(1)));
13340       return 0;
13341 
13342     case AVR_BUILTIN_DELAY_CYCLES:
13343       {
13344         arg0 = CALL_EXPR_ARG (exp, 0);
13345         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13346 
13347         if (!CONST_INT_P (op0))
13348           error ("%s expects a compile time integer constant", bname);
13349         else
13350           avr_expand_delay_cycles (op0);
13351 
13352         return NULL_RTX;
13353       }
13354 
13355     case AVR_BUILTIN_INSERT_BITS:
13356       {
13357         arg0 = CALL_EXPR_ARG (exp, 0);
13358         op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
13359 
13360         if (!CONST_INT_P (op0))
13361           {
13362             error ("%s expects a compile time long integer constant"
13363                    " as first argument", bname);
13364             return target;
13365           }
13366 
13367         break;
13368       }
13369 
13370     case AVR_BUILTIN_ROUNDHR:   case AVR_BUILTIN_ROUNDUHR:
13371     case AVR_BUILTIN_ROUNDR:    case AVR_BUILTIN_ROUNDUR:
13372     case AVR_BUILTIN_ROUNDLR:   case AVR_BUILTIN_ROUNDULR:
13373     case AVR_BUILTIN_ROUNDLLR:  case AVR_BUILTIN_ROUNDULLR:
13374 
13375     case AVR_BUILTIN_ROUNDHK:   case AVR_BUILTIN_ROUNDUHK:
13376     case AVR_BUILTIN_ROUNDK:    case AVR_BUILTIN_ROUNDUK:
13377     case AVR_BUILTIN_ROUNDLK:   case AVR_BUILTIN_ROUNDULK:
13378     case AVR_BUILTIN_ROUNDLLK:  case AVR_BUILTIN_ROUNDULLK:
13379 
13380       /* Warn about odd rounding.  Rounding points >= FBIT will have
13381          no effect.  */
13382 
13383       if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
13384         break;
13385 
13386       int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
13387 
13388       if (rbit >= (int) GET_MODE_FBIT (mode))
13389         {
13390           warning (OPT_Wextra, "rounding to %d bits has no effect for "
13391                    "fixed-point value with %d fractional bits",
13392                    rbit, GET_MODE_FBIT (mode));
13393 
13394           return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
13395                               EXPAND_NORMAL);
13396         }
13397       else if (rbit <= - (int) GET_MODE_IBIT (mode))
13398         {
13399           warning (0, "rounding result will always be 0");
13400           return CONST0_RTX (mode);
13401         }
13402 
13403       /* The rounding points RP satisfies now:  -IBIT < RP < FBIT.
13404 
13405          TR 18037 only specifies results for  RP > 0.  However, the
13406          remaining cases of  -IBIT < RP <= 0  can easily be supported
13407          without any additional overhead.  */
13408 
13409       break; /* round */
13410     }
13411 
13412   /* No fold found and no insn:  Call support function from libgcc.  */
13413 
13414   if (d->icode == CODE_FOR_nothing
13415       && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
13416     {
13417       return expand_call (exp, target, ignore);
13418     }
13419 
13420   /* No special treatment needed: vanilla expand.  */
13421 
13422   gcc_assert (d->icode != CODE_FOR_nothing);
13423   gcc_assert (d->n_args == call_expr_nargs (exp));
13424 
13425   if (d->n_args == 0)
13426     {
13427       emit_insn ((GEN_FCN (d->icode)) (target));
13428       return NULL_RTX;
13429     }
13430 
13431   return avr_default_expand_builtin (d->icode, exp, target);
13432 }
13433 
13434 
13435 /* Helper for `avr_fold_builtin' that folds  absfx (FIXED_CST).  */
13436 
13437 static tree
avr_fold_absfx(tree tval)13438 avr_fold_absfx (tree tval)
13439 {
13440   if (FIXED_CST != TREE_CODE (tval))
13441     return NULL_TREE;
13442 
13443   /* Our fixed-points have no padding:  Use double_int payload directly.  */
13444 
13445   FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
13446   unsigned int bits = GET_MODE_BITSIZE (fval.mode);
13447   double_int ival = fval.data.sext (bits);
13448 
13449   if (!ival.is_negative())
13450     return tval;
13451 
13452   /* ISO/IEC TR 18037, 7.18a.6.2:  The absfx functions are saturating.  */
13453 
13454   fval.data = (ival == double_int::min_value (bits, false).sext (bits))
13455     ? double_int::max_value (bits, false)
13456     : -ival;
13457 
13458   return build_fixed (TREE_TYPE (tval), fval);
13459 }
13460 
13461 
13462 /* Implement `TARGET_FOLD_BUILTIN'.  */
13463 
13464 static tree
avr_fold_builtin(tree fndecl,int n_args ATTRIBUTE_UNUSED,tree * arg,bool ignore ATTRIBUTE_UNUSED)13465 avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
13466                   bool ignore ATTRIBUTE_UNUSED)
13467 {
13468   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
13469   tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
13470 
13471   if (!optimize)
13472     return NULL_TREE;
13473 
13474   switch (fcode)
13475     {
13476     default:
13477       break;
13478 
13479     case AVR_BUILTIN_SWAP:
13480       {
13481         return fold_build2 (LROTATE_EXPR, val_type, arg[0],
13482                             build_int_cst (val_type, 4));
13483       }
13484 
13485     case AVR_BUILTIN_ABSHR:
13486     case AVR_BUILTIN_ABSR:
13487     case AVR_BUILTIN_ABSLR:
13488     case AVR_BUILTIN_ABSLLR:
13489 
13490     case AVR_BUILTIN_ABSHK:
13491     case AVR_BUILTIN_ABSK:
13492     case AVR_BUILTIN_ABSLK:
13493     case AVR_BUILTIN_ABSLLK:
13494       /* GCC is not good with folding ABS for fixed-point.  Do it by hand.  */
13495 
13496       return avr_fold_absfx (arg[0]);
13497 
13498     case AVR_BUILTIN_BITSHR:    case AVR_BUILTIN_HRBITS:
13499     case AVR_BUILTIN_BITSHK:    case AVR_BUILTIN_HKBITS:
13500     case AVR_BUILTIN_BITSUHR:   case AVR_BUILTIN_UHRBITS:
13501     case AVR_BUILTIN_BITSUHK:   case AVR_BUILTIN_UHKBITS:
13502 
13503     case AVR_BUILTIN_BITSR:     case AVR_BUILTIN_RBITS:
13504     case AVR_BUILTIN_BITSK:     case AVR_BUILTIN_KBITS:
13505     case AVR_BUILTIN_BITSUR:    case AVR_BUILTIN_URBITS:
13506     case AVR_BUILTIN_BITSUK:    case AVR_BUILTIN_UKBITS:
13507 
13508     case AVR_BUILTIN_BITSLR:    case AVR_BUILTIN_LRBITS:
13509     case AVR_BUILTIN_BITSLK:    case AVR_BUILTIN_LKBITS:
13510     case AVR_BUILTIN_BITSULR:   case AVR_BUILTIN_ULRBITS:
13511     case AVR_BUILTIN_BITSULK:   case AVR_BUILTIN_ULKBITS:
13512 
13513     case AVR_BUILTIN_BITSLLR:   case AVR_BUILTIN_LLRBITS:
13514     case AVR_BUILTIN_BITSLLK:   case AVR_BUILTIN_LLKBITS:
13515     case AVR_BUILTIN_BITSULLR:  case AVR_BUILTIN_ULLRBITS:
13516     case AVR_BUILTIN_BITSULLK:  case AVR_BUILTIN_ULLKBITS:
13517 
13518       gcc_assert (TYPE_PRECISION (val_type)
13519                   == TYPE_PRECISION (TREE_TYPE (arg[0])));
13520 
13521       return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
13522 
13523     case AVR_BUILTIN_INSERT_BITS:
13524       {
13525         tree tbits = arg[1];
13526         tree tval = arg[2];
13527         tree tmap;
13528         tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
13529         unsigned int map;
13530         bool changed = false;
13531         unsigned i;
13532         avr_map_op_t best_g;
13533 
13534         if (TREE_CODE (arg[0]) != INTEGER_CST)
13535           {
13536             /* No constant as first argument: Don't fold this and run into
13537                error in avr_expand_builtin.  */
13538 
13539             break;
13540           }
13541 
13542         tmap = wide_int_to_tree (map_type, arg[0]);
13543         map = TREE_INT_CST_LOW (tmap);
13544 
13545         if (TREE_CODE (tval) != INTEGER_CST
13546             && 0 == avr_map_metric (map, MAP_MASK_PREIMAGE_F))
13547           {
13548             /* There are no F in the map, i.e. 3rd operand is unused.
13549                Replace that argument with some constant to render
13550                respective input unused.  */
13551 
13552             tval = build_int_cst (val_type, 0);
13553             changed = true;
13554           }
13555 
13556         if (TREE_CODE (tbits) != INTEGER_CST
13557             && 0 == avr_map_metric (map, MAP_PREIMAGE_0_7))
13558           {
13559             /* Similar for the bits to be inserted. If they are unused,
13560                we can just as well pass 0.  */
13561 
13562             tbits = build_int_cst (val_type, 0);
13563           }
13564 
13565         if (TREE_CODE (tbits) == INTEGER_CST)
13566           {
13567             /* Inserting bits known at compile time is easy and can be
13568                performed by AND and OR with appropriate masks.  */
13569 
13570             int bits = TREE_INT_CST_LOW (tbits);
13571             int mask_ior = 0, mask_and = 0xff;
13572 
13573             for (i = 0; i < 8; i++)
13574               {
13575                 int mi = avr_map (map, i);
13576 
13577                 if (mi < 8)
13578                   {
13579                     if (bits & (1 << mi))     mask_ior |=  (1 << i);
13580                     else                      mask_and &= ~(1 << i);
13581                   }
13582               }
13583 
13584             tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
13585                                 build_int_cst (val_type, mask_ior));
13586             return fold_build2 (BIT_AND_EXPR, val_type, tval,
13587                                 build_int_cst (val_type, mask_and));
13588           }
13589 
13590         if (changed)
13591           return build_call_expr (fndecl, 3, tmap, tbits, tval);
13592 
13593         /* If bits don't change their position we can use vanilla logic
13594            to merge the two arguments.  */
13595 
13596         if (0 == avr_map_metric (map, MAP_NONFIXED_0_7))
13597           {
13598             int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
13599             tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
13600 
13601             tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
13602             tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
13603             return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
13604           }
13605 
13606         /* Try to decomposing map to reduce overall cost.  */
13607 
13608         if (avr_log.builtin)
13609           avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
13610 
13611         best_g = avr_map_op[0];
13612         best_g.cost = 1000;
13613 
13614         for (i = 0; i < sizeof (avr_map_op) / sizeof (*avr_map_op); i++)
13615           {
13616             avr_map_op_t g
13617               = avr_map_decompose (map, avr_map_op + i,
13618                                    TREE_CODE (tval) == INTEGER_CST);
13619 
13620             if (g.cost >= 0 && g.cost < best_g.cost)
13621               best_g = g;
13622           }
13623 
13624         if (avr_log.builtin)
13625           avr_edump ("\n");
13626 
13627         if (best_g.arg == 0)
13628           /* No optimization found */
13629           break;
13630 
13631         /* Apply operation G to the 2nd argument.  */
13632 
13633         if (avr_log.builtin)
13634           avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
13635                      best_g.str, best_g.arg, best_g.map, best_g.cost);
13636 
13637         /* Do right-shifts arithmetically: They copy the MSB instead of
13638            shifting in a non-usable value (0) as with logic right-shift.  */
13639 
13640         tbits = fold_convert (signed_char_type_node, tbits);
13641         tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
13642                              build_int_cst (val_type, best_g.arg));
13643         tbits = fold_convert (val_type, tbits);
13644 
13645         /* Use map o G^-1 instead of original map to undo the effect of G.  */
13646 
13647         tmap = wide_int_to_tree (map_type, best_g.map);
13648 
13649         return build_call_expr (fndecl, 3, tmap, tbits, tval);
13650       } /* AVR_BUILTIN_INSERT_BITS */
13651     }
13652 
13653   return NULL_TREE;
13654 }
13655 
13656 
13657 
13658 /* Initialize the GCC target structure.  */
13659 
13660 #undef  TARGET_ASM_ALIGNED_HI_OP
13661 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
13662 #undef  TARGET_ASM_ALIGNED_SI_OP
13663 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
13664 #undef  TARGET_ASM_UNALIGNED_HI_OP
13665 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
13666 #undef  TARGET_ASM_UNALIGNED_SI_OP
13667 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
13668 #undef  TARGET_ASM_INTEGER
13669 #define TARGET_ASM_INTEGER avr_assemble_integer
13670 #undef  TARGET_ASM_FILE_START
13671 #define TARGET_ASM_FILE_START avr_file_start
13672 #undef  TARGET_ASM_FILE_END
13673 #define TARGET_ASM_FILE_END avr_file_end
13674 
13675 #undef  TARGET_ASM_FUNCTION_END_PROLOGUE
13676 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
13677 #undef  TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
13678 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
13679 
13680 #undef  TARGET_FUNCTION_VALUE
13681 #define TARGET_FUNCTION_VALUE avr_function_value
13682 #undef  TARGET_LIBCALL_VALUE
13683 #define TARGET_LIBCALL_VALUE avr_libcall_value
13684 #undef  TARGET_FUNCTION_VALUE_REGNO_P
13685 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
13686 
13687 #undef  TARGET_ATTRIBUTE_TABLE
13688 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
13689 #undef  TARGET_INSERT_ATTRIBUTES
13690 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
13691 #undef  TARGET_SECTION_TYPE_FLAGS
13692 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
13693 
13694 #undef  TARGET_ASM_NAMED_SECTION
13695 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
13696 #undef  TARGET_ASM_INIT_SECTIONS
13697 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
13698 #undef  TARGET_ENCODE_SECTION_INFO
13699 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
13700 #undef  TARGET_ASM_SELECT_SECTION
13701 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
13702 
13703 #undef  TARGET_REGISTER_MOVE_COST
13704 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
13705 #undef  TARGET_MEMORY_MOVE_COST
13706 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
13707 #undef  TARGET_RTX_COSTS
13708 #define TARGET_RTX_COSTS avr_rtx_costs
13709 #undef  TARGET_ADDRESS_COST
13710 #define TARGET_ADDRESS_COST avr_address_cost
13711 #undef  TARGET_MACHINE_DEPENDENT_REORG
13712 #define TARGET_MACHINE_DEPENDENT_REORG avr_reorg
13713 #undef  TARGET_FUNCTION_ARG
13714 #define TARGET_FUNCTION_ARG avr_function_arg
13715 #undef  TARGET_FUNCTION_ARG_ADVANCE
13716 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
13717 
13718 #undef  TARGET_SET_CURRENT_FUNCTION
13719 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
13720 
13721 #undef  TARGET_RETURN_IN_MEMORY
13722 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
13723 
13724 #undef  TARGET_STRICT_ARGUMENT_NAMING
13725 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
13726 
13727 #undef  TARGET_BUILTIN_SETJMP_FRAME_VALUE
13728 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE avr_builtin_setjmp_frame_value
13729 
13730 #undef TARGET_CONDITIONAL_REGISTER_USAGE
13731 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
13732 
13733 #undef  TARGET_HARD_REGNO_SCRATCH_OK
13734 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
13735 #undef  TARGET_CASE_VALUES_THRESHOLD
13736 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
13737 
13738 #undef  TARGET_FRAME_POINTER_REQUIRED
13739 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
13740 #undef  TARGET_CAN_ELIMINATE
13741 #define TARGET_CAN_ELIMINATE avr_can_eliminate
13742 
13743 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
13744 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
13745 
13746 #undef TARGET_WARN_FUNC_RETURN
13747 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
13748 
13749 #undef  TARGET_CLASS_LIKELY_SPILLED_P
13750 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
13751 
13752 #undef  TARGET_OPTION_OVERRIDE
13753 #define TARGET_OPTION_OVERRIDE avr_option_override
13754 
13755 #undef  TARGET_CANNOT_MODIFY_JUMPS_P
13756 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
13757 
13758 #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
13759 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
13760 
13761 #undef  TARGET_INIT_BUILTINS
13762 #define TARGET_INIT_BUILTINS avr_init_builtins
13763 
13764 #undef  TARGET_BUILTIN_DECL
13765 #define TARGET_BUILTIN_DECL avr_builtin_decl
13766 
13767 #undef  TARGET_EXPAND_BUILTIN
13768 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
13769 
13770 #undef  TARGET_FOLD_BUILTIN
13771 #define TARGET_FOLD_BUILTIN avr_fold_builtin
13772 
13773 #undef  TARGET_SCALAR_MODE_SUPPORTED_P
13774 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
13775 
13776 #undef  TARGET_BUILD_BUILTIN_VA_LIST
13777 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
13778 
13779 #undef  TARGET_FIXED_POINT_SUPPORTED_P
13780 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
13781 
13782 #undef  TARGET_CONVERT_TO_TYPE
13783 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
13784 
13785 #undef  TARGET_ADDR_SPACE_SUBSET_P
13786 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
13787 
13788 #undef  TARGET_ADDR_SPACE_CONVERT
13789 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
13790 
13791 #undef  TARGET_ADDR_SPACE_ADDRESS_MODE
13792 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
13793 
13794 #undef  TARGET_ADDR_SPACE_POINTER_MODE
13795 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
13796 
13797 #undef  TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
13798 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P  \
13799   avr_addr_space_legitimate_address_p
13800 
13801 #undef  TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
13802 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
13803 
13804 #undef  TARGET_MODE_DEPENDENT_ADDRESS_P
13805 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
13806 
13807 #undef  TARGET_SECONDARY_RELOAD
13808 #define TARGET_SECONDARY_RELOAD avr_secondary_reload
13809 
13810 #undef  TARGET_PRINT_OPERAND
13811 #define TARGET_PRINT_OPERAND avr_print_operand
13812 #undef  TARGET_PRINT_OPERAND_ADDRESS
13813 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
13814 #undef  TARGET_PRINT_OPERAND_PUNCT_VALID_P
13815 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
13816 
13817 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
13818 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
13819   avr_use_by_pieces_infrastructure_p
13820 
13821 struct gcc_target targetm = TARGET_INITIALIZER;
13822 
13823 
13824 #include "gt-avr.h"
13825