/* Known address spaces. The order must be the same as in the respective
enum from avr.h (or designated initialized must be used). */
-const avr_addrspace_t avr_addrspace[] =
-{
- { ADDR_SPACE_RAM, 0, 2, "" , 0 },
- { ADDR_SPACE_FLASH, 1, 2, "__flash", 0 },
- { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1 },
- { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2 },
- { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3 },
- { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4 },
- { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5 },
- { ADDR_SPACE_MEMX, 1, 3, "__memx", 0 },
- { 0 , 0, 0, NULL, 0 }
+const avr_addrspace_t avr_addrspace[ADDR_SPACE_COUNT] =
+{
+ { ADDR_SPACE_RAM, 0, 2, "", 0, NULL },
+ { ADDR_SPACE_FLASH, 1, 2, "__flash", 0, ".progmem.data" },
+ { ADDR_SPACE_FLASH1, 1, 2, "__flash1", 1, ".progmem1.data" },
+ { ADDR_SPACE_FLASH2, 1, 2, "__flash2", 2, ".progmem2.data" },
+ { ADDR_SPACE_FLASH3, 1, 2, "__flash3", 3, ".progmem3.data" },
+ { ADDR_SPACE_FLASH4, 1, 2, "__flash4", 4, ".progmem4.data" },
+ { ADDR_SPACE_FLASH5, 1, 2, "__flash5", 5, ".progmem5.data" },
+ { ADDR_SPACE_MEMX, 1, 3, "__memx", 0, ".progmemx.data" },
};
-/* Map 64-k Flash segment to section prefix. */
-static const char* const progmem_section_prefix[6] =
- {
- ".progmem.data",
- ".progmem1.data",
- ".progmem2.data",
- ".progmem3.data",
- ".progmem4.data",
- ".progmem5.data"
- };
/* Holding RAM addresses of some SFRs used by the compiler and that
are unique over all devices in an architecture like 'avr4'. */
static GTY(()) section *progmem_swtable_section;
/* Unnamed sections associated to __attribute__((progmem)) aka. PROGMEM
- or to address space __flash*. */
-static GTY(()) section *progmem_section[6];
+ or to address space __flash* or __memx. Only used as singletons inside
+ avr_asm_select_section, but it must not be local there because of GTY. */
+static GTY(()) section *progmem_section[ADDR_SPACE_COUNT];
/* Condition for insns/expanders from avr-dimode.md. */
bool avr_have_dimode = true;
{
tree args = TYPE_ARG_TYPES (TREE_TYPE (decl));
tree ret = TREE_TYPE (TREE_TYPE (decl));
- const char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
-
+ const char *name;
+
+ name = DECL_ASSEMBLER_NAME_SET_P (decl)
+ ? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))
+ : IDENTIFIER_POINTER (DECL_NAME (decl));
+
+ /* Skip a leading '*' that might still prefix the assembler name,
+ e.g. in non-LTO runs. */
+
+ name = default_strip_name_encoding (name);
+
/* Silently ignore 'signal' if 'interrupt' is present. AVR-LibC startet
using this when it switched from SIGNAL and INTERRUPT to ISR. */
return count;
}
+
+/* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
+
+static bool
+avr_allocate_stack_slots_for_args (void)
+{
+ return !cfun->machine->is_naked;
+}
+
+
/* Return true if register FROM can be eliminated via register TO. */
static bool
leaf function and thus X has already been saved. */
int irq_state = -1;
- HOST_WIDE_INT size_cfa = size;
+ HOST_WIDE_INT size_cfa = size, neg_size;
rtx fp_plus_insns, fp, my_fp;
gcc_assert (frame_pointer_needed
}
size = trunc_int_for_mode (size, GET_MODE (my_fp));
+ neg_size = trunc_int_for_mode (-size, GET_MODE (my_fp));
/************ Method 1: Adjust frame pointer ************/
gen_rtx_SET (VOIDmode, fp, stack_pointer_rtx));
}
- insn = emit_move_insn (my_fp, plus_constant (my_fp, -size));
+ insn = emit_move_insn (my_fp, plus_constant (my_fp, neg_size));
if (frame_pointer_needed)
{
RTX_FRAME_RELATED_P (insn) = 1;
}
break;
+ case CC_SET_VZN:
+ /* Insn like INC, DEC, NEG that set Z,N,V. We currently don't make use
+ of this combination, cf. also PR61055. */
+ CC_STATUS_INIT;
+ break;
+
case CC_SET_CZN:
/* Insn sets the Z,N,C flags of CC to recog_operand[0].
The V flag may or may not be known but that's ok because
op, plen, 1);
if (n_bytes == 2 && PLUS == code)
- *pcc = CC_SET_ZN;
+ *pcc = CC_SET_CZN;
}
i++;
{
avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0",
op, plen, 1);
+ *pcc = CC_CLOBBER;
break;
}
if (reason)
{
- avr_edump ("%?: %s, %d, %d\n",
- avr_addrspace[as].name,
- avr_addrspace[as].segment, avr_current_device->n_flash);
if (avr_addrspace[as].segment >= avr_current_device->n_flash)
{
if (TYPE_P (node))
static void
avr_asm_init_sections (void)
{
- unsigned int n;
-
/* Set up a section for jump tables. Alignment is handled by
ASM_OUTPUT_BEFORE_CASE_LABEL. */
",\"ax\",@progbits");
}
- for (n = 0; n < sizeof (progmem_section) / sizeof (*progmem_section); n++)
- {
- progmem_section[n]
- = get_unnamed_section (0, avr_output_progmem_section_asm_op,
- progmem_section_prefix[n]);
- }
-
/* Override section callbacks to keep track of `avr_need_clear_bss_p'
resp. `avr_need_copy_data_p'. */
if (flags & AVR_SECTION_PROGMEM)
{
addr_space_t as = (flags & AVR_SECTION_PROGMEM) / SECTION_MACH_DEP;
- int segment = avr_addrspace[as].segment;
const char *old_prefix = ".rodata";
- const char *new_prefix = progmem_section_prefix[segment];
-
+ const char *new_prefix = avr_addrspace[as].section_name;
+
if (STR_PREFIX_P (name, old_prefix))
{
const char *sname = ACONCAT ((new_prefix,
&& avr_progmem_p (decl, DECL_ATTRIBUTES (decl)))
{
addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (decl));
- int segment = avr_addrspace[as].segment;
+
+ /* __progmem__ goes in generic space but shall be allocated to
+ .progmem.data */
+
+ if (ADDR_SPACE_GENERIC_P (as))
+ as = ADDR_SPACE_FLASH;
if (sect->common.flags & SECTION_NAMED)
{
const char * name = sect->named.name;
const char * old_prefix = ".rodata";
- const char * new_prefix = progmem_section_prefix[segment];
+ const char * new_prefix = avr_addrspace[as].section_name;
if (STR_PREFIX_P (name, old_prefix))
{
return get_section (sname, sect->common.flags, sect->named.decl);
}
}
-
- return progmem_section[segment];
+
+ if (!progmem_section[as])
+ {
+ progmem_section[as]
+ = get_unnamed_section (0, avr_output_progmem_section_asm_op,
+ avr_addrspace[as].section_name);
+ }
+
+ return progmem_section[as];
}
return sect;
static void
avr_expand_delay_cycles (rtx operands0)
{
- unsigned HOST_WIDE_INT cycles = UINTVAL (operands0);
+ unsigned HOST_WIDE_INT cycles = UINTVAL (operands0) & GET_MODE_MASK (SImode);
unsigned HOST_WIDE_INT cycles_used;
unsigned HOST_WIDE_INT loop_count;
#undef TARGET_CAN_ELIMINATE
#define TARGET_CAN_ELIMINATE avr_can_eliminate
+#undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
+#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS avr_allocate_stack_slots_for_args
+
#undef TARGET_CLASS_LIKELY_SPILLED_P
#define TARGET_CLASS_LIKELY_SPILLED_P avr_class_likely_spilled_p