]> Cypherpunks repositories - gostls13.git/commitdiff
6g: avoid unnecessary conversion in shift bounds check
authorRuss Cox <rsc@golang.org>
Mon, 24 May 2010 22:30:53 +0000 (15:30 -0700)
committerRuss Cox <rsc@golang.org>
Mon, 24 May 2010 22:30:53 +0000 (15:30 -0700)
R=ken2
CC=golang-dev
https://golang.org/cl/1278042

src/cmd/6g/ggen.c

index a92d945724227773e1e459efb4e991d82d4d6e86..59a6d529dc824e02227cd73ed1936bc19b5975fa 100644 (file)
@@ -888,6 +888,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
        int a, rcx;
        Prog *p1;
        uvlong sc;
+       Type *tcount;
 
        a = optoas(op, nl->type);
 
@@ -920,8 +921,16 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
 
        rcx = reg[D_CX];
        nodreg(&n1, types[TUINT32], D_CX);
+       
+       // Allow either uint32 or uint64 as shift type,
+       // to avoid unnecessary conversion from uint32 to uint64
+       // just to do the comparison.
+       tcount = types[simtype[nr->type->etype]];
+       if(tcount->etype < TUINT32)
+               tcount = types[TUINT32];
+
        regalloc(&n1, nr->type, &n1);           // to hold the shift type in CX
-       regalloc(&n3, types[TUINT64], &n1);     // to clear high bits of CX
+       regalloc(&n3, tcount, &n1);     // to clear high bits of CX
 
        nodreg(&cx, types[TUINT64], D_CX);
        memset(&oldcx, 0, sizeof oldcx);
@@ -929,6 +938,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
                regalloc(&oldcx, types[TUINT64], N);
                gmove(&cx, &oldcx);
        }
+       cx.type = tcount;
 
        if(samereg(&cx, res))
                regalloc(&n2, nl->type, N);
@@ -946,9 +956,9 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
        regfree(&n3);
 
        // test and fix up large shifts
-       nodconst(&n3, types[TUINT64], nl->type->width*8);
-       gins(optoas(OCMP, types[TUINT64]), &n1, &n3);
-       p1 = gbranch(optoas(OLT, types[TUINT64]), T);
+       nodconst(&n3, tcount, nl->type->width*8);
+       gins(optoas(OCMP, tcount), &n1, &n3);
+       p1 = gbranch(optoas(OLT, tcount), T);
        if(op == ORSH && issigned[nl->type->etype]) {
                nodconst(&n3, types[TUINT32], nl->type->width*8-1);
                gins(a, &n3, &n2);
@@ -960,6 +970,7 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
        gins(a, &n1, &n2);
 
        if(oldcx.op != 0) {
+               cx.type = types[TUINT64];
                gmove(&oldcx, &cx);
                regfree(&oldcx);
        }