/* 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;
;
}
- /* 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
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;
}
}
}
+/* 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. */
enum machine_mode mode)
{
struct constant *c;
- rtx offset;
int i;
for (i = 0; i < NR_C_MODES; i++)
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
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))
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. */
&& 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);
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.