pa.c (mem_shadd_or_shadd_rtx_p): New function factored out of hppa_legitimize_address to handle both forms of a...
* pa.c (mem_shadd_or_shadd_rtx_p): New function factored out of hppa_legitimize_address to handle both forms of a multiply by 2, 4 or 8. (hppa_legitimize_address): Use mem_shadd_or_shadd_rtx_p. Always generate the ASHIFT variant as the result is not directly used in a MEM. Update comments and refactor slightly to improve readability. From-SVN: r223579
This commit is contained in:
parent
9b789cc15c
commit
92d0b05816
2 changed files with 98 additions and 48 deletions
|
@ -1,3 +1,13 @@
|
|||
2015-05-22 Jeff Law <law@redhat.com>
|
||||
|
||||
* pa.c (mem_shadd_or_shadd_rtx_p): New function factored out
|
||||
of hppa_legitimize_address to handle both forms of a multiply
|
||||
by 2, 4 or 8.
|
||||
(hppa_legitimize_address): Use mem_shadd_or_shadd_rtx_p.
|
||||
Always generate the ASHIFT variant as the result is not directly
|
||||
used in a MEM. Update comments and refactor slightly to improve
|
||||
readability.
|
||||
|
||||
2015-05-22 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
|
||||
|
||||
PR target/65491
|
||||
|
|
|
@ -997,6 +997,23 @@ legitimize_tls_address (rtx addr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Helper for hppa_legitimize_address. Given X, return true if it
|
||||
is a left shift by 1, 2 or 3 positions or a multiply by 2, 4 or 8.
|
||||
|
||||
This respectively represent canonical shift-add rtxs or scaled
|
||||
memory addresses. */
|
||||
static bool
|
||||
mem_shadd_or_shadd_rtx_p (rtx x)
|
||||
{
|
||||
return ((GET_CODE (x) == ASHIFT
|
||||
|| GET_CODE (x) == MULT)
|
||||
&& GET_CODE (XEXP (x, 1)) == CONST_INT
|
||||
&& ((GET_CODE (x) == ASHIFT
|
||||
&& pa_shadd_constant_p (INTVAL (XEXP (x, 1))))
|
||||
|| (GET_CODE (x) == MULT
|
||||
&& pa_mem_shadd_constant_p (INTVAL (XEXP (x, 1))))));
|
||||
}
|
||||
|
||||
/* Try machine-dependent ways of modifying an illegitimate address
|
||||
to be legitimate. If we find one, return the new, valid address.
|
||||
This macro is used in only one place: `memory_address' in explow.c.
|
||||
|
@ -1042,6 +1059,13 @@ legitimize_tls_address (rtx addr)
|
|||
manner if Y is 2, 4, or 8. (allows more shadd insns and shifted indexed
|
||||
addressing modes to be used).
|
||||
|
||||
Note that the addresses passed into hppa_legitimize_address always
|
||||
come from a MEM, so we only have to match the MULT form on incoming
|
||||
addresses. But to be future proof we also match the ASHIFT form.
|
||||
|
||||
However, this routine always places those shift-add sequences into
|
||||
registers, so we have to generate the ASHIFT form as our output.
|
||||
|
||||
Put X and Z into registers. Then put the entire expression into
|
||||
a register. */
|
||||
|
||||
|
@ -1138,18 +1162,21 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
return plus_constant (Pmode, ptr_reg, offset - newoffset);
|
||||
}
|
||||
|
||||
/* Handle (plus (mult (a) (shadd_constant)) (b)). */
|
||||
/* Handle (plus (mult (a) (mem_shadd_constant)) (b)). */
|
||||
|
||||
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
|
||||
&& pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
|
||||
if (GET_CODE (x) == PLUS
|
||||
&& mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
|
||||
&& (OBJECT_P (XEXP (x, 1))
|
||||
|| GET_CODE (XEXP (x, 1)) == SUBREG)
|
||||
&& GET_CODE (XEXP (x, 1)) != CONST)
|
||||
{
|
||||
int val = INTVAL (XEXP (XEXP (x, 0), 1));
|
||||
rtx reg1, reg2;
|
||||
/* If we were given a MULT, we must fix the constant
|
||||
as we're going to create the ASHIFT form. */
|
||||
int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
|
||||
if (GET_CODE (XEXP (x, 0)) == MULT)
|
||||
shift_val = exact_log2 (shift_val);
|
||||
|
||||
rtx reg1, reg2;
|
||||
reg1 = XEXP (x, 1);
|
||||
if (GET_CODE (reg1) != REG)
|
||||
reg1 = force_reg (Pmode, force_operand (reg1, 0));
|
||||
|
@ -1158,26 +1185,30 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
if (GET_CODE (reg2) != REG)
|
||||
reg2 = force_reg (Pmode, force_operand (reg2, 0));
|
||||
|
||||
return force_reg (Pmode, gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode,
|
||||
reg2,
|
||||
GEN_INT (val)),
|
||||
reg1));
|
||||
return force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_ASHIFT (Pmode, reg2,
|
||||
GEN_INT (shift_val)),
|
||||
reg1));
|
||||
}
|
||||
|
||||
/* Similarly for (plus (plus (mult (a) (shadd_constant)) (b)) (c)).
|
||||
/* Similarly for (plus (plus (mult (a) (mem_shadd_constant)) (b)) (c)).
|
||||
|
||||
Only do so for floating point modes since this is more speculative
|
||||
and we lose if it's an integer store. */
|
||||
if (GET_CODE (x) == PLUS
|
||||
&& GET_CODE (XEXP (x, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
|
||||
&& GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
|
||||
&& pa_shadd_constant_p (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
|
||||
&& mem_shadd_or_shadd_rtx_p (XEXP (XEXP (x, 0), 0))
|
||||
&& (mode == SFmode || mode == DFmode))
|
||||
{
|
||||
int shift_val = INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1));
|
||||
|
||||
/* First, try and figure out what to use as a base register. */
|
||||
/* If we were given a MULT, we must fix the constant
|
||||
as we're going to create the ASHIFT form. */
|
||||
if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
|
||||
shift_val = exact_log2 (shift_val);
|
||||
|
||||
/* Try and figure out what to use as a base register. */
|
||||
rtx reg1, reg2, base, idx;
|
||||
|
||||
reg1 = XEXP (XEXP (x, 0), 1);
|
||||
|
@ -1201,9 +1232,9 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
{
|
||||
base = reg1;
|
||||
idx = gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode,
|
||||
XEXP (XEXP (XEXP (x, 0), 0), 0),
|
||||
XEXP (XEXP (XEXP (x, 0), 0), 1)),
|
||||
gen_rtx_ASHIFT (Pmode,
|
||||
XEXP (XEXP (XEXP (x, 0), 0), 0),
|
||||
GEN_INT (shift_val)),
|
||||
XEXP (x, 1));
|
||||
}
|
||||
else if (GET_CODE (reg2) == REG
|
||||
|
@ -1225,8 +1256,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
{
|
||||
/* Divide the CONST_INT by the scale factor, then add it to A. */
|
||||
int val = INTVAL (XEXP (idx, 1));
|
||||
val /= (1 << shift_val);
|
||||
|
||||
val /= INTVAL (XEXP (XEXP (idx, 0), 1));
|
||||
reg1 = XEXP (XEXP (idx, 0), 0);
|
||||
if (GET_CODE (reg1) != REG)
|
||||
reg1 = force_reg (Pmode, force_operand (reg1, 0));
|
||||
|
@ -1237,8 +1268,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
return
|
||||
force_reg
|
||||
(Pmode, gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode, reg1,
|
||||
XEXP (XEXP (idx, 0), 1)),
|
||||
gen_rtx_ASHIFT (Pmode, reg1,
|
||||
GEN_INT (shift_val)),
|
||||
base));
|
||||
}
|
||||
|
||||
|
@ -1247,7 +1278,6 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
&& INTVAL (XEXP (idx, 1)) <= 4096
|
||||
&& INTVAL (XEXP (idx, 1)) >= -4096)
|
||||
{
|
||||
int val = INTVAL (XEXP (XEXP (idx, 0), 1));
|
||||
rtx reg1, reg2;
|
||||
|
||||
reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));
|
||||
|
@ -1256,11 +1286,11 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
if (GET_CODE (reg2) != CONST_INT)
|
||||
reg2 = force_reg (Pmode, force_operand (reg2, 0));
|
||||
|
||||
return force_reg (Pmode, gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode,
|
||||
reg2,
|
||||
GEN_INT (val)),
|
||||
reg1));
|
||||
return force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_ASHIFT (Pmode, reg2,
|
||||
GEN_INT (shift_val)),
|
||||
reg1));
|
||||
}
|
||||
|
||||
/* Get the index into a register, then add the base + index and
|
||||
|
@ -1278,8 +1308,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
|
||||
reg1 = force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode, reg1,
|
||||
XEXP (XEXP (idx, 0), 1)),
|
||||
gen_rtx_ASHIFT (Pmode, reg1,
|
||||
GEN_INT (shift_val)),
|
||||
reg2));
|
||||
|
||||
/* Add the result to our base register and return. */
|
||||
|
@ -1315,7 +1345,7 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
|
||||
{
|
||||
/* See if this looks like
|
||||
(plus (mult (reg) (shadd_const))
|
||||
(plus (mult (reg) (mem_shadd_const))
|
||||
(const (plus (symbol_ref) (const_int))))
|
||||
|
||||
Where const_int is small. In that case the const
|
||||
|
@ -1324,14 +1354,18 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
If const_int is big, but can be divided evenly by shadd_const
|
||||
and added to (reg). This allows more scaled indexed addresses. */
|
||||
if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF
|
||||
&& GET_CODE (XEXP (x, 0)) == MULT
|
||||
&& mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
|
||||
&& GET_CODE (XEXP (y, 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (y, 1)) >= -4096
|
||||
&& INTVAL (XEXP (y, 1)) <= 4095
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
|
||||
&& pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
|
||||
&& INTVAL (XEXP (y, 1)) <= 4095)
|
||||
{
|
||||
int val = INTVAL (XEXP (XEXP (x, 0), 1));
|
||||
int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
|
||||
|
||||
/* If we were given a MULT, we must fix the constant
|
||||
as we're going to create the ASHIFT form. */
|
||||
if (GET_CODE (XEXP (x, 0)) == MULT)
|
||||
shift_val = exact_log2 (shift_val);
|
||||
|
||||
rtx reg1, reg2;
|
||||
|
||||
reg1 = XEXP (x, 1);
|
||||
|
@ -1342,21 +1376,27 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
if (GET_CODE (reg2) != REG)
|
||||
reg2 = force_reg (Pmode, force_operand (reg2, 0));
|
||||
|
||||
return force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode,
|
||||
reg2,
|
||||
GEN_INT (val)),
|
||||
reg1));
|
||||
return
|
||||
force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_ASHIFT (Pmode,
|
||||
reg2,
|
||||
GEN_INT (shift_val)),
|
||||
reg1));
|
||||
}
|
||||
else if ((mode == DFmode || mode == SFmode)
|
||||
&& GET_CODE (XEXP (y, 0)) == SYMBOL_REF
|
||||
&& GET_CODE (XEXP (x, 0)) == MULT
|
||||
&& mem_shadd_or_shadd_rtx_p (XEXP (x, 0))
|
||||
&& GET_CODE (XEXP (y, 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
|
||||
&& pa_shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
|
||||
&& INTVAL (XEXP (y, 1)) % (1 << INTVAL (XEXP (XEXP (x, 0), 1))) == 0)
|
||||
{
|
||||
int shift_val = INTVAL (XEXP (XEXP (x, 0), 1));
|
||||
|
||||
/* If we were given a MULT, we must fix the constant
|
||||
as we're going to create the ASHIFT form. */
|
||||
if (GET_CODE (XEXP (x, 0)) == MULT)
|
||||
shift_val = exact_log2 (shift_val);
|
||||
|
||||
regx1
|
||||
= force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
|
||||
/ INTVAL (XEXP (XEXP (x, 0), 1))));
|
||||
|
@ -1368,8 +1408,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
|
|||
return
|
||||
force_reg (Pmode,
|
||||
gen_rtx_PLUS (Pmode,
|
||||
gen_rtx_MULT (Pmode, regx2,
|
||||
XEXP (XEXP (x, 0), 1)),
|
||||
gen_rtx_ASHIFT (Pmode, regx2,
|
||||
GEN_INT (shift_val)),
|
||||
force_reg (Pmode, XEXP (y, 0))));
|
||||
}
|
||||
else if (GET_CODE (XEXP (y, 1)) == CONST_INT
|
||||
|
|
Loading…
Add table
Reference in a new issue