ref: 1322203e42cf437adb88ff233bf8955a3d68aac6
parent: 7be5d13a28a8424b4f0275a65fe0c896df1e9bf4
author: Ori Bernstein <[email protected]>
date: Wed Jun 6 22:02:04 EDT 2012
Add support for shift operations.
--- a/8/insns.def
+++ b/8/insns.def
@@ -30,6 +30,9 @@
Insn(Iand, "\tand%t %r,%x\n", 0)
Insn(Ior, "\tor%t %r,%x\n", 0)
Insn(Ixor, "\txor%t %r,%x\n", 0)
+Insn(Ishl, "\tsal%1t %r,%x\n", 0)
+Insn(Isar, "\tshr%1t %r,%x\n", 0)
+Insn(Ishr, "\tshr%1t %r,%x\n", 0)
Insn(Itest, "\ttest%t %r,%r\n", 0)
Insn(Icmp, "\tcmp%t %r,%r\n", 0)
--- a/8/isel.c
+++ b/8/isel.c
@@ -512,7 +512,7 @@
Loc selexpr(Isel *s, Node *n)
{
Loc a, b, c, r;
- Loc eax, edx;
+ Loc eax, edx, cl; /* x86 wanst some hard-coded regs */
Node **args;
args = n->expr.args;
@@ -519,6 +519,7 @@
r = (Loc){Locnone, };
locreg(&eax, Reax);
locreg(&edx, Redx);
+ locreg(&cl, Rcl);
switch (exprop(n)) {
case Oadd: r = binop(s, Iadd, args[0], args[1]); break;
case Osub: r = binop(s, Isub, args[0], args[1]); break;
@@ -545,8 +546,8 @@
b = selexpr(s, args[1]);
b = inr(s, b);
c = coreg(eax, mode(n));
- g(s, Ixor, &edx, &edx, NULL);
g(s, Imov, &a, &c, NULL);
+ g(s, Ixor, &edx, &edx, NULL);
g(s, Idiv, &b, NULL);
freereg(s, Redx);
if (exprop(n) == Odiv)
@@ -563,8 +564,26 @@
case Obor: r = binop(s, Ior, 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 Obsl: die("Unimplemented op %s", opstr(exprop(n))); break;
- case Obsr: die("Unimplemented op %s", opstr(exprop(n))); break;
+ case Obsl:
+ case Obsr:
+ claimreg(s, Rcl); /* shift requires cl as it's arg. stupid. */
+ a = selexpr(s, args[0]);
+ a = inr(s, a);
+ b = selexpr(s, args[1]);
+ c = coreg(cl, b.mode);
+ g(s, Imov, &b, &c, NULL);
+ if (exprop(n) == Obsr) {
+ if (istysigned(n->expr.type))
+ g(s, Isar, &cl, &a, NULL);
+ else
+ g(s, Ishr, &cl, &a, NULL);
+ } else {
+ g(s, Ishl, &cl, &a, NULL);
+ }
+ freeloc(s, cl);
+ freeloc(s, b);
+ r = a;
+ break;
case Obnot: die("Unimplemented op %s", opstr(exprop(n))); break;
case Oderef: die("Unimplemented op %s", opstr(exprop(n))); break;
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -295,6 +295,7 @@
Type *mktyenum(int line, Node **decls, size_t ndecls);
Cstr *mkcstr(int line, char *name, Node **memb, size_t nmemb, Node **funcs, size_t nfuncs);
Type *tylike(Type *t, Ty ty); /* constrains tyvar t like it was builtin ty */
+int istysigned(Type *t);
/* type manipulation */
int hascstr(Type *t, Cstr *c);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -358,7 +358,7 @@
case '>':
if (match('=')) {
tt = Tge;
- } else if (match('<')) {
+ } else if (match('>')) {
if (match('='))
tt = Tbsreq;
else
--- a/parse/type.c
+++ b/parse/type.c
@@ -187,6 +187,17 @@
return t;
}
+int istysigned(Type *t)
+{
+ switch (t->type) {
+ case Tyint8: case Tyint16: case Tyint:
+ case Tyint32: case Tyint64: case Tylong:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
void tlappend(Type ***tl, int *len, Type *t)
{
*tl = xrealloc(tl, (*len + 1)*sizeof(Type*));
--- a/test/tests
+++ b/test/tests
@@ -3,6 +3,7 @@
mul E 84
div E 42
mod E 6
+bsr E 5
struct1 E 12
struct E 42
array E 7