summaryrefslogtreecommitdiff
path: root/6
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-09-09 23:13:22 -0700
committerOri Bernstein <ori@eigenstate.org>2017-09-10 01:07:53 -0700
commit509d071791cc2c008759f637931b7afea73c083b (patch)
tree830c23c540910a897eedf0321597107caa95adac /6
parent795ee8f8c9ef7eae69fdd2d00bfc4b7753e31dbb (diff)
downloadmc-509d071791cc2c008759f637931b7afea73c083b.tar.gz
Emit rotl/rotr instructions.
Diffstat (limited to '6')
-rw-r--r--6/insns.def5
-rw-r--r--6/isel.c53
2 files changed, 57 insertions, 1 deletions
diff --git a/6/insns.def b/6/insns.def
index 105aa10..1e0a864 100644
--- a/6/insns.def
+++ b/6/insns.def
@@ -143,6 +143,11 @@ Insn(Ishr,
"\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",
diff --git a/6/isel.c b/6/isel.c
index a8d476c..e4974e6 100644
--- a/6/isel.c
+++ b/6/isel.c
@@ -608,6 +608,54 @@ gencall(Isel *s, Node *n)
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 @@ selexpr(Isel *s, Node *n)
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]);