mirror of
https://github.com/golang/go
synced 2024-11-24 04:20:03 -07:00
runtime: pass windows float syscall args via XMM
Based on the calling convention documented in: https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx and long-used in golang.org/x/mobile/gl via some fixup asm: https://go.googlesource.com/mobile/+/master/gl/work_windows_amd64.s Fixes #6510 Change-Id: I97e81baaa2872bcd732b1308915eb66f1ba2168f Reviewed-on: https://go-review.googlesource.com/32173 Run-TryBot: David Crawshaw <crawshaw@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Alex Brainman <alex.brainman@gmail.com> Reviewed-by: Minux Ma <minux@golang.org>
This commit is contained in:
parent
dd500193d3
commit
9c02c75639
@ -45,6 +45,14 @@ loadregs:
|
||||
MOVQ 8(SI), DX
|
||||
MOVQ 16(SI), R8
|
||||
MOVQ 24(SI), R9
|
||||
// Floating point arguments are passed in the XMM
|
||||
// registers. Set them here in case any of the arguments
|
||||
// are floating point values. For details see
|
||||
// https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx
|
||||
MOVQ CX, X0
|
||||
MOVQ DX, X1
|
||||
MOVQ R8, X2
|
||||
MOVQ R9, X3
|
||||
|
||||
// Call stdcall function.
|
||||
CALL AX
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"internal/syscall/windows/sysdll"
|
||||
"internal/testenv"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
@ -622,6 +623,61 @@ uintptr_t cfunc(callback f, uintptr_t n) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFloatArgs(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>
|
||||
|
||||
uintptr_t cfunc(uintptr_t a, double b, float c, double d) {
|
||||
if (a == 1 && b == 2.2 && c == 3.3f && d == 4.4e44) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
`
|
||||
tmpdir, err := ioutil.TempDir("", "TestFloatArgs")
|
||||
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("cfunc")
|
||||
|
||||
r, _, err := proc.Call(
|
||||
1,
|
||||
uintptr(math.Float64bits(2.2)),
|
||||
uintptr(math.Float32bits(3.3)),
|
||||
uintptr(math.Float64bits(4.4e44)),
|
||||
)
|
||||
if r != 1 {
|
||||
t.Errorf("got %d want 1 (err=%v)", r, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTimeBeginPeriod(t *testing.T) {
|
||||
const TIMERR_NOERROR = 0
|
||||
if *runtime.TimeBeginPeriodRetValue != TIMERR_NOERROR {
|
||||
|
Loading…
Reference in New Issue
Block a user