summaryrefslogtreecommitdiff
path: root/gcc/config
diff options
context:
space:
mode:
authorkelvin <kelvin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-17 00:18:32 +0000
committerkelvin <kelvin@138bc75d-0d04-0410-961f-82ee72b054a4>2016-12-17 00:18:32 +0000
commit9cd62877282864d0c98bb0d4eaedfc83c77df843 (patch)
treeea9851d8e7e5138b16ac4e64d27516b89184c168 /gcc/config
parent33230a5fcf5a2b4a91a3c12f20bae9fbb41bdc73 (diff)
downloadgcc-9cd62877282864d0c98bb0d4eaedfc83c77df843.tar.gz
gcc/testsuite/ChangeLog:
2016-12-16 Kelvin Nilsen <kelvin@gcc.gnu.org> * gcc.target/powerpc/byte-in-either-range-0.c: New test. * gcc.target/powerpc/byte-in-either-range-1.c: New test. * gcc.target/powerpc/byte-in-range-0.c: New test. * gcc.target/powerpc/byte-in-range-1.c: New test. * gcc.target/powerpc/byte-in-set-0.c: New test. * gcc.target/powerpc/byte-in-set-1.c: New test. * gcc.target/powerpc/byte-in-set-2.c: New test. gcc/ChangeLog: 2016-12-16 Kelvin Nilsen <kelvin@gcc.gnu.org> * config/rs6000/altivec.md (UNSPEC_CMPRB): New unspec value. (UNSPEC_CMPRB2): New unspec value. (UNSPEC_CMPEQB): New unspec value. (cmprb): New expansion. (*cmprb_internal): New insn. (*setb_internal): New insn. (cmprb2): New expansion. (*cmprb2_internal): New insn. (cmpeqb): New expansion. (*cmpeqb_internal): New insn. * config/rs6000/rs6000-builtin.def (BU_P9_2): New macro. (BU_P9_64BIT_2): Likewise. (BU_P9_OVERLOAD_2): Likewise. (CMPRB): Add byte-in-range built-in function. (CMBRB2): Add byte-in-either-range built-in function. (CMPEQB): Add byte-in-set built-in function. (CMPRB): Add overload support for byte-in-range function. (CMPRB2): Add overload support for byte-in-either-range function. (CMPEQB): Add overload support for byte-in-set built-in function. * config/rs6000/rs6000-c.c (P9_BUILTIN_CMPRB): Macro expansion to define argument types for new builtin. (P9_BUILTIN_CMPRB2): Likewise. (P9_BUILTIN_CMPEQB): Likewise. * doc/extend.texi (PowerPC AltiVec Built-in Functions): Rearrange the order of presentation for certain built-in functions (scalar_extract_exp, scalar_extract_sig, scalar_insert_exp) (scalar_cmp_exp_gt, scalar_cmp_exp_lt, scalar_cmp_exp_eq) (scalar_cmp_exp_unordered, scalar_test_data_class) (scalar_test_neg) to improve locality and flow. Document the new __builtin_scalar_byte_in_set, __builtin_scalar_byte_in_range, and __builtin_scalar_byte_in_either_range functions. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@243770 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config')
-rw-r--r--gcc/config/rs6000/altivec.md186
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def36
-rw-r--r--gcc/config/rs6000/rs6000-c.c7
3 files changed, 229 insertions, 0 deletions
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 802aa7459af..6c0a5953d7c 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -153,6 +153,9 @@
UNSPEC_BCDADD
UNSPEC_BCDSUB
UNSPEC_BCD_OVERFLOW
+ UNSPEC_CMPRB
+ UNSPEC_CMPRB2
+ UNSPEC_CMPEQB
])
(define_c_enum "unspecv"
@@ -3707,6 +3710,189 @@
"darn %0,1"
[(set_attr "type" "integer")])
+;; Test byte within range.
+;;
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the range specified by operand 2.
+;; The bytes of operand 2 are organized as xx:xx:hi:lo.
+;;
+;; Return in target register operand 0 a value of 1 if lo <= vv and
+;; vv <= hi. Otherwise, set register operand 0 to 0.
+;;
+;; Though the instructions to which this expansion maps operate on
+;; 64-bit registers, the current implementation only operates on
+;; SI-mode operands as the high-order bits provide no information
+;; that is not already available in the low-order bits. To avoid the
+;; costs of data widening operations, future enhancements might allow
+;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
+(define_expand "cmprb"
+ [(set (match_dup 3)
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPRB))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (if_then_else:SI (lt (match_dup 3)
+ (const_int 0))
+ (const_int -1)
+ (if_then_else (gt (match_dup 3)
+ (const_int 0))
+ (const_int 1)
+ (const_int 0))))]
+ "TARGET_P9_MISC"
+{
+ operands[3] = gen_reg_rtx (CCmode);
+})
+
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the range specified by operand 2.
+;; The bytes of operand 2 are organized as xx:xx:hi:lo.
+;;
+;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
+;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
+;; 3 bits of the target CR register are all set to 0.
+(define_insn "*cmprb_internal"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPRB))]
+ "TARGET_P9_MISC"
+ "cmprb %0,0,%1,%2"
+ [(set_attr "type" "logical")])
+
+;; Set operand 0 register to -1 if the LT bit (0x8) of condition
+;; register operand 1 is on. Otherwise, set operand 0 register to 1
+;; if the GT bit (0x4) of condition register operand 1 is on.
+;; Otherwise, set operand 0 to 0. Note that the result stored into
+;; register operand 0 is non-zero iff either the LT or GT bits are on
+;; within condition register operand 1.
+(define_insn "*setb_internal"
+ [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
+ (const_int 0))
+ (const_int -1)
+ (if_then_else (gt (match_dup 1)
+ (const_int 0))
+ (const_int 1)
+ (const_int 0))))]
+ "TARGET_P9_MISC"
+ "setb %0,%1"
+ [(set_attr "type" "logical")])
+
+;; Test byte within two ranges.
+;;
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the range specified by operand 2.
+;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
+;;
+;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
+;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
+;; operand 0 to 0.
+;;
+;; Though the instructions to which this expansion maps operate on
+;; 64-bit registers, the current implementation only operates on
+;; SI-mode operands as the high-order bits provide no information
+;; that is not already available in the low-order bits. To avoid the
+;; costs of data widening operations, future enhancements might allow
+;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
+(define_expand "cmprb2"
+ [(set (match_dup 3)
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPRB2))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (if_then_else:SI (lt (match_dup 3)
+ (const_int 0))
+ (const_int -1)
+ (if_then_else (gt (match_dup 3)
+ (const_int 0))
+ (const_int 1)
+ (const_int 0))))]
+ "TARGET_P9_MISC"
+{
+ operands[3] = gen_reg_rtx (CCmode);
+})
+
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the ranges specified by operand 2.
+;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
+;;
+;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
+;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
+;; Otherwise, set the GT bit to 0. The other 3 bits of the target
+;; CR register are all set to 0.
+(define_insn "*cmprb2_internal"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:SI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPRB2))]
+ "TARGET_P9_MISC"
+ "cmprb %0,1,%1,%2"
+ [(set_attr "type" "logical")])
+
+;; Test byte membership within set of 8 bytes.
+;;
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the set specified by operand 2.
+;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
+;;
+;; Return in target register operand 0 a value of 1 if vv equals one
+;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
+;; register operand 0 to 0. Note that the 8 byte values held within
+;; operand 2 need not be unique.
+;;
+;; Though the instructions to which this expansion maps operate on
+;; 64-bit registers, the current implementation requires that operands
+;; 0 and 1 have mode SI as the high-order bits provide no information
+;; that is not already available in the low-order bits. To avoid the
+;; costs of data widening operations, future enhancements might allow
+;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
+(define_expand "cmpeqb"
+ [(set (match_dup 3)
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:DI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPEQB))
+ (set (match_operand:SI 0 "gpc_reg_operand" "=r")
+ (if_then_else:SI (lt (match_dup 3)
+ (const_int 0))
+ (const_int -1)
+ (if_then_else (gt (match_dup 3)
+ (const_int 0))
+ (const_int 1)
+ (const_int 0))))]
+ "TARGET_P9_MISC && TARGET_64BIT"
+{
+ operands[3] = gen_reg_rtx (CCmode);
+})
+
+;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
+;; represents a byte whose value is ignored in this context and
+;; vv, the least significant byte, holds the byte value that is to
+;; be tested for membership within the set specified by operand 2.
+;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
+;;
+;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
+;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
+;; set the GT bit to zero. The other 3 bits of the target CR register
+;; are all set to 0.
+(define_insn "*cmpeqb_internal"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=y")
+ (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
+ (match_operand:DI 2 "gpc_reg_operand" "r")]
+ UNSPEC_CMPEQB))]
+ "TARGET_P9_MISC && TARGET_64BIT"
+ "cmpeqb %0,%1,%2"
+ [(set_attr "type" "logical")])
+
(define_expand "bcd<bcd_add_sub>_<code>"
[(parallel [(set (reg:CCFP CR6_REGNO)
(compare:CCFP
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 702c2d04d15..f29b226b9ab 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -898,6 +898,23 @@
| RS6000_BTC_PREDICATE), \
CODE_FOR_nothing) /* ICODE */
+#define BU_P9_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (P9_BUILTIN_SCALAR_ ## ENUM, /* ENUM */ \
+ "__builtin_scalar_" NAME, /* NAME */ \
+ RS6000_BTM_P9_VECTOR, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_P9_64BIT_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (P9_BUILTIN_SCALAR_ ## ENUM, /* ENUM */ \
+ "__builtin_scalar_" NAME, /* NAME */ \
+ RS6000_BTM_P9_VECTOR \
+ | RS6000_BTM_64BIT, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
#define BU_P9V_OVERLOAD_1(ENUM, NAME) \
RS6000_BUILTIN_1 (P9V_BUILTIN_VEC_ ## ENUM, /* ENUM */ \
"__builtin_vec_" NAME, /* NAME */ \
@@ -921,6 +938,15 @@
(RS6000_BTC_OVERLOADED /* ATTR */ \
| RS6000_BTC_TERNARY), \
CODE_FOR_nothing) /* ICODE */
+
+#define BU_P9_OVERLOAD_2(ENUM, NAME) \
+ RS6000_BUILTIN_2 (P9_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_P9_VECTOR, /* MASK */ \
+ (RS6000_BTC_OVERLOADED /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_nothing) /* ICODE */
+
#endif
@@ -2152,6 +2178,16 @@ BU_P9V_OVERLOAD_1 (VPRTYBD, "vprtybd")
BU_P9V_OVERLOAD_1 (VPRTYBQ, "vprtybq")
BU_P9V_OVERLOAD_1 (VPRTYBW, "vprtybw")
+/* 2 argument functions added in ISA 3.0 (power9). */
+BU_P9_2 (CMPRB, "byte_in_range", CONST, cmprb)
+BU_P9_2 (CMPRB2, "byte_in_either_range", CONST, cmprb2)
+BU_P9_64BIT_2 (CMPEQB, "byte_in_set", CONST, cmpeqb)
+
+/* 2 argument overloaded functions added in ISA 3.0 (power9). */
+BU_P9_OVERLOAD_2 (CMPRB, "byte_in_range")
+BU_P9_OVERLOAD_2 (CMPRB2, "byte_in_either_range")
+BU_P9_OVERLOAD_2 (CMPEQB, "byte_in_set")
+
/* 1 argument IEEE 128-bit floating-point functions. */
BU_FLOAT128_1 (FABSQ, "fabsq", CONST, abskf2)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index 6ec9d59a291..57cac7bdc05 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -4926,6 +4926,13 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
{ P9V_BUILTIN_VEC_VPRTYBQ, P9V_BUILTIN_VPRTYBQ,
RS6000_BTI_UINTTI, RS6000_BTI_UINTTI, 0, 0 },
+ { P9_BUILTIN_CMPRB, P9_BUILTIN_SCALAR_CMPRB,
+ RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, 0 },
+ { P9_BUILTIN_CMPRB2, P9_BUILTIN_SCALAR_CMPRB2,
+ RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTSI, 0 },
+ { P9_BUILTIN_CMPEQB, P9_BUILTIN_SCALAR_CMPEQB,
+ RS6000_BTI_INTSI, RS6000_BTI_UINTQI, RS6000_BTI_UINTDI, 0 },
+
{ P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM,
RS6000_BTI_V4SI, RS6000_BTI_V2DI, RS6000_BTI_V2DI, 0 },
{ P8V_BUILTIN_VEC_VPKUDUM, P8V_BUILTIN_VPKUDUM,