]> Cypherpunks repositories - gostls13.git/commitdiff
div and mod operators
authorKen Thompson <ken@golang.org>
Sat, 7 Jun 2008 03:43:29 +0000 (20:43 -0700)
committerKen Thompson <ken@golang.org>
Sat, 7 Jun 2008 03:43:29 +0000 (20:43 -0700)
SVN=121576

src/cmd/6g/cgen.c
src/cmd/6g/gen.c
src/cmd/6g/gg.h
src/cmd/6g/gsubr.c

index ef77fa19fd08fb3bf23429a9d8ce5379c5355bee..07bb11c3b28837b3bee2ad130023c11cee9d3e5d 100644 (file)
@@ -112,9 +112,7 @@ cgen(Node *n, Node *res)
                goto sbop;
 
        // asymmetric binary
-       case OMOD:
        case OSUB:
-       case ODIV:
        case OLSH:
        case ORSH:
                a = optoas(n->op, nl->type);
@@ -237,6 +235,11 @@ cgen(Node *n, Node *res)
                cgen_call(n);
                cgen_callret(n, res);
                break;
+
+       case OMOD:
+       case ODIV:
+               cgen_div(n->op, nl, nr, res);
+               break;
        }
        goto ret;
 
index 47e503764075907b5e8e8756d99904a7562d5bd4..165a91a83f298cbf3a1b6e754024be3574288ae2 100644 (file)
@@ -826,3 +826,56 @@ cgen_as(Node *nl, Node *nr, int op)
        }
        cgen(nr, nl);
 }
+
+void
+cgen_div(int op, Node *nl, Node *nr, Node *res)
+{
+       Node n1, n2, n3;
+       int a;
+
+       if(reg[D_AX] || reg[D_DX]) {
+               fatal("registers occupide");
+       }
+
+       a = optoas(op, nl->type);
+
+       // hold down the DX:AX registers
+       nodreg(&n1, types[TINT64], D_AX);
+       nodreg(&n2, types[TINT64], D_DX);
+       regalloc(&n1, nr->type, &n1);
+       regalloc(&n2, nr->type, &n2);
+
+       if(!issigned[nl->type->etype]) {
+               nodconst(&n3, nl->type, 0);
+               gmove(&n3, &n2);
+       }
+
+       if(nl->ullman >= nr->ullman) {
+               cgen(nl, &n1);
+               if(issigned[nl->type->etype])
+                       gins(ACDQ, N, N);
+               if(!nr->addable) {
+                       regalloc(&n3, nr->type, res);
+                       cgen(nr, &n3);
+                       gins(a, &n3, N);
+                       regfree(&n3);
+               } else
+                       gins(a, nr, N);
+       } else {
+               regalloc(&n3, nr->type, res);
+               cgen(nr, &n3);
+               cgen(nl, &n1);
+               if(issigned[nl->type->etype])
+                       gins(ACDQ, N, N);
+               gins(a, &n3, N);
+               regfree(&n3);
+       }
+
+       if(op == ODIV)
+               gmove(&n1, res);
+       else
+               gmove(&n2, res);
+
+       regfree(&n1);
+       regfree(&n2);
+}
index 5cd31b4aeba6a2f150b4d6a5e3daf4e8b111028e..290b10114b039c9e4a73f5385b112489384c3102 100644 (file)
@@ -117,6 +117,7 @@ void        cgen_call(Node*);
 void   cgen_callmeth(Node*);
 void   cgen_callinter(Node*, Node*);
 void   cgen_callret(Node*, Node*);
+void   cgen_div(int, Node*, Node*, Node*);
 void   genpanic(void);
 int    needconvert(Type*, Type*);
 void   genconv(Type*, Type*);
index 9ced8fe2f54694f564dd34b8f89fbde01e19fafb..125e4c8323c529859def46bdbff15c3a0370506d 100644 (file)
@@ -1397,36 +1397,46 @@ optoas(int op, Type *t)
                break;
 
        case CASE(ODIV, TINT8):
+       case CASE(OMOD, TINT8):
                a = AIDIVB;
                break;
 
        case CASE(ODIV, TUINT8):
+       case CASE(OMOD, TUINT8):
                a = ADIVB;
                break;
 
        case CASE(ODIV, TINT16):
+       case CASE(OMOD, TINT16):
                a = AIDIVW;
                break;
 
        case CASE(ODIV, TUINT16):
+       case CASE(OMOD, TUINT16):
                a = ADIVW;
                break;
 
        case CASE(ODIV, TINT32):
+       case CASE(OMOD, TINT32):
                a = AIDIVL;
                break;
 
        case CASE(ODIV, TUINT32):
        case CASE(ODIV, TPTR32):
+       case CASE(OMOD, TUINT32):
+       case CASE(OMOD, TPTR32):
                a = ADIVL;
                break;
 
        case CASE(ODIV, TINT64):
+       case CASE(OMOD, TINT64):
                a = AIDIVQ;
                break;
 
        case CASE(ODIV, TUINT64):
        case CASE(ODIV, TPTR64):
+       case CASE(OMOD, TUINT64):
+       case CASE(OMOD, TPTR64):
                a = ADIVQ;
                break;