mirror of
https://github.com/golang/go
synced 2024-11-17 12:54:47 -07:00
runtime: allow float syscall return values on windows amd64
RELNOTE=yes
Fixes #37273
Change-Id: Iedb7eab185dfeccb1b26902ef36411d2c53ea3e0
GitHub-Last-Rev: bbe30ba45d
GitHub-Pull-Request: golang/go#37380
Reviewed-on: https://go-review.googlesource.com/c/go/+/220578
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
parent
0d6b317ee6
commit
450d0b2f30
@ -62,6 +62,10 @@ loadregs:
|
||||
// Return result.
|
||||
POPQ CX
|
||||
MOVQ AX, libcall_r1(CX)
|
||||
// Floating point return values are returned in XMM0. Setting r2 to this
|
||||
// value in case this call returned a floating point value. For details,
|
||||
// see https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
|
||||
MOVQ X0, libcall_r2(CX)
|
||||
|
||||
// GetLastError().
|
||||
MOVQ 0x30(GS), DI
|
||||
|
@ -725,6 +725,82 @@ uintptr_t cfunc(uintptr_t a, double b, float c, double d) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFloatReturn(t *testing.T) {
|
||||
if _, err := exec.LookPath("gcc"); err != nil {
|
||||
t.Skip("skipping test: gcc is missing")
|
||||
}
|
||||
if runtime.GOARCH != "amd64" {
|
||||
t.Skipf("skipping test: GOARCH=%s", runtime.GOARCH)
|
||||
}
|
||||
|
||||
const src = `
|
||||
#include <stdint.h>
|
||||
#include <windows.h>
|
||||
|
||||
float cfuncFloat(uintptr_t a, double b, float c, double d) {
|
||||
if (a == 1 && b == 2.2 && c == 3.3f && d == 4.4e44) {
|
||||
return 1.5f;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
double cfuncDouble(uintptr_t a, double b, float c, double d) {
|
||||
if (a == 1 && b == 2.2 && c == 3.3f && d == 4.4e44) {
|
||||
return 2.5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
`
|
||||
tmpdir, err := ioutil.TempDir("", "TestFloatReturn")
|
||||
if err != nil {
|
||||
t.Fatal("TempDir failed: ", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpdir)
|
||||
|
||||
srcname := "mydll.c"
|
||||
err = ioutil.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
outname := "mydll.dll"
|
||||
cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", outname, srcname)
|
||||
cmd.Dir = tmpdir
|
||||
out, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
t.Fatalf("failed to build dll: %v - %v", err, string(out))
|
||||
}
|
||||
dllpath := filepath.Join(tmpdir, outname)
|
||||
|
||||
dll := syscall.MustLoadDLL(dllpath)
|
||||
defer dll.Release()
|
||||
|
||||
proc := dll.MustFindProc("cfuncFloat")
|
||||
|
||||
_, r, err := proc.Call(
|
||||
1,
|
||||
uintptr(math.Float64bits(2.2)),
|
||||
uintptr(math.Float32bits(3.3)),
|
||||
uintptr(math.Float64bits(4.4e44)),
|
||||
)
|
||||
fr := math.Float32frombits(uint32(r))
|
||||
if fr != 1.5 {
|
||||
t.Errorf("got %f want 1.5 (err=%v)", fr, err)
|
||||
}
|
||||
|
||||
proc = dll.MustFindProc("cfuncDouble")
|
||||
|
||||
_, r, err = proc.Call(
|
||||
1,
|
||||
uintptr(math.Float64bits(2.2)),
|
||||
uintptr(math.Float32bits(3.3)),
|
||||
uintptr(math.Float64bits(4.4e44)),
|
||||
)
|
||||
dr := math.Float64frombits(uint64(r))
|
||||
if dr != 2.5 {
|
||||
t.Errorf("got %f want 2.5 (err=%v)", dr, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeBeginPeriod(t *testing.T) {
|
||||
const TIMERR_NOERROR = 0
|
||||
if *runtime.TimeBeginPeriodRetValue != TIMERR_NOERROR {
|
||||
|
Loading…
Reference in New Issue
Block a user