mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: stop using fucomi* ops for 387 builds
The fucomi* opcodes were only introduced for the Pentium Pro.
They do not exist for an MMX Pentium. Use the fucom* instructions
instead and move the condition codes from the fp flags register to
the integer flags register explicitly.
The use of fucomi* opcodes in ggen.go was introduced in 1.5 (CL 8738).
The bad ops were generated for 64-bit floating-point comparisons.
The use of fucomi* opcodes in gsubr.go dates back to at least 1.1.
The bad ops were generated for float{32,64} to uint64 conversions.
Fixes #13923
Change-Id: I5290599f5edea8abf8fb18036f44fa78bd1fc9e6
Reviewed-on: https://go-review.googlesource.com/18590
Reviewed-by: Minux Ma <minux@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
f3ce054a44
commit
3d01f28e47
4 changed files with 120 additions and 11 deletions
102
src/cmd/compile/internal/gc/float_test.go
Normal file
102
src/cmd/compile/internal/gc/float_test.go
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// Copyright 2016 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 gc
|
||||
|
||||
import "testing"
|
||||
|
||||
// For GO386=387, make sure fucomi* opcodes are not used
|
||||
// for comparison operations.
|
||||
// Note that this test will fail only on a Pentium MMX
|
||||
// processor (with GOARCH=386 GO386=387), as it just runs
|
||||
// some code and looks for an unimplemented instruction fault.
|
||||
|
||||
//go:noinline
|
||||
func compare1(a, b float64) bool {
|
||||
return a < b
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func compare2(a, b float32) bool {
|
||||
return a < b
|
||||
}
|
||||
|
||||
func TestFloatCompare(t *testing.T) {
|
||||
if !compare1(3, 5) {
|
||||
t.Errorf("compare1 returned false")
|
||||
}
|
||||
if !compare2(3, 5) {
|
||||
t.Errorf("compare2 returned false")
|
||||
}
|
||||
}
|
||||
|
||||
// For GO386=387, make sure fucomi* opcodes are not used
|
||||
// for float->int conversions.
|
||||
|
||||
//go:noinline
|
||||
func cvt1(a float64) uint64 {
|
||||
return uint64(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt2(a float64) uint32 {
|
||||
return uint32(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt3(a float32) uint64 {
|
||||
return uint64(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt4(a float32) uint32 {
|
||||
return uint32(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt5(a float64) int64 {
|
||||
return int64(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt6(a float64) int32 {
|
||||
return int32(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt7(a float32) int64 {
|
||||
return int64(a)
|
||||
}
|
||||
|
||||
//go:noinline
|
||||
func cvt8(a float32) int32 {
|
||||
return int32(a)
|
||||
}
|
||||
|
||||
func TestFloatConvert(t *testing.T) {
|
||||
if got := cvt1(3.5); got != 3 {
|
||||
t.Errorf("cvt1 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt2(3.5); got != 3 {
|
||||
t.Errorf("cvt2 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt3(3.5); got != 3 {
|
||||
t.Errorf("cvt3 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt4(3.5); got != 3 {
|
||||
t.Errorf("cvt4 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt5(3.5); got != 3 {
|
||||
t.Errorf("cvt5 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt6(3.5); got != 3 {
|
||||
t.Errorf("cvt6 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt7(3.5); got != 3 {
|
||||
t.Errorf("cvt7 got %d, wanted 3", got)
|
||||
}
|
||||
if got := cvt8(3.5); got != 3 {
|
||||
t.Errorf("cvt8 got %d, wanted 3", got)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue