From patchwork Sun Sep 25 04:45:59 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Miller X-Patchwork-Id: 116266 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 35693B6F76 for ; Sun, 25 Sep 2011 14:47:04 +1000 (EST) Received: (qmail 20709 invoked by alias); 25 Sep 2011 04:47:00 -0000 Received: (qmail 20693 invoked by uid 22791); 25 Sep 2011 04:46:57 -0000 X-SWARE-Spam-Status: No, hits=-1.6 required=5.0 tests=AWL, BAYES_00, TW_UV, TW_VW X-Spam-Check-By: sourceware.org Received: from shards.monkeyblade.net (HELO shards.monkeyblade.net) (198.137.202.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 25 Sep 2011 04:46:43 +0000 Received: from localhost (cpe-66-65-62-183.nyc.res.rr.com [66.65.62.183]) (authenticated bits=0) by shards.monkeyblade.net (8.14.4/8.14.4) with ESMTP id p8P4k06D014417 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 24 Sep 2011 21:46:03 -0700 Date: Sun, 25 Sep 2011 00:45:59 -0400 (EDT) Message-Id: <20110925.004559.310205857952397.davem@davemloft.net> To: hp@bitrange.com Cc: gcc-patches@gcc.gnu.org, ebotcazou@adacore.com Subject: Re: [PATCH] Add VIS intrinsics header for sparc. From: David Miller In-Reply-To: <20110924.020832.1683526855969392801.davem@davemloft.net> References: <20110922.021541.2162102036631303082.davem@davemloft.net> <20110924.020832.1683526855969392801.davem@davemloft.net> Mime-Version: 1.0 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org From: David Miller Date: Sat, 24 Sep 2011 02:08:32 -0400 (EDT) > I'll look into your other suggestion in PR48974, namely making use of > fone VIS instructions. Hans, just FYI, here is a patch I am regression testing which implements this. 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 @@ ;; . ;;; 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], mode) - || register_or_zero_operand (operands[1], mode))" + || register_or_zero_or_all_ones_operand (operands[1], 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], mode) - || register_or_zero_operand (operands[1], mode))" + || register_or_zero_or_all_ones_operand (operands[1], 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], mode) - || register_or_zero_operand (operands[1], mode))" + || register_or_zero_or_all_ones_operand (operands[1], 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")