mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-11 01:30:55 +08:00
pa.c (hppa_legitimize_address): Don't lose for (plus (plus (mult (A) (shadd_const)) (B)) (C)) if...
* pa.c (hppa_legitimize_address): Don't lose for (plus (plus (mult (A) (shadd_const)) (B)) (C)) if B + C isn't a valid address for indexing. (basereg_operand): Only accept base registers after cse has completed. Don't accept the frame pointer if it's likely to be eliminated. * pa.md (unscaled indexing patterns): Add variants with basereg and index register reversed. (HImode and QImode loads): Add zero extended variants. From-SVN: r11625
This commit is contained in:
parent
fdb5537fe0
commit
31d4f31fd7
@ -767,19 +767,19 @@ hppa_legitimize_address (x, oldx, mode)
|
||||
{
|
||||
rtx regx1, regx2;
|
||||
|
||||
/* Add the two unscaled terms B and C; only force them into registers
|
||||
if it's absolutely necessary. */
|
||||
/* Add the two unscaled terms B and C; if either B or C isn't
|
||||
a register or small constant int, then fail. */
|
||||
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));
|
||||
return orig;
|
||||
|
||||
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));
|
||||
return orig;
|
||||
|
||||
/* Add them, make sure the result is in canonical form. */
|
||||
if (GET_CODE (regx1) == REG)
|
||||
@ -4941,6 +4941,12 @@ basereg_operand (op, mode)
|
||||
rtx op;
|
||||
enum machine_mode mode;
|
||||
{
|
||||
/* cse will create some unscaled indexed addresses, however; it
|
||||
generally isn't a win on the PA, so avoid creating unscaled
|
||||
indexed addresses until after cse is finished. */
|
||||
if (!cse_not_expected)
|
||||
return 0;
|
||||
|
||||
/* Once reload has started everything is considered valid. Reload should
|
||||
only create indexed addresses using the stack/frame pointer, and any
|
||||
others were checked for validity when created by the combine pass.
|
||||
@ -4952,8 +4958,14 @@ basereg_operand (op, mode)
|
||||
if (TARGET_NO_SPACE_REGS || reload_in_progress || reload_completed)
|
||||
return (GET_CODE (op) == REG || GET_CODE (op) == CONST_INT);
|
||||
|
||||
/* Stack and frame pointers are always OK for indexing. */
|
||||
if (op == stack_pointer_rtx || op == frame_pointer_rtx)
|
||||
/* Stack is always OK for indexing. */
|
||||
if (op == stack_pointer_rtx)
|
||||
return 1;
|
||||
|
||||
/* While it's always safe to index off the frame pointer, it's not
|
||||
always profitable, particularly when the frame pointer is being
|
||||
eliminated. */
|
||||
if (! flag_omit_frame_pointer && op == frame_pointer_rtx)
|
||||
return 1;
|
||||
|
||||
/* The only other valid OPs are pseudo registers with
|
||||
|
@ -1527,6 +1527,25 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldwx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldwx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
@ -1851,7 +1870,20 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn can occur if the second operand
|
||||
; Same thing with zero extension.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:HI
|
||||
(plus:SI
|
||||
(mult:SI (match_operand:SI 2 "register_operand" "r")
|
||||
(const_int 2))
|
||||
(match_operand:SI 1 "register_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"ldhx,s %2(0,%1),%0"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; These variants of the above insns can occur if the second operand
|
||||
;; is the frame pointer. This is a kludge, but there doesn't
|
||||
;; seem to be a way around it. Only recognize it while reloading.
|
||||
;; Note how operand 3 uses a predicate of "const_int_operand", but
|
||||
@ -1877,6 +1909,44 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
; Now the zero extended variant.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=&r")
|
||||
(zero_extend:SI (mem:HI (plus:SI (plus:SI
|
||||
(mult:SI (match_operand:SI 2 "register_operand" "r")
|
||||
(const_int 2))
|
||||
(match_operand:SI 1 "register_operand" "r"))
|
||||
(match_operand:SI 3 "const_int_operand" "rI")))))]
|
||||
"! TARGET_DISABLE_INDEXING && reload_in_progress"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
return \"sh1addl %2,%1,%0\;ldh %3(0,%0),%0\";
|
||||
else
|
||||
return \"sh1addl %2,%1,%0\;ldhx %3(0,%0),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldhx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldhx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
@ -1896,6 +1966,49 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
; Now zero extended variants.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:HI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldhx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldhx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:HI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "basereg_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[1] == hard_frame_pointer_rtx
|
||||
|| operands[1] == stack_pointer_rtx)
|
||||
return \"ldhx %2(0,%1),%0\";
|
||||
else
|
||||
return \"ldhx %1(0,%2),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(mem:HI (plus:SI (match_operand:SI 1 "register_operand" "=r")
|
||||
@ -1907,6 +2020,20 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
; And a zero extended variant.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:HI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "register_operand" "=r")
|
||||
(match_operand:SI 2 "int5_operand" "L")))))
|
||||
(set (match_dup 1)
|
||||
(plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"ldhs,mb %2(0,%1),%0"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "=r")
|
||||
(match_operand:SI 1 "int5_operand" "L")))
|
||||
@ -1962,6 +2089,25 @@
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||
(mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldbx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldbx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
@ -1981,6 +2127,91 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
; Indexed byte load with zero extension to SImode or HImode.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:QI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldbx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldbx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:QI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "basereg_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[1] == hard_frame_pointer_rtx
|
||||
|| operands[1] == stack_pointer_rtx)
|
||||
return \"ldbx %2(0,%1),%0\";
|
||||
else
|
||||
return \"ldbx %1(0,%2),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(zero_extend:HI (mem:QI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"ldbx %1(0,%2),%0\";
|
||||
else
|
||||
return \"ldbx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(zero_extend:HI (mem:QI
|
||||
(plus:SI
|
||||
(match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "basereg_operand" "r")))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[1] == hard_frame_pointer_rtx
|
||||
|| operands[1] == stack_pointer_rtx)
|
||||
return \"ldbx %2(0,%1),%0\";
|
||||
else
|
||||
return \"ldbx %1(0,%2),%0\";
|
||||
}"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||
(mem:QI (plus:SI (match_operand:SI 1 "register_operand" "=r")
|
||||
@ -1991,6 +2222,29 @@
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
; Now the same thing with zero extensions.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(zero_extend:SI (mem:QI (plus:SI
|
||||
(match_operand:SI 1 "register_operand" "=r")
|
||||
(match_operand:SI 2 "int5_operand" "L")))))
|
||||
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"ldbs,mb %2(0,%1),%0"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(zero_extend:HI (mem:QI (plus:SI
|
||||
(match_operand:SI 1 "register_operand" "=r")
|
||||
(match_operand:SI 2 "int5_operand" "L")))))
|
||||
(set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
|
||||
""
|
||||
"ldbs,mb %2(0,%1),%0"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "=r")
|
||||
(match_operand:SI 1 "int5_operand" "L")))
|
||||
@ -2225,6 +2479,25 @@
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "register_operand" "=fx")
|
||||
(mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"flddx %1(0,%2),%0\";
|
||||
else
|
||||
return \"flddx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "register_operand" "=fx")
|
||||
(mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
@ -2283,6 +2556,25 @@
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r")))
|
||||
(match_operand:DF 0 "register_operand" "fx"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"fstdx %0,%1(0,%2)\";
|
||||
else
|
||||
return \"fstdx %0,%2(0,%1)\";
|
||||
}"
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "basereg_operand" "r")))
|
||||
@ -2568,6 +2860,25 @@
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "register_operand" "=fx")
|
||||
(mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"fldwx %1(0,%2),%0\";
|
||||
else
|
||||
return \"fldwx %2(0,%1),%0\";
|
||||
}"
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "register_operand" "=fx")
|
||||
(mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
@ -2626,6 +2937,25 @@
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
|
||||
(match_operand:SI 2 "register_operand" "r")))
|
||||
(match_operand:SF 0 "register_operand" "fx"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"*
|
||||
{
|
||||
/* Reload can create backwards (relative to cse) unscaled index
|
||||
address modes when eliminating registers and possibly for
|
||||
pseudos that don't get hard registers. Deal with it. */
|
||||
if (operands[2] == hard_frame_pointer_rtx
|
||||
|| operands[2] == stack_pointer_rtx)
|
||||
return \"fstwx %0,%1(0,%2)\";
|
||||
else
|
||||
return \"fstwx %0,%2(0,%1)\";
|
||||
}"
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(match_operand:SI 2 "basereg_operand" "r")))
|
||||
|
Loading…
x
Reference in New Issue
Block a user