diff --git a/src/cmd/5g/ggen.c b/src/cmd/5g/ggen.c index 3f32e601b30..758e140dcec 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 731e922bb66..45fd17b27ee 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 1185ee49f8e..5adf29a438a 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 549488d16c9..f6fa7da0b02 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 2f151307abd..5ee82eeac79 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);