Generate 'fone' and 'fones' sparc instructions when possible.

* config/sparc/constraints.md (C, P, Z): New constraints for
	const_doube, const_int, and const_vector "all ones" values.
	Make unused constraint letters comment match reality.
	* config/sparc/predicates.md (const_all_ones_operand,
	register_or_zero_or_all_ones_operand): New predicates.
	* config/sparc/sparc.c (sparc_expand_move): Allow all ones
	as well as zero constants when VIS.
	(sparc_legitimate_constant_p): Likewise.
	* config/sparc/sparc.md (movsi_insn): Add fones alternative.
	(movsf_insn): Likewise
	(movdi_insn_sp64): Add fone alternative.
	(movdf_insn_sp32_v9): Likewise.
	(movdf_insn_sp64): Likewise.

From-SVN: r179173
This commit is contained in:
David S. Miller 2011-09-25 21:03:53 +00:00 committed by David S. Miller
parent a0ce4616fb
commit 7cbcf85bf9
5 changed files with 116 additions and 42 deletions

View File

@ -1,3 +1,19 @@
2011-09-25 David S. Miller <davem@davemloft.net>
* config/sparc/constraints.md (C, P, Z): New constraints for
const_doube, const_int, and const_vector "all ones" values.
Make unused constraint letters comment match reality.
* config/sparc/predicates.md (const_all_ones_operand,
register_or_zero_or_all_ones_operand): New predicates.
* config/sparc/sparc.c (sparc_expand_move): Allow all ones
as well as zero constants when VIS.
(sparc_legitimate_constant_p): Likewise.
* config/sparc/sparc.md (movsi_insn): Add fones alternative.
(movsf_insn): Likewise
(movdi_insn_sp64): Add fone alternative.
(movdf_insn_sp32_v9): Likewise.
(movdf_insn_sp64): Likewise.
2011-09-25 Jakub Jelinek <jakub@redhat.com>
* tree-ssa-structalias.c (intra_create_variable_infos): Treat

View File

@ -18,7 +18,7 @@
;; <http://www.gnu.org/licenses/>.
;;; Unused letters:
;;; ABCD P Z
;;; AB
;;; a jkl q tuvwxyz
@ -52,6 +52,10 @@
(and (match_code "const_double")
(match_test "const_zero_operand (op, mode)")))
(define_constraint "C"
"The floating-point all-ones constant"
(and (match_code "const_double")
(match_test "const_all_ones_operand (op, mode)")))
;; Integer constant constraints
@ -95,6 +99,10 @@
(and (match_code "const_int")
(match_test "ival == 4096")))
(define_constraint "P"
"The integer constant -1"
(and (match_code "const_int")
(match_test "ival == -1")))
;; Extra constraints
;; Our memory extra constraints have to emulate the behavior of 'm' and 'o',
@ -146,3 +154,8 @@
"The vector zero constant"
(and (match_code "const_vector")
(match_test "const_zero_operand (op, mode)")))
(define_constraint "Z"
"The vector all ones constant"
(and (match_code "const_vector")
(match_test "const_all_ones_operand (op, mode)")))

View File

@ -29,6 +29,35 @@
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST1_RTX (mode)")))
;; Return true if the integer representation of OP is
;; all-ones.
(define_predicate "const_all_ones_operand"
(match_code "const_int,const_double,const_vector")
{
if (GET_CODE (op) == CONST_INT && INTVAL (op) == -1)
return true;
#if HOST_BITS_PER_WIDE_INT == 32
if (GET_CODE (op) == CONST_DOUBLE
&& GET_MODE (op) == VOIDmode
&& CONST_DOUBLE_HIGH (op) == ~(HOST_WIDE_INT)0
&& CONST_DOUBLE_LOW (op) == ~(HOST_WIDE_INT)0)
return true;
#endif
if (GET_CODE (op) == CONST_VECTOR)
{
int i, num_elem = CONST_VECTOR_NUNITS (op);
for (i = 0; i < num_elem; i++)
{
rtx n = CONST_VECTOR_ELT (op, i);
if (! const_all_ones_operand (n, mode))
return false;
}
return true;
}
return false;
})
;; Return true if OP is the integer constant 4096.
(define_predicate "const_4096_operand"
(and (match_code "const_int")
@ -211,6 +240,12 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_zero_operand")))
;; Return true if OP is either the zero constant, the all-ones
;; constant, or a register.
(define_predicate "register_or_zero_or_all_ones_operand"
(ior (match_operand 0 "register_or_zero_operand")
(match_operand 0 "const_all_ones_operand")))
;; Return true if OP is a register operand in a floating point register.
(define_predicate "fp_register_operand"
(match_operand 0 "register_operand")

View File

@ -1170,9 +1170,11 @@ sparc_expand_move (enum machine_mode mode, rtx *operands)
if (operands [1] == const0_rtx)
operands[1] = CONST0_RTX (mode);
/* We can clear FP registers if TARGET_VIS, and always other regs. */
/* We can clear or set to all-ones FP registers if TARGET_VIS, and
always other regs. */
if ((TARGET_VIS || REGNO (operands[0]) < SPARC_FIRST_FP_REG)
&& const_zero_operand (operands[1], mode))
&& (const_zero_operand (operands[1], mode)
|| const_all_ones_operand (operands[1], mode)))
return false;
if (REGNO (operands[0]) < SPARC_FIRST_FP_REG
@ -3096,19 +3098,21 @@ sparc_legitimate_constant_p (enum machine_mode mode, rtx x)
return true;
/* Floating point constants are generally not ok.
The only exception is 0.0 in VIS. */
The only exception is 0.0 and all-ones in VIS. */
if (TARGET_VIS
&& SCALAR_FLOAT_MODE_P (mode)
&& const_zero_operand (x, mode))
&& (const_zero_operand (x, mode)
|| const_all_ones_operand (x, mode)))
return true;
return false;
case CONST_VECTOR:
/* Vector constants are generally not ok.
The only exception is 0 in VIS. */
The only exception is 0 or -1 in VIS. */
if (TARGET_VIS
&& const_zero_operand (x, mode))
&& (const_zero_operand (x, mode)
|| const_all_ones_operand (x, mode)))
return true;
return false;

View File

@ -1303,10 +1303,10 @@
})
(define_insn "*movsi_insn"
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d")
(match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J"))]
[(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,!f,!f,!m,d,d")
(match_operand:SI 1 "input_operand" "rI,K,m,rJ,f,m,f,J,P"))]
"(register_operand (operands[0], SImode)
|| register_or_zero_operand (operands[1], SImode))"
|| register_or_zero_or_all_ones_operand (operands[1], SImode))"
"@
mov\t%1, %0
sethi\t%%hi(%a1), %0
@ -1315,8 +1315,9 @@
fmovs\t%1, %0
ld\t%1, %0
st\t%1, %0
fzeros\t%0"
[(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")])
fzeros\t%0
fones\t%0"
[(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")])
(define_insn "*movsi_lo_sum"
[(set (match_operand:SI 0 "register_operand" "=r")
@ -1505,11 +1506,11 @@
(set_attr "fptype" "*,*,*,*,*,*,*,*,*,*,*,*,double,*,*")])
(define_insn "*movdi_insn_sp64"
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b")
(match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J"))]
[(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,r,m,?e,?e,?W,b,b")
(match_operand:DI 1 "input_operand" "rI,N,m,rJ,e,W,e,J,P"))]
"TARGET_ARCH64
&& (register_operand (operands[0], DImode)
|| register_or_zero_operand (operands[1], DImode))"
|| register_or_zero_or_all_ones_operand (operands[1], DImode))"
"@
mov\t%1, %0
sethi\t%%hi(%a1), %0
@ -1518,9 +1519,10 @@
fmovd\t%1, %0
ldd\t%1, %0
std\t%1, %0
fzero\t%0"
[(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga")
(set_attr "fptype" "*,*,*,*,double,*,*,double")])
fzero\t%0
fone\t%0"
[(set_attr "type" "*,*,load,store,fpmove,fpload,fpstore,fga,fga")
(set_attr "fptype" "*,*,*,*,double,*,*,double,double")])
(define_expand "movdi_pic_label_ref"
[(set (match_dup 3) (high:DI
@ -1918,16 +1920,16 @@
})
(define_insn "*movsf_insn"
[(set (match_operand:V32 0 "nonimmediate_operand" "=d,f,*r,*r,*r,f,*r,m,m")
(match_operand:V32 1 "input_operand" "GY,f,*rRY,Q,S,m,m,f,*rGY"))]
[(set (match_operand:V32 0 "nonimmediate_operand" "=d,d,f,*r,*r,*r,f,*r,m,m")
(match_operand:V32 1 "input_operand" "GY,ZC,f,*rRY,Q,S,m,m,f,*rGY"))]
"TARGET_FPU
&& (register_operand (operands[0], <V32:MODE>mode)
|| register_or_zero_operand (operands[1], <V32:MODE>mode))"
|| register_or_zero_or_all_ones_operand (operands[1], <V32:MODE>mode))"
{
if (GET_CODE (operands[1]) == CONST_DOUBLE
&& (which_alternative == 2
|| which_alternative == 3
|| which_alternative == 4))
&& (which_alternative == 3
|| which_alternative == 4
|| which_alternative == 5))
{
REAL_VALUE_TYPE r;
long i;
@ -1942,24 +1944,26 @@
case 0:
return "fzeros\t%0";
case 1:
return "fmovs\t%1, %0";
return "fones\t%0";
case 2:
return "mov\t%1, %0";
return "fmovs\t%1, %0";
case 3:
return "sethi\t%%hi(%a1), %0";
return "mov\t%1, %0";
case 4:
return "#";
return "sethi\t%%hi(%a1), %0";
case 5:
return "#";
case 6:
return "ld\t%1, %0";
case 7:
return "ld\t%1, %0";
case 8:
case 9:
return "st\t%r1, %0";
default:
gcc_unreachable ();
}
}
[(set_attr "type" "fga,fpmove,*,*,*,fpload,load,fpstore,store")])
[(set_attr "type" "fga,fga,fpmove,*,*,*,fpload,load,fpstore,store")])
;; Exactly the same as above, except that all `f' cases are deleted.
;; This is necessary to prevent reload from ever trying to use a `f' reg
@ -2091,15 +2095,16 @@
;; We have available v9 double floats but not 64-bit integer registers.
(define_insn "*movdf_insn_sp32_v9"
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,T,W,U,T,f,*r,o")
(match_operand:V64 1 "input_operand" "GY,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,T,W,U,T,f,*r,o")
(match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,GY,e,T,U,o#F,*roGYDF,*rGYf"))]
"TARGET_FPU
&& TARGET_V9
&& ! TARGET_ARCH64
&& (register_operand (operands[0], <V64:MODE>mode)
|| register_or_zero_operand (operands[1], <V64:MODE>mode))"
|| register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
"@
fzero\t%0
fone\t%0
fmovd\t%1, %0
ldd\t%1, %0
stx\t%r1, %0
@ -2109,9 +2114,9 @@
#
#
#"
[(set_attr "type" "fga,fpmove,load,store,store,load,store,*,*,*")
(set_attr "length" "*,*,*,*,*,*,*,2,2,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*,*,*")])
[(set_attr "type" "fga,fga,fpmove,load,store,store,load,store,*,*,*")
(set_attr "length" "*,*,*,*,*,*,*,*,2,2,2")
(set_attr "fptype" "double,double,double,*,*,*,*,*,*,*,*")])
(define_insn "*movdf_insn_sp32_v9_no_fpu"
[(set (match_operand:DF 0 "nonimmediate_operand" "=U,T,T,r,o")
@ -2132,14 +2137,15 @@
;; We have available both v9 double floats and 64-bit integer registers.
(define_insn "*movdf_insn_sp64"
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,e,e,W,*r,*r,m,*r")
(match_operand:V64 1 "input_operand" "GY,e,W#F,e,*rGY,m,*rGY,DF"))]
[(set (match_operand:V64 0 "nonimmediate_operand" "=b,b,e,e,W,*r,*r,m,*r")
(match_operand:V64 1 "input_operand" "GY,ZC,e,W#F,e,*rGY,m,*rGY,DF"))]
"TARGET_FPU
&& TARGET_ARCH64
&& (register_operand (operands[0], <V64:MODE>mode)
|| register_or_zero_operand (operands[1], <V64:MODE>mode))"
|| register_or_zero_or_all_ones_operand (operands[1], <V64:MODE>mode))"
"@
fzero\t%0
fone\t%0
fmovd\t%1, %0
ldd\t%1, %0
std\t%1, %0
@ -2147,9 +2153,9 @@
ldx\t%1, %0
stx\t%r1, %0
#"
[(set_attr "type" "fga,fpmove,load,store,*,load,store,*")
(set_attr "length" "*,*,*,*,*,*,*,2")
(set_attr "fptype" "double,double,*,*,*,*,*,*")])
[(set_attr "type" "fga,fga,fpmove,load,store,*,load,store,*")
(set_attr "length" "*,*,*,*,*,*,*,*,2")
(set_attr "fptype" "double,double,double,*,*,*,*,*,*")])
(define_insn "*movdf_insn_sp64_no_fpu"
[(set (match_operand:DF 0 "nonimmediate_operand" "=r,r,m")