aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/s390/s390.c59
-rw-r--r--gcc/config/s390/s390.md1
3 files changed, 42 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 32a67a5..25a8c88 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2008-10-13 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/s390/s390.md (UNSPEC_POOL_OFFSET): New constant.
+ * config/s390/s390.c (machine_function): Remove
+ decomposed_literal_pool_addresses_ok_p.
+ (s390_decompose_address): Check for UNSPEC_POOL_OFFSET instead of
+ the difference of two labels.
+ (s390_output_addr_const_extra): Handle UNSPEC_POOL_OFFSET.
+ (s390_pool_offset): New function.
+ (s390_find_constant, s390_find_execute, s390_dump_pool): Use it.
+ (s390_reorg): Don't set decomposed_literal_pool_addresses_ok_p.
+
2008-10-13 Nathan Froyd <froydnj@codesourcery.com>
* doc/install.texi (powerpc-*-*): Require binutils 2.15.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index d15ed2a..45dae8b 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -316,9 +316,6 @@ struct machine_function GTY(())
/* True if we may need to perform branch splitting. */
bool split_branches_pending_p;
- /* True during final stage of literal pool processing. */
- bool decomposed_literal_pool_addresses_ok_p;
-
/* Some local-dynamic TLS symbol name. */
const char *some_ld_name;
@@ -1955,15 +1952,10 @@ s390_decompose_address (rtx addr, struct s390_address *out)
;
}
- /* Accept chunkified literal pool symbol references. */
- else if (cfun && cfun->machine
- && cfun->machine->decomposed_literal_pool_addresses_ok_p
- && GET_CODE (disp) == MINUS
- && GET_CODE (XEXP (disp, 0)) == LABEL_REF
- && GET_CODE (XEXP (disp, 1)) == LABEL_REF)
- {
- ;
- }
+ /* Accept pool label offsets. */
+ else if (GET_CODE (disp) == UNSPEC
+ && XINT (disp, 1) == UNSPEC_POOL_OFFSET)
+ ;
/* Accept literal pool references. */
else if (GET_CODE (disp) == UNSPEC
@@ -4909,6 +4901,14 @@ s390_output_addr_const_extra (FILE *file, rtx x)
return true;
}
+ if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 2)
+ switch (XINT (x, 1))
+ {
+ case UNSPEC_POOL_OFFSET:
+ x = gen_rtx_MINUS (GET_MODE (x), XVECEXP (x, 0, 0), XVECEXP (x, 0, 1));
+ output_addr_const (file, x);
+ return true;
+ }
return false;
}
@@ -5823,6 +5823,20 @@ s390_add_constant (struct constant_pool *pool, rtx val, enum machine_mode mode)
}
}
+/* Return an rtx that represents the offset of X from the start of
+ pool POOL. */
+
+static rtx
+s390_pool_offset (struct constant_pool *pool, rtx x)
+{
+ rtx label;
+
+ label = gen_rtx_LABEL_REF (GET_MODE (x), pool->label);
+ x = gen_rtx_UNSPEC (GET_MODE (x), gen_rtvec (2, x, label),
+ UNSPEC_POOL_OFFSET);
+ return gen_rtx_CONST (GET_MODE (x), x);
+}
+
/* Find constant VAL of mode MODE in the constant pool POOL.
Return an RTX describing the distance from the start of
the pool to the location of the new constant. */
@@ -5832,7 +5846,6 @@ s390_find_constant (struct constant_pool *pool, rtx val,
enum machine_mode mode)
{
struct constant *c;
- rtx offset;
int i;
for (i = 0; i < NR_C_MODES; i++)
@@ -5846,10 +5859,7 @@ s390_find_constant (struct constant_pool *pool, rtx val,
gcc_assert (c);
- offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
- gen_rtx_LABEL_REF (Pmode, pool->label));
- offset = gen_rtx_CONST (Pmode, offset);
- return offset;
+ return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
}
/* Check whether INSN is an execute. Return the label_ref to its
@@ -5897,7 +5907,6 @@ static rtx
s390_find_execute (struct constant_pool *pool, rtx insn)
{
struct constant *c;
- rtx offset;
for (c = pool->execute; c != NULL; c = c->next)
if (INSN_UID (insn) == INSN_UID (c->value))
@@ -5905,10 +5914,7 @@ s390_find_execute (struct constant_pool *pool, rtx insn)
gcc_assert (c);
- offset = gen_rtx_MINUS (Pmode, gen_rtx_LABEL_REF (Pmode, c->label),
- gen_rtx_LABEL_REF (Pmode, pool->label));
- offset = gen_rtx_CONST (Pmode, offset);
- return offset;
+ return s390_pool_offset (pool, gen_rtx_LABEL_REF (Pmode, c->label));
}
/* For an execute INSN, extract the execute target template. */
@@ -5989,11 +5995,7 @@ s390_dump_pool (struct constant_pool *pool, bool remote_label)
&& GET_CODE (XEXP (value, 0)) == UNSPEC
&& XINT (XEXP (value, 0), 1) == UNSPEC_LTREL_OFFSET
&& XVECLEN (XEXP (value, 0), 0) == 1)
- {
- value = gen_rtx_MINUS (Pmode, XVECEXP (XEXP (value, 0), 0, 0),
- gen_rtx_LABEL_REF (VOIDmode, pool->label));
- value = gen_rtx_CONST (VOIDmode, value);
- }
+ value = s390_pool_offset (pool, XVECEXP (XEXP (value, 0), 0, 0));
insn = emit_label_after (c->label, insn);
INSN_ADDRESSES_NEW (insn, -1);
@@ -9598,9 +9600,6 @@ s390_reorg (void)
machine_dependent_reorg might confuse insn length counts. */
split_all_insns_noflow ();
- /* From here on decomposed literal pool addresses must be accepted. */
- cfun->machine->decomposed_literal_pool_addresses_ok_p = true;
-
/* Install the main literal pool and the associated base
register load insns.
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 21cde2b..f43ee1d 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -68,6 +68,7 @@
; GOT/PLT and lt-relative accesses
(UNSPEC_LTREL_OFFSET 100)
(UNSPEC_LTREL_BASE 101)
+ (UNSPEC_POOL_OFFSET 102)
(UNSPEC_GOTENT 110)
(UNSPEC_GOT 111)
(UNSPEC_GOTOFF 112)