1
0
mirror of https://github.com/golang/go synced 2024-11-25 23:37:58 -07:00

cleaned up cgen() to be a bit more straightforward.

R=rsc
APPROVED=rsc
DELTA=104  (46 added, 56 deleted, 2 changed)
OCL=35392
CL=35394
This commit is contained in:
Kai Backman 2009-10-06 14:48:39 -07:00
parent c62b3265a7
commit 620ec45c5f

View File

@ -76,46 +76,6 @@ cgen(Node *n, Node *res)
goto ret; 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 // update addressability for string, slice
// can't do in walk because n->left->addable // can't do in walk because n->left->addable
// changes if n->left is an escaping local variable. // changes if n->left is an escaping local variable.
@ -130,8 +90,9 @@ cgen(Node *n, Node *res)
break; break;
} }
if(n->addable) { // if both are addressable, move
if (n->op == OREGISTER || is64(n->type) || is64(res->type)) { if(n->addable && res->addable) {
if (is64(n->type) || is64(res->type) || n->op == OREGISTER || res->op == OREGISTER) {
gmove(n, res); gmove(n, res);
} else { } else {
regalloc(&n1, n->type, N); regalloc(&n1, n->type, N);
@ -142,6 +103,51 @@ cgen(Node *n, Node *res)
goto ret; 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; nl = n->left;
nr = n->right; nr = n->right;
@ -172,22 +178,6 @@ cgen(Node *n, Node *res)
cgen64(n, res); cgen64(n, res);
return; 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) { switch(n->op) {