detached c2f2945

purego: SyscallN r2 return float (#67)

* purego: SyscallN r2 return float

We originally discussed this change and decided against doing it because r2 usually returns the upper 64bits on 32bit platforms. However, on Windows amd64 r2 is actually the float return value.

https://github.com/golang/go/blob/7717ac151ae1556541dddc6a817ac04733f1af44/src/runtime/sys_windows_amd64.s#L66

And there is a TODO for arm64 as well.

https://github.com/golang/go/blob/2cea6cdb6016708e89c9472cdb0504731699681d/src/runtime/sys_windows_arm64.s#L91

Doing this makes supporting float returns easier without having to implement a full C calling convention for RegisterFunc

* Add comment describing when r2 is a float
commit
c2f2945fb3c5d7013c1f9bb4fde65685a24eafab
author
TotallyGamerJet · · 2022-11-10 19:08 UTC
committer
GitHub · · 2022-11-10 19:08 UTC
parent
54b6cdc
signature
GPG Unverified4AEE18F83AFDEB23 The key is unknown
3 files · +11 -6
M func_darwin.go +6 -1
@@ -4,6 +4,7 @@
44 package purego
55
66 import (
7+ "math"
78 "reflect"
89 "runtime"
910 "unsafe"
@@ -110,7 +111,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
110111 panic("purego: unsupported kind: " + v.Kind().String())
111112 }
112113 }
113- r1, _, _ := SyscallN(cfn, sysargs...) //TODO: handle float32/64 and struct types
114+ r1, r2, _ := SyscallN(cfn, sysargs...) //TODO: handle float32/64 and struct types
114115 if ty.NumOut() == 0 {
115116 return nil
116117 }
@@ -134,6 +135,10 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
134135 RegisterFunc(v.Interface(), r1)
135136 case reflect.String:
136137 v.SetString(strings.GoString(r1))
138+ case reflect.Float32, reflect.Float64:
139+ // NOTE: r2 is only the floating return value on 64bit platforms.
140+ // On 32bit platforms r2 is the upper part of a 64bit return.
141+ v.SetFloat(math.Float64frombits(uint64(r2)))
137142 default:
138143 panic("purego: unsupported return kind: " + outType.Kind().String())
139144 }
@@ -4,6 +4,7 @@
4 package purego4 package purego
5 5
6 import (6 import (
7+ "math"
7 "reflect"8 "reflect"
8 "runtime"9 "runtime"
9 "unsafe"10 "unsafe"
@@ -110,7 +111,7 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
110 panic("purego: unsupported kind: " + v.Kind().String())111 panic("purego: unsupported kind: " + v.Kind().String())
111 }112 }
112 }113 }
113- r1, _, _ := SyscallN(cfn, sysargs...) //TODO: handle float32/64 and struct types114+ r1, r2, _ := SyscallN(cfn, sysargs...) //TODO: handle float32/64 and struct types
114 if ty.NumOut() == 0 {115 if ty.NumOut() == 0 {
115 return nil116 return nil
116 }117 }
@@ -134,6 +135,10 @@ func RegisterFunc(fptr interface{}, cfn uintptr) {
134 RegisterFunc(v.Interface(), r1)135 RegisterFunc(v.Interface(), r1)
135 case reflect.String:136 case reflect.String:
136 v.SetString(strings.GoString(r1))137 v.SetString(strings.GoString(r1))
138+ case reflect.Float32, reflect.Float64:
139+ // NOTE: r2 is only the floating return value on 64bit platforms.
140+ // On 32bit platforms r2 is the upper part of a 64bit return.
141+ v.SetFloat(math.Float64frombits(uint64(r2)))
137 default:142 default:
138 panic("purego: unsupported return kind: " + outType.Kind().String())143 panic("purego: unsupported return kind: " + outType.Kind().String())
139 }144 }
M sys_darwin_amd64.s +1 -1
@@ -64,7 +64,7 @@ TEXT syscall9X(SB), NOSPLIT, $0
6464
6565 MOVQ 24(BP), DI // get the pointer back
6666 MOVQ AX, syscall9Args_r1(DI) // r1
67- MOVQ DX, syscall9Args_r2(DI) // r2
67+ MOVQ X0, syscall9Args_r2(DI) // r2
6868
6969 XORL AX, AX // no error (it's ignored anyway)
7070 ADDQ $32, SP
@@ -64,7 +64,7 @@ TEXT syscall9X(SB), NOSPLIT, $0
64 64
65 MOVQ 24(BP), DI // get the pointer back65 MOVQ 24(BP), DI // get the pointer back
66 MOVQ AX, syscall9Args_r1(DI) // r166 MOVQ AX, syscall9Args_r1(DI) // r1
67- MOVQ DX, syscall9Args_r2(DI) // r267+ MOVQ X0, syscall9Args_r2(DI) // r2
68 68
69 XORL AX, AX // no error (it's ignored anyway)69 XORL AX, AX // no error (it's ignored anyway)
70 ADDQ $32, SP70 ADDQ $32, SP
M sys_darwin_arm64.s +4 -4
@@ -57,10 +57,10 @@ TEXT syscall9X(SB), NOSPLIT, $0
5757
5858 BL (R12)
5959
60- MOVD 8(RSP), R2 // pop structure pointer
61- ADD $16, RSP
62- MOVD R0, syscall9Args_r1(R2) // save r1
63- MOVD R1, syscall9Args_r2(R2) // save r2
60+ MOVD 8(RSP), R2 // pop structure pointer
61+ ADD $16, RSP
62+ MOVD R0, syscall9Args_r1(R2) // save r1
63+ FMOVD F0, syscall9Args_r2(R2) // save r2
6464 RET
6565
6666 // runtime·cgocallback expects a call to the ABIInternal function
@@ -57,10 +57,10 @@ TEXT syscall9X(SB), NOSPLIT, $0
57 57
58 BL (R12)58 BL (R12)
59 59
60- MOVD 8(RSP), R2 // pop structure pointer60+ MOVD 8(RSP), R2 // pop structure pointer
61- ADD $16, RSP61+ ADD $16, RSP
62- MOVD R0, syscall9Args_r1(R2) // save r162+ MOVD R0, syscall9Args_r1(R2) // save r1
63- MOVD R1, syscall9Args_r2(R2) // save r263+ FMOVD F0, syscall9Args_r2(R2) // save r2
64 RET64 RET
65 65
66 // runtime·cgocallback expects a call to the ABIInternal function66 // runtime·cgocallback expects a call to the ABIInternal function

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close