mirror of
https://github.com/golang/go
synced 2024-11-22 00:04:41 -07:00
8g: respect ullman numbers in float comparison
Fixes #602. R=ken2 CC=golang-dev https://golang.org/cl/212045
This commit is contained in:
parent
7b76175a1c
commit
fb5506600f
@ -848,7 +848,7 @@ bgen(Node *n, int true, Prog *to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isslice(nl->type)) {
|
if(isslice(nl->type)) {
|
||||||
// only valid to cmp darray to literal nil
|
// front end should only leave cmp to literal nil
|
||||||
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
|
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
|
||||||
yyerror("illegal array comparison");
|
yyerror("illegal array comparison");
|
||||||
break;
|
break;
|
||||||
@ -867,7 +867,7 @@ bgen(Node *n, int true, Prog *to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isinter(nl->type)) {
|
if(isinter(nl->type)) {
|
||||||
// front end shold only leave cmp to literal nil
|
// front end should only leave cmp to literal nil
|
||||||
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
|
if((a != OEQ && a != ONE) || nr->op != OLITERAL) {
|
||||||
yyerror("illegal interface comparison");
|
yyerror("illegal interface comparison");
|
||||||
break;
|
break;
|
||||||
@ -899,10 +899,16 @@ bgen(Node *n, int true, Prog *to)
|
|||||||
nodreg(&ax, types[TUINT16], D_AX);
|
nodreg(&ax, types[TUINT16], D_AX);
|
||||||
et = simsimtype(nr->type);
|
et = simsimtype(nr->type);
|
||||||
if(et == TFLOAT64) {
|
if(et == TFLOAT64) {
|
||||||
// easy - do in FPU
|
if(nl->ullman > nr->ullman) {
|
||||||
|
cgen(nl, &tmp);
|
||||||
|
cgen(nr, &tmp);
|
||||||
|
gins(AFXCHD, &tmp, &n2);
|
||||||
|
} else {
|
||||||
cgen(nr, &tmp);
|
cgen(nr, &tmp);
|
||||||
cgen(nl, &tmp);
|
cgen(nl, &tmp);
|
||||||
gins(AFUCOMPP, &tmp, &n2);
|
}
|
||||||
|
gins(AFUCOMIP, &tmp, &n2);
|
||||||
|
gins(AFMOVDP, &tmp, &tmp); // annoying pop but still better than STSW+SAHF
|
||||||
} else {
|
} else {
|
||||||
// TODO(rsc): The moves back and forth to memory
|
// TODO(rsc): The moves back and forth to memory
|
||||||
// here are for truncating the value to 32 bits.
|
// here are for truncating the value to 32 bits.
|
||||||
@ -916,9 +922,9 @@ bgen(Node *n, int true, Prog *to)
|
|||||||
cgen(nl, &t2);
|
cgen(nl, &t2);
|
||||||
gmove(&t2, &tmp);
|
gmove(&t2, &tmp);
|
||||||
gins(AFCOMFP, &t1, &tmp);
|
gins(AFCOMFP, &t1, &tmp);
|
||||||
}
|
|
||||||
gins(AFSTSW, N, &ax);
|
gins(AFSTSW, N, &ax);
|
||||||
gins(ASAHF, N, N);
|
gins(ASAHF, N, N);
|
||||||
|
}
|
||||||
if(a == OEQ) {
|
if(a == OEQ) {
|
||||||
// neither NE nor P
|
// neither NE nor P
|
||||||
p1 = gbranch(AJNE, T);
|
p1 = gbranch(AJNE, T);
|
||||||
|
33
test/fixedbugs/bug258.go
Normal file
33
test/fixedbugs/bug258.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// $G $D/$F.go && $L $F.$A && ./$A.out
|
||||||
|
|
||||||
|
// Copyright 2010 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
|
||||||
|
|
||||||
|
import "math"
|
||||||
|
|
||||||
|
func f() float64 {
|
||||||
|
math.Pow(2, 2)
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
// 386 float register bug used to load constant before call
|
||||||
|
if -5 < f() {
|
||||||
|
} else {
|
||||||
|
println("BUG 1")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if f() > -7 {
|
||||||
|
} else {
|
||||||
|
println("BUG 2")
|
||||||
|
}
|
||||||
|
|
||||||
|
if math.Pow(2, 3) != 8 {
|
||||||
|
println("BUG 3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user