]> Cypherpunks repositories - gostls13.git/commitdiff
cleaned up cgen() to be a bit more straightforward.
authorKai Backman <kaib@golang.org>
Tue, 6 Oct 2009 21:48:39 +0000 (14:48 -0700)
committerKai Backman <kaib@golang.org>
Tue, 6 Oct 2009 21:48:39 +0000 (14:48 -0700)
R=rsc
APPROVED=rsc
DELTA=104  (46 added, 56 deleted, 2 changed)
OCL=35392
CL=35394

src/cmd/5g/cgen.c

index dfee75e0ec5f7da7d60c745b4bcdcadf89db1424..1362cc07dbfa151b9b35dc1caf62ae9f6e0e0213 100644 (file)
@@ -76,46 +76,6 @@ cgen(Node *n, Node *res)
                goto ret;
        }
 
-       if(!res->addable) {
-               if(n->ullman > res->ullman) {
-                       regalloc(&n1, n->type, res);
-                       cgen(n, &n1);
-                       if(n1.ullman > res->ullman) {
-                               dump("n1", &n1);
-                               dump("res", res);
-                               fatal("loop in cgen");
-                       }
-                       cgen(&n1, res);
-                       regfree(&n1);
-                       goto ret;
-               }
-
-               if(res->ullman >= UINF)
-                       goto gen;
-
-               a = optoas(OAS, res->type);
-               if(sudoaddable(a, res, &addr, &w)) {
-                       if(n->op != OREGISTER) {
-                               regalloc(&n2, res->type, N);
-                               cgen(n, &n2);
-                               p1 = gins(a, &n2, N);
-                               regfree(&n2);
-                       } else
-                               p1 = gins(a, n, N);
-                       p1->to = addr;
-                       if(debug['g'])
-                               print("%P [ignore previous line]\n", p1);
-                       sudoclean();
-                       goto ret;
-               }
-
-       gen:
-               igen(res, &n1, N);
-               cgen(n, &n1);
-               regfree(&n1);
-               goto ret;
-       }
-
        // update addressability for string, slice
        // can't do in walk because n->left->addable
        // changes if n->left is an escaping local variable.
@@ -130,8 +90,9 @@ cgen(Node *n, Node *res)
                break;
        }
 
-       if(n->addable) {
-               if (n->op == OREGISTER || is64(n->type) || is64(res->type)) {
+       // if both are addressable, move
+       if(n->addable && res->addable) {
+               if (is64(n->type) || is64(res->type) || n->op == OREGISTER || res->op == OREGISTER) {
                        gmove(n, res);
                } else {
                        regalloc(&n1, n->type, N);
@@ -142,6 +103,51 @@ cgen(Node *n, Node *res)
                goto ret;
        }
 
+       // if both are not addressable, use a temporary.
+       if(!n->addable && !res->addable) {
+               // could use regalloc here sometimes,
+               // but have to check for ullman >= UINF.
+               tempname(&n1, n->type);
+               cgen(n, &n1);
+               cgen(&n1, res);
+               return;
+       }
+
+       // if result is not addressable directly but n is,
+       // compute its address and then store via the address.
+       if(!res->addable) {
+               igen(res, &n1, N);
+               cgen(n, &n1);
+               regfree(&n1);
+               return;
+       }
+
+       // if n is sudoaddable generate addr and move
+       if (!is64(n->type) && !is64(res->type)) {
+               a = optoas(OAS, n->type);
+               if(sudoaddable(a, n, &addr, &w)) {
+                       if (res->op != OREGISTER) {
+                               regalloc(&n2, res->type, N);
+                               p1 = gins(a, N, &n2);
+                               p1->from = addr;
+                               if(debug['g'])
+                                       print("%P [ignore previous line]\n", p1);
+                               gmove(&n2, res);
+                               regfree(&n2);
+                       } else {
+                               p1 = gins(a, N, res);
+                               p1->from = addr;
+                               if(debug['g'])
+                                       print("%P [ignore previous line]\n", p1);
+                       }
+                       sudoclean();
+                       goto ret;
+               }
+       }
+
+       // otherwise, the result is addressable but n is not.
+       // let's do some computation.
+
        nl = n->left;
        nr = n->right;
 
@@ -172,22 +178,6 @@ cgen(Node *n, Node *res)
                        cgen64(n, res);
                        return;
                }
-       } else {
-               a = optoas(OAS, n->type);
-               if(sudoaddable(a, n, &addr, &w)) {
-                       if(res->op == OREGISTER) {
-                               p1 = gins(a, N, res);
-                               p1->from = addr;
-                       } else {
-                               regalloc(&n2, n->type, N);
-                               p1 = gins(a, N, &n2);
-                               p1->from = addr;
-                               gins(a, &n2, res);
-                               regfree(&n2);
-                       }
-                       sudoclean();
-                       goto ret;
-               }
        }
 
        switch(n->op) {