pa.md (pre_ldwm): Fix bug exposed by recent changes.

* pa.md (pre_ldwm): Fix bug exposed by recent changes.
        Simplify.
        (pre_stwm, post_ldwm, post_stwm): Likewise.
        (HImode and QImode variants): Likewise.
        * pa.c (hppa_expand_prologue): Corresponding changes.
        (hppa_expand_epilogue): Likewise.

        * pa.c (hppa_legitimize_address): Generate more indexing
        address modes.

From-SVN: r10972
This commit is contained in:
Jeff Law 1996-01-13 21:15:10 -07:00
parent 6b0bd7a3ba
commit 305123ba4b
2 changed files with 149 additions and 71 deletions

View File

@ -718,10 +718,8 @@ hppa_legitimize_address (x, oldx, mode)
only do so if indexing is safe.
Indexing is safe when the second operand for the outer PLUS
is a REG, SUBREG, SYMBOL_REF or the like.
is a REG, SUBREG, SYMBOL_REF or the like. */
For 2.5, indexing is also safe for (plus (symbol_ref) (const_int))
if the integer is > 0. */
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
@ -741,8 +739,64 @@ hppa_legitimize_address (x, oldx, mode)
reg1));
}
/* Similarly for (plus (plus (mult (a) (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 ((mode == DFmode || mode == SFmode)
&& 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
&& shadd_constant_p (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))))
{
rtx regx1, regx2;
/* Add the two unscaled terms B and C; only force them into registers
if it's absolutely necessary. */
regx1 = XEXP (XEXP (x, 0), 1);
if (! (GET_CODE (regx1) == REG
|| (GET_CODE (regx1) == CONST_INT
&& INT_14_BITS (regx1))))
regx1 = force_reg (Pmode, force_operand (XEXP (XEXP (x, 0), 1), 0));
regx2 = XEXP (x, 1);
if (! (GET_CODE (regx2) == REG
|| (GET_CODE (regx2) == CONST_INT
&& INT_14_BITS (regx2))))
regx2 = force_reg (Pmode, force_operand (XEXP (x, 1), 0));
/* Add them, make sure the result is in canonical form. */
if (GET_CODE (regx1) == REG)
regx1 = force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regx2));
else if (GET_CODE (regx2) == REG)
regx1 = force_reg (Pmode, gen_rtx (PLUS, Pmode, regx2, regx1));
else
regx1 = force_reg (Pmode, gen_rtx (PLUS, Pmode,
force_reg (Pmode, regx1),
regx2));
/* Get the term to scale in a register. */
regx2 = XEXP (XEXP (XEXP (x, 0), 0), 0);
if (GET_CODE (regx2) != REG)
regx2 = force_reg (Pmode, force_operand (regx2, 0));
/* And make an indexed address. */
regx2 = gen_rtx (PLUS, Pmode,
gen_rtx (MULT, Pmode, regx2,
XEXP (XEXP (XEXP (x, 0), 0), 1)),
regx1);
/* Return it. */
return force_reg (Pmode, regx2);
}
/* Uh-oh. We might have an address for x[n-100000]. This needs
special handling. */
special handling.
This is common enough that we want to try and rearrange the terms
so that we can use indexing for these addresses too. Again, only
do the optimization for floatint point modes. */
if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
@ -757,7 +811,7 @@ hppa_legitimize_address (x, oldx, mode)
to access memory, or better yet have the MI parts of the compiler
handle this. */
rtx regx1, regy1, regy2, y;
rtx regx1, regx2, regy1, regy2, y;
/* Strip off any CONST. */
y = XEXP (x, 1);
@ -766,11 +820,41 @@ hppa_legitimize_address (x, oldx, mode)
if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
{
regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
regx1 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
/* See if this looks like
(plus (mult (reg) (shadd_const))
(const (plus (symbol_ref) (const_int))))
Where const_int can be divided evenly by shadd_const and
added to (reg). This allows more scaled indexed addresses. */
if ((mode == DFmode || mode == SFmode)
&& GET_CODE (XEXP (y, 0)) == SYMBOL_REF
&& GET_CODE (XEXP (y, 1)) == CONST_INT
&& INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0)
{
regx1
= force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
/ INTVAL (XEXP (XEXP (x, 0), 1))));
regx2 = XEXP (XEXP (x, 0), 0);
if (GET_CODE (regx2) != REG)
regx2 = force_reg (Pmode, force_operand (regx2, 0));
regx2 = force_reg (Pmode, gen_rtx (GET_CODE (y), Pmode,
regx2, regx1));
return force_reg (Pmode,
gen_rtx (PLUS, Pmode,
gen_rtx (MULT, Pmode, regx2,
XEXP (XEXP (x, 0), 1)),
force_reg (Pmode, XEXP (y, 0))));
}
else
{
/* Doesn't look like one we can optimize. */
regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
regx1 = force_reg (Pmode,
gen_rtx (GET_CODE (y), Pmode, regx1, regy2));
return force_reg (Pmode, gen_rtx (PLUS, Pmode, regx1, regy1));
}
}
}
@ -2077,9 +2161,7 @@ hppa_expand_prologue()
emit_move_insn (tmpreg, frame_pointer_rtx);
emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
if (VAL_14_BITS_P (actual_fsize))
emit_insn (gen_post_stwm (stack_pointer_rtx,
stack_pointer_rtx,
size_rtx, tmpreg));
emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, size_rtx));
else
{
/* It is incorrect to store the saved frame pointer at *sp,
@ -2088,9 +2170,7 @@ hppa_expand_prologue()
So instead use stwm to store at *sp and post-increment the
stack pointer as an atomic operation. Then increment sp to
finish allocating the new frame. */
emit_insn (gen_post_stwm (stack_pointer_rtx,
stack_pointer_rtx,
GEN_INT (64), tmpreg));
emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, GEN_INT (64)));
set_reg_plus_d (STACK_POINTER_REGNUM,
STACK_POINTER_REGNUM,
actual_fsize - 64);
@ -2209,9 +2289,8 @@ hppa_expand_prologue()
{
merge_sp_adjust_with_store = 0;
emit_insn (gen_post_stwm (stack_pointer_rtx,
stack_pointer_rtx,
GEN_INT (-offset),
gen_rtx (REG, SImode, i)));
gen_rtx (REG, SImode, i),
GEN_INT (-offset)));
}
else
store_reg (i, offset, STACK_POINTER_REGNUM);
@ -2425,16 +2504,16 @@ hppa_expand_epilogue ()
stream, doing so avoids some very obscure problems. */
emit_insn (gen_blockage ());
set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
emit_insn (gen_pre_ldwm (stack_pointer_rtx, stack_pointer_rtx,
GEN_INT (-64), frame_pointer_rtx));
emit_insn (gen_pre_ldwm (frame_pointer_rtx,
stack_pointer_rtx,
GEN_INT (-64)));
}
/* If we were deferring a callee register restore, do it now. */
else if (! frame_pointer_needed && merge_sp_adjust_with_load)
emit_insn (gen_pre_ldwm (stack_pointer_rtx,
emit_insn (gen_pre_ldwm (gen_rtx (REG, SImode,
merge_sp_adjust_with_load),
stack_pointer_rtx,
GEN_INT (- actual_fsize),
gen_rtx (REG, SImode,
merge_sp_adjust_with_load)));
GEN_INT (- actual_fsize)));
else if (actual_fsize != 0)
set_reg_plus_d (STACK_POINTER_REGNUM,
STACK_POINTER_REGNUM,

View File

@ -1549,65 +1549,65 @@
;; Load or store with base-register modification.
(define_insn "pre_ldwm"
[(set (match_operand:SI 3 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "=r")
(match_operand:SI 2 "pre_cint_operand" ""))))
(set (match_operand:SI 0 "register_operand" "=r")
(set (match_dup 1)
(plus:SI (match_dup 1) (match_dup 2)))]
""
"*
{
if (INTVAL (operands[2]) < 0)
return \"ldwm %2(0,%0),%3\";
return \"ldws,mb %2(0,%0),%3\";
return \"ldwm %2(0,%1),%0\";
return \"ldws,mb %2(0,%1),%0\";
}"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn "pre_stwm"
[(set (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "pre_cint_operand" "")))
(match_operand:SI 3 "reg_or_0_operand" "rM"))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1) (match_dup 2)))]
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "pre_cint_operand" "")))
(match_operand:SI 2 "reg_or_0_operand" "rM"))
(set (match_dup 0)
(plus:SI (match_dup 0) (match_dup 1)))]
""
"*
{
if (INTVAL (operands[2]) < 0)
return \"stwm %r3,%2(0,%0)\";
return \"stws,mb %r3,%2(0,%0)\";
if (INTVAL (operands[1]) < 0)
return \"stwm %r2,%1(0,%0)\";
return \"stws,mb %r2,%1(0,%0)\";
}"
[(set_attr "type" "store")
(set_attr "length" "4")])
(define_insn "post_ldwm"
[(set (match_operand:SI 3 "register_operand" "r")
(mem:SI (match_operand:SI 1 "register_operand" "0")))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1)
[(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (match_operand:SI 1 "register_operand" "=r")))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 2 "post_cint_operand" "")))]
""
"*
{
if (INTVAL (operands[2]) > 0)
return \"ldwm %2(0,%0),%3\";
return \"ldws,ma %2(0,%0),%3\";
return \"ldwm %2(0,%1),%0\";
return \"ldws,ma %2(0,%1),%1\";
}"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn "post_stwm"
[(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
(match_operand:SI 3 "reg_or_0_operand" "rM"))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1)
[(set (mem:SI (match_operand:SI 0 "register_operand" "=r"))
(match_operand:SI 1 "reg_or_0_operand" "rM"))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 2 "post_cint_operand" "")))]
""
"*
{
if (INTVAL (operands[2]) > 0)
return \"stwm %r3,%2(0,%0)\";
return \"stws,ma %r3,%2(0,%0)\";
return \"stwm %r1,%2(0,%0)\";
return \"stws,ma %r1,%2(0,%0)\";
}"
[(set_attr "type" "store")
(set_attr "length" "4")])
@ -1887,24 +1887,24 @@
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:HI 3 "register_operand" "=r")
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0")
[(set (match_operand:HI 0 "register_operand" "=r")
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "=r")
(match_operand:SI 2 "int5_operand" "L"))))
(set (match_operand:SI 0 "register_operand" "=r")
(set (match_dup 1)
(plus:SI (match_dup 1) (match_dup 2)))]
""
"ldhs,mb %2(0,%0),%3"
"ldhs,mb %2(0,%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn ""
[(set (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "int5_operand" "L")))
(match_operand:HI 3 "reg_or_0_operand" "rM"))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1) (match_dup 2)))]
[(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "int5_operand" "L")))
(match_operand:HI 2 "reg_or_0_operand" "rM"))
(set (match_dup 0)
(plus:SI (match_dup 0) (match_dup 1)))]
""
"sths,mb %r3,%2(0,%0)"
"sths,mb %r2,%1(0,%0)"
[(set_attr "type" "store")
(set_attr "length" "4")])
@ -1972,24 +1972,23 @@
(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:QI 3 "register_operand" "=r")
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0")
[(set (match_operand:QI 0 "register_operand" "=r")
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "=r")
(match_operand:SI 2 "int5_operand" "L"))))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1) (match_dup 2)))]
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
""
"ldbs,mb %2(0,%0),%3"
"ldbs,mb %2(0,%1),%0"
[(set_attr "type" "load")
(set_attr "length" "4")])
(define_insn ""
[(set (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "int5_operand" "L")))
(match_operand:QI 3 "reg_or_0_operand" "rM"))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_dup 1) (match_dup 2)))]
[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "=r")
(match_operand:SI 1 "int5_operand" "L")))
(match_operand:QI 2 "reg_or_0_operand" "rM"))
(set (match_dup 0)
(plus:SI (match_dup 0) (match_dup 1)))]
""
"stbs,mb %r3,%2(0,%0)"
"stbs,mb %r2,%1(0,%0)"
[(set_attr "type" "store")
(set_attr "length" "4")])