From patchwork Sat May 9 01:13:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bill Schmidt X-Patchwork-Id: 1286509 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=Vd8QFOZQ; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 49Jq2x1TYyz9sSc for ; Sat, 9 May 2020 11:13:42 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F09BB386F82E; Sat, 9 May 2020 01:13:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F09BB386F82E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1588986820; bh=asoq8wTvyD2e1DYrzvilOuzzs4upJf83W+x/H6eVH5E=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=Vd8QFOZQJweVUdIiRg/Qm09cqdJmeFtk+FpJIjsl5UZgZU3axN3QZgKerQAi/Y3aV Tw9Woe+IOHOYbbHRKrp+1ShHlU+G73huGWZ8wUg7kY/3XX2zh0y/mY4E5GFRAKpw2h yMWWjpt0rYK3596ULsk2zVXj44V9iO+iLY1LbmSQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id BC0523851C04; Sat, 9 May 2020 01:13:32 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org BC0523851C04 Received: from pps.filterd (m0098417.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 04916pYH065472; Fri, 8 May 2020 21:13:31 -0400 Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com with ESMTP id 30vtw65d93-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 21:13:31 -0400 Received: from m0098417.ppops.net (m0098417.ppops.net [127.0.0.1]) by pps.reinject (8.16.0.36/8.16.0.36) with SMTP id 0491BuCR083773; Fri, 8 May 2020 21:13:30 -0400 Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com with ESMTP id 30vtw65d8j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Fri, 08 May 2020 21:13:30 -0400 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.16.0.27/8.16.0.27) with SMTP id 04914nIJ019770; Sat, 9 May 2020 01:13:30 GMT Received: from b03cxnp08027.gho.boulder.ibm.com (b03cxnp08027.gho.boulder.ibm.com [9.17.130.19]) by ppma03dal.us.ibm.com with ESMTP id 30s0g8btn9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sat, 09 May 2020 01:13:29 +0000 Received: from b03ledav005.gho.boulder.ibm.com (b03ledav005.gho.boulder.ibm.com [9.17.130.236]) by b03cxnp08027.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 0491DRZ86554264 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sat, 9 May 2020 01:13:27 GMT Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 6A2BEBE053; Sat, 9 May 2020 01:13:28 +0000 (GMT) Received: from b03ledav005.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 22CD9BE04F; Sat, 9 May 2020 01:13:28 +0000 (GMT) Received: from localhost (unknown [9.40.194.84]) by b03ledav005.gho.boulder.ibm.com (Postfix) with ESMTP; Sat, 9 May 2020 01:13:27 +0000 (GMT) To: gcc-patches@gcc.gnu.org Subject: [PATCH] rs6000: Add xxeval and vec_ternarylogic Date: Fri, 8 May 2020 20:13:22 -0500 Message-Id: <20200509011322.35014-1-wschmidt@linux.ibm.com> X-Mailer: git-send-email 2.17.1 X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216, 18.0.676 definitions=2020-05-08_20:2020-05-08, 2020-05-08 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 mlxlogscore=999 priorityscore=1501 suspectscore=1 adultscore=0 lowpriorityscore=0 clxscore=1015 phishscore=0 bulkscore=0 spamscore=0 malwarescore=0 impostorscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005090003 X-Spam-Status: No, score=-13.1 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Bill Schmidt via Gcc-patches From: Bill Schmidt Reply-To: Bill Schmidt Cc: kelvin@gcc.gnu.org, dje.gcc@gmail.com, segher@kernel.crashing.org Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" From: Kelvin Nilsen 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. Bootstrapped and tested on powerpc64le-unknown-linux-gnu with no regressions, using a native POWER9 compiler. Is this okay for master? Thanks, Bill [gcc] 2020-05-08 Kelvin Nilsen * config/rs6000/altivec.h (vec_ternarylogic): New #define. (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. (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-08 Kelvin Nilsen * 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. --- gcc/config/rs6000/altivec.h | 1 + gcc/config/rs6000/altivec.md | 11 + gcc/config/rs6000/predicates.md | 5 + gcc/config/rs6000/rs6000-builtin.def | 23 ++ gcc/config/rs6000/rs6000-c.c | 47 +++- gcc/config/rs6000/rs6000-call.c | 251 ++++++++++++++++++ gcc/config/rs6000/rs6000.h | 12 +- gcc/doc/extend.texi | 21 ++ .../gcc.target/powerpc/vec-ternarylogic-0.c | 120 +++++++++ .../gcc.target/powerpc/vec-ternarylogic-1.c | 119 +++++++++ .../gcc.target/powerpc/vec-ternarylogic-10.c | 129 +++++++++ .../gcc.target/powerpc/vec-ternarylogic-2.c | 105 ++++++++ .../gcc.target/powerpc/vec-ternarylogic-3.c | 106 ++++++++ .../gcc.target/powerpc/vec-ternarylogic-4.c | 104 ++++++++ .../gcc.target/powerpc/vec-ternarylogic-5.c | 103 +++++++ .../gcc.target/powerpc/vec-ternarylogic-6.c | 104 ++++++++ .../gcc.target/powerpc/vec-ternarylogic-7.c | 103 +++++++ .../gcc.target/powerpc/vec-ternarylogic-8.c | 128 +++++++++ .../gcc.target/powerpc/vec-ternarylogic-9.c | 129 +++++++++ 19 files changed, 1616 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-0.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-2.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-3.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-4.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-5.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-6.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-7.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-8.c create mode 100644 gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-9.c diff --git a/gcc/config/rs6000/altivec.h b/gcc/config/rs6000/altivec.h index 74319f13fa6..addf7d0db52 100644 --- a/gcc/config/rs6000/altivec.h +++ b/gcc/config/rs6000/altivec.h @@ -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 */ diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md index 11d2dfe9426..7382d7c4b44 100644 --- a/gcc/config/rs6000/altivec.md +++ b/gcc/config/rs6000/altivec.md @@ -168,6 +168,7 @@ (define_c_enum "unspec" UNSPEC_VPEXTD UNSPEC_VCLRLB UNSPEC_VCLRRB + UNSPEC_XXEVAL ]) (define_c_enum "unspecv" @@ -3271,6 +3272,16 @@ (define_insn "vperm_v16qiv8hi" [(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") diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index bf04e4d431f..c3f460face2 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -234,6 +234,11 @@ (define_predicate "u7bit_cint_operand" (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" diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def index 4b06323a07f..7ff8db5dccc 100644 --- a/gcc/config/rs6000/rs6000-builtin.def +++ b/gcc/config/rs6000/rs6000-builtin.def @@ -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. */ diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c index ee2db96f2bd..cacaea00bd4 100644 --- a/gcc/config/rs6000/rs6000-c.c +++ b/gcc/config/rs6000/rs6000-c.c @@ -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 diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c index 9da5b48463e..9b9562ce4c3 100644 --- a/gcc/config/rs6000/rs6000-call.c +++ b/gcc/config/rs6000/rs6000-call.c @@ -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,44 @@ static const struct builtin_description bdesc_3arg[] = #include "rs6000-builtin.def" }; +/* 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 +#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) \ + { 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 @@ -8314,6 +8372,7 @@ 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) #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++) diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h index 5603af994fa..1209a33173e 100644 --- a/gcc/config/rs6000/rs6000.h +++ b/gcc/config/rs6000/rs6000.h @@ -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 diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 9602a310cbb..c66a9ac7c3d 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -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. diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-0.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-0.c new file mode 100644 index 00000000000..bc1d05c008d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-0.c @@ -0,0 +1,120 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-1.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-1.c new file mode 100644 index 00000000000..8beb80fe60a --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-1.c @@ -0,0 +1,119 @@ +/* { dg-do run} */ +/* { dg-require-effective-target powerpc_future_hw } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c new file mode 100644 index 00000000000..868fb23c01b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-10.c @@ -0,0 +1,129 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-2.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-2.c new file mode 100644 index 00000000000..0d482b8e672 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-2.c @@ -0,0 +1,105 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-3.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-3.c new file mode 100644 index 00000000000..a7245e51da2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-3.c @@ -0,0 +1,106 @@ +/* { dg-do run } */ +/* { dg-require-effective-target powerpc_future_hw } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-4.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-4.c new file mode 100644 index 00000000000..dbd9ffb856e --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-4.c @@ -0,0 +1,104 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-5.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-5.c new file mode 100644 index 00000000000..4d5d8e5e0d6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-5.c @@ -0,0 +1,103 @@ +/* { dg-do run } */ +/* { dg-require-effective-target powerpc_future_hw } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-6.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-6.c new file mode 100644 index 00000000000..0114bacd5fc --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-6.c @@ -0,0 +1,104 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-7.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-7.c new file mode 100644 index 00000000000..27ac4a22866 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-7.c @@ -0,0 +1,103 @@ +/* { dg-do run } */ +/* { dg-require-effective-target powerpc_future_hw } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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; +} diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-8.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-8.c new file mode 100644 index 00000000000..0d6b9e74239 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-8.c @@ -0,0 +1,128 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-9.c b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-9.c new file mode 100644 index 00000000000..b6113596867 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vec-ternarylogic-9.c @@ -0,0 +1,129 @@ +/* { dg-do run } */ +/* { dg-require-effective-target powerpc_future_hw } */ +/* { dg-options "-mdejagnu-cpu=future" } */ + +#include + +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} } } */