1
0
mirror of https://github.com/golang/go synced 2024-11-22 08:24:41 -07:00

get function calls out of the way before

allocating registers in shift and div.

fix behavior when res == a reserved register.

R=ken
OCL=32765
CL=32767
This commit is contained in:
Russ Cox 2009-08-04 19:16:57 -07:00
parent aa347c4a0d
commit 4dec8ef35a
3 changed files with 68 additions and 15 deletions

View File

@ -534,11 +534,19 @@ dodiv(int op, Node *nl, Node *nr, Node *res, Node *ax, Node *dx)
void void
cgen_div(int op, Node *nl, Node *nr, Node *res) cgen_div(int op, Node *nl, Node *nr, Node *res)
{ {
Node ax, dx, oldax, olddx; Node ax, dx, oldax, olddx, n1, n2;
int rax, rdx; int rax, rdx;
if(nl->ullman >= UINF || nr->ullman >= UINF) if(nl->ullman >= UINF) {
fatal("cgen_div UINF"); tempname(&n1, nl->type);
cgen(nl, &n1);
nl = &n1;
}
if(nr->ullman >= UINF) {
tempname(&n2, nr->type);
cgen(nr, &n2);
nr = &n2;
}
rax = reg[D_AX]; rax = reg[D_AX];
rdx = reg[D_DX]; rdx = reg[D_DX];
@ -549,13 +557,14 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
regalloc(&dx, nl->type, &dx); regalloc(&dx, nl->type, &dx);
// save current ax and dx if they are live // save current ax and dx if they are live
// and not the destination
memset(&oldax, 0, sizeof oldax); memset(&oldax, 0, sizeof oldax);
memset(&olddx, 0, sizeof olddx); memset(&olddx, 0, sizeof olddx);
if(rax > 0) { if(rax > 0 && !samereg(&ax, res)) {
regalloc(&oldax, nl->type, N); regalloc(&oldax, nl->type, N);
gmove(&ax, &oldax); gmove(&ax, &oldax);
} }
if(rdx > 0) { if(rdx > 0 && !samereg(&dx, res)) {
regalloc(&olddx, nl->type, N); regalloc(&olddx, nl->type, N);
gmove(&dx, &olddx); gmove(&dx, &olddx);
} }
@ -565,11 +574,11 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
regfree(&ax); regfree(&ax);
regfree(&dx); regfree(&dx);
if(rax > 0) { if(oldax.op != 0) {
gmove(&oldax, &ax); gmove(&oldax, &ax);
regfree(&oldax); regfree(&oldax);
} }
if(rdx > 0) { if(olddx.op != 0) {
gmove(&olddx, &dx); gmove(&olddx, &dx);
regfree(&olddx); regfree(&olddx);
} }
@ -584,8 +593,8 @@ cgen_div(int op, Node *nl, Node *nr, Node *res)
void void
cgen_shift(int op, Node *nl, Node *nr, Node *res) cgen_shift(int op, Node *nl, Node *nr, Node *res)
{ {
Node n1, n2, n3; Node n1, n2, n3, n4, n5, cx, oldcx;
int a; int a, rcx;
Prog *p1; Prog *p1;
uvlong sc; uvlong sc;
@ -607,10 +616,32 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
goto ret; goto ret;
} }
if(nl->ullman >= UINF) {
tempname(&n4, nl->type);
cgen(nl, &n4);
nl = &n4;
}
if(nr->ullman >= UINF) {
tempname(&n5, nr->type);
cgen(nr, &n5);
nr = &n5;
}
rcx = reg[D_CX];
nodreg(&n1, types[TUINT32], D_CX); nodreg(&n1, types[TUINT32], D_CX);
regalloc(&n1, nr->type, &n1); // to hold the shift type in CX regalloc(&n1, nr->type, &n1); // to hold the shift type in CX
regalloc(&n3, types[TUINT64], &n1); // to clear high bits of CX regalloc(&n3, types[TUINT64], &n1); // to clear high bits of CX
nodreg(&cx, types[TUINT64], D_CX);
memset(&oldcx, 0, sizeof oldcx);
if(rcx > 0 && !samereg(&cx, res)) {
regalloc(&oldcx, types[TUINT64], N);
gmove(&cx, &oldcx);
}
if(samereg(&cx, res))
regalloc(&n2, nl->type, N);
else
regalloc(&n2, nl->type, res); regalloc(&n2, nl->type, res);
if(nl->ullman >= nr->ullman) { if(nl->ullman >= nr->ullman) {
cgen(nl, &n2); cgen(nl, &n2);
@ -637,6 +668,11 @@ cgen_shift(int op, Node *nl, Node *nr, Node *res)
patch(p1, pc); patch(p1, pc);
gins(a, &n1, &n2); gins(a, &n1, &n2);
if(oldcx.op != 0) {
gmove(&oldcx, &cx);
regfree(&oldcx);
}
gmove(&n2, res); gmove(&n2, res);
regfree(&n1); regfree(&n1);

View File

@ -60,8 +60,8 @@ func TestSecondsToUTC(t *testing.T) {
} }
if !same(tm, golden) { if !same(tm, golden) {
t.Errorf("SecondsToUTC(%d):", sec); t.Errorf("SecondsToUTC(%d):", sec);
t.Errorf(" want=%v", *golden); t.Errorf(" want=%+v", *golden);
t.Errorf(" have=%v", *tm); t.Errorf(" have=%+v", *tm);
} }
} }
} }
@ -77,8 +77,8 @@ func TestSecondsToLocalTime(t *testing.T) {
} }
if !same(tm, golden) { if !same(tm, golden) {
t.Errorf("SecondsToLocalTime(%d):", sec); t.Errorf("SecondsToLocalTime(%d):", sec);
t.Errorf(" want=%v", *golden); t.Errorf(" want=%+v", *golden);
t.Errorf(" have=%v", *tm); t.Errorf(" have=%+v", *tm);
} }
} }
} }

17
test/fixedbugs/bug180.go Normal file
View File

@ -0,0 +1,17 @@
// $G $D/$F.go && $L $F.$A && ./$A.out
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
func shift(x int) int {
return 1<<(1<<(1<<(uint(x))));
}
func main() {
if n := shift(2); n != 1<<(1<<(1<<2)) {
panicln("bad shift", n);
}
}