RISC-V: Add testcases for unsigned .SAT_SUB vector form 10
[official-gcc.git] / gcc / config / avr / avr.cc
blob74924ab0565779c597d10ee880548640a9dd59ae
1 /* Subroutines for insn-output.cc for ATMEL AVR micro controllers
2 Copyright (C) 1998-2024 Free Software Foundation, Inc.
3 Contributed by Denis Chertykov (chertykov@gmail.com)
5 This file is part of GCC.
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.
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.
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/>. */
21 #define IN_TARGET_CODE 1
23 #include "config.h"
24 #include "system.h"
25 #include "intl.h"
26 #include "coretypes.h"
27 #include "backend.h"
28 #include "target.h"
29 #include "rtl.h"
30 #include "tree.h"
31 #include "stringpool.h"
32 #include "attribs.h"
33 #include "cgraph.h"
34 #include "c-family/c-common.h"
35 #include "cfghooks.h"
36 #include "df.h"
37 #include "memmodel.h"
38 #include "tm_p.h"
39 #include "optabs.h"
40 #include "regs.h"
41 #include "emit-rtl.h"
42 #include "recog.h"
43 #include "conditions.h"
44 #include "insn-attr.h"
45 #include "reload.h"
46 #include "varasm.h"
47 #include "calls.h"
48 #include "stor-layout.h"
49 #include "output.h"
50 #include "explow.h"
51 #include "expr.h"
52 #include "langhooks.h"
53 #include "cfgrtl.h"
54 #include "builtins.h"
55 #include "context.h"
56 #include "tree-pass.h"
57 #include "print-rtl.h"
58 #include "rtl-iter.h"
60 /* This file should be included last. */
61 #include "target-def.h"
63 /* Maximal allowed offset for an address in the LD command */
64 #define MAX_LD_OFFSET(MODE) (64 - (signed)GET_MODE_SIZE (MODE))
66 /* The 4 bits starting at SECTION_MACH_DEP are reserved to store the
67 address space where data is to be located.
68 As the only non-generic address spaces are all located in flash,
69 this can be used to test if data shall go into some .progmem* section.
70 This must be the rightmost field of machine dependent section flags. */
71 #define AVR_SECTION_PROGMEM (0xf * SECTION_MACH_DEP)
73 /* Similar 4-bit region for SYMBOL_REF_FLAGS. */
74 #define AVR_SYMBOL_FLAG_PROGMEM (0xf * SYMBOL_FLAG_MACH_DEP)
76 /* Similar 4-bit region in SYMBOL_REF_FLAGS:
77 Set address-space AS in SYMBOL_REF_FLAGS of SYM */
78 #define AVR_SYMBOL_SET_ADDR_SPACE(SYM,AS) \
79 do { \
80 SYMBOL_REF_FLAGS (sym) &= ~AVR_SYMBOL_FLAG_PROGMEM; \
81 SYMBOL_REF_FLAGS (sym) |= (AS) * SYMBOL_FLAG_MACH_DEP; \
82 } while (0)
84 /* Read address-space from SYMBOL_REF_FLAGS of SYM */
85 #define AVR_SYMBOL_GET_ADDR_SPACE(SYM) \
86 ((SYMBOL_REF_FLAGS (sym) & AVR_SYMBOL_FLAG_PROGMEM) \
87 / SYMBOL_FLAG_MACH_DEP)
89 /* (AVR_TINY only): Symbol has attribute progmem */
90 #define AVR_SYMBOL_FLAG_TINY_PM \
91 (SYMBOL_FLAG_MACH_DEP << 7)
93 /* (AVR_TINY only): Symbol has attribute absdata */
94 #define AVR_SYMBOL_FLAG_TINY_ABSDATA \
95 (SYMBOL_FLAG_MACH_DEP << 8)
97 #define TINY_ADIW(REG1, REG2, I) \
98 "subi " #REG1 ",lo8(-(" #I "))" CR_TAB \
99 "sbci " #REG2 ",hi8(-(" #I "))"
101 #define TINY_SBIW(REG1, REG2, I) \
102 "subi " #REG1 ",lo8((" #I "))" CR_TAB \
103 "sbci " #REG2 ",hi8((" #I "))"
105 #define AVR_TMP_REGNO (AVR_TINY ? TMP_REGNO_TINY : TMP_REGNO)
106 #define AVR_ZERO_REGNO (AVR_TINY ? ZERO_REGNO_TINY : ZERO_REGNO)
108 /* Known address spaces. The order must be the same as in the respective
109 enum from avr.h (or designated initialized must be used). */
110 const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
112 { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
113 { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
114 { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
115 { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
116 { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
117 { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
118 { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
119 { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
123 /* Holding RAM addresses of some SFRs used by the compiler and that
124 are unique over all devices in an architecture like 'avr4'. */
126 typedef struct
128 /* SREG: The processor status */
129 int sreg;
131 /* RAMPX, RAMPY, RAMPD and CCP of XMEGA */
132 int ccp;
133 int rampd;
134 int rampx;
135 int rampy;
137 /* RAMPZ: The high byte of 24-bit address used with ELPM */
138 int rampz;
140 /* SP: The stack pointer and its low and high byte */
141 int sp_l;
142 int sp_h;
143 } avr_addr_t;
145 static avr_addr_t avr_addr;
148 /* Prototypes for local helper functions. */
150 static const char *out_movqi_r_mr (rtx_insn *, rtx[], int *);
151 static const char *out_movhi_r_mr (rtx_insn *, rtx[], int *);
152 static const char *out_movsi_r_mr (rtx_insn *, rtx[], int *);
153 static const char *out_movqi_mr_r (rtx_insn *, rtx[], int *);
154 static const char *out_movhi_mr_r (rtx_insn *, rtx[], int *);
155 static const char *out_movsi_mr_r (rtx_insn *, rtx[], int *);
157 static int get_sequence_length (rtx_insn *insns);
158 static int sequent_regs_live (void);
159 static const char *ptrreg_to_str (int);
160 static const char *cond_string (enum rtx_code);
161 static int avr_num_arg_regs (machine_mode, const_tree);
162 static int avr_operand_rtx_cost (rtx, machine_mode, enum rtx_code,
163 int, bool);
164 static void output_reload_in_const (rtx *, rtx, int *, bool);
165 static struct machine_function *avr_init_machine_status (void);
166 static bool _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn);
169 /* Prototypes for hook implementors if needed before their implementation. */
171 static bool avr_rtx_costs (rtx, machine_mode, int, int, int *, bool);
174 /* Allocate registers from r25 to r8 for parameters for function calls
175 resp. r25 to r20 for reduced Tiny. */
176 #define FIRST_CUM_REG REG_26
178 /* Last call saved register */
179 #define LAST_CALLEE_SAVED_REG (AVR_TINY ? REG_19 : REG_17)
181 /* Implicit target register of LPM instruction (R0) */
182 extern GTY(()) rtx lpm_reg_rtx;
183 rtx lpm_reg_rtx;
185 /* (Implicit) address register of LPM instruction (R31:R30 = Z) */
186 extern GTY(()) rtx lpm_addr_reg_rtx;
187 rtx lpm_addr_reg_rtx;
189 /* Temporary register RTX (reg:QI TMP_REGNO) */
190 extern GTY(()) rtx tmp_reg_rtx;
191 rtx tmp_reg_rtx;
193 /* Zeroed register RTX (reg:QI ZERO_REGNO) */
194 extern GTY(()) rtx zero_reg_rtx;
195 rtx zero_reg_rtx;
197 /* Condition Code register RTX (reg:CC REG_CC) */
198 extern GTY(()) rtx cc_reg_rtx;
199 rtx cc_reg_rtx;
201 /* RTXs for all general purpose registers as QImode */
202 extern GTY(()) rtx all_regs_rtx[REG_32];
203 rtx all_regs_rtx[REG_32];
205 /* SREG, the processor status */
206 extern GTY(()) rtx sreg_rtx;
207 rtx sreg_rtx;
209 /* RAMP* special function registers */
210 extern GTY(()) rtx rampd_rtx;
211 extern GTY(()) rtx rampx_rtx;
212 extern GTY(()) rtx rampy_rtx;
213 extern GTY(()) rtx rampz_rtx;
214 rtx rampd_rtx;
215 rtx rampx_rtx;
216 rtx rampy_rtx;
217 rtx rampz_rtx;
219 /* RTX containing the strings "" and "e", respectively */
220 static GTY(()) rtx xstring_empty;
221 static GTY(()) rtx xstring_e;
223 /* Current architecture. */
224 const avr_arch_t *avr_arch;
225 enum avr_arch_id avr_arch_index;
227 /* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
228 or to address space __flash* or __memx. Only used as singletons inside
229 avr_asm_select_section, but it must not be local there because of GTY. */
230 static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
232 /* Condition for insns/expanders from avr-dimode.md. */
233 bool avr_have_dimode = true;
235 /* To track if code will use .bss, .data, .rodata. */
236 bool avr_need_clear_bss_p = false;
237 bool avr_need_copy_data_p = false;
238 bool avr_has_rodata_p = false;
241 /* Transform UP into lowercase and write the result to LO.
242 You must provide enough space for LO. Return LO. */
244 static char *
245 avr_tolower (char *lo, const char *up)
247 char *lo0 = lo;
249 for (; *up; up++, lo++)
250 *lo = TOLOWER (*up);
252 *lo = '\0';
254 return lo0;
258 /* Constraint helper function. XVAL is a CONST_INT or a CONST_DOUBLE.
259 Return true if the least significant N_BYTES bytes of XVAL all have a
260 popcount in POP_MASK and false, otherwise. POP_MASK represents a subset
261 of integers which contains an integer N iff bit N of POP_MASK is set. */
263 bool
264 avr_popcount_each_byte (rtx xval, int n_bytes, int pop_mask)
266 machine_mode mode = GET_MODE (xval);
268 if (VOIDmode == mode)
269 mode = SImode;
271 for (int i = 0; i < n_bytes; i++)
273 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
274 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
276 if ((pop_mask & (1 << popcount_hwi (val8))) == 0)
277 return false;
280 return true;
284 /* Constraint helper function. XVAL is a CONST_INT. Return true if we
285 can perform XOR without a clobber reg, provided the operation is on
286 a d-register. This means each byte is in { 0, 0xff, 0x80 }. */
288 bool
289 avr_xor_noclobber_dconst (rtx xval, int n_bytes)
291 machine_mode mode = GET_MODE (xval);
293 if (VOIDmode == mode)
294 mode = SImode;
296 for (int i = 0; i < n_bytes; ++i)
298 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
299 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
301 if (val8 != 0 && val8 != 0xff && val8 != 0x80)
302 return false;
305 return true;
309 /* Access some RTX as INT_MODE. If X is a CONST_FIXED we can get
310 the bit representation of X by "casting" it to CONST_INT. */
313 avr_to_int_mode (rtx x)
315 machine_mode mode = GET_MODE (x);
317 return VOIDmode == mode
319 : simplify_gen_subreg (int_mode_for_mode (mode).require (), x, mode, 0);
323 /* Return true if hard register REG supports the ADIW and SBIW instructions. */
325 bool
326 avr_adiw_reg_p (rtx reg)
328 return (AVR_HAVE_ADIW
329 && test_hard_reg_class (ADDW_REGS, reg));
333 namespace {
335 static const pass_data avr_pass_data_recompute_notes =
337 RTL_PASS, // type
338 "", // name (will be patched)
339 OPTGROUP_NONE, // optinfo_flags
340 TV_DF_SCAN, // tv_id
341 0, // properties_required
342 0, // properties_provided
343 0, // properties_destroyed
344 0, // todo_flags_start
345 TODO_df_finish | TODO_df_verify // todo_flags_finish
349 class avr_pass_recompute_notes : public rtl_opt_pass
351 public:
352 avr_pass_recompute_notes (gcc::context *ctxt, const char *name)
353 : rtl_opt_pass (avr_pass_data_recompute_notes, ctxt)
355 this->name = name;
358 virtual unsigned int execute (function *)
360 df_note_add_problem ();
361 df_analyze ();
363 return 0;
365 }; // avr_pass_recompute_notes
367 static const pass_data avr_pass_data_casesi =
369 RTL_PASS, // type
370 "", // name (will be patched)
371 OPTGROUP_NONE, // optinfo_flags
372 TV_DF_SCAN, // tv_id
373 0, // properties_required
374 0, // properties_provided
375 0, // properties_destroyed
376 0, // todo_flags_start
377 0 // todo_flags_finish
381 class avr_pass_casesi : public rtl_opt_pass
383 public:
384 avr_pass_casesi (gcc::context *ctxt, const char *name)
385 : rtl_opt_pass (avr_pass_data_casesi, ctxt)
387 this->name = name;
390 void avr_rest_of_handle_casesi (function *);
392 virtual bool gate (function *) { return optimize > 0; }
394 virtual unsigned int execute (function *func)
396 avr_rest_of_handle_casesi (func);
398 return 0;
400 }; // avr_pass_casesi
403 static const pass_data avr_pass_data_ifelse =
405 RTL_PASS, // type
406 "", // name (will be patched)
407 OPTGROUP_NONE, // optinfo_flags
408 TV_DF_SCAN, // tv_id
409 0, // properties_required
410 0, // properties_provided
411 0, // properties_destroyed
412 0, // todo_flags_start
413 TODO_df_finish | TODO_df_verify // todo_flags_finish
416 class avr_pass_ifelse : public rtl_opt_pass
418 public:
419 avr_pass_ifelse (gcc::context *ctxt, const char *name)
420 : rtl_opt_pass (avr_pass_data_ifelse, ctxt)
422 this->name = name;
425 void avr_rest_of_handle_ifelse (function *);
427 virtual bool gate (function *) { return optimize > 0; }
429 virtual unsigned int execute (function *func)
431 avr_rest_of_handle_ifelse (func);
433 return 0;
435 }; // avr_pass_ifelse
437 } // anon namespace
439 rtl_opt_pass *
440 make_avr_pass_recompute_notes (gcc::context *ctxt)
442 return new avr_pass_recompute_notes (ctxt, "avr-notes-free-cfg");
445 rtl_opt_pass *
446 make_avr_pass_casesi (gcc::context *ctxt)
448 return new avr_pass_casesi (ctxt, "avr-casesi");
451 rtl_opt_pass *
452 make_avr_pass_ifelse (gcc::context *ctxt)
454 return new avr_pass_ifelse (ctxt, "avr-ifelse");
458 /* Make one parallel insn with all the patterns from insns i[0]..i[5]. */
460 static rtx_insn *
461 avr_parallel_insn_from_insns (rtx_insn *i[5])
463 rtvec vec = gen_rtvec (5, PATTERN (i[0]), PATTERN (i[1]), PATTERN (i[2]),
464 PATTERN (i[3]), PATTERN (i[4]));
465 start_sequence();
466 emit (gen_rtx_PARALLEL (VOIDmode, vec));
467 rtx_insn *insn = get_insns();
468 end_sequence();
470 return insn;
474 /* Return true if we see an insn stream generated by casesi expander together
475 with an extension to SImode of the switch value.
477 If this is the case, fill in the insns from casesi to INSNS[1..5] and
478 the SImode extension to INSNS[0]. Moreover, extract the operands of
479 pattern casesi_<mode>_sequence forged from the sequence to recog_data. */
481 static bool
482 avr_is_casesi_sequence (basic_block bb, rtx_insn *insn, rtx_insn *insns[5])
484 rtx set_4, set_0;
486 /* A first and quick test for a casesi sequences. As a side effect of
487 the test, harvest respective insns to INSNS[0..4]. */
489 if (!(JUMP_P (insns[4] = insn)
490 // casesi is the only insn that comes up with UNSPEC_INDEX_JMP,
491 // hence the following test ensures that we are actually dealing
492 // with code from casesi.
493 && (set_4 = single_set (insns[4]))
494 && UNSPEC == GET_CODE (SET_SRC (set_4))
495 && UNSPEC_INDEX_JMP == XINT (SET_SRC (set_4), 1)
497 && (insns[3] = prev_real_insn (insns[4]))
498 && (insns[2] = prev_real_insn (insns[3]))
499 && (insns[1] = prev_real_insn (insns[2]))
501 // Insn prior to casesi.
502 && (insns[0] = prev_real_insn (insns[1]))
503 && (set_0 = single_set (insns[0]))
504 && extend_operator (SET_SRC (set_0), SImode)))
506 return false;
509 if (dump_file)
511 fprintf (dump_file, ";; Sequence from casesi in "
512 "[bb %d]:\n\n", bb->index);
513 for (int i = 0; i < 5; i++)
514 print_rtl_single (dump_file, insns[i]);
517 /* We have to deal with quite some operands. Extracting them by hand
518 would be tedious, therefore wrap the insn patterns into a parallel,
519 run recog against it and then use insn extract to get the operands. */
521 rtx_insn *xinsn = avr_parallel_insn_from_insns (insns);
523 INSN_CODE (xinsn) = recog (PATTERN (xinsn), xinsn, NULL /* num_clobbers */);
525 /* Failing to recognize means that someone changed the casesi expander or
526 that some passes prior to this one performed some unexpected changes.
527 Gracefully drop such situations instead of aborting. */
529 if (INSN_CODE (xinsn) < 0)
531 if (dump_file)
532 fprintf (dump_file, ";; Sequence not recognized, giving up.\n\n");
534 return false;
537 gcc_assert (CODE_FOR_casesi_qi_sequence == INSN_CODE (xinsn)
538 || CODE_FOR_casesi_hi_sequence == INSN_CODE (xinsn));
540 extract_insn (xinsn);
542 // Assert on the anatomy of xinsn's operands we are going to work with.
544 gcc_assert (recog_data.n_operands == 11);
545 gcc_assert (recog_data.n_dups == 4);
547 if (dump_file)
549 fprintf (dump_file, ";; Operands extracted:\n");
550 for (int i = 0; i < recog_data.n_operands; i++)
551 avr_fdump (dump_file, ";; $%d = %r\n", i, recog_data.operand[i]);
552 fprintf (dump_file, "\n");
555 return true;
559 /* Perform some extra checks on operands of casesi_<mode>_sequence.
560 Not all operand dependencies can be described by means of predicates.
561 This function performs left over checks and should always return true.
562 Returning false means that someone changed the casesi expander but did
563 not adjust casesi_<mode>_sequence. */
565 bool
566 avr_casei_sequence_check_operands (rtx *xop)
568 rtx sub_5 = NULL_RTX;
570 if (AVR_HAVE_EIJMP_EICALL
571 // The last clobber op of the tablejump.
572 && xop[8] == all_regs_rtx[REG_24])
574 // $6 is: (subreg:SI ($5) 0)
575 sub_5 = xop[6];
578 if (!AVR_HAVE_EIJMP_EICALL
579 // $6 is: (plus:HI (subreg:SI ($5) 0)
580 // (label_ref ($3)))
581 && PLUS == GET_CODE (xop[6])
582 && LABEL_REF == GET_CODE (XEXP (xop[6], 1))
583 && rtx_equal_p (xop[3], XEXP (XEXP (xop[6], 1), 0))
584 // The last clobber op of the tablejump.
585 && xop[8] == const0_rtx)
587 sub_5 = XEXP (xop[6], 0);
590 if (sub_5
591 && SUBREG_P (sub_5)
592 && SUBREG_BYTE (sub_5) == 0
593 && rtx_equal_p (xop[5], SUBREG_REG (sub_5)))
594 return true;
596 if (dump_file)
597 fprintf (dump_file, "\n;; Failed condition for casesi_<mode>_sequence\n\n");
599 return false;
603 /* INSNS[1..4] is a sequence as generated by casesi and INSNS[0] is an
604 extension of an 8-bit or 16-bit integer to SImode. XOP contains the
605 operands of INSNS as extracted by insn_extract from pattern
606 casesi_<mode>_sequence:
608 $0: SImode reg switch value as result of $9.
609 $1: Negative of smallest index in switch.
610 $2: Number of entries in switch.
611 $3: Label to table.
612 $4: Label if out-of-bounds.
613 $5: $0 + $1.
614 $6: 3-byte PC: subreg:HI ($5) + label_ref ($3)
615 2-byte PC: subreg:HI ($5)
616 $7: HI reg index into table (Z or pseudo)
617 $8: R24 or const0_rtx (to be clobbered)
618 $9: Extension to SImode of an 8-bit or 16-bit integer register $10.
619 $10: QImode or HImode register input of $9.
621 Try to optimize this sequence, i.e. use the original HImode / QImode
622 switch value instead of SImode. */
624 static void
625 avr_optimize_casesi (rtx_insn *insns[5], rtx *xop)
627 // Original mode of the switch value; this is QImode or HImode.
628 machine_mode mode = GET_MODE (xop[10]);
630 // How the original switch value was extended to SImode; this is
631 // SIGN_EXTEND or ZERO_EXTEND.
632 enum rtx_code code = GET_CODE (xop[9]);
634 // Lower index, upper index (plus one) and range of case calues.
635 HOST_WIDE_INT low_idx = -INTVAL (xop[1]);
636 HOST_WIDE_INT num_idx = INTVAL (xop[2]);
637 HOST_WIDE_INT hig_idx = low_idx + num_idx;
639 // Maximum ranges of (un)signed QImode resp. HImode.
640 unsigned umax = QImode == mode ? 0xff : 0xffff;
641 int imax = QImode == mode ? 0x7f : 0x7fff;
642 int imin = -imax - 1;
644 // Testing the case range and whether it fits into the range of the
645 // (un)signed mode. This test should actually always pass because it
646 // makes no sense to have case values outside the mode range. Notice
647 // that case labels which are unreachable because they are outside the
648 // mode of the switch value (e.g. "case -1" for uint8_t) have already
649 // been thrown away by the middle-end.
651 if (SIGN_EXTEND == code
652 && low_idx >= imin
653 && hig_idx <= imax)
655 // ok
657 else if (ZERO_EXTEND == code
658 && low_idx >= 0
659 && (unsigned) hig_idx <= umax)
661 // ok
663 else
665 if (dump_file)
666 fprintf (dump_file, ";; Case ranges too big, giving up.\n\n");
667 return;
670 // Do normalization of switch value $10 and out-of-bound check in its
671 // original mode instead of in SImode. Use a newly created pseudo.
672 // This will replace insns[1..2].
674 start_sequence();
676 rtx reg = copy_to_mode_reg (mode, xop[10]);
678 rtx (*gen_add)(rtx,rtx,rtx) = QImode == mode ? gen_addqi3 : gen_addhi3;
679 rtx (*gen_cbranch)(rtx,rtx,rtx,rtx)
680 = QImode == mode ? gen_cbranchqi4 : gen_cbranchhi4;
682 emit_insn (gen_add (reg, reg, gen_int_mode (-low_idx, mode)));
683 rtx op0 = reg; rtx op1 = gen_int_mode (num_idx, mode);
684 rtx labelref = copy_rtx (xop[4]);
685 rtx xbranch = gen_cbranch (gen_rtx_fmt_ee (GTU, VOIDmode, op0, op1),
686 op0, op1, labelref);
687 rtx_insn *cbranch = emit_jump_insn (xbranch);
688 JUMP_LABEL (cbranch) = xop[4];
689 ++LABEL_NUSES (xop[4]);
691 rtx_insn *seq1 = get_insns();
692 rtx_insn *last1 = get_last_insn();
693 end_sequence();
695 emit_insn_after (seq1, insns[2]);
697 // After the out-of-bounds test and corresponding branch, use a
698 // 16-bit index. If QImode is used, extend it to HImode first.
699 // This will replace insns[4].
701 start_sequence();
703 if (QImode == mode)
704 reg = force_reg (HImode, gen_rtx_fmt_e (code, HImode, reg));
706 rtx pat_4 = AVR_3_BYTE_PC
707 ? gen_movhi (xop[7], reg)
708 : gen_addhi3 (xop[7], reg, gen_rtx_LABEL_REF (VOIDmode, xop[3]));
710 emit_insn (pat_4);
712 rtx_insn *seq2 = get_insns();
713 rtx_insn *last2 = get_last_insn();
714 end_sequence();
716 emit_insn_after (seq2, insns[3]);
718 if (dump_file)
720 fprintf (dump_file, ";; New insns: ");
722 for (rtx_insn *insn = seq1; ; insn = NEXT_INSN (insn))
724 fprintf (dump_file, "%d, ", INSN_UID (insn));
725 if (insn == last1)
726 break;
728 for (rtx_insn *insn = seq2; ; insn = NEXT_INSN (insn))
730 fprintf (dump_file, "%d%s", INSN_UID (insn),
731 insn == last2 ? ".\n\n" : ", ");
732 if (insn == last2)
733 break;
736 fprintf (dump_file, ";; Deleting insns: %d, %d, %d.\n\n",
737 INSN_UID (insns[1]), INSN_UID (insns[2]), INSN_UID (insns[3]));
740 // Pseudodelete the SImode and subreg of SImode insns. We don't care
741 // about the extension insns[0]: Its result is now unused and other
742 // passes will clean it up.
744 SET_INSN_DELETED (insns[1]);
745 SET_INSN_DELETED (insns[2]);
746 SET_INSN_DELETED (insns[3]);
750 void
751 avr_pass_casesi::avr_rest_of_handle_casesi (function *func)
753 basic_block bb;
755 FOR_EACH_BB_FN (bb, func)
757 rtx_insn *insn, *insns[5];
759 FOR_BB_INSNS (bb, insn)
761 if (avr_is_casesi_sequence (bb, insn, insns))
763 avr_optimize_casesi (insns, recog_data.operand);
770 /* A helper for the next method. Suppose we have two conditional branches
772 if (reg <cond1> xval1) goto label1;
773 if (reg <cond2> xval2) goto label2;
775 If the second comparison is redundant and there is a code <cond> such
776 that the sequence can be performed as
778 REG_CC = compare (reg, xval1);
779 if (REG_CC <cond1> 0) goto label1;
780 if (REG_CC <cond> 0) goto label2;
782 then return <cond>. Otherwise, return UNKNOWN.
783 xval1 and xval2 are CONST_INT, and mode is the scalar int mode in which
784 the comparison will be carried out. reverse_cond1 can be set to reverse
785 condition cond1. This is useful if the second comparison does not follow
786 the first one, but is located after label1 like in:
788 if (reg <cond1> xval1) goto label1;
790 label1:
791 if (reg <cond2> xval2) goto label2; */
793 static enum rtx_code
794 avr_redundant_compare (enum rtx_code cond1, rtx xval1,
795 enum rtx_code cond2, rtx xval2,
796 machine_mode mode, bool reverse_cond1)
798 HOST_WIDE_INT ival1 = INTVAL (xval1);
799 HOST_WIDE_INT ival2 = INTVAL (xval2);
801 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (mode);
802 unsigned HOST_WIDE_INT uval1 = mask & UINTVAL (xval1);
803 unsigned HOST_WIDE_INT uval2 = mask & UINTVAL (xval2);
805 if (reverse_cond1)
806 cond1 = reverse_condition (cond1);
808 if (cond1 == EQ)
810 ////////////////////////////////////////////////
811 // A sequence like
812 // if (reg == val) goto label1;
813 // if (reg > val) goto label2;
814 // can be re-written using the same, simple comparison like in:
815 // REG_CC = compare (reg, val)
816 // if (REG_CC == 0) goto label1;
817 // if (REG_CC >= 0) goto label2;
818 if (ival1 == ival2
819 && (cond2 == GT || cond2 == GTU))
820 return avr_normalize_condition (cond2);
822 // Similar, but the input sequence is like
823 // if (reg == val) goto label1;
824 // if (reg >= val) goto label2;
825 if (ival1 == ival2
826 && (cond2 == GE || cond2 == GEU))
827 return cond2;
829 // Similar, but the input sequence is like
830 // if (reg == val) goto label1;
831 // if (reg >= val + 1) goto label2;
832 if ((cond2 == GE && ival2 == 1 + ival1)
833 || (cond2 == GEU && uval2 == 1 + uval1))
834 return cond2;
836 // Similar, but the input sequence is like
837 // if (reg == val) goto label1;
838 // if (reg > val - 1) goto label2;
839 if ((cond2 == GT && ival2 == ival1 - 1)
840 || (cond2 == GTU && uval2 == uval1 - 1))
841 return avr_normalize_condition (cond2);
843 /////////////////////////////////////////////////////////
844 // A sequence like
845 // if (reg == val) goto label1;
846 // if (reg < 1 + val) goto label2;
847 // can be re-written as
848 // REG_CC = compare (reg, val)
849 // if (REG_CC == 0) goto label1;
850 // if (REG_CC < 0) goto label2;
851 if ((cond2 == LT && ival2 == 1 + ival1)
852 || (cond2 == LTU && uval2 == 1 + uval1))
853 return cond2;
855 // Similar, but with an input sequence like
856 // if (reg == val) goto label1;
857 // if (reg <= val) goto label2;
858 if (ival1 == ival2
859 && (cond2 == LE || cond2 == LEU))
860 return avr_normalize_condition (cond2);
862 // Similar, but with an input sequence like
863 // if (reg == val) goto label1;
864 // if (reg < val) goto label2;
865 if (ival1 == ival2
866 && (cond2 == LT || cond2 == LTU))
867 return cond2;
869 // Similar, but with an input sequence like
870 // if (reg == val) goto label1;
871 // if (reg <= val - 1) goto label2;
872 if ((cond2 == LE && ival2 == ival1 - 1)
873 || (cond2 == LEU && uval2 == uval1 - 1))
874 return avr_normalize_condition (cond2);
876 } // cond1 == EQ
878 return UNKNOWN;
882 /* If-else decision trees generated for switch / case may produce sequences
883 like
885 SREG = compare (reg, val);
886 if (SREG == 0) goto label1;
887 SREG = compare (reg, 1 + val);
888 if (SREG >= 0) goto label2;
890 which can be optimized to
892 SREG = compare (reg, val);
893 if (SREG == 0) goto label1;
894 if (SREG >= 0) goto label2;
896 The optimal place for such a pass would be directly after expand, but
897 it's not possible for a jump insn to target more than one code label.
898 Hence, run a mini pass right before split2 which introduces REG_CC. */
900 void
901 avr_pass_ifelse::avr_rest_of_handle_ifelse (function *)
903 rtx_insn *next_insn;
905 for (rtx_insn *insn = get_insns(); insn; insn = next_insn)
907 next_insn = next_nonnote_nondebug_insn (insn);
909 if (! next_insn)
910 break;
912 // Search for two cbranch insns. The first one is a cbranch.
913 // Filter for "cbranch<mode>4_insn" with mode in QI, HI, PSI, SI.
915 if (! JUMP_P (insn))
916 continue;
918 int icode1 = recog_memoized (insn);
920 if (icode1 != CODE_FOR_cbranchqi4_insn
921 && icode1 != CODE_FOR_cbranchhi4_insn
922 && icode1 != CODE_FOR_cbranchpsi4_insn
923 && icode1 != CODE_FOR_cbranchsi4_insn)
924 continue;
926 rtx_jump_insn *insn1 = as_a<rtx_jump_insn *> (insn);
927 rtx_jump_insn *insn2 = nullptr;
928 bool follow_label1 = false;
930 // Extract the operands of the first insn:
931 // $0 = comparison operator ($1, $2)
932 // $1 = reg
933 // $2 = reg or const_int
934 // $3 = code_label
935 // $4 = optional SCRATCH for HI, PSI, SI cases.
937 const auto &op = recog_data.operand;
939 extract_insn (insn1);
940 rtx xop1[5] = { op[0], op[1], op[2], op[3], op[4] };
941 int n_operands = recog_data.n_operands;
943 // For now, we can optimize cbranches that follow an EQ cbranch,
944 // and cbranches that follow the label of a NE cbranch.
946 if (GET_CODE (xop1[0]) == EQ
947 && JUMP_P (next_insn)
948 && recog_memoized (next_insn) == icode1)
950 // The 2nd cbranch insn follows insn1, i.e. is located in the
951 // fallthrough path of insn1.
953 insn2 = as_a<rtx_jump_insn *> (next_insn);
955 else if (GET_CODE (xop1[0]) == NE)
957 // insn1 might branch to a label followed by a cbranch.
959 rtx target1 = JUMP_LABEL (insn1);
960 rtx_insn *code_label1 = JUMP_LABEL_AS_INSN (insn1);
961 rtx_insn *next = next_nonnote_nondebug_insn (code_label1);
962 rtx_insn *barrier = prev_nonnote_nondebug_insn (code_label1);
964 if (// Target label of insn1 is used exactly once and
965 // is not a fallthru, i.e. is preceded by a barrier.
966 LABEL_NUSES (target1) == 1
967 && barrier
968 && BARRIER_P (barrier)
969 // Following the target label is a cbranch of the same kind.
970 && next
971 && JUMP_P (next)
972 && recog_memoized (next) == icode1)
974 follow_label1 = true;
975 insn2 = as_a<rtx_jump_insn *> (next);
979 if (! insn2)
980 continue;
982 // Also extract operands of insn2, and filter for REG + CONST_INT
983 // comparsons against the same register.
985 extract_insn (insn2);
986 rtx xop2[5] = { op[0], op[1], op[2], op[3], op[4] };
988 if (! rtx_equal_p (xop1[1], xop2[1])
989 || ! CONST_INT_P (xop1[2])
990 || ! CONST_INT_P (xop2[2]))
991 continue;
993 machine_mode mode = GET_MODE (xop1[1]);
994 enum rtx_code code1 = GET_CODE (xop1[0]);
995 enum rtx_code code2 = GET_CODE (xop2[0]);
997 code2 = avr_redundant_compare (code1, xop1[2], code2, xop2[2],
998 mode, follow_label1);
999 if (code2 == UNKNOWN)
1000 continue;
1002 //////////////////////////////////////////////////////
1003 // Found a replacement.
1005 if (dump_file)
1007 fprintf (dump_file, "\n;; Found chain of jump_insn %d and"
1008 " jump_insn %d, follow_label1=%d:\n",
1009 INSN_UID (insn1), INSN_UID (insn2), follow_label1);
1010 print_rtl_single (dump_file, PATTERN (insn1));
1011 print_rtl_single (dump_file, PATTERN (insn2));
1014 if (! follow_label1)
1015 next_insn = next_nonnote_nondebug_insn (insn2);
1017 // Pop the new branch conditions and the new comparison.
1018 // Prematurely split into compare + branch so that we can drop
1019 // the 2nd comparison. The following pass, split2, splits all
1020 // insns for REG_CC, and it should still work as usual even when
1021 // there are already some REG_CC insns around.
1023 rtx xcond1 = gen_rtx_fmt_ee (code1, VOIDmode, cc_reg_rtx, const0_rtx);
1024 rtx xcond2 = gen_rtx_fmt_ee (code2, VOIDmode, cc_reg_rtx, const0_rtx);
1025 rtx xpat1 = gen_branch (xop1[3], xcond1);
1026 rtx xpat2 = gen_branch (xop2[3], xcond2);
1027 rtx xcompare = NULL_RTX;
1029 if (mode == QImode)
1031 gcc_assert (n_operands == 4);
1032 xcompare = gen_cmpqi3 (xop1[1], xop1[2]);
1034 else
1036 gcc_assert (n_operands == 5);
1037 rtx (*gen_cmp)(rtx,rtx,rtx)
1038 = mode == HImode ? gen_gen_comparehi
1039 : mode == PSImode ? gen_gen_comparepsi
1040 : gen_gen_comparesi; // SImode
1041 xcompare = gen_cmp (xop1[1], xop1[2], xop1[4]);
1044 // Emit that stuff.
1046 rtx_insn *cmp = emit_insn_before (xcompare, insn1);
1047 rtx_jump_insn *branch1 = emit_jump_insn_before (xpat1, insn1);
1048 rtx_jump_insn *branch2 = emit_jump_insn_before (xpat2, insn2);
1050 JUMP_LABEL (branch1) = xop1[3];
1051 JUMP_LABEL (branch2) = xop2[3];
1052 // delete_insn() decrements LABEL_NUSES when deleting a JUMP_INSN, but
1053 // when we pop a new JUMP_INSN, do it by hand.
1054 ++LABEL_NUSES (xop1[3]);
1055 ++LABEL_NUSES (xop2[3]);
1057 delete_insn (insn1);
1058 delete_insn (insn2);
1060 // As a side effect, also recog the new insns.
1061 gcc_assert (valid_insn_p (cmp));
1062 gcc_assert (valid_insn_p (branch1));
1063 gcc_assert (valid_insn_p (branch2));
1064 } // loop insns
1068 /* Set `avr_arch' as specified by `-mmcu='.
1069 Return true on success. */
1071 static bool
1072 avr_set_core_architecture (void)
1074 /* Search for mcu core architecture. */
1076 if (!avr_mmcu)
1077 avr_mmcu = AVR_MMCU_DEFAULT;
1079 avr_arch = &avr_arch_types[0];
1081 for (const avr_mcu_t *mcu = avr_mcu_types; ; mcu++)
1083 if (mcu->name == NULL)
1085 /* Reached the end of `avr_mcu_types'. This should actually never
1086 happen as options are provided by device-specs. It could be a
1087 typo in a device-specs or calling the compiler proper directly
1088 with -mmcu=<device>. */
1090 error ("unknown core architecture %qs specified with %qs",
1091 avr_mmcu, "-mmcu=");
1092 avr_inform_core_architectures ();
1093 break;
1095 else if (strcmp (mcu->name, avr_mmcu) == 0
1096 // Is this a proper architecture ?
1097 && mcu->macro == NULL)
1099 avr_arch = &avr_arch_types[mcu->arch_id];
1100 avr_arch_index = mcu->arch_id;
1101 if (avr_n_flash < 0)
1102 avr_n_flash = 1 + (mcu->flash_size - 1) / 0x10000;
1104 return true;
1108 return false;
1112 /* Implement `TARGET_OPTION_OVERRIDE'. */
1114 static void
1115 avr_option_override (void)
1117 /* caller-save.cc looks for call-clobbered hard registers that are assigned
1118 to pseudos that cross calls and tries so save-restore them around calls
1119 in order to reduce the number of stack slots needed.
1121 This might lead to situations where reload is no more able to cope
1122 with the challenge of AVR's very few address registers and fails to
1123 perform the requested spills. */
1125 if (avr_strict_X)
1126 flag_caller_saves = 0;
1128 /* Unwind tables currently require a frame pointer for correctness,
1129 see toplev.cc:process_options(). */
1131 if ((flag_unwind_tables
1132 || flag_non_call_exceptions
1133 || flag_asynchronous_unwind_tables)
1134 && !ACCUMULATE_OUTGOING_ARGS)
1136 flag_omit_frame_pointer = 0;
1139 /* Disable flag_delete_null_pointer_checks if zero is a valid address. */
1140 if (targetm.addr_space.zero_address_valid (ADDR_SPACE_GENERIC))
1141 flag_delete_null_pointer_checks = 0;
1143 /* PR ipa/92606: Inter-procedural analysis optimizes data across
1144 address-spaces and PROGMEM. As of v14, the PROGMEM part is
1145 still not fixed (and there is still no target hook as proposed
1146 in PR92932). Just disable respective bogus optimization. */
1147 flag_ipa_icf_variables = 0;
1149 if (flag_pic == 1)
1150 warning (OPT_fpic, "%<-fpic%> is not supported");
1151 if (flag_pic == 2)
1152 warning (OPT_fPIC, "%<-fPIC%> is not supported");
1153 if (flag_pie == 1)
1154 warning (OPT_fpie, "%<-fpie%> is not supported");
1155 if (flag_pie == 2)
1156 warning (OPT_fPIE, "%<-fPIE%> is not supported");
1158 #if !defined (HAVE_AS_AVR_MGCCISR_OPTION)
1159 avr_gasisr_prologues = 0;
1160 #endif
1162 if (!avr_set_core_architecture())
1163 return;
1165 /* Sould be set by avr-common.cc */
1166 gcc_assert (avr_long_double >= avr_double && avr_double >= 32);
1168 /* RAM addresses of some SFRs common to all devices in respective arch. */
1170 /* SREG: Status Register containing flags like I (global IRQ) */
1171 avr_addr.sreg = 0x3F + avr_arch->sfr_offset;
1173 /* RAMPZ: Address' high part when loading via ELPM */
1174 avr_addr.rampz = 0x3B + avr_arch->sfr_offset;
1176 avr_addr.rampy = 0x3A + avr_arch->sfr_offset;
1177 avr_addr.rampx = 0x39 + avr_arch->sfr_offset;
1178 avr_addr.rampd = 0x38 + avr_arch->sfr_offset;
1179 avr_addr.ccp = (AVR_TINY ? 0x3C : 0x34) + avr_arch->sfr_offset;
1181 /* SP: Stack Pointer (SP_H:SP_L) */
1182 avr_addr.sp_l = 0x3D + avr_arch->sfr_offset;
1183 avr_addr.sp_h = avr_addr.sp_l + 1;
1185 init_machine_status = avr_init_machine_status;
1187 avr_log_set_avr_log();
1190 /* Function to set up the backend function structure. */
1192 static struct machine_function *
1193 avr_init_machine_status (void)
1195 return ggc_cleared_alloc<machine_function> ();
1199 /* Implement `INIT_EXPANDERS'. */
1200 /* The function works like a singleton. */
1202 void
1203 avr_init_expanders (void)
1205 for (int regno = REG_0; regno < REG_32; regno ++)
1206 all_regs_rtx[regno] = gen_rtx_REG (QImode, regno);
1208 lpm_reg_rtx = all_regs_rtx[LPM_REGNO];
1209 tmp_reg_rtx = all_regs_rtx[AVR_TMP_REGNO];
1210 zero_reg_rtx = all_regs_rtx[AVR_ZERO_REGNO];
1212 cc_reg_rtx = gen_rtx_REG (CCmode, REG_CC);
1214 lpm_addr_reg_rtx = gen_rtx_REG (HImode, REG_Z);
1216 sreg_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.sreg));
1217 rampd_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampd));
1218 rampx_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampx));
1219 rampy_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampy));
1220 rampz_rtx = gen_rtx_MEM (QImode, GEN_INT (avr_addr.rampz));
1222 xstring_empty = gen_rtx_CONST_STRING (VOIDmode, "");
1223 xstring_e = gen_rtx_CONST_STRING (VOIDmode, "e");
1225 /* TINY core does not have regs r10-r16, but avr-dimode.md expects them
1226 to be present */
1227 if (AVR_TINY)
1228 avr_have_dimode = false;
1232 /* Implement `REGNO_REG_CLASS'. */
1233 /* Return register class for register R. */
1235 enum reg_class
1236 avr_regno_reg_class (int r)
1238 static const enum reg_class reg_class_tab[] =
1240 R0_REG,
1241 /* r1 - r15 */
1242 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
1243 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
1244 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
1245 NO_LD_REGS, NO_LD_REGS, NO_LD_REGS, NO_LD_REGS,
1246 /* r16 - r23 */
1247 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
1248 SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS, SIMPLE_LD_REGS,
1249 /* r24, r25 */
1250 ADDW_REGS, ADDW_REGS,
1251 /* X: r26, 27 */
1252 POINTER_X_REGS, POINTER_X_REGS,
1253 /* Y: r28, r29 */
1254 POINTER_Y_REGS, POINTER_Y_REGS,
1255 /* Z: r30, r31 */
1256 POINTER_Z_REGS, POINTER_Z_REGS,
1257 /* SP: SPL, SPH */
1258 STACK_REG, STACK_REG
1261 if (r <= 33)
1262 return reg_class_tab[r];
1264 if (r == REG_CC)
1265 return CC_REG;
1267 return ALL_REGS;
1271 /* Implement `TARGET_SCALAR_MODE_SUPPORTED_P'. */
1273 static bool
1274 avr_scalar_mode_supported_p (scalar_mode mode)
1276 if (ALL_FIXED_POINT_MODE_P (mode))
1277 return true;
1279 if (PSImode == mode)
1280 return true;
1282 return default_scalar_mode_supported_p (mode);
1286 /* Return TRUE if DECL is a VAR_DECL located in flash and FALSE, otherwise. */
1288 static bool
1289 avr_decl_flash_p (tree decl)
1291 if (TREE_CODE (decl) != VAR_DECL
1292 || TREE_TYPE (decl) == error_mark_node)
1294 return false;
1297 return !ADDR_SPACE_GENERIC_P (TYPE_ADDR_SPACE (TREE_TYPE (decl)));
1301 /* Return TRUE if DECL is a VAR_DECL located in the 24-bit flash
1302 address space and FALSE, otherwise. */
1304 static bool
1305 avr_decl_memx_p (tree decl)
1307 if (TREE_CODE (decl) != VAR_DECL
1308 || TREE_TYPE (decl) == error_mark_node)
1310 return false;
1313 return (ADDR_SPACE_MEMX == TYPE_ADDR_SPACE (TREE_TYPE (decl)));
1317 /* Return TRUE if X is a MEM rtx located in flash and FALSE, otherwise. */
1319 bool
1320 avr_mem_flash_p (rtx x)
1322 return (MEM_P (x)
1323 && !ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (x)));
1327 /* Return TRUE if X is a MEM rtx located in the 24-bit flash
1328 address space and FALSE, otherwise. */
1330 bool
1331 avr_mem_memx_p (rtx x)
1333 return (MEM_P (x)
1334 && ADDR_SPACE_MEMX == MEM_ADDR_SPACE (x));
1338 /* A helper for the subsequent function attribute used to dig for
1339 attribute 'name' in a FUNCTION_DECL or FUNCTION_TYPE */
1341 static inline bool
1342 avr_lookup_function_attribute1 (const_tree func, const char *name)
1344 if (FUNCTION_DECL == TREE_CODE (func))
1346 if (NULL_TREE != lookup_attribute (name, DECL_ATTRIBUTES (func)))
1348 return true;
1351 func = TREE_TYPE (func);
1354 gcc_assert (FUNC_OR_METHOD_TYPE_P (func));
1356 return NULL_TREE != lookup_attribute (name, TYPE_ATTRIBUTES (func));
1359 /* Return nonzero if FUNC is a naked function. */
1361 static bool
1362 avr_naked_function_p (tree func)
1364 return avr_lookup_function_attribute1 (func, "naked");
1367 /* Return nonzero if FUNC is an interrupt function as specified
1368 by the "interrupt" attribute. */
1370 static bool
1371 avr_interrupt_function_p (tree func)
1373 return avr_lookup_function_attribute1 (func, "interrupt");
1376 /* Return nonzero if FUNC is a signal function as specified
1377 by the "signal" attribute. */
1379 static bool
1380 avr_signal_function_p (tree func)
1382 return avr_lookup_function_attribute1 (func, "signal");
1385 /* Return nonzero if FUNC is an OS_task function. */
1387 static bool
1388 avr_OS_task_function_p (tree func)
1390 return avr_lookup_function_attribute1 (func, "OS_task");
1393 /* Return nonzero if FUNC is an OS_main function. */
1395 static bool
1396 avr_OS_main_function_p (tree func)
1398 return avr_lookup_function_attribute1 (func, "OS_main");
1402 /* Return nonzero if FUNC is a no_gccisr function as specified
1403 by the "no_gccisr" attribute. */
1405 static bool
1406 avr_no_gccisr_function_p (tree func)
1408 return avr_lookup_function_attribute1 (func, "no_gccisr");
1412 /* Implement `TARGET_CAN_INLINE_P'. */
1413 /* Some options like -mgas_isr_prologues depend on optimization level,
1414 and the inliner might think that due to different options, inlining
1415 is not permitted; see PR104327. */
1417 static bool
1418 avr_can_inline_p (tree /* caller */, tree /* callee */)
1420 // No restrictions whatsoever.
1421 return true;
1424 /* Implement `TARGET_SET_CURRENT_FUNCTION'. */
1425 /* Sanity cheching for above function attributes. */
1427 static void
1428 avr_set_current_function (tree decl)
1430 if (decl == NULL_TREE
1431 || current_function_decl == NULL_TREE
1432 || current_function_decl == error_mark_node
1433 || ! cfun->machine
1434 || cfun->machine->attributes_checked_p)
1435 return;
1437 location_t loc = DECL_SOURCE_LOCATION (decl);
1439 cfun->machine->is_naked = avr_naked_function_p (decl);
1440 cfun->machine->is_signal = avr_signal_function_p (decl);
1441 cfun->machine->is_interrupt = avr_interrupt_function_p (decl);
1442 cfun->machine->is_OS_task = avr_OS_task_function_p (decl);
1443 cfun->machine->is_OS_main = avr_OS_main_function_p (decl);
1444 cfun->machine->is_no_gccisr = avr_no_gccisr_function_p (decl);
1446 const char *isr = cfun->machine->is_interrupt ? "interrupt" : "signal";
1448 /* Too much attributes make no sense as they request conflicting features. */
1450 if (cfun->machine->is_OS_task
1451 && (cfun->machine->is_signal || cfun->machine->is_interrupt))
1452 error_at (loc, "function attributes %qs and %qs are mutually exclusive",
1453 "OS_task", isr);
1455 if (cfun->machine->is_OS_main
1456 && (cfun->machine->is_signal || cfun->machine->is_interrupt))
1457 error_at (loc, "function attributes %qs and %qs are mutually exclusive",
1458 "OS_main", isr);
1460 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
1462 tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
1463 tree ret = TREE_TYPE (TREE_TYPE (decl));
1464 const char *name;
1466 name = DECL_ASSEMBLER_NAME_SET_P (decl)
1467 ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
1468 : IDENTIFIER_POINTER (DECL_NAME (decl));
1470 /* Skip a leading '*' that might still prefix the assembler name,
1471 e.g. in non-LTO runs. */
1473 name = default_strip_name_encoding (name);
1475 /* Interrupt handlers must be void __vector (void) functions. */
1477 if (args && TREE_CODE (TREE_VALUE (args)) != VOID_TYPE)
1478 error_at (loc, "%qs function cannot have arguments", isr);
1480 if (TREE_CODE (ret) != VOID_TYPE)
1481 error_at (loc, "%qs function cannot return a value", isr);
1483 #if defined WITH_AVRLIBC
1484 /* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
1485 using this when it switched from SIGNAL and INTERRUPT to ISR. */
1487 if (cfun->machine->is_interrupt)
1488 cfun->machine->is_signal = 0;
1490 /* If the function has the 'signal' or 'interrupt' attribute, ensure
1491 that the name of the function is "__vector_NN" so as to catch
1492 when the user misspells the vector name. */
1494 if (!startswith (name, "__vector"))
1495 warning_at (loc, OPT_Wmisspelled_isr, "%qs appears to be a misspelled "
1496 "%qs handler, missing %<__vector%> prefix", name, isr);
1497 #endif // AVR-LibC naming conventions
1500 #if defined WITH_AVRLIBC
1501 // Common problem is using "ISR" without first including avr/interrupt.h.
1502 const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1503 name = default_strip_name_encoding (name);
1504 if (strcmp ("ISR", name) == 0)
1506 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a reserved identifier"
1507 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>"
1508 " before using the %qs macro", name, name);
1510 if (strcmp ("INTERRUPT", name) == 0
1511 || strcmp ("SIGNAL", name) == 0)
1513 warning_at (loc, OPT_Wmisspelled_isr, "%qs is a deprecated identifier"
1514 " in AVR-LibC. Consider %<#include <avr/interrupt.h>%>"
1515 " or %<#include <compat/deprecated.h>%>"
1516 " before using the %qs macro", name, name);
1518 #endif // AVR-LibC naming conventions
1520 /* Don't print the above diagnostics more than once. */
1522 cfun->machine->attributes_checked_p = 1;
1526 /* Implement `ACCUMULATE_OUTGOING_ARGS'. */
1529 avr_accumulate_outgoing_args (void)
1531 if (!cfun)
1532 return TARGET_ACCUMULATE_OUTGOING_ARGS;
1534 /* FIXME: For setjmp and in avr_builtin_setjmp_frame_value we don't know
1535 what offset is correct. In some cases it is relative to
1536 virtual_outgoing_args_rtx and in others it is relative to
1537 virtual_stack_vars_rtx. For example code see
1538 gcc.c-torture/execute/built-in-setjmp.c
1539 gcc.c-torture/execute/builtins/sprintf-chk.c */
1541 return (TARGET_ACCUMULATE_OUTGOING_ARGS
1542 && !(cfun->calls_setjmp
1543 || cfun->has_nonlocal_label));
1547 /* Report contribution of accumulated outgoing arguments to stack size. */
1549 static inline int
1550 avr_outgoing_args_size (void)
1552 return (ACCUMULATE_OUTGOING_ARGS
1553 ? (HOST_WIDE_INT) crtl->outgoing_args_size : 0);
1557 /* Implement `TARGET_STARTING_FRAME_OFFSET'. */
1558 /* This is the offset from the frame pointer register to the first stack slot
1559 that contains a variable living in the frame. */
1561 static HOST_WIDE_INT
1562 avr_starting_frame_offset (void)
1564 return 1 + avr_outgoing_args_size ();
1568 /* Return the number of hard registers to push/pop in the prologue/epilogue
1569 of the current function, and optionally store these registers in SET. */
1571 static int
1572 avr_regs_to_save (HARD_REG_SET *set)
1574 int count = 0;
1575 int int_or_sig_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
1577 if (set)
1578 CLEAR_HARD_REG_SET (*set);
1580 /* No need to save any registers if the function never returns or
1581 has the "OS_task" or "OS_main" attribute. */
1583 if (TREE_THIS_VOLATILE (current_function_decl)
1584 || cfun->machine->is_OS_task
1585 || cfun->machine->is_OS_main)
1586 return 0;
1588 for (int reg = REG_0; reg < REG_32; reg++)
1590 /* Do not push/pop __tmp_reg__, __zero_reg__, as well as
1591 any global register variables. */
1593 if (fixed_regs[reg])
1594 continue;
1596 if ((int_or_sig_p && !crtl->is_leaf && call_used_or_fixed_reg_p (reg))
1597 || (df_regs_ever_live_p (reg)
1598 && (int_or_sig_p || !call_used_or_fixed_reg_p (reg))
1599 /* Don't record frame pointer registers here. They are treated
1600 indivitually in prologue. */
1601 && !(frame_pointer_needed
1602 && (reg == REG_Y || reg == REG_Y + 1))))
1604 if (set)
1605 SET_HARD_REG_BIT (*set, reg);
1606 count++;
1609 return count;
1613 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1615 static bool
1616 avr_allocate_stack_slots_for_args (void)
1618 return !cfun->machine->is_naked;
1622 /* Implement `TARGET_CAN_ELIMINATE'. */
1623 /* Return true if register FROM can be eliminated via register TO. */
1625 static bool
1626 avr_can_eliminate (const int /*from*/, const int to)
1628 return ((frame_pointer_needed && to == FRAME_POINTER_REGNUM)
1629 || !frame_pointer_needed);
1633 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1635 static bool
1636 avr_warn_func_return (tree decl)
1638 /* Naked functions are implemented entirely in assembly, including the
1639 return sequence, so suppress warnings about this. */
1641 return !avr_naked_function_p (decl);
1645 /* Worker function for `INITIAL_ELIMINATION_OFFSET'. */
1646 /* Compute offset between arg_pointer and frame_pointer. */
1649 avr_initial_elimination_offset (int from, int to)
1651 if (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
1652 return 0;
1653 else
1655 int offset = frame_pointer_needed ? 2 : 0;
1656 int avr_pc_size = AVR_HAVE_EIJMP_EICALL ? 3 : 2;
1658 // If FROM is ARG_POINTER_REGNUM, we are not in an ISR as ISRs
1659 // might not have arguments. Hence the following is not affected
1660 // by gasisr prologues.
1661 offset += avr_regs_to_save (NULL);
1662 return (get_frame_size () + avr_outgoing_args_size()
1663 + avr_pc_size + 1 + offset);
1668 /* Helper for the function below. */
1670 static void
1671 avr_adjust_type_node (tree *node, machine_mode mode, int sat_p)
1673 *node = make_node (FIXED_POINT_TYPE);
1674 TYPE_SATURATING (*node) = sat_p;
1675 TYPE_UNSIGNED (*node) = UNSIGNED_FIXED_POINT_MODE_P (mode);
1676 TYPE_IBIT (*node) = GET_MODE_IBIT (mode);
1677 TYPE_FBIT (*node) = GET_MODE_FBIT (mode);
1678 TYPE_PRECISION (*node) = GET_MODE_BITSIZE (mode);
1679 SET_TYPE_ALIGN (*node, 8);
1680 SET_TYPE_MODE (*node, mode);
1682 layout_type (*node);
1686 /* Implement `TARGET_BUILD_BUILTIN_VA_LIST'. */
1688 static tree
1689 avr_build_builtin_va_list (void)
1691 /* avr-modes.def adjusts [U]TA to be 64-bit modes with 48 fractional bits.
1692 This is more appropriate for the 8-bit machine AVR than 128-bit modes.
1693 The ADJUST_IBIT/FBIT are handled in toplev:init_adjust_machine_modes()
1694 which is auto-generated by genmodes, but the compiler assigns [U]DAmode
1695 to the long long accum modes instead of the desired [U]TAmode.
1697 Fix this now, right after node setup in tree.cc:build_common_tree_nodes().
1698 This must run before c-cppbuiltin.cc:builtin_define_fixed_point_constants()
1699 which built-in defines macros like __ULLACCUM_FBIT__ that are used by
1700 libgcc to detect IBIT and FBIT. */
1702 avr_adjust_type_node (&ta_type_node, TAmode, 0);
1703 avr_adjust_type_node (&uta_type_node, UTAmode, 0);
1704 avr_adjust_type_node (&sat_ta_type_node, TAmode, 1);
1705 avr_adjust_type_node (&sat_uta_type_node, UTAmode, 1);
1707 unsigned_long_long_accum_type_node = uta_type_node;
1708 long_long_accum_type_node = ta_type_node;
1709 sat_unsigned_long_long_accum_type_node = sat_uta_type_node;
1710 sat_long_long_accum_type_node = sat_ta_type_node;
1712 /* Dispatch to the default handler. */
1714 return std_build_builtin_va_list ();
1718 /* Worker function for `INCOMING_RETURN_ADDR_RTX'. */
1719 /* Return contents of MEM at frame pointer + stack size + 1 (+2 if 3-byte PC).
1720 This is return address of function. */
1723 avr_return_addr_rtx (int count, rtx tem)
1725 rtx r;
1727 /* Can only return this function's return address. Others not supported. */
1728 if (count)
1729 return NULL;
1731 if (AVR_3_BYTE_PC)
1733 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+2");
1734 warning (0, "%<builtin_return_address%> contains only 2 bytes"
1735 " of address");
1737 else
1738 r = gen_rtx_SYMBOL_REF (Pmode, ".L__stack_usage+1");
1740 cfun->machine->use_L__stack_usage = 1;
1742 r = gen_rtx_PLUS (Pmode, tem, r);
1743 r = gen_frame_mem (Pmode, memory_address (Pmode, r));
1744 r = gen_rtx_ROTATE (HImode, r, GEN_INT (8));
1745 return r;
1748 /* Return 1 if the function epilogue is just a single "ret". */
1751 avr_simple_epilogue (void)
1753 return (! frame_pointer_needed
1754 && get_frame_size () == 0
1755 && avr_outgoing_args_size() == 0
1756 && avr_regs_to_save (NULL) == 0
1757 && ! cfun->machine->is_interrupt
1758 && ! cfun->machine->is_signal
1759 && ! cfun->machine->is_naked
1760 && ! TREE_THIS_VOLATILE (current_function_decl));
1763 /* This function checks sequence of live registers. */
1765 static int
1766 sequent_regs_live (void)
1768 int live_seq = 0;
1769 int cur_seq = 0;
1771 for (int reg = 0; reg <= LAST_CALLEE_SAVED_REG; ++reg)
1773 if (fixed_regs[reg])
1775 /* Don't recognize sequences that contain global register
1776 variables. */
1778 if (live_seq != 0)
1779 return 0;
1780 else
1781 continue;
1784 if (!call_used_or_fixed_reg_p (reg))
1786 if (df_regs_ever_live_p (reg))
1788 ++live_seq;
1789 ++cur_seq;
1791 else
1792 cur_seq = 0;
1796 if (!frame_pointer_needed)
1798 if (df_regs_ever_live_p (REG_Y))
1800 ++live_seq;
1801 ++cur_seq;
1803 else
1804 cur_seq = 0;
1806 if (df_regs_ever_live_p (REG_Y + 1))
1808 ++live_seq;
1809 ++cur_seq;
1811 else
1812 cur_seq = 0;
1814 else
1816 cur_seq += 2;
1817 live_seq += 2;
1819 return (cur_seq == live_seq) ? live_seq : 0;
1823 namespace {
1824 static const pass_data avr_pass_data_fuse_add =
1826 RTL_PASS, // type
1827 "", // name (will be patched)
1828 OPTGROUP_NONE, // optinfo_flags
1829 TV_DF_SCAN, // tv_id
1830 0, // properties_required
1831 0, // properties_provided
1832 0, // properties_destroyed
1833 0, // todo_flags_start
1834 TODO_df_finish // todo_flags_finish
1838 class avr_pass_fuse_add : public rtl_opt_pass
1840 public:
1841 avr_pass_fuse_add (gcc::context *ctxt, const char *name)
1842 : rtl_opt_pass (avr_pass_data_fuse_add, ctxt)
1844 this->name = name;
1847 virtual bool gate (function *) { return optimize && avr_fuse_add > 0; }
1849 virtual unsigned int execute (function *);
1851 struct Some_Insn
1853 rtx_insn *insn = nullptr;
1854 rtx dest, src;
1855 bool valid () const { return insn != nullptr; }
1856 void set_deleted ()
1858 gcc_assert (insn);
1859 SET_INSN_DELETED (insn);
1860 insn = nullptr;
1864 // If .insn is not NULL, then this is a reg:HI += const_int
1865 // of an address register.
1866 struct Add_Insn : Some_Insn
1868 rtx addend;
1869 int regno;
1870 Add_Insn () {}
1871 Add_Insn (rtx_insn *insn);
1874 // If .insn is not NULL, then this sets an address register
1875 // to a constant value.
1876 struct Ldi_Insn : Some_Insn
1878 int regno;
1879 Ldi_Insn () {}
1880 Ldi_Insn (rtx_insn *insn);
1883 // If .insn is not NULL, then this is a load or store insn where the
1884 // address is REG or POST_INC with an address register.
1885 struct Mem_Insn : Some_Insn
1887 rtx reg_or_0, mem, addr, addr_reg;
1888 int addr_regno;
1889 enum rtx_code addr_code;
1890 machine_mode mode;
1891 addr_space_t addr_space;
1892 bool store_p, volatile_p;
1893 Mem_Insn () {}
1894 Mem_Insn (rtx_insn *insn);
1897 rtx_insn *fuse_ldi_add (Ldi_Insn &prev_ldi, Add_Insn &add);
1898 rtx_insn *fuse_add_add (Add_Insn &prev_add, Add_Insn &add);
1899 rtx_insn *fuse_add_mem (Add_Insn &prev_add, Mem_Insn &mem);
1900 rtx_insn *fuse_mem_add (Mem_Insn &prev_mem, Add_Insn &add);
1901 }; // avr_pass_fuse_add
1903 } // anon namespace
1905 rtl_opt_pass *
1906 make_avr_pass_fuse_add (gcc::context *ctxt)
1908 return new avr_pass_fuse_add (ctxt, "avr-fuse-add");
1911 /* Describe properties of AVR's indirect load and store instructions
1912 LD, LDD, ST, STD, LPM, ELPM depending on register number, volatility etc.
1913 Rules for "volatile" accesses are:
1915 | Xmega | non-Xmega
1916 ------+-----------------+----------------
1917 load | read LSB first | read LSB first
1918 store | write LSB first | write MSB first
1921 struct AVR_LdSt_Props
1923 bool has_postinc, has_predec, has_ldd;
1924 // The insn printers will use POST_INC or PRE_DEC addressing, no matter
1925 // what adressing modes we are feeding into them.
1926 bool want_postinc, want_predec;
1928 AVR_LdSt_Props (int regno, bool store_p, bool volatile_p, addr_space_t as)
1930 bool generic_p = ADDR_SPACE_GENERIC_P (as);
1931 bool flashx_p = ! generic_p && as != ADDR_SPACE_MEMX;
1932 has_postinc = generic_p || (flashx_p && regno == REG_Z);
1933 has_predec = generic_p;
1934 has_ldd = ! AVR_TINY && generic_p && (regno == REG_Y || regno == REG_Z);
1935 want_predec = volatile_p && generic_p && ! AVR_XMEGA && store_p;
1936 want_postinc = volatile_p && generic_p && (AVR_XMEGA || ! store_p);
1937 want_postinc |= flashx_p && regno == REG_Z;
1940 AVR_LdSt_Props (const avr_pass_fuse_add::Mem_Insn &m)
1941 : AVR_LdSt_Props (m.addr_regno, m.store_p, m.volatile_p, m.addr_space)
1943 gcc_assert (m.valid ());
1947 /* Emit a single_set that clobbers REG_CC. */
1949 static rtx_insn *
1950 emit_move_ccc (rtx dest, rtx src)
1952 return emit_insn (gen_gen_move_clobbercc (dest, src));
1955 /* Emit a single_set that clobbers REG_CC after insn AFTER. */
1957 static rtx_insn *
1958 emit_move_ccc_after (rtx dest, rtx src, rtx_insn *after)
1960 return emit_insn_after (gen_gen_move_clobbercc (dest, src), after);
1963 static bool
1964 reg_seen_between_p (const_rtx reg, const rtx_insn *from, const rtx_insn *to)
1966 return (reg_used_between_p (reg, from, to)
1967 || reg_set_between_p (reg, from, to));
1971 static void
1972 avr_maybe_adjust_cfa (rtx_insn *insn, rtx reg, int addend)
1974 if (addend
1975 && frame_pointer_needed
1976 && REGNO (reg) == FRAME_POINTER_REGNUM
1977 && avr_fuse_add == 3)
1979 rtx plus = plus_constant (Pmode, reg, addend);
1980 RTX_FRAME_RELATED_P (insn) = 1;
1981 add_reg_note (insn, REG_CFA_ADJUST_CFA, gen_rtx_SET (reg, plus));
1986 // If successful, this represents a SET of a pointer register to a constant.
1987 avr_pass_fuse_add::Ldi_Insn::Ldi_Insn (rtx_insn *insn)
1989 rtx set = single_set (insn);
1990 if (!set)
1991 return;
1993 src = SET_SRC (set);
1994 dest = SET_DEST (set);
1996 if (REG_P (dest)
1997 && GET_MODE (dest) == Pmode
1998 && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z)
1999 && CONSTANT_P (src))
2001 this->insn = insn;
2005 // If successful, this represents a PLUS with CONST_INT of a pointer
2006 // register X, Y or Z. Otherwise, the object is not valid().
2007 avr_pass_fuse_add::Add_Insn::Add_Insn (rtx_insn *insn)
2009 rtx set = single_set (insn);
2010 if (!set)
2011 return;
2013 src = SET_SRC (set);
2014 dest = SET_DEST (set);
2015 if (REG_P (dest)
2016 // We are only interested in PLUSes that change address regs.
2017 && GET_MODE (dest) == Pmode
2018 && IN_RANGE (regno = REGNO (dest), REG_X, REG_Z)
2019 && PLUS == GET_CODE (src)
2020 && rtx_equal_p (XEXP (src, 0), dest)
2021 && CONST_INT_P (XEXP (src, 1)))
2023 // This is reg:HI += const_int.
2024 addend = XEXP (src, 1);
2025 this->insn = insn;
2029 // If successful, this represents a load or store insn where the addressing
2030 // mode uses pointer register X, Y or Z. Otherwise, the object is not valid().
2031 avr_pass_fuse_add::Mem_Insn::Mem_Insn (rtx_insn *insn)
2033 rtx set = single_set (insn);
2034 if (!set)
2035 return;
2037 src = SET_SRC (set);
2038 dest = SET_DEST (set);
2039 mode = GET_MODE (dest);
2041 if (MEM_P (dest)
2042 && (REG_P (src) || src == CONST0_RTX (mode)))
2044 reg_or_0 = src;
2045 mem = dest;
2047 else if (REG_P (dest) && MEM_P (src))
2049 reg_or_0 = dest;
2050 mem = src;
2052 else
2053 return;
2055 addr = XEXP (mem, 0);
2056 addr_code = GET_CODE (addr);
2058 if (addr_code == REG)
2059 addr_reg = addr;
2060 else if (addr_code == POST_INC || addr_code == PRE_DEC)
2061 addr_reg = XEXP (addr, 0);
2062 else
2063 return;
2065 addr_regno = REGNO (addr_reg);
2067 if (avr_fuse_add == 2
2068 && frame_pointer_needed
2069 && addr_regno == FRAME_POINTER_REGNUM)
2070 MEM_VOLATILE_P (mem) = 0;
2072 if (reg_overlap_mentioned_p (reg_or_0, addr) // Can handle CONSTANT_P.
2073 || addr_regno > REG_Z
2074 || avr_mem_memx_p (mem)
2075 // The following optimizations only handle REG and POST_INC,
2076 // so that's all what we allow here.
2077 || (addr_code != REG && addr_code != POST_INC))
2078 return;
2080 addr_space = MEM_ADDR_SPACE (mem);
2081 volatile_p = MEM_VOLATILE_P (mem);
2082 store_p = MEM_P (dest);
2084 // Turn this "valid".
2085 this->insn = insn;
2088 /* Try to combine a Ldi insn with a PLUS CONST_INT addend to one Ldi insn.
2089 If LDI is valid, then it precedes ADD in the same block.
2090 When a replacement is found, a new insn is emitted and the old insns
2091 are pseudo-deleted. The returned insn is the point where the calling
2092 scanner should continue. When no replacement is found, nullptr is
2093 returned and nothing changed. */
2095 rtx_insn *
2096 avr_pass_fuse_add::fuse_ldi_add (Ldi_Insn &ldi, Add_Insn &add)
2098 if (! ldi.valid ()
2099 || reg_seen_between_p (ldi.dest, ldi.insn, add.insn))
2101 // If something is between the Ldi and the current insn, we can
2102 // set the Ldi invalid to speed future scans.
2103 return ldi.insn = nullptr;
2106 // Found a Ldi with const and a PLUS insns in the same BB,
2107 // and with no interfering insns between them.
2109 // Emit new Ldi with the sum of the original offsets after the old Ldi.
2110 rtx xval = plus_constant (Pmode, ldi.src, INTVAL (add.addend));
2112 rtx_insn *insn = emit_move_ccc_after (ldi.dest, xval, ldi.insn);
2113 avr_dump (";; new Ldi[%d] insn %d after %d: R%d = %r\n\n", ldi.regno,
2114 INSN_UID (insn), INSN_UID (ldi.insn), ldi.regno, xval);
2116 rtx_insn *next = NEXT_INSN (add.insn);
2117 ldi.set_deleted ();
2118 add.set_deleted ();
2120 return next;
2123 /* Try to combine two PLUS insns with CONST_INT addend to one such insn.
2124 If PREV_ADD is valid, then it precedes ADD in the same basic block.
2125 When a replacement is found, a new insn is emitted and the old insns
2126 are pseudo-deleted. The returned insn is the point where the calling
2127 scanner should continue. When no replacement is found, nullptr is
2128 returned and nothing changed. */
2130 rtx_insn *
2131 avr_pass_fuse_add::fuse_add_add (Add_Insn &prev_add, Add_Insn &add)
2133 if (! prev_add.valid ()
2134 || reg_seen_between_p (add.dest, prev_add.insn, add.insn))
2136 // If something is between the previous Add and the current insn,
2137 // we can set the previous Add invalid to speed future scans.
2138 return prev_add.insn = nullptr;
2141 // Found two PLUS insns in the same BB, and with no interfering
2142 // insns between them.
2143 rtx plus = plus_constant (Pmode, add.src, INTVAL (prev_add.addend));
2145 rtx_insn *next;
2146 if (REG_P (plus))
2148 avr_dump (";; Add[%d] from %d annihilates %d\n\n", add.regno,
2149 INSN_UID (prev_add.insn), INSN_UID (add.insn));
2150 next = NEXT_INSN (add.insn);
2152 else
2154 // Emit after the current insn, so that it will be picked
2155 // up as next valid Add insn.
2156 next = emit_move_ccc_after (add.dest, plus, add.insn);
2157 avr_dump (";; #1 new Add[%d] insn %d after %d: R%d += %d\n\n",
2158 add.regno, INSN_UID (next), INSN_UID (add.insn),
2159 add.regno, (int) INTVAL (XEXP (plus, 1)));
2160 gcc_assert (GET_CODE (plus) == PLUS);
2163 add.set_deleted ();
2164 prev_add.set_deleted ();
2166 return next;
2169 /* Try to combine a PLUS of the address register with a load or store insn.
2170 If ADD is valid, then it precedes MEM in the same basic block.
2171 When a replacement is found, a new insn is emitted and the old insns
2172 are pseudo-deleted. The returned insn is the point where the calling
2173 scanner should continue. When no replacement is found, nullptr is
2174 returned and nothing changed. */
2176 rtx_insn *
2177 avr_pass_fuse_add::fuse_add_mem (Add_Insn &add, Mem_Insn &mem)
2179 if (! add.valid ()
2180 || reg_seen_between_p (add.dest, add.insn, mem.insn))
2182 // If something is between the Add and the current insn, we can
2183 // set the Add invalid to speed future scans.
2184 return add.insn = nullptr;
2187 AVR_LdSt_Props ap { mem };
2189 int msize = GET_MODE_SIZE (mem.mode);
2191 // The mem insn really wants PRE_DEC.
2192 bool case1 = ((mem.addr_code == REG || mem.addr_code == POST_INC)
2193 && msize > 1 && ap.want_predec && ! ap.has_ldd);
2195 // The offset can be consumed by a PRE_DEC.
2196 bool case2 = (- INTVAL (add.addend) == msize
2197 && (mem.addr_code == REG || mem.addr_code == POST_INC)
2198 && ap.has_predec && ! ap.want_postinc);
2200 if (! case1 && ! case2)
2201 return nullptr;
2203 // Change from REG or POST_INC to PRE_DEC.
2204 rtx xmem = change_address (mem.mem, mem.mode,
2205 gen_rtx_PRE_DEC (Pmode, mem.addr_reg));
2206 rtx dest = mem.store_p ? xmem : mem.reg_or_0;
2207 rtx src = mem.store_p ? mem.reg_or_0 : xmem;
2209 rtx_insn *next = emit_move_ccc_after (dest, src, mem.insn);
2210 add_reg_note (next, REG_INC, mem.addr_reg);
2211 avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", mem.addr_regno,
2212 INSN_UID (next), INSN_UID (mem.insn), dest, src);
2214 // Changing REG or POST_INC -> PRE_DEC means that the addend before
2215 // the memory access must be increased by the size of the access,
2216 rtx plus = plus_constant (Pmode, add.src, msize);
2217 if (! REG_P (plus))
2219 rtx_insn *insn = emit_move_ccc_after (add.dest, plus, add.insn);
2220 avr_dump (";; #2 new Add[%d] insn %d after %d: R%d += %d\n\n",
2221 add.regno, INSN_UID (insn), INSN_UID (add.insn),
2222 add.regno, (int) INTVAL (XEXP (plus, 1)));
2223 gcc_assert (GET_CODE (plus) == PLUS);
2225 else
2226 avr_dump (";; Add[%d] insn %d consumed into %d\n\n",
2227 add.regno, INSN_UID (add.insn), INSN_UID (next));
2229 // Changing POST_INC -> PRE_DEC means that the addend after the mem has to be
2230 // the size of the access. The hope is that this new add insn may be unused.
2231 if (mem.addr_code == POST_INC)
2233 plus = plus_constant (Pmode, add.dest, msize);
2234 rtx_insn *next2 = emit_move_ccc_after (add.dest, plus, next);
2235 avr_dump (";; #3 new Add[%d] insn %d after %d: R%d += %d\n\n", add.regno,
2236 INSN_UID (next2), INSN_UID (next), add.regno, msize);
2237 next = next2;
2240 add.set_deleted ();
2241 mem.set_deleted ();
2243 return next;
2246 /* Try to combine a load or store insn with a PLUS of the address register.
2247 If MEM is valid, then it precedes ADD in the same basic block.
2248 When a replacement is found, a new insn is emitted and the old insns
2249 are pseudo-deleted. The returned insn is the point where the calling
2250 scanner should continue. When no replacement is found, nullptr is
2251 returned and nothing changed. */
2253 rtx_insn *
2254 avr_pass_fuse_add::fuse_mem_add (Mem_Insn &mem, Add_Insn &add)
2256 if (! mem.valid ()
2257 || reg_seen_between_p (add.dest, mem.insn, add.insn))
2259 // If something is between the Mem and the current insn, we can
2260 // set the Mem invalid to speed future scans.
2261 return mem.insn = nullptr;
2264 AVR_LdSt_Props ap { mem };
2266 int msize = GET_MODE_SIZE (mem.mode);
2268 // The add insn can be consumed by a POST_INC.
2269 bool case1 = (mem.addr_code == REG
2270 && INTVAL (add.addend) == msize
2271 && ap.has_postinc && ! ap.want_predec);
2273 // There are cases where even a partial consumption of the offset is better.
2274 // This are the cases where no LD+offset addressing is available, because
2275 // the address register is obviously used after the mem insn, and a mem insn
2276 // with REG addressing mode will have to restore the address.
2277 bool case2 = (mem.addr_code == REG
2278 && msize > 1 && ap.want_postinc && ! ap.has_ldd);
2280 if (! case1 && ! case2)
2281 return nullptr;
2283 // Change addressing mode from REG to POST_INC.
2284 rtx xmem = change_address (mem.mem, mem.mode,
2285 gen_rtx_POST_INC (Pmode, mem.addr_reg));
2286 rtx dest = mem.store_p ? xmem : mem.reg_or_0;
2287 rtx src = mem.store_p ? mem.reg_or_0 : xmem;
2289 rtx_insn *insn = emit_move_ccc_after (dest, src, mem.insn);
2290 add_reg_note (insn, REG_INC, mem.addr_reg);
2291 avr_dump (";; new Mem[%d] insn %d after %d: %r = %r\n\n", add.regno,
2292 INSN_UID (insn), INSN_UID (mem.insn), dest, src);
2294 rtx_insn *next = NEXT_INSN (add.insn);
2296 // Changing REG -> POST_INC means that the post addend must be
2297 // decreased by the size of the access.
2298 rtx plus = plus_constant (Pmode, add.src, -msize);
2299 if (! REG_P (plus))
2301 next = emit_move_ccc_after (mem.addr_reg, plus, add.insn);
2302 avr_dump (";; #4 new Add[%d] insn %d after %d: R%d += %d\n\n",
2303 add.regno, INSN_UID (next), INSN_UID (add.insn),
2304 add.regno, (int) INTVAL (XEXP (plus, 1)));
2305 gcc_assert (GET_CODE (plus) == PLUS);
2307 else
2308 avr_dump (";; Add[%d] insn %d consumed into %d\n\n",
2309 add.regno, INSN_UID (add.insn), INSN_UID (insn));
2311 add.set_deleted ();
2312 mem.set_deleted ();
2314 return next;
2317 /* Try to post-reload combine PLUS with CONST_INt of pointer registers with:
2318 - Sets to a constant address.
2319 - PLUS insn of that kind.
2320 - Indirect loads and stores.
2321 In almost all cases, combine opportunities arise from the preparation
2322 done by `avr_split_tiny_move', but in some rare cases combinations are
2323 found for the ordinary cores, too.
2324 As we consider at most one Mem insn per try, there may still be missed
2325 optimizations like POST_INC + PLUS + POST_INC might be performed
2326 as PRE_DEC + PRE_DEC for two adjacent locations. */
2328 unsigned int
2329 avr_pass_fuse_add::execute (function *func)
2331 df_note_add_problem ();
2332 df_analyze ();
2334 int n_add = 0, n_mem = 0, n_ldi = 0;
2335 basic_block bb;
2337 FOR_EACH_BB_FN (bb, func)
2339 Ldi_Insn prev_ldi_insns[REG_32];
2340 Add_Insn prev_add_insns[REG_32];
2341 Mem_Insn prev_mem_insns[REG_32];
2342 rtx_insn *insn, *curr;
2344 avr_dump ("\n;; basic block %d\n\n", bb->index);
2346 FOR_BB_INSNS_SAFE (bb, insn, curr)
2348 rtx_insn *next = nullptr;
2349 Ldi_Insn ldi_insn { insn };
2350 Add_Insn add_insn { insn };
2351 Mem_Insn mem_insn { insn };
2353 if (add_insn.valid ())
2355 // Found reg:HI += const_int
2356 avr_dump (";; insn %d: Add[%d]: R%d += %d\n\n",
2357 INSN_UID (add_insn.insn), add_insn.regno,
2358 add_insn.regno, (int) INTVAL (add_insn.addend));
2359 Ldi_Insn &prev_ldi_insn = prev_ldi_insns[add_insn.regno];
2360 Add_Insn &prev_add_insn = prev_add_insns[add_insn.regno];
2361 Mem_Insn &prev_mem_insn = prev_mem_insns[add_insn.regno];
2362 if ((next = fuse_ldi_add (prev_ldi_insn, add_insn)))
2363 curr = next, n_ldi += 1;
2364 else if ((next = fuse_add_add (prev_add_insn, add_insn)))
2365 curr = next, n_add += 1;
2366 else if ((next = fuse_mem_add (prev_mem_insn, add_insn)))
2367 curr = next, n_mem += 1;
2368 else
2369 prev_add_insn = add_insn;
2371 else if (mem_insn.valid ())
2373 int addr_regno = REGNO (mem_insn.addr_reg);
2374 avr_dump (";; insn %d: Mem[%d]: %r = %r\n\n",
2375 INSN_UID (mem_insn.insn), addr_regno,
2376 mem_insn.dest, mem_insn.src);
2377 Add_Insn &prev_add_insn = prev_add_insns[addr_regno];
2378 if ((next = fuse_add_mem (prev_add_insn, mem_insn)))
2379 curr = next, n_mem += 1;
2380 else
2381 prev_mem_insns[addr_regno] = mem_insn;
2383 else if (ldi_insn.valid ())
2385 if (! CONST_INT_P (ldi_insn.src))
2386 avr_dump (";; insn %d: Ldi[%d]: R%d = %r\n\n",
2387 INSN_UID (ldi_insn.insn), ldi_insn.regno,
2388 ldi_insn.regno, ldi_insn.src);
2389 prev_ldi_insns[ldi_insn.regno] = ldi_insn;
2391 } // for insns
2392 } // for BBs
2394 avr_dump (";; Function %f: Found %d changes: %d ldi, %d add, %d mem.\n",
2395 n_ldi + n_add + n_mem, n_ldi, n_add, n_mem);
2397 return 0;
2401 namespace {
2402 static const pass_data avr_pass_data_pre_proep =
2404 RTL_PASS, // type
2405 "", // name (will be patched)
2406 OPTGROUP_NONE, // optinfo_flags
2407 TV_DF_SCAN, // tv_id
2408 0, // properties_required
2409 0, // properties_provided
2410 0, // properties_destroyed
2411 0, // todo_flags_start
2412 0 // todo_flags_finish
2416 class avr_pass_pre_proep : public rtl_opt_pass
2418 public:
2419 avr_pass_pre_proep (gcc::context *ctxt, const char *name)
2420 : rtl_opt_pass (avr_pass_data_pre_proep, ctxt)
2422 this->name = name;
2425 void compute_maybe_gasisr (function *);
2427 virtual unsigned int execute (function *fun)
2429 if (avr_gasisr_prologues
2430 // Whether this function is an ISR worth scanning at all.
2431 && !fun->machine->is_no_gccisr
2432 && (fun->machine->is_interrupt
2433 || fun->machine->is_signal)
2434 && !cfun->machine->is_naked
2435 // Paranoia: Non-local gotos and labels that might escape.
2436 && !cfun->calls_setjmp
2437 && !cfun->has_nonlocal_label
2438 && !cfun->has_forced_label_in_static)
2440 compute_maybe_gasisr (fun);
2443 return 0;
2446 }; // avr_pass_pre_proep
2448 } // anon namespace
2450 rtl_opt_pass *
2451 make_avr_pass_pre_proep (gcc::context *ctxt)
2453 return new avr_pass_pre_proep (ctxt, "avr-pre-proep");
2457 /* Set fun->machine->gasisr.maybe provided we don't find anything that
2458 prohibits GAS generating parts of ISR prologues / epilogues for us. */
2460 void
2461 avr_pass_pre_proep::compute_maybe_gasisr (function *fun)
2463 // Don't use BB iterators so that we see JUMP_TABLE_DATA.
2465 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
2467 // Transparent calls always use [R]CALL and are filtered out by GAS.
2468 // ISRs don't use -mcall-prologues, hence what remains to be filtered
2469 // out are open coded (tail) calls.
2471 if (CALL_P (insn))
2472 return;
2474 // __tablejump2__ clobbers something and is targeted by JMP so
2475 // that GAS won't see its usage.
2477 if (AVR_HAVE_JMP_CALL
2478 && JUMP_TABLE_DATA_P (insn))
2479 return;
2481 // Non-local gotos not seen in *FUN.
2483 if (JUMP_P (insn)
2484 && find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
2485 return;
2488 fun->machine->gasisr.maybe = 1;
2492 /* Obtain the length sequence of insns. */
2495 get_sequence_length (rtx_insn *insns)
2497 int length = 0;
2499 for (rtx_insn *insn = insns; insn; insn = NEXT_INSN (insn))
2500 length += get_attr_length (insn);
2502 return length;
2506 /* Implement `INCOMING_RETURN_ADDR_RTX'. */
2509 avr_incoming_return_addr_rtx (void)
2511 /* The return address is at the top of the stack. Note that the push
2512 was via post-decrement, which means the actual address is off by one. */
2513 return gen_frame_mem (HImode, plus_constant (Pmode, stack_pointer_rtx, 1));
2517 /* Unset a bit in *SET. If successful, return the respective bit number.
2518 Otherwise, return -1 and *SET is unaltered. */
2520 static int
2521 avr_hregs_split_reg (HARD_REG_SET *set)
2523 for (int regno = REG_0; regno < REG_32; regno++)
2524 if (TEST_HARD_REG_BIT (*set, regno))
2526 // Don't remove a register from *SET which might indicate that
2527 // some RAMP* register might need ISR prologue / epilogue treatment.
2529 if (AVR_HAVE_RAMPX
2530 && (REG_X == regno || REG_X + 1 == regno)
2531 && TEST_HARD_REG_BIT (*set, REG_X)
2532 && TEST_HARD_REG_BIT (*set, REG_X + 1))
2533 continue;
2535 if (AVR_HAVE_RAMPY
2536 && !frame_pointer_needed
2537 && (REG_Y == regno || REG_Y + 1 == regno)
2538 && TEST_HARD_REG_BIT (*set, REG_Y)
2539 && TEST_HARD_REG_BIT (*set, REG_Y + 1))
2540 continue;
2542 if (AVR_HAVE_RAMPZ
2543 && (REG_Z == regno || REG_Z + 1 == regno)
2544 && TEST_HARD_REG_BIT (*set, REG_Z)
2545 && TEST_HARD_REG_BIT (*set, REG_Z + 1))
2546 continue;
2548 CLEAR_HARD_REG_BIT (*set, regno);
2549 return regno;
2552 return -1;
2556 /* Helper for expand_prologue. Emit a push of a byte register. */
2558 static void
2559 emit_push_byte (unsigned regno, bool frame_related_p)
2561 rtx mem, reg;
2562 rtx_insn *insn;
2564 mem = gen_rtx_POST_DEC (HImode, stack_pointer_rtx);
2565 mem = gen_frame_mem (QImode, mem);
2566 reg = gen_rtx_REG (QImode, regno);
2568 insn = emit_insn (gen_rtx_SET (mem, reg));
2569 if (frame_related_p)
2570 RTX_FRAME_RELATED_P (insn) = 1;
2572 cfun->machine->stack_usage++;
2576 /* Helper for expand_prologue. Emit a push of a SFR via register TREG.
2577 SFR is a MEM representing the memory location of the SFR.
2578 If CLR_P then clear the SFR after the push using zero_reg. */
2580 static void
2581 emit_push_sfr (rtx sfr, bool frame_related_p, bool clr_p, int treg)
2583 gcc_assert (MEM_P (sfr));
2585 /* IN treg, IO(SFR) */
2586 rtx_insn *insn = emit_move_insn (all_regs_rtx[treg], sfr);
2587 if (frame_related_p)
2588 RTX_FRAME_RELATED_P (insn) = 1;
2590 /* PUSH treg */
2591 emit_push_byte (treg, frame_related_p);
2593 if (clr_p)
2595 /* OUT IO(SFR), __zero_reg__ */
2596 insn = emit_move_insn (sfr, const0_rtx);
2597 if (frame_related_p)
2598 RTX_FRAME_RELATED_P (insn) = 1;
2602 static void
2603 avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set)
2605 rtx_insn *insn;
2606 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
2607 int live_seq = sequent_regs_live ();
2609 HOST_WIDE_INT size_max
2610 = (HOST_WIDE_INT) GET_MODE_MASK (AVR_HAVE_8BIT_SP ? QImode : Pmode);
2612 bool minimize = (TARGET_CALL_PROLOGUES
2613 && size < size_max
2614 && live_seq
2615 && !isr_p
2616 && !cfun->machine->is_OS_task
2617 && !cfun->machine->is_OS_main
2618 && !AVR_TINY);
2620 if (minimize
2621 && (frame_pointer_needed
2622 || avr_outgoing_args_size() > 8
2623 || (AVR_2_BYTE_PC && live_seq > 6)
2624 || live_seq > 7))
2626 rtx pattern;
2627 int reg, offset;
2629 emit_move_insn (gen_rtx_REG (HImode, REG_X),
2630 gen_int_mode (size, HImode));
2632 pattern = gen_call_prologue_saves (gen_int_mode (live_seq, HImode),
2633 gen_int_mode (live_seq+size, HImode));
2634 insn = emit_insn (pattern);
2635 RTX_FRAME_RELATED_P (insn) = 1;
2637 /* Describe the effect of the unspec_volatile call to prologue_saves.
2638 Note that this formulation assumes that add_reg_note pushes the
2639 notes to the front. Thus we build them in the reverse order of
2640 how we want dwarf2out to process them. */
2642 /* The function does always set frame_pointer_rtx, but whether that
2643 is going to be permanent in the function is frame_pointer_needed. */
2645 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2646 gen_rtx_SET ((frame_pointer_needed
2647 ? frame_pointer_rtx
2648 : stack_pointer_rtx),
2649 plus_constant (Pmode, stack_pointer_rtx,
2650 -(size + live_seq))));
2652 /* Note that live_seq always contains r28+r29, but the other
2653 registers to be saved are all below 18. */
2655 int first_reg = (LAST_CALLEE_SAVED_REG + 1) - (live_seq - 2);
2657 for (reg = REG_29, offset = -live_seq + 1;
2658 reg >= first_reg;
2659 reg = (reg == REG_28 ? LAST_CALLEE_SAVED_REG : reg - 1), ++offset)
2661 rtx m, r;
2663 m = gen_rtx_MEM (QImode, plus_constant (Pmode, stack_pointer_rtx,
2664 offset));
2665 r = gen_rtx_REG (QImode, reg);
2666 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (m, r));
2669 cfun->machine->stack_usage += size + live_seq;
2671 else /* !minimize */
2673 for (int reg = REG_0; reg < REG_32; ++reg)
2674 if (TEST_HARD_REG_BIT (set, reg))
2675 emit_push_byte (reg, true);
2677 if (frame_pointer_needed
2678 && (!(cfun->machine->is_OS_task || cfun->machine->is_OS_main)))
2680 /* Push frame pointer. Always be consistent about the
2681 ordering of pushes -- epilogue_restores expects the
2682 register pair to be pushed low byte first. */
2684 emit_push_byte (REG_Y, true);
2685 emit_push_byte (REG_Y + 1, true);
2688 if (frame_pointer_needed
2689 && size == 0)
2691 insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
2692 RTX_FRAME_RELATED_P (insn) = 1;
2695 if (size != 0)
2697 /* Creating a frame can be done by direct manipulation of the
2698 stack or via the frame pointer. These two methods are:
2699 fp = sp
2700 fp -= size
2701 sp = fp
2703 sp -= size
2704 fp = sp (*)
2705 the optimum method depends on function type, stack and
2706 frame size. To avoid a complex logic, both methods are
2707 tested and shortest is selected.
2709 There is also the case where SIZE != 0 and no frame pointer is
2710 needed; this can occur if ACCUMULATE_OUTGOING_ARGS is on.
2711 In that case, insn (*) is not needed in that case.
2712 We use the X register as scratch. This is save because in X
2713 is call-clobbered.
2714 In an interrupt routine, the case of SIZE != 0 together with
2715 !frame_pointer_needed can only occur if the function is not a
2716 leaf function and thus X has already been saved. */
2718 int irq_state = -1;
2719 HOST_WIDE_INT size_cfa = size, neg_size;
2720 rtx_insn *fp_plus_insns;
2722 gcc_assert (frame_pointer_needed
2723 || !isr_p
2724 || !crtl->is_leaf);
2726 rtx my_fp = (frame_pointer_needed
2727 ? frame_pointer_rtx
2728 : gen_rtx_REG (Pmode, REG_X));
2729 rtx fp = my_fp;
2731 if (AVR_HAVE_8BIT_SP)
2733 /* The high byte (r29) does not change:
2734 Prefer SUBI (1 cycle) over SBIW (2 cycles, same size). */
2736 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
2739 /* Cut down size and avoid size = 0 so that we don't run
2740 into ICE like PR52488 in the remainder. */
2742 if (size > size_max)
2744 /* Don't error so that insane code from newlib still compiles
2745 and does not break building newlib. As PR51345 is implemented
2746 now, there are multilib variants with -msp8.
2748 If user wants sanity checks he can use -Wstack-usage=
2749 or similar options.
2751 For CFA we emit the original, non-saturated size so that
2752 the generic machinery is aware of the real stack usage and
2753 will print the above diagnostic as expected. */
2755 size = size_max;
2758 size = trunc_int_for_mode (size, GET_MODE (my_fp));
2759 neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
2761 /************ Method 1: Adjust frame pointer ************/
2763 start_sequence ();
2765 /* Normally, the dwarf2out frame-related-expr interpreter does
2766 not expect to have the CFA change once the frame pointer is
2767 set up. Thus, we avoid marking the move insn below and
2768 instead indicate that the entire operation is complete after
2769 the frame pointer subtraction is done. */
2771 insn = emit_move_insn (fp, stack_pointer_rtx);
2772 if (frame_pointer_needed)
2774 RTX_FRAME_RELATED_P (insn) = 1;
2775 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2776 gen_rtx_SET (fp, stack_pointer_rtx));
2779 insn = emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp),
2780 my_fp, neg_size));
2782 if (frame_pointer_needed)
2784 RTX_FRAME_RELATED_P (insn) = 1;
2785 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2786 gen_rtx_SET (fp, plus_constant (Pmode, fp,
2787 -size_cfa)));
2790 /* Copy to stack pointer. Note that since we've already
2791 changed the CFA to the frame pointer this operation
2792 need not be annotated if frame pointer is needed.
2793 Always move through unspec, see PR50063.
2794 For meaning of irq_state see movhi_sp_r insn. */
2796 if (cfun->machine->is_interrupt)
2797 irq_state = 1;
2799 if (TARGET_NO_INTERRUPTS
2800 || cfun->machine->is_signal
2801 || cfun->machine->is_OS_main)
2802 irq_state = 0;
2804 if (AVR_HAVE_8BIT_SP)
2805 irq_state = 2;
2807 insn = emit_insn (gen_movhi_sp_r (stack_pointer_rtx,
2808 fp, GEN_INT (irq_state)));
2809 if (!frame_pointer_needed)
2811 RTX_FRAME_RELATED_P (insn) = 1;
2812 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2813 gen_rtx_SET (stack_pointer_rtx,
2814 plus_constant (Pmode,
2815 stack_pointer_rtx,
2816 -size_cfa)));
2819 fp_plus_insns = get_insns ();
2820 end_sequence ();
2822 /************ Method 2: Adjust Stack pointer ************/
2824 /* Stack adjustment by means of RCALL . and/or PUSH __TMP_REG__
2825 can only handle specific offsets. */
2827 int n_rcall = size / (AVR_3_BYTE_PC ? 3 : 2);
2829 if (avr_sp_immediate_operand (gen_int_mode (-size, HImode), HImode)
2830 // Don't use more than 3 RCALLs.
2831 && n_rcall <= 3)
2833 rtx_insn *sp_plus_insns;
2835 start_sequence ();
2837 insn = emit_move_insn (stack_pointer_rtx,
2838 plus_constant (Pmode, stack_pointer_rtx,
2839 -size));
2840 RTX_FRAME_RELATED_P (insn) = 1;
2841 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2842 gen_rtx_SET (stack_pointer_rtx,
2843 plus_constant (Pmode,
2844 stack_pointer_rtx,
2845 -size_cfa)));
2846 if (frame_pointer_needed)
2848 insn = emit_move_insn (fp, stack_pointer_rtx);
2849 RTX_FRAME_RELATED_P (insn) = 1;
2852 sp_plus_insns = get_insns ();
2853 end_sequence ();
2855 /************ Use shortest method ************/
2857 emit_insn (get_sequence_length (sp_plus_insns)
2858 < get_sequence_length (fp_plus_insns)
2859 ? sp_plus_insns
2860 : fp_plus_insns);
2862 else
2864 emit_insn (fp_plus_insns);
2867 cfun->machine->stack_usage += size_cfa;
2868 } /* !minimize && size != 0 */
2869 } /* !minimize */
2873 /* Output function prologue. */
2875 void
2876 avr_expand_prologue (void)
2878 HARD_REG_SET set;
2879 HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size();
2881 cfun->machine->stack_usage = 0;
2883 /* Prologue: naked. */
2884 if (cfun->machine->is_naked)
2886 return;
2889 avr_regs_to_save (&set);
2891 if (cfun->machine->is_interrupt || cfun->machine->is_signal)
2893 int treg = AVR_TMP_REGNO;
2894 /* Enable interrupts. */
2895 if (cfun->machine->is_interrupt)
2896 emit_insn (gen_enable_interrupt ());
2898 if (cfun->machine->gasisr.maybe)
2900 /* Let GAS PR21472 emit prologue preamble for us which handles SREG,
2901 ZERO_REG and TMP_REG and one additional, optional register for
2902 us in an optimal way. This even scans through inline asm. */
2904 cfun->machine->gasisr.yes = 1;
2906 // The optional reg or TMP_REG if we don't need one. If we need one,
2907 // remove that reg from SET so that it's not puhed / popped twice.
2908 // We also use it below instead of TMP_REG in some places.
2910 treg = avr_hregs_split_reg (&set);
2911 if (treg < 0)
2912 treg = AVR_TMP_REGNO;
2913 cfun->machine->gasisr.regno = treg;
2915 // The worst case of pushes. The exact number can be inferred
2916 // at assembly time by magic expression __gcc_isr.n_pushed.
2917 cfun->machine->stack_usage += 3 + (treg != AVR_TMP_REGNO);
2919 // Emit a Prologue chunk. Epilogue chunk(s) might follow.
2920 // The final Done chunk is emit by final postscan.
2921 emit_insn (gen_gasisr (GEN_INT (GASISR_Prologue), GEN_INT (treg)));
2923 else // !TARGET_GASISR_PROLOGUES: Classic, dumb prologue preamble.
2925 /* Push zero reg. */
2926 emit_push_byte (AVR_ZERO_REGNO, true);
2928 /* Push tmp reg. */
2929 emit_push_byte (AVR_TMP_REGNO, true);
2931 /* Push SREG. */
2932 /* ??? There's no dwarf2 column reserved for SREG. */
2933 emit_push_sfr (sreg_rtx, false, false /* clr */, AVR_TMP_REGNO);
2935 /* Clear zero reg. */
2936 emit_move_insn (zero_reg_rtx, const0_rtx);
2938 /* Prevent any attempt to delete the setting of ZERO_REG! */
2939 emit_use (zero_reg_rtx);
2942 /* Push and clear RAMPD/X/Y/Z if present and low-part register is used.
2943 ??? There are no dwarf2 columns reserved for RAMPD/X/Y/Z. */
2945 if (AVR_HAVE_RAMPD)
2946 emit_push_sfr (rampd_rtx, false /* frame */, true /* clr */, treg);
2948 if (AVR_HAVE_RAMPX
2949 && TEST_HARD_REG_BIT (set, REG_X)
2950 && TEST_HARD_REG_BIT (set, REG_X + 1))
2952 emit_push_sfr (rampx_rtx, false /* frame */, true /* clr */, treg);
2955 if (AVR_HAVE_RAMPY
2956 && (frame_pointer_needed
2957 || (TEST_HARD_REG_BIT (set, REG_Y)
2958 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
2960 emit_push_sfr (rampy_rtx, false /* frame */, true /* clr */, treg);
2963 if (AVR_HAVE_RAMPZ
2964 && TEST_HARD_REG_BIT (set, REG_Z)
2965 && TEST_HARD_REG_BIT (set, REG_Z + 1))
2967 emit_push_sfr (rampz_rtx, false /* frame */, AVR_HAVE_RAMPD, treg);
2969 } /* is_interrupt is_signal */
2971 avr_prologue_setup_frame (size, set);
2973 if (flag_stack_usage_info)
2974 current_function_static_stack_size
2975 = cfun->machine->stack_usage + INCOMING_FRAME_SP_OFFSET;
2979 /* Implement `TARGET_ASM_FUNCTION_END_PROLOGUE'. */
2980 /* Output summary at end of function prologue. */
2982 static void
2983 avr_asm_function_end_prologue (FILE *file)
2985 if (cfun->machine->is_naked)
2987 fputs ("/* prologue: naked */\n", file);
2989 else
2991 if (cfun->machine->is_interrupt)
2993 fputs ("/* prologue: Interrupt */\n", file);
2995 else if (cfun->machine->is_signal)
2997 fputs ("/* prologue: Signal */\n", file);
2999 else
3000 fputs ("/* prologue: function */\n", file);
3003 if (ACCUMULATE_OUTGOING_ARGS)
3004 fprintf (file, "/* outgoing args size = %d */\n",
3005 avr_outgoing_args_size());
3007 fprintf (file, "/* frame size = " HOST_WIDE_INT_PRINT_DEC " */\n",
3008 (HOST_WIDE_INT) get_frame_size());
3010 if (!cfun->machine->gasisr.yes)
3012 fprintf (file, "/* stack size = %d */\n", cfun->machine->stack_usage);
3013 // Create symbol stack offset so all functions have it. Add 1 to stack
3014 // usage for offset so that SP + .L__stack_offset = return address.
3015 fprintf (file, ".L__stack_usage = %d\n", cfun->machine->stack_usage);
3017 else
3019 int used_by_gasisr = 3 + (cfun->machine->gasisr.regno != AVR_TMP_REGNO);
3020 int to = cfun->machine->stack_usage;
3021 int from = to - used_by_gasisr;
3022 // Number of pushed regs is only known at assembly-time.
3023 fprintf (file, "/* stack size = %d...%d */\n", from , to);
3024 fprintf (file, ".L__stack_usage = %d + __gcc_isr.n_pushed\n", from);
3029 /* Worker function for `EPILOGUE_USES'. */
3032 avr_epilogue_uses (int /*regno*/)
3034 if (reload_completed
3035 && cfun->machine
3036 && (cfun->machine->is_interrupt || cfun->machine->is_signal))
3037 return 1;
3038 return 0;
3041 /* Helper for avr_expand_epilogue. Emit a pop of a byte register. */
3043 static void
3044 emit_pop_byte (unsigned regno)
3046 rtx mem = gen_rtx_PRE_INC (HImode, stack_pointer_rtx);
3047 mem = gen_frame_mem (QImode, mem);
3048 rtx reg = gen_rtx_REG (QImode, regno);
3050 emit_insn (gen_rtx_SET (reg, mem));
3053 /* Output RTL epilogue. */
3055 void
3056 avr_expand_epilogue (bool sibcall_p)
3058 HARD_REG_SET set;
3059 bool isr_p = cfun->machine->is_interrupt || cfun->machine->is_signal;
3061 HOST_WIDE_INT size = get_frame_size() + avr_outgoing_args_size();
3063 /* epilogue: naked */
3064 if (cfun->machine->is_naked)
3066 gcc_assert (!sibcall_p);
3068 emit_jump_insn (gen_return ());
3069 return;
3072 avr_regs_to_save (&set);
3073 int live_seq = sequent_regs_live ();
3075 bool minimize = (TARGET_CALL_PROLOGUES
3076 && live_seq
3077 && !isr_p
3078 && !cfun->machine->is_OS_task
3079 && !cfun->machine->is_OS_main
3080 && !AVR_TINY);
3082 if (minimize
3083 && (live_seq > 4
3084 || frame_pointer_needed
3085 || size))
3087 /* Get rid of frame. */
3089 if (!frame_pointer_needed)
3091 emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
3094 if (size)
3096 emit_move_insn (frame_pointer_rtx,
3097 plus_constant (Pmode, frame_pointer_rtx, size));
3100 emit_insn (gen_epilogue_restores (gen_int_mode (live_seq, HImode)));
3101 return;
3104 if (size)
3106 /* Try two methods to adjust stack and select shortest. */
3108 int irq_state = -1;
3110 gcc_assert (frame_pointer_needed
3111 || !isr_p
3112 || !crtl->is_leaf);
3114 rtx my_fp = (frame_pointer_needed
3115 ? frame_pointer_rtx
3116 : gen_rtx_REG (Pmode, REG_X));
3117 rtx fp = my_fp;
3119 if (AVR_HAVE_8BIT_SP)
3121 /* The high byte (r29) does not change:
3122 Prefer SUBI (1 cycle) over SBIW (2 cycles). */
3124 my_fp = all_regs_rtx[FRAME_POINTER_REGNUM];
3127 /* For rationale see comment in prologue generation. */
3129 HOST_WIDE_INT size_max = (HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (my_fp));
3130 if (size > size_max)
3131 size = size_max;
3132 size = trunc_int_for_mode (size, GET_MODE (my_fp));
3134 /********** Method 1: Adjust fp register **********/
3136 start_sequence ();
3138 if (!frame_pointer_needed)
3139 emit_move_insn (fp, stack_pointer_rtx);
3141 emit_move_insn (my_fp, plus_constant (GET_MODE (my_fp), my_fp, size));
3143 /* Copy to stack pointer. */
3145 if (TARGET_NO_INTERRUPTS)
3146 irq_state = 0;
3148 if (AVR_HAVE_8BIT_SP)
3149 irq_state = 2;
3151 emit_insn (gen_movhi_sp_r (stack_pointer_rtx, fp,
3152 GEN_INT (irq_state)));
3154 rtx_insn *fp_plus_insns = get_insns ();
3155 end_sequence ();
3157 /********** Method 2: Adjust Stack pointer **********/
3159 if (avr_sp_immediate_operand (gen_int_mode (size, HImode), HImode))
3161 start_sequence ();
3163 emit_move_insn (stack_pointer_rtx,
3164 plus_constant (Pmode, stack_pointer_rtx, size));
3166 rtx_insn *sp_plus_insns = get_insns ();
3167 end_sequence ();
3169 /************ Use shortest method ************/
3171 emit_insn (get_sequence_length (sp_plus_insns)
3172 < get_sequence_length (fp_plus_insns)
3173 ? sp_plus_insns
3174 : fp_plus_insns);
3176 else
3177 emit_insn (fp_plus_insns);
3178 } /* size != 0 */
3180 if (frame_pointer_needed
3181 && !(cfun->machine->is_OS_task || cfun->machine->is_OS_main))
3183 /* Restore previous frame_pointer. See avr_expand_prologue for
3184 rationale for not using pophi. */
3186 emit_pop_byte (REG_Y + 1);
3187 emit_pop_byte (REG_Y);
3190 /* Restore used registers. */
3192 int treg = AVR_TMP_REGNO;
3194 if (isr_p
3195 && cfun->machine->gasisr.yes)
3197 treg = cfun->machine->gasisr.regno;
3198 CLEAR_HARD_REG_BIT (set, treg);
3201 for (int reg = REG_31; reg >= REG_0; --reg)
3202 if (TEST_HARD_REG_BIT (set, reg))
3203 emit_pop_byte (reg);
3205 if (isr_p)
3207 /* Restore RAMPZ/Y/X/D using tmp_reg as scratch.
3208 The conditions to restore them must be tha same as in prologue. */
3210 if (AVR_HAVE_RAMPZ
3211 && TEST_HARD_REG_BIT (set, REG_Z)
3212 && TEST_HARD_REG_BIT (set, REG_Z + 1))
3214 emit_pop_byte (treg);
3215 emit_move_insn (rampz_rtx, all_regs_rtx[treg]);
3218 if (AVR_HAVE_RAMPY
3219 && (frame_pointer_needed
3220 || (TEST_HARD_REG_BIT (set, REG_Y)
3221 && TEST_HARD_REG_BIT (set, REG_Y + 1))))
3223 emit_pop_byte (treg);
3224 emit_move_insn (rampy_rtx, all_regs_rtx[treg]);
3227 if (AVR_HAVE_RAMPX
3228 && TEST_HARD_REG_BIT (set, REG_X)
3229 && TEST_HARD_REG_BIT (set, REG_X + 1))
3231 emit_pop_byte (treg);
3232 emit_move_insn (rampx_rtx, all_regs_rtx[treg]);
3235 if (AVR_HAVE_RAMPD)
3237 emit_pop_byte (treg);
3238 emit_move_insn (rampd_rtx, all_regs_rtx[treg]);
3241 if (cfun->machine->gasisr.yes)
3243 // Emit an Epilogue chunk.
3244 emit_insn (gen_gasisr (GEN_INT (GASISR_Epilogue),
3245 GEN_INT (cfun->machine->gasisr.regno)));
3247 else // !TARGET_GASISR_PROLOGUES
3249 /* Restore SREG using tmp_reg as scratch. */
3251 emit_pop_byte (AVR_TMP_REGNO);
3252 emit_move_insn (sreg_rtx, tmp_reg_rtx);
3254 /* Restore tmp REG. */
3255 emit_pop_byte (AVR_TMP_REGNO);
3257 /* Restore zero REG. */
3258 emit_pop_byte (AVR_ZERO_REGNO);
3262 if (!sibcall_p)
3263 emit_jump_insn (gen_return ());
3267 /* Implement `TARGET_ASM_FUNCTION_BEGIN_EPILOGUE'. */
3269 static void
3270 avr_asm_function_begin_epilogue (FILE *file)
3272 app_disable();
3273 fprintf (file, "/* epilogue start */\n");
3277 /* Implement `TARGET_CANNOT_MODITY_JUMPS_P'. */
3279 static bool
3280 avr_cannot_modify_jumps_p (void)
3282 /* Naked Functions must not have any instructions after
3283 their epilogue, see PR42240 */
3285 return (reload_completed
3286 && cfun->machine
3287 && cfun->machine->is_naked);
3291 /* Implement `TARGET_MODE_DEPENDENT_ADDRESS_P'. */
3293 static bool
3294 avr_mode_dependent_address_p (const_rtx /*addr*/, addr_space_t as)
3296 /* FIXME: Non-generic addresses are not mode-dependent in themselves.
3297 This hook just serves to hack around PR rtl-optimization/52543 by
3298 claiming that non-generic addresses were mode-dependent so that
3299 lower-subreg.cc will skip these addresses. lower-subreg.cc sets up fake
3300 RTXes to probe SET and MEM costs and assumes that MEM is always in the
3301 generic address space which is not true. */
3303 return !ADDR_SPACE_GENERIC_P (as);
3307 /* Return true if rtx X is a CONST_INT, CONST or SYMBOL_REF
3308 address with the `absdata' variable attribute, i.e. respective
3309 data can be read / written by LDS / STS instruction.
3310 This is used only for AVR_TINY. */
3312 static bool
3313 avr_address_tiny_absdata_p (rtx x, machine_mode mode)
3315 if (CONST == GET_CODE (x))
3316 x = XEXP (XEXP (x, 0), 0);
3318 if (SYMBOL_REF_P (x))
3319 return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_ABSDATA;
3321 if (CONST_INT_P (x)
3322 && IN_RANGE (INTVAL (x), 0, 0xc0 - GET_MODE_SIZE (mode)))
3323 return true;
3325 return false;
3329 /* Helper function for `avr_legitimate_address_p'. */
3331 static inline bool
3332 avr_reg_ok_for_addr_p (rtx reg, addr_space_t as,
3333 RTX_CODE outer_code, bool strict)
3335 return (REG_P (reg)
3336 && (avr_regno_mode_code_ok_for_base_p (REGNO (reg), QImode,
3337 as, outer_code, UNKNOWN)
3338 || (!strict
3339 && REGNO (reg) >= FIRST_PSEUDO_REGISTER)));
3343 /* Return nonzero if X (an RTX) is a legitimate memory address on the target
3344 machine for a memory operand of mode MODE. */
3346 static bool
3347 avr_legitimate_address_p (machine_mode mode, rtx x, bool strict)
3349 bool ok = CONSTANT_ADDRESS_P (x);
3351 switch (GET_CODE (x))
3353 case REG:
3354 ok = avr_reg_ok_for_addr_p (x, ADDR_SPACE_GENERIC,
3355 MEM, strict);
3357 if (strict
3358 && GET_MODE_SIZE (mode) > 4
3359 && REG_X == REGNO (x))
3361 ok = false;
3363 break;
3365 case POST_INC:
3366 case PRE_DEC:
3367 ok = avr_reg_ok_for_addr_p (XEXP (x, 0), ADDR_SPACE_GENERIC,
3368 GET_CODE (x), strict);
3369 break;
3371 case PLUS:
3373 rtx reg = XEXP (x, 0);
3374 rtx op1 = XEXP (x, 1);
3376 if (REG_P (reg)
3377 && CONST_INT_P (op1)
3378 && INTVAL (op1) >= 0)
3380 bool fit = (IN_RANGE (INTVAL (op1), 0, MAX_LD_OFFSET (mode))
3381 // Reduced Tiny does not support PLUS addressing
3382 // anyway, so we are not restricted to LD offset.
3383 || AVR_TINY);
3385 if (fit)
3387 ok = (! strict
3388 || avr_reg_ok_for_addr_p (reg, ADDR_SPACE_GENERIC,
3389 PLUS, strict));
3391 if (reg == frame_pointer_rtx
3392 || reg == arg_pointer_rtx)
3394 ok = true;
3397 else if (frame_pointer_needed
3398 && reg == frame_pointer_rtx)
3400 ok = true;
3404 break;
3406 default:
3407 break;
3410 if (AVR_TINY
3411 && CONSTANT_ADDRESS_P (x))
3413 /* avrtiny's load / store instructions only cover addresses 0..0xbf:
3414 IN / OUT range is 0..0x3f and LDS / STS can access 0x40..0xbf. */
3416 ok = avr_address_tiny_absdata_p (x, mode);
3419 if (avr_log.legitimate_address_p)
3421 avr_edump ("\n%?: ret=%d, mode=%m strict=%d "
3422 "reload_completed=%d reload_in_progress=%d %s:",
3423 ok, mode, strict, reload_completed, reload_in_progress,
3424 reg_renumber ? "(reg_renumber)" : "");
3426 if (GET_CODE (x) == PLUS
3427 && REG_P (XEXP (x, 0))
3428 && CONST_INT_P (XEXP (x, 1))
3429 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
3430 && reg_renumber)
3432 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
3433 true_regnum (XEXP (x, 0)));
3436 avr_edump ("\n%r\n", x);
3439 return ok;
3443 /* Former implementation of TARGET_LEGITIMIZE_ADDRESS,
3444 now only a helper for avr_addr_space_legitimize_address. */
3445 /* Attempts to replace X with a valid
3446 memory address for an operand of mode MODE */
3448 static rtx
3449 avr_legitimize_address (rtx x, rtx oldx, machine_mode mode)
3451 bool big_offset_p = false;
3453 x = oldx;
3455 if (AVR_TINY)
3457 if (CONSTANT_ADDRESS_P (x)
3458 && ! avr_address_tiny_absdata_p (x, mode))
3460 x = force_reg (Pmode, x);
3464 if (GET_CODE (oldx) == PLUS
3465 && REG_P (XEXP (oldx, 0)))
3467 if (REG_P (XEXP (oldx, 1)))
3468 x = force_reg (GET_MODE (oldx), oldx);
3469 else if (CONST_INT_P (XEXP (oldx, 1)))
3471 int offs = INTVAL (XEXP (oldx, 1));
3472 if (frame_pointer_rtx != XEXP (oldx, 0)
3473 && offs > MAX_LD_OFFSET (mode))
3475 big_offset_p = true;
3476 x = force_reg (GET_MODE (oldx), oldx);
3481 if (avr_log.legitimize_address)
3483 avr_edump ("\n%?: mode=%m\n %r\n", mode, oldx);
3485 if (x != oldx)
3486 avr_edump (" %s --> %r\n", big_offset_p ? "(big offset)" : "", x);
3489 return x;
3493 /* Implement `LEGITIMIZE_RELOAD_ADDRESS'. */
3494 /* This will allow register R26/27 to be used where it is no worse than normal
3495 base pointers R28/29 or R30/31. For example, if base offset is greater
3496 than 63 bytes or for R++ or --R addressing. */
3499 avr_legitimize_reload_address (rtx *px, machine_mode mode, int opnum,
3500 int type, int addr_type, int /*ind_levels*/,
3501 rtx (*mk_memloc)(rtx,int))
3503 rtx x = *px;
3505 if (avr_log.legitimize_reload_address)
3506 avr_edump ("\n%?:%m %r\n", mode, x);
3508 if (1 && (GET_CODE (x) == POST_INC
3509 || GET_CODE (x) == PRE_DEC))
3511 push_reload (XEXP (x, 0), XEXP (x, 0), &XEXP (x, 0), &XEXP (x, 0),
3512 POINTER_REGS, GET_MODE (x), GET_MODE (x), 0, 0,
3513 opnum, RELOAD_OTHER);
3515 if (avr_log.legitimize_reload_address)
3516 avr_edump (" RCLASS.1 = %R\n IN = %r\n OUT = %r\n",
3517 POINTER_REGS, XEXP (x, 0), XEXP (x, 0));
3519 return x;
3522 if (GET_CODE (x) == PLUS
3523 && REG_P (XEXP (x, 0))
3524 && reg_equiv_constant (REGNO (XEXP (x, 0))) == 0
3525 && CONST_INT_P (XEXP (x, 1))
3526 && INTVAL (XEXP (x, 1)) >= 1)
3528 bool fit = INTVAL (XEXP (x, 1)) <= MAX_LD_OFFSET (mode);
3530 if (fit)
3532 if (reg_equiv_address (REGNO (XEXP (x, 0))) != 0)
3534 int regno = REGNO (XEXP (x, 0));
3535 rtx mem = mk_memloc (x, regno);
3537 push_reload (XEXP (mem, 0), NULL_RTX, &XEXP (mem, 0), NULL,
3538 POINTER_REGS, Pmode, VOIDmode, 0, 0,
3539 1, (enum reload_type) addr_type);
3541 if (avr_log.legitimize_reload_address)
3542 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
3543 POINTER_REGS, XEXP (mem, 0), NULL_RTX);
3545 push_reload (mem, NULL_RTX, &XEXP (x, 0), NULL,
3546 BASE_POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
3547 opnum, (enum reload_type) type);
3549 if (avr_log.legitimize_reload_address)
3550 avr_edump (" RCLASS.2 = %R\n IN = %r\n OUT = %r\n",
3551 BASE_POINTER_REGS, mem, NULL_RTX);
3553 return x;
3556 else if (! (frame_pointer_needed
3557 && XEXP (x, 0) == frame_pointer_rtx))
3559 push_reload (x, NULL_RTX, px, NULL,
3560 POINTER_REGS, GET_MODE (x), VOIDmode, 0, 0,
3561 opnum, (enum reload_type) type);
3563 if (avr_log.legitimize_reload_address)
3564 avr_edump (" RCLASS.3 = %R\n IN = %r\n OUT = %r\n",
3565 POINTER_REGS, x, NULL_RTX);
3567 return x;
3571 return NULL_RTX;
3575 /* Helper function to print assembler resp. track instruction
3576 sequence lengths. Always return "".
3578 If PLEN == NULL:
3579 Output assembler code from template TPL with operands supplied
3580 by OPERANDS. This is just forwarding to output_asm_insn.
3582 If PLEN != NULL:
3583 If N_WORDS >= 0 Add N_WORDS to *PLEN.
3584 If N_WORDS < 0 Set *PLEN to -N_WORDS.
3585 Don't output anything.
3588 static const char *
3589 avr_asm_len (const char *tpl, rtx *operands, int *plen, int n_words)
3591 if (plen == NULL)
3592 output_asm_insn (tpl, operands);
3593 else
3595 if (n_words < 0)
3596 *plen = -n_words;
3597 else
3598 *plen += n_words;
3601 return "";
3605 /* Return a pointer register name as a string. */
3607 static const char *
3608 ptrreg_to_str (int regno)
3610 switch (regno)
3612 case REG_X: return "X";
3613 case REG_Y: return "Y";
3614 case REG_Z: return "Z";
3615 default:
3616 output_operand_lossage ("address operand requires constraint for"
3617 " X, Y, or Z register");
3619 return NULL;
3622 /* Return the condition name as a string.
3623 Used in conditional jump constructing */
3625 static const char *
3626 cond_string (enum rtx_code code)
3628 bool cc_overflow_unusable = false;
3630 switch (code)
3632 case NE:
3633 return "ne";
3634 case EQ:
3635 return "eq";
3636 case GE:
3637 if (cc_overflow_unusable)
3638 return "pl";
3639 else
3640 return "ge";
3641 case LT:
3642 if (cc_overflow_unusable)
3643 return "mi";
3644 else
3645 return "lt";
3646 case GEU:
3647 return "sh";
3648 case LTU:
3649 return "lo";
3650 default:
3651 gcc_unreachable ();
3654 return "";
3658 /* Return true if rtx X is a CONST or SYMBOL_REF with progmem.
3659 This must be used for AVR_TINY only because on other cores
3660 the flash memory is not visible in the RAM address range and
3661 cannot be read by, say, LD instruction. */
3663 static bool
3664 avr_address_tiny_pm_p (rtx x)
3666 if (CONST == GET_CODE (x))
3667 x = XEXP (XEXP (x, 0), 0);
3669 if (SYMBOL_REF_P (x))
3670 return SYMBOL_REF_FLAGS (x) & AVR_SYMBOL_FLAG_TINY_PM;
3672 return false;
3675 /* Implement `TARGET_PRINT_OPERAND_ADDRESS'. */
3676 /* Output ADDR to FILE as address. */
3678 static void
3679 avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
3681 if (AVR_TINY
3682 && avr_address_tiny_pm_p (addr))
3684 addr = plus_constant (Pmode, addr, avr_arch->flash_pm_offset);
3687 switch (GET_CODE (addr))
3689 case REG:
3690 fprintf (file, "%s", ptrreg_to_str (REGNO (addr)));
3691 break;
3693 case PRE_DEC:
3694 fprintf (file, "-%s", ptrreg_to_str (REGNO (XEXP (addr, 0))));
3695 break;
3697 case POST_INC:
3698 fprintf (file, "%s+", ptrreg_to_str (REGNO (XEXP (addr, 0))));
3699 break;
3701 default:
3702 if (CONSTANT_ADDRESS_P (addr)
3703 && text_segment_operand (addr, VOIDmode))
3705 rtx x = addr;
3706 if (GET_CODE (x) == CONST)
3707 x = XEXP (x, 0);
3708 if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
3710 /* Assembler gs() will implant word address. Make offset
3711 a byte offset inside gs() for assembler. This is
3712 needed because the more logical (constant+gs(sym)) is not
3713 accepted by gas. For 128K and smaller devices this is ok.
3714 For large devices it will create a trampoline to offset
3715 from symbol which may not be what the user really wanted. */
3717 fprintf (file, "gs(");
3718 output_addr_const (file, XEXP (x, 0));
3719 fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC ")",
3720 2 * INTVAL (XEXP (x, 1)));
3721 if (AVR_3_BYTE_PC)
3722 if (warning (0, "pointer offset from symbol maybe incorrect"))
3724 output_addr_const (stderr, addr);
3725 fprintf (stderr, "\n");
3728 else
3730 fprintf (file, "gs(");
3731 output_addr_const (file, addr);
3732 fprintf (file, ")");
3735 else
3736 output_addr_const (file, addr);
3741 /* Implement `TARGET_PRINT_OPERAND_PUNCT_VALID_P'. */
3743 static bool
3744 avr_print_operand_punct_valid_p (unsigned char code)
3746 return code == '~' || code == '!';
3750 /* Implement `TARGET_PRINT_OPERAND'. */
3751 /* Output X as assembler operand to file FILE.
3752 For a description of supported %-codes, see top of avr.md. */
3754 static void
3755 avr_print_operand (FILE *file, rtx x, int code)
3757 int abcd = 0, ef = 0, ij = 0;
3759 if (code >= 'A' && code <= 'D')
3760 abcd = code - 'A';
3761 else if (code == 'E' || code == 'F')
3762 ef = code - 'E';
3763 else if (code == 'I' || code == 'J')
3764 ij = code - 'I';
3766 if (code == '~')
3768 if (!AVR_HAVE_JMP_CALL)
3769 fputc ('r', file);
3771 else if (code == '!')
3773 if (AVR_HAVE_EIJMP_EICALL)
3774 fputc ('e', file);
3776 else if (code == 't'
3777 || code == 'T')
3779 static int t_regno = -1;
3780 static int t_nbits = -1;
3782 if (REG_P (x) && t_regno < 0 && code == 'T')
3784 t_regno = REGNO (x);
3785 t_nbits = GET_MODE_BITSIZE (GET_MODE (x));
3787 else if (CONST_INT_P (x) && t_regno >= 0
3788 && IN_RANGE (INTVAL (x), 0, t_nbits - 1))
3790 int bpos = INTVAL (x);
3792 fprintf (file, "%s", reg_names[t_regno + bpos / 8]);
3793 if (code == 'T')
3794 fprintf (file, ",%d", bpos % 8);
3796 t_regno = -1;
3798 else
3799 fatal_insn ("operands to %T/%t must be reg + const_int:", x);
3801 else if (code == 'E' || code == 'F')
3803 rtx op = XEXP (x, 0);
3804 fprintf (file, "%s", reg_names[REGNO (op) + ef]);
3806 else if (code == 'I' || code == 'J')
3808 rtx op = XEXP (XEXP (x, 0), 0);
3809 fprintf (file, "%s", reg_names[REGNO (op) + ij]);
3811 else if (REG_P (x))
3813 if (x == zero_reg_rtx)
3814 fprintf (file, "__zero_reg__");
3815 else if (code == 'r' && REGNO (x) < REG_32)
3816 fprintf (file, "%d", (int) REGNO (x));
3817 else
3818 fprintf (file, "%s", reg_names[REGNO (x) + abcd]);
3820 else if (CONST_INT_P (x))
3822 HOST_WIDE_INT ival = INTVAL (x);
3824 if ('i' != code)
3825 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival + abcd);
3826 else if (low_io_address_operand (x, VOIDmode)
3827 || high_io_address_operand (x, VOIDmode))
3829 if (AVR_HAVE_RAMPZ && ival == avr_addr.rampz)
3830 fprintf (file, "__RAMPZ__");
3831 else if (AVR_HAVE_RAMPY && ival == avr_addr.rampy)
3832 fprintf (file, "__RAMPY__");
3833 else if (AVR_HAVE_RAMPX && ival == avr_addr.rampx)
3834 fprintf (file, "__RAMPX__");
3835 else if (AVR_HAVE_RAMPD && ival == avr_addr.rampd)
3836 fprintf (file, "__RAMPD__");
3837 else if ((AVR_XMEGA || AVR_TINY) && ival == avr_addr.ccp)
3838 fprintf (file, "__CCP__");
3839 else if (ival == avr_addr.sreg) fprintf (file, "__SREG__");
3840 else if (ival == avr_addr.sp_l) fprintf (file, "__SP_L__");
3841 else if (ival == avr_addr.sp_h) fprintf (file, "__SP_H__");
3842 else
3844 fprintf (file, HOST_WIDE_INT_PRINT_HEX,
3845 ival - avr_arch->sfr_offset);
3848 else
3849 fatal_insn ("bad address, not an I/O address:", x);
3851 else if (MEM_P (x))
3853 rtx addr = XEXP (x, 0);
3855 if (code == 'm')
3857 if (!CONSTANT_P (addr))
3858 fatal_insn ("bad address, not a constant:", addr);
3859 /* Assembler template with m-code is data - not progmem section */
3860 if (text_segment_operand (addr, VOIDmode))
3861 if (warning (0, "accessing data memory with"
3862 " program memory address"))
3864 output_addr_const (stderr, addr);
3865 fprintf(stderr,"\n");
3867 output_addr_const (file, addr);
3869 else if (code == 'i')
3871 avr_print_operand (file, addr, 'i');
3873 else if (code == 'o')
3875 if (GET_CODE (addr) != PLUS)
3876 fatal_insn ("bad address, not (reg+disp):", addr);
3878 avr_print_operand (file, XEXP (addr, 1), 0);
3880 else if (code == 'b')
3882 if (GET_CODE (addr) != PLUS)
3883 fatal_insn ("bad address, not (reg+disp):", addr);
3885 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
3887 else if (code == 'p' || code == 'r')
3889 if (GET_CODE (addr) != POST_INC && GET_CODE (addr) != PRE_DEC)
3890 fatal_insn ("bad address, not post_inc or pre_dec:", addr);
3892 if (code == 'p')
3893 /* X, Y, Z */
3894 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
3895 else
3896 avr_print_operand (file, XEXP (addr, 0), 0); /* r26, r28, r30 */
3898 else if (GET_CODE (addr) == PLUS)
3900 avr_print_operand_address (file, VOIDmode, XEXP (addr, 0));
3901 if (REGNO (XEXP (addr, 0)) == REG_X)
3902 fatal_insn ("internal compiler error. Bad address:"
3903 ,addr);
3904 fputc ('+', file);
3905 avr_print_operand (file, XEXP (addr, 1), code);
3907 else
3908 avr_print_operand_address (file, VOIDmode, addr);
3910 else if (code == 'i')
3912 if (SYMBOL_REF_P (x) && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO))
3913 avr_print_operand_address
3914 (file, VOIDmode, plus_constant (HImode, x, -avr_arch->sfr_offset));
3915 else
3916 fatal_insn ("bad address, not an I/O address:", x);
3918 else if (code == 'x')
3920 /* Constant progmem address - like used in jmp or call */
3921 if (text_segment_operand (x, VOIDmode) == 0)
3922 if (warning (0, "accessing program memory"
3923 " with data memory address"))
3925 output_addr_const (stderr, x);
3926 fprintf(stderr,"\n");
3928 /* Use normal symbol for direct address no linker trampoline needed */
3929 output_addr_const (file, x);
3931 else if (CONST_FIXED_P (x))
3933 HOST_WIDE_INT ival = INTVAL (avr_to_int_mode (x));
3934 if (code != 0)
3935 output_operand_lossage ("Unsupported code '%c' for fixed-point:",
3936 code);
3937 fprintf (file, HOST_WIDE_INT_PRINT_DEC, ival);
3939 else if (CONST_DOUBLE_P (x))
3941 if (GET_MODE (x) == SFmode)
3943 long val;
3944 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), val);
3945 fprintf (file, "0x%lx", val);
3947 else if (GET_MODE (x) == DFmode)
3949 long l[2];
3950 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x), l);
3951 fprintf (file, "0x%lx%08lx", l[1] & 0xffffffff, l[0] & 0xffffffff);
3953 else
3954 fatal_insn ("internal compiler error. Unknown mode:", x);
3956 else if (GET_CODE (x) == CONST_STRING)
3957 fputs (XSTR (x, 0), file);
3958 else if (code == 'j')
3959 fputs (cond_string (GET_CODE (x)), file);
3960 else if (code == 'k')
3961 fputs (cond_string (reverse_condition (GET_CODE (x))), file);
3962 else
3963 avr_print_operand_address (file, VOIDmode, x);
3967 /* Implement `TARGET_USE_BY_PIECES_INFRASTRUCTURE_P'. */
3968 /* Prefer sequence of loads/stores for moves of size upto
3969 two - two pairs of load/store instructions are always better
3970 than the 5 instruction sequence for a loop (1 instruction
3971 for loop counter setup, and 4 for the body of the loop). */
3973 static bool
3974 avr_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
3975 unsigned int align,
3976 enum by_pieces_operation op, bool speed_p)
3978 if (op != MOVE_BY_PIECES
3979 || (speed_p && size > MOVE_MAX_PIECES))
3980 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
3982 return size <= MOVE_MAX_PIECES;
3985 /* Choose mode for jump insn:
3986 1 - relative jump in range -63 <= x <= 62 ;
3987 2 - relative jump in range -2046 <= x <= 2045 ;
3988 3 - absolute jump (only for ATmega[16]03). */
3991 avr_jump_mode (rtx x, rtx_insn *insn)
3993 int dest_addr = INSN_ADDRESSES (INSN_UID (GET_CODE (x) == LABEL_REF
3994 ? XEXP (x, 0) : x));
3995 int cur_addr = INSN_ADDRESSES (INSN_UID (insn));
3996 int jump_distance = cur_addr - dest_addr;
3998 if (IN_RANGE (jump_distance, -63, 62))
3999 return 1;
4000 else if (IN_RANGE (jump_distance, -2046, 2045))
4001 return 2;
4002 else if (AVR_HAVE_JMP_CALL)
4003 return 3;
4005 return 2;
4008 /* Return an AVR condition jump commands.
4009 X is a comparison RTX.
4010 LEN is a number returned by avr_jump_mode function.
4011 If REVERSE nonzero then condition code in X must be reversed. */
4013 const char *
4014 ret_cond_branch (rtx x, int len, int reverse)
4016 RTX_CODE cond = reverse ? reverse_condition (GET_CODE (x)) : GET_CODE (x);
4017 bool cc_overflow_unusable = false;
4019 switch (cond)
4021 case GT:
4022 if (cc_overflow_unusable)
4023 return (len == 1 ? ("breq .+2" CR_TAB
4024 "brpl %0") :
4025 len == 2 ? ("breq .+4" CR_TAB
4026 "brmi .+2" CR_TAB
4027 "rjmp %0") :
4028 ("breq .+6" CR_TAB
4029 "brmi .+4" CR_TAB
4030 "jmp %0"));
4032 else
4033 return (len == 1 ? ("breq .+2" CR_TAB
4034 "brge %0") :
4035 len == 2 ? ("breq .+4" CR_TAB
4036 "brlt .+2" CR_TAB
4037 "rjmp %0") :
4038 ("breq .+6" CR_TAB
4039 "brlt .+4" CR_TAB
4040 "jmp %0"));
4041 case GTU:
4042 return (len == 1 ? ("breq .+2" CR_TAB
4043 "brsh %0") :
4044 len == 2 ? ("breq .+4" CR_TAB
4045 "brlo .+2" CR_TAB
4046 "rjmp %0") :
4047 ("breq .+6" CR_TAB
4048 "brlo .+4" CR_TAB
4049 "jmp %0"));
4050 case LE:
4051 if (cc_overflow_unusable)
4052 return (len == 1 ? ("breq %0" CR_TAB
4053 "brmi %0") :
4054 len == 2 ? ("breq .+2" CR_TAB
4055 "brpl .+2" CR_TAB
4056 "rjmp %0") :
4057 ("breq .+2" CR_TAB
4058 "brpl .+4" CR_TAB
4059 "jmp %0"));
4060 else
4061 return (len == 1 ? ("breq %0" CR_TAB
4062 "brlt %0") :
4063 len == 2 ? ("breq .+2" CR_TAB
4064 "brge .+2" CR_TAB
4065 "rjmp %0") :
4066 ("breq .+2" CR_TAB
4067 "brge .+4" CR_TAB
4068 "jmp %0"));
4069 case LEU:
4070 return (len == 1 ? ("breq %0" CR_TAB
4071 "brlo %0") :
4072 len == 2 ? ("breq .+2" CR_TAB
4073 "brsh .+2" CR_TAB
4074 "rjmp %0") :
4075 ("breq .+2" CR_TAB
4076 "brsh .+4" CR_TAB
4077 "jmp %0"));
4078 default:
4079 if (reverse)
4081 switch (len)
4083 case 1:
4084 return "br%k1 %0";
4085 case 2:
4086 return ("br%j1 .+2" CR_TAB
4087 "rjmp %0");
4088 default:
4089 return ("br%j1 .+4" CR_TAB
4090 "jmp %0");
4093 else
4095 switch (len)
4097 case 1:
4098 return "br%j1 %0";
4099 case 2:
4100 return ("br%k1 .+2" CR_TAB
4101 "rjmp %0");
4102 default:
4103 return ("br%k1 .+4" CR_TAB
4104 "jmp %0");
4108 return "";
4112 /* Worker function for `FINAL_PRESCAN_INSN'. */
4113 /* Output insn cost for next insn. */
4115 void
4116 avr_final_prescan_insn (rtx_insn *insn, rtx * /*operands*/,
4117 int /*num_operands*/)
4119 if (avr_log.rtx_costs)
4121 rtx set = single_set (insn);
4123 if (set)
4124 fprintf (asm_out_file, "/* DEBUG: cost = %d. */\n",
4125 set_src_cost (SET_SRC (set), GET_MODE (SET_DEST (set)),
4126 optimize_insn_for_speed_p ()));
4127 else
4128 fprintf (asm_out_file, "/* DEBUG: pattern-cost = %d. */\n",
4129 rtx_cost (PATTERN (insn), VOIDmode, INSN, 0,
4130 optimize_insn_for_speed_p()));
4133 if (avr_log.insn_addresses)
4134 fprintf (asm_out_file, ";; ADDR = %d\n",
4135 (int) INSN_ADDRESSES (INSN_UID (insn)));
4139 /* Implement `TARGET_ASM_FINAL_POSTSCAN_INSN'. */
4140 /* When GAS generates (parts of) ISR prologue / epilogue for us, we must
4141 hint GAS about the end of the code to scan. There migh be code located
4142 after the last epilogue. */
4144 static void
4145 avr_asm_final_postscan_insn (FILE *stream, rtx_insn *insn, rtx *, int)
4147 if (cfun->machine->gasisr.yes
4148 && !next_real_insn (insn))
4150 app_disable();
4151 fprintf (stream, "\t__gcc_isr %d,r%d\n", GASISR_Done,
4152 cfun->machine->gasisr.regno);
4157 /* Worker function for `FUNCTION_ARG_REGNO_P'. */
4158 /* Returns nonzero if REGNO is the number of a hard
4159 register in which function arguments are sometimes passed. */
4162 avr_function_arg_regno_p (int r)
4164 return AVR_TINY
4165 ? IN_RANGE (r, REG_20, REG_25)
4166 : IN_RANGE (r, REG_8, REG_25);
4170 /* Worker function for `INIT_CUMULATIVE_ARGS'. */
4171 /* Initializing the variable cum for the state at the beginning
4172 of the argument list. */
4174 void
4175 avr_init_cumulative_args (CUMULATIVE_ARGS *cum, tree fntype, rtx libname,
4176 tree /*fndecl*/)
4178 cum->nregs = AVR_TINY ? 1 + REG_25 - REG_20 : 1 + REG_25 - REG_8;
4179 cum->regno = FIRST_CUM_REG;
4180 cum->has_stack_args = 0;
4181 if (!libname && stdarg_p (fntype))
4182 cum->nregs = 0;
4184 /* Assume the calle may be tail called */
4186 cfun->machine->sibcall_fails = 0;
4189 /* Returns the number of registers to allocate for a function argument. */
4191 static int
4192 avr_num_arg_regs (machine_mode mode, const_tree type)
4194 int size = (mode == BLKmode
4195 ? int_size_in_bytes (type)
4196 : GET_MODE_SIZE (mode));
4198 /* Align all function arguments to start in even-numbered registers.
4199 Odd-sized arguments leave holes above them. */
4201 return (size + 1) & ~1;
4205 /* Implement `TARGET_FUNCTION_ARG'. */
4206 /* Controls whether a function argument is passed
4207 in a register, and which register. */
4209 static rtx
4210 avr_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
4212 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4213 int bytes = avr_num_arg_regs (arg.mode, arg.type);
4215 if (cum->nregs && bytes <= cum->nregs)
4216 return gen_rtx_REG (arg.mode, cum->regno - bytes);
4218 cum->has_stack_args = 1;
4220 return NULL_RTX;
4224 /* Implement `TARGET_FUNCTION_ARG_ADVANCE'. */
4225 /* Update the summarizer variable CUM to advance past an argument
4226 in the argument list. */
4228 static void
4229 avr_function_arg_advance (cumulative_args_t cum_v, const function_arg_info &arg)
4231 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
4232 int bytes = avr_num_arg_regs (arg.mode, arg.type);
4234 cum->nregs -= bytes;
4235 cum->regno -= bytes;
4237 /* A parameter is being passed in a call-saved register. As the original
4238 contents of these regs has to be restored before leaving the function,
4239 a function must not pass arguments in call-saved regs in order to get
4240 tail-called. */
4242 if (cum->regno >= REG_8
4243 && cum->nregs >= 0
4244 && !call_used_or_fixed_reg_p (cum->regno))
4246 /* FIXME: We ship info on failing tail-call in struct machine_function.
4247 This uses internals of calls.cc:expand_call() and the way args_so_far
4248 is used. targetm.function_ok_for_sibcall() needs to be extended to
4249 pass &args_so_far, too. At present, CUMULATIVE_ARGS is target
4250 dependent so that such an extension is not wanted. */
4252 cfun->machine->sibcall_fails = 1;
4255 /* Test if all registers needed by the ABI are actually available. If the
4256 user has fixed a GPR needed to pass an argument, an (implicit) function
4257 call will clobber that fixed register. See PR45099 for an example. */
4259 if (cum->regno >= REG_8
4260 && cum->nregs >= 0)
4262 for (int regno = cum->regno; regno < cum->regno + bytes; regno++)
4263 if (fixed_regs[regno])
4264 warning (0, "fixed register %s used to pass parameter to function",
4265 reg_names[regno]);
4268 if (cum->nregs <= 0)
4270 cum->nregs = 0;
4271 cum->regno = FIRST_CUM_REG;
4275 /* Implement `TARGET_FUNCTION_OK_FOR_SIBCALL' */
4276 /* Decide whether we can make a sibling call to a function. DECL is the
4277 declaration of the function being targeted by the call and EXP is the
4278 CALL_EXPR representing the call. */
4280 static bool
4281 avr_function_ok_for_sibcall (tree decl_callee, tree exp_callee)
4283 /* Tail-calling must fail if callee-saved regs are used to pass
4284 function args. We must not tail-call when `epilogue_restores'
4285 is used. Unfortunately, we cannot tell at this point if that
4286 actually will happen or not, and we cannot step back from
4287 tail-calling. Thus, we inhibit tail-calling with -mcall-prologues. */
4289 if (cfun->machine->sibcall_fails
4290 || TARGET_CALL_PROLOGUES)
4292 return false;
4295 tree fntype_callee = TREE_TYPE (CALL_EXPR_FN (exp_callee));
4297 if (decl_callee)
4299 decl_callee = TREE_TYPE (decl_callee);
4301 else
4303 decl_callee = fntype_callee;
4305 while (FUNCTION_TYPE != TREE_CODE (decl_callee)
4306 && METHOD_TYPE != TREE_CODE (decl_callee))
4308 decl_callee = TREE_TYPE (decl_callee);
4312 /* Ensure that caller and callee have compatible epilogues */
4314 if (cfun->machine->is_interrupt
4315 || cfun->machine->is_signal
4316 || cfun->machine->is_naked
4317 || avr_naked_function_p (decl_callee))
4319 return false;
4322 return true;
4325 /***********************************************************************
4326 Functions for outputting various mov's for a various modes
4327 ************************************************************************/
4329 /* Return true if a value of mode MODE is read from flash by
4330 __load_* function from libgcc. */
4332 bool
4333 avr_load_libgcc_p (rtx op)
4335 machine_mode mode = GET_MODE (op);
4336 int n_bytes = GET_MODE_SIZE (mode);
4338 return (n_bytes > 2
4339 && !AVR_HAVE_LPMX
4340 && avr_mem_flash_p (op));
4343 /* Return true if a value of mode MODE is read by __xload_* function. */
4345 bool
4346 avr_xload_libgcc_p (machine_mode mode)
4348 int n_bytes = GET_MODE_SIZE (mode);
4350 return (n_bytes > 1
4351 || avr_n_flash > 1);
4355 /* Fixme: This is a hack because secondary reloads don't works as expected.
4357 Find an unused d-register to be used as scratch in INSN.
4358 EXCLUDE is either NULL_RTX or some register. In the case where EXCLUDE
4359 is a register, skip all possible return values that overlap EXCLUDE.
4360 The policy for the returned register is similar to that of
4361 `reg_unused_after', i.e. the returned register may overlap the SET_DEST
4362 of INSN.
4364 Return a QImode d-register or NULL_RTX if nothing found. */
4366 static rtx
4367 avr_find_unused_d_reg (rtx_insn *insn, rtx exclude)
4369 bool isr_p = (avr_interrupt_function_p (current_function_decl)
4370 || avr_signal_function_p (current_function_decl));
4372 for (int regno = REG_16; regno < REG_32; regno++)
4374 rtx reg = all_regs_rtx[regno];
4376 if ((exclude
4377 && reg_overlap_mentioned_p (exclude, reg))
4378 || fixed_regs[regno])
4380 continue;
4383 /* Try non-live register */
4385 if (!df_regs_ever_live_p (regno)
4386 && (TREE_THIS_VOLATILE (current_function_decl)
4387 || cfun->machine->is_OS_task
4388 || cfun->machine->is_OS_main
4389 || (!isr_p && call_used_or_fixed_reg_p (regno))))
4391 return reg;
4394 /* Any live register can be used if it is unused after.
4395 Prologue/epilogue will care for it as needed. */
4397 if (df_regs_ever_live_p (regno)
4398 && reg_unused_after (insn, reg))
4400 return reg;
4404 return NULL_RTX;
4408 /* Helper function for the next function in the case where only restricted
4409 version of LPM instruction is available. */
4411 static const char *
4412 avr_out_lpm_no_lpmx (rtx_insn *insn, rtx *xop, int *plen)
4414 rtx dest = xop[0];
4415 rtx addr = xop[1];
4416 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
4417 int regno_dest;
4419 regno_dest = REGNO (dest);
4421 /* The implicit target register of LPM. */
4422 xop[3] = lpm_reg_rtx;
4424 switch (GET_CODE (addr))
4426 default:
4427 gcc_unreachable();
4429 case REG:
4431 gcc_assert (REG_Z == REGNO (addr));
4433 switch (n_bytes)
4435 default:
4436 gcc_unreachable();
4438 case 1:
4439 avr_asm_len ("%4lpm", xop, plen, 1);
4441 if (regno_dest != LPM_REGNO)
4442 avr_asm_len ("mov %0,%3", xop, plen, 1);
4444 return "";
4446 case 2:
4447 if (REGNO (dest) == REG_Z)
4448 return avr_asm_len ("%4lpm" CR_TAB
4449 "push %3" CR_TAB
4450 "adiw %2,1" CR_TAB
4451 "%4lpm" CR_TAB
4452 "mov %B0,%3" CR_TAB
4453 "pop %A0", xop, plen, 6);
4455 avr_asm_len ("%4lpm" CR_TAB
4456 "mov %A0,%3" CR_TAB
4457 "adiw %2,1" CR_TAB
4458 "%4lpm" CR_TAB
4459 "mov %B0,%3", xop, plen, 5);
4461 if (!reg_unused_after (insn, addr))
4462 avr_asm_len ("sbiw %2,1", xop, plen, 1);
4464 break; /* 2 */
4467 break; /* REG */
4469 case POST_INC:
4471 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
4472 && n_bytes <= 4);
4474 if (regno_dest == LPM_REGNO)
4475 avr_asm_len ("%4lpm" CR_TAB
4476 "adiw %2,1", xop, plen, 2);
4477 else
4478 avr_asm_len ("%4lpm" CR_TAB
4479 "mov %A0,%3" CR_TAB
4480 "adiw %2,1", xop, plen, 3);
4482 if (n_bytes >= 2)
4483 avr_asm_len ("%4lpm" CR_TAB
4484 "mov %B0,%3" CR_TAB
4485 "adiw %2,1", xop, plen, 3);
4487 if (n_bytes >= 3)
4488 avr_asm_len ("%4lpm" CR_TAB
4489 "mov %C0,%3" CR_TAB
4490 "adiw %2,1", xop, plen, 3);
4492 if (n_bytes >= 4)
4493 avr_asm_len ("%4lpm" CR_TAB
4494 "mov %D0,%3" CR_TAB
4495 "adiw %2,1", xop, plen, 3);
4497 break; /* POST_INC */
4499 } /* switch CODE (addr) */
4501 return "";
4505 /* If PLEN == NULL: Ouput instructions to load a value from a memory location
4506 OP[1] in AS1 to register OP[0].
4507 If PLEN != 0 set *PLEN to the length in words of the instruction sequence.
4508 Return "". */
4510 const char *
4511 avr_out_lpm (rtx_insn *insn, rtx *op, int *plen)
4513 rtx xop[7];
4514 rtx dest = op[0];
4515 rtx src = SET_SRC (single_set (insn));
4516 int n_bytes = GET_MODE_SIZE (GET_MODE (dest));
4517 addr_space_t as = MEM_ADDR_SPACE (src);
4519 if (plen)
4520 *plen = 0;
4522 if (MEM_P (dest))
4524 warning (0, "writing to address space %qs not supported",
4525 avr_addrspace[MEM_ADDR_SPACE (dest)].name);
4527 return "";
4530 rtx addr = XEXP (src, 0);
4531 RTX_CODE code = GET_CODE (addr);
4533 gcc_assert (REG_P (dest));
4534 gcc_assert (REG == code || POST_INC == code);
4536 xop[0] = dest;
4537 xop[1] = addr;
4538 xop[2] = lpm_addr_reg_rtx;
4539 xop[4] = xstring_empty;
4540 xop[5] = tmp_reg_rtx;
4541 xop[6] = XEXP (rampz_rtx, 0);
4543 int segment = avr_addrspace[as].segment;
4545 /* Set RAMPZ as needed. */
4547 if (segment)
4549 xop[4] = GEN_INT (segment);
4550 xop[3] = avr_find_unused_d_reg (insn, lpm_addr_reg_rtx);
4552 if (xop[3] != NULL_RTX)
4554 avr_asm_len ("ldi %3,%4" CR_TAB
4555 "out %i6,%3", xop, plen, 2);
4557 else if (segment == 1)
4559 avr_asm_len ("clr %5" CR_TAB
4560 "inc %5" CR_TAB
4561 "out %i6,%5", xop, plen, 3);
4563 else
4565 avr_asm_len ("mov %5,%2" CR_TAB
4566 "ldi %2,%4" CR_TAB
4567 "out %i6,%2" CR_TAB
4568 "mov %2,%5", xop, plen, 4);
4571 xop[4] = xstring_e;
4573 if (!AVR_HAVE_ELPMX)
4574 return avr_out_lpm_no_lpmx (insn, xop, plen);
4576 else if (!AVR_HAVE_LPMX)
4578 return avr_out_lpm_no_lpmx (insn, xop, plen);
4581 /* We have [E]LPMX: Output reading from Flash the comfortable way. */
4583 switch (GET_CODE (addr))
4585 default:
4586 gcc_unreachable();
4588 case REG:
4590 gcc_assert (REG_Z == REGNO (addr));
4592 switch (n_bytes)
4594 default:
4595 gcc_unreachable();
4597 case 1:
4598 avr_asm_len ("%4lpm %0,%a2", xop, plen, 1);
4599 break;
4601 case 2:
4602 if (REGNO (dest) == REG_Z)
4603 avr_asm_len ("%4lpm %5,%a2+" CR_TAB
4604 "%4lpm %B0,%a2" CR_TAB
4605 "mov %A0,%5", xop, plen, 3);
4606 else
4608 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
4609 "%4lpm %B0,%a2", xop, plen, 2);
4611 if (!reg_unused_after (insn, addr))
4612 avr_asm_len ("sbiw %2,1", xop, plen, 1);
4615 break; /* 2 */
4617 case 3:
4619 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
4620 "%4lpm %B0,%a2+" CR_TAB
4621 "%4lpm %C0,%a2", xop, plen, 3);
4623 if (!reg_unused_after (insn, addr))
4624 avr_asm_len ("sbiw %2,2", xop, plen, 1);
4626 break; /* 3 */
4628 case 4:
4630 avr_asm_len ("%4lpm %A0,%a2+" CR_TAB
4631 "%4lpm %B0,%a2+", xop, plen, 2);
4633 if (REGNO (dest) == REG_Z - 2)
4634 avr_asm_len ("%4lpm %5,%a2+" CR_TAB
4635 "%4lpm %C0,%a2" CR_TAB
4636 "mov %D0,%5", xop, plen, 3);
4637 else
4639 avr_asm_len ("%4lpm %C0,%a2+" CR_TAB
4640 "%4lpm %D0,%a2", xop, plen, 2);
4642 if (!reg_unused_after (insn, addr))
4643 avr_asm_len ("sbiw %2,3", xop, plen, 1);
4646 break; /* 4 */
4647 } /* n_bytes */
4649 break; /* REG */
4651 case POST_INC:
4653 gcc_assert (REG_Z == REGNO (XEXP (addr, 0))
4654 && n_bytes <= 4);
4656 avr_asm_len ("%4lpm %A0,%a2+", xop, plen, 1);
4657 if (n_bytes >= 2) avr_asm_len ("%4lpm %B0,%a2+", xop, plen, 1);
4658 if (n_bytes >= 3) avr_asm_len ("%4lpm %C0,%a2+", xop, plen, 1);
4659 if (n_bytes >= 4) avr_asm_len ("%4lpm %D0,%a2+", xop, plen, 1);
4661 break; /* POST_INC */
4663 } /* switch CODE (addr) */
4665 if (xop[4] == xstring_e && AVR_HAVE_RAMPD)
4667 /* Reset RAMPZ to 0 so that EBI devices don't read garbage from RAM. */
4669 xop[0] = zero_reg_rtx;
4670 avr_asm_len ("out %i6,%0", xop, plen, 1);
4673 return "";
4677 /* Worker function for xload_8 insn. */
4679 const char *
4680 avr_out_xload (rtx_insn * /*insn*/, rtx *op, int *plen)
4682 rtx xop[4];
4684 xop[0] = op[0];
4685 xop[1] = op[1];
4686 xop[2] = lpm_addr_reg_rtx;
4687 xop[3] = AVR_HAVE_LPMX ? op[0] : lpm_reg_rtx;
4689 avr_asm_len (AVR_HAVE_LPMX ? "lpm %3,%a2" : "lpm", xop, plen, -1);
4691 avr_asm_len ("sbrc %1,7" CR_TAB
4692 "ld %3,%a2", xop, plen, 2);
4694 if (REGNO (xop[0]) != REGNO (xop[3]))
4695 avr_asm_len ("mov %0,%3", xop, plen, 1);
4697 return "";
4701 const char *
4702 output_movqi (rtx_insn *insn, rtx operands[], int *plen)
4704 rtx dest = operands[0];
4705 rtx src = operands[1];
4707 if (avr_mem_flash_p (src)
4708 || avr_mem_flash_p (dest))
4710 return avr_out_lpm (insn, operands, plen);
4713 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 1);
4715 if (REG_P (dest))
4717 if (REG_P (src)) /* mov r,r */
4719 if (test_hard_reg_class (STACK_REG, dest))
4720 return avr_asm_len ("out %0,%1", operands, plen, -1);
4721 else if (test_hard_reg_class (STACK_REG, src))
4722 return avr_asm_len ("in %0,%1", operands, plen, -1);
4724 return avr_asm_len ("mov %0,%1", operands, plen, -1);
4726 else if (CONSTANT_P (src))
4728 output_reload_in_const (operands, NULL_RTX, plen, false);
4729 return "";
4731 else if (MEM_P (src))
4732 return out_movqi_r_mr (insn, operands, plen); /* mov r,m */
4734 else if (MEM_P (dest))
4736 rtx xop[2];
4738 xop[0] = dest;
4739 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4741 return out_movqi_mr_r (insn, xop, plen);
4744 return "";
4748 const char *
4749 output_movhi (rtx_insn *insn, rtx xop[], int *plen)
4751 rtx dest = xop[0];
4752 rtx src = xop[1];
4754 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 2);
4756 if (avr_mem_flash_p (src)
4757 || avr_mem_flash_p (dest))
4759 return avr_out_lpm (insn, xop, plen);
4762 if (REG_P (dest))
4764 if (REG_P (src)) /* mov r,r */
4766 if (test_hard_reg_class (STACK_REG, dest))
4768 if (AVR_HAVE_8BIT_SP)
4769 return avr_asm_len ("out __SP_L__,%A1", xop, plen, -1);
4771 if (AVR_XMEGA)
4772 return avr_asm_len ("out __SP_L__,%A1" CR_TAB
4773 "out __SP_H__,%B1", xop, plen, -2);
4775 /* Use simple load of SP if no interrupts are used. */
4777 return TARGET_NO_INTERRUPTS
4778 ? avr_asm_len ("out __SP_H__,%B1" CR_TAB
4779 "out __SP_L__,%A1", xop, plen, -2)
4780 : avr_asm_len ("in __tmp_reg__,__SREG__" CR_TAB
4781 "cli" CR_TAB
4782 "out __SP_H__,%B1" CR_TAB
4783 "out __SREG__,__tmp_reg__" CR_TAB
4784 "out __SP_L__,%A1", xop, plen, -5);
4786 else if (test_hard_reg_class (STACK_REG, src))
4788 return !AVR_HAVE_SPH
4789 ? avr_asm_len ("in %A0,__SP_L__" CR_TAB
4790 "clr %B0", xop, plen, -2)
4792 : avr_asm_len ("in %A0,__SP_L__" CR_TAB
4793 "in %B0,__SP_H__", xop, plen, -2);
4796 return AVR_HAVE_MOVW
4797 ? avr_asm_len ("movw %0,%1", xop, plen, -1)
4799 : avr_asm_len ("mov %A0,%A1" CR_TAB
4800 "mov %B0,%B1", xop, plen, -2);
4801 } /* REG_P (src) */
4802 else if (CONSTANT_P (src))
4804 return output_reload_inhi (xop, NULL, plen);
4806 else if (MEM_P (src))
4808 return out_movhi_r_mr (insn, xop, plen); /* mov r,m */
4811 else if (MEM_P (dest))
4813 rtx xop[2];
4815 xop[0] = dest;
4816 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
4818 return out_movhi_mr_r (insn, xop, plen);
4821 fatal_insn ("invalid insn:", insn);
4823 return "";
4827 /* Same as out_movqi_r_mr, but TINY does not have ADIW or SBIW */
4829 static const char *
4830 avr_out_movqi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4832 rtx dest = op[0];
4833 rtx src = op[1];
4834 rtx x = XEXP (src, 0);
4836 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4837 "ld %0,%b1" , op, plen, -3);
4839 if (!reg_overlap_mentioned_p (dest, XEXP (x, 0))
4840 && !reg_unused_after (insn, XEXP (x, 0)))
4841 avr_asm_len (TINY_SBIW (%I1, %J1, %o1), op, plen, 2);
4843 return "";
4846 static const char *
4847 out_movqi_r_mr (rtx_insn *insn, rtx op[], int *plen)
4849 rtx dest = op[0];
4850 rtx src = op[1];
4851 rtx x = XEXP (src, 0);
4853 if (CONSTANT_ADDRESS_P (x))
4855 int n_words = AVR_TINY ? 1 : 2;
4856 return io_address_operand (x, QImode)
4857 ? avr_asm_len ("in %0,%i1", op, plen, -1)
4858 : avr_asm_len ("lds %0,%m1", op, plen, -n_words);
4861 if (GET_CODE (x) == PLUS
4862 && REG_P (XEXP (x, 0))
4863 && CONST_INT_P (XEXP (x, 1)))
4865 /* memory access by reg+disp */
4867 int disp = INTVAL (XEXP (x, 1));
4869 if (AVR_TINY)
4870 return avr_out_movqi_r_mr_reg_disp_tiny (insn, op, plen);
4872 if (disp - GET_MODE_SIZE (GET_MODE (src)) >= 63)
4874 if (REGNO (XEXP (x, 0)) != REG_Y)
4875 fatal_insn ("incorrect insn:",insn);
4877 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
4878 return avr_asm_len ("adiw r28,%o1-63" CR_TAB
4879 "ldd %0,Y+63" CR_TAB
4880 "sbiw r28,%o1-63", op, plen, -3);
4882 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
4883 "sbci r29,hi8(-%o1)" CR_TAB
4884 "ld %0,Y" CR_TAB
4885 "subi r28,lo8(%o1)" CR_TAB
4886 "sbci r29,hi8(%o1)", op, plen, -5);
4888 else if (REGNO (XEXP (x, 0)) == REG_X)
4890 /* This is a paranoid case LEGITIMIZE_RELOAD_ADDRESS must exclude
4891 it but I have this situation with extremal optimizing options. */
4893 avr_asm_len ("adiw r26,%o1" CR_TAB
4894 "ld %0,X", op, plen, -2);
4896 if (!reg_overlap_mentioned_p (dest, XEXP (x, 0))
4897 && !reg_unused_after (insn, XEXP (x, 0)))
4899 avr_asm_len ("sbiw r26,%o1", op, plen, 1);
4902 return "";
4905 return avr_asm_len ("ldd %0,%1", op, plen, -1);
4908 return avr_asm_len ("ld %0,%1", op, plen, -1);
4912 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
4914 static const char *
4915 avr_out_movhi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4917 rtx dest = op[0];
4918 rtx src = op[1];
4919 rtx base = XEXP (src, 0);
4921 int reg_dest = true_regnum (dest);
4922 int reg_base = true_regnum (base);
4924 if (reg_dest == reg_base) /* R = (R) */
4925 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
4926 "ld %B0,%1" CR_TAB
4927 "mov %A0,__tmp_reg__", op, plen, -3);
4929 avr_asm_len ("ld %A0,%1+" CR_TAB
4930 "ld %B0,%1", op, plen, -2);
4932 if (!reg_unused_after (insn, base))
4933 avr_asm_len (TINY_SBIW (%E1, %F1, 1), op, plen, 2);
4935 return "";
4939 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
4941 static const char *
4942 avr_out_movhi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
4944 rtx dest = op[0];
4945 rtx src = op[1];
4946 rtx base = XEXP (src, 0);
4948 int reg_dest = true_regnum (dest);
4949 int reg_base = true_regnum (XEXP (base, 0));
4951 if (reg_base == reg_dest)
4953 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4954 "ld __tmp_reg__,%b1+" CR_TAB
4955 "ld %B0,%b1" CR_TAB
4956 "mov %A0,__tmp_reg__", op, plen, -5);
4958 else
4960 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
4961 "ld %A0,%b1+" CR_TAB
4962 "ld %B0,%b1", op, plen, -4);
4964 if (!reg_unused_after (insn, XEXP (base, 0)))
4965 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+1), op, plen, 2);
4967 return "";
4972 /* Same as movhi_r_mr, but TINY does not have ADIW, SBIW and LDD */
4974 static const char *
4975 avr_out_movhi_r_mr_pre_dec_tiny (rtx_insn *insn, rtx op[], int *plen)
4977 rtx dest = op[0];
4978 rtx src = op[1];
4979 rtx base = XEXP (src, 0);
4981 /* "volatile" forces reading low byte first, even if less efficient,
4982 for correct operation with 16-bit I/O registers. */
4983 bool mem_volatile_p = MEM_VOLATILE_P (src);
4985 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
4986 fatal_insn ("incorrect insn:", insn);
4988 if (!mem_volatile_p)
4989 return avr_asm_len ("ld %B0,%1" CR_TAB
4990 "ld %A0,%1", op, plen, -2);
4992 return avr_asm_len (TINY_SBIW (%I1, %J1, 2) CR_TAB
4993 "ld %A0,%p1+" CR_TAB
4994 "ld %B0,%p1" CR_TAB
4995 TINY_SBIW (%I1, %J1, 1), op, plen, -6);
4999 static const char *
5000 out_movhi_r_mr (rtx_insn *insn, rtx op[], int *plen)
5002 rtx dest = op[0];
5003 rtx src = op[1];
5004 rtx base = XEXP (src, 0);
5005 int reg_dest = true_regnum (dest);
5006 int reg_base = true_regnum (base);
5007 /* "volatile" forces reading low byte first, even if less efficient,
5008 for correct operation with 16-bit I/O registers. */
5009 bool mem_volatile_p = MEM_VOLATILE_P (src);
5011 if (reg_base > 0)
5013 if (AVR_TINY)
5014 return avr_out_movhi_r_mr_reg_no_disp_tiny (insn, op, plen);
5016 if (reg_dest == reg_base) /* R = (R) */
5017 return avr_asm_len ("ld __tmp_reg__,%1+" CR_TAB
5018 "ld %B0,%1" CR_TAB
5019 "mov %A0,__tmp_reg__", op, plen, -3);
5021 if (reg_base != REG_X)
5022 return avr_asm_len ("ld %A0,%1" CR_TAB
5023 "ldd %B0,%1+1", op, plen, -2);
5025 avr_asm_len ("ld %A0,X+" CR_TAB
5026 "ld %B0,X", op, plen, -2);
5028 if (!reg_unused_after (insn, base))
5029 avr_asm_len ("sbiw r26,1", op, plen, 1);
5031 return "";
5033 else if (GET_CODE (base) == PLUS) /* (R + i) */
5035 int disp = INTVAL (XEXP (base, 1));
5036 int reg_base = true_regnum (XEXP (base, 0));
5038 if (AVR_TINY)
5039 return avr_out_movhi_r_mr_reg_disp_tiny (insn, op, plen);
5041 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
5043 if (REGNO (XEXP (base, 0)) != REG_Y)
5044 fatal_insn ("incorrect insn:",insn);
5046 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (src))
5047 ? avr_asm_len ("adiw r28,%o1-62" CR_TAB
5048 "ldd %A0,Y+62" CR_TAB
5049 "ldd %B0,Y+63" CR_TAB
5050 "sbiw r28,%o1-62", op, plen, -4)
5052 : avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
5053 "sbci r29,hi8(-%o1)" CR_TAB
5054 "ld %A0,Y" CR_TAB
5055 "ldd %B0,Y+1" CR_TAB
5056 "subi r28,lo8(%o1)" CR_TAB
5057 "sbci r29,hi8(%o1)", op, plen, -6);
5060 /* This is a paranoid case. LEGITIMIZE_RELOAD_ADDRESS must exclude
5061 it but I have this situation with extremal
5062 optimization options. */
5064 if (reg_base == REG_X)
5066 if (reg_base == reg_dest)
5067 return avr_asm_len ("adiw r26,%o1" CR_TAB
5068 "ld __tmp_reg__,X+" CR_TAB
5069 "ld %B0,X" CR_TAB
5070 "mov %A0,__tmp_reg__", op, plen, -4);
5072 avr_asm_len ("adiw r26,%o1" CR_TAB
5073 "ld %A0,X+" CR_TAB
5074 "ld %B0,X", op, plen, -3);
5076 if (!reg_unused_after (insn, XEXP (base, 0)))
5077 avr_asm_len ("sbiw r26,%o1+1", op, plen, 1);
5079 return "";
5082 return reg_base == reg_dest
5083 ? avr_asm_len ("ldd __tmp_reg__,%A1" CR_TAB
5084 "ldd %B0,%B1" CR_TAB
5085 "mov %A0,__tmp_reg__", op, plen, -3)
5087 : avr_asm_len ("ldd %A0,%A1" CR_TAB
5088 "ldd %B0,%B1", op, plen, -2);
5090 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5092 if (AVR_TINY)
5093 return avr_out_movhi_r_mr_pre_dec_tiny (insn, op, plen);
5095 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
5096 fatal_insn ("incorrect insn:", insn);
5098 if (!mem_volatile_p)
5099 return avr_asm_len ("ld %B0,%1" CR_TAB
5100 "ld %A0,%1", op, plen, -2);
5102 return REGNO (XEXP (base, 0)) == REG_X
5103 ? avr_asm_len ("sbiw r26,2" CR_TAB
5104 "ld %A0,X+" CR_TAB
5105 "ld %B0,X" CR_TAB
5106 "sbiw r26,1", op, plen, -4)
5108 : avr_asm_len ("sbiw %r1,2" CR_TAB
5109 "ld %A0,%p1" CR_TAB
5110 "ldd %B0,%p1+1", op, plen, -3);
5112 else if (GET_CODE (base) == POST_INC) /* (R++) */
5114 if (reg_overlap_mentioned_p (dest, XEXP (base, 0)))
5115 fatal_insn ("incorrect insn:", insn);
5117 return avr_asm_len ("ld %A0,%1" CR_TAB
5118 "ld %B0,%1", op, plen, -2);
5120 else if (CONSTANT_ADDRESS_P (base))
5122 int n_words = AVR_TINY ? 2 : 4;
5123 return io_address_operand (base, HImode)
5124 ? avr_asm_len ("in %A0,%i1" CR_TAB
5125 "in %B0,%i1+1", op, plen, -2)
5127 : avr_asm_len ("lds %A0,%m1" CR_TAB
5128 "lds %B0,%m1+1", op, plen, -n_words);
5131 fatal_insn ("unknown move insn:",insn);
5132 return "";
5135 static const char *
5136 avr_out_movsi_r_mr_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
5138 rtx dest = op[0];
5139 rtx src = op[1];
5140 rtx base = XEXP (src, 0);
5141 int reg_dest = true_regnum (dest);
5142 int reg_base = true_regnum (base);
5144 if (reg_dest == reg_base)
5146 /* "ld r26,-X" is undefined */
5147 return *l = 9, (TINY_ADIW (%E1, %F1, 3) CR_TAB
5148 "ld %D0,%1" CR_TAB
5149 "ld %C0,-%1" CR_TAB
5150 "ld __tmp_reg__,-%1" CR_TAB
5151 TINY_SBIW (%E1, %F1, 1) CR_TAB
5152 "ld %A0,%1" CR_TAB
5153 "mov %B0,__tmp_reg__");
5155 else if (reg_dest == reg_base - 2)
5157 return *l = 5, ("ld %A0,%1+" CR_TAB
5158 "ld %B0,%1+" CR_TAB
5159 "ld __tmp_reg__,%1+" CR_TAB
5160 "ld %D0,%1" CR_TAB
5161 "mov %C0,__tmp_reg__");
5163 else if (reg_unused_after (insn, base))
5165 return *l = 4, ("ld %A0,%1+" CR_TAB
5166 "ld %B0,%1+" CR_TAB
5167 "ld %C0,%1+" CR_TAB
5168 "ld %D0,%1");
5170 else
5172 return *l = 6, ("ld %A0,%1+" CR_TAB
5173 "ld %B0,%1+" CR_TAB
5174 "ld %C0,%1+" CR_TAB
5175 "ld %D0,%1" CR_TAB
5176 TINY_SBIW (%E1, %F1, 3));
5181 static const char *
5182 avr_out_movsi_r_mr_reg_disp_tiny (rtx_insn *insn, rtx op[], int *l)
5184 rtx dest = op[0];
5185 rtx src = op[1];
5186 rtx base = XEXP (src, 0);
5187 int reg_dest = true_regnum (dest);
5188 int reg_base = true_regnum (XEXP (base, 0));
5190 if (reg_dest == reg_base)
5192 /* "ld r26,-X" is undefined */
5193 return *l = 9, (TINY_ADIW (%I1, %J1, %o1+3) CR_TAB
5194 "ld %D0,%b1" CR_TAB
5195 "ld %C0,-%b1" CR_TAB
5196 "ld __tmp_reg__,-%b1" CR_TAB
5197 TINY_SBIW (%I1, %J1, 1) CR_TAB
5198 "ld %A0,%b1" CR_TAB
5199 "mov %B0,__tmp_reg__");
5201 else if (reg_dest == reg_base - 2)
5203 return *l = 7, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
5204 "ld %A0,%b1+" CR_TAB
5205 "ld %B0,%b1+" CR_TAB
5206 "ld __tmp_reg__,%b1+" CR_TAB
5207 "ld %D0,%b1" CR_TAB
5208 "mov %C0,__tmp_reg__");
5210 else if (reg_unused_after (insn, XEXP (base, 0)))
5212 return *l = 6, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
5213 "ld %A0,%b1+" CR_TAB
5214 "ld %B0,%b1+" CR_TAB
5215 "ld %C0,%b1+" CR_TAB
5216 "ld %D0,%b1");
5218 else
5220 return *l = 8, (TINY_ADIW (%I1, %J1, %o1) CR_TAB
5221 "ld %A0,%b1+" CR_TAB
5222 "ld %B0,%b1+" CR_TAB
5223 "ld %C0,%b1+" CR_TAB
5224 "ld %D0,%b1" CR_TAB
5225 TINY_SBIW (%I1, %J1, %o1+3));
5229 static const char *
5230 out_movsi_r_mr (rtx_insn *insn, rtx op[], int *l)
5232 rtx dest = op[0];
5233 rtx src = op[1];
5234 rtx base = XEXP (src, 0);
5235 int reg_dest = true_regnum (dest);
5236 int reg_base = true_regnum (base);
5237 int tmp;
5239 if (!l)
5240 l = &tmp;
5242 if (reg_base > 0)
5244 if (AVR_TINY)
5245 return avr_out_movsi_r_mr_reg_no_disp_tiny (insn, op, l);
5247 if (reg_base == REG_X) /* (R26) */
5249 if (reg_dest == REG_X)
5250 /* "ld r26,-X" is undefined */
5251 return *l=7, ("adiw r26,3" CR_TAB
5252 "ld r29,X" CR_TAB
5253 "ld r28,-X" CR_TAB
5254 "ld __tmp_reg__,-X" CR_TAB
5255 "sbiw r26,1" CR_TAB
5256 "ld r26,X" CR_TAB
5257 "mov r27,__tmp_reg__");
5258 else if (reg_dest == REG_X - 2)
5259 return *l=5, ("ld %A0,X+" CR_TAB
5260 "ld %B0,X+" CR_TAB
5261 "ld __tmp_reg__,X+" CR_TAB
5262 "ld %D0,X" CR_TAB
5263 "mov %C0,__tmp_reg__");
5264 else if (reg_unused_after (insn, base))
5265 return *l=4, ("ld %A0,X+" CR_TAB
5266 "ld %B0,X+" CR_TAB
5267 "ld %C0,X+" CR_TAB
5268 "ld %D0,X");
5269 else
5270 return *l=5, ("ld %A0,X+" CR_TAB
5271 "ld %B0,X+" CR_TAB
5272 "ld %C0,X+" CR_TAB
5273 "ld %D0,X" CR_TAB
5274 "sbiw r26,3");
5276 else
5278 if (reg_dest == reg_base)
5279 return *l=5, ("ldd %D0,%1+3" CR_TAB
5280 "ldd %C0,%1+2" CR_TAB
5281 "ldd __tmp_reg__,%1+1" CR_TAB
5282 "ld %A0,%1" CR_TAB
5283 "mov %B0,__tmp_reg__");
5284 else if (reg_base == reg_dest + 2)
5285 return *l=5, ("ld %A0,%1" CR_TAB
5286 "ldd %B0,%1+1" CR_TAB
5287 "ldd __tmp_reg__,%1+2" CR_TAB
5288 "ldd %D0,%1+3" CR_TAB
5289 "mov %C0,__tmp_reg__");
5290 else
5291 return *l=4, ("ld %A0,%1" CR_TAB
5292 "ldd %B0,%1+1" CR_TAB
5293 "ldd %C0,%1+2" CR_TAB
5294 "ldd %D0,%1+3");
5297 else if (GET_CODE (base) == PLUS) /* (R + i) */
5299 int disp = INTVAL (XEXP (base, 1));
5301 if (AVR_TINY)
5302 return avr_out_movsi_r_mr_reg_disp_tiny (insn, op, l);
5304 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
5306 if (REGNO (XEXP (base, 0)) != REG_Y)
5307 fatal_insn ("incorrect insn:",insn);
5309 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
5310 return *l = 6, ("adiw r28,%o1-60" CR_TAB
5311 "ldd %A0,Y+60" CR_TAB
5312 "ldd %B0,Y+61" CR_TAB
5313 "ldd %C0,Y+62" CR_TAB
5314 "ldd %D0,Y+63" CR_TAB
5315 "sbiw r28,%o1-60");
5317 return *l = 8, ("subi r28,lo8(-%o1)" CR_TAB
5318 "sbci r29,hi8(-%o1)" CR_TAB
5319 "ld %A0,Y" CR_TAB
5320 "ldd %B0,Y+1" CR_TAB
5321 "ldd %C0,Y+2" CR_TAB
5322 "ldd %D0,Y+3" CR_TAB
5323 "subi r28,lo8(%o1)" CR_TAB
5324 "sbci r29,hi8(%o1)");
5327 reg_base = true_regnum (XEXP (base, 0));
5328 if (reg_base == REG_X)
5330 /* R = (X + d) */
5331 if (reg_dest == REG_X)
5333 *l = 7;
5334 /* "ld r26,-X" is undefined */
5335 return ("adiw r26,%o1+3" CR_TAB
5336 "ld r29,X" CR_TAB
5337 "ld r28,-X" CR_TAB
5338 "ld __tmp_reg__,-X" CR_TAB
5339 "sbiw r26,1" CR_TAB
5340 "ld r26,X" CR_TAB
5341 "mov r27,__tmp_reg__");
5343 *l = 6;
5344 if (reg_dest == REG_X - 2)
5345 return ("adiw r26,%o1" CR_TAB
5346 "ld r24,X+" CR_TAB
5347 "ld r25,X+" CR_TAB
5348 "ld __tmp_reg__,X+" CR_TAB
5349 "ld r27,X" CR_TAB
5350 "mov r26,__tmp_reg__");
5352 return ("adiw r26,%o1" CR_TAB
5353 "ld %A0,X+" CR_TAB
5354 "ld %B0,X+" CR_TAB
5355 "ld %C0,X+" CR_TAB
5356 "ld %D0,X" CR_TAB
5357 "sbiw r26,%o1+3");
5359 if (reg_dest == reg_base)
5360 return *l=5, ("ldd %D0,%D1" CR_TAB
5361 "ldd %C0,%C1" CR_TAB
5362 "ldd __tmp_reg__,%B1" CR_TAB
5363 "ldd %A0,%A1" CR_TAB
5364 "mov %B0,__tmp_reg__");
5365 else if (reg_dest == reg_base - 2)
5366 return *l=5, ("ldd %A0,%A1" CR_TAB
5367 "ldd %B0,%B1" CR_TAB
5368 "ldd __tmp_reg__,%C1" CR_TAB
5369 "ldd %D0,%D1" CR_TAB
5370 "mov %C0,__tmp_reg__");
5371 return *l=4, ("ldd %A0,%A1" CR_TAB
5372 "ldd %B0,%B1" CR_TAB
5373 "ldd %C0,%C1" CR_TAB
5374 "ldd %D0,%D1");
5376 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5377 return *l=4, ("ld %D0,%1" CR_TAB
5378 "ld %C0,%1" CR_TAB
5379 "ld %B0,%1" CR_TAB
5380 "ld %A0,%1");
5381 else if (GET_CODE (base) == POST_INC) /* (R++) */
5382 return *l=4, ("ld %A0,%1" CR_TAB
5383 "ld %B0,%1" CR_TAB
5384 "ld %C0,%1" CR_TAB
5385 "ld %D0,%1");
5386 else if (CONSTANT_ADDRESS_P (base))
5388 if (io_address_operand (base, SImode))
5390 *l = 4;
5391 return ("in %A0,%i1" CR_TAB
5392 "in %B0,%i1+1" CR_TAB
5393 "in %C0,%i1+2" CR_TAB
5394 "in %D0,%i1+3");
5396 else
5398 *l = AVR_TINY ? 4 : 8;
5399 return ("lds %A0,%m1" CR_TAB
5400 "lds %B0,%m1+1" CR_TAB
5401 "lds %C0,%m1+2" CR_TAB
5402 "lds %D0,%m1+3");
5406 fatal_insn ("unknown move insn:",insn);
5407 return "";
5410 static const char *
5411 avr_out_movsi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *l)
5413 rtx dest = op[0];
5414 rtx src = op[1];
5415 rtx base = XEXP (dest, 0);
5416 int reg_base = true_regnum (base);
5417 int reg_src = true_regnum (src);
5419 if (reg_base == reg_src)
5421 /* "ld r26,-X" is undefined */
5422 if (reg_unused_after (insn, base))
5424 return *l = 7, ("mov __tmp_reg__, %B1" CR_TAB
5425 "st %0,%A1" CR_TAB
5426 TINY_ADIW (%E0, %F0, 1) CR_TAB
5427 "st %0+,__tmp_reg__" CR_TAB
5428 "st %0+,%C1" CR_TAB
5429 "st %0+,%D1");
5431 else
5433 return *l = 9, ("mov __tmp_reg__, %B1" CR_TAB
5434 "st %0,%A1" CR_TAB
5435 TINY_ADIW (%E0, %F0, 1) CR_TAB
5436 "st %0+,__tmp_reg__" CR_TAB
5437 "st %0+,%C1" CR_TAB
5438 "st %0+,%D1" CR_TAB
5439 TINY_SBIW (%E0, %F0, 3));
5442 else if (reg_base == reg_src + 2)
5444 if (reg_unused_after (insn, base))
5445 return *l = 7, ("mov __zero_reg__,%C1" CR_TAB
5446 "mov __tmp_reg__,%D1" CR_TAB
5447 "st %0+,%A1" CR_TAB
5448 "st %0+,%B1" CR_TAB
5449 "st %0+,__zero_reg__" CR_TAB
5450 "st %0,__tmp_reg__" CR_TAB
5451 "clr __zero_reg__");
5452 else
5453 return *l = 9, ("mov __zero_reg__,%C1" CR_TAB
5454 "mov __tmp_reg__,%D1" CR_TAB
5455 "st %0+,%A1" CR_TAB
5456 "st %0+,%B1" CR_TAB
5457 "st %0+,__zero_reg__" CR_TAB
5458 "st %0,__tmp_reg__" CR_TAB
5459 "clr __zero_reg__" CR_TAB
5460 TINY_SBIW (%E0, %F0, 3));
5463 return *l = 6, ("st %0+,%A1" CR_TAB
5464 "st %0+,%B1" CR_TAB
5465 "st %0+,%C1" CR_TAB
5466 "st %0,%D1" CR_TAB
5467 TINY_SBIW (%E0, %F0, 3));
5470 static const char *
5471 avr_out_movsi_mr_r_reg_disp_tiny (rtx op[], int *l)
5473 rtx dest = op[0];
5474 rtx src = op[1];
5475 rtx base = XEXP (dest, 0);
5476 int reg_base = REGNO (XEXP (base, 0));
5477 int reg_src =true_regnum (src);
5479 if (reg_base == reg_src)
5481 *l = 11;
5482 return ("mov __tmp_reg__,%A2" CR_TAB
5483 "mov __zero_reg__,%B2" CR_TAB
5484 TINY_ADIW (%I0, %J0, %o0) CR_TAB
5485 "st %b0+,__tmp_reg__" CR_TAB
5486 "st %b0+,__zero_reg__" CR_TAB
5487 "st %b0+,%C2" CR_TAB
5488 "st %b0,%D2" CR_TAB
5489 "clr __zero_reg__" CR_TAB
5490 TINY_SBIW (%I0, %J0, %o0+3));
5492 else if (reg_src == reg_base - 2)
5494 *l = 11;
5495 return ("mov __tmp_reg__,%C2" CR_TAB
5496 "mov __zero_reg__,%D2" CR_TAB
5497 TINY_ADIW (%I0, %J0, %o0) CR_TAB
5498 "st %b0+,%A0" CR_TAB
5499 "st %b0+,%B0" CR_TAB
5500 "st %b0+,__tmp_reg__" CR_TAB
5501 "st %b0,__zero_reg__" CR_TAB
5502 "clr __zero_reg__" CR_TAB
5503 TINY_SBIW (%I0, %J0, %o0+3));
5505 *l = 8;
5506 return (TINY_ADIW (%I0, %J0, %o0) CR_TAB
5507 "st %b0+,%A1" CR_TAB
5508 "st %b0+,%B1" CR_TAB
5509 "st %b0+,%C1" CR_TAB
5510 "st %b0,%D1" CR_TAB
5511 TINY_SBIW (%I0, %J0, %o0+3));
5514 static const char *
5515 out_movsi_mr_r (rtx_insn *insn, rtx op[], int *l)
5517 rtx dest = op[0];
5518 rtx src = op[1];
5519 rtx base = XEXP (dest, 0);
5520 int reg_base = true_regnum (base);
5521 int reg_src = true_regnum (src);
5522 int tmp;
5524 if (!l)
5525 l = &tmp;
5527 if (CONSTANT_ADDRESS_P (base))
5529 if (io_address_operand (base, SImode))
5531 return *l=4,("out %i0, %A1" CR_TAB
5532 "out %i0+1,%B1" CR_TAB
5533 "out %i0+2,%C1" CR_TAB
5534 "out %i0+3,%D1");
5536 else
5538 *l = AVR_TINY ? 4 : 8;
5539 return ("sts %m0,%A1" CR_TAB
5540 "sts %m0+1,%B1" CR_TAB
5541 "sts %m0+2,%C1" CR_TAB
5542 "sts %m0+3,%D1");
5546 if (reg_base > 0) /* (r) */
5548 if (AVR_TINY)
5549 return avr_out_movsi_mr_r_reg_no_disp_tiny (insn, op, l);
5551 if (reg_base == REG_X) /* (R26) */
5553 if (reg_src == REG_X)
5555 /* "st X+,r26" is undefined */
5556 if (reg_unused_after (insn, base))
5557 return *l=6, ("mov __tmp_reg__,r27" CR_TAB
5558 "st X,r26" CR_TAB
5559 "adiw r26,1" CR_TAB
5560 "st X+,__tmp_reg__" CR_TAB
5561 "st X+,r28" CR_TAB
5562 "st X,r29");
5563 else
5564 return *l=7, ("mov __tmp_reg__,r27" CR_TAB
5565 "st X,r26" CR_TAB
5566 "adiw r26,1" CR_TAB
5567 "st X+,__tmp_reg__" CR_TAB
5568 "st X+,r28" CR_TAB
5569 "st X,r29" CR_TAB
5570 "sbiw r26,3");
5572 else if (reg_base == reg_src + 2)
5574 if (reg_unused_after (insn, base))
5575 return *l=7, ("mov __zero_reg__,%C1" CR_TAB
5576 "mov __tmp_reg__,%D1" CR_TAB
5577 "st %0+,%A1" CR_TAB
5578 "st %0+,%B1" CR_TAB
5579 "st %0+,__zero_reg__" CR_TAB
5580 "st %0,__tmp_reg__" CR_TAB
5581 "clr __zero_reg__");
5582 else
5583 return *l=8, ("mov __zero_reg__,%C1" CR_TAB
5584 "mov __tmp_reg__,%D1" CR_TAB
5585 "st %0+,%A1" CR_TAB
5586 "st %0+,%B1" CR_TAB
5587 "st %0+,__zero_reg__" CR_TAB
5588 "st %0,__tmp_reg__" CR_TAB
5589 "clr __zero_reg__" CR_TAB
5590 "sbiw r26,3");
5592 return *l=5, ("st %0+,%A1" CR_TAB
5593 "st %0+,%B1" CR_TAB
5594 "st %0+,%C1" CR_TAB
5595 "st %0,%D1" CR_TAB
5596 "sbiw r26,3");
5598 else
5599 return *l=4, ("st %0,%A1" CR_TAB
5600 "std %0+1,%B1" CR_TAB
5601 "std %0+2,%C1" CR_TAB
5602 "std %0+3,%D1");
5604 else if (GET_CODE (base) == PLUS) /* (R + i) */
5606 int disp = INTVAL (XEXP (base, 1));
5608 if (AVR_TINY)
5609 return avr_out_movsi_mr_r_reg_disp_tiny (op, l);
5611 reg_base = REGNO (XEXP (base, 0));
5612 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
5614 if (reg_base != REG_Y)
5615 fatal_insn ("incorrect insn:",insn);
5617 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
5618 return *l = 6, ("adiw r28,%o0-60" CR_TAB
5619 "std Y+60,%A1" CR_TAB
5620 "std Y+61,%B1" CR_TAB
5621 "std Y+62,%C1" CR_TAB
5622 "std Y+63,%D1" CR_TAB
5623 "sbiw r28,%o0-60");
5625 return *l = 8, ("subi r28,lo8(-%o0)" CR_TAB
5626 "sbci r29,hi8(-%o0)" CR_TAB
5627 "st Y,%A1" CR_TAB
5628 "std Y+1,%B1" CR_TAB
5629 "std Y+2,%C1" CR_TAB
5630 "std Y+3,%D1" CR_TAB
5631 "subi r28,lo8(%o0)" CR_TAB
5632 "sbci r29,hi8(%o0)");
5634 if (reg_base == REG_X)
5636 /* (X + d) = R */
5637 if (reg_src == REG_X)
5639 *l = 9;
5640 return ("mov __tmp_reg__,r26" CR_TAB
5641 "mov __zero_reg__,r27" CR_TAB
5642 "adiw r26,%o0" CR_TAB
5643 "st X+,__tmp_reg__" CR_TAB
5644 "st X+,__zero_reg__" CR_TAB
5645 "st X+,r28" CR_TAB
5646 "st X,r29" CR_TAB
5647 "clr __zero_reg__" CR_TAB
5648 "sbiw r26,%o0+3");
5650 else if (reg_src == REG_X - 2)
5652 *l = 9;
5653 return ("mov __tmp_reg__,r26" CR_TAB
5654 "mov __zero_reg__,r27" CR_TAB
5655 "adiw r26,%o0" CR_TAB
5656 "st X+,r24" CR_TAB
5657 "st X+,r25" CR_TAB
5658 "st X+,__tmp_reg__" CR_TAB
5659 "st X,__zero_reg__" CR_TAB
5660 "clr __zero_reg__" CR_TAB
5661 "sbiw r26,%o0+3");
5663 *l = 6;
5664 return ("adiw r26,%o0" CR_TAB
5665 "st X+,%A1" CR_TAB
5666 "st X+,%B1" CR_TAB
5667 "st X+,%C1" CR_TAB
5668 "st X,%D1" CR_TAB
5669 "sbiw r26,%o0+3");
5671 return *l=4, ("std %A0,%A1" CR_TAB
5672 "std %B0,%B1" CR_TAB
5673 "std %C0,%C1" CR_TAB
5674 "std %D0,%D1");
5676 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5677 return *l=4, ("st %0,%D1" CR_TAB
5678 "st %0,%C1" CR_TAB
5679 "st %0,%B1" CR_TAB
5680 "st %0,%A1");
5681 else if (GET_CODE (base) == POST_INC) /* (R++) */
5682 return *l=4, ("st %0,%A1" CR_TAB
5683 "st %0,%B1" CR_TAB
5684 "st %0,%C1" CR_TAB
5685 "st %0,%D1");
5686 fatal_insn ("unknown move insn:",insn);
5687 return "";
5690 const char *
5691 output_movsisf (rtx_insn *insn, rtx operands[], int *l)
5693 int dummy;
5694 rtx dest = operands[0];
5695 rtx src = operands[1];
5696 int *real_l = l;
5698 if (avr_mem_flash_p (src)
5699 || avr_mem_flash_p (dest))
5701 return avr_out_lpm (insn, operands, real_l);
5704 if (!l)
5705 l = &dummy;
5707 gcc_assert (GET_MODE_SIZE (GET_MODE (dest)) == 4);
5709 if (REG_P (dest))
5711 if (REG_P (src)) /* mov r,r */
5713 if (true_regnum (dest) > true_regnum (src))
5715 if (AVR_HAVE_MOVW)
5717 *l = 2;
5718 return ("movw %C0,%C1" CR_TAB
5719 "movw %A0,%A1");
5721 *l = 4;
5722 return ("mov %D0,%D1" CR_TAB
5723 "mov %C0,%C1" CR_TAB
5724 "mov %B0,%B1" CR_TAB
5725 "mov %A0,%A1");
5727 else
5729 if (AVR_HAVE_MOVW)
5731 *l = 2;
5732 return ("movw %A0,%A1" CR_TAB
5733 "movw %C0,%C1");
5735 *l = 4;
5736 return ("mov %A0,%A1" CR_TAB
5737 "mov %B0,%B1" CR_TAB
5738 "mov %C0,%C1" CR_TAB
5739 "mov %D0,%D1");
5742 else if (CONSTANT_P (src))
5744 return output_reload_insisf (operands, NULL_RTX, real_l);
5746 else if (MEM_P (src))
5747 return out_movsi_r_mr (insn, operands, real_l); /* mov r,m */
5749 else if (MEM_P (dest))
5751 const char *templ;
5753 if (src == CONST0_RTX (GET_MODE (dest)))
5754 operands[1] = zero_reg_rtx;
5756 templ = out_movsi_mr_r (insn, operands, real_l);
5758 if (!real_l)
5759 output_asm_insn (templ, operands);
5761 operands[1] = src;
5762 return "";
5764 fatal_insn ("invalid insn:", insn);
5765 return "";
5769 /* Handle loads of 24-bit types from memory to register. */
5771 static const char *
5772 avr_out_load_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
5774 rtx dest = op[0];
5775 rtx src = op[1];
5776 rtx base = XEXP (src, 0);
5777 int reg_dest = true_regnum (dest);
5778 int reg_base = true_regnum (base);
5780 if (reg_base == reg_dest)
5782 return avr_asm_len (TINY_ADIW (%E1, %F1, 2) CR_TAB
5783 "ld %C0,%1" CR_TAB
5784 "ld __tmp_reg__,-%1" CR_TAB
5785 TINY_SBIW (%E1, %F1, 1) CR_TAB
5786 "ld %A0,%1" CR_TAB
5787 "mov %B0,__tmp_reg__", op, plen, -8);
5789 else
5791 avr_asm_len ("ld %A0,%1+" CR_TAB
5792 "ld %B0,%1+" CR_TAB
5793 "ld %C0,%1", op, plen, -3);
5795 if (reg_dest != reg_base - 2
5796 && !reg_unused_after (insn, base))
5798 avr_asm_len (TINY_SBIW (%E1, %F1, 2), op, plen, 2);
5800 return "";
5804 static const char *
5805 avr_out_load_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
5807 rtx dest = op[0];
5808 rtx src = op[1];
5809 rtx base = XEXP (src, 0);
5810 int reg_dest = true_regnum (dest);
5811 int reg_base = true_regnum (base);
5813 reg_base = true_regnum (XEXP (base, 0));
5814 if (reg_base == reg_dest)
5816 return avr_asm_len (TINY_ADIW (%I1, %J1, %o1+2) CR_TAB
5817 "ld %C0,%b1" CR_TAB
5818 "ld __tmp_reg__,-%b1" CR_TAB
5819 TINY_SBIW (%I1, %J1, 1) CR_TAB
5820 "ld %A0,%b1" CR_TAB
5821 "mov %B0,__tmp_reg__", op, plen, -8);
5823 else
5825 avr_asm_len (TINY_ADIW (%I1, %J1, %o1) CR_TAB
5826 "ld %A0,%b1+" CR_TAB
5827 "ld %B0,%b1+" CR_TAB
5828 "ld %C0,%b1", op, plen, -5);
5830 if (reg_dest != reg_base - 2
5831 && !reg_unused_after (insn, XEXP (base, 0)))
5832 avr_asm_len (TINY_SBIW (%I1, %J1, %o1+2), op, plen, 2);
5834 return "";
5838 static const char *
5839 avr_out_load_psi (rtx_insn *insn, rtx *op, int *plen)
5841 rtx dest = op[0];
5842 rtx src = op[1];
5843 rtx base = XEXP (src, 0);
5844 int reg_dest = true_regnum (dest);
5845 int reg_base = true_regnum (base);
5847 if (reg_base > 0)
5849 if (AVR_TINY)
5850 return avr_out_load_psi_reg_no_disp_tiny (insn, op, plen);
5852 if (reg_base == REG_X) /* (R26) */
5854 if (reg_dest == REG_X)
5855 /* "ld r26,-X" is undefined */
5856 return avr_asm_len ("adiw r26,2" CR_TAB
5857 "ld r28,X" CR_TAB
5858 "ld __tmp_reg__,-X" CR_TAB
5859 "sbiw r26,1" CR_TAB
5860 "ld r26,X" CR_TAB
5861 "mov r27,__tmp_reg__", op, plen, -6);
5862 else
5864 avr_asm_len ("ld %A0,X+" CR_TAB
5865 "ld %B0,X+" CR_TAB
5866 "ld %C0,X", op, plen, -3);
5868 if (reg_dest != REG_X - 2
5869 && !reg_unused_after (insn, base))
5871 avr_asm_len ("sbiw r26,2", op, plen, 1);
5874 return "";
5877 else /* reg_base != REG_X */
5879 if (reg_dest == reg_base)
5880 return avr_asm_len ("ldd %C0,%1+2" CR_TAB
5881 "ldd __tmp_reg__,%1+1" CR_TAB
5882 "ld %A0,%1" CR_TAB
5883 "mov %B0,__tmp_reg__", op, plen, -4);
5884 else
5885 return avr_asm_len ("ld %A0,%1" CR_TAB
5886 "ldd %B0,%1+1" CR_TAB
5887 "ldd %C0,%1+2", op, plen, -3);
5890 else if (GET_CODE (base) == PLUS) /* (R + i) */
5892 int disp = INTVAL (XEXP (base, 1));
5894 if (AVR_TINY)
5895 return avr_out_load_psi_reg_disp_tiny (insn, op, plen);
5897 if (disp > MAX_LD_OFFSET (GET_MODE (src)))
5899 if (REGNO (XEXP (base, 0)) != REG_Y)
5900 fatal_insn ("incorrect insn:",insn);
5902 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (src)))
5903 return avr_asm_len ("adiw r28,%o1-61" CR_TAB
5904 "ldd %A0,Y+61" CR_TAB
5905 "ldd %B0,Y+62" CR_TAB
5906 "ldd %C0,Y+63" CR_TAB
5907 "sbiw r28,%o1-61", op, plen, -5);
5909 return avr_asm_len ("subi r28,lo8(-%o1)" CR_TAB
5910 "sbci r29,hi8(-%o1)" CR_TAB
5911 "ld %A0,Y" CR_TAB
5912 "ldd %B0,Y+1" CR_TAB
5913 "ldd %C0,Y+2" CR_TAB
5914 "subi r28,lo8(%o1)" CR_TAB
5915 "sbci r29,hi8(%o1)", op, plen, -7);
5918 reg_base = true_regnum (XEXP (base, 0));
5919 if (reg_base == REG_X)
5921 /* R = (X + d) */
5922 if (reg_dest == REG_X)
5924 /* "ld r26,-X" is undefined */
5925 return avr_asm_len ("adiw r26,%o1+2" CR_TAB
5926 "ld r28,X" CR_TAB
5927 "ld __tmp_reg__,-X" CR_TAB
5928 "sbiw r26,1" CR_TAB
5929 "ld r26,X" CR_TAB
5930 "mov r27,__tmp_reg__", op, plen, -6);
5933 avr_asm_len ("adiw r26,%o1" CR_TAB
5934 "ld %A0,X+" CR_TAB
5935 "ld %B0,X+" CR_TAB
5936 "ld %C0,X", op, plen, -4);
5938 if (reg_dest != REG_W
5939 && !reg_unused_after (insn, XEXP (base, 0)))
5940 avr_asm_len ("sbiw r26,%o1+2", op, plen, 1);
5942 return "";
5945 if (reg_dest == reg_base)
5946 return avr_asm_len ("ldd %C0,%C1" CR_TAB
5947 "ldd __tmp_reg__,%B1" CR_TAB
5948 "ldd %A0,%A1" CR_TAB
5949 "mov %B0,__tmp_reg__", op, plen, -4);
5951 return avr_asm_len ("ldd %A0,%A1" CR_TAB
5952 "ldd %B0,%B1" CR_TAB
5953 "ldd %C0,%C1", op, plen, -3);
5955 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
5956 return avr_asm_len ("ld %C0,%1" CR_TAB
5957 "ld %B0,%1" CR_TAB
5958 "ld %A0,%1", op, plen, -3);
5959 else if (GET_CODE (base) == POST_INC) /* (R++) */
5960 return avr_asm_len ("ld %A0,%1" CR_TAB
5961 "ld %B0,%1" CR_TAB
5962 "ld %C0,%1", op, plen, -3);
5964 else if (CONSTANT_ADDRESS_P (base))
5966 int n_words = AVR_TINY ? 3 : 6;
5967 return avr_asm_len ("lds %A0,%m1" CR_TAB
5968 "lds %B0,%m1+1" CR_TAB
5969 "lds %C0,%m1+2", op, plen , -n_words);
5972 fatal_insn ("unknown move insn:",insn);
5973 return "";
5977 static const char *
5978 avr_out_store_psi_reg_no_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
5980 rtx dest = op[0];
5981 rtx src = op[1];
5982 rtx base = XEXP (dest, 0);
5983 int reg_base = true_regnum (base);
5984 int reg_src = true_regnum (src);
5986 if (reg_base == reg_src)
5988 avr_asm_len ("st %0,%A1" CR_TAB
5989 "mov __tmp_reg__,%B1" CR_TAB
5990 TINY_ADIW (%E0, %F0, 1) CR_TAB /* st X+, r27 is undefined */
5991 "st %0+,__tmp_reg__" CR_TAB
5992 "st %0,%C1", op, plen, -6);
5995 else if (reg_src == reg_base - 2)
5997 avr_asm_len ("st %0,%A1" CR_TAB
5998 "mov __tmp_reg__,%C1" CR_TAB
5999 TINY_ADIW (%E0, %F0, 1) CR_TAB
6000 "st %0+,%B1" CR_TAB
6001 "st %0,__tmp_reg__", op, plen, 6);
6003 else
6005 avr_asm_len ("st %0+,%A1" CR_TAB
6006 "st %0+,%B1" CR_TAB
6007 "st %0,%C1", op, plen, -3);
6010 if (!reg_unused_after (insn, base))
6011 avr_asm_len (TINY_SBIW (%E0, %F0, 2), op, plen, 2);
6013 return "";
6016 static const char *
6017 avr_out_store_psi_reg_disp_tiny (rtx_insn *insn, rtx *op, int *plen)
6019 rtx dest = op[0];
6020 rtx src = op[1];
6021 rtx base = XEXP (dest, 0);
6022 int reg_base = REGNO (XEXP (base, 0));
6023 int reg_src = true_regnum (src);
6025 if (reg_src == reg_base)
6026 avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
6027 "mov __zero_reg__,%B1" CR_TAB
6028 TINY_ADIW (%I0, %J0, %o0) CR_TAB
6029 "st %b0+,__tmp_reg__" CR_TAB
6030 "st %b0+,__zero_reg__" CR_TAB
6031 "st %b0,%C1" CR_TAB
6032 "clr __zero_reg__", op, plen, -8);
6033 else if (reg_src == reg_base - 2)
6034 avr_asm_len ("mov __tmp_reg__,%C1" CR_TAB
6035 TINY_ADIW (%I0, %J0, %o0) CR_TAB
6036 "st %b0+,%A1" CR_TAB
6037 "st %b0+,%B1" CR_TAB
6038 "st %b0,__tmp_reg__", op, plen, -6);
6039 else
6040 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
6041 "st %b0+,%A1" CR_TAB
6042 "st %b0+,%B1" CR_TAB
6043 "st %b0,%C1", op, plen, -5);
6045 if (!reg_unused_after (insn, XEXP (base, 0)))
6046 avr_asm_len (TINY_SBIW (%I0, %J0, %o0+2), op, plen, 2);
6048 return "";
6051 /* Handle store of 24-bit type from register or zero to memory. */
6053 static const char *
6054 avr_out_store_psi (rtx_insn *insn, rtx *op, int *plen)
6056 rtx dest = op[0];
6057 rtx src = op[1];
6058 rtx base = XEXP (dest, 0);
6059 int reg_base = true_regnum (base);
6061 if (CONSTANT_ADDRESS_P (base))
6063 int n_words = AVR_TINY ? 3 : 6;
6064 return avr_asm_len ("sts %m0,%A1" CR_TAB
6065 "sts %m0+1,%B1" CR_TAB
6066 "sts %m0+2,%C1", op, plen, -n_words);
6069 if (reg_base > 0) /* (r) */
6071 if (AVR_TINY)
6072 return avr_out_store_psi_reg_no_disp_tiny (insn, op, plen);
6074 if (reg_base == REG_X) /* (R26) */
6076 gcc_assert (!reg_overlap_mentioned_p (base, src));
6078 avr_asm_len ("st %0+,%A1" CR_TAB
6079 "st %0+,%B1" CR_TAB
6080 "st %0,%C1", op, plen, -3);
6082 if (!reg_unused_after (insn, base))
6083 avr_asm_len ("sbiw r26,2", op, plen, 1);
6085 return "";
6087 else
6088 return avr_asm_len ("st %0,%A1" CR_TAB
6089 "std %0+1,%B1" CR_TAB
6090 "std %0+2,%C1", op, plen, -3);
6092 else if (GET_CODE (base) == PLUS) /* (R + i) */
6094 int disp = INTVAL (XEXP (base, 1));
6096 if (AVR_TINY)
6097 return avr_out_store_psi_reg_disp_tiny (insn, op, plen);
6099 reg_base = REGNO (XEXP (base, 0));
6101 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
6103 if (reg_base != REG_Y)
6104 fatal_insn ("incorrect insn:",insn);
6106 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
6107 return avr_asm_len ("adiw r28,%o0-61" CR_TAB
6108 "std Y+61,%A1" CR_TAB
6109 "std Y+62,%B1" CR_TAB
6110 "std Y+63,%C1" CR_TAB
6111 "sbiw r28,%o0-61", op, plen, -5);
6113 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
6114 "sbci r29,hi8(-%o0)" CR_TAB
6115 "st Y,%A1" CR_TAB
6116 "std Y+1,%B1" CR_TAB
6117 "std Y+2,%C1" CR_TAB
6118 "subi r28,lo8(%o0)" CR_TAB
6119 "sbci r29,hi8(%o0)", op, plen, -7);
6121 if (reg_base == REG_X)
6123 /* (X + d) = R */
6124 gcc_assert (!reg_overlap_mentioned_p (XEXP (base, 0), src));
6126 avr_asm_len ("adiw r26,%o0" CR_TAB
6127 "st X+,%A1" CR_TAB
6128 "st X+,%B1" CR_TAB
6129 "st X,%C1", op, plen, -4);
6131 if (!reg_unused_after (insn, XEXP (base, 0)))
6132 avr_asm_len ("sbiw r26,%o0+2", op, plen, 1);
6134 return "";
6137 return avr_asm_len ("std %A0,%A1" CR_TAB
6138 "std %B0,%B1" CR_TAB
6139 "std %C0,%C1", op, plen, -3);
6141 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
6142 return avr_asm_len ("st %0,%C1" CR_TAB
6143 "st %0,%B1" CR_TAB
6144 "st %0,%A1", op, plen, -3);
6145 else if (GET_CODE (base) == POST_INC) /* (R++) */
6146 return avr_asm_len ("st %0,%A1" CR_TAB
6147 "st %0,%B1" CR_TAB
6148 "st %0,%C1", op, plen, -3);
6150 fatal_insn ("unknown move insn:",insn);
6151 return "";
6155 /* Move around 24-bit stuff. */
6157 const char *
6158 avr_out_movpsi (rtx_insn *insn, rtx *op, int *plen)
6160 rtx dest = op[0];
6161 rtx src = op[1];
6163 if (avr_mem_flash_p (src)
6164 || avr_mem_flash_p (dest))
6166 return avr_out_lpm (insn, op, plen);
6169 if (register_operand (dest, VOIDmode))
6171 if (register_operand (src, VOIDmode)) /* mov r,r */
6173 if (true_regnum (dest) > true_regnum (src))
6175 avr_asm_len ("mov %C0,%C1", op, plen, -1);
6177 if (AVR_HAVE_MOVW)
6178 return avr_asm_len ("movw %A0,%A1", op, plen, 1);
6179 else
6180 return avr_asm_len ("mov %B0,%B1" CR_TAB
6181 "mov %A0,%A1", op, plen, 2);
6183 else
6185 if (AVR_HAVE_MOVW)
6186 avr_asm_len ("movw %A0,%A1", op, plen, -1);
6187 else
6188 avr_asm_len ("mov %A0,%A1" CR_TAB
6189 "mov %B0,%B1", op, plen, -2);
6191 return avr_asm_len ("mov %C0,%C1", op, plen, 1);
6194 else if (CONSTANT_P (src))
6196 return avr_out_reload_inpsi (op, NULL_RTX, plen);
6198 else if (MEM_P (src))
6199 return avr_out_load_psi (insn, op, plen); /* mov r,m */
6201 else if (MEM_P (dest))
6203 rtx xop[2];
6205 xop[0] = dest;
6206 xop[1] = src == CONST0_RTX (GET_MODE (dest)) ? zero_reg_rtx : src;
6208 return avr_out_store_psi (insn, xop, plen);
6211 fatal_insn ("invalid insn:", insn);
6212 return "";
6215 static const char *
6216 avr_out_movqi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
6218 rtx dest = op[0];
6219 rtx src = op[1];
6220 rtx x = XEXP (dest, 0);
6222 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
6224 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
6225 TINY_ADIW (%I0, %J0, %o0) CR_TAB
6226 "st %b0,__tmp_reg__", op, plen, -4);
6228 else
6230 avr_asm_len (TINY_ADIW (%I0, %J0, %o0) CR_TAB
6231 "st %b0,%1", op, plen, -3);
6234 if (!reg_unused_after (insn, XEXP (x, 0)))
6235 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
6237 return "";
6240 static const char *
6241 out_movqi_mr_r (rtx_insn *insn, rtx op[], int *plen)
6243 rtx dest = op[0];
6244 rtx src = op[1];
6245 rtx x = XEXP (dest, 0);
6247 if (CONSTANT_ADDRESS_P (x))
6249 int n_words = AVR_TINY ? 1 : 2;
6250 return io_address_operand (x, QImode)
6251 ? avr_asm_len ("out %i0,%1", op, plen, -1)
6252 : avr_asm_len ("sts %m0,%1", op, plen, -n_words);
6254 else if (GET_CODE (x) == PLUS
6255 && REG_P (XEXP (x, 0))
6256 && CONST_INT_P (XEXP (x, 1)))
6258 /* memory access by reg+disp */
6260 int disp = INTVAL (XEXP (x, 1));
6262 if (AVR_TINY)
6263 return avr_out_movqi_mr_r_reg_disp_tiny (insn, op, plen);
6265 if (disp - GET_MODE_SIZE (GET_MODE (dest)) >= 63)
6267 if (REGNO (XEXP (x, 0)) != REG_Y)
6268 fatal_insn ("incorrect insn:",insn);
6270 if (disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest)))
6271 return avr_asm_len ("adiw r28,%o0-63" CR_TAB
6272 "std Y+63,%1" CR_TAB
6273 "sbiw r28,%o0-63", op, plen, -3);
6275 return avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
6276 "sbci r29,hi8(-%o0)" CR_TAB
6277 "st Y,%1" CR_TAB
6278 "subi r28,lo8(%o0)" CR_TAB
6279 "sbci r29,hi8(%o0)", op, plen, -5);
6281 else if (REGNO (XEXP (x, 0)) == REG_X)
6283 if (reg_overlap_mentioned_p (src, XEXP (x, 0)))
6285 avr_asm_len ("mov __tmp_reg__,%1" CR_TAB
6286 "adiw r26,%o0" CR_TAB
6287 "st X,__tmp_reg__", op, plen, -3);
6289 else
6291 avr_asm_len ("adiw r26,%o0" CR_TAB
6292 "st X,%1", op, plen, -2);
6295 if (!reg_unused_after (insn, XEXP (x, 0)))
6296 avr_asm_len ("sbiw r26,%o0", op, plen, 1);
6298 return "";
6301 return avr_asm_len ("std %0,%1", op, plen, -1);
6304 return avr_asm_len ("st %0,%1", op, plen, -1);
6308 /* Helper for the next function for XMEGA. It does the same
6309 but with low byte first. */
6311 static const char *
6312 avr_out_movhi_mr_r_xmega (rtx_insn *insn, rtx op[], int *plen)
6314 rtx dest = op[0];
6315 rtx src = op[1];
6316 rtx base = XEXP (dest, 0);
6317 int reg_base = true_regnum (base);
6318 int reg_src = true_regnum (src);
6320 /* "volatile" forces writing low byte first, even if less efficient,
6321 for correct operation with 16-bit I/O registers like SP. */
6322 bool mem_volatile_p = MEM_VOLATILE_P (dest);
6324 if (CONSTANT_ADDRESS_P (base))
6326 return io_address_operand (base, HImode)
6327 ? avr_asm_len ("out %i0,%A1" CR_TAB
6328 "out %i0+1,%B1", op, plen, -2)
6330 : avr_asm_len ("sts %m0,%A1" CR_TAB
6331 "sts %m0+1,%B1", op, plen, -4);
6334 if (reg_base > 0)
6336 if (reg_base != REG_X)
6337 return avr_asm_len ("st %0,%A1" CR_TAB
6338 "std %0+1,%B1", op, plen, -2);
6340 if (reg_src == REG_X)
6341 /* "st X+,r26" and "st -X,r26" are undefined. */
6342 avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
6343 "st X,r26" CR_TAB
6344 "adiw r26,1" CR_TAB
6345 "st X,__tmp_reg__", op, plen, -4);
6346 else
6347 avr_asm_len ("st X+,%A1" CR_TAB
6348 "st X,%B1", op, plen, -2);
6350 return reg_unused_after (insn, base)
6351 ? ""
6352 : avr_asm_len ("sbiw r26,1", op, plen, 1);
6354 else if (GET_CODE (base) == PLUS)
6356 int disp = INTVAL (XEXP (base, 1));
6357 reg_base = REGNO (XEXP (base, 0));
6358 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
6360 if (reg_base != REG_Y)
6361 fatal_insn ("incorrect insn:",insn);
6363 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
6364 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
6365 "std Y+62,%A1" CR_TAB
6366 "std Y+63,%B1" CR_TAB
6367 "sbiw r28,%o0-62", op, plen, -4)
6369 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
6370 "sbci r29,hi8(-%o0)" CR_TAB
6371 "st Y,%A1" CR_TAB
6372 "std Y+1,%B1" CR_TAB
6373 "subi r28,lo8(%o0)" CR_TAB
6374 "sbci r29,hi8(%o0)", op, plen, -6);
6377 if (reg_base != REG_X)
6378 return avr_asm_len ("std %A0,%A1" CR_TAB
6379 "std %B0,%B1", op, plen, -2);
6380 /* (X + d) = R */
6381 return reg_src == REG_X
6382 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
6383 "mov __zero_reg__,r27" CR_TAB
6384 "adiw r26,%o0" CR_TAB
6385 "st X+,__tmp_reg__" CR_TAB
6386 "st X,__zero_reg__" CR_TAB
6387 "clr __zero_reg__" CR_TAB
6388 "sbiw r26,%o0+1", op, plen, -7)
6390 : avr_asm_len ("adiw r26,%o0" CR_TAB
6391 "st X+,%A1" CR_TAB
6392 "st X,%B1" CR_TAB
6393 "sbiw r26,%o0+1", op, plen, -4);
6395 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
6397 if (!mem_volatile_p)
6398 return avr_asm_len ("st %0,%B1" CR_TAB
6399 "st %0,%A1", op, plen, -2);
6401 return REGNO (XEXP (base, 0)) == REG_X
6402 ? avr_asm_len ("sbiw r26,2" CR_TAB
6403 "st X+,%A1" CR_TAB
6404 "st X,%B1" CR_TAB
6405 "sbiw r26,1", op, plen, -4)
6407 : avr_asm_len ("sbiw %r0,2" CR_TAB
6408 "st %p0,%A1" CR_TAB
6409 "std %p0+1,%B1", op, plen, -3);
6411 else if (GET_CODE (base) == POST_INC) /* (R++) */
6413 return avr_asm_len ("st %0,%A1" CR_TAB
6414 "st %0,%B1", op, plen, -2);
6417 fatal_insn ("unknown move insn:",insn);
6418 return "";
6421 static const char *
6422 avr_out_movhi_mr_r_reg_no_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
6424 rtx dest = op[0];
6425 rtx src = op[1];
6426 rtx base = XEXP (dest, 0);
6427 int reg_base = true_regnum (base);
6428 int reg_src = true_regnum (src);
6429 bool mem_volatile_p = MEM_VOLATILE_P (dest);
6431 if (reg_base == reg_src)
6433 return !mem_volatile_p && reg_unused_after (insn, src)
6434 ? avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
6435 "st %0,%A1" CR_TAB
6436 TINY_ADIW (%E0, %F0, 1) CR_TAB
6437 "st %0,__tmp_reg__", op, plen, -5)
6438 : avr_asm_len ("mov __tmp_reg__,%B1" CR_TAB
6439 TINY_ADIW (%E0, %F0, 1) CR_TAB
6440 "st %0,__tmp_reg__" CR_TAB
6441 TINY_SBIW (%E0, %F0, 1) CR_TAB
6442 "st %0, %A1", op, plen, -7);
6445 return !mem_volatile_p && reg_unused_after (insn, base)
6446 ? avr_asm_len ("st %0+,%A1" CR_TAB
6447 "st %0,%B1", op, plen, -2)
6448 : avr_asm_len (TINY_ADIW (%E0, %F0, 1) CR_TAB
6449 "st %0,%B1" CR_TAB
6450 "st -%0,%A1", op, plen, -4);
6453 static const char *
6454 avr_out_movhi_mr_r_reg_disp_tiny (rtx_insn *insn, rtx op[], int *plen)
6456 rtx dest = op[0];
6457 rtx src = op[1];
6458 rtx base = XEXP (dest, 0);
6459 int reg_base = REGNO (XEXP (base, 0));
6460 int reg_src = true_regnum (src);
6462 if (reg_src == reg_base)
6463 avr_asm_len ("mov __tmp_reg__,%A1" CR_TAB
6464 "mov __zero_reg__,%B1" CR_TAB
6465 TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
6466 "st %b0,__zero_reg__" CR_TAB
6467 "st -%b0,__tmp_reg__" CR_TAB
6468 "clr __zero_reg__", op, plen, -7);
6469 else
6470 avr_asm_len (TINY_ADIW (%I0, %J0, %o0+1) CR_TAB
6471 "st %b0,%B1" CR_TAB
6472 "st -%b0,%A1", op, plen, -4);
6474 if (!reg_unused_after (insn, XEXP (base, 0)))
6475 avr_asm_len (TINY_SBIW (%I0, %J0, %o0), op, plen, 2);
6477 return "";
6480 static const char *
6481 avr_out_movhi_mr_r_post_inc_tiny (rtx op[], int *plen)
6483 return avr_asm_len (TINY_ADIW (%I0, %J0, 1) CR_TAB
6484 "st %p0,%B1" CR_TAB
6485 "st -%p0,%A1" CR_TAB
6486 TINY_ADIW (%I0, %J0, 2), op, plen, -6);
6489 static const char *
6490 out_movhi_mr_r (rtx_insn *insn, rtx op[], int *plen)
6492 rtx dest = op[0];
6493 rtx src = op[1];
6494 rtx base = XEXP (dest, 0);
6495 int reg_base = true_regnum (base);
6496 int reg_src = true_regnum (src);
6498 /* "volatile" forces writing high-byte first (no-xmega) resp.
6499 low-byte first (xmega) even if less efficient, for correct
6500 operation with 16-bit I/O registers like. */
6502 if (AVR_XMEGA)
6503 return avr_out_movhi_mr_r_xmega (insn, op, plen);
6505 bool mem_volatile_p = MEM_VOLATILE_P (dest);
6507 if (CONSTANT_ADDRESS_P (base))
6509 int n_words = AVR_TINY ? 2 : 4;
6510 return io_address_operand (base, HImode)
6511 ? avr_asm_len ("out %i0+1,%B1" CR_TAB
6512 "out %i0,%A1", op, plen, -2)
6514 : avr_asm_len ("sts %m0+1,%B1" CR_TAB
6515 "sts %m0,%A1", op, plen, -n_words);
6518 if (reg_base > 0)
6520 if (AVR_TINY)
6521 return avr_out_movhi_mr_r_reg_no_disp_tiny (insn, op, plen);
6523 if (reg_base != REG_X)
6524 return avr_asm_len ("std %0+1,%B1" CR_TAB
6525 "st %0,%A1", op, plen, -2);
6527 if (reg_src == REG_X)
6528 /* "st X+,r26" and "st -X,r26" are undefined. */
6529 return !mem_volatile_p && reg_unused_after (insn, src)
6530 ? avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
6531 "st X,r26" CR_TAB
6532 "adiw r26,1" CR_TAB
6533 "st X,__tmp_reg__", op, plen, -4)
6535 : avr_asm_len ("mov __tmp_reg__,r27" CR_TAB
6536 "adiw r26,1" CR_TAB
6537 "st X,__tmp_reg__" CR_TAB
6538 "sbiw r26,1" CR_TAB
6539 "st X,r26", op, plen, -5);
6541 return !mem_volatile_p && reg_unused_after (insn, base)
6542 ? avr_asm_len ("st X+,%A1" CR_TAB
6543 "st X,%B1", op, plen, -2)
6544 : avr_asm_len ("adiw r26,1" CR_TAB
6545 "st X,%B1" CR_TAB
6546 "st -X,%A1", op, plen, -3);
6548 else if (GET_CODE (base) == PLUS)
6550 int disp = INTVAL (XEXP (base, 1));
6552 if (AVR_TINY)
6553 return avr_out_movhi_mr_r_reg_disp_tiny (insn, op, plen);
6555 reg_base = REGNO (XEXP (base, 0));
6556 if (disp > MAX_LD_OFFSET (GET_MODE (dest)))
6558 if (reg_base != REG_Y)
6559 fatal_insn ("incorrect insn:",insn);
6561 return disp <= 63 + MAX_LD_OFFSET (GET_MODE (dest))
6562 ? avr_asm_len ("adiw r28,%o0-62" CR_TAB
6563 "std Y+63,%B1" CR_TAB
6564 "std Y+62,%A1" CR_TAB
6565 "sbiw r28,%o0-62", op, plen, -4)
6567 : avr_asm_len ("subi r28,lo8(-%o0)" CR_TAB
6568 "sbci r29,hi8(-%o0)" CR_TAB
6569 "std Y+1,%B1" CR_TAB
6570 "st Y,%A1" CR_TAB
6571 "subi r28,lo8(%o0)" CR_TAB
6572 "sbci r29,hi8(%o0)", op, plen, -6);
6575 if (reg_base != REG_X)
6576 return avr_asm_len ("std %B0,%B1" CR_TAB
6577 "std %A0,%A1", op, plen, -2);
6578 /* (X + d) = R */
6579 return reg_src == REG_X
6580 ? avr_asm_len ("mov __tmp_reg__,r26" CR_TAB
6581 "mov __zero_reg__,r27" CR_TAB
6582 "adiw r26,%o0+1" CR_TAB
6583 "st X,__zero_reg__" CR_TAB
6584 "st -X,__tmp_reg__" CR_TAB
6585 "clr __zero_reg__" CR_TAB
6586 "sbiw r26,%o0", op, plen, -7)
6588 : avr_asm_len ("adiw r26,%o0+1" CR_TAB
6589 "st X,%B1" CR_TAB
6590 "st -X,%A1" CR_TAB
6591 "sbiw r26,%o0", op, plen, -4);
6593 else if (GET_CODE (base) == PRE_DEC) /* (--R) */
6595 return avr_asm_len ("st %0,%B1" CR_TAB
6596 "st %0,%A1", op, plen, -2);
6598 else if (GET_CODE (base) == POST_INC) /* (R++) */
6600 if (!mem_volatile_p)
6601 return avr_asm_len ("st %0,%A1" CR_TAB
6602 "st %0,%B1", op, plen, -2);
6604 if (AVR_TINY)
6605 return avr_out_movhi_mr_r_post_inc_tiny (op, plen);
6607 return REGNO (XEXP (base, 0)) == REG_X
6608 ? avr_asm_len ("adiw r26,1" CR_TAB
6609 "st X,%B1" CR_TAB
6610 "st -X,%A1" CR_TAB
6611 "adiw r26,2", op, plen, -4)
6613 : avr_asm_len ("std %p0+1,%B1" CR_TAB
6614 "st %p0,%A1" CR_TAB
6615 "adiw %r0,2", op, plen, -3);
6617 fatal_insn ("unknown move insn:",insn);
6618 return "";
6622 /* During reload, we allow much more addresses than Reduced Tiny actually
6623 supports. Split them after reload in order to get closer to the
6624 core's capabilities. This sets the stage for pass .avr-fuse-add. */
6626 bool
6627 avr_split_tiny_move (rtx_insn * /*insn*/, rtx *xop)
6629 bool store_p = false;
6630 rtx mem, reg_or_0;
6632 if (REG_P (xop[0]) && MEM_P (xop[1]))
6634 reg_or_0 = xop[0];
6635 mem = xop[1];
6637 else if (MEM_P (xop[0])
6638 && (REG_P (xop[1])
6639 || xop[1] == CONST0_RTX (GET_MODE (xop[0]))))
6641 mem = xop[0];
6642 reg_or_0 = xop[1];
6643 store_p = true;
6645 else
6646 return false;
6648 machine_mode mode = GET_MODE (mem);
6649 rtx base, addr = XEXP (mem, 0);
6650 enum rtx_code addr_code = GET_CODE (addr);
6652 if (REG_P (reg_or_0)
6653 && reg_overlap_mentioned_p (reg_or_0, addr))
6654 return false;
6655 else if (addr_code == PLUS || addr_code == PRE_DEC || addr_code == POST_INC)
6656 base = XEXP (addr, 0);
6657 else if (addr_code == REG)
6658 base = addr;
6659 else
6660 return false;
6662 if (REGNO (base) > REG_Z)
6663 return false;
6665 bool volatile_p = MEM_VOLATILE_P (mem);
6666 bool mem_volatile_p = false;
6667 if (frame_pointer_needed
6668 && REGNO (base) == FRAME_POINTER_REGNUM)
6670 if (avr_fuse_add < 2
6671 // Be a projection (we always split PLUS).
6672 || (avr_fuse_add == 2 && volatile_p && addr_code != PLUS))
6673 return false;
6675 // Changing the frame pointer locally may confuse later passes
6676 // like .dse2 which don't track changes of FP, not even when
6677 // respective CFA notes are present. An example is pr22141-1.c.
6678 if (avr_fuse_add == 2)
6679 mem_volatile_p = true;
6682 enum rtx_code new_code = UNKNOWN;
6683 HOST_WIDE_INT add = 0, sub = 0;
6684 int msize = GET_MODE_SIZE (mode);
6686 AVR_LdSt_Props ap { REGNO (base), store_p, volatile_p, ADDR_SPACE_GENERIC };
6688 switch (addr_code)
6690 default:
6691 return false;
6693 case PLUS:
6694 add = INTVAL (XEXP (addr, 1));
6695 if (msize == 1)
6697 new_code = REG;
6698 sub = -add;
6700 else if (ap.want_predec)
6702 // volatile stores prefer PRE_DEC (MSB first)
6703 sub = -add;
6704 add += msize;
6705 new_code = PRE_DEC;
6707 else
6709 new_code = POST_INC;
6710 sub = -add - msize;
6712 break;
6714 case POST_INC:
6715 // volatile stores prefer PRE_DEC (MSB first)
6716 if (msize > 1 && ap.want_predec)
6718 add = msize;
6719 new_code = PRE_DEC;
6720 sub = msize;
6721 break;
6723 return false;
6725 case PRE_DEC:
6726 // volatile loads prefer POST_INC (LSB first)
6727 if (msize > 1 && ap.want_postinc)
6729 add = -msize;
6730 new_code = POST_INC;
6731 sub = -msize;
6732 break;
6734 return false;
6736 case REG:
6737 if (msize == 1)
6738 return false;
6740 if (ap.want_predec)
6742 add = msize;
6743 new_code = PRE_DEC;
6744 sub = 0;
6746 else
6748 add = 0;
6749 new_code = POST_INC;
6750 sub = -msize;
6752 break;
6753 } // switch addr_code
6755 rtx_insn *insn;
6757 if (add)
6759 insn = emit_move_ccc (base, plus_constant (Pmode, base, add));
6760 avr_maybe_adjust_cfa (insn, base, add);
6763 rtx new_addr = new_code == REG
6764 ? base
6765 : gen_rtx_fmt_e (new_code, Pmode, base);
6767 rtx new_mem = change_address (mem, mode, new_addr);
6768 if (mem_volatile_p)
6769 MEM_VOLATILE_P (new_mem) = 1;
6771 insn = emit_move_ccc (store_p ? new_mem : reg_or_0,
6772 store_p ? reg_or_0 : new_mem);
6773 if (auto_inc_p (new_addr))
6775 add_reg_note (insn, REG_INC, base);
6776 int off = new_code == POST_INC ? msize : -msize;
6777 avr_maybe_adjust_cfa (insn, base, off);
6780 if (sub)
6782 insn = emit_move_ccc (base, plus_constant (Pmode, base, sub));
6783 avr_maybe_adjust_cfa (insn, base, sub);
6786 return true;
6790 /* Implement `TARGET_FRAME_POINTER_REQUIRED'. */
6791 /* Return 1 if frame pointer for current function required. */
6793 static bool
6794 avr_frame_pointer_required_p (void)
6796 return (cfun->calls_alloca
6797 || cfun->calls_setjmp
6798 || cfun->has_nonlocal_label
6799 || crtl->args.info.has_stack_args
6800 || get_frame_size () > 0);
6804 /* Returns the condition of the branch following INSN, where INSN is some
6805 comparison. If the next insn is not a branch or the condition code set
6806 by INSN might be used by more insns than the next one, return UNKNOWN.
6807 For now, just look at the next insn, which misses some opportunities like
6808 following jumps. */
6810 static RTX_CODE
6811 compare_condition (rtx_insn *insn)
6813 rtx set;
6814 rtx_insn *next = next_real_nondebug_insn (insn);
6816 if (next
6817 && JUMP_P (next)
6818 // If SREG does not die in the next insn, it is used in more than one
6819 // branch. This can happen due to pass .avr-ifelse optimizations.
6820 && dead_or_set_regno_p (next, REG_CC)
6821 // Branches are (set (pc) (if_then_else (COND (...)))).
6822 && (set = single_set (next))
6823 && GET_CODE (SET_SRC (set)) == IF_THEN_ELSE)
6825 return GET_CODE (XEXP (SET_SRC (set), 0));
6828 return UNKNOWN;
6832 /* Returns true if INSN is a tst insn that only tests the sign. */
6834 static bool
6835 compare_sign_p (rtx_insn *insn)
6837 RTX_CODE cond = compare_condition (insn);
6838 return (cond == GE || cond == LT);
6842 /* Returns true if INSN is a compare insn with the EQ or NE condition. */
6844 static bool
6845 compare_eq_p (rtx_insn *insn)
6847 RTX_CODE cond = compare_condition (insn);
6848 return (cond == EQ || cond == NE);
6852 /* Implement `TARGET_CANONICALIZE_COMPARISON'. */
6853 /* Basically tries to convert "difficult" comparisons like GT[U]
6854 and LE[U] to simple ones. Some asymmetric comparisons can be
6855 transformed to EQ or NE against zero. */
6857 static void
6858 avr_canonicalize_comparison (int *icode, rtx *op0, rtx *op1, bool op0_fixed)
6860 enum rtx_code code = (enum rtx_code) *icode;
6861 machine_mode mode = GET_MODE (*op0);
6863 bool signed_p = code == GT || code == LE;
6864 bool unsigned_p = code == GTU || code == LEU;
6865 bool difficult_p = signed_p || unsigned_p;
6867 if (// Only do integers and fixed-points.
6868 (! SCALAR_INT_MODE_P (mode)
6869 && ! ALL_SCALAR_FIXED_POINT_MODE_P (mode))
6870 // Only do comparisons against a register.
6871 || ! register_operand (*op0, mode))
6872 return;
6874 // Canonicalize "difficult" reg-reg comparisons.
6876 if (! op0_fixed
6877 && difficult_p
6878 && register_operand (*op1, mode))
6880 std::swap (*op0, *op1);
6881 *icode = (int) swap_condition (code);
6882 return;
6885 // Canonicalize comparisons against compile-time constants.
6887 if (CONST_INT_P (*op1)
6888 || CONST_FIXED_P (*op1))
6890 // INT_MODE of the same size.
6891 scalar_int_mode imode = int_mode_for_mode (mode).require ();
6893 unsigned HOST_WIDE_INT mask = GET_MODE_MASK (imode);
6894 unsigned HOST_WIDE_INT maxval = signed_p ? mask >> 1 : mask;
6896 // Convert value *op1 to imode.
6897 rtx xval = simplify_gen_subreg (imode, *op1, mode, 0);
6899 // Canonicalize difficult comparisons against const.
6900 if (difficult_p
6901 && (UINTVAL (xval) & mask) != maxval)
6903 // Convert *op0 > *op1 to *op0 >= 1 + *op1.
6904 // Convert *op0 <= *op1 to *op0 < 1 + *op1.
6905 xval = simplify_binary_operation (PLUS, imode, xval, const1_rtx);
6907 // Convert value back to its original mode.
6908 *op1 = simplify_gen_subreg (mode, xval, imode, 0);
6910 // Map > to >= and <= to <.
6911 *icode = (int) avr_normalize_condition (code);
6913 return;
6916 // Some asymmetric comparisons can be turned into EQ or NE.
6917 if (code == LTU && xval == const1_rtx)
6919 *icode = (int) EQ;
6920 *op1 = CONST0_RTX (mode);
6921 return;
6924 if (code == GEU && xval == const1_rtx)
6926 *icode = (int) NE;
6927 *op1 = CONST0_RTX (mode);
6928 return;
6934 /* Output compare instruction
6936 compare (XOP[0], XOP[1])
6938 for a register XOP[0] and a compile-time constant XOP[1]. Return "".
6939 XOP[2] is an 8-bit scratch register as needed.
6941 PLEN == NULL: Output instructions.
6942 PLEN != NULL: Set *PLEN to the length (in words) of the sequence.
6943 Don't output anything. */
6945 const char *
6946 avr_out_compare (rtx_insn *insn, rtx *xop, int *plen)
6948 /* Register to compare and value to compare against. */
6949 rtx xreg = xop[0];
6950 rtx xval = xop[1];
6952 /* Number of bytes to operate on. */
6953 int n_bytes = GET_MODE_SIZE (GET_MODE (xreg));
6955 /* Value (0..0xff) held in clobber register xop[2] or -1 if unknown. */
6956 int clobber_val = -1;
6958 /* Map fixed mode operands to integer operands with the same binary
6959 representation. They are easier to handle in the remainder. */
6961 if (CONST_FIXED_P (xval))
6963 xreg = avr_to_int_mode (xop[0]);
6964 xval = avr_to_int_mode (xop[1]);
6967 /* MODE of the comparison. */
6968 machine_mode mode = GET_MODE (xreg);
6970 gcc_assert (REG_P (xreg));
6971 gcc_assert ((CONST_INT_P (xval) && n_bytes <= 4)
6972 || (const_double_operand (xval, VOIDmode) && n_bytes == 8));
6974 if (plen)
6975 *plen = 0;
6977 /* Comparisons == +/-1 and != +/-1 can be done similar to camparing
6978 against 0 by ORing the bytes. This is one instruction shorter.
6979 Notice that 64-bit comparisons are always against reg:ALL8 18 (ACC_A)
6980 and therefore don't use this. */
6982 if (!test_hard_reg_class (LD_REGS, xreg)
6983 && compare_eq_p (insn)
6984 && reg_unused_after (insn, xreg))
6986 if (xval == const1_rtx)
6988 avr_asm_len ("dec %A0" CR_TAB
6989 "or %A0,%B0", xop, plen, 2);
6991 if (n_bytes >= 3)
6992 avr_asm_len ("or %A0,%C0", xop, plen, 1);
6994 if (n_bytes >= 4)
6995 avr_asm_len ("or %A0,%D0", xop, plen, 1);
6997 return "";
6999 else if (xval == constm1_rtx)
7001 if (n_bytes >= 4)
7002 avr_asm_len ("and %A0,%D0", xop, plen, 1);
7004 if (n_bytes >= 3)
7005 avr_asm_len ("and %A0,%C0", xop, plen, 1);
7007 return avr_asm_len ("and %A0,%B0" CR_TAB
7008 "com %A0", xop, plen, 2);
7012 /* Comparisons == -1 and != -1 of a d-register that's used after the
7013 comparison. (If it's unused after we use CPI / SBCI or ADIW sequence
7014 from below.) Instead of CPI Rlo,-1 / LDI Rx,-1 / CPC Rhi,Rx we can
7015 use CPI Rlo,-1 / CPC Rhi,Rlo which is 1 instruction shorter:
7016 If CPI is true then Rlo contains -1 and we can use Rlo instead of Rx
7017 when CPC'ing the high part. If CPI is false then CPC cannot render
7018 the result to true. This also works for the more generic case where
7019 the constant is of the form 0xabab. */
7021 if (n_bytes == 2
7022 && xval != const0_rtx
7023 && test_hard_reg_class (LD_REGS, xreg)
7024 && compare_eq_p (insn)
7025 && !reg_unused_after (insn, xreg))
7027 rtx xlo8 = simplify_gen_subreg (QImode, xval, mode, 0);
7028 rtx xhi8 = simplify_gen_subreg (QImode, xval, mode, 1);
7030 if (INTVAL (xlo8) == INTVAL (xhi8))
7032 xop[0] = xreg;
7033 xop[1] = xlo8;
7035 return avr_asm_len ("cpi %A0,%1" CR_TAB
7036 "cpc %B0,%A0", xop, plen, 2);
7040 for (int i = 0; i < n_bytes; i++)
7042 /* We compare byte-wise. */
7043 rtx reg8 = simplify_gen_subreg (QImode, xreg, mode, i);
7044 rtx xval8 = simplify_gen_subreg (QImode, xval, mode, i);
7046 /* 8-bit value to compare with this byte. */
7047 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
7049 /* Registers R16..R31 can operate with immediate. */
7050 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
7052 xop[0] = reg8;
7053 xop[1] = gen_int_mode (val8, QImode);
7055 /* Word registers >= R24 can use SBIW/ADIW with 0..63. */
7057 if (i == 0
7058 && avr_adiw_reg_p (reg8))
7060 int val16 = trunc_int_for_mode (INTVAL (xval), HImode);
7062 if (IN_RANGE (val16, 0, 63)
7063 && (val8 == 0
7064 || reg_unused_after (insn, xreg)))
7066 avr_asm_len ("sbiw %0,%1", xop, plen, 1);
7068 i++;
7069 continue;
7072 if (n_bytes == 2
7073 && IN_RANGE (val16, -63, -1)
7074 && compare_eq_p (insn)
7075 && reg_unused_after (insn, xreg))
7077 return avr_asm_len ("adiw %0,%n1", xop, plen, 1);
7081 /* Comparing against 0 is easy. */
7083 if (val8 == 0)
7085 avr_asm_len (i == 0
7086 ? "cp %0,__zero_reg__"
7087 : "cpc %0,__zero_reg__", xop, plen, 1);
7088 continue;
7091 /* Upper registers can compare and subtract-with-carry immediates.
7092 Notice that compare instructions do the same as respective subtract
7093 instruction; the only difference is that comparisons don't write
7094 the result back to the target register. */
7096 if (ld_reg_p)
7098 if (i == 0)
7100 avr_asm_len ("cpi %0,%1", xop, plen, 1);
7101 continue;
7103 else if (reg_unused_after (insn, xreg))
7105 avr_asm_len ("sbci %0,%1", xop, plen, 1);
7106 continue;
7110 /* Must load the value into the scratch register. */
7112 gcc_assert (REG_P (xop[2]));
7114 if (clobber_val != (int) val8)
7115 avr_asm_len ("ldi %2,%1", xop, plen, 1);
7116 clobber_val = (int) val8;
7118 avr_asm_len (i == 0
7119 ? "cp %0,%2"
7120 : "cpc %0,%2", xop, plen, 1);
7123 return "";
7127 /* Prepare operands of compare_const_di2 to be used with avr_out_compare. */
7129 const char *
7130 avr_out_compare64 (rtx_insn *insn, rtx *op, int *plen)
7132 rtx xop[3] = { gen_rtx_REG (DImode, ACC_A), op[0], op[1] };
7134 return avr_out_compare (insn, xop, plen);
7137 /* Output test instruction for HImode. */
7139 const char *
7140 avr_out_tsthi (rtx_insn *insn, rtx *op, int *plen)
7142 if (compare_sign_p (insn))
7144 avr_asm_len ("tst %B0", op, plen, -1);
7146 else if (reg_unused_after (insn, op[0])
7147 && compare_eq_p (insn))
7149 /* Faster than sbiw if we can clobber the operand. */
7150 avr_asm_len ("or %A0,%B0", op, plen, -1);
7152 else
7154 avr_out_compare (insn, op, plen);
7157 return "";
7161 /* Output test instruction for PSImode. */
7163 const char *
7164 avr_out_tstpsi (rtx_insn *insn, rtx *op, int *plen)
7166 if (compare_sign_p (insn))
7168 avr_asm_len ("tst %C0", op, plen, -1);
7170 else if (reg_unused_after (insn, op[0])
7171 && compare_eq_p (insn))
7173 /* Faster than sbiw if we can clobber the operand. */
7174 avr_asm_len ("or %A0,%B0" CR_TAB
7175 "or %A0,%C0", op, plen, -2);
7177 else
7179 avr_out_compare (insn, op, plen);
7182 return "";
7186 /* Output test instruction for SImode. */
7188 const char *
7189 avr_out_tstsi (rtx_insn *insn, rtx *op, int *plen)
7191 if (compare_sign_p (insn))
7193 avr_asm_len ("tst %D0", op, plen, -1);
7195 else if (reg_unused_after (insn, op[0])
7196 && compare_eq_p (insn))
7198 /* Faster than sbiw if we can clobber the operand. */
7199 avr_asm_len ("or %A0,%B0" CR_TAB
7200 "or %A0,%C0" CR_TAB
7201 "or %A0,%D0", op, plen, -3);
7203 else
7205 avr_out_compare (insn, op, plen);
7208 return "";
7212 /* Output a comparison of a zero- or sign-extended register against a
7213 plain register. CODE is SIGN_EXTEND or ZERO_EXTEND. Return "".
7215 PLEN != 0: Set *PLEN to the code length in words. Don't output anything.
7216 PLEN == 0: Print instructions. */
7218 const char *
7219 avr_out_cmp_ext (rtx xop[], enum rtx_code code, int *plen)
7221 // The smaller reg is the one that's to be extended. Get its index as z.
7222 int z = GET_MODE_SIZE (GET_MODE (xop[1])) < GET_MODE_SIZE (GET_MODE (xop[0]));
7223 rtx zreg = xop[z];
7224 rtx reg = xop[1 - z];
7225 machine_mode mode = GET_MODE (reg);
7226 machine_mode zmode = GET_MODE (zreg);
7227 rtx zex;
7229 if (plen)
7230 *plen = 0;
7232 // zex holds the extended bytes above zreg. This is 0 for ZERO_EXTEND,
7233 // and 0 or -1 for SIGN_EXTEND.
7235 if (code == SIGN_EXTEND)
7237 // Sign-extend the high-byte of zreg to tmp_reg.
7238 int zmsb = GET_MODE_SIZE (zmode) - 1;
7239 rtx xzmsb = simplify_gen_subreg (QImode, zreg, zmode, zmsb);
7241 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
7242 "rol __tmp_reg__" CR_TAB
7243 "sbc __tmp_reg__,__tmp_reg__", &xzmsb, plen, 3);
7244 zex = tmp_reg_rtx;
7246 else if (code == ZERO_EXTEND)
7248 zex = zero_reg_rtx;
7250 else
7251 gcc_unreachable();
7253 // Now output n_bytes bytes of the very comparison.
7255 int n_bytes = GET_MODE_SIZE (mode);
7257 avr_asm_len ("cp %0,%1", xop, plen, 1);
7259 for (int b = 1; b < n_bytes; ++b)
7261 rtx regs[2];
7262 regs[1 - z] = simplify_gen_subreg (QImode, reg, mode, b);
7263 regs[z] = (b < GET_MODE_SIZE (zmode)
7264 ? simplify_gen_subreg (QImode, zreg, zmode, b)
7265 : zex);
7267 avr_asm_len ("cpc %0,%1", regs, plen, 1);
7270 return "";
7274 /* Generate asm equivalent for various shifts. This only handles cases
7275 that are not already carefully hand-optimized in ?sh??i3_out.
7277 OPERANDS[0] resp. %0 in TEMPL is the operand to be shifted.
7278 OPERANDS[2] is the shift count as CONST_INT, MEM or REG.
7279 OPERANDS[3] is a QImode scratch register from LD regs if
7280 available and SCRATCH, otherwise (no scratch available)
7282 TEMPL is an assembler template that shifts by one position.
7283 T_LEN is the length of this template. */
7285 void
7286 out_shift_with_cnt (const char *templ, rtx_insn *insn, rtx operands[],
7287 int *plen, int t_len)
7289 bool second_label = true;
7290 bool saved_in_tmp = false;
7291 bool use_zero_reg = false;
7292 rtx op[5];
7294 op[0] = operands[0];
7295 op[1] = operands[1];
7296 op[2] = operands[2];
7297 op[3] = operands[3];
7299 if (plen)
7300 *plen = 0;
7302 if (CONST_INT_P (operands[2]))
7304 /* Operand 3 is a scratch register if this is a
7305 parallel with three elements i.e. a set,
7306 a clobber of a scratch, and clobber of REG_CC.
7307 If a scratch reg is not available, then the parallel
7308 will contain only a set and clobber of REG_CC. */
7309 bool scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
7310 && XVECLEN (PATTERN (insn), 0) == 3
7311 && REG_P (operands[3]));
7312 int count = INTVAL (operands[2]);
7313 int max_len = 10; /* If larger than this, always use a loop. */
7315 if (count <= 0)
7316 return;
7318 if (count < 8 && !scratch)
7319 use_zero_reg = true;
7321 if (optimize_size)
7322 max_len = t_len + (scratch ? 3 : (use_zero_reg ? 4 : 5));
7324 if (t_len * count <= max_len)
7326 /* Output shifts inline with no loop - faster. */
7328 while (count-- > 0)
7329 avr_asm_len (templ, op, plen, t_len);
7331 return;
7334 if (scratch)
7336 avr_asm_len ("ldi %3,%2", op, plen, 1);
7338 else if (use_zero_reg)
7340 /* Hack to save one word: use __zero_reg__ as loop counter.
7341 Set one bit, then shift in a loop until it is 0 again. */
7343 op[3] = zero_reg_rtx;
7345 avr_asm_len ("set" CR_TAB
7346 "bld %3,%2-1", op, plen, 2);
7348 else
7350 /* No scratch register available, use one from LD_REGS (saved in
7351 __tmp_reg__) that doesn't overlap with registers to shift. */
7353 op[3] = all_regs_rtx[((REGNO (op[0]) - 1) & 15) + REG_16];
7354 op[4] = tmp_reg_rtx;
7355 saved_in_tmp = true;
7357 avr_asm_len ("mov %4,%3" CR_TAB
7358 "ldi %3,%2", op, plen, 2);
7361 second_label = false;
7363 else if (MEM_P (op[2]))
7365 rtx op_mov[2];
7367 op_mov[0] = op[3] = tmp_reg_rtx;
7368 op_mov[1] = op[2];
7370 out_movqi_r_mr (insn, op_mov, plen);
7372 else if (register_operand (op[2], QImode))
7374 op[3] = op[2];
7376 if (!reg_unused_after (insn, op[2])
7377 || reg_overlap_mentioned_p (op[0], op[2]))
7379 op[3] = tmp_reg_rtx;
7380 avr_asm_len ("mov %3,%2", op, plen, 1);
7383 else
7384 fatal_insn ("bad shift insn:", insn);
7386 if (second_label)
7387 avr_asm_len ("rjmp 2f", op, plen, 1);
7389 avr_asm_len ("1:", op, plen, 0);
7390 avr_asm_len (templ, op, plen, t_len);
7392 if (second_label)
7393 avr_asm_len ("2:", op, plen, 0);
7395 avr_asm_len (use_zero_reg ? "lsr %3" : "dec %3", op, plen, 1);
7396 avr_asm_len (second_label ? "brpl 1b" : "brne 1b", op, plen, 1);
7398 if (saved_in_tmp)
7399 avr_asm_len ("mov %3,%4", op, plen, 1);
7403 /* 8bit shift left ((char)x << i) */
7405 const char *
7406 ashlqi3_out (rtx_insn *insn, rtx operands[], int *len)
7408 if (CONST_INT_P (operands[2]))
7410 int k;
7412 if (!len)
7413 len = &k;
7415 switch (INTVAL (operands[2]))
7417 default:
7418 if (INTVAL (operands[2]) < 8)
7419 break;
7421 *len = 1;
7422 return "clr %0";
7424 case 1:
7425 *len = 1;
7426 return "lsl %0";
7428 case 2:
7429 *len = 2;
7430 return ("lsl %0" CR_TAB
7431 "lsl %0");
7433 case 3:
7434 *len = 3;
7435 return ("lsl %0" CR_TAB
7436 "lsl %0" CR_TAB
7437 "lsl %0");
7439 case 4:
7440 if (test_hard_reg_class (LD_REGS, operands[0]))
7442 *len = 2;
7443 return ("swap %0" CR_TAB
7444 "andi %0,0xf0");
7446 *len = 4;
7447 return ("lsl %0" CR_TAB
7448 "lsl %0" CR_TAB
7449 "lsl %0" CR_TAB
7450 "lsl %0");
7452 case 5:
7453 if (test_hard_reg_class (LD_REGS, operands[0]))
7455 *len = 3;
7456 return ("swap %0" CR_TAB
7457 "lsl %0" CR_TAB
7458 "andi %0,0xe0");
7460 *len = 5;
7461 return ("lsl %0" CR_TAB
7462 "lsl %0" CR_TAB
7463 "lsl %0" CR_TAB
7464 "lsl %0" CR_TAB
7465 "lsl %0");
7467 case 6:
7468 if (test_hard_reg_class (LD_REGS, operands[0]))
7470 *len = 4;
7471 return ("swap %0" CR_TAB
7472 "lsl %0" CR_TAB
7473 "lsl %0" CR_TAB
7474 "andi %0,0xc0");
7476 *len = 6;
7477 return ("lsl %0" CR_TAB
7478 "lsl %0" CR_TAB
7479 "lsl %0" CR_TAB
7480 "lsl %0" CR_TAB
7481 "lsl %0" CR_TAB
7482 "lsl %0");
7484 case 7:
7485 *len = 3;
7486 return ("ror %0" CR_TAB
7487 "clr %0" CR_TAB
7488 "ror %0");
7491 else if (CONSTANT_P (operands[2]))
7492 fatal_insn ("internal compiler error. Incorrect shift:", insn);
7494 out_shift_with_cnt ("lsl %0",
7495 insn, operands, len, 1);
7496 return "";
7500 /* 16bit shift left ((short)x << i) */
7502 const char *
7503 ashlhi3_out (rtx_insn *insn, rtx operands[], int *len)
7505 if (CONST_INT_P (operands[2]))
7507 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
7508 && XVECLEN (PATTERN (insn), 0) == 3
7509 && REG_P (operands[3]));
7510 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
7511 int k;
7512 int *t = len;
7514 if (!len)
7515 len = &k;
7517 switch (INTVAL (operands[2]))
7519 default:
7520 if (INTVAL (operands[2]) < 16)
7521 break;
7523 *len = 2;
7524 return ("clr %B0" CR_TAB
7525 "clr %A0");
7527 case 4:
7528 if (optimize_size && scratch)
7529 break; /* 5 */
7530 if (ldi_ok)
7532 *len = 6;
7533 return ("swap %A0" CR_TAB
7534 "swap %B0" CR_TAB
7535 "andi %B0,0xf0" CR_TAB
7536 "eor %B0,%A0" CR_TAB
7537 "andi %A0,0xf0" CR_TAB
7538 "eor %B0,%A0");
7540 if (scratch)
7542 *len = 7;
7543 return ("swap %A0" CR_TAB
7544 "swap %B0" CR_TAB
7545 "ldi %3,0xf0" CR_TAB
7546 "and %B0,%3" CR_TAB
7547 "eor %B0,%A0" CR_TAB
7548 "and %A0,%3" CR_TAB
7549 "eor %B0,%A0");
7551 break; /* optimize_size ? 6 : 8 */
7553 case 5:
7554 if (optimize_size)
7555 break; /* scratch ? 5 : 6 */
7556 if (ldi_ok)
7558 *len = 8;
7559 return ("lsl %A0" CR_TAB
7560 "rol %B0" CR_TAB
7561 "swap %A0" CR_TAB
7562 "swap %B0" CR_TAB
7563 "andi %B0,0xf0" CR_TAB
7564 "eor %B0,%A0" CR_TAB
7565 "andi %A0,0xf0" CR_TAB
7566 "eor %B0,%A0");
7568 if (scratch)
7570 *len = 9;
7571 return ("lsl %A0" CR_TAB
7572 "rol %B0" CR_TAB
7573 "swap %A0" CR_TAB
7574 "swap %B0" CR_TAB
7575 "ldi %3,0xf0" CR_TAB
7576 "and %B0,%3" CR_TAB
7577 "eor %B0,%A0" CR_TAB
7578 "and %A0,%3" CR_TAB
7579 "eor %B0,%A0");
7581 break; /* 10 */
7583 case 6:
7584 if (optimize_size)
7585 break; /* scratch ? 5 : 6 */
7586 *len = 9;
7587 return ("clr __tmp_reg__" CR_TAB
7588 "lsr %B0" CR_TAB
7589 "ror %A0" CR_TAB
7590 "ror __tmp_reg__" CR_TAB
7591 "lsr %B0" CR_TAB
7592 "ror %A0" CR_TAB
7593 "ror __tmp_reg__" CR_TAB
7594 "mov %B0,%A0" CR_TAB
7595 "mov %A0,__tmp_reg__");
7597 case 7:
7598 *len = 5;
7599 return ("lsr %B0" CR_TAB
7600 "mov %B0,%A0" CR_TAB
7601 "clr %A0" CR_TAB
7602 "ror %B0" CR_TAB
7603 "ror %A0");
7605 case 8:
7606 return *len = 2, ("mov %B0,%A1" CR_TAB
7607 "clr %A0");
7609 case 9:
7610 *len = 3;
7611 return ("mov %B0,%A0" CR_TAB
7612 "clr %A0" CR_TAB
7613 "lsl %B0");
7615 case 10:
7616 *len = 4;
7617 return ("mov %B0,%A0" CR_TAB
7618 "clr %A0" CR_TAB
7619 "lsl %B0" CR_TAB
7620 "lsl %B0");
7622 case 11:
7623 *len = 5;
7624 return ("mov %B0,%A0" CR_TAB
7625 "clr %A0" CR_TAB
7626 "lsl %B0" CR_TAB
7627 "lsl %B0" CR_TAB
7628 "lsl %B0");
7630 case 12:
7631 if (ldi_ok)
7633 *len = 4;
7634 return ("mov %B0,%A0" CR_TAB
7635 "clr %A0" CR_TAB
7636 "swap %B0" CR_TAB
7637 "andi %B0,0xf0");
7639 if (scratch)
7641 *len = 5;
7642 return ("mov %B0,%A0" CR_TAB
7643 "clr %A0" CR_TAB
7644 "swap %B0" CR_TAB
7645 "ldi %3,0xf0" CR_TAB
7646 "and %B0,%3");
7648 *len = 6;
7649 return ("mov %B0,%A0" CR_TAB
7650 "clr %A0" CR_TAB
7651 "lsl %B0" CR_TAB
7652 "lsl %B0" CR_TAB
7653 "lsl %B0" CR_TAB
7654 "lsl %B0");
7656 case 13:
7657 if (ldi_ok)
7659 *len = 5;
7660 return ("mov %B0,%A0" CR_TAB
7661 "clr %A0" CR_TAB
7662 "swap %B0" CR_TAB
7663 "lsl %B0" CR_TAB
7664 "andi %B0,0xe0");
7666 if (AVR_HAVE_MUL && scratch)
7668 *len = 5;
7669 return ("ldi %3,0x20" CR_TAB
7670 "mul %A0,%3" CR_TAB
7671 "mov %B0,r0" CR_TAB
7672 "clr %A0" CR_TAB
7673 "clr __zero_reg__");
7675 if (optimize_size && scratch)
7676 break; /* 5 */
7677 if (scratch)
7679 *len = 6;
7680 return ("mov %B0,%A0" CR_TAB
7681 "clr %A0" CR_TAB
7682 "swap %B0" CR_TAB
7683 "lsl %B0" CR_TAB
7684 "ldi %3,0xe0" CR_TAB
7685 "and %B0,%3");
7687 if (AVR_HAVE_MUL)
7689 *len = 6;
7690 return ("set" CR_TAB
7691 "bld r1,5" CR_TAB
7692 "mul %A0,r1" CR_TAB
7693 "mov %B0,r0" CR_TAB
7694 "clr %A0" CR_TAB
7695 "clr __zero_reg__");
7697 *len = 7;
7698 return ("mov %B0,%A0" CR_TAB
7699 "clr %A0" CR_TAB
7700 "lsl %B0" CR_TAB
7701 "lsl %B0" CR_TAB
7702 "lsl %B0" CR_TAB
7703 "lsl %B0" CR_TAB
7704 "lsl %B0");
7706 case 14:
7707 if (AVR_HAVE_MUL && ldi_ok)
7709 *len = 5;
7710 return ("ldi %B0,0x40" CR_TAB
7711 "mul %A0,%B0" CR_TAB
7712 "mov %B0,r0" CR_TAB
7713 "clr %A0" CR_TAB
7714 "clr __zero_reg__");
7716 if (AVR_HAVE_MUL && scratch)
7718 *len = 5;
7719 return ("ldi %3,0x40" CR_TAB
7720 "mul %A0,%3" CR_TAB
7721 "mov %B0,r0" CR_TAB
7722 "clr %A0" CR_TAB
7723 "clr __zero_reg__");
7725 if (optimize_size && ldi_ok)
7727 *len = 5;
7728 return ("mov %B0,%A0" CR_TAB
7729 "ldi %A0,6" "\n1:\t"
7730 "lsl %B0" CR_TAB
7731 "dec %A0" CR_TAB
7732 "brne 1b");
7734 if (optimize_size && scratch)
7735 break; /* 5 */
7736 *len = 6;
7737 return ("clr %B0" CR_TAB
7738 "lsr %A0" CR_TAB
7739 "ror %B0" CR_TAB
7740 "lsr %A0" CR_TAB
7741 "ror %B0" CR_TAB
7742 "clr %A0");
7744 case 15:
7745 *len = 4;
7746 return ("clr %B0" CR_TAB
7747 "lsr %A0" CR_TAB
7748 "ror %B0" CR_TAB
7749 "clr %A0");
7751 len = t;
7753 out_shift_with_cnt ("lsl %A0" CR_TAB
7754 "rol %B0", insn, operands, len, 2);
7755 return "";
7759 /* 24-bit shift left */
7761 const char *
7762 avr_out_ashlpsi3 (rtx_insn *insn, rtx *op, int *plen)
7764 if (plen)
7765 *plen = 0;
7767 if (CONST_INT_P (op[2]))
7769 switch (INTVAL (op[2]))
7771 default:
7772 if (INTVAL (op[2]) < 24)
7773 break;
7775 return avr_asm_len ("clr %A0" CR_TAB
7776 "clr %B0" CR_TAB
7777 "clr %C0", op, plen, 3);
7779 case 8:
7781 int reg0 = REGNO (op[0]);
7782 int reg1 = REGNO (op[1]);
7784 if (reg0 >= reg1)
7785 return avr_asm_len ("mov %C0,%B1" CR_TAB
7786 "mov %B0,%A1" CR_TAB
7787 "clr %A0", op, plen, 3);
7788 else
7789 return avr_asm_len ("clr %A0" CR_TAB
7790 "mov %B0,%A1" CR_TAB
7791 "mov %C0,%B1", op, plen, 3);
7794 case 16:
7796 int reg0 = REGNO (op[0]);
7797 int reg1 = REGNO (op[1]);
7799 if (reg0 + 2 != reg1)
7800 avr_asm_len ("mov %C0,%A0", op, plen, 1);
7802 return avr_asm_len ("clr %B0" CR_TAB
7803 "clr %A0", op, plen, 2);
7806 case 23:
7807 return avr_asm_len ("clr %C0" CR_TAB
7808 "lsr %A0" CR_TAB
7809 "ror %C0" CR_TAB
7810 "clr %B0" CR_TAB
7811 "clr %A0", op, plen, 5);
7815 out_shift_with_cnt ("lsl %A0" CR_TAB
7816 "rol %B0" CR_TAB
7817 "rol %C0", insn, op, plen, 3);
7818 return "";
7822 /* 32bit shift left ((long)x << i) */
7824 const char *
7825 ashlsi3_out (rtx_insn *insn, rtx operands[], int *len)
7827 if (CONST_INT_P (operands[2]))
7829 int k;
7830 int *t = len;
7832 if (!len)
7833 len = &k;
7835 switch (INTVAL (operands[2]))
7837 default:
7838 if (INTVAL (operands[2]) < 32)
7839 break;
7841 if (AVR_HAVE_MOVW)
7842 return *len = 3, ("clr %D0" CR_TAB
7843 "clr %C0" CR_TAB
7844 "movw %A0,%C0");
7845 *len = 4;
7846 return ("clr %D0" CR_TAB
7847 "clr %C0" CR_TAB
7848 "clr %B0" CR_TAB
7849 "clr %A0");
7851 case 8:
7853 int reg0 = true_regnum (operands[0]);
7854 int reg1 = true_regnum (operands[1]);
7855 *len = 4;
7856 if (reg0 >= reg1)
7857 return ("mov %D0,%C1" CR_TAB
7858 "mov %C0,%B1" CR_TAB
7859 "mov %B0,%A1" CR_TAB
7860 "clr %A0");
7861 else
7862 return ("clr %A0" CR_TAB
7863 "mov %B0,%A1" CR_TAB
7864 "mov %C0,%B1" CR_TAB
7865 "mov %D0,%C1");
7868 case 16:
7870 int reg0 = true_regnum (operands[0]);
7871 int reg1 = true_regnum (operands[1]);
7872 if (reg0 + 2 == reg1)
7873 return *len = 2, ("clr %B0" CR_TAB
7874 "clr %A0");
7875 if (AVR_HAVE_MOVW)
7876 return *len = 3, ("movw %C0,%A1" CR_TAB
7877 "clr %B0" CR_TAB
7878 "clr %A0");
7879 else
7880 return *len = 4, ("mov %C0,%A1" CR_TAB
7881 "mov %D0,%B1" CR_TAB
7882 "clr %B0" CR_TAB
7883 "clr %A0");
7886 case 24:
7887 *len = 4;
7888 return ("mov %D0,%A1" CR_TAB
7889 "clr %C0" CR_TAB
7890 "clr %B0" CR_TAB
7891 "clr %A0");
7893 case 31:
7894 *len = 6;
7895 return ("clr %D0" CR_TAB
7896 "lsr %A0" CR_TAB
7897 "ror %D0" CR_TAB
7898 "clr %C0" CR_TAB
7899 "clr %B0" CR_TAB
7900 "clr %A0");
7902 len = t;
7904 out_shift_with_cnt ("lsl %A0" CR_TAB
7905 "rol %B0" CR_TAB
7906 "rol %C0" CR_TAB
7907 "rol %D0", insn, operands, len, 4);
7908 return "";
7911 /* 8bit arithmetic shift right ((signed char)x >> i) */
7913 const char *
7914 ashrqi3_out (rtx_insn *insn, rtx operands[], int *len)
7916 if (CONST_INT_P (operands[2]))
7918 int k;
7920 if (!len)
7921 len = &k;
7923 switch (INTVAL (operands[2]))
7925 case 1:
7926 *len = 1;
7927 return "asr %0";
7929 case 2:
7930 *len = 2;
7931 return ("asr %0" CR_TAB
7932 "asr %0");
7934 case 3:
7935 *len = 3;
7936 return ("asr %0" CR_TAB
7937 "asr %0" CR_TAB
7938 "asr %0");
7940 case 4:
7941 *len = 4;
7942 return ("asr %0" CR_TAB
7943 "asr %0" CR_TAB
7944 "asr %0" CR_TAB
7945 "asr %0");
7947 case 5:
7948 *len = 5;
7949 return ("asr %0" CR_TAB
7950 "asr %0" CR_TAB
7951 "asr %0" CR_TAB
7952 "asr %0" CR_TAB
7953 "asr %0");
7955 case 6:
7956 *len = 4;
7957 return ("bst %0,6" CR_TAB
7958 "lsl %0" CR_TAB
7959 "sbc %0,%0" CR_TAB
7960 "bld %0,0");
7962 default:
7963 if (INTVAL (operands[2]) < 8)
7964 break;
7966 /* fall through */
7968 case 7:
7969 *len = 2;
7970 return ("lsl %0" CR_TAB
7971 "sbc %0,%0");
7974 else if (CONSTANT_P (operands[2]))
7975 fatal_insn ("internal compiler error. Incorrect shift:", insn);
7977 out_shift_with_cnt ("asr %0",
7978 insn, operands, len, 1);
7979 return "";
7983 /* 16bit arithmetic shift right ((signed short)x >> i) */
7985 const char *
7986 ashrhi3_out (rtx_insn *insn, rtx operands[], int *len)
7988 if (CONST_INT_P (operands[2]))
7990 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
7991 && XVECLEN (PATTERN (insn), 0) == 3
7992 && REG_P (operands[3]));
7993 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
7994 int k;
7995 int *t = len;
7997 if (!len)
7998 len = &k;
8000 switch (INTVAL (operands[2]))
8002 case 4:
8003 case 5:
8004 /* XXX try to optimize this too? */
8005 break;
8007 case 6:
8008 if (optimize_size)
8009 break; /* scratch ? 5 : 6 */
8010 *len = 8;
8011 return ("mov __tmp_reg__,%A0" CR_TAB
8012 "mov %A0,%B0" CR_TAB
8013 "lsl __tmp_reg__" CR_TAB
8014 "rol %A0" CR_TAB
8015 "sbc %B0,%B0" CR_TAB
8016 "lsl __tmp_reg__" CR_TAB
8017 "rol %A0" CR_TAB
8018 "rol %B0");
8020 case 7:
8021 *len = 4;
8022 return ("lsl %A0" CR_TAB
8023 "mov %A0,%B0" CR_TAB
8024 "rol %A0" CR_TAB
8025 "sbc %B0,%B0");
8027 case 8:
8029 int reg0 = true_regnum (operands[0]);
8030 int reg1 = true_regnum (operands[1]);
8032 if (reg0 == reg1)
8033 return *len = 3, ("mov %A0,%B0" CR_TAB
8034 "lsl %B0" CR_TAB
8035 "sbc %B0,%B0");
8036 else
8037 return *len = 4, ("mov %A0,%B1" CR_TAB
8038 "clr %B0" CR_TAB
8039 "sbrc %A0,7" CR_TAB
8040 "dec %B0");
8043 case 9:
8044 *len = 4;
8045 return ("mov %A0,%B0" CR_TAB
8046 "lsl %B0" CR_TAB
8047 "sbc %B0,%B0" CR_TAB
8048 "asr %A0");
8050 case 10:
8051 *len = 5;
8052 return ("mov %A0,%B0" CR_TAB
8053 "lsl %B0" CR_TAB
8054 "sbc %B0,%B0" CR_TAB
8055 "asr %A0" CR_TAB
8056 "asr %A0");
8058 case 11:
8059 if (AVR_HAVE_MUL && ldi_ok)
8061 *len = 5;
8062 return ("ldi %A0,0x20" CR_TAB
8063 "muls %B0,%A0" CR_TAB
8064 "mov %A0,r1" CR_TAB
8065 "sbc %B0,%B0" CR_TAB
8066 "clr __zero_reg__");
8068 if (optimize_size && scratch)
8069 break; /* 5 */
8070 *len = 6;
8071 return ("mov %A0,%B0" CR_TAB
8072 "lsl %B0" CR_TAB
8073 "sbc %B0,%B0" CR_TAB
8074 "asr %A0" CR_TAB
8075 "asr %A0" CR_TAB
8076 "asr %A0");
8078 case 12:
8079 if (AVR_HAVE_MUL && ldi_ok)
8081 *len = 5;
8082 return ("ldi %A0,0x10" CR_TAB
8083 "muls %B0,%A0" CR_TAB
8084 "mov %A0,r1" CR_TAB
8085 "sbc %B0,%B0" CR_TAB
8086 "clr __zero_reg__");
8088 if (optimize_size && scratch)
8089 break; /* 5 */
8090 *len = 7;
8091 return ("mov %A0,%B0" CR_TAB
8092 "lsl %B0" CR_TAB
8093 "sbc %B0,%B0" CR_TAB
8094 "asr %A0" CR_TAB
8095 "asr %A0" CR_TAB
8096 "asr %A0" CR_TAB
8097 "asr %A0");
8099 case 13:
8100 if (AVR_HAVE_MUL && ldi_ok)
8102 *len = 5;
8103 return ("ldi %A0,0x08" CR_TAB
8104 "muls %B0,%A0" CR_TAB
8105 "mov %A0,r1" CR_TAB
8106 "sbc %B0,%B0" CR_TAB
8107 "clr __zero_reg__");
8109 if (optimize_size)
8110 break; /* scratch ? 5 : 7 */
8111 *len = 8;
8112 return ("mov %A0,%B0" CR_TAB
8113 "lsl %B0" CR_TAB
8114 "sbc %B0,%B0" CR_TAB
8115 "asr %A0" CR_TAB
8116 "asr %A0" CR_TAB
8117 "asr %A0" CR_TAB
8118 "asr %A0" CR_TAB
8119 "asr %A0");
8121 case 14:
8122 *len = 5;
8123 return ("lsl %B0" CR_TAB
8124 "sbc %A0,%A0" CR_TAB
8125 "lsl %B0" CR_TAB
8126 "mov %B0,%A0" CR_TAB
8127 "rol %A0");
8129 default:
8130 if (INTVAL (operands[2]) < 16)
8131 break;
8133 /* fall through */
8135 case 15:
8136 return *len = 3, ("lsl %B0" CR_TAB
8137 "sbc %A0,%A0" CR_TAB
8138 "mov %B0,%A0");
8140 len = t;
8142 out_shift_with_cnt ("asr %B0" CR_TAB
8143 "ror %A0", insn, operands, len, 2);
8144 return "";
8148 /* 24-bit arithmetic shift right */
8150 const char *
8151 avr_out_ashrpsi3 (rtx_insn *insn, rtx *op, int *plen)
8153 int dest = REGNO (op[0]);
8154 int src = REGNO (op[1]);
8156 if (CONST_INT_P (op[2]))
8158 if (plen)
8159 *plen = 0;
8161 switch (INTVAL (op[2]))
8163 case 8:
8164 if (dest <= src)
8165 return avr_asm_len ("mov %A0,%B1" CR_TAB
8166 "mov %B0,%C1" CR_TAB
8167 "clr %C0" CR_TAB
8168 "sbrc %B0,7" CR_TAB
8169 "dec %C0", op, plen, 5);
8170 else
8171 return avr_asm_len ("clr %C0" CR_TAB
8172 "sbrc %C1,7" CR_TAB
8173 "dec %C0" CR_TAB
8174 "mov %B0,%C1" CR_TAB
8175 "mov %A0,%B1", op, plen, 5);
8177 case 16:
8178 if (dest != src + 2)
8179 avr_asm_len ("mov %A0,%C1", op, plen, 1);
8181 return avr_asm_len ("clr %B0" CR_TAB
8182 "sbrc %A0,7" CR_TAB
8183 "com %B0" CR_TAB
8184 "mov %C0,%B0", op, plen, 4);
8186 default:
8187 if (INTVAL (op[2]) < 24)
8188 break;
8190 /* fall through */
8192 case 23:
8193 return avr_asm_len ("lsl %C0" CR_TAB
8194 "sbc %A0,%A0" CR_TAB
8195 "mov %B0,%A0" CR_TAB
8196 "mov %C0,%A0", op, plen, 4);
8197 } /* switch */
8200 out_shift_with_cnt ("asr %C0" CR_TAB
8201 "ror %B0" CR_TAB
8202 "ror %A0", insn, op, plen, 3);
8203 return "";
8207 /* 32-bit arithmetic shift right ((signed long)x >> i) */
8209 const char *
8210 ashrsi3_out (rtx_insn *insn, rtx operands[], int *len)
8212 if (CONST_INT_P (operands[2]))
8214 int k;
8215 int *t = len;
8217 if (!len)
8218 len = &k;
8220 switch (INTVAL (operands[2]))
8222 case 8:
8224 int reg0 = true_regnum (operands[0]);
8225 int reg1 = true_regnum (operands[1]);
8226 *len=6;
8227 if (reg0 <= reg1)
8228 return ("mov %A0,%B1" CR_TAB
8229 "mov %B0,%C1" CR_TAB
8230 "mov %C0,%D1" CR_TAB
8231 "clr %D0" CR_TAB
8232 "sbrc %C0,7" CR_TAB
8233 "dec %D0");
8234 else
8235 return ("clr %D0" CR_TAB
8236 "sbrc %D1,7" CR_TAB
8237 "dec %D0" CR_TAB
8238 "mov %C0,%D1" CR_TAB
8239 "mov %B0,%C1" CR_TAB
8240 "mov %A0,%B1");
8243 case 16:
8245 int reg0 = true_regnum (operands[0]);
8246 int reg1 = true_regnum (operands[1]);
8248 if (reg0 == reg1 + 2)
8249 return *len = 4, ("clr %D0" CR_TAB
8250 "sbrc %B0,7" CR_TAB
8251 "com %D0" CR_TAB
8252 "mov %C0,%D0");
8253 if (AVR_HAVE_MOVW)
8254 return *len = 5, ("movw %A0,%C1" CR_TAB
8255 "clr %D0" CR_TAB
8256 "sbrc %B0,7" CR_TAB
8257 "com %D0" CR_TAB
8258 "mov %C0,%D0");
8259 else
8260 return *len = 6, ("mov %B0,%D1" CR_TAB
8261 "mov %A0,%C1" CR_TAB
8262 "clr %D0" CR_TAB
8263 "sbrc %B0,7" CR_TAB
8264 "com %D0" CR_TAB
8265 "mov %C0,%D0");
8268 case 24:
8269 return *len = 6, ("mov %A0,%D1" CR_TAB
8270 "clr %D0" CR_TAB
8271 "sbrc %A0,7" CR_TAB
8272 "com %D0" CR_TAB
8273 "mov %B0,%D0" CR_TAB
8274 "mov %C0,%D0");
8276 default:
8277 if (INTVAL (operands[2]) < 32)
8278 break;
8280 /* fall through */
8282 case 31:
8283 if (AVR_HAVE_MOVW)
8284 return *len = 4, ("lsl %D0" CR_TAB
8285 "sbc %A0,%A0" CR_TAB
8286 "mov %B0,%A0" CR_TAB
8287 "movw %C0,%A0");
8288 else
8289 return *len = 5, ("lsl %D0" CR_TAB
8290 "sbc %A0,%A0" CR_TAB
8291 "mov %B0,%A0" CR_TAB
8292 "mov %C0,%A0" CR_TAB
8293 "mov %D0,%A0");
8295 len = t;
8297 out_shift_with_cnt ("asr %D0" CR_TAB
8298 "ror %C0" CR_TAB
8299 "ror %B0" CR_TAB
8300 "ror %A0", insn, operands, len, 4);
8301 return "";
8304 /* 8-bit logic shift right ((unsigned char)x >> i) */
8306 const char *
8307 lshrqi3_out (rtx_insn *insn, rtx operands[], int *len)
8309 if (CONST_INT_P (operands[2]))
8311 int k;
8313 if (!len)
8314 len = &k;
8316 switch (INTVAL (operands[2]))
8318 default:
8319 if (INTVAL (operands[2]) < 8)
8320 break;
8322 *len = 1;
8323 return "clr %0";
8325 case 1:
8326 *len = 1;
8327 return "lsr %0";
8329 case 2:
8330 *len = 2;
8331 return ("lsr %0" CR_TAB
8332 "lsr %0");
8333 case 3:
8334 *len = 3;
8335 return ("lsr %0" CR_TAB
8336 "lsr %0" CR_TAB
8337 "lsr %0");
8339 case 4:
8340 if (test_hard_reg_class (LD_REGS, operands[0]))
8342 *len=2;
8343 return ("swap %0" CR_TAB
8344 "andi %0,0x0f");
8346 *len = 4;
8347 return ("lsr %0" CR_TAB
8348 "lsr %0" CR_TAB
8349 "lsr %0" CR_TAB
8350 "lsr %0");
8352 case 5:
8353 if (test_hard_reg_class (LD_REGS, operands[0]))
8355 *len = 3;
8356 return ("swap %0" CR_TAB
8357 "lsr %0" CR_TAB
8358 "andi %0,0x7");
8360 *len = 5;
8361 return ("lsr %0" CR_TAB
8362 "lsr %0" CR_TAB
8363 "lsr %0" CR_TAB
8364 "lsr %0" CR_TAB
8365 "lsr %0");
8367 case 6:
8368 if (test_hard_reg_class (LD_REGS, operands[0]))
8370 *len = 4;
8371 return ("swap %0" CR_TAB
8372 "lsr %0" CR_TAB
8373 "lsr %0" CR_TAB
8374 "andi %0,0x3");
8376 *len = 6;
8377 return ("lsr %0" CR_TAB
8378 "lsr %0" CR_TAB
8379 "lsr %0" CR_TAB
8380 "lsr %0" CR_TAB
8381 "lsr %0" CR_TAB
8382 "lsr %0");
8384 case 7:
8385 *len = 3;
8386 return ("bst %1,7" CR_TAB
8387 "clr %0" CR_TAB
8388 "bld %0,0");
8391 else if (CONSTANT_P (operands[2]))
8392 fatal_insn ("internal compiler error. Incorrect shift:", insn);
8394 out_shift_with_cnt ("lsr %0",
8395 insn, operands, len, 1);
8396 return "";
8399 /* 16-bit logic shift right ((unsigned short)x >> i) */
8401 const char *
8402 lshrhi3_out (rtx_insn *insn, rtx operands[], int *len)
8404 if (CONST_INT_P (operands[2]))
8406 int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL
8407 && XVECLEN (PATTERN (insn), 0) == 3
8408 && REG_P (operands[3]));
8409 int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
8410 int k;
8411 int *t = len;
8413 if (!len)
8414 len = &k;
8416 switch (INTVAL (operands[2]))
8418 default:
8419 if (INTVAL (operands[2]) < 16)
8420 break;
8422 *len = 2;
8423 return ("clr %B0" CR_TAB
8424 "clr %A0");
8426 case 4:
8427 if (optimize_size && scratch)
8428 break; /* 5 */
8429 if (ldi_ok)
8431 *len = 6;
8432 return ("swap %B0" CR_TAB
8433 "swap %A0" CR_TAB
8434 "andi %A0,0x0f" CR_TAB
8435 "eor %A0,%B0" CR_TAB
8436 "andi %B0,0x0f" CR_TAB
8437 "eor %A0,%B0");
8439 if (scratch)
8441 *len = 7;
8442 return ("swap %B0" CR_TAB
8443 "swap %A0" CR_TAB
8444 "ldi %3,0x0f" CR_TAB
8445 "and %A0,%3" CR_TAB
8446 "eor %A0,%B0" CR_TAB
8447 "and %B0,%3" CR_TAB
8448 "eor %A0,%B0");
8450 break; /* optimize_size ? 6 : 8 */
8452 case 5:
8453 if (optimize_size)
8454 break; /* scratch ? 5 : 6 */
8455 if (ldi_ok)
8457 *len = 8;
8458 return ("lsr %B0" CR_TAB
8459 "ror %A0" CR_TAB
8460 "swap %B0" CR_TAB
8461 "swap %A0" CR_TAB
8462 "andi %A0,0x0f" CR_TAB
8463 "eor %A0,%B0" CR_TAB
8464 "andi %B0,0x0f" CR_TAB
8465 "eor %A0,%B0");
8467 if (scratch)
8469 *len = 9;
8470 return ("lsr %B0" CR_TAB
8471 "ror %A0" CR_TAB
8472 "swap %B0" CR_TAB
8473 "swap %A0" CR_TAB
8474 "ldi %3,0x0f" CR_TAB
8475 "and %A0,%3" CR_TAB
8476 "eor %A0,%B0" CR_TAB
8477 "and %B0,%3" CR_TAB
8478 "eor %A0,%B0");
8480 break; /* 10 */
8482 case 6:
8483 if (optimize_size)
8484 break; /* scratch ? 5 : 6 */
8485 *len = 9;
8486 return ("clr __tmp_reg__" CR_TAB
8487 "lsl %A0" CR_TAB
8488 "rol %B0" CR_TAB
8489 "rol __tmp_reg__" CR_TAB
8490 "lsl %A0" CR_TAB
8491 "rol %B0" CR_TAB
8492 "rol __tmp_reg__" CR_TAB
8493 "mov %A0,%B0" CR_TAB
8494 "mov %B0,__tmp_reg__");
8496 case 7:
8497 *len = 5;
8498 return ("lsl %A0" CR_TAB
8499 "mov %A0,%B0" CR_TAB
8500 "rol %A0" CR_TAB
8501 "sbc %B0,%B0" CR_TAB
8502 "neg %B0");
8504 case 8:
8505 return *len = 2, ("mov %A0,%B1" CR_TAB
8506 "clr %B0");
8508 case 9:
8509 *len = 3;
8510 return ("mov %A0,%B0" CR_TAB
8511 "clr %B0" CR_TAB
8512 "lsr %A0");
8514 case 10:
8515 *len = 4;
8516 return ("mov %A0,%B0" CR_TAB
8517 "clr %B0" CR_TAB
8518 "lsr %A0" CR_TAB
8519 "lsr %A0");
8521 case 11:
8522 *len = 5;
8523 return ("mov %A0,%B0" CR_TAB
8524 "clr %B0" CR_TAB
8525 "lsr %A0" CR_TAB
8526 "lsr %A0" CR_TAB
8527 "lsr %A0");
8529 case 12:
8530 if (ldi_ok)
8532 *len = 4;
8533 return ("mov %A0,%B0" CR_TAB
8534 "clr %B0" CR_TAB
8535 "swap %A0" CR_TAB
8536 "andi %A0,0x0f");
8538 if (scratch)
8540 *len = 5;
8541 return ("mov %A0,%B0" CR_TAB
8542 "clr %B0" CR_TAB
8543 "swap %A0" CR_TAB
8544 "ldi %3,0x0f" CR_TAB
8545 "and %A0,%3");
8547 *len = 6;
8548 return ("mov %A0,%B0" CR_TAB
8549 "clr %B0" CR_TAB
8550 "lsr %A0" CR_TAB
8551 "lsr %A0" CR_TAB
8552 "lsr %A0" CR_TAB
8553 "lsr %A0");
8555 case 13:
8556 if (ldi_ok)
8558 *len = 5;
8559 return ("mov %A0,%B0" CR_TAB
8560 "clr %B0" CR_TAB
8561 "swap %A0" CR_TAB
8562 "lsr %A0" CR_TAB
8563 "andi %A0,0x07");
8565 if (AVR_HAVE_MUL && scratch)
8567 *len = 5;
8568 return ("ldi %3,0x08" CR_TAB
8569 "mul %B0,%3" CR_TAB
8570 "mov %A0,r1" CR_TAB
8571 "clr %B0" CR_TAB
8572 "clr __zero_reg__");
8574 if (optimize_size && scratch)
8575 break; /* 5 */
8576 if (scratch)
8578 *len = 6;
8579 return ("mov %A0,%B0" CR_TAB
8580 "clr %B0" CR_TAB
8581 "swap %A0" CR_TAB
8582 "lsr %A0" CR_TAB
8583 "ldi %3,0x07" CR_TAB
8584 "and %A0,%3");
8586 if (AVR_HAVE_MUL)
8588 *len = 6;
8589 return ("set" CR_TAB
8590 "bld r1,3" CR_TAB
8591 "mul %B0,r1" CR_TAB
8592 "mov %A0,r1" CR_TAB
8593 "clr %B0" CR_TAB
8594 "clr __zero_reg__");
8596 *len = 7;
8597 return ("mov %A0,%B0" CR_TAB
8598 "clr %B0" CR_TAB
8599 "lsr %A0" CR_TAB
8600 "lsr %A0" CR_TAB
8601 "lsr %A0" CR_TAB
8602 "lsr %A0" CR_TAB
8603 "lsr %A0");
8605 case 14:
8606 if (AVR_HAVE_MUL && ldi_ok)
8608 *len = 5;
8609 return ("ldi %A0,0x04" CR_TAB
8610 "mul %B0,%A0" CR_TAB
8611 "mov %A0,r1" CR_TAB
8612 "clr %B0" CR_TAB
8613 "clr __zero_reg__");
8615 if (AVR_HAVE_MUL && scratch)
8617 *len = 5;
8618 return ("ldi %3,0x04" CR_TAB
8619 "mul %B0,%3" CR_TAB
8620 "mov %A0,r1" CR_TAB
8621 "clr %B0" CR_TAB
8622 "clr __zero_reg__");
8624 if (optimize_size && ldi_ok)
8626 *len = 5;
8627 return ("mov %A0,%B0" CR_TAB
8628 "ldi %B0,6" "\n1:\t"
8629 "lsr %A0" CR_TAB
8630 "dec %B0" CR_TAB
8631 "brne 1b");
8633 if (optimize_size && scratch)
8634 break; /* 5 */
8635 *len = 6;
8636 return ("clr %A0" CR_TAB
8637 "lsl %B0" CR_TAB
8638 "rol %A0" CR_TAB
8639 "lsl %B0" CR_TAB
8640 "rol %A0" CR_TAB
8641 "clr %B0");
8643 case 15:
8644 *len = 4;
8645 return ("bst %B1,7" CR_TAB
8646 "clr %A0" CR_TAB
8647 "clr %B0" CR_TAB
8648 "bld %A0,0");
8650 len = t;
8652 out_shift_with_cnt ("lsr %B0" CR_TAB
8653 "ror %A0", insn, operands, len, 2);
8654 return "";
8658 /* 24-bit logic shift right */
8660 const char *
8661 avr_out_lshrpsi3 (rtx_insn *insn, rtx *op, int *plen)
8663 int dest = REGNO (op[0]);
8664 int src = REGNO (op[1]);
8666 if (CONST_INT_P (op[2]))
8668 if (plen)
8669 *plen = 0;
8671 switch (INTVAL (op[2]))
8673 case 8:
8674 if (dest <= src)
8675 return avr_asm_len ("mov %A0,%B1" CR_TAB
8676 "mov %B0,%C1" CR_TAB
8677 "clr %C0", op, plen, 3);
8678 else
8679 return avr_asm_len ("clr %C0" CR_TAB
8680 "mov %B0,%C1" CR_TAB
8681 "mov %A0,%B1", op, plen, 3);
8683 case 16:
8684 if (dest != src + 2)
8685 avr_asm_len ("mov %A0,%C1", op, plen, 1);
8687 return avr_asm_len ("clr %B0" CR_TAB
8688 "clr %C0", op, plen, 2);
8690 default:
8691 if (INTVAL (op[2]) < 24)
8692 break;
8694 /* fall through */
8696 case 23:
8697 return avr_asm_len ("bst %C1,7" CR_TAB
8698 "clr %A0" CR_TAB
8699 "clr %B0" CR_TAB
8700 "clr %C0" CR_TAB
8701 "bld %A0,0", op, plen, 5);
8702 } /* switch */
8705 out_shift_with_cnt ("lsr %C0" CR_TAB
8706 "ror %B0" CR_TAB
8707 "ror %A0", insn, op, plen, 3);
8708 return "";
8712 /* 32-bit logic shift right ((unsigned int)x >> i) */
8714 const char *
8715 lshrsi3_out (rtx_insn *insn, rtx operands[], int *len)
8717 if (CONST_INT_P (operands[2]))
8719 int k;
8720 int *t = len;
8722 if (!len)
8723 len = &k;
8725 switch (INTVAL (operands[2]))
8727 default:
8728 if (INTVAL (operands[2]) < 32)
8729 break;
8731 if (AVR_HAVE_MOVW)
8732 return *len = 3, ("clr %D0" CR_TAB
8733 "clr %C0" CR_TAB
8734 "movw %A0,%C0");
8735 *len = 4;
8736 return ("clr %D0" CR_TAB
8737 "clr %C0" CR_TAB
8738 "clr %B0" CR_TAB
8739 "clr %A0");
8741 case 8:
8743 int reg0 = true_regnum (operands[0]);
8744 int reg1 = true_regnum (operands[1]);
8745 *len = 4;
8746 if (reg0 <= reg1)
8747 return ("mov %A0,%B1" CR_TAB
8748 "mov %B0,%C1" CR_TAB
8749 "mov %C0,%D1" CR_TAB
8750 "clr %D0");
8751 else
8752 return ("clr %D0" CR_TAB
8753 "mov %C0,%D1" CR_TAB
8754 "mov %B0,%C1" CR_TAB
8755 "mov %A0,%B1");
8758 case 16:
8760 int reg0 = true_regnum (operands[0]);
8761 int reg1 = true_regnum (operands[1]);
8763 if (reg0 == reg1 + 2)
8764 return *len = 2, ("clr %C0" CR_TAB
8765 "clr %D0");
8766 if (AVR_HAVE_MOVW)
8767 return *len = 3, ("movw %A0,%C1" CR_TAB
8768 "clr %C0" CR_TAB
8769 "clr %D0");
8770 else
8771 return *len = 4, ("mov %B0,%D1" CR_TAB
8772 "mov %A0,%C1" CR_TAB
8773 "clr %C0" CR_TAB
8774 "clr %D0");
8777 case 24:
8778 return *len = 4, ("mov %A0,%D1" CR_TAB
8779 "clr %B0" CR_TAB
8780 "clr %C0" CR_TAB
8781 "clr %D0");
8783 case 31:
8784 if (AVR_HAVE_MOVW)
8785 return *len = 5, ("bst %D1,7" CR_TAB
8786 "clr %A0" CR_TAB
8787 "clr %B0" CR_TAB
8788 "movw %C0,%A0" CR_TAB
8789 "bld %A0,0");
8790 *len = 6;
8791 return ("bst %D1,7" CR_TAB
8792 "clr %A0" CR_TAB
8793 "clr %B0" CR_TAB
8794 "clr %C0" CR_TAB
8795 "clr %D0" CR_TAB
8796 "bld %A0,0");
8798 len = t;
8800 out_shift_with_cnt ("lsr %D0" CR_TAB
8801 "ror %C0" CR_TAB
8802 "ror %B0" CR_TAB
8803 "ror %A0", insn, operands, len, 4);
8804 return "";
8808 /* Output addition of register XOP[0] and compile time constant XOP[2].
8809 INSN is a single_set insn or an insn pattern.
8810 CODE == PLUS: perform addition by using ADD instructions or
8811 CODE == MINUS: perform addition by using SUB instructions:
8813 XOP[0] = XOP[0] + XOP[2]
8815 Or perform addition/subtraction with register XOP[2] depending on CODE:
8817 XOP[0] = XOP[0] +/- XOP[2]
8819 If PLEN == NULL, print assembler instructions to perform the operation;
8820 otherwise, set *PLEN to the length of the instruction sequence (in words)
8821 printed with PLEN == NULL. XOP[3] is an 8-bit scratch register or NULL_RTX.
8823 CODE_SAT == UNKNOWN: Perform ordinary, non-saturating operation.
8824 CODE_SAT != UNKNOWN: Perform operation and saturate according to CODE_SAT.
8825 If CODE_SAT != UNKNOWN then SIGN contains the sign of the summand resp.
8826 the subtrahend in the original insn, provided it is a compile time constant.
8827 In all other cases, SIGN is 0.
8829 If OUT_LABEL is true, print the final 0: label which is needed for
8830 saturated addition / subtraction. The only case where OUT_LABEL = false
8831 is useful is for saturated addition / subtraction performed during
8832 fixed-point rounding, cf. `avr_out_round'. */
8834 static void
8835 avr_out_plus_1 (rtx insn, rtx *xop, int *plen, enum rtx_code code,
8836 enum rtx_code code_sat, int sign, bool out_label)
8838 /* MODE of the operation. */
8839 machine_mode mode = GET_MODE (xop[0]);
8841 /* INT_MODE of the same size. */
8842 scalar_int_mode imode = int_mode_for_mode (mode).require ();
8844 /* Number of bytes to operate on. */
8845 int n_bytes = GET_MODE_SIZE (mode);
8847 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
8848 int clobber_val = -1;
8850 /* op[0]: 8-bit destination register
8851 op[1]: 8-bit const int
8852 op[2]: 8-bit scratch register */
8853 rtx op[3];
8855 /* Started the operation? Before starting the operation we may skip
8856 adding 0. This is no more true after the operation started because
8857 carry must be taken into account. */
8858 bool started = false;
8860 /* Value to add. There are two ways to add VAL: R += VAL and R -= -VAL. */
8861 rtx xval = xop[2];
8863 /* Output a BRVC instruction. Only needed with saturation. */
8864 bool out_brvc = true;
8866 if (plen)
8867 *plen = 0;
8869 if (REG_P (xop[2]))
8871 for (int i = 0; i < n_bytes; i++)
8873 /* We operate byte-wise on the destination. */
8874 op[0] = simplify_gen_subreg (QImode, xop[0], mode, i);
8875 op[1] = simplify_gen_subreg (QImode, xop[2], mode, i);
8877 if (i == 0)
8878 avr_asm_len (code == PLUS ? "add %0,%1" : "sub %0,%1",
8879 op, plen, 1);
8880 else
8881 avr_asm_len (code == PLUS ? "adc %0,%1" : "sbc %0,%1",
8882 op, plen, 1);
8885 if (reg_overlap_mentioned_p (xop[0], xop[2]))
8887 gcc_assert (REGNO (xop[0]) == REGNO (xop[2]));
8889 if (MINUS == code)
8890 return;
8893 goto saturate;
8896 if (CONST_FIXED_P (xval))
8897 xval = avr_to_int_mode (xval);
8899 /* Adding/Subtracting zero is a no-op. */
8901 if (xval == const0_rtx)
8902 return;
8904 if (MINUS == code)
8905 xval = simplify_unary_operation (NEG, imode, xval, imode);
8907 op[2] = xop[3];
8909 if (SS_PLUS == code_sat && MINUS == code
8910 && sign < 0
8911 && 0x80 == (INTVAL (simplify_gen_subreg (QImode, xval, imode, n_bytes-1))
8912 & GET_MODE_MASK (QImode)))
8914 /* We compute x + 0x80 by means of SUB instructions. We negated the
8915 constant subtrahend above and are left with x - (-128) so that we
8916 need something like SUBI r,128 which does not exist because SUBI sets
8917 V according to the sign of the subtrahend. Notice the only case
8918 where this must be done is when NEG overflowed in case [2s] because
8919 the V computation needs the right sign of the subtrahend. */
8921 rtx msb = simplify_gen_subreg (QImode, xop[0], mode, n_bytes - 1);
8923 avr_asm_len ("subi %0,128" CR_TAB
8924 "brmi 0f", &msb, plen, 2);
8925 out_brvc = false;
8927 goto saturate;
8930 for (int i = 0; i < n_bytes; i++)
8932 /* We operate byte-wise on the destination. */
8933 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
8934 rtx xval8 = simplify_gen_subreg (QImode, xval, imode, i);
8936 /* 8-bit value to operate with this byte. */
8937 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
8939 /* Registers R16..R31 can operate with immediate. */
8940 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
8942 op[0] = reg8;
8943 op[1] = gen_int_mode (val8, QImode);
8945 /* To get usable cc0 no low-bytes must have been skipped. */
8947 if (!started
8948 && i % 2 == 0
8949 && i + 2 <= n_bytes
8950 && avr_adiw_reg_p (reg8))
8952 rtx xval16 = simplify_gen_subreg (HImode, xval, imode, i);
8953 unsigned int val16 = UINTVAL (xval16) & GET_MODE_MASK (HImode);
8955 /* Registers R24, X, Y, Z can use ADIW/SBIW with constants < 64
8956 i.e. operate word-wise. */
8958 if (val16 < 64)
8960 if (val16 != 0)
8962 started = true;
8963 avr_asm_len (code == PLUS ? "adiw %0,%1" : "sbiw %0,%1",
8964 op, plen, 1);
8967 i++;
8968 continue;
8972 if (AVR_TINY
8973 && optimize
8974 && i == 0
8975 && n_bytes == 2
8976 // When that pass adjusts the frame pointer, then we know that
8977 // reg Y points to ordinary memory, and the only side-effect
8978 // of -Y and Y+ is the side effect on Y.
8979 && avr_fuse_add >= 2
8980 && frame_pointer_needed
8981 && REGNO (xop[0]) == FRAME_POINTER_REGNUM)
8983 if (INSN_P (insn)
8984 && _reg_unused_after (as_a <rtx_insn *> (insn), xop[0], false))
8985 return;
8987 if (AVR_HAVE_8BIT_SP)
8989 avr_asm_len ("subi %A0,%n2", xop, plen, 1);
8990 return;
8992 else if (xop[2] == const1_rtx || xop[2] == constm1_rtx)
8994 avr_asm_len (xop[2] == const1_rtx
8995 ? "ld __tmp_reg__,%a0+"
8996 : "ld __tmp_reg__,-%a0", xop, plen, 1);
8997 return;
9001 if (val8 == 0)
9003 if (started)
9004 avr_asm_len (code == PLUS
9005 ? "adc %0,__zero_reg__" : "sbc %0,__zero_reg__",
9006 op, plen, 1);
9007 continue;
9009 else if ((val8 == 1 || val8 == 0xff)
9010 && UNKNOWN == code_sat
9011 && !started
9012 && i == n_bytes - 1)
9014 avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
9015 op, plen, 1);
9016 break;
9019 switch (code)
9021 case PLUS:
9023 gcc_assert (plen != NULL || (op[2] && REG_P (op[2])));
9025 if (plen != NULL && UNKNOWN != code_sat)
9027 /* This belongs to the x + 0x80 corner case. The code with
9028 ADD instruction is not smaller, thus make this case
9029 expensive so that the caller won't pick it. */
9031 *plen += 10;
9032 break;
9035 if (clobber_val != (int) val8)
9036 avr_asm_len ("ldi %2,%1", op, plen, 1);
9037 clobber_val = (int) val8;
9039 avr_asm_len (started ? "adc %0,%2" : "add %0,%2", op, plen, 1);
9041 break; /* PLUS */
9043 case MINUS:
9045 if (ld_reg_p)
9046 avr_asm_len (started ? "sbci %0,%1" : "subi %0,%1", op, plen, 1);
9047 else
9049 gcc_assert (plen != NULL || REG_P (op[2]));
9051 if (clobber_val != (int) val8)
9052 avr_asm_len ("ldi %2,%1", op, plen, 1);
9053 clobber_val = (int) val8;
9055 avr_asm_len (started ? "sbc %0,%2" : "sub %0,%2", op, plen, 1);
9058 break; /* MINUS */
9060 default:
9061 /* Unknown code */
9062 gcc_unreachable();
9065 started = true;
9067 } /* for all sub-bytes */
9069 saturate:
9071 if (UNKNOWN == code_sat)
9072 return;
9074 /* Vanilla addition/subtraction is done. We are left with saturation.
9076 We have to compute A = A <op> B where A is a register and
9077 B is a register or a non-zero compile time constant CONST.
9078 A is register class "r" if unsigned && B is REG. Otherwise, A is in "d".
9079 B stands for the original operand $2 in INSN. In the case of B = CONST,
9080 SIGN in { -1, 1 } is the sign of B. Otherwise, SIGN is 0.
9082 CODE is the instruction flavor we use in the asm sequence to perform <op>.
9085 unsigned
9086 operation | code | sat if | b is | sat value | case
9087 -----------------+-------+----------+--------------+-----------+-------
9088 + as a + b | add | C == 1 | const, reg | u+ = 0xff | [1u]
9089 + as a - (-b) | sub | C == 0 | const | u+ = 0xff | [2u]
9090 - as a - b | sub | C == 1 | const, reg | u- = 0 | [3u]
9091 - as a + (-b) | add | C == 0 | const | u- = 0 | [4u]
9094 signed
9095 operation | code | sat if | b is | sat value | case
9096 -----------------+-------+----------+--------------+-----------+-------
9097 + as a + b | add | V == 1 | const, reg | s+ | [1s]
9098 + as a - (-b) | sub | V == 1 | const | s+ | [2s]
9099 - as a - b | sub | V == 1 | const, reg | s- | [3s]
9100 - as a + (-b) | add | V == 1 | const | s- | [4s]
9102 s+ = b < 0 ? -0x80 : 0x7f
9103 s- = b < 0 ? 0x7f : -0x80
9105 The cases a - b actually perform a - (-(-b)) if B is CONST.
9108 op[0] = simplify_gen_subreg (QImode, xop[0], mode, n_bytes-1);
9109 op[1] = n_bytes > 1
9110 ? simplify_gen_subreg (QImode, xop[0], mode, n_bytes-2)
9111 : NULL_RTX;
9113 bool need_copy = true;
9114 int len_call = 1 + AVR_HAVE_JMP_CALL;
9116 switch (code_sat)
9118 default:
9119 gcc_unreachable();
9121 case SS_PLUS:
9122 case SS_MINUS:
9124 if (out_brvc)
9125 avr_asm_len ("brvc 0f", op, plen, 1);
9127 if (reg_overlap_mentioned_p (xop[0], xop[2]))
9129 /* [1s,reg] */
9131 if (n_bytes == 1)
9132 avr_asm_len ("ldi %0,0x7f" CR_TAB
9133 "adc %0,__zero_reg__", op, plen, 2);
9134 else
9135 avr_asm_len ("ldi %0,0x7f" CR_TAB
9136 "ldi %1,0xff" CR_TAB
9137 "adc %1,__zero_reg__" CR_TAB
9138 "adc %0,__zero_reg__", op, plen, 4);
9140 else if (sign == 0 && PLUS == code)
9142 /* [1s,reg] */
9144 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
9146 if (n_bytes == 1)
9147 avr_asm_len ("ldi %0,0x80" CR_TAB
9148 "sbrs %2,7" CR_TAB
9149 "dec %0", op, plen, 3);
9150 else
9151 avr_asm_len ("ldi %0,0x80" CR_TAB
9152 "cp %2,%0" CR_TAB
9153 "sbc %1,%1" CR_TAB
9154 "sbci %0,0", op, plen, 4);
9156 else if (sign == 0 && MINUS == code)
9158 /* [3s,reg] */
9160 op[2] = simplify_gen_subreg (QImode, xop[2], mode, n_bytes-1);
9162 if (n_bytes == 1)
9163 avr_asm_len ("ldi %0,0x7f" CR_TAB
9164 "sbrs %2,7" CR_TAB
9165 "inc %0", op, plen, 3);
9166 else
9167 avr_asm_len ("ldi %0,0x7f" CR_TAB
9168 "cp %0,%2" CR_TAB
9169 "sbc %1,%1" CR_TAB
9170 "sbci %0,-1", op, plen, 4);
9172 else if ((sign < 0) ^ (SS_MINUS == code_sat))
9174 /* [1s,const,B < 0] [2s,B < 0] */
9175 /* [3s,const,B > 0] [4s,B > 0] */
9177 if (n_bytes == 8)
9179 avr_asm_len ("%~call __clr_8", op, plen, len_call);
9180 need_copy = false;
9183 avr_asm_len ("ldi %0,0x80", op, plen, 1);
9184 if (n_bytes > 1 && need_copy)
9185 avr_asm_len ("clr %1", op, plen, 1);
9187 else if ((sign > 0) ^ (SS_MINUS == code_sat))
9189 /* [1s,const,B > 0] [2s,B > 0] */
9190 /* [3s,const,B < 0] [4s,B < 0] */
9192 if (n_bytes == 8)
9194 avr_asm_len ("sec" CR_TAB
9195 "%~call __sbc_8", op, plen, 1 + len_call);
9196 need_copy = false;
9199 avr_asm_len ("ldi %0,0x7f", op, plen, 1);
9200 if (n_bytes > 1 && need_copy)
9201 avr_asm_len ("ldi %1,0xff", op, plen, 1);
9203 else
9204 gcc_unreachable();
9206 break;
9208 case US_PLUS:
9209 /* [1u] : [2u] */
9211 avr_asm_len (PLUS == code ? "brcc 0f" : "brcs 0f", op, plen, 1);
9213 if (n_bytes == 8)
9215 if (MINUS == code)
9216 avr_asm_len ("sec", op, plen, 1);
9217 avr_asm_len ("%~call __sbc_8", op, plen, len_call);
9219 need_copy = false;
9221 else
9223 if (MINUS == code && !test_hard_reg_class (LD_REGS, op[0]))
9224 avr_asm_len ("sec" CR_TAB
9225 "sbc %0,%0", op, plen, 2);
9226 else
9227 avr_asm_len (PLUS == code ? "sbc %0,%0" : "ldi %0,0xff",
9228 op, plen, 1);
9230 break; /* US_PLUS */
9232 case US_MINUS:
9233 /* [4u] : [3u] */
9235 avr_asm_len (PLUS == code ? "brcs 0f" : "brcc 0f", op, plen, 1);
9237 if (n_bytes == 8)
9239 avr_asm_len ("%~call __clr_8", op, plen, len_call);
9240 need_copy = false;
9242 else
9243 avr_asm_len ("clr %0", op, plen, 1);
9245 break;
9248 /* We set the MSB in the unsigned case and the 2 MSBs in the signed case.
9249 Now copy the right value to the LSBs. */
9251 if (need_copy && n_bytes > 1)
9253 if (US_MINUS == code_sat || US_PLUS == code_sat)
9255 avr_asm_len ("mov %1,%0", op, plen, 1);
9257 if (n_bytes > 2)
9259 op[0] = xop[0];
9260 if (AVR_HAVE_MOVW)
9261 avr_asm_len ("movw %0,%1", op, plen, 1);
9262 else
9263 avr_asm_len ("mov %A0,%1" CR_TAB
9264 "mov %B0,%1", op, plen, 2);
9267 else if (n_bytes > 2)
9269 op[0] = xop[0];
9270 avr_asm_len ("mov %A0,%1" CR_TAB
9271 "mov %B0,%1", op, plen, 2);
9275 if (need_copy && n_bytes == 8)
9277 if (AVR_HAVE_MOVW)
9278 avr_asm_len ("movw %r0+2,%0" CR_TAB
9279 "movw %r0+4,%0", xop, plen, 2);
9280 else
9281 avr_asm_len ("mov %r0+2,%0" CR_TAB
9282 "mov %r0+3,%0" CR_TAB
9283 "mov %r0+4,%0" CR_TAB
9284 "mov %r0+5,%0", xop, plen, 4);
9287 if (out_label)
9288 avr_asm_len ("0:", op, plen, 0);
9292 /* Output addition/subtraction of register XOP[0] and a constant XOP[2] that
9293 is not a compile-time constant:
9295 XOP[0] = XOP[0] +/- XOP[2]
9297 This is a helper for the function below. The only insns that need this
9298 are additions/subtraction for pointer modes, i.e. HImode and PSImode. */
9300 static const char *
9301 avr_out_plus_symbol (rtx *xop, enum rtx_code code, int *plen)
9303 machine_mode mode = GET_MODE (xop[0]);
9305 /* Only pointer modes want to add symbols. */
9307 gcc_assert (mode == HImode || mode == PSImode);
9309 avr_asm_len (PLUS == code
9310 ? "subi %A0,lo8(-(%2))" CR_TAB "sbci %B0,hi8(-(%2))"
9311 : "subi %A0,lo8(%2)" CR_TAB "sbci %B0,hi8(%2)",
9312 xop, plen, -2);
9314 if (PSImode == mode)
9315 avr_asm_len (PLUS == code
9316 ? "sbci %C0,hlo8(-(%2))"
9317 : "sbci %C0,hlo8(%2)", xop, plen, 1);
9318 return "";
9322 /* Prepare operands of addition/subtraction to be used with avr_out_plus_1.
9324 INSN is a single_set insn or an insn pattern with a binary operation as
9325 SET_SRC that is one of: PLUS, SS_PLUS, US_PLUS, MINUS, SS_MINUS, US_MINUS.
9327 XOP are the operands of INSN. In the case of 64-bit operations with
9328 constant XOP[] has just one element: The summand/subtrahend in XOP[0].
9329 The non-saturating insns up to 32 bits may or may not supply a "d" class
9330 scratch as XOP[3].
9332 If PLEN == NULL output the instructions.
9333 If PLEN != NULL set *PLEN to the length of the sequence in words.
9335 PLEN defaults to NULL.
9337 OUT_LABEL defaults to TRUE. For a description, see AVR_OUT_PLUS_1.
9339 Return "" */
9341 const char *
9342 avr_out_plus (rtx insn, rtx *xop, int *plen, bool out_label)
9344 int len_plus, len_minus;
9345 rtx op[4];
9346 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
9347 rtx xdest = SET_DEST (xpattern);
9348 machine_mode mode = GET_MODE (xdest);
9349 scalar_int_mode imode = int_mode_for_mode (mode).require ();
9350 int n_bytes = GET_MODE_SIZE (mode);
9351 enum rtx_code code_sat = GET_CODE (SET_SRC (xpattern));
9352 enum rtx_code code
9353 = (PLUS == code_sat || SS_PLUS == code_sat || US_PLUS == code_sat
9354 ? PLUS : MINUS);
9356 /* PLUS and MINUS don't saturate: Use modular wrap-around. */
9358 if (PLUS == code_sat || MINUS == code_sat)
9359 code_sat = UNKNOWN;
9361 if (n_bytes <= 4 && REG_P (xop[2]))
9363 avr_out_plus_1 (insn, xop, plen, code, code_sat, 0, out_label);
9364 return "";
9367 if (n_bytes == 8)
9369 op[0] = gen_rtx_REG (DImode, ACC_A);
9370 op[1] = gen_rtx_REG (DImode, ACC_A);
9371 op[2] = avr_to_int_mode (xop[0]);
9373 else
9375 if (!REG_P (xop[2])
9376 && !CONST_INT_P (xop[2])
9377 && !CONST_FIXED_P (xop[2]))
9379 return avr_out_plus_symbol (xop, code, plen);
9382 op[0] = avr_to_int_mode (xop[0]);
9383 op[1] = avr_to_int_mode (xop[1]);
9384 op[2] = avr_to_int_mode (xop[2]);
9387 /* Saturations and 64-bit operations don't have a clobber operand.
9388 For the other cases, the caller will provide a proper XOP[3]. */
9390 xpattern = INSN_P (insn) ? PATTERN (insn) : insn;
9391 op[3] = PARALLEL == GET_CODE (xpattern) ? xop[3] : NULL_RTX;
9393 /* Saturation will need the sign of the original operand. */
9395 rtx xmsb = simplify_gen_subreg (QImode, op[2], imode, n_bytes-1);
9396 int sign = INTVAL (xmsb) < 0 ? -1 : 1;
9398 /* If we subtract and the subtrahend is a constant, then negate it
9399 so that avr_out_plus_1 can be used. */
9401 if (MINUS == code)
9402 op[2] = simplify_unary_operation (NEG, imode, op[2], imode);
9404 /* Work out the shortest sequence. */
9406 avr_out_plus_1 (insn, op, &len_minus, MINUS, code_sat, sign, out_label);
9407 avr_out_plus_1 (insn, op, &len_plus, PLUS, code_sat, sign, out_label);
9409 if (plen)
9410 *plen = (len_minus <= len_plus) ? len_minus : len_plus;
9411 else if (len_minus <= len_plus)
9412 avr_out_plus_1 (insn, op, NULL, MINUS, code_sat, sign, out_label);
9413 else
9414 avr_out_plus_1 (insn, op, NULL, PLUS, code_sat, sign, out_label);
9416 return "";
9420 /* Output an instruction sequence for addition of REG in XOP[0] and CONST_INT
9421 in XOP[1] in such a way that SREG.Z and SREG.N are set according to the
9422 result. XOP[2] might be a d-regs clobber register. If XOP[2] is SCRATCH,
9423 then the addition can be performed without a clobber reg. Return "".
9425 If PLEN == NULL, then output the instructions.
9426 If PLEN != NULL, then set *PLEN to the length of the sequence in words. */
9428 const char *
9429 avr_out_plus_set_ZN (rtx *xop, int *plen)
9431 if (plen)
9432 *plen = 0;
9434 // Register to compare and value to compare against.
9435 rtx xreg = xop[0];
9436 rtx xval = xop[1];
9438 machine_mode mode = GET_MODE (xreg);
9440 // Number of bytes to operate on.
9441 int n_bytes = GET_MODE_SIZE (mode);
9443 if (n_bytes == 1)
9445 if (INTVAL (xval) == 1)
9446 return avr_asm_len ("inc %0", xop, plen, 1);
9448 if (INTVAL (xval) == -1)
9449 return avr_asm_len ("dec %0", xop, plen, 1);
9452 if (n_bytes == 2
9453 && avr_adiw_reg_p (xreg)
9454 && IN_RANGE (INTVAL (xval), 1, 63))
9456 // Add 16-bit value in [1..63] to a w register.
9457 return avr_asm_len ("adiw %0, %1", xop, plen, 1);
9460 // Addition won't work; subtract the negative of XVAL instead.
9461 xval = simplify_unary_operation (NEG, mode, xval, mode);
9463 // Value (0..0xff) held in clobber register xop[2] or -1 if unknown.
9464 int clobber_val = -1;
9466 // [0] = Current sub-register.
9467 // [1] = Current partial xval.
9468 // [2] = 8-bit clobber d-register or SCRATCH.
9469 rtx op[3];
9470 op[2] = xop[2];
9472 // Work byte-wise from LSB to MSB. The lower two bytes might be
9473 // SBIW'ed in one go.
9474 for (int i = 0; i < n_bytes; ++i)
9476 op[0] = simplify_gen_subreg (QImode, xreg, mode, i);
9478 if (i == 0
9479 && n_bytes >= 2
9480 && avr_adiw_reg_p (op[0]))
9482 op[1] = simplify_gen_subreg (HImode, xval, mode, 0);
9483 if (IN_RANGE (INTVAL (op[1]), 0, 63))
9485 // SBIW can handle the lower 16 bits.
9486 avr_asm_len ("sbiw %0, %1", op, plen, 1);
9488 // Next byte has already been handled: Skip it.
9489 ++i;
9490 continue;
9494 op[1] = simplify_gen_subreg (QImode, xval, mode, i);
9496 if (test_hard_reg_class (LD_REGS, op[0]))
9498 // d-regs can subtract immediates.
9499 avr_asm_len (i == 0
9500 ? "subi %0, %1"
9501 : "sbci %0, %1", op, plen, 1);
9503 else
9505 int val8 = 0xff & INTVAL (op[1]);
9506 if (val8 == 0)
9508 // Any register can subtract 0.
9509 avr_asm_len (i == 0
9510 ? "sub %0, __zero_reg__"
9511 : "sbc %0, __zero_reg__", op, plen, 1);
9513 else
9515 // Use d-register to hold partial xval.
9517 if (val8 != clobber_val)
9519 // Load partial xval to QI clobber reg and memoize for later.
9520 gcc_assert (REG_P (op[2]));
9521 avr_asm_len ("ldi %2, %1", op, plen, 1);
9522 clobber_val = val8;
9525 avr_asm_len (i == 0
9526 ? "sub %0, %2"
9527 : "sbc %0, %2", op, plen, 1);
9530 } // Loop bytes.
9532 return "";
9536 /* Output bit operation (IOR, AND, XOR) with register XOP[0] and compile
9537 time constant XOP[2]:
9539 XOP[0] = XOP[0] <op> XOP[2]
9541 and return "". If PLEN == NULL, print assembler instructions to perform the
9542 operation; otherwise, set *PLEN to the length of the instruction sequence
9543 (in words) printed with PLEN == NULL. XOP[3] is either an 8-bit clobber
9544 register or SCRATCH if no clobber register is needed for the operation.
9545 INSN is an INSN_P or a pattern of an insn. */
9547 const char *
9548 avr_out_bitop (rtx insn, rtx *xop, int *plen)
9550 /* CODE and MODE of the operation. */
9551 rtx xpattern = INSN_P (insn) ? single_set (as_a <rtx_insn *> (insn)) : insn;
9552 enum rtx_code code = GET_CODE (SET_SRC (xpattern));
9553 machine_mode mode = GET_MODE (xop[0]);
9555 /* Number of bytes to operate on. */
9556 int n_bytes = GET_MODE_SIZE (mode);
9558 /* Value of T-flag (0 or 1) or -1 if unknow. */
9559 int set_t = -1;
9561 /* Value (0..0xff) held in clobber register op[3] or -1 if unknown. */
9562 int clobber_val = -1;
9564 /* op[0]: 8-bit destination register
9565 op[1]: 8-bit const int
9566 op[2]: 8-bit clobber register, SCRATCH or NULL_RTX.
9567 op[3]: 8-bit register containing 0xff or NULL_RTX */
9568 rtx op[4];
9570 op[2] = QImode == mode ? NULL_RTX : xop[3];
9571 op[3] = NULL_RTX;
9573 if (plen)
9574 *plen = 0;
9576 for (int i = 0; i < n_bytes; i++)
9578 /* We operate byte-wise on the destination. */
9579 rtx reg8 = simplify_gen_subreg (QImode, xop[0], mode, i);
9580 rtx xval8 = simplify_gen_subreg (QImode, xop[2], mode, i);
9582 /* 8-bit value to operate with this byte. */
9583 unsigned int val8 = UINTVAL (xval8) & GET_MODE_MASK (QImode);
9585 /* Number of bits set in the current byte of the constant. */
9586 int pop8 = popcount_hwi (val8);
9588 /* Registers R16..R31 can operate with immediate. */
9589 bool ld_reg_p = test_hard_reg_class (LD_REGS, reg8);
9591 op[0] = reg8;
9592 op[1] = GEN_INT (val8);
9594 switch (code)
9596 case IOR:
9598 if (pop8 == 0)
9599 continue;
9600 else if (ld_reg_p)
9601 avr_asm_len ("ori %0,%1", op, plen, 1);
9602 else if (pop8 == 1)
9604 if (set_t != 1)
9605 avr_asm_len ("set", op, plen, 1);
9606 set_t = 1;
9608 op[1] = GEN_INT (exact_log2 (val8));
9609 avr_asm_len ("bld %0,%1", op, plen, 1);
9611 else if (pop8 == 8)
9613 if (op[3] != NULL_RTX)
9614 avr_asm_len ("mov %0,%3", op, plen, 1);
9615 else
9616 avr_asm_len ("clr %0" CR_TAB
9617 "dec %0", op, plen, 2);
9619 op[3] = op[0];
9621 else
9623 if (clobber_val != (int) val8)
9624 avr_asm_len ("ldi %2,%1", op, plen, 1);
9625 clobber_val = (int) val8;
9627 avr_asm_len ("or %0,%2", op, plen, 1);
9630 continue; /* IOR */
9632 case AND:
9634 if (pop8 == 8)
9635 continue;
9636 else if (pop8 == 0)
9637 avr_asm_len ("clr %0", op, plen, 1);
9638 else if (ld_reg_p)
9639 avr_asm_len ("andi %0,%1", op, plen, 1);
9640 else if (pop8 == 7)
9642 if (set_t != 0)
9643 avr_asm_len ("clt", op, plen, 1);
9644 set_t = 0;
9646 op[1] = GEN_INT (exact_log2 (GET_MODE_MASK (QImode) & ~val8));
9647 avr_asm_len ("bld %0,%1", op, plen, 1);
9649 else
9651 if (clobber_val != (int) val8)
9652 avr_asm_len ("ldi %2,%1", op, plen, 1);
9653 clobber_val = (int) val8;
9655 avr_asm_len ("and %0,%2", op, plen, 1);
9658 continue; /* AND */
9660 case XOR:
9662 if (pop8 == 0)
9663 continue;
9664 else if (pop8 == 8)
9665 avr_asm_len ("com %0", op, plen, 1);
9666 else if (ld_reg_p && val8 == (1 << 7))
9667 avr_asm_len ("subi %0,%1", op, plen, 1);
9668 else
9670 if (clobber_val != (int) val8)
9671 avr_asm_len ("ldi %2,%1", op, plen, 1);
9672 clobber_val = (int) val8;
9674 avr_asm_len ("eor %0,%2", op, plen, 1);
9677 continue; /* XOR */
9679 default:
9680 /* Unknown rtx_code */
9681 gcc_unreachable();
9683 } /* for all sub-bytes */
9685 return "";
9689 /* Output sign extension from XOP[1] to XOP[0] and return "".
9690 If PLEN == NULL, print assembler instructions to perform the operation;
9691 otherwise, set *PLEN to the length of the instruction sequence (in words)
9692 as printed with PLEN == NULL. */
9694 const char *
9695 avr_out_sign_extend (rtx_insn *insn, rtx *xop, int *plen)
9697 // Size in bytes of source resp. destination operand.
9698 unsigned n_src = GET_MODE_SIZE (GET_MODE (xop[1]));
9699 unsigned n_dest = GET_MODE_SIZE (GET_MODE (xop[0]));
9700 rtx r_msb = all_regs_rtx[REGNO (xop[1]) + n_src - 1];
9702 if (plen)
9703 *plen = 0;
9705 // Copy destination to source
9707 if (REGNO (xop[0]) != REGNO (xop[1]))
9709 gcc_assert (n_src <= 2);
9711 if (n_src == 2)
9712 avr_asm_len (AVR_HAVE_MOVW
9713 ? "movw %0,%1"
9714 : "mov %B0,%B1", xop, plen, 1);
9715 if (n_src == 1 || !AVR_HAVE_MOVW)
9716 avr_asm_len ("mov %A0,%A1", xop, plen, 1);
9719 // Set Carry to the sign bit MSB.7...
9721 if (REGNO (xop[0]) == REGNO (xop[1])
9722 || !reg_unused_after (insn, r_msb))
9724 avr_asm_len ("mov __tmp_reg__,%0", &r_msb, plen, 1);
9725 r_msb = tmp_reg_rtx;
9728 avr_asm_len ("lsl %0", &r_msb, plen, 1);
9730 // ...and propagate it to all the new sign bits
9732 for (unsigned n = n_src; n < n_dest; n++)
9733 avr_asm_len ("sbc %0,%0", &all_regs_rtx[REGNO (xop[0]) + n], plen, 1);
9735 return "";
9739 /* PLEN == NULL: Output code to add CONST_INT OP[0] to SP.
9740 PLEN != NULL: Set *PLEN to the length of that sequence.
9741 Return "". */
9743 const char *
9744 avr_out_addto_sp (rtx *op, int *plen)
9746 int pc_len = AVR_2_BYTE_PC ? 2 : 3;
9747 int addend = INTVAL (op[0]);
9749 if (plen)
9750 *plen = 0;
9752 if (addend < 0)
9754 if (flag_verbose_asm || flag_print_asm_name)
9755 avr_asm_len (ASM_COMMENT_START "SP -= %n0", op, plen, 0);
9757 while (addend <= -pc_len)
9759 addend += pc_len;
9760 avr_asm_len ("rcall .", op, plen, 1);
9763 while (addend++ < 0)
9764 avr_asm_len ("push __tmp_reg__", op, plen, 1);
9766 else if (addend > 0)
9768 if (flag_verbose_asm || flag_print_asm_name)
9769 avr_asm_len (ASM_COMMENT_START "SP += %0", op, plen, 0);
9771 while (addend-- > 0)
9772 avr_asm_len ("pop __tmp_reg__", op, plen, 1);
9775 return "";
9779 /* Output instructions to insert an inverted bit into OP[0]: $0.$1 = ~$2.$3.
9780 If PLEN = NULL then output the respective instruction sequence which
9781 is a combination of BST / BLD and some instruction(s) to invert the bit.
9782 If PLEN != NULL then store the length of the sequence (in words) in *PLEN.
9783 Return "". */
9785 const char *
9786 avr_out_insert_notbit (rtx_insn *insn, rtx op[], int *plen)
9788 if (INTVAL (op[1]) == 7
9789 && test_hard_reg_class (LD_REGS, op[0]))
9791 /* If the inserted bit number is 7 and we have a d-reg, then invert
9792 the bit after the insertion by means of SUBI *,0x80. */
9794 if (INTVAL (op[3]) == 7
9795 && REGNO (op[0]) == REGNO (op[2]))
9797 avr_asm_len ("subi %0,0x80", op, plen, -1);
9799 else
9801 avr_asm_len ("bst %2,%3" CR_TAB
9802 "bld %0,%1" CR_TAB
9803 "subi %0,0x80", op, plen, -3);
9806 else if (test_hard_reg_class (LD_REGS, op[0])
9807 && (INTVAL (op[1]) != INTVAL (op[3])
9808 || !reg_overlap_mentioned_p (op[0], op[2])))
9810 /* If the destination bit is in a d-reg we can jump depending
9811 on the source bit and use ANDI / ORI. This just applies if we
9812 have not an early-clobber situation with the bit. */
9814 avr_asm_len ("andi %0,~(1<<%1)" CR_TAB
9815 "sbrs %2,%3" CR_TAB
9816 "ori %0,1<<%1", op, plen, -3);
9818 else
9820 /* Otherwise, invert the bit by means of COM before we store it with
9821 BST and then undo the COM if needed. */
9823 avr_asm_len ("com %2" CR_TAB
9824 "bst %2,%3", op, plen, -2);
9826 if (!reg_unused_after (insn, op[2])
9827 // A simple 'reg_unused_after' is not enough because that function
9828 // assumes that the destination register is overwritten completely
9829 // and hence is in order for our purpose. This is not the case
9830 // with BLD which just changes one bit of the destination.
9831 || reg_overlap_mentioned_p (op[0], op[2]))
9833 /* Undo the COM from above. */
9834 avr_asm_len ("com %2", op, plen, 1);
9837 avr_asm_len ("bld %0,%1", op, plen, 1);
9840 return "";
9844 /* Output instructions for XOP[0] = (XOP[1] <Shift> XOP[2]) & XOP[3] where
9845 - XOP[0] and XOP[1] have the same mode which is one of: QI, HI, PSI, SI.
9846 - XOP[3] is an exact const_int power of 2.
9847 - XOP[2] and XOP[3] are const_int.
9848 - <Shift> is any of: ASHIFT, LSHIFTRT, ASHIFTRT.
9849 - The result depends on XOP[1].
9850 or XOP[0] = XOP[1] & XOP[2] where
9851 - XOP[0] and XOP[1] have the same mode which is one of: HI, PSI, SI.
9852 - XOP[2] is an exact const_int power of 2.
9853 Returns "".
9854 PLEN != 0: Set *PLEN to the code length in words. Don't output anything.
9855 PLEN == 0: Output instructions. */
9857 const char*
9858 avr_out_insv (rtx_insn *insn, rtx xop[], int *plen)
9860 machine_mode mode = GET_MODE (xop[0]);
9861 int n_bytes = GET_MODE_SIZE (mode);
9862 rtx xsrc = SET_SRC (single_set (insn));
9864 gcc_assert (AND == GET_CODE (xsrc));
9866 rtx xop2 = xop[2];
9867 rtx xop3 = xop[3];
9869 if (REG_P (XEXP (xsrc, 0)))
9871 // This function can also handle AND with an exact power of 2,
9872 // which can be regarded as a XOP[1] shift with offset 0.
9873 rtx xshift = gen_rtx_ASHIFT (mode, xop[1], const0_rtx);
9874 xsrc = gen_rtx_AND (mode, xshift, xop[2]);
9875 xop3 = xop[2];
9876 xop2 = const0_rtx;
9879 // Any of ASHIFT, LSHIFTRT, ASHIFTRT.
9880 enum rtx_code code = GET_CODE (XEXP (xsrc, 0));
9881 int shift = code == ASHIFT ? INTVAL (xop2) : -INTVAL (xop2);
9883 // Determines the position of the output bit.
9884 unsigned mask = GET_MODE_MASK (mode) & INTVAL (xop3);
9886 // Position of the output / input bit, respectively.
9887 int obit = exact_log2 (mask);
9888 int ibit = obit - shift;
9890 gcc_assert (IN_RANGE (obit, 0, GET_MODE_BITSIZE (mode) - 1));
9891 gcc_assert (IN_RANGE (ibit, 0, GET_MODE_BITSIZE (mode) - 1));
9893 // In the remainder, use the sub-bytes that hold the bits.
9894 rtx op[4] =
9896 // Output
9897 simplify_gen_subreg (QImode, xop[0], mode, obit / 8),
9898 GEN_INT (obit & 7),
9899 // Input
9900 simplify_gen_subreg (QImode, xop[1], mode, ibit / 8),
9901 GEN_INT (ibit & 7)
9903 obit &= 7;
9904 ibit &= 7;
9906 // The length of the default sequence at the end of this function.
9907 // We only emit anything other than the default when we find a sequence
9908 // that is strictly shorter than the default sequence; which is:
9909 // BST + <CLR-result-bytes> + BLD.
9910 const int len0 = 2 + n_bytes - (n_bytes == 4 && AVR_HAVE_MOVW);
9912 // Finding something shorter than the default sequence implies that there
9913 // must be at most 2 instructions that deal with the bytes containing the
9914 // relevant bits. In addition, we need N_BYTES - 1 instructions to clear
9915 // the remaining result bytes.
9917 const int n_clr = n_bytes - 1;
9918 bool clr_p = false;
9919 bool andi_p = false;
9921 if (plen)
9922 *plen = 0;
9924 if (REGNO (op[0]) == REGNO (op[2])
9925 // Output reg allows ANDI.
9926 && test_hard_reg_class (LD_REGS, op[0]))
9928 if (1 + n_clr < len0
9929 // Same byte and bit: A single ANDI will do.
9930 && obit == ibit)
9932 clr_p = andi_p = true;
9934 else if (2 + n_clr < len0
9935 // |obit - ibit| = 4: SWAP + ANDI will do.
9936 && (obit == ibit + 4 || obit == ibit - 4))
9938 avr_asm_len ("swap %0", op, plen, 1);
9939 clr_p = andi_p = true;
9941 else if (2 + n_clr < len0
9942 // LSL + ANDI will do.
9943 && obit == ibit + 1)
9945 avr_asm_len ("lsl %0", op, plen, 1);
9946 clr_p = andi_p = true;
9948 else if (2 + n_clr < len0
9949 // LSR + ANDI will do.
9950 && obit == ibit - 1)
9952 avr_asm_len ("lsr %0", op, plen, 1);
9953 clr_p = andi_p = true;
9957 if (REGNO (op[0]) != REGNO (op[2])
9958 && obit == ibit)
9960 if (2 + n_clr < len0
9961 // Same bit but different byte: MOV + ANDI will do.
9962 && test_hard_reg_class (LD_REGS, op[0]))
9964 avr_asm_len ("mov %0,%2", op, plen, 1);
9965 clr_p = andi_p = true;
9967 else if (2 + n_clr < len0
9968 // Same bit but different byte: We can use ANDI + MOV,
9969 // but only if the input byte is LD_REGS and unused after.
9970 && test_hard_reg_class (LD_REGS, op[2])
9971 && reg_unused_after (insn, op[2]))
9973 avr_asm_len ("andi %2,1<<%3" CR_TAB
9974 "mov %0,%2", op, plen, 2);
9975 clr_p = true;
9979 // Output remaining instructions of the shorter sequence.
9981 if (andi_p)
9982 avr_asm_len ("andi %0,1<<%1", op, plen, 1);
9984 if (clr_p)
9986 for (int b = 0; b < n_bytes; ++b)
9988 rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b);
9989 if (REGNO (byte) != REGNO (op[0]))
9990 avr_asm_len ("clr %0", &byte, plen, 1);
9993 // CLR_P means we found a shorter sequence, so we are done now.
9994 return "";
9997 // No shorter sequence found, just emit BST, CLR*, BLD sequence.
9999 avr_asm_len ("bst %2,%3", op, plen, -1);
10001 if (n_bytes == 4 && AVR_HAVE_MOVW)
10002 avr_asm_len ("clr %A0" CR_TAB
10003 "clr %B0" CR_TAB
10004 "movw %C0,%A0", xop, plen, 3);
10005 else
10006 for (int b = 0; b < n_bytes; ++b)
10008 rtx byte = simplify_gen_subreg (QImode, xop[0], mode, b);
10009 avr_asm_len ("clr %0", &byte, plen, 1);
10012 return avr_asm_len ("bld %0,%1", op, plen, 1);
10016 /* Output instructions to extract a bit to 8-bit register XOP[0].
10017 The input XOP[1] is a register or an 8-bit MEM in the lower I/O range.
10018 XOP[2] is the const_int bit position. Return "".
10020 PLEN != 0: Set *PLEN to the code length in words. Don't output anything.
10021 PLEN == 0: Output instructions. */
10023 const char *
10024 avr_out_extr (rtx_insn *insn, rtx xop[], int *plen)
10026 rtx dest = xop[0];
10027 rtx src = xop[1];
10028 int bit = INTVAL (xop[2]);
10030 if (GET_MODE (src) != QImode)
10032 src = xop[1] = simplify_gen_subreg (QImode, src, GET_MODE (src), bit / 8);
10033 bit %= 8;
10034 xop[2] = GEN_INT (bit);
10037 if (MEM_P (src))
10039 xop[1] = XEXP (src, 0); // address
10040 gcc_assert (low_io_address_operand (xop[1], Pmode));
10042 return avr_asm_len ("clr %0" CR_TAB
10043 "sbic %i1,%2" CR_TAB
10044 "inc %0", xop, plen, -3);
10047 gcc_assert (REG_P (src));
10049 bool ld_dest_p = test_hard_reg_class (LD_REGS, dest);
10050 bool ld_src_p = test_hard_reg_class (LD_REGS, src);
10052 if (ld_dest_p
10053 && REGNO (src) == REGNO (dest))
10055 if (bit == 0)
10056 return avr_asm_len ("andi %0,1", xop, plen, -1);
10057 if (bit == 1)
10058 return avr_asm_len ("lsr %0" CR_TAB
10059 "andi %0,1", xop, plen, -2);
10060 if (bit == 4)
10061 return avr_asm_len ("swap %0" CR_TAB
10062 "andi %0,1", xop, plen, -2);
10065 if (bit == 0
10066 && REGNO (src) != REGNO (dest))
10068 if (ld_dest_p)
10069 return avr_asm_len ("mov %0,%1" CR_TAB
10070 "andi %0,1", xop, plen, -2);
10071 if (ld_src_p
10072 && reg_unused_after (insn, src))
10073 return avr_asm_len ("andi %1,1" CR_TAB
10074 "mov %0,%1", xop, plen, -2);
10077 return avr_asm_len ("bst %1,%2" CR_TAB
10078 "clr %0" CR_TAB
10079 "bld %0,0", xop, plen, -3);
10083 /* Output instructions to extract a negated bit to 8-bit register XOP[0].
10084 The input XOP[1] is an 8-bit register or MEM in the lower I/O range.
10085 XOP[2] is the const_int bit position. Return "".
10087 PLEN != 0: Set *PLEN to the code length in words. Don't output anything.
10088 PLEN == 0: Output instructions. */
10090 const char *
10091 avr_out_extr_not (rtx_insn * /* insn */, rtx xop[], int *plen)
10093 rtx dest = xop[0];
10094 rtx src = xop[1];
10095 int bit = INTVAL (xop[2]);
10097 if (MEM_P (src))
10099 xop[1] = XEXP (src, 0); // address
10100 gcc_assert (low_io_address_operand (xop[1], Pmode));
10102 return avr_asm_len ("clr %0" CR_TAB
10103 "sbis %i1,%2" CR_TAB
10104 "inc %0", xop, plen, -3);
10107 gcc_assert (REG_P (src));
10109 bool ld_src_p = test_hard_reg_class (LD_REGS, src);
10111 if (ld_src_p
10112 && REGNO (src) == REGNO (dest))
10114 if (bit == 0)
10115 return avr_asm_len ("inc %0" CR_TAB
10116 "andi %0,1", xop, plen, -2);
10117 if (bit == 1)
10118 return avr_asm_len ("lsr %0" CR_TAB
10119 "inc %0" CR_TAB
10120 "andi %0,1", xop, plen, -3);
10121 if (bit == 4)
10122 return avr_asm_len ("swap %0" CR_TAB
10123 "inc %0" CR_TAB
10124 "andi %0,1", xop, plen, -3);
10127 if (bit == 7
10128 && ld_src_p)
10129 return avr_asm_len ("cpi %1,0x80" CR_TAB
10130 "sbc %0,%0" CR_TAB
10131 "neg %0", xop, plen, -3);
10133 if (REGNO (src) != REGNO (dest))
10134 return avr_asm_len ("clr %0" CR_TAB
10135 "sbrs %1,%2" CR_TAB
10136 "inc %0", xop, plen, -3);
10138 return avr_asm_len ("clr __tmp_reg__" CR_TAB
10139 "sbrs %1,%2" CR_TAB
10140 "inc __tmp_reg__" CR_TAB
10141 "mov %0,__tmp_reg__", xop, plen, -4);
10145 /* Outputs instructions needed for fixed point type conversion.
10146 This includes converting between any fixed point type, as well
10147 as converting to any integer type. Conversion between integer
10148 types is not supported.
10150 Converting signed fractional types requires a bit shift if converting
10151 to or from any unsigned fractional type because the decimal place is
10152 shifted by 1 bit. When the destination is a signed fractional, the sign
10153 is stored in either the carry or T bit. */
10155 const char *
10156 avr_out_fract (rtx_insn *insn, rtx operands[], bool intsigned, int *plen)
10158 rtx xop[6];
10159 RTX_CODE shift = UNKNOWN;
10160 bool sign_in_carry = false;
10161 bool msb_in_carry = false;
10162 bool lsb_in_tmp_reg = false;
10163 bool lsb_in_carry = false;
10164 bool frac_rounded = false;
10165 const char *code_ashift = "lsl %0";
10168 #define MAY_CLOBBER(RR) \
10169 /* Shorthand used below. */ \
10170 ((sign_bytes \
10171 && IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
10172 || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \
10173 || (reg_unused_after (insn, all_regs_rtx[RR]) \
10174 && !IN_RANGE (RR, dest.regno, dest.regno_msb)))
10176 struct
10178 /* bytes : Length of operand in bytes.
10179 ibyte : Length of integral part in bytes.
10180 fbyte, fbit : Length of fractional part in bytes, bits. */
10182 bool sbit;
10183 unsigned fbit, bytes, ibyte, fbyte;
10184 unsigned regno, regno_msb;
10185 } dest, src, *val[2] = { &dest, &src };
10187 if (plen)
10188 *plen = 0;
10190 /* Step 0: Determine information on source and destination operand we
10191 ====== will need in the remainder. */
10193 for (size_t i = 0; i < ARRAY_SIZE (val); i++)
10195 machine_mode mode;
10197 xop[i] = operands[i];
10199 mode = GET_MODE (xop[i]);
10201 val[i]->bytes = GET_MODE_SIZE (mode);
10202 val[i]->regno = REGNO (xop[i]);
10203 val[i]->regno_msb = REGNO (xop[i]) + val[i]->bytes - 1;
10205 if (SCALAR_INT_MODE_P (mode))
10207 val[i]->sbit = intsigned;
10208 val[i]->fbit = 0;
10210 else if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
10212 val[i]->sbit = SIGNED_SCALAR_FIXED_POINT_MODE_P (mode);
10213 val[i]->fbit = GET_MODE_FBIT (mode);
10215 else
10216 fatal_insn ("unsupported fixed-point conversion", insn);
10218 val[i]->fbyte = (1 + val[i]->fbit) / BITS_PER_UNIT;
10219 val[i]->ibyte = val[i]->bytes - val[i]->fbyte;
10222 // Byte offset of the decimal point taking into account different place
10223 // of the decimal point in input and output and different register numbers
10224 // of input and output.
10225 int offset = dest.regno - src.regno + dest.fbyte - src.fbyte;
10227 // Number of destination bytes that will come from sign / zero extension.
10228 int sign_bytes = (dest.ibyte - src.ibyte) * (dest.ibyte > src.ibyte);
10230 // Number of bytes at the low end to be filled with zeros.
10231 int zero_bytes = (dest.fbyte - src.fbyte) * (dest.fbyte > src.fbyte);
10233 // Do we have a 16-Bit register that is cleared?
10234 rtx clrw = NULL_RTX;
10236 bool sign_extend = src.sbit && sign_bytes;
10238 if (dest.fbit % 8 == 0 && src.fbit % 8 == 7)
10239 shift = ASHIFT;
10240 else if (dest.fbit % 8 == 7 && src.fbit % 8 == 0)
10241 shift = ASHIFTRT;
10242 else if (dest.fbit % 8 == src.fbit % 8)
10243 shift = UNKNOWN;
10244 else
10245 gcc_unreachable();
10247 /* If we need to round the fraction part, we might need to save/round it
10248 before clobbering any of it in Step 1. Also, we might want to do
10249 the rounding now to make use of LD_REGS. */
10250 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
10251 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
10252 && !TARGET_FRACT_CONV_TRUNC)
10254 bool overlap
10255 = (src.regno <=
10256 (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
10257 && dest.regno - offset -1 >= dest.regno);
10258 unsigned s0 = dest.regno - offset -1;
10259 bool use_src = true;
10260 unsigned sn;
10261 unsigned copied_msb = src.regno_msb;
10262 bool have_carry = false;
10264 if (src.ibyte > dest.ibyte)
10265 copied_msb -= src.ibyte - dest.ibyte;
10267 for (sn = s0; sn <= copied_msb; sn++)
10268 if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
10269 && !reg_unused_after (insn, all_regs_rtx[sn]))
10270 use_src = false;
10271 if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
10273 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
10274 &all_regs_rtx[src.regno_msb], plen, 2);
10275 sn = src.regno;
10276 if (sn < s0)
10278 if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
10279 avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
10280 else
10281 avr_asm_len ("sec" CR_TAB
10282 "cpc %0,__zero_reg__",
10283 &all_regs_rtx[sn], plen, 2);
10284 have_carry = true;
10286 while (++sn < s0)
10287 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
10289 avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
10290 &all_regs_rtx[s0], plen, 1);
10291 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
10292 avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
10293 avr_asm_len ("\n0:", NULL, plen, 0);
10294 frac_rounded = true;
10296 else if (use_src && overlap)
10298 avr_asm_len ("clr __tmp_reg__" CR_TAB
10299 "sbrc %1,0" CR_TAB
10300 "dec __tmp_reg__", xop, plen, 1);
10301 sn = src.regno;
10302 if (sn < s0)
10304 avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
10305 have_carry = true;
10308 while (++sn < s0)
10309 avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
10311 if (have_carry)
10312 avr_asm_len ("clt" CR_TAB
10313 "bld __tmp_reg__,7" CR_TAB
10314 "adc %0,__tmp_reg__",
10315 &all_regs_rtx[s0], plen, 1);
10316 else
10317 avr_asm_len ("lsr __tmp_reg" CR_TAB
10318 "add %0,__tmp_reg__",
10319 &all_regs_rtx[s0], plen, 2);
10320 for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
10321 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
10322 frac_rounded = true;
10324 else if (overlap)
10326 bool use_src
10327 = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
10328 && (IN_RANGE (s0, dest.regno, dest.regno_msb)
10329 || reg_unused_after (insn, all_regs_rtx[s0])));
10330 xop[2] = all_regs_rtx[s0];
10331 unsigned sn = src.regno;
10332 if (!use_src || sn == s0)
10333 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
10334 /* We need to consider to-be-discarded bits
10335 if the value is negative. */
10336 if (sn < s0)
10338 avr_asm_len ("tst %0" CR_TAB
10339 "brpl 0f",
10340 &all_regs_rtx[src.regno_msb], plen, 2);
10341 /* Test to-be-discarded bytes for any nozero bits.
10342 ??? Could use OR or SBIW to test two registers at once. */
10343 if (sn < s0)
10344 avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
10346 while (++sn < s0)
10347 avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
10348 /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */
10349 if (use_src)
10350 avr_asm_len ("breq 0f" CR_TAB
10351 "ori %2,1"
10352 "\n0:\t" "mov __tmp_reg__,%2",
10353 xop, plen, 3);
10354 else
10355 avr_asm_len ("breq 0f" CR_TAB
10356 "set" CR_TAB
10357 "bld __tmp_reg__,0\n0:",
10358 xop, plen, 3);
10360 lsb_in_tmp_reg = true;
10364 /* Step 1: Clear bytes at the low end and copy payload bits from source
10365 ====== to destination. */
10367 int step = offset < 0 ? 1 : -1;
10368 unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
10370 // We cleared at least that number of registers.
10371 int clr_n = 0;
10373 for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
10375 // Next regno of destination is needed for MOVW
10376 unsigned d1 = d0 + step;
10378 // Current and next regno of source
10379 signed s0 = d0 - offset;
10380 signed s1 = s0 + step;
10382 // Must current resp. next regno be CLRed? This applies to the low
10383 // bytes of the destination that have no associated source bytes.
10384 bool clr0 = s0 < (signed) src.regno;
10385 bool clr1 = s1 < (signed) src.regno && d1 >= dest.regno;
10387 // First gather what code to emit (if any) and additional step to
10388 // apply if a MOVW is in use. xop[2] is destination rtx and xop[3]
10389 // is the source rtx for the current loop iteration.
10390 const char *code = NULL;
10391 int stepw = 0;
10393 if (clr0)
10395 if (AVR_HAVE_MOVW && clr1 && clrw)
10397 xop[2] = all_regs_rtx[d0 & ~1];
10398 xop[3] = clrw;
10399 code = "movw %2,%3";
10400 stepw = step;
10402 else
10404 xop[2] = all_regs_rtx[d0];
10405 code = "clr %2";
10407 if (++clr_n >= 2
10408 && !clrw
10409 && d0 % 2 == (step > 0))
10411 clrw = all_regs_rtx[d0 & ~1];
10415 else if (offset && s0 <= (signed) src.regno_msb)
10417 int movw = AVR_HAVE_MOVW && offset % 2 == 0
10418 && d0 % 2 == (offset > 0)
10419 && d1 <= dest.regno_msb && d1 >= dest.regno
10420 && s1 <= (signed) src.regno_msb && s1 >= (signed) src.regno;
10422 xop[2] = all_regs_rtx[d0 & ~movw];
10423 xop[3] = all_regs_rtx[s0 & ~movw];
10424 code = movw ? "movw %2,%3" : "mov %2,%3";
10425 stepw = step * movw;
10428 if (code)
10430 if (sign_extend && shift != ASHIFT && !sign_in_carry
10431 && (d0 == src.regno_msb || d0 + stepw == src.regno_msb))
10433 /* We are going to override the sign bit. If we sign-extend,
10434 store the sign in the Carry flag. This is not needed if
10435 the destination will be ASHIFT in the remainder because
10436 the ASHIFT will set Carry without extra instruction. */
10438 avr_asm_len ("lsl %0", &all_regs_rtx[src.regno_msb], plen, 1);
10439 sign_in_carry = true;
10442 unsigned src_msb = dest.regno_msb - sign_bytes - offset + 1;
10444 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
10445 && src.ibyte > dest.ibyte
10446 && (d0 == src_msb || d0 + stepw == src_msb))
10448 /* We are going to override the MSB. If we shift right,
10449 store the MSB in the Carry flag. This is only needed if
10450 we don't sign-extend becaue with sign-extension the MSB
10451 (the sign) will be produced by the sign extension. */
10453 avr_asm_len ("lsr %0", &all_regs_rtx[src_msb], plen, 1);
10454 msb_in_carry = true;
10457 unsigned src_lsb = dest.regno - offset -1;
10459 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
10460 && !lsb_in_tmp_reg
10461 && (d0 == src_lsb || d0 + stepw == src_lsb))
10463 /* We are going to override the new LSB; store it into carry. */
10465 avr_asm_len ("lsl %0", &all_regs_rtx[src_lsb], plen, 1);
10466 code_ashift = "rol %0";
10467 lsb_in_carry = true;
10470 avr_asm_len (code, xop, plen, 1);
10471 d0 += stepw;
10475 /* Step 2: Shift destination left by 1 bit position. This might be needed
10476 ====== for signed input and unsigned output. */
10478 if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry)
10480 unsigned s0 = dest.regno - offset -1;
10482 /* n1169 4.1.4 says:
10483 "Conversions from a fixed-point to an integer type round toward zero."
10484 Hence, converting a fract type to integer only gives a non-zero result
10485 for -1. */
10486 if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
10487 && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
10488 && !TARGET_FRACT_CONV_TRUNC)
10490 gcc_assert (s0 == src.regno_msb);
10491 /* Check if the input is -1. We do that by checking if negating
10492 the input causes an integer overflow. */
10493 unsigned sn = src.regno;
10494 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
10495 while (sn <= s0)
10496 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
10498 /* Overflow goes with set carry. Clear carry otherwise. */
10499 avr_asm_len ("brvs 0f" CR_TAB
10500 "clc\n0:", NULL, plen, 2);
10502 /* Likewise, when converting from accumulator types to integer, we
10503 need to round up negative values. */
10504 else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
10505 && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
10506 && !TARGET_FRACT_CONV_TRUNC
10507 && !frac_rounded)
10509 bool have_carry = false;
10511 xop[2] = all_regs_rtx[s0];
10512 if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
10513 avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
10514 avr_asm_len ("tst %0" CR_TAB "brpl 0f",
10515 &all_regs_rtx[src.regno_msb], plen, 2);
10516 if (!lsb_in_tmp_reg)
10518 unsigned sn = src.regno;
10519 if (sn < s0)
10521 avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
10522 plen, 1);
10523 have_carry = true;
10525 while (++sn < s0)
10526 avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
10527 lsb_in_tmp_reg = !MAY_CLOBBER (s0);
10529 /* Add in C and the rounding value 127. */
10530 /* If the destination msb is a sign byte, and in LD_REGS,
10531 grab it as a temporary. */
10532 if (sign_bytes
10533 && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
10534 dest.regno_msb))
10536 xop[3] = all_regs_rtx[dest.regno_msb];
10537 avr_asm_len ("ldi %3,127", xop, plen, 1);
10538 avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
10539 : have_carry ? "adc %2,%3"
10540 : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
10541 : "add %2,%3"),
10542 xop, plen, 1);
10544 else
10546 /* Fall back to use __zero_reg__ as a temporary. */
10547 avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
10548 if (have_carry)
10549 avr_asm_len ("clt" CR_TAB
10550 "bld __zero_reg__,7", NULL, plen, 2);
10551 else
10552 avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
10553 avr_asm_len (have_carry && lsb_in_tmp_reg
10554 ? "adc __tmp_reg__,__zero_reg__"
10555 : have_carry ? "adc %2,__zero_reg__"
10556 : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
10557 : "add %2,__zero_reg__",
10558 xop, plen, 1);
10559 avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
10562 for (d0 = dest.regno + zero_bytes;
10563 d0 <= dest.regno_msb - sign_bytes; d0++)
10564 avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
10566 avr_asm_len (lsb_in_tmp_reg
10567 ? "\n0:\t" "lsl __tmp_reg__"
10568 : "\n0:\t" "lsl %2",
10569 xop, plen, 1);
10571 else if (MAY_CLOBBER (s0))
10572 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
10573 else
10574 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
10575 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
10577 code_ashift = "rol %0";
10578 lsb_in_carry = true;
10581 if (shift == ASHIFT)
10583 for (d0 = dest.regno + zero_bytes;
10584 d0 <= dest.regno_msb - sign_bytes; d0++)
10586 avr_asm_len (code_ashift, &all_regs_rtx[d0], plen, 1);
10587 code_ashift = "rol %0";
10590 lsb_in_carry = false;
10591 sign_in_carry = true;
10594 /* Step 4a: Store MSB in carry if we don't already have it or will produce
10595 ======= it in sign-extension below. */
10597 if (!sign_extend && shift == ASHIFTRT && !msb_in_carry
10598 && src.ibyte > dest.ibyte)
10600 unsigned s0 = dest.regno_msb - sign_bytes - offset + 1;
10602 if (MAY_CLOBBER (s0))
10603 avr_asm_len ("lsr %0", &all_regs_rtx[s0], plen, 1);
10604 else
10605 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
10606 "lsr __tmp_reg__", &all_regs_rtx[s0], plen, 2);
10608 msb_in_carry = true;
10611 /* Step 3: Sign-extend or zero-extend the destination as needed.
10612 ====== */
10614 if (sign_extend && !sign_in_carry)
10616 unsigned s0 = src.regno_msb;
10618 if (MAY_CLOBBER (s0))
10619 avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
10620 else
10621 avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
10622 "lsl __tmp_reg__", &all_regs_rtx[s0], plen, 2);
10624 sign_in_carry = true;
10627 gcc_assert (sign_in_carry + msb_in_carry + lsb_in_carry <= 1);
10629 unsigned copies = 0;
10630 rtx movw = sign_extend ? NULL_RTX : clrw;
10632 for (d0 = dest.regno_msb - sign_bytes + 1; d0 <= dest.regno_msb; d0++)
10634 if (AVR_HAVE_MOVW && movw
10635 && d0 % 2 == 0 && d0 + 1 <= dest.regno_msb)
10637 xop[2] = all_regs_rtx[d0];
10638 xop[3] = movw;
10639 avr_asm_len ("movw %2,%3", xop, plen, 1);
10640 d0++;
10642 else
10644 avr_asm_len (sign_extend ? "sbc %0,%0" : "clr %0",
10645 &all_regs_rtx[d0], plen, 1);
10647 if (++copies >= 2 && !movw && d0 % 2 == 1)
10648 movw = all_regs_rtx[d0-1];
10650 } /* for */
10653 /* Step 4: Right shift the destination. This might be needed for
10654 ====== conversions from unsigned to signed. */
10656 if (shift == ASHIFTRT)
10658 const char *code_ashiftrt = "lsr %0";
10660 if (sign_extend || msb_in_carry)
10661 code_ashiftrt = "ror %0";
10663 if (src.sbit && src.ibyte == dest.ibyte)
10664 code_ashiftrt = "asr %0";
10666 for (d0 = dest.regno_msb - sign_bytes;
10667 d0 >= dest.regno + zero_bytes - 1 && d0 >= dest.regno; d0--)
10669 avr_asm_len (code_ashiftrt, &all_regs_rtx[d0], plen, 1);
10670 code_ashiftrt = "ror %0";
10674 #undef MAY_CLOBBER
10676 return "";
10680 /* Output fixed-point rounding. XOP[0] = XOP[1] is the operand to round.
10681 XOP[2] is the rounding point, a CONST_INT. The function prints the
10682 instruction sequence if PLEN = NULL and computes the length in words
10683 of the sequence if PLEN != NULL. Most of this function deals with
10684 preparing operands for calls to `avr_out_plus' and `avr_out_bitop'. */
10686 const char *
10687 avr_out_round (rtx_insn * /*insn*/, rtx *xop, int *plen)
10689 scalar_mode mode = as_a <scalar_mode> (GET_MODE (xop[0]));
10690 scalar_int_mode imode = int_mode_for_mode (mode).require ();
10691 // The smallest fractional bit not cleared by the rounding is 2^(-RP).
10692 int fbit = (int) GET_MODE_FBIT (mode);
10693 double_int i_add = double_int_zero.set_bit (fbit-1 - INTVAL (xop[2]));
10694 wide_int wi_add = wi::set_bit_in_zero (fbit-1 - INTVAL (xop[2]),
10695 GET_MODE_PRECISION (imode));
10696 // Lengths of PLUS and AND parts.
10697 int len_add = 0, *plen_add = plen ? &len_add : NULL;
10698 int len_and = 0, *plen_and = plen ? &len_and : NULL;
10700 // Add-Saturate 1/2 * 2^(-RP). Don't print the label "0:" when printing
10701 // the saturated addition so that we can emit the "rjmp 1f" before the
10702 // "0:" below.
10704 rtx xadd = const_fixed_from_double_int (i_add, mode);
10705 rtx xpattern, xsrc, op[4];
10707 xsrc = SIGNED_FIXED_POINT_MODE_P (mode)
10708 ? gen_rtx_SS_PLUS (mode, xop[1], xadd)
10709 : gen_rtx_US_PLUS (mode, xop[1], xadd);
10710 xpattern = gen_rtx_SET (xop[0], xsrc);
10712 op[0] = xop[0];
10713 op[1] = xop[1];
10714 op[2] = xadd;
10715 avr_out_plus (xpattern, op, plen_add, false /* Don't print "0:" */);
10717 avr_asm_len ("rjmp 1f" CR_TAB
10718 "0:", NULL, plen_add, 1);
10720 // Keep all bits from RP and higher: ... 2^(-RP)
10721 // Clear all bits from RP+1 and lower: 2^(-RP-1) ...
10722 // Rounding point ^^^^^^^
10723 // Added above ^^^^^^^^^
10724 rtx xreg = simplify_gen_subreg (imode, xop[0], mode, 0);
10725 rtx xmask = immed_wide_int_const (-wi_add - wi_add, imode);
10727 xpattern = gen_rtx_SET (xreg, gen_rtx_AND (imode, xreg, xmask));
10729 op[0] = xreg;
10730 op[1] = xreg;
10731 op[2] = xmask;
10732 op[3] = gen_rtx_SCRATCH (QImode);
10733 avr_out_bitop (xpattern, op, plen_and);
10734 avr_asm_len ("1:", NULL, plen, 0);
10736 if (plen)
10737 *plen = len_add + len_and;
10739 return "";
10743 /* Create RTL split patterns for byte sized rotate expressions. This
10744 produces a series of move instructions and considers overlap situations.
10745 Overlapping non-HImode operands need a scratch register. */
10747 bool
10748 avr_rotate_bytes (rtx operands[])
10750 machine_mode mode = GET_MODE (operands[0]);
10751 bool overlapped = reg_overlap_mentioned_p (operands[0], operands[1]);
10752 bool same_reg = rtx_equal_p (operands[0], operands[1]);
10753 int num = INTVAL (operands[2]);
10754 rtx scratch = operands[3];
10755 /* Work out if byte or word move is needed. Odd byte rotates need QImode.
10756 Word move if no scratch is needed, otherwise use size of scratch. */
10757 machine_mode move_mode = QImode;
10759 if (num & 0xf)
10760 move_mode = QImode;
10761 else if ((mode == SImode && !same_reg) || !overlapped)
10762 move_mode = HImode;
10763 else
10764 move_mode = GET_MODE (scratch);
10766 /* Force DI rotate to use QI moves since other DI moves are currently split
10767 into QI moves so forward propagation works better. */
10768 if (mode == DImode)
10769 move_mode = QImode;
10770 /* Make scratch smaller if needed. */
10771 if (SCRATCH != GET_CODE (scratch)
10772 && HImode == GET_MODE (scratch)
10773 && QImode == move_mode)
10774 scratch = simplify_gen_subreg (move_mode, scratch, HImode, 0);
10776 int move_size = GET_MODE_SIZE (move_mode);
10777 /* Number of bytes/words to rotate. */
10778 int offset = (num >> 3) / move_size;
10779 /* Number of moves needed. */
10780 int size = GET_MODE_SIZE (mode) / move_size;
10781 /* Himode byte swap is special case to avoid a scratch register. */
10782 if (mode == HImode && same_reg)
10784 /* HImode byte swap, using xor. This is as quick as using scratch. */
10785 rtx src, dst;
10786 src = simplify_gen_subreg (move_mode, operands[1], mode, 0);
10787 dst = simplify_gen_subreg (move_mode, operands[0], mode, 1);
10788 if (!rtx_equal_p (dst, src))
10790 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
10791 emit_move_insn (src, gen_rtx_XOR (QImode, src, dst));
10792 emit_move_insn (dst, gen_rtx_XOR (QImode, dst, src));
10795 else
10797 #define MAX_SIZE 8 /* GET_MODE_SIZE (DImode) / GET_MODE_SIZE (QImode) */
10798 /* Create linked list of moves to determine move order. */
10799 struct {
10800 rtx src, dst;
10801 int links;
10802 } move[MAX_SIZE + 8];
10803 int blocked, moves;
10805 gcc_assert (size <= MAX_SIZE);
10806 /* Generate list of subreg moves. */
10807 for (int i = 0; i < size; i++)
10809 int from = i;
10810 int to = (from + offset) % size;
10811 move[i].src = simplify_gen_subreg (move_mode, operands[1],
10812 mode, from * move_size);
10813 move[i].dst = simplify_gen_subreg (move_mode, operands[0],
10814 mode, to * move_size);
10815 move[i].links = -1;
10817 /* Mark dependence where a dst of one move is the src of another move.
10818 The first move is a conflict as it must wait until second is
10819 performed. We ignore moves to self - we catch this later. */
10820 if (overlapped)
10821 for (int i = 0; i < size; i++)
10822 if (reg_overlap_mentioned_p (move[i].dst, operands[1]))
10823 for (int j = 0; j < size; j++)
10824 if (j != i && rtx_equal_p (move[j].src, move[i].dst))
10826 /* The dst of move i is the src of move j. */
10827 move[i].links = j;
10828 break;
10831 blocked = -1;
10832 moves = 0;
10833 /* Go through move list and perform non-conflicting moves. As each
10834 non-overlapping move is made, it may remove other conflicts
10835 so the process is repeated until no conflicts remain. */
10838 blocked = -1;
10839 moves = 0;
10840 /* Emit move where dst is not also a src or we have used that
10841 src already. */
10842 for (int i = 0; i < size; i++)
10843 if (move[i].src != NULL_RTX)
10845 if (move[i].links == -1
10846 || move[move[i].links].src == NULL_RTX)
10848 moves++;
10849 /* Ignore NOP moves to self. */
10850 if (!rtx_equal_p (move[i].dst, move[i].src))
10851 emit_move_insn (move[i].dst, move[i].src);
10853 /* Remove conflict from list. */
10854 move[i].src = NULL_RTX;
10856 else
10857 blocked = i;
10860 /* Check for deadlock. This is when no moves occurred and we have
10861 at least one blocked move. */
10862 if (moves == 0 && blocked != -1)
10864 /* Need to use scratch register to break deadlock.
10865 Add move to put dst of blocked move into scratch.
10866 When this move occurs, it will break chain deadlock.
10867 The scratch register is substituted for real move. */
10869 gcc_assert (SCRATCH != GET_CODE (scratch));
10871 move[size].src = move[blocked].dst;
10872 move[size].dst = scratch;
10873 /* Scratch move is never blocked. */
10874 move[size].links = -1;
10875 /* Make sure we have valid link. */
10876 gcc_assert (move[blocked].links != -1);
10877 /* Replace src of blocking move with scratch reg. */
10878 move[move[blocked].links].src = scratch;
10879 /* Make dependent on scratch move occurring. */
10880 move[blocked].links = size;
10881 size=size+1;
10884 while (blocked != -1);
10886 return true;
10890 /* Worker function for `ADJUST_INSN_LENGTH'. */
10891 /* Modifies the length assigned to instruction INSN
10892 LEN is the initially computed length of the insn. */
10895 avr_adjust_insn_length (rtx_insn *insn, int len)
10897 rtx *op = recog_data.operand;
10899 /* As we pretend jump tables in .text, fix branch offsets crossing jump
10900 tables now. */
10902 if (JUMP_TABLE_DATA_P (insn))
10903 return 0;
10905 /* Some complex insns don't need length adjustment and therefore
10906 the length need not/must not be adjusted for these insns.
10907 It is easier to state this in an insn attribute "adjust_len" than
10908 to clutter up code here... */
10910 if (!NONDEBUG_INSN_P (insn) || recog_memoized (insn) == -1)
10912 return len;
10915 /* Read from insn attribute "adjust_len" if/how length is to be adjusted. */
10917 enum attr_adjust_len adjust_len = get_attr_adjust_len (insn);
10919 if (adjust_len == ADJUST_LEN_NO)
10921 /* Nothing to adjust: The length from attribute "length" is fine.
10922 This is the default. */
10924 return len;
10927 /* Extract insn's operands. */
10929 extract_constrain_insn_cached (insn);
10931 /* Dispatch to right function. */
10933 switch (adjust_len)
10935 case ADJUST_LEN_RELOAD_IN16: output_reload_inhi (op, op[2], &len); break;
10936 case ADJUST_LEN_RELOAD_IN24: avr_out_reload_inpsi (op, op[2], &len); break;
10937 case ADJUST_LEN_RELOAD_IN32: output_reload_insisf (op, op[2], &len); break;
10939 case ADJUST_LEN_OUT_BITOP: avr_out_bitop (insn, op, &len); break;
10940 case ADJUST_LEN_EXTR_NOT: avr_out_extr_not (insn, op, &len); break;
10941 case ADJUST_LEN_EXTR: avr_out_extr (insn, op, &len); break;
10942 case ADJUST_LEN_INSV: avr_out_insv (insn, op, &len); break;
10944 case ADJUST_LEN_PLUS: avr_out_plus (insn, op, &len); break;
10945 case ADJUST_LEN_ADDTO_SP: avr_out_addto_sp (op, &len); break;
10947 case ADJUST_LEN_MOV8: output_movqi (insn, op, &len); break;
10948 case ADJUST_LEN_MOV16: output_movhi (insn, op, &len); break;
10949 case ADJUST_LEN_MOV24: avr_out_movpsi (insn, op, &len); break;
10950 case ADJUST_LEN_MOV32: output_movsisf (insn, op, &len); break;
10951 case ADJUST_LEN_CPYMEM: avr_out_cpymem (insn, op, &len); break;
10952 case ADJUST_LEN_XLOAD: avr_out_xload (insn, op, &len); break;
10953 case ADJUST_LEN_SEXT: avr_out_sign_extend (insn, op, &len); break;
10955 case ADJUST_LEN_SFRACT: avr_out_fract (insn, op, true, &len); break;
10956 case ADJUST_LEN_UFRACT: avr_out_fract (insn, op, false, &len); break;
10957 case ADJUST_LEN_ROUND: avr_out_round (insn, op, &len); break;
10959 case ADJUST_LEN_TSTHI: avr_out_tsthi (insn, op, &len); break;
10960 case ADJUST_LEN_TSTPSI: avr_out_tstpsi (insn, op, &len); break;
10961 case ADJUST_LEN_TSTSI: avr_out_tstsi (insn, op, &len); break;
10962 case ADJUST_LEN_COMPARE: avr_out_compare (insn, op, &len); break;
10963 case ADJUST_LEN_COMPARE64: avr_out_compare64 (insn, op, &len); break;
10964 case ADJUST_LEN_CMP_UEXT: avr_out_cmp_ext (op, ZERO_EXTEND, &len); break;
10965 case ADJUST_LEN_CMP_SEXT: avr_out_cmp_ext (op, SIGN_EXTEND, &len); break;
10967 case ADJUST_LEN_LSHRQI: lshrqi3_out (insn, op, &len); break;
10968 case ADJUST_LEN_LSHRHI: lshrhi3_out (insn, op, &len); break;
10969 case ADJUST_LEN_LSHRSI: lshrsi3_out (insn, op, &len); break;
10971 case ADJUST_LEN_ASHRQI: ashrqi3_out (insn, op, &len); break;
10972 case ADJUST_LEN_ASHRHI: ashrhi3_out (insn, op, &len); break;
10973 case ADJUST_LEN_ASHRSI: ashrsi3_out (insn, op, &len); break;
10975 case ADJUST_LEN_ASHLQI: ashlqi3_out (insn, op, &len); break;
10976 case ADJUST_LEN_ASHLHI: ashlhi3_out (insn, op, &len); break;
10977 case ADJUST_LEN_ASHLSI: ashlsi3_out (insn, op, &len); break;
10979 case ADJUST_LEN_ASHLPSI: avr_out_ashlpsi3 (insn, op, &len); break;
10980 case ADJUST_LEN_ASHRPSI: avr_out_ashrpsi3 (insn, op, &len); break;
10981 case ADJUST_LEN_LSHRPSI: avr_out_lshrpsi3 (insn, op, &len); break;
10983 case ADJUST_LEN_CALL: len = AVR_HAVE_JMP_CALL ? 2 : 1; break;
10985 case ADJUST_LEN_INSERT_BITS: avr_out_insert_bits (op, &len); break;
10986 case ADJUST_LEN_ADD_SET_ZN: avr_out_plus_set_ZN (op, &len); break;
10988 case ADJUST_LEN_INSV_NOTBIT: avr_out_insert_notbit (insn, op, &len); break;
10990 default:
10991 gcc_unreachable();
10994 return len;
10997 /* Return nonzero if register REG dead after INSN. */
11000 reg_unused_after (rtx_insn *insn, rtx reg)
11002 return (dead_or_set_p (insn, reg)
11003 || (REG_P (reg) && _reg_unused_after (insn, reg, true)));
11006 /* A helper for the previous function.
11007 Return nonzero if REG is not used after INSN.
11008 We assume REG is a reload reg, and therefore does
11009 not live past labels. It may live past calls or jumps though. */
11011 bool
11012 _reg_unused_after (rtx_insn *insn, rtx reg, bool look_at_insn)
11014 if (look_at_insn)
11016 /* If the reg is set by this instruction, then it is safe for our
11017 case. Disregard the case where this is a store to memory, since
11018 we are checking a register used in the store address. */
11019 rtx set = single_set (insn);
11020 if (set && !MEM_P (SET_DEST (set))
11021 && reg_overlap_mentioned_p (reg, SET_DEST (set)))
11022 return 1;
11025 while ((insn = NEXT_INSN (insn)))
11027 rtx set;
11028 enum rtx_code code = GET_CODE (insn);
11030 #if 0
11031 /* If this is a label that existed before reload, then the register
11032 if dead here. However, if this is a label added by reorg, then
11033 the register may still be live here. We can't tell the difference,
11034 so we just ignore labels completely. */
11035 if (code == CODE_LABEL)
11036 return 1;
11037 /* else */
11038 #endif
11040 if (!INSN_P (insn))
11041 continue;
11043 if (code == JUMP_INSN)
11044 return 0;
11046 /* If this is a sequence, we must handle them all at once.
11047 We could have for instance a call that sets the target register,
11048 and an insn in a delay slot that uses the register. In this case,
11049 we must return 0. */
11050 else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
11052 rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
11053 int retval = 0;
11055 for (int i = 0; i < seq->len (); i++)
11057 rtx_insn *this_insn = seq->insn (i);
11058 rtx set = single_set (this_insn);
11060 if (CALL_P (this_insn))
11061 code = CALL_INSN;
11062 else if (JUMP_P (this_insn))
11064 if (INSN_ANNULLED_BRANCH_P (this_insn))
11065 return 0;
11066 code = JUMP_INSN;
11069 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
11070 return 0;
11071 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
11073 if (!MEM_P (SET_DEST (set)))
11074 retval = 1;
11075 else
11076 return 0;
11078 if (set == 0
11079 && reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
11080 return 0;
11082 if (retval == 1)
11083 return 1;
11084 else if (code == JUMP_INSN)
11085 return 0;
11088 if (code == CALL_INSN)
11090 rtx tem;
11091 for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
11092 if (GET_CODE (XEXP (tem, 0)) == USE
11093 && REG_P (XEXP (XEXP (tem, 0), 0))
11094 && reg_overlap_mentioned_p (reg, XEXP (XEXP (tem, 0), 0)))
11095 return 0;
11096 if (call_used_or_fixed_reg_p (REGNO (reg)))
11097 return 1;
11100 set = single_set (insn);
11102 if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
11103 return 0;
11104 if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
11105 return !MEM_P (SET_DEST (set));
11106 if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
11107 return 0;
11109 return 1;
11113 /* Implement `TARGET_ASM_INTEGER'. */
11114 /* Target hook for assembling integer objects. The AVR version needs
11115 special handling for references to certain labels. */
11117 static bool
11118 avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
11120 if (size == POINTER_SIZE / BITS_PER_UNIT && aligned_p
11121 && text_segment_operand (x, VOIDmode))
11123 fputs ("\t.word\tgs(", asm_out_file);
11124 output_addr_const (asm_out_file, x);
11125 fputs (")\n", asm_out_file);
11127 return true;
11129 else if (GET_MODE (x) == PSImode)
11131 /* This needs binutils 2.23+, see PR binutils/13503 */
11133 fputs ("\t.byte\tlo8(", asm_out_file);
11134 output_addr_const (asm_out_file, x);
11135 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
11137 fputs ("\t.byte\thi8(", asm_out_file);
11138 output_addr_const (asm_out_file, x);
11139 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
11141 fputs ("\t.byte\thh8(", asm_out_file);
11142 output_addr_const (asm_out_file, x);
11143 fputs (")" ASM_COMMENT_START "need binutils PR13503\n", asm_out_file);
11145 return true;
11147 else if (CONST_FIXED_P (x))
11149 /* varasm fails to handle big fixed modes that don't fit in hwi. */
11151 for (unsigned n = 0; n < size; n++)
11153 rtx xn = simplify_gen_subreg (QImode, x, GET_MODE (x), n);
11154 default_assemble_integer (xn, 1, aligned_p);
11157 return true;
11160 if (AVR_TINY
11161 && avr_address_tiny_pm_p (x))
11163 x = plus_constant (Pmode, x, avr_arch->flash_pm_offset);
11166 return default_assemble_integer (x, size, aligned_p);
11169 /* Implement `TARGET_CLASS_MAX_NREGS'. Reasons described in comments for
11170 avr_hard_regno_nregs. */
11172 static unsigned char
11173 avr_class_max_nregs (reg_class_t rclass, machine_mode mode)
11175 if (rclass == CC_REG && mode == CCmode)
11176 return 1;
11178 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
11182 /* Implement `TARGET_CLASS_LIKELY_SPILLED_P'. */
11183 /* Return value is nonzero if pseudos that have been
11184 assigned to registers of class CLASS would likely be spilled
11185 because registers of CLASS are needed for spill registers. */
11187 static bool
11188 avr_class_likely_spilled_p (reg_class_t c)
11190 return (c != ALL_REGS
11191 && (AVR_TINY ? 1 : c != ADDW_REGS));
11195 /* Valid attributes:
11196 progmem - Put data to program memory.
11197 signal - Make a function to be hardware interrupt.
11198 After function prologue interrupts remain disabled.
11199 interrupt - Make a function to be hardware interrupt. Before function
11200 prologue interrupts are enabled by means of SEI.
11201 naked - Don't generate function prologue/epilogue and RET
11202 instruction. */
11204 /* Handle a "progmem" attribute; arguments as in
11205 struct attribute_spec.handler. */
11207 static tree
11208 avr_handle_progmem_attribute (tree *node, tree name, tree args,
11209 int /*flags*/, bool *no_add_attrs)
11211 if (DECL_P (*node))
11213 if (TREE_CODE (*node) == TYPE_DECL)
11215 /* This is really a decl attribute, not a type attribute,
11216 but try to handle it for GCC 3.0 backwards compatibility. */
11218 tree type = TREE_TYPE (*node);
11219 tree attr = tree_cons (name, args, TYPE_ATTRIBUTES (type));
11220 tree newtype = build_type_attribute_variant (type, attr);
11222 TYPE_MAIN_VARIANT (newtype) = TYPE_MAIN_VARIANT (type);
11223 TREE_TYPE (*node) = newtype;
11224 *no_add_attrs = true;
11226 else if (TREE_STATIC (*node) || DECL_EXTERNAL (*node))
11228 *no_add_attrs = false;
11230 else
11232 warning (OPT_Wattributes, "%qE attribute ignored",
11233 name);
11234 *no_add_attrs = true;
11238 return NULL_TREE;
11241 /* Handle an attribute requiring a FUNCTION_DECL; arguments as in
11242 struct attribute_spec.handler. */
11244 static tree
11245 avr_handle_fndecl_attribute (tree *node, tree name, tree /*args*/,
11246 int /*flags*/, bool *no_add_attrs)
11248 if (TREE_CODE (*node) != FUNCTION_DECL)
11250 warning (OPT_Wattributes, "%qE attribute only applies to functions",
11251 name);
11252 *no_add_attrs = true;
11255 return NULL_TREE;
11258 static tree
11259 avr_handle_fntype_attribute (tree *node, tree name, tree /*args*/,
11260 int /*flags*/, bool *no_add_attrs)
11262 if (TREE_CODE (*node) != FUNCTION_TYPE)
11264 warning (OPT_Wattributes, "%qE attribute only applies to functions",
11265 name);
11266 *no_add_attrs = true;
11269 return NULL_TREE;
11272 static tree
11273 avr_handle_absdata_attribute (tree *node, tree name, tree /* args */,
11274 int /* flags */, bool *no_add)
11276 location_t loc = DECL_SOURCE_LOCATION (*node);
11278 if (AVR_TINY)
11280 if (TREE_CODE (*node) != VAR_DECL
11281 || (!TREE_STATIC (*node) && !DECL_EXTERNAL (*node)))
11283 warning_at (loc, OPT_Wattributes, "%qE attribute only applies to"
11284 " variables in static storage", name);
11285 *no_add = true;
11288 else
11290 warning_at (loc, OPT_Wattributes, "%qE attribute only supported"
11291 " for reduced Tiny cores", name);
11292 *no_add = true;
11295 return NULL_TREE;
11298 static tree
11299 avr_handle_addr_attribute (tree *node, tree name, tree args,
11300 int /*flags*/, bool *no_add)
11302 bool io_p = startswith (IDENTIFIER_POINTER (name), "io");
11303 HOST_WIDE_INT io_start = avr_arch->sfr_offset;
11304 HOST_WIDE_INT io_end = strcmp (IDENTIFIER_POINTER (name), "io_low") == 0
11305 ? io_start + 0x1f
11306 : io_start + 0x3f;
11307 location_t loc = DECL_SOURCE_LOCATION (*node);
11309 if (!VAR_P (*node))
11311 warning_at (loc, OPT_Wattributes, "%qE attribute only applies to "
11312 "variables", name);
11313 *no_add = true;
11314 return NULL_TREE;
11317 if (args != NULL_TREE)
11319 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11320 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11321 tree arg = TREE_VALUE (args);
11322 if (TREE_CODE (arg) != INTEGER_CST)
11324 warning_at (loc, OPT_Wattributes, "%qE attribute allows only an "
11325 "integer constant argument", name);
11326 *no_add = true;
11328 else if (io_p
11329 && (!tree_fits_shwi_p (arg)
11330 || ! IN_RANGE (TREE_INT_CST_LOW (arg), io_start, io_end)))
11332 warning_at (loc, OPT_Wattributes, "%qE attribute address out of range"
11333 " 0x%x%s0x%x", name, (int) io_start, "...", (int) io_end);
11334 *no_add = true;
11336 else
11338 tree attribs = DECL_ATTRIBUTES (*node);
11339 const char *names[] = { "io", "io_low", "address", NULL };
11340 for (const char **p = names; *p; p++)
11342 tree other = lookup_attribute (*p, attribs);
11343 if (other && TREE_VALUE (other))
11345 warning_at (loc, OPT_Wattributes,
11346 "both %s and %qE attribute provide address",
11347 *p, name);
11348 *no_add = true;
11349 break;
11355 if (*no_add == false && io_p && !TREE_THIS_VOLATILE (*node))
11356 warning_at (loc, OPT_Wattributes, "%qE attribute on non-volatile variable",
11357 name);
11359 // Optimizers must not draw any conclusions from "static int addr;" etc.
11360 // because the contents of `addr' are not given by its initializer but
11361 // by the contents at the address as specified by the attribute.
11362 if (VAR_P (*node) && ! *no_add)
11363 TREE_THIS_VOLATILE (*node) = 1;
11365 return NULL_TREE;
11369 avr_eval_addr_attrib (rtx x)
11371 if (SYMBOL_REF_P (x)
11372 && (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_ADDRESS))
11374 tree decl = SYMBOL_REF_DECL (x);
11375 tree attr = NULL_TREE;
11377 if (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_IO)
11379 attr = lookup_attribute ("io", DECL_ATTRIBUTES (decl));
11380 if (!attr || !TREE_VALUE (attr))
11381 attr = lookup_attribute ("io_low", DECL_ATTRIBUTES (decl));
11383 if (!attr || !TREE_VALUE (attr))
11384 attr = lookup_attribute ("address", DECL_ATTRIBUTES (decl));
11385 gcc_assert (attr && TREE_VALUE (attr) && TREE_VALUE (TREE_VALUE (attr)));
11386 return GEN_INT (TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attr))));
11388 return x;
11392 /* AVR attributes. */
11393 TARGET_GNU_ATTRIBUTES (avr_attribute_table,
11395 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
11396 affects_type_identity, handler, exclude } */
11397 { "progmem", 0, 0, false, false, false, false,
11398 avr_handle_progmem_attribute, NULL },
11399 { "signal", 0, 0, true, false, false, false,
11400 avr_handle_fndecl_attribute, NULL },
11401 { "interrupt", 0, 0, true, false, false, false,
11402 avr_handle_fndecl_attribute, NULL },
11403 { "no_gccisr", 0, 0, true, false, false, false,
11404 avr_handle_fndecl_attribute, NULL },
11405 { "naked", 0, 0, false, true, true, false,
11406 avr_handle_fntype_attribute, NULL },
11407 { "OS_task", 0, 0, false, true, true, false,
11408 avr_handle_fntype_attribute, NULL },
11409 { "OS_main", 0, 0, false, true, true, false,
11410 avr_handle_fntype_attribute, NULL },
11411 { "io", 0, 1, true, false, false, false,
11412 avr_handle_addr_attribute, NULL },
11413 { "io_low", 0, 1, true, false, false, false,
11414 avr_handle_addr_attribute, NULL },
11415 { "address", 1, 1, true, false, false, false,
11416 avr_handle_addr_attribute, NULL },
11417 { "absdata", 0, 0, true, false, false, false,
11418 avr_handle_absdata_attribute, NULL }
11422 /* Return true if we support address space AS for the architecture in effect
11423 and false, otherwise. If LOC is not UNKNOWN_LOCATION then also issue
11424 a respective error. */
11426 bool
11427 avr_addr_space_supported_p (addr_space_t as, location_t loc)
11429 if (AVR_TINY)
11431 if (loc != UNKNOWN_LOCATION)
11432 error_at (loc, "address spaces are not supported for reduced "
11433 "Tiny devices");
11434 return false;
11436 else if (avr_addrspace[as].segment >= avr_n_flash)
11438 if (loc != UNKNOWN_LOCATION)
11439 error_at (loc, "address space %qs not supported for devices with "
11440 "flash size up to %d KiB", avr_addrspace[as].name,
11441 64 * avr_n_flash);
11442 return false;
11445 return true;
11449 /* Implement `TARGET_ADDR_SPACE_DIAGNOSE_USAGE'. */
11451 static void
11452 avr_addr_space_diagnose_usage (addr_space_t as, location_t loc)
11454 (void) avr_addr_space_supported_p (as, loc);
11458 /* Implement `TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID'. Zero is a valid
11459 address in all address spaces. Even in ADDR_SPACE_FLASH1 etc..,
11460 a zero address is valid and means 0x<RAMPZ val>0000, where RAMPZ is
11461 set to the appropriate segment value. */
11463 static bool
11464 avr_addr_space_zero_address_valid (addr_space_t)
11466 return true;
11470 /* Look if DECL shall be placed in program memory space by
11471 means of attribute `progmem' or some address-space qualifier.
11472 Return non-zero if DECL is data that must end up in Flash and
11473 zero if the data lives in RAM (.bss, .data, .rodata, ...).
11475 Return 2 if DECL is located in 24-bit flash address-space
11476 Return 1 if DECL is located in 16-bit flash address-space
11477 Return -1 if attribute `progmem' occurs in DECL or ATTRIBUTES
11478 Return 0 otherwise */
11481 avr_progmem_p (tree decl, tree attributes)
11483 if (TREE_CODE (decl) != VAR_DECL)
11484 return 0;
11486 if (avr_decl_memx_p (decl))
11487 return 2;
11489 if (avr_decl_flash_p (decl))
11490 return 1;
11492 if (NULL_TREE
11493 != lookup_attribute ("progmem", attributes))
11494 return -1;
11496 tree a = decl;
11499 a = TREE_TYPE(a);
11500 while (TREE_CODE (a) == ARRAY_TYPE);
11502 if (a == error_mark_node)
11503 return 0;
11505 if (NULL_TREE != lookup_attribute ("progmem", TYPE_ATTRIBUTES (a)))
11506 return -1;
11508 return 0;
11512 /* Return true if DECL has attribute `absdata' set. This function should
11513 only be used for AVR_TINY. */
11515 static bool
11516 avr_decl_absdata_p (tree decl, tree attributes)
11518 return (VAR_P (decl)
11519 && NULL_TREE != lookup_attribute ("absdata", attributes));
11523 /* Scan type TYP for pointer references to address space ASn.
11524 Return ADDR_SPACE_GENERIC (i.e. 0) if all pointers targeting
11525 the AS are also declared to be CONST.
11526 Otherwise, return the respective address space, i.e. a value != 0. */
11528 static addr_space_t
11529 avr_nonconst_pointer_addrspace (tree typ)
11531 while (ARRAY_TYPE == TREE_CODE (typ))
11532 typ = TREE_TYPE (typ);
11534 if (POINTER_TYPE_P (typ))
11536 tree target = TREE_TYPE (typ);
11538 /* Pointer to function: Test the function's return type. */
11540 if (FUNCTION_TYPE == TREE_CODE (target))
11541 return avr_nonconst_pointer_addrspace (TREE_TYPE (target));
11543 /* "Ordinary" pointers... */
11545 while (TREE_CODE (target) == ARRAY_TYPE)
11546 target = TREE_TYPE (target);
11548 /* Pointers to non-generic address space must be const. */
11550 addr_space_t as = TYPE_ADDR_SPACE (target);
11552 if (!ADDR_SPACE_GENERIC_P (as)
11553 && !TYPE_READONLY (target)
11554 && avr_addr_space_supported_p (as))
11556 return as;
11559 /* Scan pointer's target type. */
11561 return avr_nonconst_pointer_addrspace (target);
11564 return ADDR_SPACE_GENERIC;
11568 /* Sanity check NODE so that all pointers targeting non-generic address spaces
11569 go along with CONST qualifier. Writing to these address spaces should
11570 be detected and complained about as early as possible. */
11572 static bool
11573 avr_pgm_check_var_decl (tree node)
11575 const char *reason = NULL;
11577 addr_space_t as = ADDR_SPACE_GENERIC;
11579 gcc_assert (as == 0);
11581 if (avr_log.progmem)
11582 avr_edump ("%?: %t\n", node);
11584 switch (TREE_CODE (node))
11586 default:
11587 break;
11589 case VAR_DECL:
11590 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
11591 reason = _("variable");
11592 break;
11594 case PARM_DECL:
11595 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
11596 reason = _("function parameter");
11597 break;
11599 case FIELD_DECL:
11600 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (node)), as)
11601 reason = _("structure field");
11602 break;
11604 case FUNCTION_DECL:
11605 if (as = avr_nonconst_pointer_addrspace (TREE_TYPE (TREE_TYPE (node))),
11607 reason = _("return type of function");
11608 break;
11610 case POINTER_TYPE:
11611 if (as = avr_nonconst_pointer_addrspace (node), as)
11612 reason = _("pointer");
11613 break;
11616 if (reason)
11618 if (TYPE_P (node))
11619 error ("pointer targeting address space %qs must be const in %qT",
11620 avr_addrspace[as].name, node);
11621 else
11622 error ("pointer targeting address space %qs must be const"
11623 " in %s %q+D",
11624 avr_addrspace[as].name, reason, node);
11627 return reason == NULL;
11631 /* Implement `TARGET_INSERT_ATTRIBUTES'. */
11633 static void
11634 avr_insert_attributes (tree node, tree *attributes)
11636 if (VAR_P (node)
11637 && ! TREE_STATIC (node)
11638 && ! DECL_EXTERNAL (node))
11640 const char *names[] = { "io", "io_low", "address", NULL };
11641 for (const char **p = names; *p; ++p)
11642 if (lookup_attribute (*p, *attributes))
11643 error ("variable %q+D with attribute %qs must be located in "
11644 "static storage", node, *p);
11647 avr_pgm_check_var_decl (node);
11649 if (TARGET_MAIN_IS_OS_TASK
11650 && TREE_CODE (node) == FUNCTION_DECL
11651 && MAIN_NAME_P (DECL_NAME (node))
11652 // FIXME: We'd like to also test `flag_hosted' which is only
11653 // available in the C-ish fronts, hence no such test for now.
11654 // Instead, we test the return type of "main" which is not exactly
11655 // the same but good enough.
11656 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (node)))
11657 && NULL == lookup_attribute ("OS_task", *attributes))
11659 *attributes = tree_cons (get_identifier ("OS_task"),
11660 NULL, *attributes);
11663 /* Add the section attribute if the variable is in progmem. */
11665 if (VAR_P (node)
11666 && (TREE_STATIC (node) || DECL_EXTERNAL (node))
11667 && avr_progmem_p (node, *attributes))
11669 tree node0 = node;
11671 /* For C++, we have to peel arrays in order to get correct
11672 determination of readonlyness. */
11675 node0 = TREE_TYPE (node0);
11676 while (TREE_CODE (node0) == ARRAY_TYPE);
11678 if (error_mark_node == node0)
11679 return;
11681 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (node));
11683 if (!TYPE_READONLY (node0)
11684 && !TREE_READONLY (node))
11686 const char *reason = "__attribute__((progmem))";
11688 if (!ADDR_SPACE_GENERIC_P (as))
11689 reason = avr_addrspace[as].name;
11691 if (avr_log.progmem)
11692 avr_edump ("\n%?: %t\n%t\n", node, node0);
11694 error ("variable %q+D must be const in order to be put into"
11695 " read-only section by means of %qs", node, reason);
11700 #ifdef HAVE_LD_AVR_AVRXMEGA2_FLMAP
11701 static const bool have_avrxmega2_flmap = true;
11702 #else
11703 static const bool have_avrxmega2_flmap = false;
11704 #endif
11706 #ifdef HAVE_LD_AVR_AVRXMEGA4_FLMAP
11707 static const bool have_avrxmega4_flmap = true;
11708 #else
11709 static const bool have_avrxmega4_flmap = false;
11710 #endif
11712 #ifdef HAVE_LD_AVR_AVRXMEGA3_RODATA_IN_FLASH
11713 static const bool have_avrxmega3_rodata_in_flash = true;
11714 #else
11715 static const bool have_avrxmega3_rodata_in_flash = false;
11716 #endif
11719 static bool
11720 avr_rodata_in_flash_p ()
11722 switch (avr_arch_index)
11724 default:
11725 break;
11727 case ARCH_AVRTINY:
11728 return true;
11730 case ARCH_AVRXMEGA3:
11731 return have_avrxmega3_rodata_in_flash;
11733 case ARCH_AVRXMEGA2:
11734 return avr_flmap && have_avrxmega2_flmap && avr_rodata_in_ram != 1;
11736 case ARCH_AVRXMEGA4:
11737 return avr_flmap && have_avrxmega4_flmap && avr_rodata_in_ram != 1;
11740 return false;
11744 /* Implement `ASM_OUTPUT_ALIGNED_DECL_LOCAL'. */
11745 /* Implement `ASM_OUTPUT_ALIGNED_DECL_COMMON'. */
11746 /* Track need of __do_clear_bss. */
11748 void
11749 avr_asm_output_aligned_decl_common (FILE *stream, tree /* decl */,
11750 const char *name,
11751 unsigned HOST_WIDE_INT size,
11752 unsigned int align, bool local_p)
11754 /* __gnu_lto_slim is just a marker for the linker injected by toplev.cc.
11755 There is no need to trigger __do_clear_bss code for them. */
11757 if (!startswith (name, "__gnu_lto"))
11758 avr_need_clear_bss_p = true;
11760 if (local_p)
11761 ASM_OUTPUT_ALIGNED_LOCAL (stream, name, size, align);
11762 else
11763 ASM_OUTPUT_ALIGNED_COMMON (stream, name, size, align);
11767 /* Implement `ASM_OUTPUT_ALIGNED_BSS'. */
11769 void
11770 avr_asm_asm_output_aligned_bss (FILE *file, tree decl, const char *name,
11771 unsigned HOST_WIDE_INT size, int align,
11772 void (*default_func)
11773 (FILE *, tree, const char *,
11774 unsigned HOST_WIDE_INT, int))
11776 if (!startswith (name, "__gnu_lto"))
11777 avr_need_clear_bss_p = true;
11779 default_func (file, decl, name, size, align);
11783 /* Unnamed section callback for data_section
11784 to track need of __do_copy_data. */
11786 static void
11787 avr_output_data_section_asm_op (const char *data)
11789 avr_need_copy_data_p = true;
11791 /* Dispatch to default. */
11792 output_section_asm_op (data);
11796 /* Unnamed section callback for bss_section
11797 to track need of __do_clear_bss. */
11799 static void
11800 avr_output_bss_section_asm_op (const char *data)
11802 avr_need_clear_bss_p = true;
11804 /* Dispatch to default. */
11805 output_section_asm_op (data);
11809 /* Unnamed section callback for progmem*.data sections. */
11811 static void
11812 avr_output_progmem_section_asm_op (const char *data)
11814 fprintf (asm_out_file, "\t.section\t%s,\"a\",@progbits\n", data);
11818 /* A noswitch section callback to output symbol definitions for
11819 attributes "io", "io_low" and "address". */
11821 static bool
11822 avr_output_addr_attrib (tree decl, const char *name,
11823 unsigned HOST_WIDE_INT /* size */,
11824 unsigned HOST_WIDE_INT /* align */)
11826 gcc_assert (DECL_RTL_SET_P (decl));
11828 FILE *stream = asm_out_file;
11829 bool local_p = ! DECL_WEAK (decl) && ! TREE_PUBLIC (decl);
11830 rtx symbol, mem = DECL_RTL (decl);
11832 if (mem != NULL_RTX && MEM_P (mem)
11833 && SYMBOL_REF_P ((symbol = XEXP (mem, 0)))
11834 && (SYMBOL_REF_FLAGS (symbol) & (SYMBOL_FLAG_IO | SYMBOL_FLAG_ADDRESS)))
11836 if (! local_p)
11838 fprintf (stream, "\t%s\t", DECL_WEAK (decl) ? ".weak" : ".globl");
11839 assemble_name (stream, name);
11840 fprintf (stream, "\n");
11843 if (SYMBOL_REF_FLAGS (symbol) & SYMBOL_FLAG_ADDRESS)
11845 assemble_name (stream, name);
11846 fprintf (stream, " = %ld\n",
11847 (long) INTVAL (avr_eval_addr_attrib (symbol)));
11849 else if (local_p)
11851 const char *names[] = { "io", "io_low", "address", NULL };
11852 for (const char **p = names; *p; ++p)
11853 if (lookup_attribute (*p, DECL_ATTRIBUTES (decl)))
11855 error ("static attribute %qs declaration for %q+D needs an "
11856 "address", *p, decl);
11857 break;
11861 return true;
11864 gcc_unreachable();
11866 return false;
11870 /* Implement `TARGET_ASM_INIT_SECTIONS'. */
11872 static void
11873 avr_asm_init_sections (void)
11875 /* Override section callbacks to keep track of `avr_need_clear_bss_p',
11876 `avr_need_copy_data_p' and `avr_has_rodata_p'.
11877 Track also .rodata for the case when .rodata is located in RAM. */
11879 if (! avr_rodata_in_flash_p ())
11880 readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
11881 data_section->unnamed.callback = avr_output_data_section_asm_op;
11882 bss_section->unnamed.callback = avr_output_bss_section_asm_op;
11883 tls_comm_section->noswitch.callback = avr_output_addr_attrib;
11887 /* Implement `TARGET_ASM_NAMED_SECTION'. */
11888 /* Track need of __do_clear_bss, __do_copy_data for named sections. */
11890 static void
11891 avr_asm_named_section (const char *name, unsigned int flags, tree decl)
11893 if (flags & AVR_SECTION_PROGMEM
11894 // Only use section .progmem*.data if there is no attribute section.
11895 && ! (decl
11896 && DECL_SECTION_NAME (decl)
11897 && symtab_node::get (decl)
11898 && ! symtab_node::get (decl)->implicit_section))
11900 addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
11901 const char *old_prefix = ".rodata";
11902 const char *new_prefix = avr_addrspace[as].section_name;
11904 if (startswith (name, old_prefix))
11906 const char *sname = ACONCAT ((new_prefix,
11907 name + strlen (old_prefix), NULL));
11908 default_elf_asm_named_section (sname, flags, decl);
11909 return;
11912 default_elf_asm_named_section (new_prefix, flags, decl);
11913 return;
11916 if (!avr_need_copy_data_p)
11917 avr_need_copy_data_p = (startswith (name, ".data")
11918 || startswith (name, ".gnu.linkonce.d"));
11920 if (!avr_has_rodata_p)
11921 avr_has_rodata_p = (startswith (name, ".rodata")
11922 || startswith (name, ".gnu.linkonce.r"));
11924 if (!avr_need_clear_bss_p)
11925 avr_need_clear_bss_p = startswith (name, ".bss");
11927 default_elf_asm_named_section (name, flags, decl);
11931 /* Implement `TARGET_SECTION_TYPE_FLAGS'. */
11933 static unsigned int
11934 avr_section_type_flags (tree decl, const char *name, int reloc)
11936 unsigned int flags = default_section_type_flags (decl, name, reloc);
11938 if (startswith (name, ".noinit"))
11940 if (decl && VAR_P (decl)
11941 && DECL_INITIAL (decl) == NULL_TREE)
11942 flags |= SECTION_BSS; /* @nobits */
11943 else
11944 warning (0, "only uninitialized variables can be placed in the "
11945 "%<.noinit%> section");
11948 if (decl && DECL_P (decl)
11949 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
11951 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
11953 /* Attribute progmem puts data in generic address space.
11954 Set section flags as if it was in __flash to get the right
11955 section prefix in the remainder. */
11957 if (ADDR_SPACE_GENERIC_P (as))
11958 as = ADDR_SPACE_FLASH;
11960 flags |= as * SECTION_MACH_DEP;
11961 flags &= ~SECTION_WRITE;
11962 flags &= ~SECTION_BSS;
11963 flags &= ~SECTION_NOTYPE;
11966 return flags;
11970 /* A helper for the next function. NODE is a decl that is associated with
11971 a symbol. Return TRUE if the respective object may be accessed by LDS.
11972 There might still be other reasons for why LDS is not appropriate.
11973 This function is only appropriate for AVR_TINY. */
11975 static bool
11976 avr_decl_maybe_lds_p (tree node)
11978 if (!node
11979 || TREE_CODE (node) != VAR_DECL
11980 || DECL_SECTION_NAME (node) != NULL)
11981 return false;
11983 /* Don't use LDS for objects that go to .rodata. The current default
11984 linker description file still locates .rodata in RAM, but this is not
11985 a must. A better linker script would just keep .rodata in flash and
11986 add an offset of 0x4000 to the VMA. Hence avoid LDS for such data. */
11988 if (TREE_READONLY (node))
11989 return false;
11991 // C++ requires peeling arrays.
11994 node = TREE_TYPE (node);
11995 while (ARRAY_TYPE == TREE_CODE (node));
11997 return (node != error_mark_node
11998 && !TYPE_READONLY (node));
12002 /* Implement `TARGET_ENCODE_SECTION_INFO'. */
12004 static void
12005 avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
12007 tree addr_attr = NULL_TREE;
12009 /* In avr_handle_progmem_attribute, DECL_INITIAL is not yet
12010 readily available, see PR34734. So we postpone the warning
12011 about uninitialized data in program memory section until here. */
12013 if (new_decl_p
12014 && decl && DECL_P (decl)
12015 && !DECL_EXTERNAL (decl)
12016 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
12018 if (!TREE_READONLY (decl))
12020 // This might happen with C++ if stuff needs constructing.
12021 error ("variable %q+D with dynamic initialization put "
12022 "into program memory area", decl);
12024 else if (NULL_TREE == DECL_INITIAL (decl))
12026 // Don't warn for (implicit) aliases like in PR80462.
12027 tree asmname = DECL_ASSEMBLER_NAME (decl);
12028 varpool_node *node = varpool_node::get_for_asmname (asmname);
12029 bool alias_p = node && node->alias;
12031 if (!alias_p)
12032 warning (OPT_Wuninitialized, "uninitialized variable %q+D put "
12033 "into program memory area", decl);
12037 default_encode_section_info (decl, rtl, new_decl_p);
12039 if (decl && DECL_P (decl)
12040 && TREE_CODE (decl) != FUNCTION_DECL
12041 && MEM_P (rtl)
12042 && SYMBOL_REF_P (XEXP (rtl, 0)))
12044 rtx sym = XEXP (rtl, 0);
12045 tree type = TREE_TYPE (decl);
12046 tree attr = DECL_ATTRIBUTES (decl);
12047 if (type == error_mark_node)
12048 return;
12050 addr_space_t as = TYPE_ADDR_SPACE (type);
12052 /* PSTR strings are in generic space but located in flash:
12053 patch address space. */
12055 if (!AVR_TINY && avr_progmem_p (decl, attr) == -1)
12056 as = ADDR_SPACE_FLASH;
12058 AVR_SYMBOL_SET_ADDR_SPACE (sym, as);
12060 tree io_low_attr = lookup_attribute ("io_low", attr);
12061 tree io_attr = lookup_attribute ("io", attr);
12062 tree address_attr = lookup_attribute ("address", attr);
12064 if (io_low_attr
12065 && TREE_VALUE (io_low_attr) && TREE_VALUE (TREE_VALUE (io_low_attr)))
12066 addr_attr = io_low_attr;
12067 else if (io_attr
12068 && TREE_VALUE (io_attr) && TREE_VALUE (TREE_VALUE (io_attr)))
12069 addr_attr = io_attr;
12070 else
12071 addr_attr = address_attr;
12073 if (io_low_attr
12074 || (io_attr && addr_attr
12075 && low_io_address_operand
12076 (GEN_INT (TREE_INT_CST_LOW
12077 (TREE_VALUE (TREE_VALUE (addr_attr)))), QImode)))
12078 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO_LOW;
12079 if (io_attr || io_low_attr)
12080 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_IO;
12081 /* If we have an (io) address attribute specification, but the variable
12082 is external, treat the address as only a tentative definition
12083 to be used to determine if an io port is in the lower range, but
12084 don't use the exact value for constant propagation. */
12085 if (addr_attr && !DECL_EXTERNAL (decl))
12086 SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_ADDRESS;
12088 if (io_attr || io_low_attr || address_attr)
12090 if (DECL_INITIAL (decl))
12092 /* Initializers are not yet parsed in TARGET_INSERT_ATTRIBUTES,
12093 hence deny initializers now. The values of symbols with an
12094 address attribute are determined by the attribute, not by
12095 some initializer. */
12097 error ("variable %q+D with attribute %qs must not have an "
12098 "initializer", decl,
12099 io_low_attr ? "io_low" : io_attr ? "io" : "address");
12101 else
12103 /* PR112952: The only way to output a variable declaration in a
12104 custom manner is by means of a noswitch section callback.
12105 There are only three noswitch sections: comm_section,
12106 lcomm_section and tls_comm_section. And there is no way to
12107 wire a custom noswitch section to a decl. As lcomm_section
12108 is bypassed with -fdata-sections -fno-common, there is no
12109 other way than making use of tls_comm_section. As we are
12110 using that section anyway, also use it in the public case. */
12112 DECL_COMMON (decl) = 1;
12113 set_decl_section_name (decl, (const char *) nullptr);
12114 set_decl_tls_model (decl, (tls_model) 2);
12119 if (AVR_TINY
12120 && decl
12121 && VAR_P (decl)
12122 && MEM_P (rtl)
12123 && SYMBOL_REF_P (XEXP (rtl, 0)))
12125 rtx sym = XEXP (rtl, 0);
12126 bool progmem_p = avr_progmem_p (decl, DECL_ATTRIBUTES (decl)) == -1;
12128 if (progmem_p)
12130 // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset).
12131 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
12134 if (avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl))
12135 || (TARGET_ABSDATA
12136 && !progmem_p
12137 && !addr_attr
12138 && avr_decl_maybe_lds_p (decl))
12139 || (addr_attr
12140 // If addr_attr is non-null, it has an argument. Peek into it.
12141 && TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (addr_attr))) < 0xc0))
12143 // May be accessed by LDS / STS.
12144 SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_ABSDATA;
12147 if (progmem_p
12148 && avr_decl_absdata_p (decl, DECL_ATTRIBUTES (decl)))
12150 error ("%q+D has incompatible attributes %qs and %qs",
12151 decl, "progmem", "absdata");
12157 /* Implement `TARGET_ASM_SELECT_SECTION' */
12159 static section *
12160 avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align)
12162 section *sect = default_elf_select_section (decl, reloc, align);
12164 if (decl && DECL_P (decl)
12165 && avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
12167 addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
12169 /* __progmem__ goes in generic space but shall be allocated to
12170 .progmem.data */
12172 if (ADDR_SPACE_GENERIC_P (as))
12173 as = ADDR_SPACE_FLASH;
12175 if (sect->common.flags & SECTION_NAMED)
12177 const char *name = sect->named.name;
12178 const char *old_prefix = ".rodata";
12179 const char *new_prefix = avr_addrspace[as].section_name;
12181 if (startswith (name, old_prefix))
12183 const char *sname = ACONCAT ((new_prefix,
12184 name + strlen (old_prefix), NULL));
12185 return get_section (sname,
12186 sect->common.flags & ~SECTION_DECLARED,
12187 sect->named.decl);
12191 if (!progmem_section[as])
12193 progmem_section[as]
12194 = get_unnamed_section (0, avr_output_progmem_section_asm_op,
12195 avr_addrspace[as].section_name);
12198 return progmem_section[as];
12201 return sect;
12204 /* Implement `TARGET_ASM_FILE_START'. */
12205 /* Outputs some text at the start of each assembler file. */
12207 static void
12208 avr_file_start (void)
12210 int sfr_offset = avr_arch->sfr_offset;
12212 if (avr_arch->asm_only)
12213 error ("architecture %qs supported for assembler only", avr_mmcu);
12215 default_file_start ();
12217 /* Print I/O addresses of some SFRs used with IN and OUT. */
12219 if (AVR_HAVE_SPH)
12220 fprintf (asm_out_file, "__SP_H__ = 0x%02x\n", avr_addr.sp_h - sfr_offset);
12222 fprintf (asm_out_file, "__SP_L__ = 0x%02x\n", avr_addr.sp_l - sfr_offset);
12223 fprintf (asm_out_file, "__SREG__ = 0x%02x\n", avr_addr.sreg - sfr_offset);
12224 if (AVR_HAVE_RAMPZ)
12225 fprintf (asm_out_file, "__RAMPZ__ = 0x%02x\n", avr_addr.rampz - sfr_offset);
12226 if (AVR_HAVE_RAMPY)
12227 fprintf (asm_out_file, "__RAMPY__ = 0x%02x\n", avr_addr.rampy - sfr_offset);
12228 if (AVR_HAVE_RAMPX)
12229 fprintf (asm_out_file, "__RAMPX__ = 0x%02x\n", avr_addr.rampx - sfr_offset);
12230 if (AVR_HAVE_RAMPD)
12231 fprintf (asm_out_file, "__RAMPD__ = 0x%02x\n", avr_addr.rampd - sfr_offset);
12232 if (AVR_XMEGA || AVR_TINY)
12233 fprintf (asm_out_file, "__CCP__ = 0x%02x\n", avr_addr.ccp - sfr_offset);
12234 fprintf (asm_out_file, "__tmp_reg__ = %d\n", AVR_TMP_REGNO);
12235 fprintf (asm_out_file, "__zero_reg__ = %d\n", AVR_ZERO_REGNO);
12239 /* Implement `TARGET_ASM_FILE_END'. */
12240 /* Outputs to the stdio stream FILE some
12241 appropriate text to go at the end of an assembler file. */
12243 static void
12244 avr_file_end (void)
12246 /* Output these only if there is anything in the
12247 .data* / .rodata* / .gnu.linkonce.* resp. .bss* or COMMON
12248 input section(s) - some code size can be saved by not
12249 linking in the initialization code from libgcc if resp.
12250 sections are empty, see PR18145. */
12252 if (avr_need_copy_data_p
12253 || (avr_has_rodata_p && ! avr_rodata_in_flash_p ()))
12254 fputs (".global __do_copy_data\n", asm_out_file);
12256 if (avr_need_clear_bss_p)
12257 fputs (".global __do_clear_bss\n", asm_out_file);
12261 /* Worker function for `ADJUST_REG_ALLOC_ORDER'. */
12262 /* Choose the order in which to allocate hard registers for
12263 pseudo-registers local to a basic block.
12265 Store the desired register order in the array `reg_alloc_order'.
12266 Element 0 should be the register to allocate first; element 1, the
12267 next register; and so on. */
12269 void
12270 avr_adjust_reg_alloc_order (void)
12272 static const int order_0[] =
12274 24, 25,
12275 18, 19, 20, 21, 22, 23,
12276 30, 31,
12277 26, 27, 28, 29,
12278 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
12279 0, 1,
12280 32, 33, 34, 35
12282 static const int tiny_order_0[] = {
12283 20, 21,
12284 22, 23,
12285 24, 25,
12286 30, 31,
12287 26, 27,
12288 28, 29,
12289 19, 18,
12290 16, 17,
12291 32, 33, 34, 35,
12292 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
12294 static const int order_1[] =
12296 18, 19, 20, 21, 22, 23, 24, 25,
12297 30, 31,
12298 26, 27, 28, 29,
12299 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
12300 0, 1,
12301 32, 33, 34, 35
12303 static const int tiny_order_1[] = {
12304 22, 23,
12305 24, 25,
12306 30, 31,
12307 26, 27,
12308 28, 29,
12309 21, 20, 19, 18,
12310 16, 17,
12311 32, 33, 34, 35,
12312 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
12314 static const int order_2[] =
12316 25, 24, 23, 22, 21, 20, 19, 18,
12317 30, 31,
12318 26, 27, 28, 29,
12319 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2,
12320 1, 0,
12321 32, 33, 34, 35
12324 /* Select specific register allocation order.
12325 Tiny Core (ATtiny4/5/9/10/20/40) devices have only 16 registers,
12326 so different allocation order should be used. */
12328 const int *order = (TARGET_ORDER_1 ? (AVR_TINY ? tiny_order_1 : order_1)
12329 : TARGET_ORDER_2 ? (AVR_TINY ? tiny_order_0 : order_2)
12330 : (AVR_TINY ? tiny_order_0 : order_0));
12332 for (size_t i = 0; i < ARRAY_SIZE (order_0); ++i)
12333 reg_alloc_order[i] = order[i];
12337 /* Implement `TARGET_REGISTER_MOVE_COST' */
12339 static int
12340 avr_register_move_cost (machine_mode /*mode*/, reg_class_t from, reg_class_t to)
12342 return (from == STACK_REG ? 6
12343 : to == STACK_REG ? 12
12344 : 2);
12348 /* Implement `TARGET_MEMORY_MOVE_COST' */
12350 static int
12351 avr_memory_move_cost (machine_mode mode, reg_class_t /*rclass*/, bool /*in*/)
12353 return (mode == QImode ? 2
12354 : mode == HImode ? 4
12355 : mode == SImode ? 8
12356 : mode == SFmode ? 8
12357 : 16);
12361 /* Cost for mul highpart. X is a LSHIFTRT, i.e. the outer TRUNCATE is
12362 already stripped off. */
12364 static int
12365 avr_mul_highpart_cost (rtx x, int)
12367 if (AVR_HAVE_MUL
12368 && LSHIFTRT == GET_CODE (x)
12369 && MULT == GET_CODE (XEXP (x, 0))
12370 && CONST_INT_P (XEXP (x, 1)))
12372 // This is the wider mode.
12373 machine_mode mode = GET_MODE (x);
12375 // The middle-end might still have PR81444, i.e. it is calling the cost
12376 // functions with strange modes. Fix this now by also considering
12377 // PSImode (should actually be SImode instead).
12378 if (HImode == mode || PSImode == mode || SImode == mode)
12380 return COSTS_N_INSNS (2);
12384 return 10000;
12388 /* Return the expected cost of a conditional branch like
12389 (set (pc)
12390 (if_then_else (X)
12391 (label_ref *)
12392 (pc)))
12393 where X is some comparison operator. */
12395 static int
12396 avr_cbranch_cost (rtx x)
12398 bool difficult_p = difficult_comparison_operator (x, VOIDmode);
12400 if (reload_completed)
12402 // After reload, we basically just have plain branches.
12403 return COSTS_N_INSNS (1 + difficult_p);
12406 rtx xreg = XEXP (x, 0);
12407 rtx xval = XEXP (x, 1);
12408 machine_mode mode = GET_MODE (xreg);
12409 if (mode == VOIDmode)
12410 mode = GET_MODE (xval);
12411 int size = GET_MODE_SIZE (mode);
12413 if (GET_CODE (xreg) == ZERO_EXTEND
12414 || GET_CODE (xval) == ZERO_EXTEND)
12416 // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = zero_extend.
12417 return COSTS_N_INSNS (size + 1);
12420 if (GET_CODE (xreg) == SIGN_EXTEND
12421 || GET_CODE (xval) == SIGN_EXTEND)
12423 // *cbranch<HISI:mode>.<code><QIPSI:mode>.0/1, code = sign_extend.
12424 // Make it a bit cheaper than it actually is (less reg pressure).
12425 return COSTS_N_INSNS (size + 1 + 1);
12428 if (GET_CODE (xreg) == ZERO_EXTRACT
12429 && XEXP (xreg, 1) == const1_rtx)
12431 // Branch on a single bit, with an additional edge due to less
12432 // register pressure.
12433 return (int) COSTS_N_INSNS (1.5);
12436 bool reg_p = register_operand (xreg, mode);
12437 bool reg_or_0_p = reg_or_0_operand (xval, mode);
12439 return COSTS_N_INSNS (size
12440 // For the branch
12441 + 1 + difficult_p
12442 // Combine might propagate constants other than zero
12443 // into the 2nd operand. Make that more expensive.
12444 + 1 * (!reg_p || !reg_or_0_p));
12448 /* Mutually recursive subroutine of avr_rtx_cost for calculating the
12449 cost of an RTX operand given its context. X is the rtx of the
12450 operand, MODE is its mode, and OUTER is the rtx_code of this
12451 operand's parent operator. */
12453 static int
12454 avr_operand_rtx_cost (rtx x, machine_mode mode, enum rtx_code outer,
12455 int opno, bool speed)
12457 enum rtx_code code = GET_CODE (x);
12459 switch (code)
12461 case REG:
12462 case SUBREG:
12463 return 0;
12465 case CONST_INT:
12466 case CONST_FIXED:
12467 case CONST_DOUBLE:
12468 return COSTS_N_INSNS (GET_MODE_SIZE (mode));
12470 default:
12471 break;
12474 int total = 0;
12475 avr_rtx_costs (x, mode, outer, opno, &total, speed);
12476 return total;
12479 /* Worker function for AVR backend's rtx_cost function.
12480 X is rtx expression whose cost is to be calculated.
12481 Return true if the complete cost has been computed.
12482 Return false if subexpressions should be scanned.
12483 In either case, *TOTAL contains the cost result. */
12485 static bool
12486 avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code,
12487 int /*opno*/, int *total, bool speed)
12489 enum rtx_code code = GET_CODE (x);
12490 HOST_WIDE_INT val;
12492 switch (code)
12494 case CONST_INT:
12495 case CONST_FIXED:
12496 case CONST_DOUBLE:
12497 case SYMBOL_REF:
12498 case CONST:
12499 case LABEL_REF:
12500 /* Immediate constants are as cheap as registers. */
12501 *total = 0;
12502 return true;
12504 case MEM:
12505 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12506 return true;
12508 case NEG:
12509 switch (mode)
12511 case E_QImode:
12512 case E_SFmode:
12513 *total = COSTS_N_INSNS (1);
12514 break;
12516 case E_HImode:
12517 case E_PSImode:
12518 case E_SImode:
12519 *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1);
12520 break;
12522 default:
12523 return false;
12525 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12526 return true;
12528 case ABS:
12529 switch (mode)
12531 case E_QImode:
12532 case E_SFmode:
12533 *total = COSTS_N_INSNS (1);
12534 break;
12536 default:
12537 return false;
12539 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12540 return true;
12542 case NOT:
12543 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12544 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12545 return true;
12547 case ZERO_EXTEND:
12548 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)
12549 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
12550 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
12551 code, 0, speed);
12552 return true;
12554 case SIGN_EXTEND:
12555 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2
12556 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0))));
12557 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
12558 code, 0, speed);
12559 return true;
12561 case PLUS:
12562 // uint16_t += 2 * uint8_t;
12563 if (mode == HImode
12564 && GET_CODE (XEXP (x, 0)) == ASHIFT
12565 && REG_P (XEXP (x, 1))
12566 && XEXP (XEXP (x, 0), 1) == const1_rtx
12567 && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTEND)
12569 *total = COSTS_N_INSNS (4);
12570 return true;
12573 // *usum_widenqihi
12574 if (mode == HImode
12575 && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
12576 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
12578 *total = COSTS_N_INSNS (3);
12579 return true;
12582 if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
12583 && REG_P (XEXP (x, 1)))
12585 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12586 return true;
12588 if (REG_P (XEXP (x, 0))
12589 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
12591 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12592 return true;
12595 switch (mode)
12597 case E_QImode:
12598 if (AVR_HAVE_MUL
12599 && MULT == GET_CODE (XEXP (x, 0))
12600 && register_operand (XEXP (x, 1), QImode))
12602 /* multiply-add */
12603 *total = COSTS_N_INSNS (speed ? 4 : 3);
12604 /* multiply-add with constant: will be split and load constant. */
12605 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
12606 *total = COSTS_N_INSNS (1) + *total;
12607 return true;
12609 *total = COSTS_N_INSNS (1);
12610 if (!CONST_INT_P (XEXP (x, 1)))
12611 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
12612 break;
12614 case E_HImode:
12615 if (AVR_HAVE_MUL
12616 && (MULT == GET_CODE (XEXP (x, 0))
12617 || ASHIFT == GET_CODE (XEXP (x, 0)))
12618 && register_operand (XEXP (x, 1), HImode)
12619 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))
12620 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 0), 0))))
12622 /* multiply-add */
12623 *total = COSTS_N_INSNS (speed ? 5 : 4);
12624 /* multiply-add with constant: will be split and load constant. */
12625 if (CONST_INT_P (XEXP (XEXP (x, 0), 1)))
12626 *total = COSTS_N_INSNS (1) + *total;
12627 return true;
12629 if (!CONST_INT_P (XEXP (x, 1)))
12631 *total = COSTS_N_INSNS (2);
12632 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
12633 speed);
12635 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
12636 *total = COSTS_N_INSNS (1);
12637 else
12638 *total = COSTS_N_INSNS (2);
12639 break;
12641 case E_PSImode:
12642 if (!CONST_INT_P (XEXP (x, 1)))
12644 *total = COSTS_N_INSNS (3);
12645 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
12646 speed);
12648 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
12649 *total = COSTS_N_INSNS (2);
12650 else
12651 *total = COSTS_N_INSNS (3);
12652 break;
12654 case E_SImode:
12655 if (!CONST_INT_P (XEXP (x, 1)))
12657 *total = COSTS_N_INSNS (4);
12658 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
12659 speed);
12661 else if (IN_RANGE (INTVAL (XEXP (x, 1)), -63, 63))
12662 *total = COSTS_N_INSNS (1);
12663 else
12664 *total = COSTS_N_INSNS (4);
12665 break;
12667 default:
12668 return false;
12670 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12671 return true;
12673 case MINUS:
12674 // *udiff_widenqihi
12675 if (mode == HImode
12676 && GET_CODE (XEXP (x, 0)) == ZERO_EXTEND
12677 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
12679 *total = COSTS_N_INSNS (2);
12680 return true;
12682 // *sub<mode>3_zero_extend1
12683 if (REG_P (XEXP (x, 0))
12684 && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND)
12686 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12687 return true;
12689 // *sub<mode>3.sign_extend2
12690 if (REG_P (XEXP (x, 0))
12691 && GET_CODE (XEXP (x, 1)) == SIGN_EXTEND)
12693 *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode));
12694 return true;
12697 if (AVR_HAVE_MUL
12698 && QImode == mode
12699 && register_operand (XEXP (x, 0), QImode)
12700 && MULT == GET_CODE (XEXP (x, 1)))
12702 /* multiply-sub */
12703 *total = COSTS_N_INSNS (speed ? 4 : 3);
12704 /* multiply-sub with constant: will be split and load constant. */
12705 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
12706 *total = COSTS_N_INSNS (1) + *total;
12707 return true;
12709 if (AVR_HAVE_MUL
12710 && HImode == mode
12711 && register_operand (XEXP (x, 0), HImode)
12712 && (MULT == GET_CODE (XEXP (x, 1))
12713 || ASHIFT == GET_CODE (XEXP (x, 1)))
12714 && (ZERO_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))
12715 || SIGN_EXTEND == GET_CODE (XEXP (XEXP (x, 1), 0))))
12717 /* multiply-sub */
12718 *total = COSTS_N_INSNS (speed ? 5 : 4);
12719 /* multiply-sub with constant: will be split and load constant. */
12720 if (CONST_INT_P (XEXP (XEXP (x, 1), 1)))
12721 *total = COSTS_N_INSNS (1) + *total;
12722 return true;
12724 /* FALLTHRU */
12725 case AND:
12726 case IOR:
12727 if (IOR == code
12728 && HImode == mode
12729 && ASHIFT == GET_CODE (XEXP (x, 0)))
12731 *total = COSTS_N_INSNS (2);
12732 // Just a rough estimate. If we see no sign- or zero-extend,
12733 // then increase the cost a little bit.
12734 if (REG_P (XEXP (XEXP (x, 0), 0)))
12735 *total += COSTS_N_INSNS (1);
12736 if (REG_P (XEXP (x, 1)))
12737 *total += COSTS_N_INSNS (1);
12738 return true;
12740 if (IOR == code
12741 && AND == GET_CODE (XEXP (x, 0))
12742 && AND == GET_CODE (XEXP (x, 1))
12743 && single_zero_operand (XEXP (XEXP (x, 0), 1), mode))
12745 // Open-coded bit transfer.
12746 *total = COSTS_N_INSNS (2);
12747 return true;
12749 if (AND == code
12750 && single_one_operand (XEXP (x, 1), mode)
12751 && (ASHIFT == GET_CODE (XEXP (x, 0))
12752 || ASHIFTRT == GET_CODE (XEXP (x, 0))
12753 || LSHIFTRT == GET_CODE (XEXP (x, 0))))
12755 // "*insv.any_shift.<mode>
12756 *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode));
12757 return true;
12759 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12760 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12761 if (!CONST_INT_P (XEXP (x, 1)))
12762 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
12763 return true;
12765 case XOR:
12766 *total = COSTS_N_INSNS (GET_MODE_SIZE (mode));
12767 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12768 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
12769 return true;
12771 case MULT:
12772 switch (mode)
12774 case E_QImode:
12775 if (AVR_HAVE_MUL)
12776 *total = COSTS_N_INSNS (!speed ? 3 : 4);
12777 else if (!speed)
12778 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
12779 else
12780 return false;
12781 break;
12783 case E_HImode:
12784 if (AVR_HAVE_MUL)
12786 rtx op0 = XEXP (x, 0);
12787 rtx op1 = XEXP (x, 1);
12788 enum rtx_code code0 = GET_CODE (op0);
12789 enum rtx_code code1 = GET_CODE (op1);
12790 bool ex0 = SIGN_EXTEND == code0 || ZERO_EXTEND == code0;
12791 bool ex1 = SIGN_EXTEND == code1 || ZERO_EXTEND == code1;
12793 if (ex0
12794 && (u8_operand (op1, HImode)
12795 || s8_operand (op1, HImode)))
12797 *total = COSTS_N_INSNS (!speed ? 4 : 6);
12798 return true;
12800 if (ex0
12801 && register_operand (op1, HImode))
12803 *total = COSTS_N_INSNS (!speed ? 5 : 8);
12804 return true;
12806 else if (ex0 || ex1)
12808 *total = COSTS_N_INSNS (!speed ? 3 : 5);
12809 return true;
12811 else if (register_operand (op0, HImode)
12812 && (u8_operand (op1, HImode)
12813 || s8_operand (op1, HImode)))
12815 *total = COSTS_N_INSNS (!speed ? 6 : 9);
12816 return true;
12818 else
12819 *total = COSTS_N_INSNS (!speed ? 7 : 10);
12821 else if (!speed)
12822 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
12823 else
12824 return false;
12825 break;
12827 case E_PSImode:
12828 if (!speed)
12829 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
12830 else
12831 *total = 10;
12832 break;
12834 case E_SImode:
12835 case E_DImode:
12836 if (AVR_HAVE_MUL)
12838 if (!speed)
12840 /* Add some additional costs besides CALL like moves etc. */
12842 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
12844 else
12846 /* Just a rough estimate. Even with -O2 we don't want bulky
12847 code expanded inline. */
12849 *total = COSTS_N_INSNS (25);
12852 else
12854 if (speed)
12855 *total = COSTS_N_INSNS (300);
12856 else
12857 /* Add some additional costs besides CALL like moves etc. */
12858 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 5 : 4);
12861 if (mode == DImode)
12862 *total *= 2;
12864 return true;
12866 default:
12867 return false;
12869 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12870 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed);
12871 return true;
12873 case DIV:
12874 case MOD:
12875 case UDIV:
12876 case UMOD:
12877 if (!speed)
12878 *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1);
12879 else
12880 *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode));
12881 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12882 /* For div/mod with const-int divisor we have at least the cost of
12883 loading the divisor. */
12884 if (CONST_INT_P (XEXP (x, 1)))
12885 *total += COSTS_N_INSNS (GET_MODE_SIZE (mode));
12886 /* Add some overall penaly for clobbering and moving around registers */
12887 *total += COSTS_N_INSNS (2);
12888 return true;
12890 case ROTATE:
12891 switch (mode)
12893 case E_QImode:
12894 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4)
12895 *total = COSTS_N_INSNS (1);
12897 break;
12899 case E_HImode:
12900 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8)
12901 *total = COSTS_N_INSNS (3);
12903 break;
12905 case E_SImode:
12906 if (CONST_INT_P (XEXP (x, 1)))
12907 switch (INTVAL (XEXP (x, 1)))
12909 case 8:
12910 case 24:
12911 *total = COSTS_N_INSNS (5);
12912 break;
12913 case 16:
12914 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 6);
12915 break;
12917 break;
12919 default:
12920 return false;
12922 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
12923 return true;
12925 case ASHIFT:
12926 switch (mode)
12928 case E_QImode:
12929 if (!CONST_INT_P (XEXP (x, 1)))
12931 *total = COSTS_N_INSNS (!speed ? 4 : 17);
12932 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
12933 speed);
12935 else
12937 val = INTVAL (XEXP (x, 1));
12938 if (val == 7)
12939 *total = COSTS_N_INSNS (3);
12940 else if (val >= 0 && val <= 7)
12941 *total = COSTS_N_INSNS (val);
12942 else
12943 *total = COSTS_N_INSNS (1);
12945 break;
12947 case E_HImode:
12948 if (AVR_HAVE_MUL)
12950 if (const_2_to_7_operand (XEXP (x, 1), HImode)
12951 && (SIGN_EXTEND == GET_CODE (XEXP (x, 0))
12952 || ZERO_EXTEND == GET_CODE (XEXP (x, 0))))
12954 *total = COSTS_N_INSNS (!speed ? 4 : 6);
12955 return true;
12959 if (const1_rtx == (XEXP (x, 1))
12960 && SIGN_EXTEND == GET_CODE (XEXP (x, 0)))
12962 *total = COSTS_N_INSNS (2);
12963 return true;
12966 if (!CONST_INT_P (XEXP (x, 1)))
12968 *total = COSTS_N_INSNS (!speed ? 5 : 41);
12969 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
12970 speed);
12972 else
12973 switch (INTVAL (XEXP (x, 1)))
12975 case 0:
12976 *total = 0;
12977 break;
12978 case 1:
12979 case 8:
12980 *total = COSTS_N_INSNS (2);
12981 break;
12982 case 9:
12983 *total = COSTS_N_INSNS (3);
12984 break;
12985 case 2:
12986 case 3:
12987 case 10:
12988 case 15:
12989 *total = COSTS_N_INSNS (4);
12990 break;
12991 case 7:
12992 case 11:
12993 case 12:
12994 *total = COSTS_N_INSNS (5);
12995 break;
12996 case 4:
12997 *total = COSTS_N_INSNS (!speed ? 5 : 8);
12998 break;
12999 case 6:
13000 *total = COSTS_N_INSNS (!speed ? 5 : 9);
13001 break;
13002 case 5:
13003 *total = COSTS_N_INSNS (!speed ? 5 : 10);
13004 break;
13005 default:
13006 *total = COSTS_N_INSNS (!speed ? 5 : 41);
13007 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13008 speed);
13010 break;
13012 case E_PSImode:
13013 if (!CONST_INT_P (XEXP (x, 1)))
13015 *total = COSTS_N_INSNS (!speed ? 6 : 73);
13017 else
13018 switch (INTVAL (XEXP (x, 1)))
13020 case 0:
13021 *total = 0;
13022 break;
13023 case 1:
13024 case 8:
13025 case 16:
13026 *total = COSTS_N_INSNS (3);
13027 break;
13028 case 23:
13029 *total = COSTS_N_INSNS (5);
13030 break;
13031 default:
13032 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
13033 break;
13035 break;
13037 case E_SImode:
13038 if (!CONST_INT_P (XEXP (x, 1)))
13040 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13041 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13042 speed);
13044 else
13045 switch (INTVAL (XEXP (x, 1)))
13047 case 0:
13048 *total = 0;
13049 break;
13050 case 24:
13051 *total = COSTS_N_INSNS (3);
13052 break;
13053 case 1:
13054 case 8:
13055 case 16:
13056 *total = COSTS_N_INSNS (4);
13057 break;
13058 case 31:
13059 *total = COSTS_N_INSNS (6);
13060 break;
13061 case 2:
13062 *total = COSTS_N_INSNS (!speed ? 7 : 8);
13063 break;
13064 default:
13065 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13066 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13067 speed);
13069 break;
13071 default:
13072 return false;
13074 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
13075 return true;
13077 case ASHIFTRT:
13078 switch (mode)
13080 case E_QImode:
13081 if (!CONST_INT_P (XEXP (x, 1)))
13083 *total = COSTS_N_INSNS (!speed ? 4 : 17);
13084 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13085 speed);
13087 else
13089 val = INTVAL (XEXP (x, 1));
13090 if (val == 6)
13091 *total = COSTS_N_INSNS (4);
13092 else if (val == 7)
13093 *total = COSTS_N_INSNS (2);
13094 else if (val >= 0 && val <= 7)
13095 *total = COSTS_N_INSNS (val);
13096 else
13097 *total = COSTS_N_INSNS (1);
13099 break;
13101 case E_HImode:
13102 if (!CONST_INT_P (XEXP (x, 1)))
13104 *total = COSTS_N_INSNS (!speed ? 5 : 41);
13105 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13106 speed);
13108 else
13109 switch (INTVAL (XEXP (x, 1)))
13111 case 0:
13112 *total = 0;
13113 break;
13114 case 1:
13115 *total = COSTS_N_INSNS (2);
13116 break;
13117 case 15:
13118 *total = COSTS_N_INSNS (3);
13119 break;
13120 case 2:
13121 case 7:
13122 case 8:
13123 case 9:
13124 *total = COSTS_N_INSNS (4);
13125 break;
13126 case 10:
13127 case 14:
13128 *total = COSTS_N_INSNS (5);
13129 break;
13130 case 11:
13131 *total = COSTS_N_INSNS (!speed ? 5 : 6);
13132 break;
13133 case 12:
13134 *total = COSTS_N_INSNS (!speed ? 5 : 7);
13135 break;
13136 case 6:
13137 case 13:
13138 *total = COSTS_N_INSNS (!speed ? 5 : 8);
13139 break;
13140 default:
13141 *total = COSTS_N_INSNS (!speed ? 5 : 41);
13142 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13143 speed);
13145 break;
13147 case E_PSImode:
13148 if (!CONST_INT_P (XEXP (x, 1)))
13150 *total = COSTS_N_INSNS (!speed ? 6 : 73);
13152 else
13153 switch (INTVAL (XEXP (x, 1)))
13155 case 0:
13156 *total = 0;
13157 break;
13158 case 1:
13159 *total = COSTS_N_INSNS (3);
13160 break;
13161 case 16:
13162 case 8:
13163 *total = COSTS_N_INSNS (5);
13164 break;
13165 case 23:
13166 *total = COSTS_N_INSNS (4);
13167 break;
13168 default:
13169 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
13170 break;
13172 break;
13174 case E_SImode:
13175 if (!CONST_INT_P (XEXP (x, 1)))
13177 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13178 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13179 speed);
13181 else
13182 switch (INTVAL (XEXP (x, 1)))
13184 case 0:
13185 *total = 0;
13186 break;
13187 case 1:
13188 *total = COSTS_N_INSNS (4);
13189 break;
13190 case 8:
13191 case 16:
13192 case 24:
13193 *total = COSTS_N_INSNS (6);
13194 break;
13195 case 2:
13196 *total = COSTS_N_INSNS (!speed ? 7 : 8);
13197 break;
13198 case 31:
13199 *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5);
13200 break;
13201 default:
13202 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13203 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13204 speed);
13206 break;
13208 default:
13209 return false;
13211 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
13212 return true;
13214 case LSHIFTRT:
13215 if (outer_code == TRUNCATE)
13217 *total = avr_mul_highpart_cost (x, speed);
13218 return true;
13221 switch (mode)
13223 case E_QImode:
13224 if (!CONST_INT_P (XEXP (x, 1)))
13226 *total = COSTS_N_INSNS (!speed ? 4 : 17);
13227 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13228 speed);
13230 else
13232 val = INTVAL (XEXP (x, 1));
13233 if (val == 7)
13234 *total = COSTS_N_INSNS (3);
13235 else if (val >= 0 && val <= 7)
13236 *total = COSTS_N_INSNS (val);
13237 else
13238 *total = COSTS_N_INSNS (1);
13240 break;
13242 case E_HImode:
13243 if (!CONST_INT_P (XEXP (x, 1)))
13245 *total = COSTS_N_INSNS (!speed ? 5 : 41);
13246 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13247 speed);
13249 else
13250 switch (INTVAL (XEXP (x, 1)))
13252 case 0:
13253 *total = 0;
13254 break;
13255 case 1:
13256 case 8:
13257 *total = COSTS_N_INSNS (2);
13258 break;
13259 case 9:
13260 *total = COSTS_N_INSNS (3);
13261 break;
13262 case 2:
13263 case 10:
13264 case 15:
13265 *total = COSTS_N_INSNS (4);
13266 break;
13267 case 7:
13268 case 11:
13269 *total = COSTS_N_INSNS (5);
13270 break;
13271 case 3:
13272 case 12:
13273 case 13:
13274 case 14:
13275 *total = COSTS_N_INSNS (!speed ? 5 : 6);
13276 break;
13277 case 4:
13278 *total = COSTS_N_INSNS (!speed ? 5 : 7);
13279 break;
13280 case 5:
13281 case 6:
13282 *total = COSTS_N_INSNS (!speed ? 5 : 9);
13283 break;
13284 default:
13285 *total = COSTS_N_INSNS (!speed ? 5 : 41);
13286 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13287 speed);
13289 break;
13291 case E_PSImode:
13292 if (!CONST_INT_P (XEXP (x, 1)))
13294 *total = COSTS_N_INSNS (!speed ? 6 : 73);
13296 else
13297 switch (INTVAL (XEXP (x, 1)))
13299 case 0:
13300 *total = 0;
13301 break;
13302 case 1:
13303 case 8:
13304 case 16:
13305 *total = COSTS_N_INSNS (3);
13306 break;
13307 case 23:
13308 *total = COSTS_N_INSNS (5);
13309 break;
13310 default:
13311 *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1)));
13312 break;
13314 break;
13316 case E_SImode:
13317 if (!CONST_INT_P (XEXP (x, 1)))
13319 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13320 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13321 speed);
13323 else
13324 switch (INTVAL (XEXP (x, 1)))
13326 case 0:
13327 *total = 0;
13328 break;
13329 case 1:
13330 *total = COSTS_N_INSNS (4);
13331 break;
13332 case 2:
13333 *total = COSTS_N_INSNS (!speed ? 7 : 8);
13334 break;
13335 case 8:
13336 case 16:
13337 case 24:
13338 *total = COSTS_N_INSNS (4);
13339 break;
13340 case 31:
13341 *total = COSTS_N_INSNS (6);
13342 break;
13343 default:
13344 *total = COSTS_N_INSNS (!speed ? 7 : 113);
13345 *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1,
13346 speed);
13348 break;
13350 default:
13351 return false;
13353 *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed);
13354 return true;
13356 case COMPARE:
13357 switch (GET_MODE (XEXP (x, 0)))
13359 case E_QImode:
13360 *total = COSTS_N_INSNS (1);
13361 if (!CONST_INT_P (XEXP (x, 1)))
13362 *total += avr_operand_rtx_cost (XEXP (x, 1), QImode, code,
13363 1, speed);
13364 break;
13366 case E_HImode:
13367 *total = COSTS_N_INSNS (2);
13368 if (!CONST_INT_P (XEXP (x, 1)))
13369 *total += avr_operand_rtx_cost (XEXP (x, 1), HImode, code,
13370 1, speed);
13371 else if (INTVAL (XEXP (x, 1)) != 0)
13372 *total += COSTS_N_INSNS (1);
13373 break;
13375 case E_PSImode:
13376 *total = COSTS_N_INSNS (3);
13377 if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) != 0)
13378 *total += COSTS_N_INSNS (2);
13379 break;
13381 case E_SImode:
13382 *total = COSTS_N_INSNS (4);
13383 if (!CONST_INT_P (XEXP (x, 1)))
13384 *total += avr_operand_rtx_cost (XEXP (x, 1), SImode, code,
13385 1, speed);
13386 else if (INTVAL (XEXP (x, 1)) != 0)
13387 *total += COSTS_N_INSNS (3);
13388 break;
13390 default:
13391 return false;
13393 *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)),
13394 code, 0, speed);
13395 return true;
13397 case TRUNCATE:
13398 if (LSHIFTRT == GET_CODE (XEXP (x, 0)))
13400 *total = avr_mul_highpart_cost (XEXP (x, 0), speed);
13401 return true;
13403 break;
13405 case IF_THEN_ELSE:
13406 if (outer_code == SET
13407 && XEXP (x, 2) == pc_rtx
13408 && ordered_comparison_operator (XEXP (x, 0), VOIDmode))
13410 *total = avr_cbranch_cost (XEXP (x, 0));
13411 return true;
13414 default:
13415 break;
13417 return false;
13421 /* Implement `TARGET_RTX_COSTS'. */
13423 static bool
13424 avr_rtx_costs (rtx x, machine_mode mode, int outer_code,
13425 int opno, int *total, bool speed)
13427 bool done = avr_rtx_costs_1 (x, mode, outer_code, opno, total, speed);
13429 if (avr_log.rtx_costs)
13431 avr_edump ("\n%?=%b (%s) total=%d, outer=%C:\n%r\n",
13432 done, speed ? "speed" : "size", *total, outer_code, x);
13435 return done;
13439 /* Implement `TARGET_INSN_COST'. */
13440 /* For some insns, it is not enough to look at the cost of the SET_SRC.
13441 In that case, have a look at the entire insn, e.g. during insn combine. */
13443 static int
13444 avr_insn_cost (rtx_insn *insn, bool speed)
13446 const int unknown_cost = -1;
13447 int cost = unknown_cost;
13449 rtx set = single_set (insn);
13451 if (set
13452 && ZERO_EXTRACT == GET_CODE (SET_DEST (set)))
13454 // Try find anything that would flip the extracted bit.
13455 bool not_bit_p = false;
13457 subrtx_iterator::array_type array;
13458 FOR_EACH_SUBRTX (iter, array, SET_SRC (set), NONCONST)
13460 enum rtx_code code = GET_CODE (*iter);
13461 not_bit_p |= code == NOT || code == XOR || code == GE;
13464 // Don't go too deep into the analysis. In almost all cases,
13465 // using BLD/BST is the best we can do for single-bit moves,
13466 // even considering CSE.
13467 cost = COSTS_N_INSNS (2 + not_bit_p);
13470 if (cost != unknown_cost)
13472 if (avr_log.rtx_costs)
13473 avr_edump ("\n%? (%s) insn_cost=%d\n%r\n",
13474 speed ? "speed" : "size", cost, insn);
13475 return cost;
13478 // Resort to what rtlanal.cc::insn_cost() implements as a default
13479 // when targetm.insn_cost() is not implemented.
13481 return pattern_cost (PATTERN (insn), speed);
13485 /* Implement `TARGET_ADDRESS_COST'. */
13487 static int
13488 avr_address_cost (rtx x, machine_mode mode, addr_space_t /*as*/,
13489 bool /*speed*/)
13491 int cost = 4;
13493 if (GET_CODE (x) == PLUS
13494 && CONST_INT_P (XEXP (x, 1))
13495 && (REG_P (XEXP (x, 0))
13496 || SUBREG_P (XEXP (x, 0))))
13498 if (INTVAL (XEXP (x, 1)) > MAX_LD_OFFSET(mode))
13499 cost = 18;
13501 else if (CONSTANT_ADDRESS_P (x))
13503 if (io_address_operand (x, QImode))
13504 cost = 2;
13506 if (AVR_TINY
13507 && avr_address_tiny_absdata_p (x, QImode))
13508 cost = 2;
13511 if (avr_log.address_cost)
13512 avr_edump ("\n%?: %d = %r\n", cost, x);
13514 return cost;
13517 /* Test for extra memory constraint 'Q'.
13518 It's a memory address based on Y or Z pointer with valid displacement. */
13521 extra_constraint_Q (rtx x)
13523 int ok = 0;
13524 rtx plus = XEXP (x, 0);
13526 if (GET_CODE (plus) == PLUS
13527 && REG_P (XEXP (plus, 0))
13528 && CONST_INT_P (XEXP (plus, 1))
13529 && (INTVAL (XEXP (plus, 1))
13530 <= MAX_LD_OFFSET (GET_MODE (x))))
13532 rtx xx = XEXP (plus, 0);
13533 int regno = REGNO (xx);
13535 ok = (/* allocate pseudos */
13536 regno >= FIRST_PSEUDO_REGISTER
13537 /* strictly check */
13538 || regno == REG_Z || regno == REG_Y
13539 /* XXX frame & arg pointer checks */
13540 || xx == frame_pointer_rtx
13541 || xx == arg_pointer_rtx);
13543 if (avr_log.constraints)
13544 avr_edump ("\n%?=%d reload_completed=%d reload_in_progress=%d\n %r\n",
13545 ok, reload_completed, reload_in_progress, x);
13548 return ok;
13551 /* Convert condition code CONDITION to the valid AVR condition code. */
13553 RTX_CODE
13554 avr_normalize_condition (RTX_CODE condition)
13556 switch (condition)
13558 case GT:
13559 return GE;
13560 case GTU:
13561 return GEU;
13562 case LE:
13563 return LT;
13564 case LEU:
13565 return LTU;
13566 default:
13567 gcc_unreachable ();
13572 /* Returns register number for function return value.*/
13574 static inline unsigned int
13575 avr_ret_register (void)
13577 return REG_24;
13581 /* Implement `TARGET_FUNCTION_VALUE_REGNO_P'. */
13583 static bool
13584 avr_function_value_regno_p (const unsigned int regno)
13586 return regno == avr_ret_register ();
13590 /* Implement `TARGET_LIBCALL_VALUE'. */
13591 /* Create an RTX representing the place where a
13592 library function returns a value of mode MODE. */
13594 static rtx
13595 avr_libcall_value (machine_mode mode, const_rtx /*func*/)
13597 int offs = GET_MODE_SIZE (mode);
13599 if (offs <= 4)
13600 offs = (offs + 1) & ~1;
13602 return gen_rtx_REG (mode, avr_ret_register () + 2 - offs);
13606 /* Implement `TARGET_FUNCTION_VALUE'. */
13607 /* Create an RTX representing the place where a
13608 function returns a value of data type VALTYPE. */
13610 static rtx
13611 avr_function_value (const_tree type, const_tree /*fn_decl_or_type*/,
13612 bool /*outgoing*/)
13614 if (TYPE_MODE (type) != BLKmode)
13615 return avr_libcall_value (TYPE_MODE (type), NULL_RTX);
13617 unsigned int offs = int_size_in_bytes (type);
13618 if (offs < 2)
13619 offs = 2;
13620 if (offs > 2 && offs < GET_MODE_SIZE (SImode))
13621 offs = GET_MODE_SIZE (SImode);
13622 else if (offs > GET_MODE_SIZE (SImode) && offs < GET_MODE_SIZE (DImode))
13623 offs = GET_MODE_SIZE (DImode);
13625 return gen_rtx_REG (BLKmode, avr_ret_register () + 2 - offs);
13629 test_hard_reg_class (enum reg_class rclass, rtx x)
13631 int regno = true_regnum (x);
13632 if (regno < 0)
13633 return 0;
13635 if (TEST_HARD_REG_CLASS (rclass, regno))
13636 return 1;
13638 return 0;
13642 /* Helper for jump_over_one_insn_p: Test if INSN is a 2-word instruction
13643 and thus is suitable to be skipped by CPSE, SBRC, etc. */
13645 static bool
13646 avr_2word_insn_p (rtx_insn *insn)
13648 if (TARGET_SKIP_BUG || !insn || get_attr_length (insn) != 2)
13650 return false;
13653 switch (INSN_CODE (insn))
13655 default:
13656 return false;
13658 case CODE_FOR_movqi_insn:
13659 case CODE_FOR_movuqq_insn:
13660 case CODE_FOR_movqq_insn:
13662 rtx set = single_set (insn);
13663 rtx src = SET_SRC (set);
13664 rtx dest = SET_DEST (set);
13666 /* Factor out LDS and STS from movqi_insn. */
13668 if (MEM_P (dest)
13669 && (REG_P (src) || src == CONST0_RTX (GET_MODE (dest))))
13671 return CONSTANT_ADDRESS_P (XEXP (dest, 0));
13673 else if (REG_P (dest)
13674 && MEM_P (src))
13676 return CONSTANT_ADDRESS_P (XEXP (src, 0));
13679 return false;
13682 case CODE_FOR_call_insn:
13683 case CODE_FOR_call_value_insn:
13684 return true;
13690 jump_over_one_insn_p (rtx_insn *insn, rtx dest)
13692 int uid = INSN_UID (GET_CODE (dest) == LABEL_REF
13693 ? XEXP (dest, 0)
13694 : dest);
13695 int jump_addr = INSN_ADDRESSES (INSN_UID (insn));
13696 int dest_addr = INSN_ADDRESSES (uid);
13697 int jump_offset = dest_addr - jump_addr - get_attr_length (insn);
13699 return (jump_offset == 1
13700 || (jump_offset == 2
13701 && avr_2word_insn_p (next_active_insn (insn))));
13705 /* Implement `TARGET_HARD_REGNO_NREGS'. CCmode is four units for historical
13706 reasons. If this hook is not defined, TARGET_HARD_REGNO_NREGS
13707 reports that CCmode requires four registers.
13708 Define this hook to allow CCmode to fit in a single REG_CC. For
13709 other modes and regs, return the number of words in mode (i.e whatever
13710 the default implementation of the hook returned). */
13712 static unsigned int
13713 avr_hard_regno_nregs (unsigned int regno, machine_mode mode)
13715 if (regno == REG_CC && mode == CCmode)
13716 return 1;
13718 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
13722 /* Implement `TARGET_HARD_REGNO_MODE_OK'. On the enhanced core, anything
13723 larger than 1 byte must start in even numbered register for "movw" to
13724 work (this way we don't have to check for odd registers everywhere). */
13726 static bool
13727 avr_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
13729 if (regno == REG_CC)
13730 return mode == CCmode;
13732 /* NOTE: 8-bit values must not be disallowed for R28 or R29.
13733 Disallowing QI et al. in these regs might lead to code like
13734 (set (subreg:QI (reg:HI 28) n) ...)
13735 which will result in wrong code because reload does not
13736 handle SUBREGs of hard regsisters like this.
13737 This could be fixed in reload. However, it appears
13738 that fixing reload is not wanted by reload people. */
13740 /* Any GENERAL_REGS register can hold 8-bit values. */
13742 if (GET_MODE_SIZE (mode) == 1)
13743 return true;
13745 /* FIXME: Ideally, the following test is not needed.
13746 However, it turned out that it can reduce the number
13747 of spill fails. AVR and it's poor endowment with
13748 address registers is extreme stress test for reload. */
13750 if (GET_MODE_SIZE (mode) >= 4
13751 && regno >= REG_X)
13752 return false;
13754 /* All modes larger than 8 bits should start in an even register. */
13756 return !(regno & 1);
13760 /* Implement `TARGET_HARD_REGNO_CALL_PART_CLOBBERED'. */
13762 static bool
13763 avr_hard_regno_call_part_clobbered (unsigned, unsigned regno,
13764 machine_mode mode)
13766 /* FIXME: This hook gets called with MODE:REGNO combinations that don't
13767 represent valid hard registers like, e.g. HI:29. Returning TRUE
13768 for such registers can lead to performance degradation as mentioned
13769 in PR53595. Thus, report invalid hard registers as FALSE. */
13771 if (!avr_hard_regno_mode_ok (regno, mode))
13772 return 0;
13774 /* Return true if any of the following boundaries is crossed:
13775 17/18 or 19/20 (if AVR_TINY), 27/28 and 29/30. */
13777 return ((regno <= LAST_CALLEE_SAVED_REG
13778 && regno + GET_MODE_SIZE (mode) > 1 + LAST_CALLEE_SAVED_REG)
13779 || (regno < REG_Y && regno + GET_MODE_SIZE (mode) > REG_Y)
13780 || (regno < REG_Z && regno + GET_MODE_SIZE (mode) > REG_Z));
13784 /* Implement `MODE_CODE_BASE_REG_CLASS'. */
13786 enum reg_class
13787 avr_mode_code_base_reg_class (machine_mode /*mode*/, addr_space_t as,
13788 RTX_CODE outer_code, RTX_CODE /*index_code*/)
13790 if (!ADDR_SPACE_GENERIC_P (as))
13792 return POINTER_Z_REGS;
13795 if (AVR_TINY)
13796 // We allow all offsets for all pointer regs. Pass .avr-fuse-add
13797 // will rectify it (register allocation cannot do it).
13798 return POINTER_REGS;
13800 if (!avr_strict_X)
13801 return reload_completed ? BASE_POINTER_REGS : POINTER_REGS;
13803 return PLUS == outer_code ? BASE_POINTER_REGS : POINTER_REGS;
13807 /* Implement `REGNO_MODE_CODE_OK_FOR_BASE_P'. */
13809 bool
13810 avr_regno_mode_code_ok_for_base_p (int regno, machine_mode /*mode*/,
13811 addr_space_t as, RTX_CODE outer_code,
13812 RTX_CODE /*index_code*/)
13814 bool ok = false;
13816 if (!ADDR_SPACE_GENERIC_P (as))
13818 if (regno < FIRST_PSEUDO_REGISTER
13819 && regno == REG_Z)
13821 return true;
13824 if (reg_renumber)
13826 regno = reg_renumber[regno];
13828 if (regno == REG_Z)
13830 return true;
13834 return false;
13837 if (regno < FIRST_PSEUDO_REGISTER
13838 && (regno == REG_X
13839 || regno == REG_Y
13840 || regno == REG_Z
13841 || regno == ARG_POINTER_REGNUM))
13843 ok = true;
13845 else if (reg_renumber)
13847 regno = reg_renumber[regno];
13849 if (regno == REG_X
13850 || regno == REG_Y
13851 || regno == REG_Z
13852 || regno == ARG_POINTER_REGNUM)
13854 ok = true;
13858 if (avr_strict_X
13859 // On Reduced Tiny, all registers are equal in that they do not
13860 // support PLUS addressing; respective addresses will be fake,
13861 // even for the frame pointer. They must be handled in the
13862 // printers by add-store-sub sequences -- or may be split after
13863 // reload by `avr_split_tiny_move'.
13864 && ! AVR_TINY
13865 && PLUS == outer_code
13866 && regno == REG_X)
13868 ok = false;
13871 return ok;
13875 /* A helper for `output_reload_insisf' and `output_reload_inhi'. */
13876 /* Set 32-bit register OP[0] to compile-time constant OP[1].
13877 CLOBBER_REG is a QI clobber register or NULL_RTX.
13878 LEN == NULL: output instructions.
13879 LEN != NULL: set *LEN to the length of the instruction sequence
13880 (in words) printed with LEN = NULL.
13881 If CLEAR_P is true, OP[0] had been cleard to Zero already.
13882 If CLEAR_P is false, nothing is known about OP[0].
13884 The effect on cc0 is as follows:
13886 Load 0 to any register except ZERO_REG : NONE
13887 Load ld register with any value : NONE
13888 Anything else: : CLOBBER */
13890 static void
13891 output_reload_in_const (rtx *op, rtx clobber_reg, int *len, bool clear_p)
13893 rtx src = op[1];
13894 rtx dest = op[0];
13895 rtx xval, xdest[4];
13896 int ival[4];
13897 int clobber_val = 1234;
13898 bool cooked_clobber_p = false;
13899 bool set_p = false;
13900 machine_mode mode = GET_MODE (dest);
13901 int n_bytes = GET_MODE_SIZE (mode);
13903 gcc_assert (REG_P (dest)
13904 && CONSTANT_P (src));
13906 if (len)
13907 *len = 0;
13909 /* (REG:SI 14) is special: It's neither in LD_REGS nor in NO_LD_REGS
13910 but has some subregs that are in LD_REGS. Use the MSB (REG:QI 17). */
13912 if (REGNO (dest) < REG_16
13913 && REGNO (dest) + GET_MODE_SIZE (mode) > REG_16)
13915 clobber_reg = all_regs_rtx[REGNO (dest) + n_bytes - 1];
13918 /* We might need a clobber reg but don't have one. Look at the value to
13919 be loaded more closely. A clobber is only needed if it is a symbol
13920 or contains a byte that is neither 0, -1 or a power of 2. */
13922 if (NULL_RTX == clobber_reg
13923 && !test_hard_reg_class (LD_REGS, dest)
13924 && (! (CONST_INT_P (src) || CONST_FIXED_P (src) || CONST_DOUBLE_P (src))
13925 || !avr_popcount_each_byte (src, n_bytes,
13926 (1 << 0) | (1 << 1) | (1 << 8))))
13928 /* We have no clobber register but need one. Cook one up.
13929 That's cheaper than loading from constant pool. */
13931 cooked_clobber_p = true;
13932 clobber_reg = all_regs_rtx[REG_Z + 1];
13933 avr_asm_len ("mov __tmp_reg__,%0", &clobber_reg, len, 1);
13936 /* Now start filling DEST from LSB to MSB. */
13938 for (int n = 0; n < n_bytes; n++)
13940 bool done_byte = false;
13941 rtx xop[3];
13943 /* Crop the n-th destination byte. */
13945 xdest[n] = simplify_gen_subreg (QImode, dest, mode, n);
13946 int ldreg_p = test_hard_reg_class (LD_REGS, xdest[n]);
13948 if (!CONST_INT_P (src)
13949 && !CONST_FIXED_P (src)
13950 && !CONST_DOUBLE_P (src))
13952 static const char *const asm_code[][2] =
13954 { "ldi %2,lo8(%1)" CR_TAB "mov %0,%2", "ldi %0,lo8(%1)" },
13955 { "ldi %2,hi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hi8(%1)" },
13956 { "ldi %2,hlo8(%1)" CR_TAB "mov %0,%2", "ldi %0,hlo8(%1)" },
13957 { "ldi %2,hhi8(%1)" CR_TAB "mov %0,%2", "ldi %0,hhi8(%1)" }
13960 xop[0] = xdest[n];
13961 xop[1] = src;
13962 xop[2] = clobber_reg;
13964 avr_asm_len (asm_code[n][ldreg_p], xop, len, ldreg_p ? 1 : 2);
13966 continue;
13969 /* Crop the n-th source byte. */
13971 xval = simplify_gen_subreg (QImode, src, mode, n);
13972 ival[n] = INTVAL (xval);
13974 /* Look if we can reuse the low word by means of MOVW. */
13976 if (n == 2
13977 && n_bytes >= 4
13978 && AVR_HAVE_MOVW)
13980 rtx lo16 = simplify_gen_subreg (HImode, src, mode, 0);
13981 rtx hi16 = simplify_gen_subreg (HImode, src, mode, 2);
13983 if (INTVAL (lo16) == INTVAL (hi16))
13985 if (INTVAL (lo16) != 0 || !clear_p)
13986 avr_asm_len ("movw %C0,%A0", &op[0], len, 1);
13988 break;
13992 /* Don't use CLR so that cc0 is set as expected. */
13994 if (ival[n] == 0)
13996 if (!clear_p)
13997 avr_asm_len (ldreg_p ? "ldi %0,0"
13998 : AVR_ZERO_REGNO == REGNO (xdest[n]) ? "clr %0"
13999 : "mov %0,__zero_reg__",
14000 &xdest[n], len, 1);
14001 continue;
14004 if (clobber_val == ival[n]
14005 && REGNO (clobber_reg) == REGNO (xdest[n]))
14007 continue;
14010 /* LD_REGS can use LDI to move a constant value */
14012 if (ldreg_p)
14014 xop[0] = xdest[n];
14015 xop[1] = xval;
14016 avr_asm_len ("ldi %0,lo8(%1)", xop, len, 1);
14017 continue;
14020 /* Try to reuse value already loaded in some lower byte. */
14022 for (int j = 0; j < n; j++)
14023 if (ival[j] == ival[n])
14025 xop[0] = xdest[n];
14026 xop[1] = xdest[j];
14028 avr_asm_len ("mov %0,%1", xop, len, 1);
14029 done_byte = true;
14030 break;
14033 if (done_byte)
14034 continue;
14036 /* Need no clobber reg for -1: Use CLR/DEC */
14038 if (ival[n] == -1)
14040 if (!clear_p)
14041 avr_asm_len ("clr %0", &xdest[n], len, 1);
14043 avr_asm_len ("dec %0", &xdest[n], len, 1);
14044 continue;
14046 else if (ival[n] == 1)
14048 if (!clear_p)
14049 avr_asm_len ("clr %0", &xdest[n], len, 1);
14051 avr_asm_len ("inc %0", &xdest[n], len, 1);
14052 continue;
14055 /* Use T flag or INC to manage powers of 2 if we have
14056 no clobber reg. */
14058 if (NULL_RTX == clobber_reg
14059 && single_one_operand (xval, QImode))
14061 xop[0] = xdest[n];
14062 xop[1] = GEN_INT (exact_log2 (ival[n] & GET_MODE_MASK (QImode)));
14064 gcc_assert (constm1_rtx != xop[1]);
14066 if (!set_p)
14068 set_p = true;
14069 avr_asm_len ("set", xop, len, 1);
14072 if (!clear_p)
14073 avr_asm_len ("clr %0", xop, len, 1);
14075 avr_asm_len ("bld %0,%1", xop, len, 1);
14076 continue;
14079 /* We actually need the LD_REGS clobber reg. */
14081 gcc_assert (NULL_RTX != clobber_reg);
14083 xop[0] = xdest[n];
14084 xop[1] = xval;
14085 xop[2] = clobber_reg;
14086 clobber_val = ival[n];
14088 avr_asm_len ("ldi %2,lo8(%1)" CR_TAB
14089 "mov %0,%2", xop, len, 2);
14092 /* If we cooked up a clobber reg above, restore it. */
14094 if (cooked_clobber_p)
14096 avr_asm_len ("mov %0,__tmp_reg__", &clobber_reg, len, 1);
14101 /* Reload the constant OP[1] into the HI register OP[0].
14102 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
14103 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
14104 need a clobber reg or have to cook one up.
14106 PLEN == NULL: Output instructions.
14107 PLEN != NULL: Output nothing. Set *PLEN to number of words occupied
14108 by the insns printed.
14110 Return "". */
14112 const char *
14113 output_reload_inhi (rtx *op, rtx clobber_reg, int *plen)
14115 output_reload_in_const (op, clobber_reg, plen, false);
14116 return "";
14120 /* Reload a SI or SF compile time constant OP[1] into the register OP[0].
14121 CLOBBER_REG is a QI clobber reg needed to move vast majority of consts
14122 into a NO_LD_REGS register. If CLOBBER_REG is NULL_RTX we either don't
14123 need a clobber reg or have to cook one up.
14125 LEN == NULL: Output instructions.
14127 LEN != NULL: Output nothing. Set *LEN to number of words occupied
14128 by the insns printed.
14130 Return "". */
14132 const char *
14133 output_reload_insisf (rtx *op, rtx clobber_reg, int *len)
14135 if (AVR_HAVE_MOVW
14136 && !test_hard_reg_class (LD_REGS, op[0])
14137 && (CONST_INT_P (op[1])
14138 || CONST_FIXED_P (op[1])
14139 || CONST_DOUBLE_P (op[1])))
14141 /* In some cases it is better to clear the destination beforehand, e.g.
14143 CLR R2 CLR R3 MOVW R4,R2 INC R2
14145 is shorther than
14147 CLR R2 INC R2 CLR R3 CLR R4 CLR R5
14149 We find it too tedious to work that out in the print function.
14150 Instead, we call the print function twice to get the lengths of
14151 both methods and use the shortest one. */
14153 int len_clr, len_noclr;
14154 output_reload_in_const (op, clobber_reg, &len_clr, true);
14155 output_reload_in_const (op, clobber_reg, &len_noclr, false);
14157 if (len_noclr - len_clr == 4)
14159 /* Default needs 4 CLR instructions: clear register beforehand. */
14161 avr_asm_len ("mov %A0,__zero_reg__" CR_TAB
14162 "mov %B0,__zero_reg__" CR_TAB
14163 "movw %C0,%A0", &op[0], len, 3);
14165 output_reload_in_const (op, clobber_reg, len, true);
14167 if (len)
14168 *len += 3;
14170 return "";
14174 /* Default: destination not pre-cleared. */
14176 output_reload_in_const (op, clobber_reg, len, false);
14177 return "";
14180 const char *
14181 avr_out_reload_inpsi (rtx *op, rtx clobber_reg, int *len)
14183 output_reload_in_const (op, clobber_reg, len, false);
14184 return "";
14188 /* Worker function for `ASM_OUTPUT_ADDR_VEC'. */
14189 /* Emit jump tables out-of-line so that branches crossing the table
14190 get shorter offsets. If we have JUMP + CALL, then put the tables
14191 in a dedicated non-.text section so that CALLs get better chance to
14192 be relaxed to RCALLs.
14194 We emit the tables by hand because `function_rodata_section' does not
14195 work as expected, cf. PR71151, and we do *NOT* want the table to be
14196 in .rodata, hence setting JUMP_TABLES_IN_TEXT_SECTION = 0 is of limited
14197 use; and setting it to 1 attributes table lengths to branch offsets...
14198 Moreover, fincal.c keeps switching section before each table entry
14199 which we find too fragile as to rely on section caching. */
14201 void
14202 avr_output_addr_vec (rtx_insn *labl, rtx table)
14204 FILE *stream = asm_out_file;
14206 app_disable();
14208 // Switch to appropriate (sub)section.
14210 if (DECL_SECTION_NAME (current_function_decl)
14211 && symtab_node::get (current_function_decl)
14212 && ! symtab_node::get (current_function_decl)->implicit_section)
14214 // .subsection will emit the code after the function and in the
14215 // section as chosen by the user.
14217 switch_to_section (current_function_section ());
14218 fprintf (stream, "\t.subsection\t1\n");
14220 else
14222 // Since PR63223 there is no restriction where to put the table; it
14223 // may even reside above 128 KiB. We put it in a section as high as
14224 // possible and avoid progmem in order not to waste flash <= 64 KiB.
14226 const char *sec_name = ".jumptables.gcc";
14228 // The table belongs to its host function, therefore use fine
14229 // grained sections so that, if that function is removed by
14230 // --gc-sections, the child table(s) may also be removed. */
14232 tree asm_name = DECL_ASSEMBLER_NAME (current_function_decl);
14233 const char *fname = IDENTIFIER_POINTER (asm_name);
14234 fname = targetm.strip_name_encoding (fname);
14235 sec_name = ACONCAT ((sec_name, ".", fname, NULL));
14237 fprintf (stream, "\t.section\t%s,\"%s\",@progbits\n", sec_name,
14238 AVR_HAVE_JMP_CALL ? "a" : "ax");
14241 // Output the label that preceeds the table.
14243 ASM_OUTPUT_ALIGN (stream, 1);
14244 targetm.asm_out.internal_label (stream, "L", CODE_LABEL_NUMBER (labl));
14246 // Output the table's content.
14248 int vlen = XVECLEN (table, 0);
14250 for (int idx = 0; idx < vlen; idx++)
14252 int value = CODE_LABEL_NUMBER (XEXP (XVECEXP (table, 0, idx), 0));
14254 if (AVR_HAVE_JMP_CALL)
14255 fprintf (stream, "\t.word gs(.L%d)\n", value);
14256 else
14257 fprintf (stream, "\trjmp .L%d\n", value);
14260 // Switch back to original section. As we clobbered the section above,
14261 // forget the current section before switching back.
14263 in_section = NULL;
14264 switch_to_section (current_function_section ());
14268 /* Implement `TARGET_CONDITIONAL_REGISTER_USAGE'. */
14270 static void
14271 avr_conditional_register_usage (void)
14273 if (AVR_TINY)
14275 const int tiny_reg_alloc_order[] = {
14276 24, 25,
14277 22, 23,
14278 30, 31,
14279 26, 27,
14280 28, 29,
14281 21, 20, 19, 18,
14282 16, 17,
14283 32, 33, 34, 35,
14284 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
14287 /* Set R0-R17 as fixed registers. Reset R0-R17 in call used register list
14288 - R0-R15 are not available in Tiny Core devices
14289 - R16 and R17 are fixed registers. */
14291 for (size_t i = REG_0; i <= REG_17; i++)
14293 fixed_regs[i] = 1;
14294 call_used_regs[i] = 1;
14297 /* Set R18 to R21 as callee saved registers
14298 - R18, R19, R20 and R21 are the callee saved registers in
14299 Tiny Core devices */
14301 for (size_t i = REG_18; i <= LAST_CALLEE_SAVED_REG; i++)
14303 call_used_regs[i] = 0;
14306 /* Update register allocation order for Tiny Core devices */
14308 for (size_t i = 0; i < ARRAY_SIZE (tiny_reg_alloc_order); i++)
14310 reg_alloc_order[i] = tiny_reg_alloc_order[i];
14313 CLEAR_HARD_REG_SET (reg_class_contents[(int) NO_LD_REGS]);
14317 /* Implement `TARGET_HARD_REGNO_SCRATCH_OK'. */
14318 /* Returns true if SCRATCH are safe to be allocated as a scratch
14319 registers (for a define_peephole2) in the current function. */
14321 static bool
14322 avr_hard_regno_scratch_ok (unsigned int regno)
14324 /* Interrupt functions can only use registers that have already been saved
14325 by the prologue, even if they would normally be call-clobbered. */
14327 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
14328 && !df_regs_ever_live_p (regno))
14329 return false;
14331 /* Don't allow hard registers that might be part of the frame pointer.
14332 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
14333 and don't care for a frame pointer that spans more than one register. */
14335 if ((!reload_completed || frame_pointer_needed)
14336 && (regno == REG_Y || regno == REG_Y + 1))
14338 return false;
14341 return true;
14345 /* Worker function for `HARD_REGNO_RENAME_OK'. */
14346 /* Return nonzero if register OLD_REG can be renamed to register NEW_REG. */
14349 avr_hard_regno_rename_ok (unsigned int old_reg, unsigned int new_reg)
14351 /* Interrupt functions can only use registers that have already been
14352 saved by the prologue, even if they would normally be
14353 call-clobbered. */
14355 if ((cfun->machine->is_interrupt || cfun->machine->is_signal)
14356 && !df_regs_ever_live_p (new_reg))
14357 return 0;
14359 /* Don't allow hard registers that might be part of the frame pointer.
14360 Some places in the compiler just test for [HARD_]FRAME_POINTER_REGNUM
14361 and don't care for a frame pointer that spans more than one register. */
14363 if ((!reload_completed || frame_pointer_needed)
14364 && (old_reg == REG_Y || old_reg == REG_Y + 1
14365 || new_reg == REG_Y || new_reg == REG_Y + 1))
14367 return 0;
14370 return 1;
14373 /* Output a branch that tests a single bit of a register (QI, HI, SI or DImode)
14374 or memory location in the I/O space (QImode only).
14376 Operand 0: comparison operator (must be EQ or NE, compare bit to zero).
14377 Operand 1: register operand to test, or CONST_INT memory address.
14378 Operand 2: bit number.
14379 Operand 3: label to jump to if the test is true. */
14381 const char *
14382 avr_out_sbxx_branch (rtx_insn *insn, rtx operands[])
14384 enum rtx_code comp = GET_CODE (operands[0]);
14385 bool long_jump = get_attr_length (insn) >= 4;
14386 bool reverse = long_jump || jump_over_one_insn_p (insn, operands[3]);
14388 if (comp == GE)
14389 comp = EQ;
14390 else if (comp == LT)
14391 comp = NE;
14393 if (reverse)
14394 comp = reverse_condition (comp);
14396 switch (GET_CODE (operands[1]))
14398 default:
14399 gcc_unreachable();
14401 case CONST_INT:
14402 case CONST:
14403 case SYMBOL_REF:
14405 if (low_io_address_operand (operands[1], QImode))
14407 if (comp == EQ)
14408 output_asm_insn ("sbis %i1,%2", operands);
14409 else
14410 output_asm_insn ("sbic %i1,%2", operands);
14412 else
14414 gcc_assert (io_address_operand (operands[1], QImode));
14415 output_asm_insn ("in __tmp_reg__,%i1", operands);
14416 if (comp == EQ)
14417 output_asm_insn ("sbrs __tmp_reg__,%2", operands);
14418 else
14419 output_asm_insn ("sbrc __tmp_reg__,%2", operands);
14422 break; /* CONST_INT */
14424 case REG:
14426 if (comp == EQ)
14427 output_asm_insn ("sbrs %T1%T2", operands);
14428 else
14429 output_asm_insn ("sbrc %T1%T2", operands);
14431 break; /* REG */
14432 } /* switch */
14434 if (long_jump)
14435 return ("rjmp .+4" CR_TAB
14436 "jmp %x3");
14438 if (!reverse)
14439 return "rjmp %x3";
14441 return "";
14445 /* Worker function for `TARGET_ASM_CONSTRUCTOR'. */
14447 static void
14448 avr_asm_out_ctor (rtx symbol, int priority)
14450 fputs ("\t.global __do_global_ctors\n", asm_out_file);
14451 default_ctor_section_asm_out_constructor (symbol, priority);
14455 /* Worker function for `TARGET_ASM_DESTRUCTOR'. */
14457 static void
14458 avr_asm_out_dtor (rtx symbol, int priority)
14460 fputs ("\t.global __do_global_dtors\n", asm_out_file);
14461 default_dtor_section_asm_out_destructor (symbol, priority);
14465 /* Implement `TARGET_RETURN_IN_MEMORY'. */
14467 static bool
14468 avr_return_in_memory (const_tree type, const_tree /*fntype*/)
14470 HOST_WIDE_INT size = int_size_in_bytes (type);
14471 HOST_WIDE_INT ret_size_limit = AVR_TINY ? 4 : 8;
14473 /* In avr, there are 8 return registers. But, for Tiny Core
14474 (ATtiny4/5/9/10/20/40) devices, only 4 registers are available.
14475 Return true if size is unknown or greater than the limit. */
14477 if (size == -1 || size > ret_size_limit)
14479 return true;
14481 else
14483 return false;
14488 /* Implement `CASE_VALUES_THRESHOLD'. */
14489 /* Supply the default for --param case-values-threshold=0 */
14491 static unsigned int
14492 avr_case_values_threshold (void)
14494 /* The exact break-even point between a jump table and an if-else tree
14495 depends on several factors not available here like, e.g. if 8-bit
14496 comparisons can be used in the if-else tree or not, on the
14497 range of the case values, if the case value can be reused, on the
14498 register allocation, etc. '7' appears to be a good choice. */
14500 return 7;
14504 /* Implement `TARGET_ADDR_SPACE_ADDRESS_MODE'. */
14506 static scalar_int_mode
14507 avr_addr_space_address_mode (addr_space_t as)
14509 return avr_addrspace[as].pointer_size == 3 ? PSImode : HImode;
14513 /* Implement `TARGET_ADDR_SPACE_POINTER_MODE'. */
14515 static scalar_int_mode
14516 avr_addr_space_pointer_mode (addr_space_t as)
14518 return avr_addr_space_address_mode (as);
14522 /* Helper for following function. */
14524 static bool
14525 avr_reg_ok_for_pgm_addr (rtx reg, bool strict)
14527 gcc_assert (REG_P (reg));
14529 if (strict)
14531 return REGNO (reg) == REG_Z;
14534 /* Avoid combine to propagate hard regs. */
14536 if (can_create_pseudo_p()
14537 && REGNO (reg) < REG_Z)
14539 return false;
14542 return true;
14546 /* Implement `TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P'. */
14548 static bool
14549 avr_addr_space_legitimate_address_p (machine_mode mode, rtx x, bool strict,
14550 addr_space_t as, code_helper = ERROR_MARK)
14552 bool ok = false;
14554 switch (as)
14556 default:
14557 gcc_unreachable();
14559 case ADDR_SPACE_GENERIC:
14560 return avr_legitimate_address_p (mode, x, strict);
14562 case ADDR_SPACE_FLASH:
14563 case ADDR_SPACE_FLASH1:
14564 case ADDR_SPACE_FLASH2:
14565 case ADDR_SPACE_FLASH3:
14566 case ADDR_SPACE_FLASH4:
14567 case ADDR_SPACE_FLASH5:
14569 switch (GET_CODE (x))
14571 case REG:
14572 ok = avr_reg_ok_for_pgm_addr (x, strict);
14573 break;
14575 case POST_INC:
14576 ok = avr_reg_ok_for_pgm_addr (XEXP (x, 0), strict);
14577 break;
14579 default:
14580 break;
14583 break; /* FLASH */
14585 case ADDR_SPACE_MEMX:
14586 if (REG_P (x))
14587 ok = (!strict
14588 && can_create_pseudo_p());
14590 if (LO_SUM == GET_CODE (x))
14592 rtx hi = XEXP (x, 0);
14593 rtx lo = XEXP (x, 1);
14595 ok = (REG_P (hi)
14596 && (!strict || REGNO (hi) < FIRST_PSEUDO_REGISTER)
14597 && REG_P (lo)
14598 && REGNO (lo) == REG_Z);
14601 break; /* MEMX */
14604 if (avr_log.legitimate_address_p)
14606 avr_edump ("\n%?: ret=%b, mode=%m strict=%d "
14607 "reload_completed=%d reload_in_progress=%d %s:",
14608 ok, mode, strict, reload_completed, reload_in_progress,
14609 reg_renumber ? "(reg_renumber)" : "");
14611 if (GET_CODE (x) == PLUS
14612 && REG_P (XEXP (x, 0))
14613 && CONST_INT_P (XEXP (x, 1))
14614 && IN_RANGE (INTVAL (XEXP (x, 1)), 0, MAX_LD_OFFSET (mode))
14615 && reg_renumber)
14617 avr_edump ("(r%d ---> r%d)", REGNO (XEXP (x, 0)),
14618 true_regnum (XEXP (x, 0)));
14621 avr_edump ("\n%r\n", x);
14624 return ok;
14628 /* Implement `TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS'. */
14630 static rtx
14631 avr_addr_space_legitimize_address (rtx x, rtx old_x,
14632 machine_mode mode, addr_space_t as)
14634 if (ADDR_SPACE_GENERIC_P (as))
14635 return avr_legitimize_address (x, old_x, mode);
14637 if (avr_log.legitimize_address)
14639 avr_edump ("\n%?: mode=%m\n %r\n", mode, old_x);
14642 return old_x;
14646 /* Implement `TARGET_ADDR_SPACE_CONVERT'. */
14648 static rtx
14649 avr_addr_space_convert (rtx src, tree type_from, tree type_to)
14651 addr_space_t as_from = TYPE_ADDR_SPACE (TREE_TYPE (type_from));
14652 addr_space_t as_to = TYPE_ADDR_SPACE (TREE_TYPE (type_to));
14654 if (avr_log.progmem)
14655 avr_edump ("\n%!: op = %r\nfrom = %t\nto = %t\n",
14656 src, type_from, type_to);
14658 /* Up-casting from 16-bit to 24-bit pointer. */
14660 if (as_from != ADDR_SPACE_MEMX
14661 && as_to == ADDR_SPACE_MEMX)
14663 rtx sym = src;
14664 rtx reg = gen_reg_rtx (PSImode);
14666 while (CONST == GET_CODE (sym) || PLUS == GET_CODE (sym))
14667 sym = XEXP (sym, 0);
14669 /* Look at symbol flags: avr_encode_section_info set the flags
14670 also if attribute progmem was seen so that we get the right
14671 promotion for, e.g. PSTR-like strings that reside in generic space
14672 but are located in flash. In that case we patch the incoming
14673 address space. */
14675 if (SYMBOL_REF_P (sym)
14676 && ADDR_SPACE_FLASH == AVR_SYMBOL_GET_ADDR_SPACE (sym))
14678 as_from = ADDR_SPACE_FLASH;
14681 /* Linearize memory: RAM has bit 23 set. */
14683 int msb = ADDR_SPACE_GENERIC_P (as_from)
14684 ? 0x80
14685 : avr_addrspace[as_from].segment;
14687 src = force_reg (Pmode, src);
14689 emit_insn (msb == 0
14690 ? gen_zero_extendhipsi2 (reg, src)
14691 : gen_n_extendhipsi2 (reg, gen_int_mode (msb, QImode), src));
14693 return reg;
14696 /* Down-casting from 24-bit to 16-bit throws away the high byte. */
14698 if (as_from == ADDR_SPACE_MEMX
14699 && as_to != ADDR_SPACE_MEMX)
14701 rtx new_src = gen_reg_rtx (Pmode);
14703 src = force_reg (PSImode, src);
14705 emit_move_insn (new_src,
14706 simplify_gen_subreg (Pmode, src, PSImode, 0));
14707 return new_src;
14710 return src;
14714 /* Implement `TARGET_ADDR_SPACE_SUBSET_P'. */
14716 static bool
14717 avr_addr_space_subset_p (addr_space_t /*subset*/, addr_space_t /*superset*/)
14719 /* Allow any kind of pointer mess. */
14721 return true;
14725 /* Implement `TARGET_CONVERT_TO_TYPE'. */
14727 static tree
14728 avr_convert_to_type (tree type, tree expr)
14730 /* Print a diagnose for pointer conversion that changes the address
14731 space of the pointer target to a non-enclosing address space,
14732 provided -Waddr-space-convert is on.
14734 FIXME: Filter out cases where the target object is known to
14735 be located in the right memory, like in
14737 (const __flash*) PSTR ("text")
14739 Also try to distinguish between explicit casts requested by
14740 the user and implicit casts like
14742 void f (const __flash char*);
14744 void g (const char *p)
14746 f ((const __flash*) p);
14749 under the assumption that an explicit casts means that the user
14750 knows what he is doing, e.g. interface with PSTR or old style
14751 code with progmem and pgm_read_xxx.
14754 if (avr_warn_addr_space_convert
14755 && expr != error_mark_node
14756 && POINTER_TYPE_P (type)
14757 && POINTER_TYPE_P (TREE_TYPE (expr)))
14759 addr_space_t as_old = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (expr)));
14760 addr_space_t as_new = TYPE_ADDR_SPACE (TREE_TYPE (type));
14762 if (avr_log.progmem)
14763 avr_edump ("%?: type = %t\nexpr = %t\n\n", type, expr);
14765 if (as_new != ADDR_SPACE_MEMX
14766 && as_new != as_old)
14768 location_t loc = EXPR_LOCATION (expr);
14769 const char *name_old = avr_addrspace[as_old].name;
14770 const char *name_new = avr_addrspace[as_new].name;
14772 warning (OPT_Waddr_space_convert,
14773 "conversion from address space %qs to address space %qs",
14774 ADDR_SPACE_GENERIC_P (as_old) ? "generic" : name_old,
14775 ADDR_SPACE_GENERIC_P (as_new) ? "generic" : name_new);
14777 return fold_build1_loc (loc, ADDR_SPACE_CONVERT_EXPR, type, expr);
14781 return NULL_TREE;
14785 /* Implement `TARGET_LEGITIMATE_COMBINED_INSN'. */
14786 /* PR78883: Filter out paradoxical SUBREGs of MEM which are not handled
14787 properly by following passes. As INSN_SCHEDULING is off and hence
14788 general_operand accepts such expressions, ditch them now. */
14790 static bool
14791 avr_legitimate_combined_insn (rtx_insn *insn)
14793 subrtx_iterator::array_type array;
14795 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
14797 const_rtx op = *iter;
14799 if (SUBREG_P (op)
14800 && MEM_P (SUBREG_REG (op))
14801 && (GET_MODE_SIZE (GET_MODE (op))
14802 > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op)))))
14804 return false;
14808 return true;
14812 /* PR63633: The middle-end might come up with hard regs as input operands.
14814 RMASK is a bit mask representing a subset of hard registers R0...R31:
14815 Rn is an element of that set iff bit n of RMASK is set.
14816 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
14817 OP[n] has to be fixed; otherwise OP[n] is left alone.
14819 For each element of OPMASK which is a hard register overlapping RMASK,
14820 replace OP[n] with a newly created pseudo register
14822 HREG == 0: Also emit a move insn that copies the contents of that
14823 hard register into the new pseudo.
14825 HREG != 0: Also set HREG[n] to the hard register. */
14827 static void
14828 avr_fix_operands (rtx *op, rtx *hreg, unsigned opmask, unsigned rmask)
14830 for (; opmask; opmask >>= 1, op++)
14832 rtx reg = *op;
14834 if (hreg)
14835 *hreg = NULL_RTX;
14837 if ((opmask & 1)
14838 && REG_P (reg)
14839 && REGNO (reg) < FIRST_PSEUDO_REGISTER
14840 // This hard-reg overlaps other prohibited hard regs?
14841 && (rmask & regmask (GET_MODE (reg), REGNO (reg))))
14843 *op = gen_reg_rtx (GET_MODE (reg));
14844 if (hreg == NULL)
14845 emit_move_insn (*op, reg);
14846 else
14847 *hreg = reg;
14850 if (hreg)
14851 hreg++;
14856 void
14857 avr_fix_inputs (rtx *op, unsigned opmask, unsigned rmask)
14859 avr_fix_operands (op, NULL, opmask, rmask);
14863 /* Helper for the function below: If bit n of MASK is set and
14864 HREG[n] != NULL, then emit a move insn to copy OP[n] to HREG[n].
14865 Otherwise do nothing for that n. Return TRUE. */
14867 static bool
14868 avr_move_fixed_operands (rtx *op, rtx *hreg, unsigned mask)
14870 for (; mask; mask >>= 1, op++, hreg++)
14871 if ((mask & 1)
14872 && *hreg)
14873 emit_move_insn (*hreg, *op);
14875 return true;
14879 /* PR63633: The middle-end might come up with hard regs as output operands.
14881 GEN is a sequence generating function like gen_mulsi3 with 3 operands OP[].
14882 RMASK is a bit mask representing a subset of hard registers R0...R31:
14883 Rn is an element of that set iff bit n of RMASK is set.
14884 OPMASK describes a subset of OP[]: If bit n of OPMASK is 1 then
14885 OP[n] has to be fixed; otherwise OP[n] is left alone.
14887 Emit the insn sequence as generated by GEN() with all elements of OPMASK
14888 which are hard registers overlapping RMASK replaced by newly created
14889 pseudo registers. After the sequence has been emitted, emit insns that
14890 move the contents of respective pseudos to their hard regs. */
14892 bool
14893 avr_emit3_fix_outputs (rtx (*gen)(rtx,rtx,rtx), rtx *op,
14894 unsigned opmask, unsigned rmask)
14896 const int n = 3;
14897 rtx hreg[n];
14899 /* It is letigimate for GEN to call this function, and in order not to
14900 get self-recursive we use the following static kludge. This is the
14901 only way not to duplicate all expanders and to avoid ugly and
14902 hard-to-maintain C-code instead of the much more appreciated RTL
14903 representation as supplied by define_expand. */
14904 static bool lock = false;
14906 gcc_assert (opmask < (1u << n));
14908 if (lock)
14909 return false;
14911 avr_fix_operands (op, hreg, opmask, rmask);
14913 lock = true;
14914 emit_insn (gen (op[0], op[1], op[2]));
14915 lock = false;
14917 return avr_move_fixed_operands (op, hreg, opmask);
14921 /* Worker function for cpymemhi expander.
14922 XOP[0] Destination as MEM:BLK
14923 XOP[1] Source " "
14924 XOP[2] # Bytes to copy
14926 Return TRUE if the expansion is accomplished.
14927 Return FALSE if the operand compination is not supported. */
14929 bool
14930 avr_emit_cpymemhi (rtx *xop)
14932 machine_mode loop_mode;
14933 addr_space_t as = MEM_ADDR_SPACE (xop[1]);
14934 rtx loop_reg, addr1, insn;
14935 rtx a_hi8 = NULL_RTX;
14937 if (avr_mem_flash_p (xop[0]))
14938 return false;
14940 if (!CONST_INT_P (xop[2]))
14941 return false;
14943 HOST_WIDE_INT count = INTVAL (xop[2]);
14944 if (count <= 0)
14945 return false;
14947 rtx a_src = XEXP (xop[1], 0);
14948 rtx a_dest = XEXP (xop[0], 0);
14950 if (PSImode == GET_MODE (a_src))
14952 gcc_assert (as == ADDR_SPACE_MEMX);
14954 loop_mode = (count < 0x100) ? QImode : HImode;
14955 loop_reg = gen_rtx_REG (loop_mode, 24);
14956 emit_move_insn (loop_reg, gen_int_mode (count, loop_mode));
14958 addr1 = simplify_gen_subreg (HImode, a_src, PSImode, 0);
14959 a_hi8 = simplify_gen_subreg (QImode, a_src, PSImode, 2);
14961 else
14963 int segment = avr_addrspace[as].segment;
14965 if (segment
14966 && avr_n_flash > 1)
14968 a_hi8 = GEN_INT (segment);
14969 emit_move_insn (rampz_rtx, a_hi8 = copy_to_mode_reg (QImode, a_hi8));
14971 else if (!ADDR_SPACE_GENERIC_P (as))
14973 as = ADDR_SPACE_FLASH;
14976 addr1 = a_src;
14978 loop_mode = (count <= 0x100) ? QImode : HImode;
14979 loop_reg = copy_to_mode_reg (loop_mode, gen_int_mode (count, loop_mode));
14982 rtx xas = GEN_INT (as);
14984 /* FIXME: Register allocator might come up with spill fails if it is left
14985 on its own. Thus, we allocate the pointer registers by hand:
14986 Z = source address
14987 X = destination address */
14989 emit_move_insn (lpm_addr_reg_rtx, addr1);
14990 emit_move_insn (gen_rtx_REG (HImode, REG_X), a_dest);
14992 /* FIXME: Register allocator does a bad job and might spill address
14993 register(s) inside the loop leading to additional move instruction
14994 to/from stack which could clobber tmp_reg. Thus, do *not* emit
14995 load and store as separate insns. Instead, we perform the copy
14996 by means of one monolithic insn. */
14998 gcc_assert (TMP_REGNO == LPM_REGNO);
15000 if (as != ADDR_SPACE_MEMX)
15002 /* Load instruction ([E]LPM or LD) is known at compile time:
15003 Do the copy-loop inline. */
15005 rtx (*fun) (rtx, rtx, rtx)
15006 = QImode == loop_mode ? gen_cpymem_qi : gen_cpymem_hi;
15008 insn = fun (xas, loop_reg, loop_reg);
15010 else
15012 rtx (*fun) (rtx, rtx)
15013 = QImode == loop_mode ? gen_cpymemx_qi : gen_cpymemx_hi;
15015 emit_move_insn (gen_rtx_REG (QImode, 23), a_hi8);
15017 insn = fun (xas, GEN_INT (avr_addr.rampz));
15020 set_mem_addr_space (SET_SRC (XVECEXP (insn, 0, 0)), as);
15021 emit_insn (insn);
15023 return true;
15027 /* Print assembler for cpymem_qi, cpymem_hi insns...
15028 $0 : Address Space
15029 $1, $2 : Loop register
15030 Z : Source address
15031 X : Destination address
15034 const char *
15035 avr_out_cpymem (rtx_insn * /*insn*/, rtx *op, int *plen)
15037 addr_space_t as = (addr_space_t) INTVAL (op[0]);
15038 machine_mode loop_mode = GET_MODE (op[1]);
15039 bool sbiw_p = avr_adiw_reg_p (op[1]);
15040 rtx xop[3] = { op[0], op[1], tmp_reg_rtx };
15042 if (plen)
15043 *plen = 0;
15045 /* Loop label */
15047 avr_asm_len ("0:", xop, plen, 0);
15049 /* Load with post-increment */
15051 switch (as)
15053 default:
15054 gcc_unreachable();
15056 case ADDR_SPACE_GENERIC:
15058 avr_asm_len ("ld %2,Z+", xop, plen, 1);
15059 break;
15061 case ADDR_SPACE_FLASH:
15063 if (AVR_HAVE_LPMX)
15064 avr_asm_len ("lpm %2,Z+", xop, plen, 1);
15065 else
15066 avr_asm_len ("lpm" CR_TAB
15067 "adiw r30,1", xop, plen, 2);
15068 break;
15070 case ADDR_SPACE_FLASH1:
15071 case ADDR_SPACE_FLASH2:
15072 case ADDR_SPACE_FLASH3:
15073 case ADDR_SPACE_FLASH4:
15074 case ADDR_SPACE_FLASH5:
15076 if (AVR_HAVE_ELPMX)
15077 avr_asm_len ("elpm %2,Z+", xop, plen, 1);
15078 else
15079 avr_asm_len ("elpm" CR_TAB
15080 "adiw r30,1", xop, plen, 2);
15081 break;
15084 /* Store with post-increment */
15086 avr_asm_len ("st X+,%2", xop, plen, 1);
15088 /* Decrement loop-counter and set Z-flag */
15090 if (QImode == loop_mode)
15092 avr_asm_len ("dec %1", xop, plen, 1);
15094 else if (sbiw_p)
15096 avr_asm_len ("sbiw %1,1", xop, plen, 1);
15098 else
15100 avr_asm_len ("subi %A1,1" CR_TAB
15101 "sbci %B1,0", xop, plen, 2);
15104 /* Loop until zero */
15106 return avr_asm_len ("brne 0b", xop, plen, 1);
15111 /* Helper for __builtin_avr_delay_cycles */
15113 static rtx
15114 avr_mem_clobber (void)
15116 rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15117 MEM_VOLATILE_P (mem) = 1;
15118 return mem;
15121 static void
15122 avr_expand_delay_cycles (rtx operands0)
15124 unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
15125 unsigned HOST_WIDE_INT cycles_used;
15126 unsigned HOST_WIDE_INT loop_count;
15128 if (IN_RANGE (cycles, 83886082, 0xFFFFFFFF))
15130 loop_count = ((cycles - 9) / 6) + 1;
15131 cycles_used = ((loop_count - 1) * 6) + 9;
15132 emit_insn (gen_delay_cycles_4 (gen_int_mode (loop_count, SImode),
15133 avr_mem_clobber()));
15134 cycles -= cycles_used;
15137 if (IN_RANGE (cycles, 262145, 83886081))
15139 loop_count = ((cycles - 7) / 5) + 1;
15140 if (loop_count > 0xFFFFFF)
15141 loop_count = 0xFFFFFF;
15142 cycles_used = ((loop_count - 1) * 5) + 7;
15143 emit_insn (gen_delay_cycles_3 (gen_int_mode (loop_count, SImode),
15144 avr_mem_clobber()));
15145 cycles -= cycles_used;
15148 if (IN_RANGE (cycles, 768, 262144))
15150 loop_count = ((cycles - 5) / 4) + 1;
15151 if (loop_count > 0xFFFF)
15152 loop_count = 0xFFFF;
15153 cycles_used = ((loop_count - 1) * 4) + 5;
15154 emit_insn (gen_delay_cycles_2 (gen_int_mode (loop_count, HImode),
15155 avr_mem_clobber()));
15156 cycles -= cycles_used;
15159 if (IN_RANGE (cycles, 6, 767))
15161 loop_count = cycles / 3;
15162 if (loop_count > 255)
15163 loop_count = 255;
15164 cycles_used = loop_count * 3;
15165 emit_insn (gen_delay_cycles_1 (gen_int_mode (loop_count, QImode),
15166 avr_mem_clobber()));
15167 cycles -= cycles_used;
15170 while (cycles >= 2)
15172 emit_insn (gen_nopv (GEN_INT (2)));
15173 cycles -= 2;
15176 if (cycles == 1)
15178 emit_insn (gen_nopv (GEN_INT (1)));
15179 cycles--;
15184 static void
15185 avr_expand_nops (rtx operands0)
15187 unsigned HOST_WIDE_INT n_nops = UINTVAL (operands0) & GET_MODE_MASK (HImode);
15189 while (n_nops--)
15191 emit_insn (gen_nopv (const1_rtx));
15196 /* Compute the image of x under f, i.e. perform x --> f(x) */
15198 static int
15199 avr_map (unsigned int f, int x)
15201 return x < 8 ? (f >> (4 * x)) & 0xf : 0;
15205 /* Return some metrics of map A. */
15207 enum
15209 /* Number of fixed points in { 0 ... 7 } */
15210 MAP_FIXED_0_7,
15212 /* Size of preimage of non-fixed points in { 0 ... 7 } */
15213 MAP_NONFIXED_0_7,
15215 /* Mask representing the fixed points in { 0 ... 7 } */
15216 MAP_MASK_FIXED_0_7,
15218 /* Size of the preimage of { 0 ... 7 } */
15219 MAP_PREIMAGE_0_7,
15221 /* Mask that represents the preimage of { f } */
15222 MAP_MASK_PREIMAGE_F
15225 static unsigned
15226 avr_map_metric (unsigned int a, int mode)
15228 unsigned metric = 0;
15230 for (unsigned i = 0; i < 8; i++)
15232 unsigned ai = avr_map (a, i);
15234 if (mode == MAP_FIXED_0_7)
15235 metric += ai == i;
15236 else if (mode == MAP_NONFIXED_0_7)
15237 metric += ai < 8 && ai != i;
15238 else if (mode == MAP_MASK_FIXED_0_7)
15239 metric |= ((unsigned) (ai == i)) << i;
15240 else if (mode == MAP_PREIMAGE_0_7)
15241 metric += ai < 8;
15242 else if (mode == MAP_MASK_PREIMAGE_F)
15243 metric |= ((unsigned) (ai == 0xf)) << i;
15244 else
15245 gcc_unreachable();
15248 return metric;
15252 /* Return true if IVAL has a 0xf in its hexadecimal representation
15253 and false, otherwise. Only nibbles 0..7 are taken into account.
15254 Used as constraint helper for C0f and Cxf. */
15256 bool
15257 avr_has_nibble_0xf (rtx ival)
15259 unsigned int map = UINTVAL (ival) & GET_MODE_MASK (SImode);
15260 return avr_map_metric (map, MAP_MASK_PREIMAGE_F) != 0;
15264 /* We have a set of bits that are mapped by a function F.
15265 Try to decompose F by means of a second function G so that
15267 F = F o G^-1 o G
15271 cost (F o G^-1) + cost (G) < cost (F)
15273 Example: Suppose builtin insert_bits supplies us with the map
15274 F = 0x3210ffff. Instead of doing 4 bit insertions to get the high
15275 nibble of the result, we can just as well rotate the bits before inserting
15276 them and use the map 0x7654ffff which is cheaper than the original map.
15277 For this example G = G^-1 = 0x32107654 and F o G^-1 = 0x7654ffff. */
15279 typedef struct
15281 /* tree code of binary function G */
15282 enum tree_code code;
15284 /* The constant second argument of G */
15285 int arg;
15287 /* G^-1, the inverse of G (*, arg) */
15288 unsigned ginv;
15290 /* The cost of applying G (*, arg) */
15291 int cost;
15293 /* The composition F o G^-1 (*, arg) for some function F */
15294 unsigned int map;
15296 /* For debug purpose only */
15297 const char *str;
15298 } avr_map_op_t;
15300 static const avr_map_op_t avr_map_op[] =
15302 { LROTATE_EXPR, 0, 0x76543210, 0, 0, "id" },
15303 { LROTATE_EXPR, 1, 0x07654321, 2, 0, "<<<" },
15304 { LROTATE_EXPR, 2, 0x10765432, 4, 0, "<<<" },
15305 { LROTATE_EXPR, 3, 0x21076543, 4, 0, "<<<" },
15306 { LROTATE_EXPR, 4, 0x32107654, 1, 0, "<<<" },
15307 { LROTATE_EXPR, 5, 0x43210765, 3, 0, "<<<" },
15308 { LROTATE_EXPR, 6, 0x54321076, 5, 0, "<<<" },
15309 { LROTATE_EXPR, 7, 0x65432107, 3, 0, "<<<" },
15310 { RSHIFT_EXPR, 1, 0x6543210c, 1, 0, ">>" },
15311 { RSHIFT_EXPR, 1, 0x7543210c, 1, 0, ">>" },
15312 { RSHIFT_EXPR, 2, 0x543210cc, 2, 0, ">>" },
15313 { RSHIFT_EXPR, 2, 0x643210cc, 2, 0, ">>" },
15314 { RSHIFT_EXPR, 2, 0x743210cc, 2, 0, ">>" },
15315 { LSHIFT_EXPR, 1, 0xc7654321, 1, 0, "<<" },
15316 { LSHIFT_EXPR, 2, 0xcc765432, 2, 0, "<<" }
15320 /* Try to decompose F as F = (F o G^-1) o G as described above.
15321 The result is a struct representing F o G^-1 and G.
15322 If result.cost < 0 then such a decomposition does not exist. */
15324 static avr_map_op_t
15325 avr_map_decompose (unsigned int f, const avr_map_op_t *g, bool val_const_p)
15327 bool val_used_p = avr_map_metric (f, MAP_MASK_PREIMAGE_F) != 0;
15328 avr_map_op_t f_ginv = *g;
15329 unsigned int ginv = g->ginv;
15331 f_ginv.cost = -1;
15333 /* Step 1: Computing F o G^-1 */
15335 for (int i = 7; i >= 0; i--)
15337 int x = avr_map (f, i);
15339 if (x <= 7)
15341 x = avr_map (ginv, x);
15343 /* The bit is no element of the image of G: no avail (cost = -1) */
15345 if (x > 7)
15346 return f_ginv;
15349 f_ginv.map = (f_ginv.map << 4) + x;
15352 /* Step 2: Compute the cost of the operations.
15353 The overall cost of doing an operation prior to the insertion is
15354 the cost of the insertion plus the cost of the operation. */
15356 /* Step 2a: Compute cost of F o G^-1 */
15358 if (avr_map_metric (f_ginv.map, MAP_NONFIXED_0_7) == 0)
15359 /* The mapping consists only of fixed points and can be folded
15360 to AND/OR logic in the remainder. Reasonable cost is 3. */
15361 f_ginv.cost = 2 + (val_used_p && !val_const_p);
15362 else
15364 rtx xop[4];
15366 /* Get the cost of the insn by calling the output worker with some
15367 fake values. Mimic effect of reloading xop[3]: Unused operands
15368 are mapped to 0 and used operands are reloaded to xop[0]. */
15370 xop[0] = all_regs_rtx[REG_24];
15371 xop[1] = gen_int_mode (f_ginv.map, SImode);
15372 xop[2] = all_regs_rtx[REG_25];
15373 xop[3] = val_used_p ? xop[0] : const0_rtx;
15375 avr_out_insert_bits (xop, &f_ginv.cost);
15377 f_ginv.cost += val_const_p && val_used_p ? 1 : 0;
15380 /* Step 2b: Add cost of G */
15382 f_ginv.cost += g->cost;
15384 if (avr_log.builtin)
15385 avr_edump (" %s%d=%d", g->str, g->arg, f_ginv.cost);
15387 return f_ginv;
15391 /* Insert bits from XOP[1] into XOP[0] according to MAP.
15392 XOP[0] and XOP[1] don't overlap.
15393 If FIXP_P = true: Move all bits according to MAP using BLD/BST sequences.
15394 If FIXP_P = false: Just move the bit if its position in the destination
15395 is different to its source position. */
15397 static void
15398 avr_move_bits (rtx *xop, unsigned int map, bool fixp_p, int *plen)
15400 /* T-flag contains this bit of the source, i.e. of XOP[1] */
15401 int t_bit_src = -1;
15403 /* We order the operations according to the requested source bit b. */
15405 for (int b = 0; b < 8; b++)
15406 for (int bit_dest = 0; bit_dest < 8; bit_dest++)
15408 int bit_src = avr_map (map, bit_dest);
15410 if (b != bit_src
15411 || bit_src >= 8
15412 /* Same position: No need to copy as requested by FIXP_P. */
15413 || (bit_dest == bit_src && !fixp_p))
15414 continue;
15416 if (t_bit_src != bit_src)
15418 /* Source bit is not yet in T: Store it to T. */
15420 t_bit_src = bit_src;
15422 xop[3] = GEN_INT (bit_src);
15423 avr_asm_len ("bst %T1%T3", xop, plen, 1);
15426 /* Load destination bit with T. */
15428 xop[3] = GEN_INT (bit_dest);
15429 avr_asm_len ("bld %T0%T3", xop, plen, 1);
15434 /* PLEN == 0: Print assembler code for `insert_bits'.
15435 PLEN != 0: Compute code length in bytes.
15437 OP[0]: Result
15438 OP[1]: The mapping composed of nibbles. If nibble no. N is
15439 0: Bit N of result is copied from bit OP[2].0
15440 ... ...
15441 7: Bit N of result is copied from bit OP[2].7
15442 0xf: Bit N of result is copied from bit OP[3].N
15443 OP[2]: Bits to be inserted
15444 OP[3]: Target value */
15446 const char *
15447 avr_out_insert_bits (rtx *op, int *plen)
15449 unsigned int map = UINTVAL (op[1]) & GET_MODE_MASK (SImode);
15450 bool fixp_p = true;
15451 rtx xop[4];
15453 xop[0] = op[0];
15454 xop[1] = op[2];
15455 xop[2] = op[3];
15457 gcc_assert (REG_P (xop[2]) || CONST_INT_P (xop[2]));
15459 if (plen)
15460 *plen = 0;
15461 else if (flag_print_asm_name)
15462 fprintf (asm_out_file, ASM_COMMENT_START "map = 0x%08x\n", map);
15464 /* If MAP has fixed points it might be better to initialize the result
15465 with the bits to be inserted instead of moving all bits by hand. */
15467 unsigned mask_fixed = avr_map_metric (map, MAP_MASK_FIXED_0_7);
15469 if (REGNO (xop[0]) == REGNO (xop[1]))
15471 /* Avoid early-clobber conflicts */
15473 avr_asm_len ("mov __tmp_reg__,%1", xop, plen, 1);
15474 xop[1] = tmp_reg_rtx;
15475 fixp_p = false;
15478 if (avr_map_metric (map, MAP_MASK_PREIMAGE_F))
15480 /* XOP[2] is used and reloaded to XOP[0] already */
15482 int n_fix = 0, n_nofix = 0;
15484 gcc_assert (REG_P (xop[2]));
15486 /* Get the code size of the bit insertions; once with all bits
15487 moved and once with fixed points omitted. */
15489 avr_move_bits (xop, map, true, &n_fix);
15490 avr_move_bits (xop, map, false, &n_nofix);
15492 if (fixp_p && n_fix - n_nofix > 3)
15494 xop[3] = gen_int_mode (~mask_fixed, QImode);
15496 avr_asm_len ("eor %0,%1" CR_TAB
15497 "andi %0,%3" CR_TAB
15498 "eor %0,%1", xop, plen, 3);
15499 fixp_p = false;
15502 else
15504 /* XOP[2] is unused */
15506 if (fixp_p && mask_fixed)
15508 avr_asm_len ("mov %0,%1", xop, plen, 1);
15509 fixp_p = false;
15513 /* Move/insert remaining bits. */
15515 avr_move_bits (xop, map, fixp_p, plen);
15517 return "";
15521 /* IDs for all the AVR builtins. */
15523 enum avr_builtin_id
15525 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
15526 AVR_BUILTIN_ ## NAME,
15527 #include "builtins.def"
15528 #undef DEF_BUILTIN
15530 AVR_BUILTIN_COUNT
15533 struct GTY(()) avr_builtin_description
15535 enum insn_code icode;
15536 int n_args;
15537 tree fndecl;
15541 /* Notice that avr_bdesc[] and avr_builtin_id are initialized in such a way
15542 that a built-in's ID can be used to access the built-in by means of
15543 avr_bdesc[ID] */
15545 static GTY(()) struct avr_builtin_description
15546 avr_bdesc[AVR_BUILTIN_COUNT] =
15548 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, LIBNAME) \
15549 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
15550 #include "builtins.def"
15551 #undef DEF_BUILTIN
15555 /* Implement `TARGET_BUILTIN_DECL'. */
15557 static tree
15558 avr_builtin_decl (unsigned id, bool /*initialize_p*/)
15560 if (id < AVR_BUILTIN_COUNT)
15561 return avr_bdesc[id].fndecl;
15563 return error_mark_node;
15567 static void
15568 avr_init_builtin_int24 (void)
15570 tree int24_type = make_signed_type (GET_MODE_BITSIZE (PSImode));
15571 tree uint24_type = make_unsigned_type (GET_MODE_BITSIZE (PSImode));
15573 lang_hooks.types.register_builtin_type (int24_type, "__int24");
15574 lang_hooks.types.register_builtin_type (uint24_type, "__uint24");
15578 /* Implement `TARGET_INIT_BUILTINS' */
15579 /* Set up all builtin functions for this target. */
15581 static void
15582 avr_init_builtins (void)
15584 tree void_ftype_void
15585 = build_function_type_list (void_type_node, NULL_TREE);
15586 tree uintQI_ftype_uintQI
15587 = build_function_type_list (unsigned_intQI_type_node,
15588 unsigned_intQI_type_node,
15589 NULL_TREE);
15590 tree uintHI_ftype_uintQI_uintQI
15591 = build_function_type_list (unsigned_intHI_type_node,
15592 unsigned_intQI_type_node,
15593 unsigned_intQI_type_node,
15594 NULL_TREE);
15595 tree intHI_ftype_intQI_intQI
15596 = build_function_type_list (intHI_type_node,
15597 intQI_type_node,
15598 intQI_type_node,
15599 NULL_TREE);
15600 tree intHI_ftype_intQI_uintQI
15601 = build_function_type_list (intHI_type_node,
15602 intQI_type_node,
15603 unsigned_intQI_type_node,
15604 NULL_TREE);
15605 tree void_ftype_uintSI
15606 = build_function_type_list (void_type_node,
15607 unsigned_intSI_type_node,
15608 NULL_TREE);
15610 tree uintQI_ftype_uintSI_uintQI_uintQI
15611 = build_function_type_list (unsigned_intQI_type_node,
15612 unsigned_intSI_type_node,
15613 unsigned_intQI_type_node,
15614 unsigned_intQI_type_node,
15615 NULL_TREE);
15617 tree const_memx_void_node
15618 = build_qualified_type (void_type_node,
15619 TYPE_QUAL_CONST
15620 | ENCODE_QUAL_ADDR_SPACE (ADDR_SPACE_MEMX));
15622 tree const_memx_ptr_type_node
15623 = build_pointer_type_for_mode (const_memx_void_node, PSImode, false);
15625 tree intQI_ftype_const_memx_ptr
15626 = build_function_type_list (intQI_type_node,
15627 const_memx_ptr_type_node,
15628 NULL);
15630 #define ITYP(T) \
15631 lang_hooks.types.type_for_size (TYPE_PRECISION (T), TYPE_UNSIGNED (T))
15633 #define FX_FTYPE_FX(fx) \
15634 tree fx##r_ftype_##fx##r \
15635 = build_function_type_list (node_##fx##r, node_##fx##r, NULL); \
15636 tree fx##k_ftype_##fx##k \
15637 = build_function_type_list (node_##fx##k, node_##fx##k, NULL)
15639 #define FX_FTYPE_FX_INT(fx) \
15640 tree fx##r_ftype_##fx##r_int \
15641 = build_function_type_list (node_##fx##r, node_##fx##r, \
15642 integer_type_node, NULL); \
15643 tree fx##k_ftype_##fx##k_int \
15644 = build_function_type_list (node_##fx##k, node_##fx##k, \
15645 integer_type_node, NULL)
15647 #define INT_FTYPE_FX(fx) \
15648 tree int_ftype_##fx##r \
15649 = build_function_type_list (integer_type_node, node_##fx##r, NULL); \
15650 tree int_ftype_##fx##k \
15651 = build_function_type_list (integer_type_node, node_##fx##k, NULL)
15653 #define INTX_FTYPE_FX(fx) \
15654 tree int##fx##r_ftype_##fx##r \
15655 = build_function_type_list (ITYP (node_##fx##r), node_##fx##r, NULL); \
15656 tree int##fx##k_ftype_##fx##k \
15657 = build_function_type_list (ITYP (node_##fx##k), node_##fx##k, NULL)
15659 #define FX_FTYPE_INTX(fx) \
15660 tree fx##r_ftype_int##fx##r \
15661 = build_function_type_list (node_##fx##r, ITYP (node_##fx##r), NULL); \
15662 tree fx##k_ftype_int##fx##k \
15663 = build_function_type_list (node_##fx##k, ITYP (node_##fx##k), NULL)
15665 tree node_hr = short_fract_type_node;
15666 tree node_nr = fract_type_node;
15667 tree node_lr = long_fract_type_node;
15668 tree node_llr = long_long_fract_type_node;
15670 tree node_uhr = unsigned_short_fract_type_node;
15671 tree node_unr = unsigned_fract_type_node;
15672 tree node_ulr = unsigned_long_fract_type_node;
15673 tree node_ullr = unsigned_long_long_fract_type_node;
15675 tree node_hk = short_accum_type_node;
15676 tree node_nk = accum_type_node;
15677 tree node_lk = long_accum_type_node;
15678 tree node_llk = long_long_accum_type_node;
15680 tree node_uhk = unsigned_short_accum_type_node;
15681 tree node_unk = unsigned_accum_type_node;
15682 tree node_ulk = unsigned_long_accum_type_node;
15683 tree node_ullk = unsigned_long_long_accum_type_node;
15686 /* For absfx builtins. */
15688 FX_FTYPE_FX (h);
15689 FX_FTYPE_FX (n);
15690 FX_FTYPE_FX (l);
15691 FX_FTYPE_FX (ll);
15693 /* For roundfx builtins. */
15695 FX_FTYPE_FX_INT (h);
15696 FX_FTYPE_FX_INT (n);
15697 FX_FTYPE_FX_INT (l);
15698 FX_FTYPE_FX_INT (ll);
15700 FX_FTYPE_FX_INT (uh);
15701 FX_FTYPE_FX_INT (un);
15702 FX_FTYPE_FX_INT (ul);
15703 FX_FTYPE_FX_INT (ull);
15705 /* For countlsfx builtins. */
15707 INT_FTYPE_FX (h);
15708 INT_FTYPE_FX (n);
15709 INT_FTYPE_FX (l);
15710 INT_FTYPE_FX (ll);
15712 INT_FTYPE_FX (uh);
15713 INT_FTYPE_FX (un);
15714 INT_FTYPE_FX (ul);
15715 INT_FTYPE_FX (ull);
15717 /* For bitsfx builtins. */
15719 INTX_FTYPE_FX (h);
15720 INTX_FTYPE_FX (n);
15721 INTX_FTYPE_FX (l);
15722 INTX_FTYPE_FX (ll);
15724 INTX_FTYPE_FX (uh);
15725 INTX_FTYPE_FX (un);
15726 INTX_FTYPE_FX (ul);
15727 INTX_FTYPE_FX (ull);
15729 /* For fxbits builtins. */
15731 FX_FTYPE_INTX (h);
15732 FX_FTYPE_INTX (n);
15733 FX_FTYPE_INTX (l);
15734 FX_FTYPE_INTX (ll);
15736 FX_FTYPE_INTX (uh);
15737 FX_FTYPE_INTX (un);
15738 FX_FTYPE_INTX (ul);
15739 FX_FTYPE_INTX (ull);
15742 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, CODE, LIBNAME) \
15744 int id = AVR_BUILTIN_ ## NAME; \
15745 const char *Name = "__builtin_avr_" #NAME; \
15746 char *name = (char *) alloca (1 + strlen (Name)); \
15748 gcc_assert (id < AVR_BUILTIN_COUNT); \
15749 avr_bdesc[id].fndecl \
15750 = add_builtin_function (avr_tolower (name, Name), TYPE, id, \
15751 BUILT_IN_MD, LIBNAME, NULL_TREE); \
15753 #include "builtins.def"
15754 #undef DEF_BUILTIN
15756 avr_init_builtin_int24 ();
15760 /* Subroutine of avr_expand_builtin to expand vanilla builtins
15761 with non-void result and 1 ... 3 arguments. */
15763 static rtx
15764 avr_default_expand_builtin (enum insn_code icode, tree exp, rtx target)
15766 rtx pat, xop[3];
15767 int n_args = call_expr_nargs (exp);
15768 machine_mode tmode = insn_data[icode].operand[0].mode;
15770 gcc_assert (n_args >= 1 && n_args <= 3);
15772 if (target == NULL_RTX
15773 || GET_MODE (target) != tmode
15774 || !insn_data[icode].operand[0].predicate (target, tmode))
15776 target = gen_reg_rtx (tmode);
15779 for (int n = 0; n < n_args; n++)
15781 tree arg = CALL_EXPR_ARG (exp, n);
15782 rtx op = expand_expr (arg, NULL_RTX, VOIDmode, EXPAND_NORMAL);
15783 machine_mode opmode = GET_MODE (op);
15784 machine_mode mode = insn_data[icode].operand[n + 1].mode;
15786 if ((opmode == SImode || opmode == VOIDmode) && mode == HImode)
15788 opmode = HImode;
15789 op = gen_lowpart (HImode, op);
15792 /* In case the insn wants input operands in modes different from
15793 the result, abort. */
15795 gcc_assert (opmode == mode || opmode == VOIDmode);
15797 if (!insn_data[icode].operand[n + 1].predicate (op, mode))
15798 op = copy_to_mode_reg (mode, op);
15800 xop[n] = op;
15803 switch (n_args)
15805 case 1: pat = GEN_FCN (icode) (target, xop[0]); break;
15806 case 2: pat = GEN_FCN (icode) (target, xop[0], xop[1]); break;
15807 case 3: pat = GEN_FCN (icode) (target, xop[0], xop[1], xop[2]); break;
15809 default:
15810 gcc_unreachable();
15813 if (pat == NULL_RTX)
15814 return NULL_RTX;
15816 emit_insn (pat);
15818 return target;
15822 /* Implement `TARGET_EXPAND_BUILTIN'. */
15823 /* Expand an expression EXP that calls a built-in function,
15824 with result going to TARGET if that's convenient
15825 (and in mode MODE if that's convenient).
15826 SUBTARGET may be used as the target for computing one of EXP's operands.
15827 IGNORE is nonzero if the value is to be ignored. */
15829 static rtx
15830 avr_expand_builtin (tree exp, rtx target, rtx /*subtarget*/,
15831 machine_mode mode, int ignore)
15833 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
15834 const char *bname = IDENTIFIER_POINTER (DECL_NAME (fndecl));
15835 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
15836 const struct avr_builtin_description *d = &avr_bdesc[id];
15837 tree arg0;
15838 rtx op0;
15840 gcc_assert (id < AVR_BUILTIN_COUNT);
15842 switch (id)
15844 case AVR_BUILTIN_NOP:
15845 emit_insn (gen_nopv (GEN_INT (1)));
15846 return 0;
15848 case AVR_BUILTIN_DELAY_CYCLES:
15850 arg0 = CALL_EXPR_ARG (exp, 0);
15851 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
15853 if (!CONST_INT_P (op0))
15854 error ("%s expects a compile time integer constant", bname);
15855 else
15856 avr_expand_delay_cycles (op0);
15858 return NULL_RTX;
15861 case AVR_BUILTIN_NOPS:
15863 arg0 = CALL_EXPR_ARG (exp, 0);
15864 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
15866 if (!CONST_INT_P (op0))
15867 error ("%s expects a compile time integer constant", bname);
15868 else
15869 avr_expand_nops (op0);
15871 return NULL_RTX;
15874 case AVR_BUILTIN_INSERT_BITS:
15876 arg0 = CALL_EXPR_ARG (exp, 0);
15877 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
15879 if (!CONST_INT_P (op0))
15881 error ("%s expects a compile time long integer constant"
15882 " as first argument", bname);
15883 return target;
15886 break;
15889 case AVR_BUILTIN_ROUNDHR: case AVR_BUILTIN_ROUNDUHR:
15890 case AVR_BUILTIN_ROUNDR: case AVR_BUILTIN_ROUNDUR:
15891 case AVR_BUILTIN_ROUNDLR: case AVR_BUILTIN_ROUNDULR:
15892 case AVR_BUILTIN_ROUNDLLR: case AVR_BUILTIN_ROUNDULLR:
15894 case AVR_BUILTIN_ROUNDHK: case AVR_BUILTIN_ROUNDUHK:
15895 case AVR_BUILTIN_ROUNDK: case AVR_BUILTIN_ROUNDUK:
15896 case AVR_BUILTIN_ROUNDLK: case AVR_BUILTIN_ROUNDULK:
15897 case AVR_BUILTIN_ROUNDLLK: case AVR_BUILTIN_ROUNDULLK:
15899 /* Warn about odd rounding. Rounding points >= FBIT will have
15900 no effect. */
15902 if (TREE_CODE (CALL_EXPR_ARG (exp, 1)) != INTEGER_CST)
15903 break;
15905 int rbit = (int) TREE_INT_CST_LOW (CALL_EXPR_ARG (exp, 1));
15907 if (rbit >= (int) GET_MODE_FBIT (mode))
15909 warning (OPT_Wextra, "rounding to %d bits has no effect for "
15910 "fixed-point value with %d fractional bits",
15911 rbit, GET_MODE_FBIT (mode));
15913 return expand_expr (CALL_EXPR_ARG (exp, 0), NULL_RTX, mode,
15914 EXPAND_NORMAL);
15916 else if (rbit <= - (int) GET_MODE_IBIT (mode))
15918 warning (0, "rounding result will always be 0");
15919 return CONST0_RTX (mode);
15922 /* The rounding points RP satisfies now: -IBIT < RP < FBIT.
15924 TR 18037 only specifies results for RP > 0. However, the
15925 remaining cases of -IBIT < RP <= 0 can easily be supported
15926 without any additional overhead. */
15928 break; /* round */
15931 /* No fold found and no insn: Call support function from libgcc. */
15933 if (d->icode == CODE_FOR_nothing
15934 && DECL_ASSEMBLER_NAME (get_callee_fndecl (exp)) != NULL_TREE)
15936 return expand_call (exp, target, ignore);
15939 /* No special treatment needed: vanilla expand. */
15941 gcc_assert (d->icode != CODE_FOR_nothing);
15942 gcc_assert (d->n_args == call_expr_nargs (exp));
15944 if (d->n_args == 0)
15946 emit_insn ((GEN_FCN (d->icode)) (target));
15947 return NULL_RTX;
15950 return avr_default_expand_builtin (d->icode, exp, target);
15954 /* Helper for `avr_fold_builtin' that folds absfx (FIXED_CST). */
15956 static tree
15957 avr_fold_absfx (tree tval)
15959 if (FIXED_CST != TREE_CODE (tval))
15960 return NULL_TREE;
15962 /* Our fixed-points have no padding: Use double_int payload directly. */
15964 FIXED_VALUE_TYPE fval = TREE_FIXED_CST (tval);
15965 unsigned int bits = GET_MODE_BITSIZE (fval.mode);
15966 double_int ival = fval.data.sext (bits);
15968 if (!ival.is_negative())
15969 return tval;
15971 /* ISO/IEC TR 18037, 7.18a.6.2: The absfx functions are saturating. */
15973 fval.data = (ival == double_int::min_value (bits, false).sext (bits))
15974 ? double_int::max_value (bits, false)
15975 : -ival;
15977 return build_fixed (TREE_TYPE (tval), fval);
15981 /* Implement `TARGET_FOLD_BUILTIN'. */
15983 static tree
15984 avr_fold_builtin (tree fndecl, int /*n_args*/, tree *arg, bool /*ignore*/)
15986 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
15987 tree val_type = TREE_TYPE (TREE_TYPE (fndecl));
15989 if (!optimize)
15990 return NULL_TREE;
15992 switch (fcode)
15994 default:
15995 break;
15997 case AVR_BUILTIN_SWAP:
15999 return fold_build2 (LROTATE_EXPR, val_type, arg[0],
16000 build_int_cst (val_type, 4));
16003 case AVR_BUILTIN_ABSHR:
16004 case AVR_BUILTIN_ABSR:
16005 case AVR_BUILTIN_ABSLR:
16006 case AVR_BUILTIN_ABSLLR:
16008 case AVR_BUILTIN_ABSHK:
16009 case AVR_BUILTIN_ABSK:
16010 case AVR_BUILTIN_ABSLK:
16011 case AVR_BUILTIN_ABSLLK:
16012 /* GCC is not good with folding ABS for fixed-point. Do it by hand. */
16014 return avr_fold_absfx (arg[0]);
16016 case AVR_BUILTIN_BITSHR: case AVR_BUILTIN_HRBITS:
16017 case AVR_BUILTIN_BITSHK: case AVR_BUILTIN_HKBITS:
16018 case AVR_BUILTIN_BITSUHR: case AVR_BUILTIN_UHRBITS:
16019 case AVR_BUILTIN_BITSUHK: case AVR_BUILTIN_UHKBITS:
16021 case AVR_BUILTIN_BITSR: case AVR_BUILTIN_RBITS:
16022 case AVR_BUILTIN_BITSK: case AVR_BUILTIN_KBITS:
16023 case AVR_BUILTIN_BITSUR: case AVR_BUILTIN_URBITS:
16024 case AVR_BUILTIN_BITSUK: case AVR_BUILTIN_UKBITS:
16026 case AVR_BUILTIN_BITSLR: case AVR_BUILTIN_LRBITS:
16027 case AVR_BUILTIN_BITSLK: case AVR_BUILTIN_LKBITS:
16028 case AVR_BUILTIN_BITSULR: case AVR_BUILTIN_ULRBITS:
16029 case AVR_BUILTIN_BITSULK: case AVR_BUILTIN_ULKBITS:
16031 case AVR_BUILTIN_BITSLLR: case AVR_BUILTIN_LLRBITS:
16032 case AVR_BUILTIN_BITSLLK: case AVR_BUILTIN_LLKBITS:
16033 case AVR_BUILTIN_BITSULLR: case AVR_BUILTIN_ULLRBITS:
16034 case AVR_BUILTIN_BITSULLK: case AVR_BUILTIN_ULLKBITS:
16036 gcc_assert (TYPE_PRECISION (val_type)
16037 == TYPE_PRECISION (TREE_TYPE (arg[0])));
16039 return build1 (VIEW_CONVERT_EXPR, val_type, arg[0]);
16041 case AVR_BUILTIN_INSERT_BITS:
16043 tree tbits = arg[1];
16044 tree tval = arg[2];
16045 tree map_type = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
16046 bool changed = false;
16047 avr_map_op_t best_g;
16049 if (TREE_CODE (arg[0]) != INTEGER_CST)
16051 /* No constant as first argument: Don't fold this and run into
16052 error in avr_expand_builtin. */
16054 break;
16057 tree tmap = wide_int_to_tree (map_type, wi::to_wide (arg[0]));
16058 unsigned int map = TREE_INT_CST_LOW (tmap);
16060 if (TREE_CODE (tval) != INTEGER_CST
16061 && avr_map_metric (map, MAP_MASK_PREIMAGE_F) == 0)
16063 /* There are no F in the map, i.e. 3rd operand is unused.
16064 Replace that argument with some constant to render
16065 respective input unused. */
16067 tval = build_int_cst (val_type, 0);
16068 changed = true;
16071 if (TREE_CODE (tbits) != INTEGER_CST
16072 && avr_map_metric (map, MAP_PREIMAGE_0_7) == 0)
16074 /* Similar for the bits to be inserted. If they are unused,
16075 we can just as well pass 0. */
16077 tbits = build_int_cst (val_type, 0);
16080 if (TREE_CODE (tbits) == INTEGER_CST)
16082 /* Inserting bits known at compile time is easy and can be
16083 performed by AND and OR with appropriate masks. */
16085 int bits = TREE_INT_CST_LOW (tbits);
16086 int mask_ior = 0, mask_and = 0xff;
16088 for (size_t i = 0; i < 8; i++)
16090 int mi = avr_map (map, i);
16092 if (mi < 8)
16094 if (bits & (1 << mi)) mask_ior |= (1 << i);
16095 else mask_and &= ~(1 << i);
16099 tval = fold_build2 (BIT_IOR_EXPR, val_type, tval,
16100 build_int_cst (val_type, mask_ior));
16101 return fold_build2 (BIT_AND_EXPR, val_type, tval,
16102 build_int_cst (val_type, mask_and));
16105 if (changed)
16106 return build_call_expr (fndecl, 3, tmap, tbits, tval);
16108 /* If bits don't change their position, we can use vanilla logic
16109 to merge the two arguments... */
16111 if (avr_map_metric (map, MAP_NONFIXED_0_7) == 0
16112 // ...except when we are copying just one bit. In that
16113 // case, BLD/BST is better than XOR/AND/XOR, see PR90622.
16114 && avr_map_metric (map, MAP_FIXED_0_7) != 1)
16116 int mask_f = avr_map_metric (map, MAP_MASK_PREIMAGE_F);
16117 tree tres, tmask = build_int_cst (val_type, mask_f ^ 0xff);
16119 tres = fold_build2 (BIT_XOR_EXPR, val_type, tbits, tval);
16120 tres = fold_build2 (BIT_AND_EXPR, val_type, tres, tmask);
16121 return fold_build2 (BIT_XOR_EXPR, val_type, tres, tval);
16124 /* Try to decomposing map to reduce overall cost. */
16126 if (avr_log.builtin)
16127 avr_edump ("\n%?: %x\n%?: ROL cost: ", map);
16129 best_g = avr_map_op[0];
16130 best_g.cost = 1000;
16132 for (size_t i = 0; i < ARRAY_SIZE (avr_map_op); i++)
16134 avr_map_op_t g
16135 = avr_map_decompose (map, avr_map_op + i,
16136 TREE_CODE (tval) == INTEGER_CST);
16138 if (g.cost >= 0 && g.cost < best_g.cost)
16139 best_g = g;
16142 if (avr_log.builtin)
16143 avr_edump ("\n");
16145 if (best_g.arg == 0)
16146 /* No optimization found */
16147 break;
16149 /* Apply operation G to the 2nd argument. */
16151 if (avr_log.builtin)
16152 avr_edump ("%?: using OP(%s%d, %x) cost %d\n",
16153 best_g.str, best_g.arg, best_g.map, best_g.cost);
16155 /* Do right-shifts arithmetically: They copy the MSB instead of
16156 shifting in a non-usable value (0) as with logic right-shift. */
16158 tbits = fold_convert (signed_char_type_node, tbits);
16159 tbits = fold_build2 (best_g.code, signed_char_type_node, tbits,
16160 build_int_cst (val_type, best_g.arg));
16161 tbits = fold_convert (val_type, tbits);
16163 /* Use map o G^-1 instead of original map to undo the effect of G. */
16165 tmap = wide_int_to_tree (map_type, best_g.map);
16167 return build_call_expr (fndecl, 3, tmap, tbits, tval);
16168 } /* AVR_BUILTIN_INSERT_BITS */
16171 return NULL_TREE;
16175 /* Implement `TARGET_MD_ASM_ADJUST'. */
16176 /* Prepend to CLOBBERS hard registers that are automatically clobbered
16177 for an asm. We do this for CC_REGNUM to maintain source compatibility
16178 with the original cc0-based compiler. */
16180 static rtx_insn *
16181 avr_md_asm_adjust (vec<rtx> &/*outputs*/, vec<rtx> &/*inputs*/,
16182 vec<machine_mode> & /*input_modes*/,
16183 vec<const char *> &/*constraints*/,
16184 vec<rtx> &/*uses*/,
16185 vec<rtx> &clobbers, HARD_REG_SET &clobbered_regs,
16186 location_t /*loc*/)
16188 clobbers.safe_push (cc_reg_rtx);
16189 SET_HARD_REG_BIT (clobbered_regs, REG_CC);
16190 return NULL;
16194 /* Worker function for `FLOAT_LIB_COMPARE_RETURNS_BOOL'. */
16196 bool
16197 avr_float_lib_compare_returns_bool (machine_mode mode, enum rtx_code)
16199 if (mode == DFmode)
16201 #if WITH_DOUBLE_COMPARISON == 2
16202 return true;
16203 #endif
16206 // This is the GCC default and also what AVR-LibC implements.
16207 return false;
16212 /* Initialize the GCC target structure. */
16214 #undef TARGET_ASM_ALIGNED_HI_OP
16215 #define TARGET_ASM_ALIGNED_HI_OP "\t.word\t"
16216 #undef TARGET_ASM_ALIGNED_SI_OP
16217 #define TARGET_ASM_ALIGNED_SI_OP "\t.long\t"
16218 #undef TARGET_ASM_UNALIGNED_HI_OP
16219 #define TARGET_ASM_UNALIGNED_HI_OP "\t.word\t"
16220 #undef TARGET_ASM_UNALIGNED_SI_OP
16221 #define TARGET_ASM_UNALIGNED_SI_OP "\t.long\t"
16222 #undef TARGET_ASM_INTEGER
16223 #define TARGET_ASM_INTEGER avr_assemble_integer
16224 #undef TARGET_ASM_FILE_START
16225 #define TARGET_ASM_FILE_START avr_file_start
16226 #undef TARGET_ASM_FILE_END
16227 #define TARGET_ASM_FILE_END avr_file_end
16229 #undef TARGET_ASM_FUNCTION_END_PROLOGUE
16230 #define TARGET_ASM_FUNCTION_END_PROLOGUE avr_asm_function_end_prologue
16231 #undef TARGET_ASM_FUNCTION_BEGIN_EPILOGUE
16232 #define TARGET_ASM_FUNCTION_BEGIN_EPILOGUE avr_asm_function_begin_epilogue
16234 #undef TARGET_FUNCTION_VALUE
16235 #define TARGET_FUNCTION_VALUE avr_function_value
16236 #undef TARGET_LIBCALL_VALUE
16237 #define TARGET_LIBCALL_VALUE avr_libcall_value
16238 #undef TARGET_FUNCTION_VALUE_REGNO_P
16239 #define TARGET_FUNCTION_VALUE_REGNO_P avr_function_value_regno_p
16241 #undef TARGET_ATTRIBUTE_TABLE
16242 #define TARGET_ATTRIBUTE_TABLE avr_attribute_table
16243 #undef TARGET_INSERT_ATTRIBUTES
16244 #define TARGET_INSERT_ATTRIBUTES avr_insert_attributes
16245 #undef TARGET_SECTION_TYPE_FLAGS
16246 #define TARGET_SECTION_TYPE_FLAGS avr_section_type_flags
16248 #undef TARGET_ASM_NAMED_SECTION
16249 #define TARGET_ASM_NAMED_SECTION avr_asm_named_section
16250 #undef TARGET_ASM_INIT_SECTIONS
16251 #define TARGET_ASM_INIT_SECTIONS avr_asm_init_sections
16252 #undef TARGET_ENCODE_SECTION_INFO
16253 #define TARGET_ENCODE_SECTION_INFO avr_encode_section_info
16254 #undef TARGET_ASM_SELECT_SECTION
16255 #define TARGET_ASM_SELECT_SECTION avr_asm_select_section
16257 #undef TARGET_ASM_FINAL_POSTSCAN_INSN
16258 #define TARGET_ASM_FINAL_POSTSCAN_INSN avr_asm_final_postscan_insn
16260 #undef TARGET_INSN_COST
16261 #define TARGET_INSN_COST avr_insn_cost
16262 #undef TARGET_REGISTER_MOVE_COST
16263 #define TARGET_REGISTER_MOVE_COST avr_register_move_cost
16264 #undef TARGET_MEMORY_MOVE_COST
16265 #define TARGET_MEMORY_MOVE_COST avr_memory_move_cost
16266 #undef TARGET_RTX_COSTS
16267 #define TARGET_RTX_COSTS avr_rtx_costs
16268 #undef TARGET_ADDRESS_COST
16269 #define TARGET_ADDRESS_COST avr_address_cost
16270 #undef TARGET_FUNCTION_ARG
16271 #define TARGET_FUNCTION_ARG avr_function_arg
16272 #undef TARGET_FUNCTION_ARG_ADVANCE
16273 #define TARGET_FUNCTION_ARG_ADVANCE avr_function_arg_advance
16275 #undef TARGET_SET_CURRENT_FUNCTION
16276 #define TARGET_SET_CURRENT_FUNCTION avr_set_current_function
16278 #undef TARGET_RETURN_IN_MEMORY
16279 #define TARGET_RETURN_IN_MEMORY avr_return_in_memory
16281 #undef TARGET_STRICT_ARGUMENT_NAMING
16282 #define TARGET_STRICT_ARGUMENT_NAMING hook_bool_CUMULATIVE_ARGS_true
16284 #undef TARGET_CONDITIONAL_REGISTER_USAGE
16285 #define TARGET_CONDITIONAL_REGISTER_USAGE avr_conditional_register_usage
16287 #undef TARGET_HARD_REGNO_NREGS
16288 #define TARGET_HARD_REGNO_NREGS avr_hard_regno_nregs
16290 #undef TARGET_HARD_REGNO_MODE_OK
16291 #define TARGET_HARD_REGNO_MODE_OK avr_hard_regno_mode_ok
16292 #undef TARGET_HARD_REGNO_SCRATCH_OK
16293 #define TARGET_HARD_REGNO_SCRATCH_OK avr_hard_regno_scratch_ok
16294 #undef TARGET_HARD_REGNO_CALL_PART_CLOBBERED
16295 #define TARGET_HARD_REGNO_CALL_PART_CLOBBERED \
16296 avr_hard_regno_call_part_clobbered
16298 #undef TARGET_CASE_VALUES_THRESHOLD
16299 #define TARGET_CASE_VALUES_THRESHOLD avr_case_values_threshold
16301 #undef TARGET_FRAME_POINTER_REQUIRED
16302 #define TARGET_FRAME_POINTER_REQUIRED avr_frame_pointer_required_p
16303 #undef TARGET_CAN_ELIMINATE
16304 #define TARGET_CAN_ELIMINATE avr_can_eliminate
16306 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
16307 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
16309 #undef TARGET_WARN_FUNC_RETURN
16310 #define TARGET_WARN_FUNC_RETURN avr_warn_func_return
16312 #undef TARGET_CLASS_LIKELY_SPILLED_P
16313 #define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p
16315 #undef TARGET_CLASS_MAX_NREGS
16316 #define TARGET_CLASS_MAX_NREGS avr_class_max_nregs
16318 #undef TARGET_OPTION_OVERRIDE
16319 #define TARGET_OPTION_OVERRIDE avr_option_override
16321 #undef TARGET_CANNOT_MODIFY_JUMPS_P
16322 #define TARGET_CANNOT_MODIFY_JUMPS_P avr_cannot_modify_jumps_p
16324 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
16325 #define TARGET_FUNCTION_OK_FOR_SIBCALL avr_function_ok_for_sibcall
16327 #undef TARGET_INIT_BUILTINS
16328 #define TARGET_INIT_BUILTINS avr_init_builtins
16330 #undef TARGET_BUILTIN_DECL
16331 #define TARGET_BUILTIN_DECL avr_builtin_decl
16333 #undef TARGET_EXPAND_BUILTIN
16334 #define TARGET_EXPAND_BUILTIN avr_expand_builtin
16336 #undef TARGET_FOLD_BUILTIN
16337 #define TARGET_FOLD_BUILTIN avr_fold_builtin
16339 #undef TARGET_SCALAR_MODE_SUPPORTED_P
16340 #define TARGET_SCALAR_MODE_SUPPORTED_P avr_scalar_mode_supported_p
16342 #undef TARGET_BUILD_BUILTIN_VA_LIST
16343 #define TARGET_BUILD_BUILTIN_VA_LIST avr_build_builtin_va_list
16345 #undef TARGET_FIXED_POINT_SUPPORTED_P
16346 #define TARGET_FIXED_POINT_SUPPORTED_P hook_bool_void_true
16348 #undef TARGET_CONVERT_TO_TYPE
16349 #define TARGET_CONVERT_TO_TYPE avr_convert_to_type
16351 #undef TARGET_LRA_P
16352 #define TARGET_LRA_P hook_bool_void_false
16354 #undef TARGET_ADDR_SPACE_SUBSET_P
16355 #define TARGET_ADDR_SPACE_SUBSET_P avr_addr_space_subset_p
16357 #undef TARGET_ADDR_SPACE_CONVERT
16358 #define TARGET_ADDR_SPACE_CONVERT avr_addr_space_convert
16360 #undef TARGET_ADDR_SPACE_ADDRESS_MODE
16361 #define TARGET_ADDR_SPACE_ADDRESS_MODE avr_addr_space_address_mode
16363 #undef TARGET_ADDR_SPACE_POINTER_MODE
16364 #define TARGET_ADDR_SPACE_POINTER_MODE avr_addr_space_pointer_mode
16366 #undef TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P
16367 #define TARGET_ADDR_SPACE_LEGITIMATE_ADDRESS_P \
16368 avr_addr_space_legitimate_address_p
16370 #undef TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS
16371 #define TARGET_ADDR_SPACE_LEGITIMIZE_ADDRESS avr_addr_space_legitimize_address
16373 #undef TARGET_ADDR_SPACE_DIAGNOSE_USAGE
16374 #define TARGET_ADDR_SPACE_DIAGNOSE_USAGE avr_addr_space_diagnose_usage
16376 #undef TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID
16377 #define TARGET_ADDR_SPACE_ZERO_ADDRESS_VALID avr_addr_space_zero_address_valid
16379 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
16380 #define TARGET_MODE_DEPENDENT_ADDRESS_P avr_mode_dependent_address_p
16382 #undef TARGET_PRINT_OPERAND
16383 #define TARGET_PRINT_OPERAND avr_print_operand
16384 #undef TARGET_PRINT_OPERAND_ADDRESS
16385 #define TARGET_PRINT_OPERAND_ADDRESS avr_print_operand_address
16386 #undef TARGET_PRINT_OPERAND_PUNCT_VALID_P
16387 #define TARGET_PRINT_OPERAND_PUNCT_VALID_P avr_print_operand_punct_valid_p
16389 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
16390 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
16391 avr_use_by_pieces_infrastructure_p
16393 #undef TARGET_LEGITIMATE_COMBINED_INSN
16394 #define TARGET_LEGITIMATE_COMBINED_INSN avr_legitimate_combined_insn
16396 #undef TARGET_STARTING_FRAME_OFFSET
16397 #define TARGET_STARTING_FRAME_OFFSET avr_starting_frame_offset
16399 #undef TARGET_MD_ASM_ADJUST
16400 #define TARGET_MD_ASM_ADJUST avr_md_asm_adjust
16402 #undef TARGET_CAN_INLINE_P
16403 #define TARGET_CAN_INLINE_P avr_can_inline_p
16405 #undef TARGET_CANONICALIZE_COMPARISON
16406 #define TARGET_CANONICALIZE_COMPARISON avr_canonicalize_comparison
16408 /* According to the opening comment in PR86772, the following applies:
16409 "If the port does not (and never will in the future) need to mitigate
16410 against unsafe speculation." */
16411 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
16412 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
16414 struct gcc_target targetm = TARGET_INITIALIZER;
16417 #include "gt-avr.h"