]> Cypherpunks repositories - gostls13.git/commitdiff
64 bit cmp and some sgen tweaks
authorKai Backman <kaib@golang.org>
Tue, 6 Oct 2009 16:47:46 +0000 (09:47 -0700)
committerKai Backman <kaib@golang.org>
Tue, 6 Oct 2009 16:47:46 +0000 (09:47 -0700)
go/test: passes 75% (256/339)

R=rsc
APPROVED=rsc
DELTA=142  (53 added, 4 deleted, 85 changed)
OCL=35367
CL=35375

src/cmd/5g/cgen.c
src/cmd/5g/cgen64.c
src/cmd/5g/gsubr.c
test/arm-pass.txt

index 93b79e3ce25d41ce7d1a2abef9caac18b8c0c27d..dfee75e0ec5f7da7d60c745b4bcdcadf89db1424 100644 (file)
@@ -880,6 +880,25 @@ bgen(Node *n, int true, Prog *to)
                        break;
                }
 
+               if(is64(nr->type)) {
+                       if(!nl->addable) {
+                               tempalloc(&n1, nl->type);
+                               cgen(nl, &n1);
+                               nl = &n1;
+                       }
+                       if(!nr->addable) {
+                               tempalloc(&n2, nr->type);
+                               cgen(nr, &n2);
+                               nr = &n2;
+                       }
+                       cmp64(nl, nr, a, to);
+                       if(nr == &n2)
+                               tempfree(&n2);
+                       if(nl == &n1)
+                               tempfree(&n1);
+                       break;
+               }
+
                a = optoas(a, nr->type);
 
                if(nr->ullman >= UINF) {
@@ -988,18 +1007,21 @@ sgen(Node *n, Node *res, int32 w)
        if(osrc % 4 != 0 || odst %4 != 0)
                fatal("sgen: non word(4) aligned offset src %d or dst %d", osrc, odst);
 
-       regalloc(&dst, types[tptr], N);
-       regalloc(&src, types[tptr], N);
-       regalloc(&tmp, types[TUINT32], N);
+       regalloc(&dst, types[tptr], res);
 
        if(n->ullman >= res->ullman) {
-               agen(n, &src);
+               agen(n, &dst);
+               regalloc(&src, types[tptr], N);
+               gins(AMOVW, &dst, &src);
                agen(res, &dst);
        } else {
                agen(res, &dst);
+               regalloc(&src, types[tptr], N);
                agen(n, &src);
        }
 
+       regalloc(&tmp, types[TUINT32], N);
+
        c = w % 4;      // bytes
        q = w / 4;      // quads
 
index 05e49fa7320aa70bd7c745db452ef3298f4490d7..6b41bb0517fce90606034132f91abbea1eaa4405 100644 (file)
@@ -458,86 +458,84 @@ cgen64(Node *n, Node *res)
 void
 cmp64(Node *nl, Node *nr, int op, Prog *to)
 {
-       fatal("cmp64 not implemented");
-//     Node lo1, hi1, lo2, hi2, rr;
-//     Prog *br;
-//     Type *t;
-
-//     split64(nl, &lo1, &hi1);
-//     split64(nr, &lo2, &hi2);
-
-//     // compare most significant word;
-//     // if they differ, we're done.
-//     t = hi1.type;
-//     if(nl->op == OLITERAL || nr->op == OLITERAL)
-//             gins(ACMPL, &hi1, &hi2);
-//     else {
-//             regalloc(&rr, types[TINT32], N);
-//             gins(AMOVL, &hi1, &rr);
-//             gins(ACMPL, &rr, &hi2);
-//             regfree(&rr);
-//     }
-//     br = P;
-//     switch(op) {
-//     default:
-//             fatal("cmp64 %O %T", op, t);
-//     case OEQ:
-//             // cmp hi
-//             // jne L
-//             // cmp lo
-//             // jeq to
-//             // L:
-//             br = gbranch(AJNE, T);
-//             break;
-//     case ONE:
-//             // cmp hi
-//             // jne to
-//             // cmp lo
-//             // jne to
-//             patch(gbranch(AJNE, T), to);
-//             break;
-//     case OGE:
-//     case OGT:
-//             // cmp hi
-//             // jgt to
-//             // jlt L
-//             // cmp lo
-//             // jge to (or jgt to)
-//             // L:
-//             patch(gbranch(optoas(OGT, t), T), to);
-//             br = gbranch(optoas(OLT, t), T);
-//             break;
-//     case OLE:
-//     case OLT:
-//             // cmp hi
-//             // jlt to
-//             // jgt L
-//             // cmp lo
-//             // jle to (or jlt to)
-//             // L:
-//             patch(gbranch(optoas(OLT, t), T), to);
-//             br = gbranch(optoas(OGT, t), T);
-//             break;
-//     }
-
-//     // compare least significant word
-//     t = lo1.type;
-//     if(nl->op == OLITERAL || nr->op == OLITERAL)
-//             gins(ACMPL, &lo1, &lo2);
-//     else {
-//             regalloc(&rr, types[TINT32], N);
-//             gins(AMOVL, &lo1, &rr);
-//             gins(ACMPL, &rr, &lo2);
-//             regfree(&rr);
-//     }
-
-//     // jump again
-//     patch(gbranch(optoas(op, t), T), to);
-
-//     // point first branch down here if appropriate
-//     if(br != P)
-//             patch(br, pc);
-
-//     splitclean();
-//     splitclean();
+       Node lo1, hi1, lo2, hi2, r1, r2;
+       Prog *br;
+       Type *t;
+
+       split64(nl, &lo1, &hi1);
+       split64(nr, &lo2, &hi2);
+
+       // compare most significant word;
+       // if they differ, we're done.
+       t = hi1.type;
+       regalloc(&r1, types[TINT32], N);
+       regalloc(&r2, types[TINT32], N);
+       gins(AMOVW, &hi1, &r1);
+       gins(AMOVW, &hi2, &r2);
+       gcmp(ACMP, &r1, &r2);
+       regfree(&r1);
+       regfree(&r2);
+
+       br = P;
+       switch(op) {
+       default:
+               fatal("cmp64 %O %T", op, t);
+       case OEQ:
+               // cmp hi
+               // bne L
+               // cmp lo
+               // beq to
+               // L:
+               br = gbranch(ABNE, T);
+               break;
+       case ONE:
+               // cmp hi
+               // bne to
+               // cmp lo
+               // bne to
+               patch(gbranch(ABNE, T), to);
+               break;
+       case OGE:
+       case OGT:
+               // cmp hi
+               // bgt to
+               // blt L
+               // cmp lo
+               // bge to (or bgt to)
+               // L:
+               patch(gbranch(optoas(OGT, t), T), to);
+               br = gbranch(optoas(OLT, t), T);
+               break;
+       case OLE:
+       case OLT:
+               // cmp hi
+               // blt to
+               // bgt L
+               // cmp lo
+               // ble to (or jlt to)
+               // L:
+               patch(gbranch(optoas(OLT, t), T), to);
+               br = gbranch(optoas(OGT, t), T);
+               break;
+       }
+
+       // compare least significant word
+       t = lo1.type;
+       regalloc(&r1, types[TINT32], N);
+       regalloc(&r2, types[TINT32], N);
+       gins(AMOVW, &lo1, &r1);
+       gins(AMOVW, &lo2, &r2);
+       gcmp(ACMP, &r1, &r2);
+       regfree(&r1);
+       regfree(&r2);
+
+       // jump again
+       patch(gbranch(optoas(op, t), T), to);
+
+       // point first branch down here if appropriate
+       if(br != P)
+               patch(br, pc);
+
+       splitclean();
+       splitclean();
 }
index 3a64cee84eaa493ecf99e5bb08c1423a1a0ae254..f0a1b2485ea4f45ce990e907a3e96babd5febdc5 100644 (file)
@@ -202,7 +202,19 @@ afunclit(Addr *a)
 void
 regalloc(Node *n, Type *t, Node *o)
 {
-       int i, et;
+       int i, et, fixfree, floatfree;
+
+       if(debug['r']) {
+               fixfree = 0;
+               for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
+                       if(reg[i] == 0)
+                               fixfree++;
+               floatfree = 0;
+               for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
+                       if(reg[i] == 0)
+                               floatfree++;
+               print("regalloc fix %d float %d\n", fixfree, floatfree);
+       }
 
        if(t == T)
                fatal("regalloc: t nil");
@@ -259,7 +271,19 @@ out:
 void
 regfree(Node *n)
 {
-       int i;
+       int i, fixfree, floatfree;
+
+       if(debug['r']) {
+               fixfree = 0;
+               for(i=REGALLOC_R0; i<=REGALLOC_RMAX; i++)
+                       if(reg[i] == 0)
+                               fixfree++;
+               floatfree = 0;
+               for(i=REGALLOC_F0; i<=REGALLOC_FMAX; i++)
+                       if(reg[i] == 0)
+                               floatfree++;
+               print("regalloc fix %d float %d\n", fixfree, floatfree);
+       }
 
        if(n->op != OREGISTER && n->op != OINDREG)
                fatal("regfree: not a register");
@@ -1098,7 +1122,7 @@ optoas(int op, Type *t)
        a = AGOK;
        switch(CASE(op, simtype[t->etype])) {
        default:
-               fatal("optoas: no entry %O-%T", op, t);
+               fatal("optoas: no entry %O-%T etype %T simtype %T", op, t, types[t->etype], types[simtype[t->etype]]);
                break;
 
 /*     case CASE(OADDR, TPTR32):
index 0c96afc9a3b1662cbbc3dc8f0ca05f87ca1ebc1e..c25b3d03d3aca8e40f29eace430a99222c5a88e2 100644 (file)
@@ -1,5 +1,6 @@
 64bit.go
 assign.go
+bigalg.go
 blank1.go
 bugs/bug136.go
 bugs/bug162.go
@@ -34,6 +35,7 @@ fixedbugs/bug005.go
 fixedbugs/bug007.go
 fixedbugs/bug008.go
 fixedbugs/bug009.go
+fixedbugs/bug012.go
 fixedbugs/bug013.go
 fixedbugs/bug014.go
 fixedbugs/bug015.go
@@ -86,6 +88,7 @@ fixedbugs/bug080.go
 fixedbugs/bug081.go
 fixedbugs/bug082.go
 fixedbugs/bug083.go
+fixedbugs/bug084.go
 fixedbugs/bug085.go
 fixedbugs/bug086.go
 fixedbugs/bug087.go
@@ -204,6 +207,7 @@ indirect.go
 indirect1.go
 initcomma.go
 initializerr.go
+intcvt.go
 interface/convert.go
 interface/convert1.go
 interface/convert2.go
@@ -219,6 +223,7 @@ iota.go
 ken/complit.go
 ken/embed.go
 ken/for.go
+ken/interbasic.go
 ken/interfun.go
 ken/intervar.go
 ken/label.go