diff options
Diffstat (limited to 'gcc/config/sh/sh.c')
-rw-r--r-- | gcc/config/sh/sh.c | 67 |
1 files changed, 42 insertions, 25 deletions
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index d2cc47186d9..70cb0c1f167 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -2244,6 +2244,10 @@ typedef struct rtx label; /* Label of value. */ rtx wend; /* End of window. */ enum machine_mode mode; /* Mode of value. */ + + /* True if this constant is accessed as part of a post-increment + sequence. Note that HImode constants are never accessed in this way. */ + bool part_of_sequence_p; } pool_node; /* The maximum number of constants that can fit into one pool, since @@ -2317,12 +2321,16 @@ add_constant (x, mode, last_value) /* Need a new one. */ pool_vector[pool_size].value = x; if (last_value && rtx_equal_p (last_value, pool_vector[pool_size - 1].value)) - lab = 0; + { + lab = 0; + pool_vector[pool_size - 1].part_of_sequence_p = true; + } else lab = gen_label_rtx (); pool_vector[pool_size].mode = mode; pool_vector[pool_size].label = lab; pool_vector[pool_size].wend = NULL_RTX; + pool_vector[pool_size].part_of_sequence_p = (lab == 0); if (lab && pool_window_label) { newref = gen_rtx_LABEL_REF (VOIDmode, pool_window_label); @@ -2395,7 +2403,7 @@ dump_table (scan) break; case SImode: case SFmode: - if (align_insn) + if (align_insn && !p->part_of_sequence_p) { for (lab = p->label; lab; lab = LABEL_REFS (lab)) emit_label_before (lab, align_insn); @@ -3718,7 +3726,6 @@ machine_dependent_reorg (first) behind. */ rtx barrier = find_barrier (num_mova, mova, insn); rtx last_float_move, last_float = 0, *last_float_addr; - int may_need_align = 1; if (num_mova && ! mova_p (mova)) { @@ -3776,27 +3783,11 @@ machine_dependent_reorg (first) if (last_float && reg_set_between_p (r0_rtx, last_float_move, scan)) last_float = 0; - if (TARGET_SHCOMPACT) - { - /* The first SFmode constant after a DFmode - constant may be pulled before a sequence - of DFmode constants, so the second SFmode - needs a label, just in case. */ - if (GET_MODE_SIZE (mode) == 4) - { - if (last_float && may_need_align) - last_float = 0; - may_need_align = 0; - } - if (last_float - && (GET_MODE_SIZE (GET_MODE (last_float)) - != GET_MODE_SIZE (mode))) - { - last_float = 0; - if (GET_MODE_SIZE (mode) == 4) - may_need_align = 1; - } - } + if (last_float + && TARGET_SHCOMPACT + && GET_MODE_SIZE (mode) != 4 + && GET_MODE_SIZE (GET_MODE (last_float)) == 4) + last_float = 0; lab = add_constant (src, mode, last_float); if (lab) emit_insn_before (gen_mova (lab), scan); @@ -4442,7 +4433,11 @@ calc_live_regs (count_ptr, live_regs_mask) && reg != RETURN_ADDRESS_POINTER_REGNUM && reg != T_REG && reg != GBR_REG) : (/* Only push those regs which are used and need to be saved. */ - regs_ever_live[reg] && ! call_used_regs[reg])) + (TARGET_SHCOMPACT + && flag_pic + && current_function_args_info.call_cookie + && reg == PIC_OFFSET_TABLE_REGNUM) + || (regs_ever_live[reg] && ! call_used_regs[reg]))) { live_regs_mask[reg / 32] |= 1 << (reg % 32); count += GET_MODE_SIZE (REGISTER_NATURAL_MODE (reg)); @@ -7755,4 +7750,26 @@ sh_cannot_change_mode_class (from, to) return NO_REGS; } + +/* If ADDRESS refers to a CODE_LABEL, add NUSES to the number of times + that label is used. */ + +void +sh_mark_label (address, nuses) + rtx address; + int nuses; +{ + if (GOTOFF_P (address)) + { + /* Extract the label or symbol. */ + address = XEXP (address, 0); + if (GET_CODE (address) == PLUS) + address = XEXP (address, 0); + address = XVECEXP (address, 0, 0); + } + if (GET_CODE (address) == LABEL_REF + && GET_CODE (XEXP (address, 0)) == CODE_LABEL) + LABEL_NUSES (XEXP (address, 0)) += nuses; +} + #include "gt-sh.h" |