mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-08 15:42:07 +08:00
pa.c (move_operand): Relax "mode" test.
Wed Jul 24 10:53:38 1996 Jeffrey A Law (law@cygnus.com) * pa/pa.c (move_operand): Relax "mode" test. Allow scaled indexed addressing modes. (output_fp_move_double): Tweak output strings to work with updated 'F' and 'M' output modifiers. (print_operand): Collapse 'F' and 'M' into a single hunk of code. For auto-increment modes output "s,ma" and "s,mb". For scaled indexing modes output "x,s" For other addresses, output nothing for 'M' and "s" for 'F'. * pa.h (EXTRA_CONSTRAINT): Don't accept scaled indexed addresses for 'Q' and 'T'. Do accept scaled indexed addresses for 'R'. (GO_IF_LEGITIMATE_ADDRESS): Accept scaled indexed addresses for SFmode and DFmode. * pa.md: Remove all scaled indexed load patterns. (movsi patterns): Accept scaled indexed addresses in some cases. Update output strings for updated 'M' and 'F' output modifiers. (movhi, movqi, movsf, movdf, movdi patterns): Likewise. From-SVN: r12558
This commit is contained in:
parent
2cf55b5554
commit
2414e0e283
@ -270,8 +270,6 @@ move_operand (op, mode)
|
||||
if (GET_CODE (op) == CONST_INT)
|
||||
return cint_ok_for_move (INTVAL (op));
|
||||
|
||||
if (GET_MODE (op) != mode)
|
||||
return 0;
|
||||
if (GET_CODE (op) == SUBREG)
|
||||
op = SUBREG_REG (op);
|
||||
if (GET_CODE (op) != MEM)
|
||||
@ -281,6 +279,22 @@ move_operand (op, mode)
|
||||
if (GET_CODE (op) == LO_SUM)
|
||||
return (register_operand (XEXP (op, 0), Pmode)
|
||||
&& CONSTANT_P (XEXP (op, 1)));
|
||||
|
||||
/* Since move_operand is only used for source operands, we can always
|
||||
allow scaled indexing! */
|
||||
if (GET_CODE (op) == PLUS
|
||||
&& ((GET_CODE (XEXP (op, 0)) == MULT
|
||||
&& GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
|
||||
&& GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (XEXP (op, 0), 1)) == GET_MODE_SIZE (mode)
|
||||
&& GET_CODE (XEXP (op, 1)) == REG)
|
||||
|| (GET_CODE (XEXP (op, 1)) == MULT
|
||||
&&GET_CODE (XEXP (XEXP (op, 1), 0)) == REG
|
||||
&& GET_CODE (XEXP (XEXP (op, 1), 1)) == CONST_INT
|
||||
&& INTVAL (XEXP (XEXP (op, 1), 1)) == GET_MODE_SIZE (mode)
|
||||
&& GET_CODE (XEXP (op, 0)) == REG)))
|
||||
return 1;
|
||||
|
||||
return memory_address_p (mode, op);
|
||||
}
|
||||
|
||||
@ -1610,11 +1624,11 @@ output_fp_move_double (operands)
|
||||
|| operands[1] == CONST0_RTX (GET_MODE (operands[0])))
|
||||
output_asm_insn ("fcpy,dbl %r1,%0", operands);
|
||||
else
|
||||
output_asm_insn ("fldds%F1 %1,%0", operands);
|
||||
output_asm_insn ("fldd%F1 %1,%0", operands);
|
||||
}
|
||||
else if (FP_REG_P (operands[1]))
|
||||
{
|
||||
output_asm_insn ("fstds%F0 %1,%0", operands);
|
||||
output_asm_insn ("fstd%F0 %1,%0", operands);
|
||||
}
|
||||
else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
|
||||
{
|
||||
@ -3324,6 +3338,7 @@ print_operand (file, x, code)
|
||||
fputs ("i", file);
|
||||
return;
|
||||
case 'M':
|
||||
case 'F':
|
||||
switch (GET_CODE (XEXP (x, 0)))
|
||||
{
|
||||
case PRE_DEC:
|
||||
@ -3334,22 +3349,16 @@ print_operand (file, x, code)
|
||||
case POST_INC:
|
||||
fputs ("s,ma", file);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 'F':
|
||||
switch (GET_CODE (XEXP (x, 0)))
|
||||
{
|
||||
case PRE_DEC:
|
||||
case PRE_INC:
|
||||
fputs (",mb", file);
|
||||
break;
|
||||
case POST_DEC:
|
||||
case POST_INC:
|
||||
fputs (",ma", file);
|
||||
case PLUS:
|
||||
if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
|
||||
|| GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
|
||||
fputs ("x,s", file);
|
||||
else if (code == 'F')
|
||||
fputs ("s", file);
|
||||
break;
|
||||
default:
|
||||
if (code == 'F')
|
||||
fputs ("s", file);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
@ -3392,7 +3401,18 @@ print_operand (file, x, code)
|
||||
fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
|
||||
break;
|
||||
default:
|
||||
output_address (XEXP (x, 0));
|
||||
if (GET_CODE (XEXP (x, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
|
||||
fprintf (file, "%s(0,%s)",
|
||||
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
|
||||
reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
|
||||
else if (GET_CODE (XEXP (x, 0)) == PLUS
|
||||
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
|
||||
fprintf (file, "%s(0,%s)",
|
||||
reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
|
||||
reg_names [REGNO (XEXP (XEXP (x, 0), 0))]);
|
||||
else
|
||||
output_address (XEXP (x, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1362,12 +1362,25 @@ extern struct rtx_def *hppa_builtin_saveregs ();
|
||||
(IS_RELOADING_PSEUDO_P (OP) \
|
||||
|| (GET_CODE (OP) == MEM \
|
||||
&& memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
|
||||
&& ! symbolic_memory_operand (OP, VOIDmode))) \
|
||||
&& ! symbolic_memory_operand (OP, VOIDmode) \
|
||||
&& !(GET_CODE (XEXP (OP, 0)) == PLUS \
|
||||
&& (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
|
||||
|| GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))))\
|
||||
: ((C) == 'R' ? \
|
||||
(GET_CODE (OP) == MEM \
|
||||
&& GET_CODE (XEXP (OP, 0)) == PLUS \
|
||||
&& (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT \
|
||||
|| GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT) \
|
||||
&& (move_operand (OP, GET_MODE (OP)) \
|
||||
|| memory_address_p (GET_MODE (OP), XEXP (OP, 0))))\
|
||||
: ((C) == 'T' ? \
|
||||
(GET_CODE (OP) == MEM \
|
||||
/* Using DFmode forces only short displacements \
|
||||
to be recognized as valid in reg+d addresses. */\
|
||||
&& memory_address_p (DFmode, XEXP (OP, 0))) : 0))
|
||||
&& memory_address_p (DFmode, XEXP (OP, 0)) \
|
||||
&& !(GET_CODE (XEXP (OP, 0)) == PLUS \
|
||||
&& (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
|
||||
|| GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))) : 0)))
|
||||
|
||||
/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
|
||||
and check its validity for a certain class.
|
||||
@ -1462,6 +1475,15 @@ extern struct rtx_def *hppa_builtin_saveregs ();
|
||||
|| ((MODE) != SFmode && (MODE) != DFmode))) \
|
||||
|| INT_5_BITS (index))) \
|
||||
goto ADDR; \
|
||||
if (base \
|
||||
&& (mode == SFmode || mode == DFmode) \
|
||||
&& GET_CODE (index) == MULT \
|
||||
&& GET_CODE (XEXP (index, 0)) == REG \
|
||||
&& REG_OK_FOR_BASE_P (XEXP (index, 0)) \
|
||||
&& GET_CODE (XEXP (index, 1)) == CONST_INT \
|
||||
&& INTVAL (XEXP (index, 1)) == (mode == SFmode ? 4 : 8)\
|
||||
&& shadd_operand (XEXP (index, 1), VOIDmode)) \
|
||||
goto ADDR; \
|
||||
} \
|
||||
else if (GET_CODE (X) == LO_SUM \
|
||||
&& GET_CODE (XEXP (X, 0)) == REG \
|
||||
|
@ -1449,7 +1449,7 @@
|
||||
[(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,Q,*q,!f,f,*T")
|
||||
(match_operand:SI 1 "move_operand"
|
||||
"r,J,N,K,Q,rM,rM,!fM,*T,f"))]
|
||||
"r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
|
||||
"(register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
@ -1462,8 +1462,8 @@
|
||||
stw%M0 %r1,%0
|
||||
mtsar %r1
|
||||
fcpy,sgl %r1,%0
|
||||
fldws%F1 %1,%0
|
||||
fstws%F0 %1,%0"
|
||||
fldw%F1 %1,%0
|
||||
fstw%F0 %1,%0"
|
||||
[(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
|
||||
(set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
|
||||
|
||||
@ -1471,7 +1471,7 @@
|
||||
[(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
|
||||
"=r,r,r,r,r,Q,*q")
|
||||
(match_operand:SI 1 "move_operand"
|
||||
"r,J,N,K,Q,rM,rM"))]
|
||||
"r,J,N,K,RQ,rM,rM"))]
|
||||
"(register_operand (operands[0], SImode)
|
||||
|| reg_or_0_operand (operands[1], SImode))
|
||||
&& TARGET_SOFT_FLOAT"
|
||||
@ -1486,47 +1486,6 @@
|
||||
[(set_attr "type" "move,move,move,move,load,store,move")
|
||||
(set_attr "length" "4,4,4,4,4,4,4")])
|
||||
|
||||
;; Load indexed. We don't use unscaled modes since they can't be used
|
||||
;; unless we can tell which of the registers is the base and which is
|
||||
;; the index, due to PA's idea of segment selection using the top bits
|
||||
;; of the base register.
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(mem:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING"
|
||||
"ldwx,s %1(0,%2),%0"
|
||||
[(set_attr "type" "load")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.)
|
||||
(define_insn ""
|
||||
[(set (match_operand:SI 0 "register_operand" "&=r")
|
||||
(mem:SI (plus:SI (plus:SI
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "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 \"sh2addl %1,%2,%0\;ldw %3(0,%0),%0\";
|
||||
else
|
||||
return \"sh2addl %1,%2,%0\;ldwx %3(0,%0),%0\";
|
||||
}"
|
||||
[(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")
|
||||
@ -1845,7 +1804,7 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
|
||||
(match_operand:HI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))]
|
||||
(match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
|
||||
"register_operand (operands[0], HImode)
|
||||
|| reg_or_0_operand (operands[1], HImode)"
|
||||
"@
|
||||
@ -1860,74 +1819,6 @@
|
||||
[(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:HI 0 "register_operand" "=r")
|
||||
(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")])
|
||||
|
||||
; 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.
|
||||
(define_insn ""
|
||||
[(set (match_operand:HI 0 "register_operand" "=&r")
|
||||
(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")])
|
||||
|
||||
; 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")
|
||||
@ -2074,7 +1965,7 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
|
||||
(match_operand:QI 1 "move_operand" "r,J,N,K,Q,rM,rM,!fM"))]
|
||||
(match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
|
||||
"register_operand (operands[0], QImode)
|
||||
|| reg_or_0_operand (operands[1], QImode)"
|
||||
"@
|
||||
@ -2360,7 +2251,7 @@
|
||||
&& operands[1] != CONST0_RTX (DFmode)
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
"* return (which_alternative == 0 ? output_move_double (operands)
|
||||
: \"fldds%F1 %1,%0\");"
|
||||
: \"fldd%F1 %1,%0\");"
|
||||
[(set_attr "type" "move,fpload")
|
||||
(set_attr "length" "16,4")])
|
||||
|
||||
@ -2409,9 +2300,9 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
|
||||
"=f,*r,Q,?o,?Q,f,*r,*r")
|
||||
"=f,*r,RQ,?o,?Q,f,*r,*r")
|
||||
(match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
|
||||
"fG,*rG,f,*r,*r,Q,o,Q"))]
|
||||
"fG,*rG,f,*r,*r,RQ,o,Q"))]
|
||||
"(register_operand (operands[0], DFmode)
|
||||
|| reg_or_0_operand (operands[1], DFmode))
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
@ -2440,45 +2331,6 @@
|
||||
[(set_attr "type" "move,store,store,load,load")
|
||||
(set_attr "length" "8,8,16,8,16")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 8))
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"flddx,s %1(0,%2),%0"
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.
|
||||
;; Ugh. Output is a FP register; so we need to earlyclobber something
|
||||
;; else as a temporary.
|
||||
(define_insn ""
|
||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(mem:DF (plus:SI
|
||||
(plus:SI
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "+&r")
|
||||
(const_int 8))
|
||||
(match_operand:SI 2 "register_operand" "r"))
|
||||
(match_operand:SI 3 "const_int_operand" "rL"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
return \"sh3addl %1,%2,%1\;fldds %3(0,%1),%0\";
|
||||
else
|
||||
return \"sh3addl %1,%2,%1\;flddx %3(0,%1),%0\";
|
||||
}"
|
||||
[(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")
|
||||
@ -2517,45 +2369,6 @@
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:DF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 8))
|
||||
(match_operand:SI 2 "register_operand" "r")))
|
||||
(match_operand:DF 0 "register_operand" "f"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"fstdx,s %0,%1(0,%2)"
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.
|
||||
;; Ugh. Output is a FP register; so we need to earlyclobber something
|
||||
;; else as a temporary.
|
||||
(define_insn ""
|
||||
[(set (mem:DF (plus:SI
|
||||
(plus:SI
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "+&r")
|
||||
(const_int 8))
|
||||
(match_operand:SI 2 "register_operand" "r"))
|
||||
(match_operand:SI 3 "const_int_operand" "rL")))
|
||||
(match_operand:DF 0 "register_operand" "f"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
return \"sh3addl %1,%2,%1\;fstds %0,%3(0,%1)\";
|
||||
else
|
||||
return \"sh3addl %1,%2,%1\;fstdx %0,%3(0,%1)\";
|
||||
}"
|
||||
[(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")))
|
||||
@ -2741,7 +2554,7 @@
|
||||
&& operands[1] != CONST0_RTX (SFmode)
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
"* return (which_alternative == 0 ? singlemove_string (operands)
|
||||
: \" fldws%F1 %1,%0\");"
|
||||
: \" fldw%F1 %1,%0\");"
|
||||
[(set_attr "type" "move,fpload")
|
||||
(set_attr "length" "8,4")])
|
||||
|
||||
@ -2790,18 +2603,18 @@
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
|
||||
"=f,r,f,r,Q,Q")
|
||||
"=f,r,f,r,RQ,Q")
|
||||
(match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
|
||||
"fG,rG,Q,Q,f,rG"))]
|
||||
"fG,rG,RQ,Q,f,rG"))]
|
||||
"(register_operand (operands[0], SFmode)
|
||||
|| reg_or_0_operand (operands[1], SFmode))
|
||||
&& ! TARGET_SOFT_FLOAT"
|
||||
"@
|
||||
fcpy,sgl %r1,%0
|
||||
copy %r1,%0
|
||||
fldws%F1 %1,%0
|
||||
fldw%F1 %1,%0
|
||||
ldw%M1 %1,%0
|
||||
fstws%F0 %r1,%0
|
||||
fstw%F0 %r1,%0
|
||||
stw%M0 %r1,%0"
|
||||
[(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
|
||||
(set_attr "length" "4,4,4,4,4,4")])
|
||||
@ -2821,45 +2634,6 @@
|
||||
[(set_attr "type" "move,load,store")
|
||||
(set_attr "length" "4,4,4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "register_operand" "r"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"fldwx,s %1(0,%2),%0"
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.
|
||||
;; Ugh. Output is a FP register; so we need to earlyclobber something
|
||||
;; else as a temporary.
|
||||
(define_insn ""
|
||||
[(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(mem:SF (plus:SI
|
||||
(plus:SI
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "+&r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "register_operand" "r"))
|
||||
(match_operand:SI 3 "const_int_operand" "rL"))))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
return \"sh2addl %1,%2,%1\;fldws %3(0,%1),%0\";
|
||||
else
|
||||
return \"sh2addl %1,%2,%1\;fldwx %3(0,%1),%0\";
|
||||
}"
|
||||
[(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")
|
||||
@ -2898,45 +2672,6 @@
|
||||
[(set_attr "type" "fpload")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
(define_insn ""
|
||||
[(set (mem:SF (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "register_operand" "r")))
|
||||
(match_operand:SF 0 "register_operand" "f"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
|
||||
"fstwx,s %0,%1(0,%2)"
|
||||
[(set_attr "type" "fpstore")
|
||||
(set_attr "length" "4")])
|
||||
|
||||
;; This variant of the above insn 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
|
||||
;; has constraints allowing a register. I don't know how this works,
|
||||
;; but it somehow makes sure that out-of-range constants are placed
|
||||
;; in a register which somehow magically is a "const_int_operand".
|
||||
;; (this was stolen from alpha.md, I'm not going to try and change it.
|
||||
;; Ugh. Output is a FP register; so we need to earlyclobber something
|
||||
;; else as a temporary.
|
||||
(define_insn ""
|
||||
[(set (mem:SF (plus:SI
|
||||
(plus:SI
|
||||
(mult:SI (match_operand:SI 1 "register_operand" "+&r")
|
||||
(const_int 4))
|
||||
(match_operand:SI 2 "register_operand" "r"))
|
||||
(match_operand:SI 3 "const_int_operand" "rL")))
|
||||
(match_operand:SF 0 "register_operand" "f"))]
|
||||
"! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT && reload_in_progress"
|
||||
"*
|
||||
{
|
||||
if (GET_CODE (operands[3]) == CONST_INT)
|
||||
return \"sh2addl %1,%2,%1\;fstws %0,%3(0,%1)\";
|
||||
else
|
||||
return \"sh2addl %1,%2,%1\;fstwx %0,%3(0,%1)\";
|
||||
}"
|
||||
[(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")))
|
||||
@ -3072,7 +2807,7 @@
|
||||
[(set (match_operand:SF 0 "register_operand" "=f")
|
||||
(float:SF (match_operand:SI 1 "const_int_operand" "m")))]
|
||||
"! TARGET_SOFT_FLOAT"
|
||||
"fldws %1,%0\;fcnvxf,sgl,sgl %0,%0"
|
||||
"fldw%F1 %1,%0\;fcnvxf,sgl,sgl %0,%0"
|
||||
[(set_attr "type" "fpalu")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
@ -3091,7 +2826,7 @@
|
||||
[(set (match_operand:DF 0 "register_operand" "=f")
|
||||
(float:DF (match_operand:SI 1 "const_int_operand" "m")))]
|
||||
"! TARGET_SOFT_FLOAT"
|
||||
"fldws %1,%0\;fcnvxf,sgl,dbl %0,%0"
|
||||
"fldw%F1 %1,%0\;fcnvxf,sgl,dbl %0,%0"
|
||||
[(set_attr "type" "fpalu")
|
||||
(set_attr "length" "8")])
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user