extend.texi (PowerPC Built-in Functions): Document new powerpc extended divide, bcd...
authorMichael Meissner <meissner@linux.vnet.ibm.com>
Thu, 24 Apr 2014 22:42:25 +0000 (22:42 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Thu, 24 Apr 2014 22:42:25 +0000 (22:42 +0000)
[gcc]
2014-04-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

* doc/extend.texi (PowerPC Built-in Functions): Document new
powerpc extended divide, bcd, pack/unpack 128-bit, builtin
functions.
(PowerPC AltiVec/VSX Built-in Functions): Likewise.

* config/rs6000/predicates.md (const_0_to_3_operand): New
predicate to match 0..3 integer constants.

* config/rs6000/rs6000-builtin.def (BU_DFP_MISC_1): Add new macros
to support adding miscellaneous builtin functions.
(BU_DFP_MISC_2): Likewise.
(BU_P7_MISC_1): Likewise.
(BU_P7_MISC_2): Likewise.
(BU_P8V_MISC_3): Likewise.
(BU_MISC_1): Likewise.
(BU_MISC_2): Likewise.
(DIVWE): Add extended divide builtin functions.
(DIVWEO): Likewise.
(DIVWEU): Likewise.
(DIVWEUO): Likewise.
(DIVDE): Likewise.
(DIVDEO): Likewise.
(DIVDEU): Likewise.
(DIVDEUO): Likewise.
(DXEX): Add decimal floating-point builtin functions.
(DXEXQ): Likewise.
(DDEDPD): Likewise.
(DDEDPDQ): Likewise.
(DENBCD): Likewise.
(DENBCDQ): Likewise.
(DIEX): Likewise.
(DIEXQ): Likewise.
(DSCLI): Likewise.
(DSCLIQ): Likewise.
(DSCRI): Likewise.
(DSCRIQ): Likewise.
(CDTBCD): Add new BCD builtin functions.
(CBCDTD): Likewise.
(ADDG6S): Likewise.
(BCDADD): Likewise.
(BCDADD_LT): Likewise.
(BCDADD_EQ): Likewise.
(BCDADD_GT): Likewise.
(BCDADD_OV): Likewise.
(BCDSUB): Likewise.
(BCDSUB_LT): Likewise.
(BCDSUB_EQ): Likewise.
(BCDSUB_GT): Likewise.
(BCDSUB_OV): Likewise.
(PACK_TD): Add new pack/unpack 128-bit type builtin functions.
(UNPACK_TD): Likewise.
(PACK_TF): Likewise.
(UNPACK_TF): Likewise.
(UNPACK_TF_0): Likewise.
(UNPACK_TF_1): Likewise.
(PACK_V1TI): Likewise.
(UNPACK_V1TI): Likewise.

* config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
support for decimal floating point builtin functions.
(rs6000_expand_ternop_builtin): Add checks for the new builtin
functions that take constant arguments.
(rs6000_invalid_builtin): Add decimal floating point builtin
support.
(rs6000_init_builtins): Setup long double, _Decimal64, and
_Decimal128 types for new builtin functions.
(builtin_function_type): Set the unsigned flags appropriately for
the new builtin functions.
(rs6000_opt_masks): Add support for decimal floating point builtin
functions.

* config/rs6000/rs6000.h (RS6000_BTM_DFP): Add support for decimal
floating point builtin functions.
(RS6000_BTM_COMMON): Likewise.
(RS6000_BTI_long_double): Likewise.
(RS6000_BTI_dfloat64): Likewise.
(RS6000_BTI_dfloat128): Likewise.
(long_double_type_internal_node): Likewise.
(dfloat64_type_internal_node): Likewise.
(dfloat128_type_internal_node): Likewise.

* config/rs6000/altivec.h (UNSPEC_BCDADD): Add support for ISA
2.07 bcd arithmetic instructions.
(UNSPEC_BCDSUB): Likewise.
(UNSPEC_BCD_OVERFLOW): Likewise.
(UNSPEC_BCD_ADD_SUB): Likewise.
(bcd_add_sub): Likewise.
(BCD_TEST): Likewise.
(bcd<bcd_add_sub>): Likewise.
(bcd<bcd_add_sub>_test): Likewise.
(bcd<bcd_add_sub>_test2): Likewise.
(bcd<bcd_add_sub>_<code>): Likewise.
(peephole2 for combined bcd ops): Likewise.

* config/rs6000/dfp.md (UNSPEC_DDEDPD): Add support for new
decimal floating point builtin functions.
(UNSPEC_DENBCD): Likewise.
(UNSPEC_DXEX): Likewise.
(UNSPEC_DIEX): Likewise.
(UNSPEC_DSCLI): Likewise.
(UNSPEC_DSCRI): Likewise.
(D64_D128): Likewise.
(dfp_suffix): Likewise.
(dfp_ddedpd_<mode>): Likewise.
(dfp_denbcd_<mode>): Likewise.
(dfp_dxex_<mode>): Likewise.
(dfp_diex_<mode>): Likewise.
(dfp_dscli_<mode>): Likewise.
(dfp_dscri_<mode>): Likewise.

* config/rs6000/rs6000.md (UNSPEC_ADDG6S): Add support for new BCD
builtin functions.
(UNSPEC_CDTBCD): Likewise.
(UNSPEC_CBCDTD): Likewise.
(UNSPEC_DIVE): Add support for new extended divide builtin
functions.
(UNSPEC_DIVEO): Likewise.
(UNSPEC_DIVEU): Likewise.
(UNSPEC_DIVEUO): Likewise.
(UNSPEC_UNPACK_128BIT): Add support for new builtin functions to
pack/unpack 128-bit types.
(UNSPEC_PACK_128BIT): Likewise.
(idiv_ldiv): New mode attribute to set the 32/64-bit divide type.
(udiv<mode>3): Use idiv_ldiv mode attribute.
(div<mode>3): Likewise.
(addg6s): Add new BCD builtin functions.
(cdtbcd): Likewise.
(cbcdtd): Likewise.
(UNSPEC_DIV_EXTEND): Add support for new extended divide
instructions.
(div_extend): Likewise.
(div<div_extend>_<mode>"): Likewise.
(FP128_64): Add support for new builtin functions to pack/unpack
128-bit types.
(unpack<mode>): Likewise.
(unpacktf_0): Likewise.
(unpacktf_1): Likewise.
(unpack<mode>_dm): Likewise.
(unpack<mode>_nodm): Likewise.
(pack<mode>): Likewise.
(unpackv1ti): Likewise.
(packv1ti): Likewise.

[gcc/testsuite]
2014-04-24  Michael Meissner  <meissner@linux.vnet.ibm.com>

* gcc.target/powerpc/pack01.c: New test to test the new pack and
unpack builtin functionss for 128-bit types.
* gcc.target/powerpc/pack02.c: Likewise.
* gcc.target/powerpc/pack03.c: Likewise.
* gcc.target/powerpc/extend-divide-1.c: New test to test extended
divide builtin functionss.
* gcc.target/powerpc/extend-divide-2.c: Likewise.
* gcc.target/powerpc/bcd-1.c: New test for the new BCD builtin
functions.
* gcc.target/powerpc/bcd-2.c: Likewise.
* gcc.target/powerpc/bcd-3.c: Likewise.
* gcc.target/powerpc/dfp-builtin-1.c: New test for the new DFP
builtin functionss.
* gcc.target/powerpc/dfp-builtin-2.c: Likewise.

From-SVN: r209768

20 files changed:
gcc/ChangeLog
gcc/config/rs6000/altivec.md
gcc/config/rs6000/dfp.md
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000-builtin.def
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.h
gcc/config/rs6000/rs6000.md
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/bcd-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/bcd-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/bcd-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/extend-divide-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/extend-divide-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pack01.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pack02.c [new file with mode: 0644]
gcc/testsuite/gcc.target/powerpc/pack03.c [new file with mode: 0644]

index cac9f8d657ea95959041de47256df964990cc1b2..d3d594dfed7c809124e097fe5ae5235d8dc01fe1 100644 (file)
@@ -1,3 +1,148 @@
+2014-04-24  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * doc/extend.texi (PowerPC Built-in Functions): Document new
+       powerpc extended divide, bcd, pack/unpack 128-bit, builtin
+       functions.
+       (PowerPC AltiVec/VSX Built-in Functions): Likewise.
+
+       * config/rs6000/predicates.md (const_0_to_3_operand): New
+       predicate to match 0..3 integer constants.
+
+       * config/rs6000/rs6000-builtin.def (BU_DFP_MISC_1): Add new macros
+       to support adding miscellaneous builtin functions.
+       (BU_DFP_MISC_2): Likewise.
+       (BU_P7_MISC_1): Likewise.
+       (BU_P7_MISC_2): Likewise.
+       (BU_P8V_MISC_3): Likewise.
+       (BU_MISC_1): Likewise.
+       (BU_MISC_2): Likewise.
+       (DIVWE): Add extended divide builtin functions.
+       (DIVWEO): Likewise.
+       (DIVWEU): Likewise.
+       (DIVWEUO): Likewise.
+       (DIVDE): Likewise.
+       (DIVDEO): Likewise.
+       (DIVDEU): Likewise.
+       (DIVDEUO): Likewise.
+       (DXEX): Add decimal floating-point builtin functions.
+       (DXEXQ): Likewise.
+       (DDEDPD): Likewise.
+       (DDEDPDQ): Likewise.
+       (DENBCD): Likewise.
+       (DENBCDQ): Likewise.
+       (DIEX): Likewise.
+       (DIEXQ): Likewise.
+       (DSCLI): Likewise.
+       (DSCLIQ): Likewise.
+       (DSCRI): Likewise.
+       (DSCRIQ): Likewise.
+       (CDTBCD): Add new BCD builtin functions.
+       (CBCDTD): Likewise.
+       (ADDG6S): Likewise.
+       (BCDADD): Likewise.
+       (BCDADD_LT): Likewise.
+       (BCDADD_EQ): Likewise.
+       (BCDADD_GT): Likewise.
+       (BCDADD_OV): Likewise.
+       (BCDSUB): Likewise.
+       (BCDSUB_LT): Likewise.
+       (BCDSUB_EQ): Likewise.
+       (BCDSUB_GT): Likewise.
+       (BCDSUB_OV): Likewise.
+       (PACK_TD): Add new pack/unpack 128-bit type builtin functions.
+       (UNPACK_TD): Likewise.
+       (PACK_TF): Likewise.
+       (UNPACK_TF): Likewise.
+       (UNPACK_TF_0): Likewise.
+       (UNPACK_TF_1): Likewise.
+       (PACK_V1TI): Likewise.
+       (UNPACK_V1TI): Likewise.
+
+       * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
+       support for decimal floating point builtin functions.
+       (rs6000_expand_ternop_builtin): Add checks for the new builtin
+       functions that take constant arguments.
+       (rs6000_invalid_builtin): Add decimal floating point builtin
+       support.
+       (rs6000_init_builtins): Setup long double, _Decimal64, and
+       _Decimal128 types for new builtin functions.
+       (builtin_function_type): Set the unsigned flags appropriately for
+       the new builtin functions.
+       (rs6000_opt_masks): Add support for decimal floating point builtin
+       functions.
+
+       * config/rs6000/rs6000.h (RS6000_BTM_DFP): Add support for decimal
+       floating point builtin functions.
+       (RS6000_BTM_COMMON): Likewise.
+       (RS6000_BTI_long_double): Likewise.
+       (RS6000_BTI_dfloat64): Likewise.
+       (RS6000_BTI_dfloat128): Likewise.
+       (long_double_type_internal_node): Likewise.
+       (dfloat64_type_internal_node): Likewise.
+       (dfloat128_type_internal_node): Likewise.
+
+       * config/rs6000/altivec.h (UNSPEC_BCDADD): Add support for ISA
+       2.07 bcd arithmetic instructions.
+       (UNSPEC_BCDSUB): Likewise.
+       (UNSPEC_BCD_OVERFLOW): Likewise.
+       (UNSPEC_BCD_ADD_SUB): Likewise.
+       (bcd_add_sub): Likewise.
+       (BCD_TEST): Likewise.
+       (bcd<bcd_add_sub>): Likewise.
+       (bcd<bcd_add_sub>_test): Likewise.
+       (bcd<bcd_add_sub>_test2): Likewise.
+       (bcd<bcd_add_sub>_<code>): Likewise.
+       (peephole2 for combined bcd ops): Likewise.
+
+       * config/rs6000/dfp.md (UNSPEC_DDEDPD): Add support for new
+       decimal floating point builtin functions.
+       (UNSPEC_DENBCD): Likewise.
+       (UNSPEC_DXEX): Likewise.
+       (UNSPEC_DIEX): Likewise.
+       (UNSPEC_DSCLI): Likewise.
+       (UNSPEC_DSCRI): Likewise.
+       (D64_D128): Likewise.
+       (dfp_suffix): Likewise.
+       (dfp_ddedpd_<mode>): Likewise.
+       (dfp_denbcd_<mode>): Likewise.
+       (dfp_dxex_<mode>): Likewise.
+       (dfp_diex_<mode>): Likewise.
+       (dfp_dscli_<mode>): Likewise.
+       (dfp_dscri_<mode>): Likewise.
+
+       * config/rs6000/rs6000.md (UNSPEC_ADDG6S): Add support for new BCD
+       builtin functions.
+       (UNSPEC_CDTBCD): Likewise.
+       (UNSPEC_CBCDTD): Likewise.
+       (UNSPEC_DIVE): Add support for new extended divide builtin
+       functions.
+       (UNSPEC_DIVEO): Likewise.
+       (UNSPEC_DIVEU): Likewise.
+       (UNSPEC_DIVEUO): Likewise.
+       (UNSPEC_UNPACK_128BIT): Add support for new builtin functions to
+       pack/unpack 128-bit types.
+       (UNSPEC_PACK_128BIT): Likewise.
+       (idiv_ldiv): New mode attribute to set the 32/64-bit divide type.
+       (udiv<mode>3): Use idiv_ldiv mode attribute.
+       (div<mode>3): Likewise.
+       (addg6s): Add new BCD builtin functions.
+       (cdtbcd): Likewise.
+       (cbcdtd): Likewise.
+       (UNSPEC_DIV_EXTEND): Add support for new extended divide
+       instructions.
+       (div_extend): Likewise.
+       (div<div_extend>_<mode>"): Likewise.
+       (FP128_64): Add support for new builtin functions to pack/unpack
+       128-bit types.
+       (unpack<mode>): Likewise.
+       (unpacktf_0): Likewise.
+       (unpacktf_1): Likewise.
+       (unpack<mode>_dm): Likewise.
+       (unpack<mode>_nodm): Likewise.
+       (pack<mode>): Likewise.
+       (unpackv1ti): Likewise.
+       (packv1ti): Likewise.
+
 2014-04-24  Vishnu K S  <Vishnu.k_s@atmel.com>
 
        * gcc/config/avr/avr.c: Add comment on why -fdelete-null-pointer-checks
index 674cb40bf7a3f9c88523f448f023a5e5f123c85b..a8cfcb739eabfed16960c5e2f8cd507042b50764 100644 (file)
    UNSPEC_VSUBEUQM
    UNSPEC_VSUBECUQ
    UNSPEC_VBPERMQ
+   UNSPEC_BCDADD
+   UNSPEC_BCDSUB
+   UNSPEC_BCD_OVERFLOW
 ])
 
 (define_c_enum "unspecv"
   "vbpermq %0,%1,%2"
   [(set_attr "length" "4")
    (set_attr "type" "vecsimple")])
+
+;; Decimal Integer operations
+(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
+
+(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
+                             (UNSPEC_BCDSUB "sub")])
+
+(define_code_iterator BCD_TEST [eq lt gt unordered])
+
+(define_insn "bcd<bcd_add_sub>"
+  [(set (match_operand:V1TI 0 "register_operand" "")
+       (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+                     (match_operand:V1TI 2 "register_operand" "")
+                     (match_operand:QI 3 "const_0_to_1_operand" "")]
+                    UNSPEC_BCD_ADD_SUB))
+   (clobber (reg:CCFP 74))]
+  "TARGET_P8_VECTOR"
+  "bcd<bcd_add_sub>. %0,%1,%2,%3"
+  [(set_attr "length" "4")
+   (set_attr "type" "vecsimple")])
+
+;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
+;; can use the unordered test for BCD nans and add/subtracts that overflow.  An
+;; UNORDERED test on an integer type (like V1TImode) is not defined.  The type
+;; probably should be one that can go in the VMX (Altivec) registers, so we
+;; can't use DDmode or DFmode.
+(define_insn "*bcd<bcd_add_sub>_test"
+  [(set (reg:CCFP 74)
+       (compare:CCFP
+        (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
+                      (match_operand:V1TI 2 "register_operand" "v")
+                      (match_operand:QI 3 "const_0_to_1_operand" "i")]
+                     UNSPEC_BCD_ADD_SUB)
+        (match_operand:V2DF 4 "zero_constant" "j")))
+   (clobber (match_scratch:V1TI 0 "=v"))]
+  "TARGET_P8_VECTOR"
+  "bcd<bcd_add_sub>. %0,%1,%2,%3"
+  [(set_attr "length" "4")
+   (set_attr "type" "vecsimple")])
+
+(define_insn "*bcd<bcd_add_sub>_test2"
+  [(set (match_operand:V1TI 0 "register_operand" "=v")
+       (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
+                     (match_operand:V1TI 2 "register_operand" "v")
+                     (match_operand:QI 3 "const_0_to_1_operand" "i")]
+                    UNSPEC_BCD_ADD_SUB))
+   (set (reg:CCFP 74)
+       (compare:CCFP
+        (unspec:V2DF [(match_dup 1)
+                      (match_dup 2)
+                      (match_dup 3)]
+                     UNSPEC_BCD_ADD_SUB)
+        (match_operand:V2DF 4 "zero_constant" "j")))]
+  "TARGET_P8_VECTOR"
+  "bcd<bcd_add_sub>. %0,%1,%2,%3"
+  [(set_attr "length" "4")
+   (set_attr "type" "vecsimple")])
+
+(define_expand "bcd<bcd_add_sub>_<code>"
+  [(parallel [(set (reg:CCFP 74)
+                  (compare:CCFP
+                   (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
+                                 (match_operand:V1TI 2 "register_operand" "")
+                                 (match_operand:QI 3 "const_0_to_1_operand" "")]
+                                UNSPEC_BCD_ADD_SUB)
+                   (match_dup 4)))
+             (clobber (match_scratch:V1TI 5 ""))])
+   (set (match_operand:SI 0 "register_operand" "")
+       (BCD_TEST:SI (reg:CCFP 74)
+                    (const_int 0)))]
+  "TARGET_P8_VECTOR"
+{
+  operands[4] = CONST0_RTX (V2DFmode);
+})
+
+;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
+;; the bcdadd/bcdsub that tests the value.  The combiner won't work since
+;; CR6 is a hard coded register.  Unfortunately, all of the Altivec predicate
+;; support is hard coded to use the fixed register CR6 instead of creating
+;; a register class for CR6.
+
+(define_peephole2
+  [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
+                  (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+                                (match_operand:V1TI 2 "register_operand" "")
+                                (match_operand:QI 3 "const_0_to_1_operand" "")]
+                               UNSPEC_BCD_ADD_SUB))
+             (clobber (reg:CCFP 74))])
+   (parallel [(set (reg:CCFP 74)
+                  (compare:CCFP
+                   (unspec:V2DF [(match_dup 1)
+                                 (match_dup 2)
+                                 (match_dup 3)]
+                                UNSPEC_BCD_ADD_SUB)
+                   (match_operand:V2DF 4 "zero_constant" "")))
+             (clobber (match_operand:V1TI 5 "register_operand" ""))])]
+  "TARGET_P8_VECTOR"
+  [(parallel [(set (match_dup 0)
+                  (unspec:V1TI [(match_dup 1)
+                                (match_dup 2)
+                                (match_dup 3)]
+                               UNSPEC_BCD_ADD_SUB))
+             (set (reg:CCFP 74)
+                  (compare:CCFP
+                   (unspec:V2DF [(match_dup 1)
+                                 (match_dup 2)
+                                 (match_dup 3)]
+                                UNSPEC_BCD_ADD_SUB)
+                   (match_dup 4)))])])
index 8e99bc0d7876881af02efeffad2904819aa961c6..40e27e77d2332b629674eb3e2480c950eccede6f 100644 (file)
   "TARGET_DFP"
   "dctfixq %0,%1"
   [(set_attr "type" "fp")])
+
+\f
+;; Decimal builtin support
+
+(define_c_enum "unspec"
+  [UNSPEC_DDEDPD
+   UNSPEC_DENBCD
+   UNSPEC_DXEX
+   UNSPEC_DIEX
+   UNSPEC_DSCLI
+   UNSPEC_DSCRI])
+
+(define_mode_iterator D64_D128 [DD TD])
+
+(define_mode_attr dfp_suffix [(DD "")
+                             (TD "q")])
+
+(define_insn "dfp_ddedpd_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
+                         (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+                        UNSPEC_DDEDPD))]
+  "TARGET_DFP"
+  "ddedpd<dfp_suffix> %1,%0,%2"
+  [(set_attr "type" "fp")])
+
+(define_insn "dfp_denbcd_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
+                         (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+                        UNSPEC_DENBCD))]
+  "TARGET_DFP"
+  "denbcd<dfp_suffix> %1,%0,%2"
+  [(set_attr "type" "fp")])
+
+(define_insn "dfp_dxex_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+                        UNSPEC_DXEX))]
+  "TARGET_DFP"
+  "dxex<dfp_suffix> %0,%1"
+  [(set_attr "type" "fp")])
+
+(define_insn "dfp_diex_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+                         (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+                        UNSPEC_DXEX))]
+  "TARGET_DFP"
+  "diex<dfp_suffix> %0,%1,%2"
+  [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscli_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+                         (match_operand:QI 2 "immediate_operand" "i")]
+                        UNSPEC_DSCLI))]
+  "TARGET_DFP"
+  "dscli<dfp_suffix> %0,%1,%2"
+  [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscri_<mode>"
+  [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+       (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+                         (match_operand:QI 2 "immediate_operand" "i")]
+                        UNSPEC_DSCRI))]
+  "TARGET_DFP"
+  "dscri<dfp_suffix> %0,%1,%2"
+  [(set_attr "type" "fp")])
index 28f4f5d98b1e0ef95c7720c013ab5218072a9df7..99903f367691b2be2de4655997a911a764d46603 100644 (file)
   (and (match_code "const_int")
        (match_test "IN_RANGE (INTVAL (op), 0, 1)")))
 
+;; Match op = 0..3.
+(define_predicate "const_0_to_3_operand"
+  (and (match_code "const_int")
+       (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
+
 ;; Match op = 2 or op = 3.
 (define_predicate "const_2_to_3_operand"
   (and (match_code "const_int")
index 83351691fa5fee510ae123649c7c111dac60b500..16793f501e722cdf4609a525d83a8105e9d5a011 100644 (file)
                    MASK,                               /* MASK */      \
                    (ATTR | RS6000_BTC_SPECIAL),        /* ATTR */      \
                    CODE_FOR_nothing)                   /* ICODE */
+
+
+/* Decimal floating point builtins for instructions.  */
+#define BU_DFP_MISC_1(ENUM, NAME, ATTR, ICODE)                         \
+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_DFP,                     /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_UNARY),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_DFP_MISC_2(ENUM, NAME, ATTR, ICODE)                         \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_DFP,                     /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.06.  These
+   instructions don't require either the DFP or VSX options, just the basic ISA
+   2.06 (popcntd) enablement since they operate on general purpose
+   registers.  */
+#define BU_P7_MISC_1(ENUM, NAME, ATTR, ICODE)                          \
+  RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_POPCNTD,                 /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_UNARY),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_P7_MISC_2(ENUM, NAME, ATTR, ICODE)                          \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_POPCNTD,                 /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.07.  These
+   instructions do require the ISA 2.07 vector support, but they aren't vector
+   instructions.  */
+#define BU_P8V_MISC_3(ENUM, NAME, ATTR, ICODE)                         \
+  RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_P8_VECTOR,               /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_TERNARY),                             \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+/* Miscellaneous builtins.  */
+#define BU_MISC_1(ENUM, NAME, ATTR, ICODE)                             \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_ALWAYS,                  /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_UNARY),                               \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
+#define BU_MISC_2(ENUM, NAME, ATTR, ICODE)                             \
+  RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM,             /* ENUM */      \
+                   "__builtin_" NAME,                  /* NAME */      \
+                   RS6000_BTM_ALWAYS,                  /* MASK */      \
+                   (RS6000_BTC_ ## ATTR                /* ATTR */      \
+                    | RS6000_BTC_BINARY),                              \
+                   CODE_FOR_ ## ICODE)                 /* ICODE */
+
 #endif
 
 /* Insure 0 is not a legitimate index.  */
@@ -1412,10 +1481,10 @@ BU_P8V_AV_2 (ORC_V4SF,          "orc_v4sf",     CONST,  orcv4sf3)
 BU_P8V_AV_2 (ORC_V2DF,         "orc_v2df",     CONST,  orcv2df3)
 
 /* 3 argument altivec instructions added in ISA 2.07.  */
-BU_P8V_AV_3 (VADDEUQM,         "vaddeuqm",      CONST, altivec_vaddeuqm)
-BU_P8V_AV_3 (VADDECUQ,         "vaddecuq",      CONST, altivec_vaddecuq)
-BU_P8V_AV_3 (VSUBEUQM,         "vsubeuqm",      CONST, altivec_vsubeuqm)
-BU_P8V_AV_3 (VSUBECUQ,         "vsubecuq",      CONST, altivec_vsubecuq)
+BU_P8V_AV_3 (VADDEUQM,         "vaddeuqm",     CONST,  altivec_vaddeuqm)
+BU_P8V_AV_3 (VADDECUQ,         "vaddecuq",     CONST,  altivec_vaddecuq)
+BU_P8V_AV_3 (VSUBEUQM,         "vsubeuqm",     CONST,  altivec_vsubeuqm)
+BU_P8V_AV_3 (VSUBECUQ,         "vsubecuq",     CONST,  altivec_vsubecuq)
 
 /* Vector comparison instructions added in ISA 2.07.  */
 BU_P8V_AV_2 (VCMPEQUD,         "vcmpequd",     CONST,  vector_eqv2di)
@@ -1474,6 +1543,64 @@ BU_P8V_OVERLOAD_3 (VADDEUQM,     "vaddeuqm")
 BU_P8V_OVERLOAD_3 (VSUBECUQ,   "vsubecuq")
 BU_P8V_OVERLOAD_3 (VSUBEUQM,   "vsubeuqm")
 
+\f
+/* 2 argument extended divide functions added in ISA 2.06.  */
+BU_P7_MISC_2 (DIVWE,           "divwe",        CONST,  dive_si)
+BU_P7_MISC_2 (DIVWEO,          "divweo",       CONST,  diveo_si)
+BU_P7_MISC_2 (DIVWEU,          "divweu",       CONST,  diveu_si)
+BU_P7_MISC_2 (DIVWEUO,         "divweuo",      CONST,  diveuo_si)
+BU_P7_MISC_2 (DIVDE,           "divde",        CONST,  dive_di)
+BU_P7_MISC_2 (DIVDEO,          "divdeo",       CONST,  diveo_di)
+BU_P7_MISC_2 (DIVDEU,          "divdeu",       CONST,  diveu_di)
+BU_P7_MISC_2 (DIVDEUO,         "divdeuo",      CONST,  diveuo_di)
+
+/* 1 argument DFP (decimal floating point) functions added in ISA 2.05.  */
+BU_DFP_MISC_1 (DXEX,           "dxex",         CONST,  dfp_dxex_dd)
+BU_DFP_MISC_1 (DXEXQ,          "dxexq",        CONST,  dfp_dxex_td)
+
+/* 2 argument DFP (decimal floating point) functions added in ISA 2.05.  */
+BU_DFP_MISC_2 (DDEDPD,         "ddedpd",       CONST,  dfp_ddedpd_dd)
+BU_DFP_MISC_2 (DDEDPDQ,                "ddedpdq",      CONST,  dfp_ddedpd_td)
+BU_DFP_MISC_2 (DENBCD,         "denbcd",       CONST,  dfp_denbcd_dd)
+BU_DFP_MISC_2 (DENBCDQ,                "denbcdq",      CONST,  dfp_denbcd_td)
+BU_DFP_MISC_2 (DIEX,           "diex",         CONST,  dfp_diex_dd)
+BU_DFP_MISC_2 (DIEXQ,          "diexq",        CONST,  dfp_diex_td)
+BU_DFP_MISC_2 (DSCLI,          "dscli",        CONST,  dfp_dscli_dd)
+BU_DFP_MISC_2 (DSCLIQ,         "dscliq",       CONST,  dfp_dscli_td)
+BU_DFP_MISC_2 (DSCRI,          "dscri",        CONST,  dfp_dscri_dd)
+BU_DFP_MISC_2 (DSCRIQ,         "dscriq",       CONST,  dfp_dscri_td)
+
+/* 1 argument BCD functions added in ISA 2.06.  */
+BU_P7_MISC_1 (CDTBCD,          "cdtbcd",       CONST,  cdtbcd)
+BU_P7_MISC_1 (CBCDTD,          "cbcdtd",       CONST,  cbcdtd)
+
+/* 2 argument BCD functions added in ISA 2.06.  */
+BU_P7_MISC_2 (ADDG6S,          "addg6s",       CONST,  addg6s)
+
+/* 3 argument BCD functions added in ISA 2.07.  */
+BU_P8V_MISC_3 (BCDADD,         "bcdadd",       CONST,  bcdadd)
+BU_P8V_MISC_3 (BCDADD_LT,      "bcdadd_lt",    CONST,  bcdadd_lt)
+BU_P8V_MISC_3 (BCDADD_EQ,      "bcdadd_eq",    CONST,  bcdadd_eq)
+BU_P8V_MISC_3 (BCDADD_GT,      "bcdadd_gt",    CONST,  bcdadd_gt)
+BU_P8V_MISC_3 (BCDADD_OV,      "bcdadd_ov",    CONST,  bcdadd_unordered)
+BU_P8V_MISC_3 (BCDSUB,         "bcdsub",       CONST,  bcdsub)
+BU_P8V_MISC_3 (BCDSUB_LT,      "bcdsub_lt",    CONST,  bcdsub_lt)
+BU_P8V_MISC_3 (BCDSUB_EQ,      "bcdsub_eq",    CONST,  bcdsub_eq)
+BU_P8V_MISC_3 (BCDSUB_GT,      "bcdsub_gt",    CONST,  bcdsub_gt)
+BU_P8V_MISC_3 (BCDSUB_OV,      "bcdsub_ov",    CONST,  bcdsub_unordered)
+
+/* 2 argument pack/unpack 128-bit floating point types.  */
+BU_DFP_MISC_2 (PACK_TD,                "pack_dec128",          CONST,  packtd)
+BU_DFP_MISC_2 (UNPACK_TD,      "unpack_dec128",        CONST,  unpacktd)
+
+BU_MISC_2 (PACK_TF,            "pack_longdouble",      CONST,  packtf)
+BU_MISC_2 (UNPACK_TF,          "unpack_longdouble",    CONST,  unpacktf)
+BU_MISC_1 (UNPACK_TF_0,                "longdouble_dw0",       CONST,  unpacktf_0)
+BU_MISC_1 (UNPACK_TF_1,                "longdouble_dw1",       CONST,  unpacktf_1)
+
+BU_P7_MISC_2 (PACK_V1TI,       "pack_vector_int128",   CONST,  packv1ti)
+BU_P7_MISC_2 (UNPACK_V1TI,     "unpack_vector_int128", CONST,  unpackv1ti)
+
 \f
 /* 1 argument crypto functions.  */
 BU_CRYPTO_1 (VSBOX,            "vsbox",          CONST, crypto_vsbox)
index d15b3ca9b9c87356da0b0dbf40e017619606cfb6..ca8fa5953c29480a7311f00596cf120dba60842b 100644 (file)
@@ -3038,7 +3038,8 @@ rs6000_builtin_mask_calculate (void)
          | ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL      : 0)
          | ((TARGET_P8_VECTOR)             ? RS6000_BTM_P8_VECTOR : 0)
          | ((TARGET_CRYPTO)                ? RS6000_BTM_CRYPTO    : 0)
-         | ((TARGET_HTM)                   ? RS6000_BTM_HTM       : 0));
+         | ((TARGET_HTM)                   ? RS6000_BTM_HTM       : 0)
+         | ((TARGET_DFP)                   ? RS6000_BTM_DFP       : 0));
 }
 
 /* Override command line options.  Mostly we process the processor type and
@@ -12402,7 +12403,15 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
        }
     }
   else if (icode == CODE_FOR_vsx_set_v2df
-           || icode == CODE_FOR_vsx_set_v2di)
+           || icode == CODE_FOR_vsx_set_v2di
+          || icode == CODE_FOR_bcdadd
+          || icode == CODE_FOR_bcdadd_lt
+          || icode == CODE_FOR_bcdadd_eq
+          || icode == CODE_FOR_bcdadd_gt
+          || icode == CODE_FOR_bcdsub
+          || icode == CODE_FOR_bcdsub_lt
+          || icode == CODE_FOR_bcdsub_eq
+          || icode == CODE_FOR_bcdsub_gt)
     {
       /* Only allow 1-bit unsigned literals.  */
       STRIP_NOPS (arg2);
@@ -12413,6 +12422,44 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
          return const0_rtx;
        }
     }
+  else if (icode == CODE_FOR_dfp_ddedpd_dd
+           || icode == CODE_FOR_dfp_ddedpd_td)
+    {
+      /* Only allow 2-bit unsigned literals where the value is 0 or 2.  */
+      STRIP_NOPS (arg0);
+      if (TREE_CODE (arg0) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg2) & ~0x3)
+       {
+         error ("argument 1 must be 0 or 2");
+         return const0_rtx;
+       }
+    }
+  else if (icode == CODE_FOR_dfp_denbcd_dd
+          || icode == CODE_FOR_dfp_denbcd_td)
+    {
+      /* Only allow 1-bit unsigned literals.  */
+      STRIP_NOPS (arg0);
+      if (TREE_CODE (arg0) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg0) & ~0x1)
+       {
+         error ("argument 1 must be a 1-bit unsigned literal");
+         return const0_rtx;
+       }
+    }
+  else if (icode == CODE_FOR_dfp_dscli_dd
+           || icode == CODE_FOR_dfp_dscli_td
+          || icode == CODE_FOR_dfp_dscri_dd
+          || icode == CODE_FOR_dfp_dscri_td)
+    {
+      /* Only allow 6-bit unsigned literals.  */
+      STRIP_NOPS (arg1);
+      if (TREE_CODE (arg1) != INTEGER_CST
+         || TREE_INT_CST_LOW (arg1) & ~0x3f)
+       {
+         error ("argument 2 must be a 6-bit unsigned literal");
+         return const0_rtx;
+       }
+    }
   else if (icode == CODE_FOR_crypto_vshasigmaw
           || icode == CODE_FOR_crypto_vshasigmad)
     {
@@ -13504,6 +13551,14 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
     error ("Builtin function %s requires the -mpaired option", name);
   else if ((fnmask & RS6000_BTM_SPE) != 0)
     error ("Builtin function %s requires the -mspe option", name);
+  else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+          == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+    error ("Builtin function %s requires the -mhard-dfp and"
+          "-mpower8-vector options", name);
+  else if ((fnmask & RS6000_BTM_DFP) != 0)
+    error ("Builtin function %s requires the -mhard-dfp option", name);
+  else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
+    error ("Builtin function %s requires the -mpower8-vector option", name);
   else
     error ("Builtin function %s is not supported with the current options",
           name);
@@ -13783,6 +13838,9 @@ rs6000_init_builtins (void)
   uintTI_type_internal_node = unsigned_intTI_type_node;
   float_type_internal_node = float_type_node;
   double_type_internal_node = double_type_node;
+  long_double_type_internal_node = long_double_type_node;
+  dfloat64_type_internal_node = dfloat64_type_node;
+  dfloat128_type_internal_node = dfloat128_type_node;
   void_type_internal_node = void_type_node;
 
   /* Initialize the modes for builtin_function_type, mapping a machine mode to
@@ -13797,6 +13855,9 @@ rs6000_init_builtins (void)
   builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
   builtin_mode_to_type[SFmode][0] = float_type_node;
   builtin_mode_to_type[DFmode][0] = double_type_node;
+  builtin_mode_to_type[TFmode][0] = long_double_type_node;
+  builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
+  builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
   builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
   builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
   builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
@@ -14889,6 +14950,8 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
       /* unsigned 1 argument functions.  */
     case CRYPTO_BUILTIN_VSBOX:
     case P8V_BUILTIN_VGBBD:
+    case MISC_BUILTIN_CDTBCD:
+    case MISC_BUILTIN_CBCDTD:
       h.uns_p[0] = 1;
       h.uns_p[1] = 1;
       break;
@@ -14907,6 +14970,11 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
     case CRYPTO_BUILTIN_VPMSUMW:
     case CRYPTO_BUILTIN_VPMSUMD:
     case CRYPTO_BUILTIN_VPMSUM:
+    case MISC_BUILTIN_ADDG6S:
+    case MISC_BUILTIN_DIVWEU:
+    case MISC_BUILTIN_DIVWEUO:
+    case MISC_BUILTIN_DIVDEU:
+    case MISC_BUILTIN_DIVDEUO:
       h.uns_p[0] = 1;
       h.uns_p[1] = 1;
       h.uns_p[2] = 1;
@@ -14968,9 +15036,18 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
       /* signed args, unsigned return.  */
     case VSX_BUILTIN_XVCVDPUXDS_UNS:
     case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI:
+    case MISC_BUILTIN_UNPACK_TD:
+    case MISC_BUILTIN_UNPACK_V1TI:
       h.uns_p[0] = 1;
       break;
 
+      /* unsigned arguments for 128-bit pack instructions.  */
+    case MISC_BUILTIN_PACK_TD:
+    case MISC_BUILTIN_PACK_V1TI:
+      h.uns_p[1] = 1;
+      h.uns_p[2] = 1;
+      break;
+
     default:
       break;
     }
@@ -31224,6 +31301,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
   { "power8-vector",    RS6000_BTM_P8_VECTOR,  false, false },
   { "crypto",           RS6000_BTM_CRYPTO,     false, false },
   { "htm",              RS6000_BTM_HTM,        false, false },
+  { "hard-dfp",                 RS6000_BTM_DFP,        false, false },
 };
 
 /* Option variables that we want to support inside attribute((target)) and
index 9ec3647fedd3ae15c113484b0fd6d42c23a41a15..5a96bebaf10628cff2d13cc5239335d50f067802 100644 (file)
@@ -2516,6 +2516,7 @@ extern int frame_pointer_needed;
 #define RS6000_BTM_FRSQRTES    MASK_POPCNTB    /* FRSQRTES instruction.  */
 #define RS6000_BTM_POPCNTD     MASK_POPCNTD    /* Target supports ISA 2.06.  */
 #define RS6000_BTM_CELL                MASK_FPRND      /* Target is cell powerpc.  */
+#define RS6000_BTM_DFP         MASK_DFP        /* Decimal floating point.  */
 
 #define RS6000_BTM_COMMON      (RS6000_BTM_ALTIVEC                     \
                                 | RS6000_BTM_VSX                       \
@@ -2527,7 +2528,8 @@ extern int frame_pointer_needed;
                                 | RS6000_BTM_FRSQRTES                  \
                                 | RS6000_BTM_HTM                       \
                                 | RS6000_BTM_POPCNTD                   \
-                                | RS6000_BTM_CELL)
+                                | RS6000_BTM_CELL                      \
+                                | RS6000_BTM_DFP)
 
 /* Define builtin enum index.  */
 
@@ -2622,6 +2624,9 @@ enum rs6000_builtin_type_index
   RS6000_BTI_UINTTI,            /* unsigned_intTI_type_node */
   RS6000_BTI_float,             /* float_type_node */
   RS6000_BTI_double,            /* double_type_node */
+  RS6000_BTI_long_double,        /* long_double_type_node */
+  RS6000_BTI_dfloat64,          /* dfloat64_type_node */
+  RS6000_BTI_dfloat128,                 /* dfloat128_type_node */
   RS6000_BTI_void,              /* void_type_node */
   RS6000_BTI_MAX
 };
@@ -2673,6 +2678,9 @@ enum rs6000_builtin_type_index
 #define uintTI_type_internal_node       (rs6000_builtin_types[RS6000_BTI_UINTTI])
 #define float_type_internal_node        (rs6000_builtin_types[RS6000_BTI_float])
 #define double_type_internal_node       (rs6000_builtin_types[RS6000_BTI_double])
+#define long_double_type_internal_node  (rs6000_builtin_types[RS6000_BTI_long_double])
+#define dfloat64_type_internal_node     (rs6000_builtin_types[RS6000_BTI_dfloat64])
+#define dfloat128_type_internal_node    (rs6000_builtin_types[RS6000_BTI_dfloat128])
 #define void_type_internal_node                 (rs6000_builtin_types[RS6000_BTI_void])
 
 extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
index eca1dde06b60a1acb0047550bfd8ff3375d811af..9207b4d5106f74ee5afda7f3bb1f3bc865c44e14 100644 (file)
    UNSPEC_P8V_MTVSRD
    UNSPEC_P8V_XXPERMDI
    UNSPEC_P8V_RELOAD_FROM_VSX
+   UNSPEC_ADDG6S
+   UNSPEC_CDTBCD
+   UNSPEC_CBCDTD
+   UNSPEC_DIVE
+   UNSPEC_DIVEO
+   UNSPEC_DIVEU
+   UNSPEC_DIVEUO
+   UNSPEC_UNPACK_128BIT
+   UNSPEC_PACK_128BIT
   ])
 
 ;;
                                         (V2DF  "X,X,X,X,X")
                                         (V1TI  "X,X,X,X,X")])
 
+;; Mode attribute to give the correct type for integer divides
+(define_mode_attr idiv_ldiv [(SI "idiv")
+                            (DI "ldiv")])
+
 \f
 ;; Start with fixed-point load and store insns.  Here we put only the more
 ;; complex forms.  Basic data transfer is done later.
                  (match_operand:GPR 2 "gpc_reg_operand" "r")))]
   ""
   "div<wd>u %0,%1,%2"
-   [(set (attr "type")
-      (cond [(match_operand:SI 0 "" "")
-               (const_string "idiv")]
-       (const_string "ldiv")))])
+   [(set_attr "type" "<idiv_ldiv>")])
 
 
 ;; For powers of two we can do srai/aze for divide and then adjust for
                 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
   ""
   "div<wd> %0,%1,%2"
-  [(set (attr "type")
-     (cond [(match_operand:SI 0 "" "")
-               (const_string "idiv")]
-       (const_string "ldiv")))])
+  [(set_attr "type" "<idiv_ldiv>")])
 
 (define_expand "mod<mode>3"
   [(use (match_operand:GPR 0 "gpc_reg_operand" ""))
   DONE;
 })
 
+\f
+;; Miscellaneous ISA 2.06 (power7) instructions
+(define_insn "addg6s"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+                   (match_operand:SI 2 "register_operand" "r")]
+                  UNSPEC_ADDG6S))]
+  "TARGET_POPCNTD"
+  "addg6s %0,%1,%2"
+  [(set_attr "type" "integer")
+   (set_attr "length" "4")])
+
+(define_insn "cdtbcd"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+                  UNSPEC_CDTBCD))]
+  "TARGET_POPCNTD"
+  "cdtbcd %0,%1"
+  [(set_attr "type" "integer")
+   (set_attr "length" "4")])
+
+(define_insn "cbcdtd"
+  [(set (match_operand:SI 0 "register_operand" "=r")
+       (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+                  UNSPEC_CBCDTD))]
+  "TARGET_POPCNTD"
+  "cbcdtd %0,%1"
+  [(set_attr "type" "integer")
+   (set_attr "length" "4")])
+
+(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
+                                       UNSPEC_DIVEO
+                                       UNSPEC_DIVEU
+                                       UNSPEC_DIVEUO])
+
+(define_int_attr div_extend [(UNSPEC_DIVE      "e")
+                            (UNSPEC_DIVEO      "eo")
+                            (UNSPEC_DIVEU      "eu")
+                            (UNSPEC_DIVEUO     "euo")])
+
+(define_insn "div<div_extend>_<mode>"
+  [(set (match_operand:GPR 0 "register_operand" "=r")
+       (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
+                    (match_operand:GPR 2 "register_operand" "r")]
+                   UNSPEC_DIV_EXTEND))]
+  "TARGET_POPCNTD"
+  "div<wd><div_extend> %0,%1,%2"
+  [(set_attr "type" "<idiv_ldiv>")])
+
+\f
+;; Pack/unpack 128-bit floating point types that take 2 scalar registers
+
+; Type of the 64-bit part when packing/unpacking 128-bit floating point types
+(define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
+
+(define_expand "unpack<mode>"
+  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
+       (unspec:<FP128_64>
+        [(match_operand:FMOVE128 1 "register_operand" "")
+         (match_operand:QI 2 "const_0_to_1_operand" "")]
+        UNSPEC_UNPACK_128BIT))]
+  ""
+  "")
+
+;; The Advance Toolchain 7.0-3 added private builtins: __builtin_longdouble_dw0
+;; and __builtin_longdouble_dw1 to optimize glibc.  Add support for these
+;; builtins here.
+
+(define_expand "unpacktf_0"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "")
+       (unspec:DF [(match_operand:TF 1 "register_operand" "")
+                   (const_int 0)]
+        UNSPEC_UNPACK_128BIT))]
+  ""
+  "")
+
+(define_expand "unpacktf_1"
+  [(set (match_operand:DF 0 "nonimmediate_operand" "")
+       (unspec:DF [(match_operand:TF 1 "register_operand" "")
+                   (const_int 1)]
+        UNSPEC_UNPACK_128BIT))]
+  ""
+  "")
+
+(define_insn_and_split "unpack<mode>_dm"
+  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
+       (unspec:<FP128_64>
+        [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
+         (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
+        UNSPEC_UNPACK_128BIT))]
+  "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 3))]
+{
+  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+    {
+      emit_note (NOTE_INSN_DELETED);
+      DONE;
+    }
+
+  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+  [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
+   (set_attr "length" "4")])
+
+(define_insn_and_split "unpack<mode>_nodm"
+  [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
+       (unspec:<FP128_64>
+        [(match_operand:FMOVE128 1 "register_operand" "d,d")
+         (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
+        UNSPEC_UNPACK_128BIT))]
+  "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
+  "#"
+  "&& reload_completed"
+  [(set (match_dup 0) (match_dup 3))]
+{
+  unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+  if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+    {
+      emit_note (NOTE_INSN_DELETED);
+      DONE;
+    }
+
+  operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+  [(set_attr "type" "fp,fpstore")
+   (set_attr "length" "4")])
+
+(define_insn_and_split "pack<mode>"
+  [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
+       (unspec:FMOVE128
+        [(match_operand:<FP128_64> 1 "register_operand" "0,d")
+         (match_operand:<FP128_64> 2 "register_operand" "d,d")]
+        UNSPEC_PACK_128BIT))]
+  ""
+  "@
+   fmr %L0,%2
+   #"
+  "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
+  [(set (match_dup 3) (match_dup 1))
+   (set (match_dup 4) (match_dup 2))]
+{
+  unsigned dest_hi = REGNO (operands[0]);
+  unsigned dest_lo = dest_hi + 1;
+
+  gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
+  gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+
+  operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+  operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+}
+  [(set_attr "type" "fp,fp")
+   (set_attr "length" "4,8")])
+
+(define_insn "unpackv1ti"
+  [(set (match_operand:DI 0 "register_operand" "=d,d")
+       (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
+                   (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
+        UNSPEC_UNPACK_128BIT))]
+  "TARGET_VSX"
+{
+  if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
+    return ASM_COMMENT_START " xxpermdi to same register";
+
+  operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
+  return "xxpermdi %x0,%x1,%x1,%3";
+}
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4")])
+
+(define_insn "packv1ti"
+  [(set (match_operand:V1TI 0 "register_operand" "=wa")
+       (unspec:V1TI
+        [(match_operand:DI 1 "register_operand" "d")
+         (match_operand:DI 2 "register_operand" "d")]
+        UNSPEC_PACK_128BIT))]
+  "TARGET_VSX"
+  "xxpermdi %x0,%x1,%x2,0"
+  [(set_attr "type" "vecperm")
+   (set_attr "length" "4")])
+
 \f
 
 (include "sync.md")
index 347a94a3aeee3895b2218bdda39905aae7fe5195..9780d923804b0a37bb44eac068fa2a8f97bc45ae 100644 (file)
@@ -12787,9 +12787,12 @@ float __builtin_recipdivf (float, float);
 float __builtin_rsqrtf (float);
 double __builtin_recipdiv (double, double);
 double __builtin_rsqrt (double);
-long __builtin_bpermd (long, long);
 uint64_t __builtin_ppc_get_timebase ();
 unsigned long __builtin_ppc_mftb ();
+double __builtin_unpack_longdouble (long double, int);
+double __builtin_longdouble_dw0 (long double);
+double __builtin_longdouble_dw1 (long double);
+long double __builtin_pack_longdouble (double, double);
 @end smallexample
 
 The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
@@ -12809,6 +12812,57 @@ The @code{__builtin_ppc_mftb} function always generates one instruction and
 returns the Time Base Register value as an unsigned long, throwing away
 the most significant word on 32-bit environments.
 
+The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 2.06 or later (@option{-mcpu=power7}
+or @option{-mpopcntd}):
+@smallexample
+long __builtin_bpermd (long, long);
+int __builtin_divwe (int, int);
+int __builtin_divweo (int, int);
+unsigned int __builtin_divweu (unsigned int, unsigned int);
+unsigned int __builtin_divweuo (unsigned int, unsigned int);
+long __builtin_divde (long, long);
+long __builtin_divdeo (long, long);
+unsigned long __builtin_divdeu (unsigned long, unsigned long);
+unsigned long __builtin_divdeuo (unsigned long, unsigned long);
+unsigned int cdtbcd (unsigned int);
+unsigned int cbcdtd (unsigned int);
+unsigned int addg6s (unsigned int, unsigned int);
+@end smallexample
+
+The @code{__builtin_divde}, @code{__builtin_divdeo},
+@code{__builitin_divdeu}, @code{__builtin_divdeou} functions require a
+64-bit environment support ISA 2.06 or later.
+
+The following built-in functions are available for the PowerPC family
+of processors when hardware decimal floating point
+(@option{-mhard-dfp}) is available:
+@smallexample
+_Decimal64 __builtin_dxex (_Decimal64);
+_Decimal128 __builtin_dxexq (_Decimal128);
+_Decimal64 __builtin_ddedpd (int, _Decimal64);
+_Decimal128 __builtin_ddedpdq (int, _Decimal128);
+_Decimal64 __builtin_denbcd (int, _Decimal64);
+_Decimal128 __builtin_denbcdq (int, _Decimal128);
+_Decimal64 __builtin_diex (_Decimal64, _Decimal64);
+_Decimal128 _builtin_diexq (_Decimal128, _Decimal128);
+_Decimal64 __builtin_dscli (_Decimal64, int);
+_Decimal128 __builitn_dscliq (_Decimal128, int);
+_Decimal64 __builtin_dscri (_Decimal64, int);
+_Decimal128 __builitn_dscriq (_Decimal128, int);
+unsigned long long __builtin_unpack_dec128 (_Decimal128, int);
+_Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long long);
+@end smallexample
+
+The following built-in functions are available for the PowerPC family
+of processors when the Vector Scalar (vsx) instruction set is
+available:
+@smallexample
+unsigned long long __builtin_unpack_vector_int128 (vector __int128_t, int);
+vector __int128_t __builtin_pack_vector_int128 (unsigned long long,
+                                                unsigned long long);
+@end smallexample
+
 @node PowerPC AltiVec/VSX Built-in Functions
 @subsection PowerPC AltiVec Built-in Functions
 
@@ -15220,6 +15274,17 @@ vector __uint128_t vec_vsubcuq (vector __uint128_t, vector __uint128_t);
 
 __int128_t vec_vsubuqm (__int128_t, __int128_t);
 __uint128_t vec_vsubuqm (__uint128_t, __uint128_t);
+
+vector __int128_t __builtin_bcdadd (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_lt (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_eq (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_gt (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_ov (vector __int128_t, vector__int128_t);
+vector __int128_t bcdsub (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_lt (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_eq (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_gt (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_ov (vector __int128_t, vector__int128_t);
 @end smallexample
 
 If the cryptographic instructions are enabled (@option{-mcrypto} or
index cb863cb8ceb8c54b6815ec8b6966e071105503dd..9906c94146389419892f64727fb3fb16bb79abb0 100644 (file)
@@ -1,3 +1,20 @@
+2014-04-24  Michael Meissner  <meissner@linux.vnet.ibm.com>
+
+       * gcc.target/powerpc/pack01.c: New test to test the new pack and
+       unpack builtin functionss for 128-bit types.
+       * gcc.target/powerpc/pack02.c: Likewise.
+       * gcc.target/powerpc/pack03.c: Likewise.
+       * gcc.target/powerpc/extend-divide-1.c: New test to test extended
+       divide builtin functionss.
+       * gcc.target/powerpc/extend-divide-2.c: Likewise.
+       * gcc.target/powerpc/bcd-1.c: New test for the new BCD builtin
+       functions.
+       * gcc.target/powerpc/bcd-2.c: Likewise.
+       * gcc.target/powerpc/bcd-3.c: Likewise.
+       * gcc.target/powerpc/dfp-builtin-1.c: New test for the new DFP
+       builtin functionss.
+       * gcc.target/powerpc/dfp-builtin-2.c: Likewise.
+
 2014-04-24  Vishnu K S  <Vishnu.k_s@atmel.com>
 
        * gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c: Skip test if
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-1.c b/gcc/testsuite/gcc.target/powerpc/bcd-1.c
new file mode 100644 (file)
index 0000000..c7496c2
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "cdtbcd " 1 } } */
+/* { dg-final { scan-assembler-times "cbcdtd " 1 } } */
+/* { dg-final { scan-assembler-times "addg6s " 1 } } */
+/* { dg-final { scan-assembler-not    "bl __builtin" } } */
+
+unsigned int
+to_bcd (unsigned int a)
+{
+  return __builtin_cdtbcd (a);
+}
+
+unsigned int
+from_bcd (unsigned int a)
+{
+  return __builtin_cbcdtd (a);
+}
+
+unsigned int
+bcd_arith (unsigned int a, unsigned int b)
+{
+  return __builtin_addg6s (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-2.c b/gcc/testsuite/gcc.target/powerpc/bcd-2.c
new file mode 100644 (file)
index 0000000..d330b74
--- /dev/null
@@ -0,0 +1,44 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times "bcdadd\[.\] " 2 } } */
+/* { dg-final { scan-assembler-times "bcdsub\[.\] " 2 } } */
+/* { dg-final { scan-assembler-not   "bl __builtin"   } } */
+/* { dg-final { scan-assembler-not   "mtvsr"                 } } */
+/* { dg-final { scan-assembler-not   "mfvsr"                 } } */
+/* { dg-final { scan-assembler-not   "lvx"                   } } */
+/* { dg-final { scan-assembler-not   "lxvw4x"                } } */
+/* { dg-final { scan-assembler-not   "lxvd2x"                } } */
+/* { dg-final { scan-assembler-not   "stvx"                  } } */
+/* { dg-final { scan-assembler-not   "stxvw4x"               } } */
+/* { dg-final { scan-assembler-not   "stxvd2x"               } } */
+
+typedef __int128_t __attribute__((__vector_size__(16)))        vector_128_t;
+typedef __int128_t                                     scalar_128_t;
+typedef        unsigned long long                              scalar_64_t;
+
+vector_128_t
+do_add_0 (vector_128_t a, vector_128_t b)
+{
+  return __builtin_bcdadd (a, b, 0);
+}
+
+vector_128_t
+do_add_1 (vector_128_t a, vector_128_t b)
+{
+  return __builtin_bcdadd (a, b, 1);
+}
+
+vector_128_t
+do_sub_0 (vector_128_t a, vector_128_t b)
+{
+  return __builtin_bcdsub (a, b, 0);
+}
+
+vector_128_t
+do_sub_1 (vector_128_t a, vector_128_t b)
+{
+  return __builtin_bcdsub (a, b, 1);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-3.c b/gcc/testsuite/gcc.target/powerpc/bcd-3.c
new file mode 100644 (file)
index 0000000..436cecf
--- /dev/null
@@ -0,0 +1,103 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times "bcdadd\[.\] " 4 } } */
+/* { dg-final { scan-assembler-times "bcdsub\[.\] " 4 } } */
+/* { dg-final { scan-assembler-not   "bl __builtin"   } } */
+/* { dg-final { scan-assembler-not   "mtvsr"                 } } */
+/* { dg-final { scan-assembler-not   "mfvsr"                 } } */
+/* { dg-final { scan-assembler-not   "lvx"                   } } */
+/* { dg-final { scan-assembler-not   "lxvw4x"                } } */
+/* { dg-final { scan-assembler-not   "lxvd2x"                } } */
+/* { dg-final { scan-assembler-not   "stvx"                  } } */
+/* { dg-final { scan-assembler-not   "stxvw4x"               } } */
+/* { dg-final { scan-assembler-not   "stxvd2x"               } } */
+
+typedef __int128_t __attribute__((__vector_size__(16)))        vector_128_t;
+typedef __int128_t                                     scalar_128_t;
+typedef        unsigned long long                              scalar_64_t;
+
+/* Test whether the peephole works to allow folding a bcdadd, with a
+   bcdadd_<test> into a single instruction.  */
+
+vector_128_t
+do_add_lt (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdadd (a, b, 0);
+  if (__builtin_bcdadd_lt (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_add_eq (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdadd (a, b, 0);
+  if (__builtin_bcdadd_eq (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_add_gt (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdadd (a, b, 0);
+  if (__builtin_bcdadd_gt (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_add_ov (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdadd (a, b, 0);
+  if (__builtin_bcdadd_ov (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_sub_lt (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdsub (a, b, 0);
+  if (__builtin_bcdsub_lt (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_sub_eq (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdsub (a, b, 0);
+  if (__builtin_bcdsub_eq (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_sub_gt (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdsub (a, b, 0);
+  if (__builtin_bcdsub_gt (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
+
+vector_128_t
+do_sub_ov (vector_128_t a, vector_128_t b, int *p)
+{
+  vector_128_t ret = __builtin_bcdsub (a, b, 0);
+  if (__builtin_bcdsub_ov (a, b, 0))
+    *p = 1;
+
+  return ret;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
new file mode 100644 (file)
index 0000000..614f272
--- /dev/null
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "ddedpd " 4    } } */
+/* { dg-final { scan-assembler-times "denbcd " 2    } } */
+/* { dg-final { scan-assembler-times "dxex "   1    } } */
+/* { dg-final { scan-assembler-times "diex "   1    } } */
+/* { dg-final { scan-assembler-times "dscli "  2    } } */
+/* { dg-final { scan-assembler-times "dscri "  2    } } */
+/* { dg-final { scan-assembler-not   "bl __builtin" } } */
+/* { dg-final { scan-assembler-not   "dctqpq"       } } */
+/* { dg-final { scan-assembler-not   "drdpq"        } } */
+/* { dg-final { scan-assembler-not   "stfd"         } } */
+/* { dg-final { scan-assembler-not   "lfd"          } } */
+
+_Decimal64
+do_dedpd_0 (_Decimal64 a)
+{
+  return __builtin_ddedpd (0, a);
+}
+
+_Decimal64
+do_dedpd_1 (_Decimal64 a)
+{
+  return __builtin_ddedpd (1, a);
+}
+
+_Decimal64
+do_dedpd_2 (_Decimal64 a)
+{
+  return __builtin_ddedpd (2, a);
+}
+
+_Decimal64
+do_dedpd_3 (_Decimal64 a)
+{
+  return __builtin_ddedpd (3, a);
+}
+
+_Decimal64
+do_enbcd_0 (_Decimal64 a)
+{
+  return __builtin_denbcd (0, a);
+}
+
+_Decimal64
+do_enbcd_1 (_Decimal64 a)
+{
+  return __builtin_denbcd (1, a);
+}
+
+_Decimal64
+do_xex (_Decimal64 a)
+{
+  return __builtin_dxex (a);
+}
+
+_Decimal64
+do_iex (_Decimal64 a, _Decimal64 b)
+{
+  return __builtin_diex (a, b);
+}
+
+_Decimal64
+do_scli_1 (_Decimal64 a)
+{
+  return __builtin_dscli (a, 1);
+}
+
+_Decimal64
+do_scli_10 (_Decimal64 a)
+{
+  return __builtin_dscli (a, 10);
+}
+
+_Decimal64
+do_scri_1 (_Decimal64 a)
+{
+  return __builtin_dscri (a, 1);
+}
+
+_Decimal64
+do_scri_10 (_Decimal64 a)
+{
+  return __builtin_dscri (a, 10);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
new file mode 100644 (file)
index 0000000..189bc9a
--- /dev/null
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "ddedpdq " 4    } } */
+/* { dg-final { scan-assembler-times "denbcdq " 2    } } */
+/* { dg-final { scan-assembler-times "dxexq "   1    } } */
+/* { dg-final { scan-assembler-times "diexq "   1    } } */
+/* { dg-final { scan-assembler-times "dscliq "  2    } } */
+/* { dg-final { scan-assembler-times "dscriq "  2    } } */
+/* { dg-final { scan-assembler-not    "bl __builtin" } } */
+/* { dg-final { scan-assembler-not   "dctqpq"        } } */
+/* { dg-final { scan-assembler-not   "drdpq"         } } */
+/* { dg-final { scan-assembler-not   "stfd"          } } */
+/* { dg-final { scan-assembler-not   "lfd"           } } */
+
+_Decimal128
+do_dedpdq_0 (_Decimal128 a)
+{
+  return __builtin_ddedpdq (0, a);
+}
+
+_Decimal128
+do_dedpdq_1 (_Decimal128 a)
+{
+  return __builtin_ddedpdq (1, a);
+}
+
+_Decimal128
+do_dedpdq_2 (_Decimal128 a)
+{
+  return __builtin_ddedpdq (2, a);
+}
+
+_Decimal128
+do_dedpdq_3 (_Decimal128 a)
+{
+  return __builtin_ddedpdq (3, a);
+}
+
+_Decimal128
+do_enbcdq_0 (_Decimal128 a)
+{
+  return __builtin_denbcdq (0, a);
+}
+
+_Decimal128
+do_enbcdq_1 (_Decimal128 a)
+{
+  return __builtin_denbcdq (1, a);
+}
+
+_Decimal128
+do_xexq (_Decimal128 a)
+{
+  return __builtin_dxexq (a);
+}
+
+_Decimal128
+do_iexq (_Decimal128 a, _Decimal128 b)
+{
+  return __builtin_diexq (a, b);
+}
+
+_Decimal128
+do_scliq_1 (_Decimal128 a)
+{
+  return __builtin_dscliq (a, 1);
+}
+
+_Decimal128
+do_scliq_10 (_Decimal128 a)
+{
+  return __builtin_dscliq (a, 10);
+}
+
+_Decimal128
+do_scriq_1 (_Decimal128 a)
+{
+  return __builtin_dscriq (a, 1);
+}
+
+_Decimal128
+do_scriq_10 (_Decimal128 a)
+{
+  return __builtin_dscriq (a, 10);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c
new file mode 100644 (file)
index 0000000..5f948b7
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "divwe "   1 } } */
+/* { dg-final { scan-assembler-times "divweo "  1 } } */
+/* { dg-final { scan-assembler-times "divweu "  1 } } */
+/* { dg-final { scan-assembler-times "divweuo " 1 } } */
+/* { dg-final { scan-assembler-not    "bl __builtin" } } */
+
+int
+div_we (int a, int b)
+{
+  return __builtin_divwe (a, b);
+}
+
+int
+div_weo (int a, int b)
+{
+  return __builtin_divweo (a, b);
+}
+
+unsigned int
+div_weu (unsigned int a, unsigned int b)
+{
+  return __builtin_divweu (a, b);
+}
+
+unsigned int
+div_weuo (unsigned int a, unsigned int b)
+{
+  return __builtin_divweuo (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c
new file mode 100644 (file)
index 0000000..8ee6c8c
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "divde "   1 } } */
+/* { dg-final { scan-assembler-times "divdeo "  1 } } */
+/* { dg-final { scan-assembler-times "divdeu "  1 } } */
+/* { dg-final { scan-assembler-times "divdeuo " 1 } } */
+/* { dg-final { scan-assembler-not    "bl __builtin" } } */
+
+long
+div_de (long a, long b)
+{
+  return __builtin_divde (a, b);
+}
+
+long
+div_deo (long a, long b)
+{
+  return __builtin_divdeo (a, b);
+}
+
+unsigned long
+div_deu (unsigned long a, unsigned long b)
+{
+  return __builtin_divdeu (a, b);
+}
+
+unsigned long
+div_deuo (unsigned long a, unsigned long b)
+{
+  return __builtin_divdeuo (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack01.c b/gcc/testsuite/gcc.target/powerpc/pack01.c
new file mode 100644 (file)
index 0000000..efac408
--- /dev/null
@@ -0,0 +1,91 @@
+/* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target p8vector_hw } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <altivec.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+typedef __int128_t __attribute__((__vector_size__(16)))        vector_128_t;
+typedef __int128_t                                     scalar_128_t;
+typedef        unsigned long long                              scalar_64_t;
+
+volatile scalar_64_t one = 1;
+volatile scalar_64_t two = 2;
+
+int
+main (void)
+{
+  scalar_128_t a = (((scalar_128_t)one) << 64) | ((scalar_128_t)two);
+  vector_128_t v1 = (vector_128_t) { a };
+  vector_128_t v2 = __builtin_pack_vector_int128 (one, two);
+  scalar_64_t x0 = __builtin_unpack_vector_int128 (v1, 0);
+  scalar_64_t x1 = __builtin_unpack_vector_int128 (v1, 1);
+  vector_128_t v3 = __builtin_pack_vector_int128 (x0, x1);
+
+  size_t i;
+  union {
+    scalar_128_t i128;
+    vector_128_t v128;
+    scalar_64_t u64;
+    unsigned char uc[sizeof (scalar_128_t)];
+    char c[sizeof (scalar_128_t)];
+  } u, u2;
+
+#ifdef DEBUG
+  {
+    printf ("a  = 0x");
+    u.i128 = a;
+    for (i = 0; i < sizeof (scalar_128_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nv1 = 0x");
+    u.v128 = v1;
+    for (i = 0; i < sizeof (scalar_128_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nv2 = 0x");
+    u.v128 = v2;
+    for (i = 0; i < sizeof (scalar_128_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nv3 = 0x");
+    u.v128 = v3;
+    for (i = 0; i < sizeof (scalar_128_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nx0 = 0x");
+    u.u64 = x0;
+    for (i = 0; i < sizeof (scalar_64_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nx1 = 0x");
+    u.u64 = x1;
+    for (i = 0; i < sizeof (scalar_64_t); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\n");
+  }
+#endif
+
+  u2.i128 = a;
+  u.v128 = v1;
+  if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+    abort ();
+
+  u.v128 = v2;
+  if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+    abort ();
+
+  u.v128 = v3;
+  if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack02.c b/gcc/testsuite/gcc.target/powerpc/pack02.c
new file mode 100644 (file)
index 0000000..74b6cd0
--- /dev/null
@@ -0,0 +1,95 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int
+main (void)
+{
+  double high = pow (2.0, 60);
+  double low  = 2.0;
+  long double a = ((long double)high) + ((long double)low);
+  double x0 = __builtin_unpack_longdouble (a, 0);
+  double x1 = __builtin_unpack_longdouble (a, 1);
+  long double b = __builtin_pack_longdouble (x0, x1);
+
+#ifdef DEBUG
+  {
+    size_t i;
+    union {
+      long double ld;
+      double d;
+      unsigned char uc[sizeof (long double)];
+      char c[sizeof (long double)];
+    } u;
+
+    printf ("a  = 0x");
+    u.ld = a;
+    for (i = 0; i < sizeof (long double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (", %Lg\n", a);
+
+    printf ("b  = 0x");
+    u.ld = b;
+    for (i = 0; i < sizeof (long double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (", %Lg\n", b);
+
+    printf ("hi = 0x");
+    u.d = high;
+    for (i = 0; i < sizeof (double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", high);
+
+    printf ("lo = 0x");
+    u.d = low;
+    for (i = 0; i < sizeof (double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", low);
+
+    printf ("x0 = 0x");
+    u.d = x0;
+    for (i = 0; i < sizeof (double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", x0);
+
+    printf ("x1 = 0x");
+    u.d = x1;
+    for (i = 0; i < sizeof (double); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", x1);
+  }
+#endif
+
+  if (high != x0)
+    abort ();
+
+  if (low != x1)
+    abort ();
+
+  if (a != b)
+    abort ();
+
+  if (x0 != high)
+    abort ();
+
+  if (x1 != low)
+    abort ();
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack03.c b/gcc/testsuite/gcc.target/powerpc/pack03.c
new file mode 100644 (file)
index 0000000..59f0e74
--- /dev/null
@@ -0,0 +1,88 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int
+main (void)
+{
+  _Decimal128 one      = (_Decimal128)1.0;
+  _Decimal128 two      = (_Decimal128)2.0;
+  _Decimal128 ten      = (_Decimal128)10.0;
+  _Decimal128 a                = one;
+  _Decimal128 b;
+  _Decimal128 c;
+  unsigned long long x0;
+  unsigned long long x1;
+  size_t i;
+
+  for (i = 0; i < 25; i++)
+    a *= ten;
+
+  a += two;
+
+  x0 = __builtin_unpack_dec128 (a, 0);
+  x1 = __builtin_unpack_dec128 (a, 1);
+  b = __builtin_pack_dec128 (x0, x1);
+  c = __builtin_dscliq (one, 25) + two;
+
+#ifdef DEBUG
+  {
+    union {
+      _Decimal128 d;
+      unsigned long long ull;
+      unsigned char uc[sizeof (_Decimal128)];
+    } u;
+
+    printf ("a  = 0x");
+    u.d = a;
+    for (i = 0; i < sizeof (_Decimal128); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (", %Lg\n", (long double)a);
+
+    printf ("b  = 0x");
+    u.d = b;
+    for (i = 0; i < sizeof (_Decimal128); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (", %Lg\n", (long double)b);
+
+    printf ("c  = 0x");
+    u.d = c;
+    for (i = 0; i < sizeof (_Decimal128); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf (", %Lg\n", (long double)c);
+
+    printf ("x0 = 0x");
+    u.ull = x0;
+    for (i = 0; i < sizeof (unsigned long long); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\nx1 = 0x");
+    u.ull = x1;
+    for (i = 0; i < sizeof (unsigned long long); i++)
+      printf ("%.2x", u.uc[i]);
+
+    printf ("\n");
+  }
+#endif
+
+  if (a != b)
+    abort ();
+
+  if (a != c)
+    abort ();
+
+  return 0;
+}