X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fconfig%2Favr%2Favr.c;h=0cb689ac8f24842e74a76f83c2a24475623dd404;hp=50682f29690dfb0d6a5729199f55604ca8a27921;hb=5da32b768afe9f6cd9f3c0b6fa37703e6134040c;hpb=4d025e72b3cb3539fb3d8c152ab9597f547450d9 diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 50682f29690..0cb689ac8f2 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -80,29 +80,18 @@ /* 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'. */ @@ -208,8 +197,9 @@ const struct mcu_type_s *avr_current_device; 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; @@ -559,8 +549,17 @@ avr_set_current_function (tree decl) { 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. */ @@ -674,6 +673,16 @@ avr_regs_to_save (HARD_REG_SET *set) 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 @@ -1004,7 +1013,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) 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 @@ -1043,6 +1052,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) } 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 ************/ @@ -1062,7 +1072,7 @@ avr_prologue_setup_frame (HOST_WIDE_INT size, HARD_REG_SET set) 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; @@ -2165,6 +2175,12 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn) } 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 @@ -5939,7 +5955,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc) op, plen, 1); if (n_bytes == 2 && PLUS == code) - *pcc = CC_SET_ZN; + *pcc = CC_SET_CZN; } i++; @@ -5961,6 +5977,7 @@ avr_out_plus_1 (rtx *xop, int *plen, enum rtx_code code, int *pcc) { avr_asm_len ((code == PLUS) ^ (val8 == 1) ? "dec %0" : "inc %0", op, plen, 1); + *pcc = CC_CLOBBER; break; } @@ -6968,9 +6985,6 @@ avr_pgm_check_var_decl (tree node) 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)) @@ -7113,8 +7127,6 @@ avr_output_progmem_section_asm_op (const void *data) 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. */ @@ -7133,13 +7145,6 @@ avr_asm_init_sections (void) ",\"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'. */ @@ -7217,10 +7222,9 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl) 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, @@ -7332,13 +7336,18 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) && 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)) { @@ -7347,8 +7356,15 @@ avr_asm_select_section (tree decl, int reloc, unsigned HOST_WIDE_INT align) 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; @@ -9916,7 +9932,7 @@ avr_mem_clobber (void) 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; @@ -10930,6 +10946,9 @@ avr_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg, #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