aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-09-25 21:03:53 +0000
committerDavid S. Miller <davem@gcc.gnu.org>2011-09-25 14:03:53 -0700
commit7cbcf85bf976f8eaeb2beee113b1ea60bdb39f99 (patch)
tree1ed185ca35b27d21246d6298bb3f375233d93b19 /gcc
parenta0ce4616fbfc372de08a3b0d73ce96bb6ac40549 (diff)
downloadgcc-7cbcf85bf976f8eaeb2beee113b1ea60bdb39f99.zip
gcc-7cbcf85bf976f8eaeb2beee113b1ea60bdb39f99.tar.gz
gcc-7cbcf85bf976f8eaeb2beee113b1ea60bdb39f99.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/sparc/constraints.md15
-rw-r--r--gcc/config/sparc/predicates.md35
-rw-r--r--gcc/config/sparc/sparc.c16
-rw-r--r--gcc/config/sparc/sparc.md76
5 files changed, 116 insertions, 42 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 71251ce..4c286fc 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md
index cca34ed..317602c 100644
--- a/gcc/config/sparc/constraints.md
+++ b/gcc/config/sparc/constraints.md
@@ -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)")))
diff --git a/gcc/config/sparc/predicates.md b/gcc/config/sparc/predicates.md
index 4af960a..21399b5 100644
--- a/gcc/config/sparc/predicates.md
+++ b/gcc/config/sparc/predicates.md
@@ -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")
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d648e87..3446379 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -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;
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index e5cf821..f830a39 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -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")