aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/sh/sh.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/sh/sh.c')
-rw-r--r--gcc/config/sh/sh.c67
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"