From patchwork Wed Oct 5 03:33:43 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Miller X-Patchwork-Id: 117735 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 C4770B6F90 for ; Wed, 5 Oct 2011 14:34:20 +1100 (EST) Received: (qmail 30296 invoked by alias); 5 Oct 2011 03:34:16 -0000 Received: (qmail 29771 invoked by uid 22791); 5 Oct 2011 03:34:08 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL, BAYES_00, RDNS_NONE, TO_NO_BRKTS_NORDNS, TW_EG, TW_FN, TW_LX, TW_SV, TW_UC X-Spam-Check-By: sourceware.org Received: from Unknown (HELO shards.monkeyblade.net) (198.137.202.13) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 05 Oct 2011 03:33:51 +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 p953XiJo005478 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Tue, 4 Oct 2011 20:33:44 -0700 Date: Tue, 04 Oct 2011 23:33:43 -0400 (EDT) Message-Id: <20111004.233343.1809479782628669707.davem@davemloft.net> To: gcc-patches@gcc.gnu.org Subject: [PATCH] Add support for more sparc VIS 3.0 instructions. From: David Miller 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 There are only a few VIS 3.0 instructions left after this, such as "lzd" (leading zero detect) and add-with-carry instructions that make use of the 64-bit condition codes. Committed to trunk. gcc/ * config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB, UNSPEC_XMUL): New unspecs. (muldi3_v8plus): Use output_v8plus_mult. (*naddsf3, *nadddf3, *nmulsf3, *nmuldf3, *nmuldf3_extend): New VIS 3.0 combiner patterns. (fhaddsf_vis, fhadddf_vis, fhsubsf_vis, fhsubdf_vis, fnhaddsf_vis, fnhaddf_vis, umulxhi_vis, *umulxhi_sp64, umulxhi_v8plus, xmulx_vis, *xmulx_sp64, xmulx_v8plus, xmulxhi_vis, *xmulxhi_sp64, xmulxhi_v8plus): New VIS 3.0 builtins patterns. * config/sparc/sparc.c (sparc_vis_init_builtins): Emit new builtins. (output_v8plus_mult): New function. * config/sparc/sparc-protos.h: Declare it. * config/sparc/visintrin.h (__vis_fhadds, __vis_fhaddd, __vis_fhsubs, __vis_fhsubd, __vis_fnhadds, __vis_fnhaddd, __vis_umulxhi, __vis_xmulx, __vis_xmulxhi): New intrinsics. * doc/extend.texi: Document new builtins. gcc/testsuite/ * gcc.target/sparc/fhalve.c: New test. * gcc.target/sparc/fnegop.c: New test. * gcc.target/sparc/xmul.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@179535 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 21 +++ gcc/config/sparc/sparc-protos.h | 1 + gcc/config/sparc/sparc.c | 99 +++++++++++ gcc/config/sparc/sparc.md | 273 ++++++++++++++++++++++++++++--- gcc/config/sparc/visintrin.h | 63 +++++++ gcc/doc/extend.texi | 11 ++ gcc/testsuite/ChangeLog | 6 + gcc/testsuite/gcc.target/sparc/fhalve.c | 39 +++++ gcc/testsuite/gcc.target/sparc/fnegop.c | 33 ++++ gcc/testsuite/gcc.target/sparc/xmul.c | 22 +++ 10 files changed, 542 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/sparc/fhalve.c create mode 100644 gcc/testsuite/gcc.target/sparc/fnegop.c create mode 100644 gcc/testsuite/gcc.target/sparc/xmul.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9e3f1a7..b108c01 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2011-10-04 David S. Miller + + * config/sparc/sparc.md (UNSPEC_FHADD, UNSPEC_FHSUB, + UNSPEC_XMUL): New unspecs. + (muldi3_v8plus): Use output_v8plus_mult. + (*naddsf3, *nadddf3, *nmulsf3, *nmuldf3, *nmuldf3_extend): + New VIS 3.0 combiner patterns. + (fhaddsf_vis, fhadddf_vis, fhsubsf_vis, fhsubdf_vis, + fnhaddsf_vis, fnhaddf_vis, umulxhi_vis, *umulxhi_sp64, + umulxhi_v8plus, xmulx_vis, *xmulx_sp64, xmulx_v8plus, + xmulxhi_vis, *xmulxhi_sp64, xmulxhi_v8plus): New VIS 3.0 + builtins patterns. + * config/sparc/sparc.c (sparc_vis_init_builtins): Emit new + builtins. + (output_v8plus_mult): New function. + * config/sparc/sparc-protos.h: Declare it. + * config/sparc/visintrin.h (__vis_fhadds, __vis_fhaddd, + __vis_fhsubs, __vis_fhsubd, __vis_fnhadds, __vis_fnhaddd, + __vis_umulxhi, __vis_xmulx, __vis_xmulxhi): New intrinsics. + * doc/extend.texi: Document new builtins. + 2011-10-04 Richard Henderson * c-typeck.c (c_build_vec_shuffle_expr): Fix uninitialized variable. diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index dfa461a..f7b563e 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -105,6 +105,7 @@ extern int v9_regcmp_p (enum rtx_code); extern int sparc_check_64 (rtx, rtx); extern rtx gen_df_reg (rtx, int); extern void sparc_expand_compare_and_swap_12 (rtx, rtx, rtx, rtx); +extern const char *output_v8plus_mult (rtx, rtx *, const char *); #endif /* RTX_CODE */ #endif /* __SPARC_PROTOS_H__ */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 5e67b4c..b2cbdd2 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -9236,6 +9236,12 @@ sparc_vis_init_builtins (void) void_type_node, 0); tree void_ftype_si = build_function_type_list (void_type_node, intSI_type_node, 0); + tree sf_ftype_sf_sf = build_function_type_list (float_type_node, + float_type_node, + float_type_node, 0); + tree df_ftype_df_df = build_function_type_list (double_type_node, + double_type_node, + double_type_node, 0); /* Packing and expanding vectors. */ def_builtin ("__builtin_vis_fpack16", CODE_FOR_fpack16_vis, @@ -9552,6 +9558,26 @@ sparc_vis_init_builtins (void) def_builtin_const ("__builtin_vis_fucmpeq8", CODE_FOR_fucmpeq8si_vis, si_ftype_v8qi_v8qi); } + + def_builtin_const ("__builtin_vis_fhadds", CODE_FOR_fhaddsf_vis, + sf_ftype_sf_sf); + def_builtin_const ("__builtin_vis_fhaddd", CODE_FOR_fhadddf_vis, + df_ftype_df_df); + def_builtin_const ("__builtin_vis_fhsubs", CODE_FOR_fhsubsf_vis, + sf_ftype_sf_sf); + def_builtin_const ("__builtin_vis_fhsubd", CODE_FOR_fhsubdf_vis, + df_ftype_df_df); + def_builtin_const ("__builtin_vis_fnhadds", CODE_FOR_fnhaddsf_vis, + sf_ftype_sf_sf); + def_builtin_const ("__builtin_vis_fnhaddd", CODE_FOR_fnhadddf_vis, + df_ftype_df_df); + + def_builtin_const ("__builtin_vis_umulxhi", CODE_FOR_umulxhi_vis, + di_ftype_di_di); + def_builtin_const ("__builtin_vis_xmulx", CODE_FOR_xmulx_vis, + di_ftype_di_di); + def_builtin_const ("__builtin_vis_xmulxhi", CODE_FOR_xmulxhi_vis, + di_ftype_di_di); } } @@ -10738,4 +10764,77 @@ sparc_preferred_reload_class (rtx x, reg_class_t rclass) return rclass; } +const char * +output_v8plus_mult (rtx insn, rtx *operands, const char *name) +{ + char mulstr[32]; + + gcc_assert (! TARGET_ARCH64); + + if (sparc_check_64 (operands[1], insn) <= 0) + output_asm_insn ("srl\t%L1, 0, %L1", operands); + if (which_alternative == 1) + output_asm_insn ("sllx\t%H1, 32, %H1", operands); + if (GET_CODE (operands[2]) == CONST_INT) + { + if (which_alternative == 1) + { + output_asm_insn ("or\t%L1, %H1, %H1", operands); + sprintf (mulstr, "%s\t%%H1, %%2, %%L0", name); + output_asm_insn (mulstr, operands); + return "srlx\t%L0, 32, %H0"; + } + else + { + output_asm_insn ("sllx\t%H1, 32, %3", operands); + output_asm_insn ("or\t%L1, %3, %3", operands); + sprintf (mulstr, "%s\t%%3, %%2, %%3", name); + output_asm_insn (mulstr, operands); + output_asm_insn ("srlx\t%3, 32, %H0", operands); + return "mov\t%3, %L0"; + } + } + else if (rtx_equal_p (operands[1], operands[2])) + { + if (which_alternative == 1) + { + output_asm_insn ("or\t%L1, %H1, %H1", operands); + sprintf (mulstr, "%s\t%%H1, %%H1, %%L0", name); + output_asm_insn (mulstr, operands); + return "srlx\t%L0, 32, %H0"; + } + else + { + output_asm_insn ("sllx\t%H1, 32, %3", operands); + output_asm_insn ("or\t%L1, %3, %3", operands); + sprintf (mulstr, "%s\t%%3, %%3, %%3", name); + output_asm_insn (mulstr, operands); + output_asm_insn ("srlx\t%3, 32, %H0", operands); + return "mov\t%3, %L0"; + } + } + if (sparc_check_64 (operands[2], insn) <= 0) + output_asm_insn ("srl\t%L2, 0, %L2", operands); + if (which_alternative == 1) + { + output_asm_insn ("or\t%L1, %H1, %H1", operands); + output_asm_insn ("sllx\t%H2, 32, %L1", operands); + output_asm_insn ("or\t%L2, %L1, %L1", operands); + sprintf (mulstr, "%s\t%%H1, %%L1, %%L0", name); + output_asm_insn (mulstr, operands); + return "srlx\t%L0, 32, %H0"; + } + else + { + output_asm_insn ("sllx\t%H1, 32, %3", operands); + output_asm_insn ("sllx\t%H2, 32, %4", operands); + output_asm_insn ("or\t%L1, %3, %3", operands); + output_asm_insn ("or\t%L2, %4, %4", operands); + sprintf (mulstr, "%s\t%%3, %%4, %%3", name); + output_asm_insn (mulstr, operands); + output_asm_insn ("srlx\t%3, 32, %H0", operands); + return "mov\t%3, %L0"; + } +} + #include "gt-sparc.h" diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 92ec3a6..e491aa1 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -86,6 +86,9 @@ (UNSPEC_FCHKSM16 80) (UNSPEC_PDISTN 81) (UNSPEC_FUCMP 82) + (UNSPEC_FHADD 83) + (UNSPEC_FHSUB 84) + (UNSPEC_XMUL 85) ]) (define_constants @@ -4012,32 +4015,7 @@ (clobber (match_scratch:SI 3 "=&h,X")) (clobber (match_scratch:SI 4 "=&h,X"))] "TARGET_V8PLUS" -{ - if (sparc_check_64 (operands[1], insn) <= 0) - output_asm_insn ("srl\t%L1, 0, %L1", operands); - if (which_alternative == 1) - output_asm_insn ("sllx\t%H1, 32, %H1", operands); - if (GET_CODE (operands[2]) == CONST_INT) - { - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %2, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %2, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; - } - else if (rtx_equal_p (operands[1], operands[2])) - { - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tmulx\t%H1, %H1, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tor\t%L1, %3, %3\n\tmulx\t%3, %3, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; - } - if (sparc_check_64 (operands[2], insn) <= 0) - output_asm_insn ("srl\t%L2, 0, %L2", operands); - if (which_alternative == 1) - return "or\t%L1, %H1, %H1\n\tsllx\t%H2, 32, %L1\n\tor\t%L2, %L1, %L1\n\tmulx\t%H1, %L1, %L0\;srlx\t%L0, 32, %H0"; - else - return "sllx\t%H1, 32, %3\n\tsllx\t%H2, 32, %4\n\tor\t%L1, %3, %3\n\tor\t%L2, %4, %4\n\tmulx\t%3, %4, %3\n\tsrlx\t%3, 32, %H0\n\tmov\t%3, %L0"; -} + "* return output_v8plus_mult (insn, operands, \"mulx\");" [(set_attr "type" "multi") (set_attr "length" "9,8")]) @@ -8407,4 +8385,247 @@ "TARGET_VIS3" "fucmp8\t%1, %2, %0") +(define_insn "*naddsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (plus:SF (match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f"))))] + "TARGET_VIS3" + "fnadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "*nadddf3" + [(set (match_operand:DF 0 "register_operand" "=e") + (neg:DF (plus:DF (match_operand:DF 1 "register_operand" "e") + (match_operand:DF 2 "register_operand" "e"))))] + "TARGET_VIS3" + "fnaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "*nmulsf3" + [(set (match_operand:SF 0 "register_operand" "=f") + (mult:SF (neg:SF (match_operand:SF 1 "register_operand" "f")) + (match_operand:SF 2 "register_operand" "f")))] + "TARGET_VIS3" + "fnmuls\t%1, %2, %0" + [(set_attr "type" "fpmul")]) + +(define_insn "*nmuldf3" + [(set (match_operand:DF 0 "register_operand" "=e") + (mult:DF (neg:DF (match_operand:DF 1 "register_operand" "e")) + (match_operand:DF 2 "register_operand" "e")))] + "TARGET_VIS3" + "fnmuld\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "fptype" "double")]) + +(define_insn "*nmuldf3_extend" + [(set (match_operand:DF 0 "register_operand" "=e") + (mult:DF (neg:DF (float_extend:DF + (match_operand:SF 1 "register_operand" "f"))) + (float_extend:DF + (match_operand:SF 2 "register_operand" "f"))))] + "TARGET_VIS3" + "fnsmuld\t%1, %2, %0" + [(set_attr "type" "fpmul") + (set_attr "fptype" "double")]) + +(define_insn "fhaddsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHADD))] + "TARGET_VIS3" + "fhadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fhadddf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHADD))] + "TARGET_VIS3" + "fhaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "fhsubsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHSUB))] + "TARGET_VIS3" + "fhsubs\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fhsubdf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHSUB))] + "TARGET_VIS3" + "fhsubd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_insn "fnhaddsf_vis" + [(set (match_operand:SF 0 "register_operand" "=f") + (neg:SF (unspec:SF [(match_operand:SF 1 "register_operand" "f") + (match_operand:SF 2 "register_operand" "f")] + UNSPEC_FHADD)))] + "TARGET_VIS3" + "fnhadds\t%1, %2, %0" + [(set_attr "type" "fp")]) + +(define_insn "fnhadddf_vis" + [(set (match_operand:DF 0 "register_operand" "=f") + (neg:DF (unspec:DF [(match_operand:DF 1 "register_operand" "f") + (match_operand:DF 2 "register_operand" "f")] + UNSPEC_FHADD)))] + "TARGET_VIS3" + "fnhaddd\t%1, %2, %0" + [(set_attr "type" "fp") + (set_attr "fptype" "double")]) + +(define_expand "umulxhi_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))) + (const_int 64))))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_umulxhi_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*umulxhi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))) + (const_int 64))))] + "TARGET_VIS3 && TARGET_ARCH64" + "umulxhi\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "umulxhi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (lshiftrt:TI + (mult:TI (zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))) + (const_int 64)))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && ! TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"umulxhi\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + +(define_expand "xmulx_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))] + UNSPEC_XMUL)))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_xmulx_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*xmulx_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))] + UNSPEC_XMUL)))] + "TARGET_VIS3 && TARGET_ARCH64" + "xmulx\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "xmulx_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))] + UNSPEC_XMUL))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && ! TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"xmulx\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + +(define_expand "xmulxhi_vis" + [(set (match_operand:DI 0 "register_operand" "") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" ""))] + UNSPEC_XMUL) + (const_int 64))))] + "TARGET_VIS3" +{ + if (! TARGET_ARCH64) + { + emit_insn (gen_xmulxhi_v8plus (operands[0], operands[1], operands[2])); + DONE; + } +}) + +(define_insn "*xmulxhi_sp64" + [(set (match_operand:DI 0 "register_operand" "=r") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI"))] + UNSPEC_XMUL) + (const_int 64))))] + "TARGET_VIS3 && TARGET_ARCH64" + "xmulxhi\t%1, %2, %0" + [(set_attr "type" "imul")]) + +(define_insn "xmulxhi_v8plus" + [(set (match_operand:DI 0 "register_operand" "=r,h") + (truncate:DI + (lshiftrt:TI + (unspec:TI [(zero_extend:TI + (match_operand:DI 1 "arith_operand" "%r,0")) + (zero_extend:TI + (match_operand:DI 2 "arith_operand" "rI,rI"))] + UNSPEC_XMUL) + (const_int 64)))) + (clobber (match_scratch:SI 3 "=&h,X")) + (clobber (match_scratch:SI 4 "=&h,X"))] + "TARGET_VIS3 && !TARGET_ARCH64" + "* return output_v8plus_mult (insn, operands, \"xmulxhi\");" + [(set_attr "type" "imul") + (set_attr "length" "9,8")]) + (include "sync.md") diff --git a/gcc/config/sparc/visintrin.h b/gcc/config/sparc/visintrin.h index 32e44e5..deb68b4 100644 --- a/gcc/config/sparc/visintrin.h +++ b/gcc/config/sparc/visintrin.h @@ -627,4 +627,67 @@ __vis_fucmpeq8 (__v8qi __A, __v8qi __B) return __builtin_vis_fucmpeq8 (__A, __B); } +extern __inline float +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fhadds (float __A, float __B) +{ + return __builtin_vis_fhadds (__A, __B); +} + +extern __inline double +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fhaddd (double __A, double __B) +{ + return __builtin_vis_fhaddd (__A, __B); +} + +extern __inline float +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fhsubs (float __A, float __B) +{ + return __builtin_vis_fhsubs (__A, __B); +} + +extern __inline double +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fhsubd (double __A, double __B) +{ + return __builtin_vis_fhsubd (__A, __B); +} + +extern __inline float +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fnhadds (float __A, float __B) +{ + return __builtin_vis_fnhadds (__A, __B); +} + +extern __inline double +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_fnhaddd (double __A, double __B) +{ + return __builtin_vis_fnhaddd (__A, __B); +} + +extern __inline __i64 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_umulxhi (__i64 __A, __i64 __B) +{ + return __builtin_vis_umulxhi (__A, __B); +} + +extern __inline __i64 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_xmulx (__i64 __A, __i64 __B) +{ + return __builtin_vis_xmulx (__A, __B); +} + +extern __inline __i64 +__attribute__ ((__gnu_inline__, __always_inline__, __artificial__)) +__vis_xmulxhi (__i64 __A, __i64 __B) +{ + return __builtin_vis_xmulxhi (__A, __B); +} + #endif /* _VISINTRIN_H_INCLUDED */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 20ee772..c3ebf09 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -13099,6 +13099,17 @@ long __builtin_vis_fucmple8 (v8qi, v8qi); long __builtin_vis_fucmpne8 (v8qi, v8qi); long __builtin_vis_fucmpgt8 (v8qi, v8qi); long __builtin_vis_fucmpeq8 (v8qi, v8qi); + +float __builtin_vis_fhadds (float, float); +double __builtin_vis_fhaddd (double, double); +float __builtin_vis_fhsubs (float, float); +double __builtin_vis_fhsubd (double, double); +float __builtin_vis_fnhadds (float, float); +double __builtin_vis_fnhaddd (double, double); + +int64_t __builtin_vis_umulxhi (int64_t, int64_t); +int64_t __builtin_vis_xmulx (int64_t, int64_t); +int64_t __builtin_vis_xmulxhi (int64_t, int64_t); @end smallexample @node SPU Built-in Functions diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b6b02a2..878ff73 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2011-10-04 David S. Miller + + * gcc.target/sparc/fhalve.c: New test. + * gcc.target/sparc/fnegop.c: New test. + * gcc.target/sparc/xmul.c: New test. + 2011-10-04 Janus Weil PR fortran/35831 diff --git a/gcc/testsuite/gcc.target/sparc/fhalve.c b/gcc/testsuite/gcc.target/sparc/fhalve.c new file mode 100644 index 0000000..340b936 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fhalve.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=niagara3 -mvis" } */ + +float test_fhadds (float x, float y) +{ + return __builtin_vis_fhadds (x, y); +} + +double test_fhaddd (double x, double y) +{ + return __builtin_vis_fhaddd (x, y); +} + +float test_fhsubs (float x, float y) +{ + return __builtin_vis_fhsubs (x, y); +} + +double test_fhsubd (double x, double y) +{ + return __builtin_vis_fhsubd (x, y); +} + +float test_fnhadds (float x, float y) +{ + return __builtin_vis_fnhadds (x, y); +} + +double test_fnhaddd (double x, double y) +{ + return __builtin_vis_fnhaddd (x, y); +} + +/* { dg-final { scan-assembler "fhadds\t%" } } */ +/* { dg-final { scan-assembler "fhaddd\t%" } } */ +/* { dg-final { scan-assembler "fhsubs\t%" } } */ +/* { dg-final { scan-assembler "fhsubd\t%" } } */ +/* { dg-final { scan-assembler "fnhadds\t%" } } */ +/* { dg-final { scan-assembler "fnhaddd\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/fnegop.c b/gcc/testsuite/gcc.target/sparc/fnegop.c new file mode 100644 index 0000000..25f8c19 --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/fnegop.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcpu=niagara3 -mvis" } */ + +float test_fnadds(float x, float y) +{ + return -(x + y); +} + +double test_fnaddd(double x, double y) +{ + return -(x + y); +} + +float test_fnmuls(float x, float y) +{ + return -(x * y); +} + +double test_fnmuld(double x, double y) +{ + return -(x * y); +} + +double test_fnsmuld(float x, float y) +{ + return -((double)x * (double)y); +} + +/* { dg-final { scan-assembler "fnadds\t%" } } */ +/* { dg-final { scan-assembler "fnaddd\t%" } } */ +/* { dg-final { scan-assembler "fnmuls\t%" } } */ +/* { dg-final { scan-assembler "fnmuld\t%" } } */ +/* { dg-final { scan-assembler "fnsmuld\t%" } } */ diff --git a/gcc/testsuite/gcc.target/sparc/xmul.c b/gcc/testsuite/gcc.target/sparc/xmul.c new file mode 100644 index 0000000..ce80e6c --- /dev/null +++ b/gcc/testsuite/gcc.target/sparc/xmul.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-mcpu=niagara3 -mvis" } */ +typedef long long int64_t; + +int64_t test_umulxhi (int64_t x, int64_t y) +{ + return __builtin_vis_umulxhi (x, y); +} + +int64_t test_xmulx (int64_t x, int64_t y) +{ + return __builtin_vis_xmulx (x, y); +} + +int64_t test_xmulxhi (int64_t x, int64_t y) +{ + return __builtin_vis_xmulxhi (x, y); +} + +/* { dg-final { scan-assembler "umulxhi\t%" } } */ +/* { dg-final { scan-assembler "xmulx\t%" } } */ +/* { dg-final { scan-assembler "xmulxhi\t%" } } */