From 305123ba4bacbad193a88f5d556989ed56aa7d15 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Sat, 13 Jan 1996 21:15:10 -0700 Subject: [PATCH] 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 --- gcc/config/pa/pa.c | 129 +++++++++++++++++++++++++++++++++++--------- gcc/config/pa/pa.md | 91 ++++++++++++++++--------------- 2 files changed, 149 insertions(+), 71 deletions(-) diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index ed019cbeb08..5c00d45bf5d 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -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, diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 8b23ea4d9f9..abaaa36b4d6 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -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")]) -- 2.30.2