diff options
author | Russ Cox <rsc@golang.org> | 2010-02-17 15:28:45 -0800 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2010-02-17 15:28:45 -0800 |
commit | 9d9b0de525a37251cbd6bc56aaf2afe17c8cf1de (patch) | |
tree | 9d25c13a7a810b6a8e8c3b7bc5241ad297e83530 | |
parent | d083717469280aab50208622332ce77fe63c7a67 (diff) | |
download | go-9d9b0de525a37251cbd6bc56aaf2afe17c8cf1de.tar.gz |
8g: respect ullman numbers in float comparison
Fixes issue 602.
R=ken2
CC=golang-dev
http://codereview.appspot.com/212045
-rw-r--r-- | src/cmd/8g/cgen.c | 22 | ||||
-rw-r--r-- | test/fixedbugs/bug258.go | 33 |
2 files changed, 47 insertions, 8 deletions
diff --git a/src/cmd/8g/cgen.c b/src/cmd/8g/cgen.c index 1ab35ab70..5712fc28e 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 000000000..8984df592 --- /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") + } + } +} |