From facb3fd7396177cc3848b478b9eb519a35880d17 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 5 Oct 2011 03:25:58 +0000 Subject: [PATCH] Add support for more sparc VIS 3.0 instructions. 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. From-SVN: r179535 --- 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 9e3f1a70d40..b108c01f25e 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 dfa461a5f58..f7b563eda9d 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 5e67b4c0093..b2cbdd28e03 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 92ec3a63b2c..e491aa1f777 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 32e44e55810..deb68b4a724 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 20ee772d753..c3ebf095fd0 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 b6b02a278f4..878ff73039f 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 00000000000..340b936b8fa --- /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 00000000000..25f8c199e24 --- /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 00000000000..ce80e6cbbe0 --- /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%" } } */ -- 2.30.2