aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuss Cox <rsc@golang.org>2010-02-17 15:28:45 -0800
committerRuss Cox <rsc@golang.org>2010-02-17 15:28:45 -0800
commitfb5506600ff219639279917b4cb635c6561be93c (patch)
tree126bc1f1032af702deeda985c87ae2ba82d1b0e0
parent7b76175a1c4c6427fb54249adaced6081edd435e (diff)
downloadgo-fb5506600ff219639279917b4cb635c6561be93c.tar.gz
go-fb5506600ff219639279917b4cb635c6561be93c.zip
8g: respect ullman numbers in float comparison
Fixes #602. R=ken2 CC=golang-dev https://golang.org/cl/212045
-rw-r--r--src/cmd/8g/cgen.c22
-rw-r--r--test/fixedbugs/bug258.go33
2 files changed, 47 insertions, 8 deletions
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c
index 1ab35ab70d..5712fc28e1 100644
--- a/src/cmd/8g/cgen.c
+++ b/src/cmd/8g/cgen.c
@@ -848,7 +848,7 @@ bgen(Node *n, int true, Prog *to)
}
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) {
yyerror("illegal array comparison");
break;
@@ -867,7 +867,7 @@ bgen(Node *n, int true, Prog *to)
}
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) {
yyerror("illegal interface comparison");
break;
@@ -899,10 +899,16 @@ bgen(Node *n, int true, Prog *to)
nodreg(&ax, types[TUINT16], D_AX);
et = simsimtype(nr->type);
if(et == TFLOAT64) {
- // easy - do in FPU
- cgen(nr, &tmp);
- cgen(nl, &tmp);
- gins(AFUCOMPP, &tmp, &n2);
+ if(nl->ullman > nr->ullman) {
+ cgen(nl, &tmp);
+ cgen(nr, &tmp);
+ gins(AFXCHD, &tmp, &n2);
+ } else {
+ cgen(nr, &tmp);
+ cgen(nl, &tmp);
+ }
+ gins(AFUCOMIP, &tmp, &n2);
+ gins(AFMOVDP, &tmp, &tmp); // annoying pop but still better than STSW+SAHF
} else {
// TODO(rsc): The moves back and forth to memory
// here are for truncating the value to 32 bits.
@@ -916,9 +922,9 @@ bgen(Node *n, int true, Prog *to)
cgen(nl, &t2);
gmove(&t2, &tmp);
gins(AFCOMFP, &t1, &tmp);
+ gins(AFSTSW, N, &ax);
+ gins(ASAHF, N, N);
}
- gins(AFSTSW, N, &ax);
- gins(ASAHF, N, N);
if(a == OEQ) {
// neither NE nor P
p1 = gbranch(AJNE, T);
diff --git a/test/fixedbugs/bug258.go b/test/fixedbugs/bug258.go
new file mode 100644
index 0000000000..8984df592d
--- /dev/null
+++ b/test/fixedbugs/bug258.go
@@ -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")
+ }
+ }
+}