summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-03-05 15:35:09 -0800
committerRuss Cox <rsc@golang.org>2010-03-05 15:35:09 -0800
commit6fbf0007b69f26ae9eeb6e14e40dc943013e20d5 (patch)
tree67cf29cef444b0985c0a0350784166479abff782 /src
parent62be41b9e6aec434582b7bc541e0eaed1e9631da (diff)
downloadgolang-6fbf0007b69f26ae9eeb6e14e40dc943013e20d5.tar.gz
gc: better compilation of floating point +=
R=ken2 CC=golang-dev http://codereview.appspot.com/255042
Diffstat (limited to 'src')
-rw-r--r--src/cmd/5g/ggen.c26
-rw-r--r--src/cmd/6g/ggen.c26
-rw-r--r--src/cmd/8g/cgen.c2
-rw-r--r--src/cmd/8g/ggen.c33
-rw-r--r--src/cmd/gc/walk.c7
5 files changed, 63 insertions, 31 deletions
diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c
index 3f32e601b..758e140dc 100644
--- a/src/cmd/5g/ggen.c
+++ b/src/cmd/5g/ggen.c
@@ -479,27 +479,35 @@ cgen_asop(Node *n)
}
hard:
- if(nr->ullman > nl->ullman) {
+ n2.op = 0;
+ n1.op = 0;
+ if(nr->ullman >= nl->ullman || nl->addable) {
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
- igen(nl, &n1, N);
+ nr = &n2;
} else {
- igen(nl, &n1, N);
- regalloc(&n2, nr->type, N);
+ tempname(&n2, nr->type);
cgen(nr, &n2);
+ nr = &n2;
+ }
+ if(!nl->addable) {
+ igen(nl, &n1, N);
+ nl = &n1;
}
n3 = *n;
- n3.left = &n1;
- n3.right = &n2;
+ n3.left = nl;
+ n3.right = nr;
n3.op = n->etype;
regalloc(&n4, nl->type, N);
cgen(&n3, &n4);
- gmove(&n4, &n1);
+ gmove(&n4, nl);
- regfree(&n1);
- regfree(&n2);
+ if(n1.op)
+ regfree(&n1);
+ if(n2.op == OREGISTER)
+ regfree(&n2);
regfree(&n4);
goto ret;
diff --git a/src/cmd/6g/ggen.c b/src/cmd/6g/ggen.c
index 731e922bb..45fd17b27 100644
--- a/src/cmd/6g/ggen.c
+++ b/src/cmd/6g/ggen.c
@@ -432,27 +432,35 @@ cgen_asop(Node *n)
}
hard:
- if(nr->ullman > nl->ullman) {
+ n2.op = 0;
+ n1.op = 0;
+ if(nr->ullman >= nl->ullman || nl->addable) {
regalloc(&n2, nr->type, N);
cgen(nr, &n2);
- igen(nl, &n1, N);
+ nr = &n2;
} else {
- igen(nl, &n1, N);
- regalloc(&n2, nr->type, N);
+ tempname(&n2, nr->type);
cgen(nr, &n2);
+ nr = &n2;
+ }
+ if(!nl->addable) {
+ igen(nl, &n1, N);
+ nl = &n1;
}
n3 = *n;
- n3.left = &n1;
- n3.right = &n2;
+ n3.left = nl;
+ n3.right = nr;
n3.op = n->etype;
regalloc(&n4, nl->type, N);
cgen(&n3, &n4);
- gmove(&n4, &n1);
+ gmove(&n4, nl);
- regfree(&n1);
- regfree(&n2);
+ if(n1.op)
+ regfree(&n1);
+ if(n2.op == OREGISTER)
+ regfree(&n2);
regfree(&n4);
ret:
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index 1185ee49f..5adf29a43 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -18,7 +18,7 @@ mgen(Node *n, Node *n1, Node *rg)
reg[n->val.u.reg]++;
return;
}
- if(n->type->width > widthptr)
+ if(n->type->width > widthptr && !isfloat[n->type->etype])
tempname(n1, n->type);
else
regalloc(n1, n->type, rg);
diff --git a/src/cmd/8g/ggen.c b/src/cmd/8g/ggen.c
index 549488d16..f6fa7da0b 100644
--- a/src/cmd/8g/ggen.c
+++ b/src/cmd/8g/ggen.c
@@ -471,21 +471,34 @@ cgen_asop(Node *n)
}
hard:
- tempname(&n2, nr->type);
- cgen(nr, &n2);
-
- igen(nl, &n1, N);
+ n2.op = 0;
+ n1.op = 0;
+ if(nr->ullman >= nl->ullman || nl->addable) {
+ mgen(nr, &n2, N);
+ nr = &n2;
+ nr = &n2;
+ } else {
+ tempname(&n2, nr->type);
+ cgen(nr, &n2);
+ nr = &n2;
+ }
+ if(!nl->addable) {
+ igen(nl, &n1, N);
+ nl = &n1;
+ }
n3 = *n;
- n3.left = &n1;
- n3.right = &n2;
+ n3.left = nl;
+ n3.right = nr;
n3.op = n->etype;
- tempname(&n4, nl->type);
- cgen(&n3, &n4);
- gmove(&n4, &n1);
+ mgen(&n3, &n4, N);
+ gmove(&n4, nl);
- regfree(&n1);
+ if(n1.op)
+ regfree(&n1);
+ mfree(&n2);
+ mfree(&n4);
ret:
;
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 2f151307a..5ee82eeac 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -823,10 +823,13 @@ walkexpr(Node **np, NodeList **init)
}
/*
- * on 32-bit arch, rewrite 64-bit ops into l = l op r
+ * on 32-bit arch, rewrite 64-bit ops into l = l op r.
+ * on 386, rewrite float ops into l = l op r.
+ * TODO(rsc): Maybe this rewrite should be done always?
*/
et = n->left->type->etype;
- if(widthptr == 4 && (et == TUINT64 || et == TINT64)) {
+ if((widthptr == 4 && (et == TUINT64 || et == TINT64)) ||
+ (thechar == '8' && isfloat[et])) {
l = safeexpr(n->left, init);
r = nod(OAS, l, nod(n->etype, l, n->right));
typecheck(&r, Etop);