Commit 44b668fc authored by meissner's avatar meissner

[gcc]

2014-04-30  Michael Meissner  <meissner@linux.vnet.ibm.com>

	Back port from mainline
	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-30  Michael Meissner  <meissner@linux.vnet.ibm.com>

	Back port from mainline
	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.



git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_9-branch@209954 138bc75d-0d04-0410-961f-82ee72b054a4
parent 2c1efc89
2014-04-30 Michael Meissner <meissner@linux.vnet.ibm.com>
Back port from mainline
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-29 Pat Haugen <pthaugen@us.ibm.com>
Backport from mainline
......
......@@ -143,6 +143,9 @@
UNSPEC_VSUBEUQM
UNSPEC_VSUBECUQ
UNSPEC_VBPERMQ
UNSPEC_BCDADD
UNSPEC_BCDSUB
UNSPEC_BCD_OVERFLOW
])
(define_c_enum "unspecv"
......@@ -3334,3 +3337,112 @@
"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)))])])
......@@ -322,3 +322,72 @@
"TARGET_DFP"
"dctfixq %0,%1"
[(set_attr "type" "fp")])
;; 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")])
......@@ -171,6 +171,11 @@
(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")
......
......@@ -570,6 +570,75 @@
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")
/* 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)
/* 1 argument crypto functions. */
BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox)
......
......@@ -3035,7 +3035,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
......@@ -12399,7 +12400,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);
......@@ -12410,6 +12419,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)
{
......@@ -13501,6 +13548,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);
......@@ -13780,6 +13835,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
......@@ -13794,6 +13852,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;
......@@ -14886,6 +14947,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;
......@@ -14904,6 +14967,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;
......@@ -14965,9 +15033,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;
}
......@@ -31221,6 +31298,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
......
......@@ -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];
......
......@@ -125,6 +125,15 @@
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
UNSPEC_LSQ
])
......@@ -482,6 +491,10 @@
(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")])
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
......@@ -2756,10 +2769,7 @@
(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
......@@ -2783,10 +2793,7 @@
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div<wd> %0,%1,%2"
[(set (attr "type")
(cond [(match_operand:SI 0 "" "")
(const_string "idiv")]