shithub: mc

Download patch

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