Commit dc66391d by Richard Sandiford Committed by Richard Sandiford

s390.md (UNSPEC_POOL_OFFSET): New constant.

gcc/
	* 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.

From-SVN: r141091
parent 1590a115
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.
......
......@@ -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.
......
......@@ -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)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment