aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-07-15 23:00:11 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-07-30 12:03:58 +0200
commit7d4ee8bc5843997cdc4408848ab2d9ec82f085b2 (patch)
treec09107f7a7bd6e186cfa6ffbccc6b00f468bf714 /gcc/d
parent6ee874f1353933b1427b5e2953358eb3424090d5 (diff)
downloadgcc-7d4ee8bc5843997cdc4408848ab2d9ec82f085b2.zip
gcc-7d4ee8bc5843997cdc4408848ab2d9ec82f085b2.tar.gz
gcc-7d4ee8bc5843997cdc4408848ab2d9ec82f085b2.tar.bz2
d: Implement core.bitop.rol() and core.bitop.ror() as intrinsics.
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.
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/intrinsics.cc56
-rw-r--r--gcc/d/intrinsics.def5
2 files changed, 61 insertions, 0 deletions
diff --git a/gcc/d/intrinsics.cc b/gcc/d/intrinsics.cc
index 7ef1ec5..28667c6 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 0c32126..5b8cb71 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")