ref: 509d071791cc2c008759f637931b7afea73c083b
parent: 795ee8f8c9ef7eae69fdd2d00bfc4b7753e31dbb
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Sep 9 19:13:22 EDT 2017
Emit rotl/rotr instructions.
--- a/6/insns.def
+++ b/6/insns.def
@@ -143,6 +143,11 @@
"\tSHR%2T %U,%R\n",
Use(.l={1,2}),
Def(.l={2}))
+Insn(Irol,
+ "\trol%2t %u,%r\n",
+ "\tROL%2T %U,%R\n",
+ Use(.l={1,2}),
+ Def(.l={2}))
Insn(Itest,
"\ttest%t %x,%r\n",
--- a/6/isel.c
+++ b/6/isel.c
@@ -608,6 +608,54 @@
return ret;
}
+static Loc*
+rolop(Isel *s, Node *n, Node *l, Node *r)
+{
+ int64_t lv, rv;
+ Type *ty;
+
+ ty = tybase(exprtype(n));
+
+ if (!istyunsigned(ty))
+ return NULL;
+ if (exprop(l) != Obsl && exprop(l) != Obsr)
+ return NULL;
+ if (exprop(r) != Obsl && exprop(r) != Obsr)
+ return NULL;
+ if (exprop(r) == exprop(l))
+ return NULL;
+ if (exprop(l->expr.args[0]) != Ovar)
+ return NULL;
+ if (exprop(r->expr.args[0]) != Ovar)
+ return NULL;
+ if (l->expr.args[0]->expr.did != r->expr.args[0]->expr.did)
+ return NULL;
+
+ if (exprop(l->expr.args[1]) != Olit)
+ return NULL;
+ if (l->expr.args[1]->expr.args[0]->type != Nlit)
+ return NULL;
+ if (l->expr.args[1]->expr.args[0]->lit.littype != Lint)
+ return NULL;
+ lv = l->expr.args[1]->expr.args[0]->lit.intval;
+
+ if (exprop(r->expr.args[1]) != Olit)
+ return NULL;
+ if (r->expr.args[1]->expr.args[0]->type != Nlit)
+ return NULL;
+ if (r->expr.args[1]->expr.args[0]->lit.littype != Lint)
+ return NULL;
+ rv = r->expr.args[1]->expr.args[0]->lit.intval;
+
+ if (lv + rv != 8*size(n))
+ return NULL;
+
+ if (exprop(l) == Obsl)
+ return binop(s, Irol, l->expr.args[0], l->expr.args[1]);
+ else
+ return binop(s, Irol, r->expr.args[0], r->expr.args[1]);
+}
+
Loc *
selexpr(Isel *s, Node *n)
{
@@ -626,7 +674,10 @@
case Osub: r = binop(s, Isub, args[0], args[1]); break;
case Oband: r = binop(s, Iand, args[0], args[1]); break;
case Obxor: r = binop(s, Ixor, args[0], args[1]); break;
- case Obor: r = binop(s, Ior, args[0], args[1]); break;
+ case Obor:
+ r = rolop(s, n, args[0], args[1]);
+ if (!r)
+ r = binop(s, Ior, args[0], args[1]); break;
case Omul:
if (size(args[0]) == 1) {
a = selexpr(s, args[0]);