]> Cypherpunks repositories - gostls13.git/commitdiff
8c: handle 64-bit switch value
authorRuss Cox <rsc@golang.org>
Wed, 14 Dec 2011 05:08:38 +0000 (00:08 -0500)
committerRuss Cox <rsc@golang.org>
Wed, 14 Dec 2011 05:08:38 +0000 (00:08 -0500)
Cases must still be 32-bit values, but one thing at a time.

R=ality, ken2, ken
CC=golang-dev
https://golang.org/cl/5485063

src/cmd/8c/swt.c
src/cmd/cc/pgen.c

index 006bfdfe23fafab11745dce5392a4b0fb8b3e5dd..937a27d88245ffaa6788df02125f7efc49e686c1 100644 (file)
@@ -36,12 +36,40 @@ swit1(C1 *q, int nc, int32 def, Node *n)
        C1 *r;
        int i;
        Prog *sp;
+       Node n1, nreg, ncon;
+
+       if(typev[n->type->etype]) {
+               if(n->op != ONAME || n->sym != nodsafe->sym) {
+                       regsalloc(&nreg, n);
+                       nreg.type = types[TVLONG];
+                       cgen(n, &nreg);
+                       swit1(q, nc, def, &nreg);
+                       return;
+               }
+       } else {
+               if(n->op != OREGISTER) {
+                       regalloc(&nreg, n, Z);
+                       nreg.type = types[TLONG];
+                       cgen(n, &nreg);
+                       swit1(q, nc, def, &nreg);
+                       regfree(&nreg);
+                       return;
+               }
+       }
 
        if(nc < 5) {
                for(i=0; i<nc; i++) {
                        if(debug['W'])
                                print("case = %.8ux\n", q->val);
-                       gopcode(OEQ, n->type, n, nodconst(q->val));
+                       if(n->type && typev[n->type->etype]) {
+                               memset(&n1, 0, sizeof n1);
+                               n1.op = OEQ;
+                               n1.left = n;
+                               ncon = *nodconst(q->val);
+                               n1.right = &ncon;
+                               boolgen(&n1, 1, Z);
+                       } else
+                               gopcode(OEQ, n->type, n, nodconst(q->val));
                        patch(p, q->label);
                        q++;
                }
@@ -53,10 +81,22 @@ swit1(C1 *q, int nc, int32 def, Node *n)
        r = q+i;
        if(debug['W'])
                print("case > %.8ux\n", r->val);
-       gopcode(OGT, n->type, n, nodconst(r->val));
-       sp = p;
-       gbranch(OGOTO);
-       p->as = AJEQ;
+       if(n->type && typev[n->type->etype]) {
+               memset(&n1, 0, sizeof n1);
+               n1.op = OGT;
+               n1.left = n;
+               ncon = *nodconst(r->val);
+               n1.right = &ncon;
+               boolgen(&n1, 1, Z);
+               sp = p;
+               n1.op = OEQ;
+               boolgen(&n1, 1, Z);
+       } else {
+               gopcode(OGT, n->type, n, nodconst(r->val));
+               sp = p;
+               gbranch(OGOTO);
+               p->as = AJEQ;
+       }
        patch(p, r->label);
        swit1(q, i, def, n);
 
index e652e2349d6841021702d32bc6291104ba5191e4..3a686102f37569c4cf3d808c3cd4e9115991bb65 100644 (file)
@@ -293,7 +293,7 @@ loop:
                complex(l);
                if(l->type == T)
                        break;
-               if(!typeword[l->type->etype] || l->type->etype == TIND) {
+               if(!typechlvp[l->type->etype] || l->type->etype == TIND) {
                        diag(n, "switch expression must be integer");
                        break;
                }
@@ -320,15 +320,7 @@ loop:
                }
 
                patch(sp, pc);
-               regalloc(&nod, l, Z);
-               /* always signed */
-               if(typev[l->type->etype])
-                       nod.type = types[TVLONG];
-               else
-                       nod.type = types[TLONG];
-               cgen(l, &nod);
-               doswit(&nod);
-               regfree(&nod);
+               doswit(l);
                patch(spb, pc);
 
                cases = cn;