From patchwork Thu Jul 30 11:11:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Iain Buclaw X-Patchwork-Id: 1338759 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=8.43.85.97; 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=DisL4l4q; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 4BHSR42rkLz9sRN for ; Thu, 30 Jul 2020 21:11:43 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id D598E384C004; Thu, 30 Jul 2020 11:11:40 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D598E384C004 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1596107500; bh=8zEsrMAaQ0QSm0ebGSTkX5TWesptk8rCOc6VrR/10bY=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=DisL4l4qf88gLWWB1aIzdr7WRhlE0+lGcVE1wIarunRo/WPUvfLfRMQVa8D4RiCuR izhlEI6gk4cWk8A5wpdvmF0UptOjoCIs50v71AcUAjSUnmCNp6p/0M36zCt7fK/UUU jM0aeQGQHdnOr/h6BHW/G1ofwfetegd4xkNJw8XQ= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [80.241.56.151]) by sourceware.org (Postfix) with ESMTPS id B0EFD3858D35 for ; Thu, 30 Jul 2020 11:11:37 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org B0EFD3858D35 Received: from smtp1.mailbox.org (smtp1.mailbox.org [80.241.60.240]) (using TLSv1.2 with cipher ECDHE-RSA-CHACHA20-POLY1305 (256/256 bits)) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4BHSQw0fqLzKmVn; Thu, 30 Jul 2020 13:11:36 +0200 (CEST) X-Virus-Scanned: amavisd-new at heinlein-support.de Received: from smtp1.mailbox.org ([80.241.60.240]) by spamfilter04.heinlein-hosting.de (spamfilter04.heinlein-hosting.de [80.241.56.122]) (amavisd-new, port 10030) with ESMTP id hn7HwSzF_Ya7; Thu, 30 Jul 2020 13:11:33 +0200 (CEST) To: gcc-patches@gcc.gnu.org Subject: [committed] d: Implement core.bitop.rol() and core.bitop.ror() as intrinsics. Date: Thu, 30 Jul 2020 13:11:30 +0200 Message-Id: <20200730111130.1241389-1-ibuclaw@gdcproject.org> MIME-Version: 1.0 X-MBO-SPAM-Probability: 10 X-Rspamd-Score: 1.52 / 15.00 / 15.00 X-Rspamd-Queue-Id: 1DFF8180E X-Rspamd-UID: 72e851 X-Spam-Status: No, score=-16.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, 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: Iain Buclaw via Gcc-patches From: Iain Buclaw Reply-To: Iain Buclaw Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, Following on from the last patch, this implements rol() and ror() in the core.bitop module as D intrinsics. Bootstrapped and regression tested on x86_64-linux-gnu and committed to mainline. Regards Iain --- gcc/d/ChangeLog: * intrinsics.cc (expand_intrinsic_rotate): Add function. (maybe_expand_intrinsic): Handle rol and ror intrinsics. * intrinsics.def (ROL): Add intrinsic. (ROL_TIARG): Add intrinsic. (ROR): Add intrinsic. (ROR_TIARG): Add intrinsic. gcc/testsuite/ChangeLog: * gdc.dg/intrinsics.d: Add ror and rol tests. --- gcc/d/intrinsics.cc | 56 +++++++++++++++++++++++++++++++ gcc/d/intrinsics.def | 5 +++ gcc/testsuite/gdc.dg/intrinsics.d | 6 ++++ 3 files changed, 67 insertions(+) diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc index 7ef1ec5ea20..28667c63e17 100644 --- a/gcc/d/intrinsics.cc +++ b/gcc/d/intrinsics.cc @@ -390,6 +390,56 @@ expand_intrinsic_popcnt (tree callexp) return call_builtin_fn (callexp, code, 1, arg); } +/* Expand a front-end intrinsic call to INTRINSIC, which is either a call to + rol() or ror(). These intrinsics expect to take one or two arguments, + the signature to which can be either: + + T rol(T) (const T value, const uint count); + T rol(uint count, T) (const T value); + T ror(T) (const T value, const uint count); + T ror(uint count, T) (const T value); + + This bitwise rotates VALUE left or right by COUNT bit positions. */ + +static tree +expand_intrinsic_rotate (intrinsic_code intrinsic, tree callexp) +{ + tree type = TREE_TYPE (callexp); + tree value = CALL_EXPR_ARG (callexp, 0); + tree count; + tree_code code; + + /* Get the equivalent tree code for the intrinsic. */ + if (intrinsic == INTRINSIC_ROL || intrinsic == INTRINSIC_ROL_TIARG) + code = LROTATE_EXPR; + else if (intrinsic == INTRINSIC_ROR || intrinsic == INTRINSIC_ROR_TIARG) + code = RROTATE_EXPR; + else + gcc_unreachable (); + + /* Get the COUNT parameter. Either from the call expression arguments or the + template instantiation arguments. */ + if (intrinsic == INTRINSIC_ROL || intrinsic == INTRINSIC_ROR) + count = CALL_EXPR_ARG (callexp, 1); + else + { + tree callee = CALL_EXPR_FN (callexp); + + if (TREE_CODE (callee) == ADDR_EXPR) + callee = TREE_OPERAND (callee, 0); + + /* Retrieve from the encoded template instantation. */ + TemplateInstance *ti = DECL_LANG_FRONTEND (callee)->isInstantiated (); + gcc_assert (ti && ti->tiargs && ti->tiargs->length == 2); + + Expression *e = isExpression ((*ti->tiargs)[0]); + gcc_assert (e && e->op == TOKint64); + count = build_expr (e, true); + } + + return fold_build2 (code, type, value, count); +} + /* Expand a front-end intrinsic call to copysign(). This takes two arguments, the signature to which can be either: @@ -737,6 +787,12 @@ maybe_expand_intrinsic (tree callexp) case INTRINSIC_POPCNT64: return expand_intrinsic_popcnt (callexp); + case INTRINSIC_ROL: + case INTRINSIC_ROL_TIARG: + case INTRINSIC_ROR: + case INTRINSIC_ROR_TIARG: + return expand_intrinsic_rotate (intrinsic, callexp); + case INTRINSIC_BSWAP32: case INTRINSIC_BSWAP64: case INTRINSIC_CEIL: diff --git a/gcc/d/intrinsics.def b/gcc/d/intrinsics.def index 0c32126b1fa..5b8cb712264 100644 --- a/gcc/d/intrinsics.def +++ b/gcc/d/intrinsics.def @@ -59,6 +59,11 @@ DEF_D_BUILTIN (BSWAP64, BSWAP64, "bswap", "core.bitop", "FNaNbNiNfmZm") DEF_D_BUILTIN (POPCNT32, NONE, "popcnt", "core.bitop", "FNaNbNiNfkZi") DEF_D_BUILTIN (POPCNT64, NONE, "popcnt", "core.bitop", "FNaNbNiNfmZi") +DEF_D_BUILTIN (ROL, NONE, "rol", "core.bitop", "FNaI1TkZI1T") +DEF_D_BUILTIN (ROL_TIARG, NONE, "rol", "core.bitop", "FNaI1TZI1T") +DEF_D_BUILTIN (ROR, NONE, "ror", "core.bitop", "FNaI1TkZI1T") +DEF_D_BUILTIN (ROR_TIARG, NONE, "ror", "core.bitop", "FNaI1TZI1T") + DEF_D_BUILTIN (VLOAD8, NONE, "volatileLoad", "core.bitop", "FNbNiNfPhZh") DEF_D_BUILTIN (VLOAD16, NONE, "volatileLoad", "core.bitop", "FNbNiNfPtZt") DEF_D_BUILTIN (VLOAD32, NONE, "volatileLoad", "core.bitop", "FNbNiNfPkZk") diff --git a/gcc/testsuite/gdc.dg/intrinsics.d b/gcc/testsuite/gdc.dg/intrinsics.d index e10c06dd41a..5888361a438 100644 --- a/gcc/testsuite/gdc.dg/intrinsics.d +++ b/gcc/testsuite/gdc.dg/intrinsics.d @@ -38,6 +38,12 @@ void test_volatileStore(ubyte *a, ubyte b) { return volatileStore(a, b); } void test_volatileStore(ushort *a, ushort b) { return volatileStore(a, b); } void test_volatileStore(uint *a, uint b) { return volatileStore(a, b); } void test_volatileStore(ulong *a, ulong b) { return volatileStore(a, b); } +// { dg-final { scan-tree-dump-not " rol " "original" } } +ubyte test_rol(ubyte a, uint b) { return rol!ubyte(a, b); } +uint test_rol(uint a) { return rol!(1, uint)(a); } +// { dg-final { scan-tree-dump-not " ror " "original" } } +ushort test_ror(ushort a, uint b) { return ror!ushort(a, b); } +ulong test_ror(ulong a) { return ror!(1, ulong)(a); } ////////////////////////////////////////////////////// // core.checkedint