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:
parent
aa347c4a0d
commit
4dec8ef35a
@ -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);
|
||||||
|
@ -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
17
test/fixedbugs/bug180.go
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user