rs6000: Add xxeval and vec_ternarylogic

Add the xxeval insn and access it via the vec_ternarylogic built-in
function.  As part of this, add support to the built-in function
infrastructure for functions that take four arguments.

[gcc]

2020-05-11  Kelvin Nilsen  <wschmidt@linux.ibm.com>

	* config/rs6000/altivec.h (vec_ternarylogic): New #define.
	* config/rs6000/altivec.md (UNSPEC_XXEVAL): New constant.
	(xxeval): New insn.
	* config/rs6000/predicates.md (u8bit_cint_operand): New predicate.
	* config/rs6000/rs6000-builtin.def: Add handling of new macro
	RS6000_BUILTIN_4.
	(BU_FUTURE_V_4): New macro. Use it.
	(BU_FUTURE_OVERLOAD_4): Likewise.
	* config/rs6000/rs6000-c.c (altivec_build_resolved_builtin): Add
	handling for quaternary built-in functions.
	(altivec_resolve_overloaded_builtin): Add special-case handling
	for __builtin_vec_xxeval.
	* config/rs6000/rs6000-call.c: Add handling of new macro
	RS6000_BUILTIN_4 in initialization of rs6000_builtin_info,
	bdesc0_arg, bdesc1_arg, bdesc2_arg, bdesc_3arg,
	bdesc_altivec_preds, bdesc_abs, and bdesc_htm arrays.
	(altivec_overloaded_builtins): Add definitions for
	FUTURE_BUILTIN_VEC_XXEVAL.
	(bdesc_4arg): New array.
	(htm_expand_builtin): Add handling for quaternary built-in
	functions.
	(rs6000_expand_quaternop_builtin): New function.
	(rs6000_expand_builtin): Add handling for quaternary built-in
	functions.
	(rs6000_init_builtins): Initialize builtin_mode_to_type entries
	for unsigned QImode and unsigned HImode.
	(builtin_quaternary_function_type): New function.
	(rs6000_common_init_builtins): Add handling of quaternary
	operations.
	* config/rs6000/rs6000.h (RS6000_BTC_QUATERNARY): New defined
	constant.
	(RS6000_BTC_PREDICATE): Change value of constant.
	(RS6000_BTC_ABS): Likewise.
	(rs6000_builtins): Add support for new macro RS6000_BUILTIN_4.
	* doc/extend.texi (PowerPC AltiVec Built-In Functions Available
	for a Future Architecture): Add description of vec_ternarylogic
	built-in function.

[gcc/testsuite]

2020-05-11  Kelvin Nilsen  <wschmidt@linux.ibm.com>

	* gcc.target/powerpc/vec-ternarylogic-0.c: New.
	* gcc.target/powerpc/vec-ternarylogic-1.c: New.
	* gcc.target/powerpc/vec-ternarylogic-10.c: New.
	* gcc.target/powerpc/vec-ternarylogic-2.c: New.
	* gcc.target/powerpc/vec-ternarylogic-3.c: New.
	* gcc.target/powerpc/vec-ternarylogic-4.c: New.
	* gcc.target/powerpc/vec-ternarylogic-5.c: New.
	* gcc.target/powerpc/vec-ternarylogic-6.c: New.
	* gcc.target/powerpc/vec-ternarylogic-7.c: New.
	* gcc.target/powerpc/vec-ternarylogic-8.c: New.
	* gcc.target/powerpc/vec-ternarylogic-9.c: New.
This commit is contained in:
Kelvin Nilsen 2020-05-11 16:25:03 -05:00 committed by Bill Schmidt
parent 2202299c2a
commit 840ac85ced
21 changed files with 1671 additions and 6 deletions

View File

@ -1,3 +1,43 @@
2020-05-11 Kelvin Nilsen <wschmidt@linux.ibm.com>
* config/rs6000/altivec.h (vec_ternarylogic): New #define.
* config/rs6000/altivec.md (UNSPEC_XXEVAL): New constant.
(xxeval): New insn.
* config/rs6000/predicates.md (u8bit_cint_operand): New predicate.
* config/rs6000/rs6000-builtin.def: Add handling of new macro
RS6000_BUILTIN_4.
(BU_FUTURE_V_4): New macro. Use it.
(BU_FUTURE_OVERLOAD_4): Likewise.
* config/rs6000/rs6000-c.c (altivec_build_resolved_builtin): Add
handling for quaternary built-in functions.
(altivec_resolve_overloaded_builtin): Add special-case handling
for __builtin_vec_xxeval.
* config/rs6000/rs6000-call.c: Add handling of new macro
RS6000_BUILTIN_4 in initialization of rs6000_builtin_info,
bdesc0_arg, bdesc1_arg, bdesc2_arg, bdesc_3arg,
bdesc_altivec_preds, bdesc_abs, and bdesc_htm arrays.
(altivec_overloaded_builtins): Add definitions for
FUTURE_BUILTIN_VEC_XXEVAL.
(bdesc_4arg): New array.
(htm_expand_builtin): Add handling for quaternary built-in
functions.
(rs6000_expand_quaternop_builtin): New function.
(rs6000_expand_builtin): Add handling for quaternary built-in
functions.
(rs6000_init_builtins): Initialize builtin_mode_to_type entries
for unsigned QImode and unsigned HImode.
(builtin_quaternary_function_type): New function.
(rs6000_common_init_builtins): Add handling of quaternary
operations.
* config/rs6000/rs6000.h (RS6000_BTC_QUATERNARY): New defined
constant.
(RS6000_BTC_PREDICATE): Change value of constant.
(RS6000_BTC_ABS): Likewise.
(rs6000_builtins): Add support for new macro RS6000_BUILTIN_4.
* doc/extend.texi (PowerPC AltiVec Built-In Functions Available
for a Future Architecture): Add description of vec_ternarylogic
built-in function.
2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
* config/rs6000/rs6000-builtin.def (__builtin_pdepd): New built-in

View File

@ -699,6 +699,7 @@ __altivec_scalar_pred(vec_any_nle,
#define vec_gnb(a, b) __builtin_vec_gnb (a, b)
#define vec_clrl(a, b) __builtin_vec_clrl (a, b)
#define vec_clrr(a, b) __builtin_vec_clrr (a, b)
#define vec_ternarylogic(a, b, c, d) __builtin_vec_xxeval (a, b, c, d)
#endif
#endif /* _ALTIVEC_H */

View File

@ -168,6 +168,7 @@
UNSPEC_VPEXTD
UNSPEC_VCLRLB
UNSPEC_VCLRRB
UNSPEC_XXEVAL
])
(define_c_enum "unspecv"
@ -3271,6 +3272,16 @@
[(set_attr "type" "vecperm")
(set_attr "isa" "*,p9v")])
(define_insn "xxeval"
[(set (match_operand:V2DI 0 "register_operand" "=wa")
(unspec:V2DI [(match_operand:V2DI 1 "altivec_register_operand" "wa")
(match_operand:V2DI 2 "altivec_register_operand" "wa")
(match_operand:V2DI 3 "altivec_register_operand" "wa")
(match_operand:QI 4 "u8bit_cint_operand" "n")]
UNSPEC_XXEVAL))]
"TARGET_FUTURE"
"xxeval %0,%1,%2,%3,%4"
[(set_attr "type" "vecsimple")])
(define_expand "vec_unpacku_hi_v16qi"
[(set (match_operand:V8HI 0 "register_operand" "=v")

View File

@ -234,6 +234,11 @@
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 127)")))
;; Return 1 if op is a unsigned 8-bit constant integer.
(define_predicate "u8bit_cint_operand"
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 255)")))
;; Return 1 if op is a signed 8-bit constant integer.
;; Integer multiplication complete more quickly
(define_predicate "s8bit_cint_operand"

View File

@ -28,6 +28,7 @@
RS6000_BUILTIN_1 -- 1 arg builtins
RS6000_BUILTIN_2 -- 2 arg builtins
RS6000_BUILTIN_3 -- 3 arg builtins
RS6000_BUILTIN_4 -- 4 arg builtins
RS6000_BUILTIN_A -- ABS builtins
RS6000_BUILTIN_D -- DST builtins
RS6000_BUILTIN_H -- HTM builtins
@ -57,6 +58,10 @@
#error "RS6000_BUILTIN_3 is not defined."
#endif
#ifndef RS6000_BUILTIN_4
#error "RS6000_BUILTIN_4 is not defined."
#endif
#ifndef RS6000_BUILTIN_A
#error "RS6000_BUILTIN_A is not defined."
#endif
@ -969,6 +974,14 @@
| RS6000_BTC_TERNARY), \
CODE_FOR_ ## ICODE) /* ICODE */
#define BU_FUTURE_V_4(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_4 (FUTURE_BUILTIN_ ## ENUM, /* ENUM */ \
"__builtin_altivec_" NAME, /* NAME */ \
RS6000_BTM_FUTURE, /* MASK */ \
(RS6000_BTC_ ## ATTR /* ATTR */ \
| RS6000_BTC_QUATERNARY), \
CODE_FOR_ ## ICODE) /* ICODE */
#define BU_FUTURE_OVERLOAD_1(ENUM, NAME) \
RS6000_BUILTIN_1 (FUTURE_BUILTIN_VEC_ ## ENUM, /* ENUM */ \
"__builtin_vec_" NAME, /* NAME */ \
@ -993,6 +1006,14 @@
| RS6000_BTC_TERNARY), \
CODE_FOR_nothing) /* ICODE */
#define BU_FUTURE_OVERLOAD_4(ENUM, NAME) \
RS6000_BUILTIN_4 (FUTURE_BUILTIN_VEC_ ## ENUM, /* ENUM */ \
"__builtin_vec_" NAME, /* NAME */ \
RS6000_BTM_FUTURE, /* MASK */ \
(RS6000_BTC_OVERLOADED /* ATTR */ \
| RS6000_BTC_QUATERNARY), \
CODE_FOR_nothing) /* ICODE */
/* Miscellaneous (non-vector) builtins for instructions which may be
added at some point in the future. */
@ -2589,11 +2610,13 @@ BU_FUTURE_V_2 (VCTZDM, "vctzdm", CONST, vctzdm)
BU_FUTURE_V_2 (VPDEPD, "vpdepd", CONST, vpdepd)
BU_FUTURE_V_2 (VPEXTD, "vpextd", CONST, vpextd)
BU_FUTURE_V_2 (VGNB, "vgnb", CONST, vgnb)
BU_FUTURE_V_4 (XXEVAL, "xxeval", CONST, xxeval)
/* Future architecture overloaded vector built-ins. */
BU_FUTURE_OVERLOAD_2 (CLRL, "clrl")
BU_FUTURE_OVERLOAD_2 (CLRR, "clrr")
BU_FUTURE_OVERLOAD_2 (GNB, "gnb")
BU_FUTURE_OVERLOAD_4 (XXEVAL, "xxeval")
/* 1 argument crypto functions. */

View File

@ -846,7 +846,7 @@ altivec_build_resolved_builtin (tree *args, int n,
tree impl_fndecl = rs6000_builtin_decls[desc->overloaded_code];
tree ret_type = rs6000_builtin_type (desc->ret_type);
tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (impl_fndecl));
tree arg_type[3];
tree arg_type[4];
tree call;
int i;
@ -895,6 +895,13 @@ altivec_build_resolved_builtin (tree *args, int n,
fully_fold_convert (arg_type[1], args[1]),
fully_fold_convert (arg_type[2], args[2]));
break;
case 4:
call = build_call_expr (impl_fndecl, 4,
fully_fold_convert (arg_type[0], args[0]),
fully_fold_convert (arg_type[1], args[1]),
fully_fold_convert (arg_type[2], args[2]),
fully_fold_convert (arg_type[3], args[3]));
break;
default:
gcc_unreachable ();
}
@ -913,7 +920,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
enum rs6000_builtins fcode
= (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl);
tree fnargs = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
tree types[3], args[3];
tree types[4], args[4];
const struct altivec_builtin_types *desc;
unsigned int n;
@ -1606,7 +1613,7 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
if (arg == error_mark_node)
return error_mark_node;
if (n >= 3)
if (n >= 4)
abort ();
arg = default_conversion (arg);
@ -1789,6 +1796,40 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl,
unsupported_builtin = true;
}
}
else if (fcode == FUTURE_BUILTIN_VEC_XXEVAL)
{
/* Need to special case __builtin_vec_xxeval because this takes
4 arguments, and the existing infrastructure handles no
more than three. */
if (nargs != 4)
{
error ("builtin %qs requires 4 arguments",
"__builtin_vec_xxeval");
return error_mark_node;
}
for ( ; desc->code == fcode; desc++)
{
if (rs6000_builtin_type_compatible (types[0], desc->op1)
&& rs6000_builtin_type_compatible (types[1], desc->op2)
&& rs6000_builtin_type_compatible (types[2], desc->op3)
&& rs6000_builtin_type_compatible (types[3],
RS6000_BTI_UINTQI))
{
if (rs6000_builtin_decls[desc->overloaded_code] == NULL_TREE)
unsupported_builtin = true;
else
{
result = altivec_build_resolved_builtin (args, n, desc);
if (rs6000_builtin_is_supported_p (desc->overloaded_code))
return result;
/* Allow loop to continue in case a different
definition is supported. */
overloaded_code = desc->overloaded_code;
unsupported_builtin = true;
}
}
}
}
else
{
/* For arguments after the last, we have RS6000_BTI_NOT_OPAQUE in

View File

@ -237,6 +237,7 @@ builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -255,6 +256,9 @@ builtin_hasher::equal (builtin_hash_struct *p1, builtin_hash_struct *p2)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
@ -286,6 +290,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -5527,6 +5532,25 @@ const struct altivec_builtin_types altivec_overloaded_builtins[] = {
RS6000_BTI_unsigned_V2DI, RS6000_BTI_UINTQI, 0 },
{ FUTURE_BUILTIN_VEC_GNB, FUTURE_BUILTIN_VGNB, RS6000_BTI_unsigned_long_long,
RS6000_BTI_unsigned_V1TI, RS6000_BTI_UINTQI, 0 },
/* The overloaded XXEVAL definitions are handled specially because the
fourth unsigned char operand is not encoded in this table. */
{ FUTURE_BUILTIN_VEC_XXEVAL, FUTURE_BUILTIN_XXEVAL,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI,
RS6000_BTI_unsigned_V16QI, RS6000_BTI_unsigned_V16QI },
{ FUTURE_BUILTIN_VEC_XXEVAL, FUTURE_BUILTIN_XXEVAL,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI,
RS6000_BTI_unsigned_V8HI, RS6000_BTI_unsigned_V8HI },
{ FUTURE_BUILTIN_VEC_XXEVAL, FUTURE_BUILTIN_XXEVAL,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI,
RS6000_BTI_unsigned_V4SI, RS6000_BTI_unsigned_V4SI },
{ FUTURE_BUILTIN_VEC_XXEVAL, FUTURE_BUILTIN_XXEVAL,
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI,
RS6000_BTI_unsigned_V2DI, RS6000_BTI_unsigned_V2DI },
{ FUTURE_BUILTIN_VEC_XXEVAL, FUTURE_BUILTIN_XXEVAL,
RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI,
RS6000_BTI_unsigned_V1TI, RS6000_BTI_unsigned_V1TI },
{ RS6000_BUILTIN_NONE, RS6000_BUILTIN_NONE, 0, 0, 0, 0 }
};
@ -8275,6 +8299,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8287,6 +8312,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
@ -8298,12 +8324,13 @@ static const struct builtin_description bdesc_3arg[] =
#include "rs6000-builtin.def"
};
/* DST operations: void foo (void *, const int, const char). */
/* Simple quaternary operations: VECd = foo (VECa, VECb, VECc, VECd). */
#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8314,6 +8341,38 @@ static const struct builtin_description bdesc_3arg[] =
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
static const struct builtin_description bdesc_4arg[] =
{
#include "rs6000-builtin.def"
};
/* DST operations: void foo (void *, const int, const char). */
#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
#undef RS6000_BUILTIN_P
#undef RS6000_BUILTIN_X
#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@ -8333,6 +8392,7 @@ static const struct builtin_description bdesc_dst[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8345,6 +8405,7 @@ static const struct builtin_description bdesc_dst[] =
{ MASK, ICODE, NAME, ENUM },
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
@ -8360,6 +8421,7 @@ static const struct builtin_description bdesc_2arg[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8370,6 +8432,7 @@ static const struct builtin_description bdesc_2arg[] =
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
@ -8391,6 +8454,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8401,6 +8465,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@ -8421,6 +8486,7 @@ static const struct builtin_description bdesc_abs[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8433,6 +8499,7 @@ static const struct builtin_description bdesc_abs[] =
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
@ -8450,6 +8517,7 @@ static const struct builtin_description bdesc_1arg[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8462,6 +8530,7 @@ static const struct builtin_description bdesc_1arg[] =
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
@ -8478,6 +8547,7 @@ static const struct builtin_description bdesc_0arg[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -8488,6 +8558,7 @@ static const struct builtin_description bdesc_0arg[] =
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) \
@ -8505,6 +8576,7 @@ static const struct builtin_description bdesc_htm[] =
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -9404,6 +9476,8 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
expected_nopnds = 2;
else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_TERNARY)
expected_nopnds = 3;
else if ((attr & RS6000_BTC_TYPE_MASK) == RS6000_BTC_QUATERNARY)
expected_nopnds = 4;
if (!(attr & RS6000_BTC_VOID))
expected_nopnds += 1;
if (uses_spr)
@ -9580,6 +9654,76 @@ cpu_expand_builtin (enum rs6000_builtins fcode, tree exp ATTRIBUTE_UNUSED,
return target;
}
static rtx
rs6000_expand_quaternop_builtin (enum insn_code icode, tree exp, rtx target)
{
rtx pat;
tree arg0 = CALL_EXPR_ARG (exp, 0);
tree arg1 = CALL_EXPR_ARG (exp, 1);
tree arg2 = CALL_EXPR_ARG (exp, 2);
tree arg3 = CALL_EXPR_ARG (exp, 3);
rtx op0 = expand_normal (arg0);
rtx op1 = expand_normal (arg1);
rtx op2 = expand_normal (arg2);
rtx op3 = expand_normal (arg3);
machine_mode tmode = insn_data[icode].operand[0].mode;
machine_mode mode0 = insn_data[icode].operand[1].mode;
machine_mode mode1 = insn_data[icode].operand[2].mode;
machine_mode mode2 = insn_data[icode].operand[3].mode;
machine_mode mode3 = insn_data[icode].operand[4].mode;
if (icode == CODE_FOR_nothing)
/* Builtin not supported on this processor. */
return 0;
/* If we got invalid arguments bail out before generating bad rtl. */
if (arg0 == error_mark_node
|| arg1 == error_mark_node
|| arg2 == error_mark_node
|| arg3 == error_mark_node)
return const0_rtx;
/* Check and prepare argument depending on the instruction code.
Note that a switch statement instead of the sequence of tests
would be incorrect as many of the CODE_FOR values could be
CODE_FOR_nothing and that would yield multiple alternatives
with identical values. We'd never reach here at runtime in
this case. */
if (icode == CODE_FOR_xxeval)
{
/* Only allow 8-bit unsigned literals. */
STRIP_NOPS (arg3);
if (TREE_CODE (arg3) != INTEGER_CST
|| TREE_INT_CST_LOW (arg3) & ~0xff)
{
error ("argument 4 must be an 8-bit unsigned literal");
return CONST0_RTX (tmode);
}
}
if (target == 0
|| GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
if (! (*insn_data[icode].operand[1].predicate) (op0, mode0))
op0 = copy_to_mode_reg (mode0, op0);
if (! (*insn_data[icode].operand[2].predicate) (op1, mode1))
op1 = copy_to_mode_reg (mode1, op1);
if (! (*insn_data[icode].operand[3].predicate) (op2, mode2))
op2 = copy_to_mode_reg (mode2, op2);
if (! (*insn_data[icode].operand[4].predicate) (op3, mode3))
op3 = copy_to_mode_reg (mode3, op3);
pat = GEN_FCN (icode) (target, op0, op1, op2, op3);
if (! pat)
return 0;
emit_insn (pat);
return target;
}
static rtx
rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
{
@ -11613,6 +11757,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
case RS6000_BTC_UNARY: name3 = "unary"; break;
case RS6000_BTC_BINARY: name3 = "binary"; break;
case RS6000_BTC_TERNARY: name3 = "ternary"; break;
case RS6000_BTC_QUATERNARY:name3 = "quaternary";break;
case RS6000_BTC_PREDICATE: name3 = "predicate"; break;
case RS6000_BTC_ABS: name3 = "abs"; break;
case RS6000_BTC_DST: name3 = "dst"; break;
@ -11795,6 +11940,7 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
gcc_assert (attr == RS6000_BTC_UNARY
|| attr == RS6000_BTC_BINARY
|| attr == RS6000_BTC_TERNARY
|| attr == RS6000_BTC_QUATERNARY
|| attr == RS6000_BTC_SPECIAL);
/* Handle simple unary operations. */
@ -11815,6 +11961,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (d->code == fcode)
return rs6000_expand_ternop_builtin (icode, exp, target);
/* Handle simple quaternary operations. */
d = bdesc_4arg;
for (i = 0; i < ARRAY_SIZE (bdesc_4arg); i++, d++)
if (d->code == fcode)
return rs6000_expand_quaternop_builtin (icode, exp, target);
/* Handle simple no-argument operations. */
d = bdesc_0arg;
for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
@ -11969,7 +12121,9 @@ rs6000_init_builtins (void)
/* Initialize the modes for builtin_function_type, mapping a machine mode to
tree type node. */
builtin_mode_to_type[QImode][0] = integer_type_node;
builtin_mode_to_type[QImode][1] = unsigned_intSI_type_node;
builtin_mode_to_type[HImode][0] = integer_type_node;
builtin_mode_to_type[HImode][1] = unsigned_intSI_type_node;
builtin_mode_to_type[SImode][0] = intSI_type_node;
builtin_mode_to_type[SImode][1] = unsigned_intSI_type_node;
builtin_mode_to_type[DImode][0] = intDI_type_node;
@ -12850,6 +13004,46 @@ htm_init_builtins (void)
}
}
/* Map types for builtin functions with an explicit return type and
exactly 4 arguments. Functions with fewer than 3 arguments use
builtin_function_type. The number of quaternary built-in
functions is very small. Handle each case specially. */
static tree
builtin_quaternary_function_type (machine_mode mode_ret,
machine_mode mode_arg0,
machine_mode mode_arg1,
machine_mode mode_arg2,
machine_mode mode_arg3,
enum rs6000_builtins builtin)
{
tree function_type = NULL;
static tree v2udi_type = builtin_mode_to_type[V2DImode][1];
static tree uchar_type = builtin_mode_to_type[QImode][1];
static tree xxeval_type =
build_function_type_list (v2udi_type, v2udi_type, v2udi_type,
v2udi_type, uchar_type, NULL_TREE);
switch (builtin) {
case FUTURE_BUILTIN_XXEVAL:
gcc_assert ((mode_ret == V2DImode)
&& (mode_arg0 == V2DImode)
&& (mode_arg1 == V2DImode)
&& (mode_arg2 == V2DImode)
&& (mode_arg3 == QImode));
function_type = xxeval_type;
break;
default:
/* A case for each quaternary built-in must be provided above. */
gcc_unreachable ();
}
return function_type;
}
/* Map types for builtin functions with an explicit return type and up to 3
arguments. Functions with fewer than 3 arguments use VOIDmode as the type
of the argument. */
@ -13145,6 +13339,63 @@ rs6000_common_init_builtins (void)
if (TARGET_EXTRA_BUILTINS)
builtin_mask |= RS6000_BTM_COMMON;
/* Add the quaternary operators. */
d = bdesc_4arg;
for (i = 0; i < ARRAY_SIZE (bdesc_4arg); i++, d++)
{
tree type;
HOST_WIDE_INT mask = d->mask;
if ((mask & builtin_mask) != mask)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin, skip quaternary %s\n", d->name);
continue;
}
if (rs6000_overloaded_builtin_p (d->code))
{
type = opaque_ftype_opaque_opaque_opaque;
if (!type)
type = opaque_ftype_opaque_opaque_opaque
= build_function_type_list (opaque_V4SI_type_node,
opaque_V4SI_type_node,
opaque_V4SI_type_node,
opaque_V4SI_type_node,
opaque_V4SI_type_node,
NULL_TREE);
}
else
{
enum insn_code icode = d->icode;
if (d->name == 0)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr, "rs6000_builtin, bdesc_4arg[%ld] no name\n",
(long) i);
continue;
}
if (icode == CODE_FOR_nothing)
{
if (TARGET_DEBUG_BUILTIN)
fprintf (stderr,
"rs6000_builtin, skip quaternary %s (no code)\n",
d->name);
continue;
}
type =
builtin_quaternary_function_type (insn_data[icode].operand[0].mode,
insn_data[icode].operand[1].mode,
insn_data[icode].operand[2].mode,
insn_data[icode].operand[3].mode,
insn_data[icode].operand[4].mode,
d->code);
}
def_builtin (d->name, type, d->code);
}
/* Add the ternary operators. */
d = bdesc_3arg;
for (i = 0; i < ARRAY_SIZE (bdesc_3arg); i++, d++)

View File

@ -2254,9 +2254,14 @@ extern int frame_pointer_needed;
#define RS6000_BTC_UNARY 0x00000001 /* normal unary function. */
#define RS6000_BTC_BINARY 0x00000002 /* normal binary function. */
#define RS6000_BTC_TERNARY 0x00000003 /* normal ternary function. */
#define RS6000_BTC_PREDICATE 0x00000004 /* predicate function. */
#define RS6000_BTC_ABS 0x00000005 /* Altivec/VSX ABS function. */
#define RS6000_BTC_QUATERNARY 0x00000004 /* normal quaternary
function. */
#define RS6000_BTC_PREDICATE 0x00000005 /* predicate function. */
#define RS6000_BTC_ABS 0x00000006 /* Altivec/VSX ABS
function. */
#define RS6000_BTC_DST 0x00000007 /* Altivec DST function. */
#define RS6000_BTC_TYPE_MASK 0x0000000f /* Mask to isolate types */
#define RS6000_BTC_MISC 0x00000000 /* No special attributes. */
@ -2334,6 +2339,7 @@ extern int frame_pointer_needed;
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H
@ -2344,6 +2350,7 @@ extern int frame_pointer_needed;
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_4(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
@ -2361,6 +2368,7 @@ enum rs6000_builtins
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
#undef RS6000_BUILTIN_4
#undef RS6000_BUILTIN_A
#undef RS6000_BUILTIN_D
#undef RS6000_BUILTIN_H

View File

@ -22055,6 +22055,27 @@ else
@end smallexample
@end deftypefn
@smallexample
@exdent vector unsigned char
@exdent vec_ternarylogic (vector unsigned char, vector unsigned char,
vector unsigned char, const unsigned char)
@exdent vector unsigned short
@exdent vec_ternarylogic (vector unsigned short, vector unsigned short,
vector unsigned short, const unsigned char)
@exdent vector unsigned int
@exdent vec_ternarylogic (vector unsigned int, vector unsigned int,
vector unsigned int, const unsigned char)
@exdent vector unsigned long long int
@exdent vec_ternarylogic (vector unsigned long long int, vector unsigned long long int,
vector unsigned long long int, const unsigned char)
@exdent vector unsigned __int128
@exdent vec_ternarylogic (vector unsigned __int128, vector unsigned __int128,
vector unsigned __int128, const unsigned char)
@end smallexample
Perform a 128-bit vector evaluate operation, as if implemented by the
Future @code{xxeval} instruction. The fourth argument must be a literal
integer value between 0 and 255 inclusive.
@findex vec_ternarylogic
The following built-in functions are made available by @option{-mmmx}.
All of them generate the machine instruction that is part of the name.

View File

@ -1,3 +1,17 @@
2020-05-11 Kelvin Nilsen <wschmidt@linux.ibm.com>
* gcc.target/powerpc/vec-ternarylogic-0.c: New.
* gcc.target/powerpc/vec-ternarylogic-1.c: New.
* gcc.target/powerpc/vec-ternarylogic-10.c: New.
* gcc.target/powerpc/vec-ternarylogic-2.c: New.
* gcc.target/powerpc/vec-ternarylogic-3.c: New.
* gcc.target/powerpc/vec-ternarylogic-4.c: New.
* gcc.target/powerpc/vec-ternarylogic-5.c: New.
* gcc.target/powerpc/vec-ternarylogic-6.c: New.
* gcc.target/powerpc/vec-ternarylogic-7.c: New.
* gcc.target/powerpc/vec-ternarylogic-8.c: New.
* gcc.target/powerpc/vec-ternarylogic-9.c: New.
2020-05-11 Kelvin Nilsen <kelvin@gcc.gnu.org>
* gcc.target/powerpc/pdep-0.c: New.

View File

@ -0,0 +1,120 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned char intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void
doTests11100101 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned char intended =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 16; l++)
{
for (int m = 0; m < 8; m++)
{
unsigned char bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void
doTests11110011 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned char intended = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < 16; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, char *argv [])
{
vector unsigned char a_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
vector unsigned char b_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
vector unsigned char c_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,119 @@
/* { dg-do run} */
/* { dg-require-effective-target powerpc_future_hw } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned char intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void
doTests11100101 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned char intended =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 16; l++)
{
for (int m = 0; m < 8; m++)
{
unsigned char bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void
doTests11110011 (vector unsigned char a_sources [],
vector unsigned char b_sources [],
vector unsigned char c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned char a = a_sources [i];
vector unsigned char b = b_sources [j];
vector unsigned char c = c_sources [k];
vector unsigned char result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned char intended = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < 16; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, char *argv [])
{
vector unsigned char a_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
vector unsigned char b_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
vector unsigned char c_sources [NumSamples] = {
{ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 },
{ 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
{ 0xcc, 0xcc, 0xcc, 0xcc, 0x55, 0x55, 0x55, 0x55,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}

View File

@ -0,0 +1,129 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
/* vec_all_eq not yet supported for arguments of type
vector unsigned __int128. */
int
vector_equal (vector unsigned __int128 a, vector unsigned __int128 b)
{
return a[0] == b[0];
}
void
doTests00000001 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result;
result = vec_ternarylogic (a, b, c, 0xfff); /* { dg-error "8-bit unsigned literal" } */
vector unsigned __int128 intended = (a & b & c);
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11100101 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result;
result = vec_ternarylogic (a, b, c, -1); /* { dg-error "8-bit unsigned literal" } */
vector unsigned __int128 intended = { 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 1; l++)
{
for (int m = 0; m < 128; m++)
{
unsigned __int128 bit_selector = 0x01;
bit_selector = bit_selector << m;
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11110011 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result;
result = vec_ternarylogic (a, b, c, i); /* { dg-error "8-bit unsigned literal" } */
vector unsigned __int128 intended = { 0 };
for (int i = 0; i < 1; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vector_equal (result, intended))
abort ();
}
}
int main (int argc, int *argv [])
{
vector unsigned __int128 a_sources [NumSamples];
vector unsigned __int128 b_sources [NumSamples];
vector unsigned __int128 c_sources [NumSamples];
a_sources [0][0] = 0x0123456789abcdefull;
a_sources [0][0] = a_sources [0][0] << 64 | 0x123456789abcdef0ull;
a_sources [1][0] = 0x5555555555555555ull;
a_sources [1][0] = a_sources [1][0] << 64 | 0xffffffffffffffffull;
a_sources [2][0] = 0xcccccccc55555555ull;
a_sources [2][0] = a_sources [2][0] << 64 | 0x0000000000000000ull;
a_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
a_sources [3][0] = a_sources [3][0] << 64 | 0x6969696969696969ull;
b_sources [0][0] = 0x0123456789abcdefull;
b_sources [0][0] = b_sources [0][0] << 64 | 0x123456789abcdef0ull;
b_sources [1][0] = 0x5555555555555555ull;
b_sources [1][0] = b_sources [1][0] << 64 | 0xffffffffffffffffull;
b_sources [2][0] = 0xcccccccc55555555ull;
b_sources [2][0] = b_sources [2][0] << 64 | 0x0000000000000000ull;
b_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
b_sources [3][0] = b_sources [3][0] << 64 | 0x6969696969696969ull;
c_sources [0][0] = 0x0123456789abcdefull;
c_sources [0][0] = c_sources [0][0] << 64 | 0x123456789abcdef0ull;
c_sources [1][0] = 0x5555555555555555ull;
c_sources [1][0] = c_sources [1][0] << 64 | 0xffffffffffffffffull;
c_sources [2][0] = 0xcccccccc55555555ull;
c_sources [2][0] = c_sources [2][0] << 64 | 0x0000000000000000ull;
c_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
c_sources [3][0] = c_sources [3][0] << 64 | 0x6969696969696969ull;
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}

View File

@ -0,0 +1,105 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned short intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned short intended =
{ 0, 0, 0, 0, 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 8; l++)
{
for (int m = 0; m < 16; m++)
{
unsigned short int bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned short intended = { 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < 8; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, short *argv [])
{
vector unsigned short int a_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
vector unsigned short int b_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
vector unsigned short int c_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,106 @@
/* { dg-do run } */
/* { dg-require-effective-target powerpc_future_hw } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned short intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned short intended =
{ 0, 0, 0, 0, 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 8; l++)
{
for (int m = 0; m < 16; m++)
{
unsigned short int bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned short int a_sources [],
vector unsigned short int b_sources [],
vector unsigned short int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned short a = a_sources [i];
vector unsigned short b = b_sources [j];
vector unsigned short c = c_sources [k];
vector unsigned short result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned short intended = { 0, 0, 0, 0, 0, 0, 0, 0 };
for (int i = 0; i < 8; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, short *argv [])
{
vector unsigned short int a_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
vector unsigned short int b_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
vector unsigned short int c_sources [NumSamples] = {
{ 0x0123, 0x4567, 0x89ab, 0xcdef, 0x1234, 0x5678, 0x9abc, 0xdef0 },
{ 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0xcccc, 0xcccc, 0x5555, 0x5555, 0x0000, 0x0000, 0x0000, 0x0000 },
{ 0xe7e7, 0xe7e7, 0xe7e7, 0xe7e7, 0x6969, 0x6969, 0x6969, 0x6969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,104 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned int intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned int intended = { 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 4; l++)
{
for (int m = 0; m < 32; m++)
{
unsigned int bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned int intended = { 0, 0, 0, 0 };
for (int i = 0; i < 4; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, int *argv [])
{
vector unsigned int a_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
vector unsigned int b_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
vector unsigned int c_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,103 @@
/* { dg-do run } */
/* { dg-require-effective-target powerpc_future_hw } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned int intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned int intended = { 0, 0, 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 4; l++)
{
for (int m = 0; m < 32; m++)
{
unsigned int bit_selector = (0x01 << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned int a_sources [],
vector unsigned int b_sources [],
vector unsigned int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned int a = a_sources [i];
vector unsigned int b = b_sources [j];
vector unsigned int c = c_sources [k];
vector unsigned int result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned int intended = { 0, 0, 0, 0 };
for (int i = 0; i < 4; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, int *argv [])
{
vector unsigned int a_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
vector unsigned int b_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
vector unsigned int c_sources [NumSamples] = {
{ 0x01234567, 0x89abcdef, 0x12345678, 0x9abcdef0 },
{ 0x55555555, 0x55555555, 0xffffffff, 0xffffffff },
{ 0xcccccccc, 0x55555555, 0x00000000, 0x00000000 },
{ 0xe7e7e7e7, 0xe7e7e7e7, 0x69696969, 0x69696969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}

View File

@ -0,0 +1,104 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned long long intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned long long intended = { 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 2; l++)
{
for (int m = 0; m < 64; m++)
{
unsigned long long int bit_selector = (0x01ll << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= (0x01ll << m);
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned long long intended = { 0, 0 };
intended [0] = b [0] | ~(a [0] & c [0]);
intended [1] = b [1] | ~(a [1] & c [1]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, char *argv [])
{
vector unsigned long long int a_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
vector unsigned long long int b_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
vector unsigned long long int c_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,103 @@
/* { dg-do run } */
/* { dg-require-effective-target powerpc_future_hw } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
void
doTests00000001 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned long long intended = (a & b & c);
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11100101 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned long long intended = { 0, 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 2; l++)
{
for (int m = 0; m < 64; m++)
{
unsigned long long int bit_selector = (0x01ll << m);
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= (0x01ll << m);
}
}
if (!vec_all_eq (result, intended))
abort ();
}
}
void doTests11110011 (vector unsigned long long int a_sources [],
vector unsigned long long int b_sources [],
vector unsigned long long int c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned long long a = a_sources [i];
vector unsigned long long b = b_sources [j];
vector unsigned long long c = c_sources [k];
vector unsigned long long result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned long long intended = { 0, 0 };
intended [0] = b [0] | ~(a [0] & c [0]);
intended [1] = b [1] | ~(a [1] & c [1]);
if (!vec_all_eq (result, intended))
abort ();
}
}
int main (int argc, char *argv [])
{
vector unsigned long long int a_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
vector unsigned long long int b_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
vector unsigned long long int c_sources [NumSamples] = {
{ 0x0123456789abcdef, 0x123456789abcdef0 },
{ 0x5555555555555555, 0xffffffffffffffff },
{ 0xcccccccc55555555, 0x0000000000000000 },
{ 0xe7e7e7e7e7e7e7e7, 0x6969696969696969 },
};
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}

View File

@ -0,0 +1,128 @@
/* { dg-do compile } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
/* vec_all_eq not yet supported for arguments of type
vector unsigned __int128. */
int
vector_equal (vector unsigned __int128 a, vector unsigned __int128 b)
{
return a[0] == b[0];
}
void
doTests00000001 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned __int128 intended = (a & b & c);
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11100101 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned __int128 intended = { 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 1; l++)
{
for (int m = 0; m < 128; m++)
{
unsigned __int128 bit_selector = 0x01;
bit_selector = bit_selector << m;
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11110011 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned __int128 intended = { 0 };
for (int i = 0; i < 1; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vector_equal (result, intended))
abort ();
}
}
int main (int argc, int *argv [])
{
vector unsigned __int128 a_sources [NumSamples];
vector unsigned __int128 b_sources [NumSamples];
vector unsigned __int128 c_sources [NumSamples];
a_sources [0][0] = 0x0123456789abcdefull;
a_sources [0][0] = a_sources [0][0] << 64 | 0x123456789abcdef0ull;
a_sources [1][0] = 0x5555555555555555ull;
a_sources [1][0] = a_sources [1][0] << 64 | 0xffffffffffffffffull;
a_sources [2][0] = 0xcccccccc55555555ull;
a_sources [2][0] = a_sources [2][0] << 64 | 0x0000000000000000ull;
a_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
a_sources [3][0] = a_sources [3][0] << 64 | 0x6969696969696969ull;
b_sources [0][0] = 0x0123456789abcdefull;
b_sources [0][0] = b_sources [0][0] << 64 | 0x123456789abcdef0ull;
b_sources [1][0] = 0x5555555555555555ull;
b_sources [1][0] = b_sources [1][0] << 64 | 0xffffffffffffffffull;
b_sources [2][0] = 0xcccccccc55555555ull;
b_sources [2][0] = b_sources [2][0] << 64 | 0x0000000000000000ull;
b_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
b_sources [3][0] = b_sources [3][0] << 64 | 0x6969696969696969ull;
c_sources [0][0] = 0x0123456789abcdefull;
c_sources [0][0] = c_sources [0][0] << 64 | 0x123456789abcdef0ull;
c_sources [1][0] = 0x5555555555555555ull;
c_sources [1][0] = c_sources [1][0] << 64 | 0xffffffffffffffffull;
c_sources [2][0] = 0xcccccccc55555555ull;
c_sources [2][0] = c_sources [2][0] << 64 | 0x0000000000000000ull;
c_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
c_sources [3][0] = c_sources [3][0] << 64 | 0x6969696969696969ull;
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */

View File

@ -0,0 +1,129 @@
/* { dg-do run } */
/* { dg-require-effective-target powerpc_future_hw } */
/* { dg-options "-mdejagnu-cpu=future" } */
#include <altivec.h>
extern void abort (void);
#define NumSamples 4
/* vec_all_eq not yet supported for arguments of type
vector unsigned __int128. */
int
vector_equal (vector unsigned __int128 a, vector unsigned __int128 b)
{
return a[0] == b[0];
}
void
doTests00000001 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0x01);
vector unsigned __int128 intended = (a & b & c);
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11100101 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0xe5);
vector unsigned __int128 intended = { 0 };
// Supposed to be a ? c: nand (b,c)
for (int l = 0; l < 1; l++)
{
for (int m = 0; m < 128; m++)
{
unsigned __int128 bit_selector = 0x01;
bit_selector = bit_selector << m;
if (a[l] & bit_selector)
intended [l] |= c [l] & bit_selector;
else if ((b [l] & c [l] & bit_selector) == 0)
intended [l] |= bit_selector;
}
}
if (!vector_equal (result, intended))
abort ();
}
}
void
doTests11110011 (vector unsigned __int128 a_sources [],
vector unsigned __int128 b_sources [],
vector unsigned __int128 c_sources []) {
for (int i = 0; i < NumSamples; i++)
for (int j = 0; j < NumSamples; j++)
for (int k = 0; k < NumSamples; k++)
{
vector unsigned __int128 a = a_sources [i];
vector unsigned __int128 b = b_sources [j];
vector unsigned __int128 c = c_sources [k];
vector unsigned __int128 result = vec_ternarylogic (a, b, c, 0xfb);
vector unsigned __int128 intended = { 0 };
for (int i = 0; i < 1; i++)
intended [i] = b [i] | ~(a [i] & c [i]);
if (!vector_equal (result, intended))
abort ();
}
}
int main (int argc, int *argv [])
{
vector unsigned __int128 a_sources [NumSamples];
vector unsigned __int128 b_sources [NumSamples];
vector unsigned __int128 c_sources [NumSamples];
a_sources [0][0] = 0x0123456789abcdefull;
a_sources [0][0] = a_sources [0][0] << 64 | 0x123456789abcdef0ull;
a_sources [1][0] = 0x5555555555555555ull;
a_sources [1][0] = a_sources [1][0] << 64 | 0xffffffffffffffffull;
a_sources [2][0] = 0xcccccccc55555555ull;
a_sources [2][0] = a_sources [2][0] << 64 | 0x0000000000000000ull;
a_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
a_sources [3][0] = a_sources [3][0] << 64 | 0x6969696969696969ull;
b_sources [0][0] = 0x0123456789abcdefull;
b_sources [0][0] = b_sources [0][0] << 64 | 0x123456789abcdef0ull;
b_sources [1][0] = 0x5555555555555555ull;
b_sources [1][0] = b_sources [1][0] << 64 | 0xffffffffffffffffull;
b_sources [2][0] = 0xcccccccc55555555ull;
b_sources [2][0] = b_sources [2][0] << 64 | 0x0000000000000000ull;
b_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
b_sources [3][0] = b_sources [3][0] << 64 | 0x6969696969696969ull;
c_sources [0][0] = 0x0123456789abcdefull;
c_sources [0][0] = c_sources [0][0] << 64 | 0x123456789abcdef0ull;
c_sources [1][0] = 0x5555555555555555ull;
c_sources [1][0] = c_sources [1][0] << 64 | 0xffffffffffffffffull;
c_sources [2][0] = 0xcccccccc55555555ull;
c_sources [2][0] = c_sources [2][0] << 64 | 0x0000000000000000ull;
c_sources [3][0] = 0xe7e7e7e7e7e7e7e7ull;
c_sources [3][0] = c_sources [3][0] << 64 | 0x6969696969696969ull;
doTests00000001 (a_sources, b_sources, c_sources);
doTests11100101 (a_sources, b_sources, c_sources);
doTests11110011 (a_sources, b_sources, c_sources);
return 0;
}
/* { dg-final { scan-assembler {\mxxeval\M} } } */