purego: support 32 arguments on 64bit (#431)
Closes #425
- commit
- fa49e74b0075772005ad4360f34107c6ff90fb50
- author
- Travis Cline · · 2026-04-30 03:18 UTC
- committer
- GitHub · · 2026-04-30 03:18 UTC
- parent
- 56b2dd8
- signature
- GPG Unverified
B5690EEEBB952194The key is unknown - refs
- tag: v0.11.0-alpha.2
31 files · +992 -580
A cdecl.go +11 -0
| @@ -0,0 +1,11 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | package purego | |
| 5 | + | ||
| 6 | + | // CDecl marks a function as being called using the __cdecl calling convention as defined in | |
| 7 | + | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | |
| 8 | + | // This is only useful on 386 Windows, but it is safe to use on other platforms. | |
| 9 | + | // | |
| 10 | + | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |
| 11 | + | type CDecl struct{} | |
| @@ -0,0 +1,11 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | package purego | |||
| 5 | + | ||||
| 6 | + | // CDecl marks a function as being called using the __cdecl calling convention as defined in | |||
| 7 | + | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | |||
| 8 | + | // This is only useful on 386 Windows, but it is safe to use on other platforms. | |||
| 9 | + | // | |||
| 10 | + | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |||
| 11 | + | type CDecl struct{} | |||
M func.go +25 -23
| @@ -23,7 +23,7 @@ const ( | |||
| 23 | 23 | ) | |
| 24 | 24 | ||
| 25 | 25 | var thePool = sync.Pool{New: func() any { | |
| 26 | - | return new(syscall15Args) | |
| 26 | + | return new(syscallArgs) | |
| 27 | 27 | }} | |
| 28 | 28 | ||
| 29 | 29 | // RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name). | |
| @@ -141,6 +141,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 141 | 141 | // to avoid crashing with too many arguments | |
| 142 | 142 | var ints int | |
| 143 | 143 | var floats int | |
| 144 | + | floatArgRegs := numOfFloatRegisters() | |
| 144 | 145 | var stack int | |
| 145 | 146 | for i := 0; i < ty.NumIn(); i++ { | |
| 146 | 147 | arg := ty.In(i) | |
| @@ -167,7 +168,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 167 | 168 | stack++ | |
| 168 | 169 | } | |
| 169 | 170 | case reflect.Float32, reflect.Float64: | |
| 170 | - | if floats < numOfFloatRegisters() { | |
| 171 | + | if floats < floatArgRegs { | |
| 171 | 172 | floats++ | |
| 172 | 173 | } else { | |
| 173 | 174 | stack++ | |
| @@ -202,10 +203,15 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 202 | 203 | } | |
| 203 | 204 | } | |
| 204 | 205 | ||
| 205 | - | sizeOfStack := maxArgs - numOfIntegerRegisters() | |
| 206 | - | // On Darwin ARM64, use byte-based validation since arguments pack efficiently. | |
| 207 | - | // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms | |
| 208 | - | if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { | |
| 206 | + | argsLimit := maxArgs | |
| 207 | + | sizeOfStack := argsLimit - numOfIntegerRegisters() | |
| 208 | + | if runtime.GOOS == "windows" { | |
| 209 | + | if ints+floats+stack > argsLimit { | |
| 210 | + | panic("purego: too many stack arguments") | |
| 211 | + | } | |
| 212 | + | } else if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { | |
| 213 | + | // On Darwin ARM64, use byte-based validation since arguments pack efficiently. | |
| 214 | + | // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms | |
| 209 | 215 | stackBytes := estimateStackBytes(ty) | |
| 210 | 216 | maxStackBytes := sizeOfStack * 8 | |
| 211 | 217 | if stackBytes > maxStackBytes { | |
| @@ -224,6 +230,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 224 | 230 | // since numOfFloatRegisters() is a function call, not a constant. | |
| 225 | 231 | // maxArgs is always greater than or equal to numOfFloatRegisters() so this is safe. | |
| 226 | 232 | var floats [maxArgs]uintptr | |
| 233 | + | floatArgRegs := numOfFloatRegisters() | |
| 227 | 234 | var numInts int | |
| 228 | 235 | var numFloats int | |
| 229 | 236 | var numStack int | |
| @@ -243,7 +250,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 243 | 250 | } | |
| 244 | 251 | } | |
| 245 | 252 | addFloat = func(x uintptr) { | |
| 246 | - | if numFloats < numOfFloatRegisters() { | |
| 253 | + | if numFloats < floatArgRegs { | |
| 247 | 254 | floats[numFloats] = x | |
| 248 | 255 | numFloats++ | |
| 249 | 256 | } else { | |
| @@ -257,6 +264,9 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 257 | 264 | // This is in contrast to how macOS and Linux pass arguments which | |
| 258 | 265 | // tries to use as many registers as possible in the calling convention. | |
| 259 | 266 | addStack = func(x uintptr) { | |
| 267 | + | if numStack >= maxArgs { | |
| 268 | + | panic("purego: too many stack arguments") | |
| 269 | + | } | |
| 260 | 270 | sysargs[numStack] = x | |
| 261 | 271 | numStack++ | |
| 262 | 272 | } | |
| @@ -310,24 +320,16 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||
| 310 | 320 | keepAlive = addValue(v, keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack) | |
| 311 | 321 | } | |
| 312 | 322 | ||
| 313 | - | syscall := thePool.Get().(*syscall15Args) | |
| 314 | - | defer thePool.Put(syscall) | |
| 315 | - | ||
| 316 | - | if runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x" { | |
| 317 | - | syscall.Set(cfn, sysargs[:], floats[:], 0) | |
| 318 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall)) | |
| 319 | - | } else if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" { | |
| 320 | - | // Use the normal arm64 calling convention even on Windows | |
| 321 | - | syscall.Set(cfn, sysargs[:], floats[:], arm64_r8) | |
| 322 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall)) | |
| 323 | - | } else { | |
| 324 | - | *syscall = syscall15Args{} | |
| 325 | - | // This is a fallback for Windows amd64, 386, and arm. Note this may not support floats | |
| 326 | - | syscall.a1, syscall.a2, _ = syscall_syscall15X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], | |
| 327 | - | sysargs[5], sysargs[6], sysargs[7], sysargs[8], sysargs[9], sysargs[10], sysargs[11], | |
| 328 | - | sysargs[12], sysargs[13], sysargs[14]) | |
| 323 | + | var syscall *syscallArgs | |
| 324 | + | if runtime.GOOS == "windows" && runtime.GOARCH != "arm64" { | |
| 325 | + | // Windows amd64, 386, and arm use syscall.SyscallN. | |
| 326 | + | syscall = thePool.Get().(*syscallArgs) | |
| 327 | + | syscall.a1, syscall.a2, _ = syscall_syscallN(cfn, sysargs[:numStack]...) | |
| 329 | 328 | syscall.f1 = syscall.a2 // on amd64 a2 stores the float return. On 32bit platforms floats aren't support | |
| 329 | + | } else { | |
| 330 | + | syscall = syscall_SyscallN(cfn, sysargs[:], floats[:], arm64_r8) | |
| 330 | 331 | } | |
| 332 | + | defer thePool.Put(syscall) | |
| 331 | 333 | if ty.NumOut() == 0 { | |
| 332 | 334 | return nil | |
| 333 | 335 | } | |
| @@ -23,7 +23,7 @@ const ( | |||||
| 23 | ) | 23 | ) | ||
| 24 | 24 | ||||
| 25 | var thePool = sync.Pool{New: func() any { | 25 | var thePool = sync.Pool{New: func() any { | ||
| 26 | - | return new(syscall15Args) | 26 | + | return new(syscallArgs) |
| 27 | }} | 27 | }} | ||
| 28 | 28 | ||||
| 29 | // RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name). | 29 | // RegisterLibFunc is a wrapper around RegisterFunc that uses the C function returned from Dlsym(handle, name). | ||
| @@ -141,6 +141,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 141 | // to avoid crashing with too many arguments | 141 | // to avoid crashing with too many arguments | ||
| 142 | var ints int | 142 | var ints int | ||
| 143 | var floats int | 143 | var floats int | ||
| 144 | + | floatArgRegs := numOfFloatRegisters() | |||
| 144 | var stack int | 145 | var stack int | ||
| 145 | for i := 0; i < ty.NumIn(); i++ { | 146 | for i := 0; i < ty.NumIn(); i++ { | ||
| 146 | arg := ty.In(i) | 147 | arg := ty.In(i) | ||
| @@ -167,7 +168,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 167 | stack++ | 168 | stack++ | ||
| 168 | } | 169 | } | ||
| 169 | case reflect.Float32, reflect.Float64: | 170 | case reflect.Float32, reflect.Float64: | ||
| 170 | - | if floats < numOfFloatRegisters() { | 171 | + | if floats < floatArgRegs { |
| 171 | floats++ | 172 | floats++ | ||
| 172 | } else { | 173 | } else { | ||
| 173 | stack++ | 174 | stack++ | ||
| @@ -202,10 +203,15 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 202 | } | 203 | } | ||
| 203 | } | 204 | } | ||
| 204 | 205 | ||||
| 205 | - | sizeOfStack := maxArgs - numOfIntegerRegisters() | 206 | + | argsLimit := maxArgs |
| 206 | - | // On Darwin ARM64, use byte-based validation since arguments pack efficiently. | 207 | + | sizeOfStack := argsLimit - numOfIntegerRegisters() |
| 207 | - | // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms | 208 | + | if runtime.GOOS == "windows" { |
| 208 | - | if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { | 209 | + | if ints+floats+stack > argsLimit { |
| 210 | + | panic("purego: too many stack arguments") | |||
| 211 | + | } | |||
| 212 | + | } else if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" { | |||
| 213 | + | // On Darwin ARM64, use byte-based validation since arguments pack efficiently. | |||
| 214 | + | // See https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms | |||
| 209 | stackBytes := estimateStackBytes(ty) | 215 | stackBytes := estimateStackBytes(ty) | ||
| 210 | maxStackBytes := sizeOfStack * 8 | 216 | maxStackBytes := sizeOfStack * 8 | ||
| 211 | if stackBytes > maxStackBytes { | 217 | if stackBytes > maxStackBytes { | ||
| @@ -224,6 +230,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 224 | // since numOfFloatRegisters() is a function call, not a constant. | 230 | // since numOfFloatRegisters() is a function call, not a constant. | ||
| 225 | // maxArgs is always greater than or equal to numOfFloatRegisters() so this is safe. | 231 | // maxArgs is always greater than or equal to numOfFloatRegisters() so this is safe. | ||
| 226 | var floats [maxArgs]uintptr | 232 | var floats [maxArgs]uintptr | ||
| 233 | + | floatArgRegs := numOfFloatRegisters() | |||
| 227 | var numInts int | 234 | var numInts int | ||
| 228 | var numFloats int | 235 | var numFloats int | ||
| 229 | var numStack int | 236 | var numStack int | ||
| @@ -243,7 +250,7 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 243 | } | 250 | } | ||
| 244 | } | 251 | } | ||
| 245 | addFloat = func(x uintptr) { | 252 | addFloat = func(x uintptr) { | ||
| 246 | - | if numFloats < numOfFloatRegisters() { | 253 | + | if numFloats < floatArgRegs { |
| 247 | floats[numFloats] = x | 254 | floats[numFloats] = x | ||
| 248 | numFloats++ | 255 | numFloats++ | ||
| 249 | } else { | 256 | } else { | ||
| @@ -257,6 +264,9 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 257 | // This is in contrast to how macOS and Linux pass arguments which | 264 | // This is in contrast to how macOS and Linux pass arguments which | ||
| 258 | // tries to use as many registers as possible in the calling convention. | 265 | // tries to use as many registers as possible in the calling convention. | ||
| 259 | addStack = func(x uintptr) { | 266 | addStack = func(x uintptr) { | ||
| 267 | + | if numStack >= maxArgs { | |||
| 268 | + | panic("purego: too many stack arguments") | |||
| 269 | + | } | |||
| 260 | sysargs[numStack] = x | 270 | sysargs[numStack] = x | ||
| 261 | numStack++ | 271 | numStack++ | ||
| 262 | } | 272 | } | ||
| @@ -310,24 +320,16 @@ func RegisterFunc(fptr any, cfn uintptr) { | |||||
| 310 | keepAlive = addValue(v, keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack) | 320 | keepAlive = addValue(v, keepAlive, addInt, addFloat, addStack, &numInts, &numFloats, &numStack) | ||
| 311 | } | 321 | } | ||
| 312 | 322 | ||||
| 313 | - | syscall := thePool.Get().(*syscall15Args) | 323 | + | var syscall *syscallArgs |
| 314 | - | defer thePool.Put(syscall) | 324 | + | if runtime.GOOS == "windows" && runtime.GOARCH != "arm64" { |
| 315 | - | 325 | + | // Windows amd64, 386, and arm use syscall.SyscallN. | |
| 316 | - | if runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x" { | 326 | + | syscall = thePool.Get().(*syscallArgs) |
| 317 | - | syscall.Set(cfn, sysargs[:], floats[:], 0) | 327 | + | syscall.a1, syscall.a2, _ = syscall_syscallN(cfn, sysargs[:numStack]...) |
| 318 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall)) | |||
| 319 | - | } else if runtime.GOARCH == "arm64" || runtime.GOOS != "windows" { | |||
| 320 | - | // Use the normal arm64 calling convention even on Windows | |||
| 321 | - | syscall.Set(cfn, sysargs[:], floats[:], arm64_r8) | |||
| 322 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(syscall)) | |||
| 323 | - | } else { | |||
| 324 | - | *syscall = syscall15Args{} | |||
| 325 | - | // This is a fallback for Windows amd64, 386, and arm. Note this may not support floats | |||
| 326 | - | syscall.a1, syscall.a2, _ = syscall_syscall15X(cfn, sysargs[0], sysargs[1], sysargs[2], sysargs[3], sysargs[4], | |||
| 327 | - | sysargs[5], sysargs[6], sysargs[7], sysargs[8], sysargs[9], sysargs[10], sysargs[11], | |||
| 328 | - | sysargs[12], sysargs[13], sysargs[14]) | |||
| 329 | syscall.f1 = syscall.a2 // on amd64 a2 stores the float return. On 32bit platforms floats aren't support | 328 | syscall.f1 = syscall.a2 // on amd64 a2 stores the float return. On 32bit platforms floats aren't support | ||
| 329 | + | } else { | |||
| 330 | + | syscall = syscall_SyscallN(cfn, sysargs[:], floats[:], arm64_r8) | |||
| 330 | } | 331 | } | ||
| 332 | + | defer thePool.Put(syscall) | |||
| 331 | if ty.NumOut() == 0 { | 333 | if ty.NumOut() == 0 { | ||
| 332 | return nil | 334 | return nil | ||
| 333 | } | 335 | } | ||
M func_test.go +161 -26
| @@ -373,8 +373,8 @@ func TestABI_ArgumentPassing(t *testing.T) { | |||
| 373 | 373 | ||
| 374 | 374 | for _, tt := range tests { | |
| 375 | 375 | t.Run(tt.name, func(t *testing.T) { | |
| 376 | - | if tt.name == "20_int32" && (runtime.GOOS != "darwin" || runtime.GOARCH != "arm64") { | |
| 377 | - | t.Skip("20 int32 arguments only supported on Darwin ARM64 with smart stack checking") | |
| 376 | + | if tt.name == "20_int32" && runtime.GOARCH == "ppc64le" { | |
| 377 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 378 | 378 | } | |
| 379 | 379 | if tt.name == "10_float32" && (runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") { | |
| 380 | 380 | t.Skip("float32 stack arguments not yet supported on this platform") | |
| @@ -394,39 +394,174 @@ func TestABI_ArgumentPassing(t *testing.T) { | |||
| 394 | 394 | } | |
| 395 | 395 | }) | |
| 396 | 396 | } | |
| 397 | - | } | |
| 398 | 397 | ||
| 399 | - | func TestABI_TooManyArguments(t *testing.T) { | |
| 400 | - | if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" { | |
| 401 | - | t.Skip("This test is specific to Darwin ARM64") | |
| 402 | - | } | |
| 398 | + | t.Run("20_uintptr", func(t *testing.T) { | |
| 399 | + | if runtime.GOARCH == "ppc64le" { | |
| 400 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 401 | + | } | |
| 402 | + | var fn func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) uintptr | |
| 403 | + | purego.RegisterLibFunc(&fn, lib, "stack_20_uintptr") | |
| 404 | + | got := fn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) | |
| 405 | + | const want = uintptr(210) | |
| 406 | + | if got != want { | |
| 407 | + | t.Fatalf("stack_20_uintptr: got %d, want %d", got, want) | |
| 408 | + | } | |
| 409 | + | }) | |
| 403 | 410 | ||
| 404 | - | libFileName := filepath.Join(t.TempDir(), "abitest.so") | |
| 405 | - | if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { | |
| 406 | - | t.Fatal(err) | |
| 407 | - | } | |
| 408 | - | lib, err := load.OpenLibrary(libFileName) | |
| 409 | - | if err != nil { | |
| 410 | - | t.Fatalf("Failed to open library %q: %v", libFileName, err) | |
| 411 | - | } | |
| 412 | - | t.Cleanup(func() { | |
| 413 | - | if err := load.CloseLibrary(lib); err != nil { | |
| 414 | - | t.Errorf("Failed to close library: %v", err) | |
| 411 | + | t.Run("32_uintptr", func(t *testing.T) { | |
| 412 | + | if runtime.GOARCH == "ppc64le" { | |
| 413 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 414 | + | } | |
| 415 | + | var fn func( | |
| 416 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 417 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 418 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 419 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 420 | + | ) uintptr | |
| 421 | + | purego.RegisterLibFunc(&fn, lib, "stack_32_uintptr") | |
| 422 | + | got := fn( | |
| 423 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 424 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 425 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |
| 426 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |
| 427 | + | ) | |
| 428 | + | const want = uintptr(528) | |
| 429 | + | if got != want { | |
| 430 | + | t.Fatalf("stack_32_uintptr: got %d, want %d", got, want) | |
| 431 | + | } | |
| 432 | + | }) | |
| 433 | + | ||
| 434 | + | t.Run("syscalln_20_uintptr", func(t *testing.T) { | |
| 435 | + | if runtime.GOARCH == "ppc64le" { | |
| 436 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 437 | + | } | |
| 438 | + | fn, err := load.OpenSymbol(lib, "stack_20_uintptr") | |
| 439 | + | if err != nil { | |
| 440 | + | t.Fatalf("OpenSymbol(stack_20_uintptr) failed: %v", err) | |
| 441 | + | } | |
| 442 | + | got, _, _ := purego.SyscallN(fn, | |
| 443 | + | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, | |
| 444 | + | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |
| 445 | + | ) | |
| 446 | + | const want = uintptr(210) | |
| 447 | + | if got != want { | |
| 448 | + | t.Fatalf("stack_20_uintptr SyscallN: got %d, want %d", got, want) | |
| 449 | + | } | |
| 450 | + | }) | |
| 451 | + | ||
| 452 | + | t.Run("syscalln_32_uintptr", func(t *testing.T) { | |
| 453 | + | if runtime.GOARCH == "ppc64le" { | |
| 454 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 455 | + | } | |
| 456 | + | fn, err := load.OpenSymbol(lib, "stack_32_uintptr") | |
| 457 | + | if err != nil { | |
| 458 | + | t.Fatalf("OpenSymbol(stack_32_uintptr) failed: %v", err) | |
| 459 | + | } | |
| 460 | + | got, _, _ := purego.SyscallN(fn, | |
| 461 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 462 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 463 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |
| 464 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |
| 465 | + | ) | |
| 466 | + | const want = uintptr(528) | |
| 467 | + | if got != want { | |
| 468 | + | t.Fatalf("stack_32_uintptr SyscallN: got %d, want %d", got, want) | |
| 469 | + | } | |
| 470 | + | }) | |
| 471 | + | ||
| 472 | + | t.Run("32_mixed_int_float", func(t *testing.T) { | |
| 473 | + | if unsafe.Sizeof(uintptr(0)) == 4 { | |
| 474 | + | t.Skip("requires 64-bit uintptr slots") | |
| 475 | + | } | |
| 476 | + | if runtime.GOARCH == "ppc64le" { | |
| 477 | + | t.Skip("mixed int/float stack arguments are not yet supported on ppc64le") | |
| 478 | + | } | |
| 479 | + | ||
| 480 | + | var fn func( | |
| 481 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 482 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |
| 483 | + | float64, float64, float64, float64, float64, float64, float64, float64, | |
| 484 | + | float64, float64, float64, float64, float64, float64, float64, float64, | |
| 485 | + | ) float64 | |
| 486 | + | purego.RegisterLibFunc(&fn, lib, "stack_32_mixed_int_float") | |
| 487 | + | got := fn( | |
| 488 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 489 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 490 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 491 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 492 | + | ) | |
| 493 | + | const want = 5168.0 | |
| 494 | + | if got != want { | |
| 495 | + | t.Fatalf("stack_32_mixed_int_float: got %f, want %f", got, want) | |
| 415 | 496 | } | |
| 416 | 497 | }) | |
| 498 | + | } | |
| 417 | 499 | ||
| 418 | - | // Test that 35 int64 arguments (27 slots needed) exceeds the limit | |
| 419 | - | t.Run("35_int64_exceeds_limit", func(t *testing.T) { | |
| 500 | + | func TestABI_TooManyArguments(t *testing.T) { | |
| 501 | + | mustPanic := func(t *testing.T, want string, f func()) { | |
| 502 | + | t.Helper() | |
| 420 | 503 | defer func() { | |
| 421 | - | if r := recover(); r != nil { | |
| 422 | - | t.Logf("Got expected panic: %v", r) | |
| 423 | - | } else { | |
| 424 | - | t.Errorf("Expected panic but didn't get one") | |
| 504 | + | r := recover() | |
| 505 | + | if r == nil { | |
| 506 | + | t.Fatalf("expected panic %q, got none", want) | |
| 507 | + | } | |
| 508 | + | got := fmt.Sprint(r) | |
| 509 | + | if got != want { | |
| 510 | + | t.Fatalf("panic mismatch:\n got: %q\n want: %q", got, want) | |
| 425 | 511 | } | |
| 426 | 512 | }() | |
| 513 | + | f() | |
| 514 | + | } | |
| 515 | + | ||
| 516 | + | // 33 int64 parameters exceeds maxArgs=32. | |
| 517 | + | t.Run("registerfunc_33_int64_exceeds_limit", func(t *testing.T) { | |
| 518 | + | mustPanic(t, "purego: too many stack arguments", func() { | |
| 519 | + | var fn func( | |
| 520 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 521 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 522 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 523 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 524 | + | int64, | |
| 525 | + | ) | |
| 526 | + | purego.RegisterFunc(&fn, 1) | |
| 527 | + | }) | |
| 528 | + | }) | |
| 427 | 529 | ||
| 428 | - | var fn func(*byte, uintptr, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64) | |
| 429 | - | purego.RegisterLibFunc(&fn, lib, "stack_35_int64_exceeds") | |
| 530 | + | t.Run("registerfunc_16_int64_exceeds_ppc64le_limit", func(t *testing.T) { | |
| 531 | + | if runtime.GOARCH != "ppc64le" { | |
| 532 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 533 | + | } | |
| 534 | + | mustPanic(t, "purego: too many stack arguments", func() { | |
| 535 | + | var fn func( | |
| 536 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 537 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |
| 538 | + | ) | |
| 539 | + | purego.RegisterFunc(&fn, 1) | |
| 540 | + | }) | |
| 541 | + | }) | |
| 542 | + | ||
| 543 | + | t.Run("syscalln_33_uintptr_exceeds_limit", func(t *testing.T) { | |
| 544 | + | mustPanic(t, "purego: too many arguments to SyscallN", func() { | |
| 545 | + | purego.SyscallN(1, | |
| 546 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 547 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 548 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |
| 549 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |
| 550 | + | 33, | |
| 551 | + | ) | |
| 552 | + | }) | |
| 553 | + | }) | |
| 554 | + | ||
| 555 | + | t.Run("syscalln_16_uintptr_exceeds_ppc64le_limit", func(t *testing.T) { | |
| 556 | + | if runtime.GOARCH != "ppc64le" { | |
| 557 | + | t.Skip("ppc64le retains the 15-argument limit") | |
| 558 | + | } | |
| 559 | + | mustPanic(t, "purego: too many arguments to SyscallN", func() { | |
| 560 | + | purego.SyscallN(1, | |
| 561 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |
| 562 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |
| 563 | + | ) | |
| 564 | + | }) | |
| 430 | 565 | }) | |
| 431 | 566 | } | |
| 432 | 567 | ||
| @@ -373,8 +373,8 @@ func TestABI_ArgumentPassing(t *testing.T) { | |||||
| 373 | 373 | ||||
| 374 | for _, tt := range tests { | 374 | for _, tt := range tests { | ||
| 375 | t.Run(tt.name, func(t *testing.T) { | 375 | t.Run(tt.name, func(t *testing.T) { | ||
| 376 | - | if tt.name == "20_int32" && (runtime.GOOS != "darwin" || runtime.GOARCH != "arm64") { | 376 | + | if tt.name == "20_int32" && runtime.GOARCH == "ppc64le" { |
| 377 | - | t.Skip("20 int32 arguments only supported on Darwin ARM64 with smart stack checking") | 377 | + | t.Skip("ppc64le retains the 15-argument limit") |
| 378 | } | 378 | } | ||
| 379 | if tt.name == "10_float32" && (runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") { | 379 | if tt.name == "10_float32" && (runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") { | ||
| 380 | t.Skip("float32 stack arguments not yet supported on this platform") | 380 | t.Skip("float32 stack arguments not yet supported on this platform") | ||
| @@ -394,39 +394,174 @@ func TestABI_ArgumentPassing(t *testing.T) { | |||||
| 394 | } | 394 | } | ||
| 395 | }) | 395 | }) | ||
| 396 | } | 396 | } | ||
| 397 | - | } | |||
| 398 | 397 | ||||
| 399 | - | func TestABI_TooManyArguments(t *testing.T) { | 398 | + | t.Run("20_uintptr", func(t *testing.T) { |
| 400 | - | if runtime.GOOS != "darwin" || runtime.GOARCH != "arm64" { | 399 | + | if runtime.GOARCH == "ppc64le" { |
| 401 | - | t.Skip("This test is specific to Darwin ARM64") | 400 | + | t.Skip("ppc64le retains the 15-argument limit") |
| 402 | - | } | 401 | + | } |
| 402 | + | var fn func(uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr) uintptr | |||
| 403 | + | purego.RegisterLibFunc(&fn, lib, "stack_20_uintptr") | |||
| 404 | + | got := fn(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) | |||
| 405 | + | const want = uintptr(210) | |||
| 406 | + | if got != want { | |||
| 407 | + | t.Fatalf("stack_20_uintptr: got %d, want %d", got, want) | |||
| 408 | + | } | |||
| 409 | + | }) | |||
| 403 | 410 | ||||
| 404 | - | libFileName := filepath.Join(t.TempDir(), "abitest.so") | 411 | + | t.Run("32_uintptr", func(t *testing.T) { |
| 405 | - | if err := buildSharedLib("CC", libFileName, filepath.Join("testdata", "abitest", "abi_test.c")); err != nil { | 412 | + | if runtime.GOARCH == "ppc64le" { |
| 406 | - | t.Fatal(err) | 413 | + | t.Skip("ppc64le retains the 15-argument limit") |
| 407 | - | } | 414 | + | } |
| 408 | - | lib, err := load.OpenLibrary(libFileName) | 415 | + | var fn func( |
| 409 | - | if err != nil { | 416 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, |
| 410 | - | t.Fatalf("Failed to open library %q: %v", libFileName, err) | 417 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, |
| 411 | - | } | 418 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, |
| 412 | - | t.Cleanup(func() { | 419 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, |
| 413 | - | if err := load.CloseLibrary(lib); err != nil { | 420 | + | ) uintptr |
| 414 | - | t.Errorf("Failed to close library: %v", err) | 421 | + | purego.RegisterLibFunc(&fn, lib, "stack_32_uintptr") |
| 422 | + | got := fn( | |||
| 423 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 424 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 425 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |||
| 426 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |||
| 427 | + | ) | |||
| 428 | + | const want = uintptr(528) | |||
| 429 | + | if got != want { | |||
| 430 | + | t.Fatalf("stack_32_uintptr: got %d, want %d", got, want) | |||
| 431 | + | } | |||
| 432 | + | }) | |||
| 433 | + | ||||
| 434 | + | t.Run("syscalln_20_uintptr", func(t *testing.T) { | |||
| 435 | + | if runtime.GOARCH == "ppc64le" { | |||
| 436 | + | t.Skip("ppc64le retains the 15-argument limit") | |||
| 437 | + | } | |||
| 438 | + | fn, err := load.OpenSymbol(lib, "stack_20_uintptr") | |||
| 439 | + | if err != nil { | |||
| 440 | + | t.Fatalf("OpenSymbol(stack_20_uintptr) failed: %v", err) | |||
| 441 | + | } | |||
| 442 | + | got, _, _ := purego.SyscallN(fn, | |||
| 443 | + | 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, | |||
| 444 | + | 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, | |||
| 445 | + | ) | |||
| 446 | + | const want = uintptr(210) | |||
| 447 | + | if got != want { | |||
| 448 | + | t.Fatalf("stack_20_uintptr SyscallN: got %d, want %d", got, want) | |||
| 449 | + | } | |||
| 450 | + | }) | |||
| 451 | + | ||||
| 452 | + | t.Run("syscalln_32_uintptr", func(t *testing.T) { | |||
| 453 | + | if runtime.GOARCH == "ppc64le" { | |||
| 454 | + | t.Skip("ppc64le retains the 15-argument limit") | |||
| 455 | + | } | |||
| 456 | + | fn, err := load.OpenSymbol(lib, "stack_32_uintptr") | |||
| 457 | + | if err != nil { | |||
| 458 | + | t.Fatalf("OpenSymbol(stack_32_uintptr) failed: %v", err) | |||
| 459 | + | } | |||
| 460 | + | got, _, _ := purego.SyscallN(fn, | |||
| 461 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 462 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 463 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |||
| 464 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |||
| 465 | + | ) | |||
| 466 | + | const want = uintptr(528) | |||
| 467 | + | if got != want { | |||
| 468 | + | t.Fatalf("stack_32_uintptr SyscallN: got %d, want %d", got, want) | |||
| 469 | + | } | |||
| 470 | + | }) | |||
| 471 | + | ||||
| 472 | + | t.Run("32_mixed_int_float", func(t *testing.T) { | |||
| 473 | + | if unsafe.Sizeof(uintptr(0)) == 4 { | |||
| 474 | + | t.Skip("requires 64-bit uintptr slots") | |||
| 475 | + | } | |||
| 476 | + | if runtime.GOARCH == "ppc64le" { | |||
| 477 | + | t.Skip("mixed int/float stack arguments are not yet supported on ppc64le") | |||
| 478 | + | } | |||
| 479 | + | ||||
| 480 | + | var fn func( | |||
| 481 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |||
| 482 | + | uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, uintptr, | |||
| 483 | + | float64, float64, float64, float64, float64, float64, float64, float64, | |||
| 484 | + | float64, float64, float64, float64, float64, float64, float64, float64, | |||
| 485 | + | ) float64 | |||
| 486 | + | purego.RegisterLibFunc(&fn, lib, "stack_32_mixed_int_float") | |||
| 487 | + | got := fn( | |||
| 488 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 489 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 490 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 491 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 492 | + | ) | |||
| 493 | + | const want = 5168.0 | |||
| 494 | + | if got != want { | |||
| 495 | + | t.Fatalf("stack_32_mixed_int_float: got %f, want %f", got, want) | |||
| 415 | } | 496 | } | ||
| 416 | }) | 497 | }) | ||
| 498 | + | } | |||
| 417 | 499 | ||||
| 418 | - | // Test that 35 int64 arguments (27 slots needed) exceeds the limit | 500 | + | func TestABI_TooManyArguments(t *testing.T) { |
| 419 | - | t.Run("35_int64_exceeds_limit", func(t *testing.T) { | 501 | + | mustPanic := func(t *testing.T, want string, f func()) { |
| 502 | + | t.Helper() | |||
| 420 | defer func() { | 503 | defer func() { | ||
| 421 | - | if r := recover(); r != nil { | 504 | + | r := recover() |
| 422 | - | t.Logf("Got expected panic: %v", r) | 505 | + | if r == nil { |
| 423 | - | } else { | 506 | + | t.Fatalf("expected panic %q, got none", want) |
| 424 | - | t.Errorf("Expected panic but didn't get one") | 507 | + | } |
| 508 | + | got := fmt.Sprint(r) | |||
| 509 | + | if got != want { | |||
| 510 | + | t.Fatalf("panic mismatch:\n got: %q\n want: %q", got, want) | |||
| 425 | } | 511 | } | ||
| 426 | }() | 512 | }() | ||
| 513 | + | f() | |||
| 514 | + | } | |||
| 515 | + | ||||
| 516 | + | // 33 int64 parameters exceeds maxArgs=32. | |||
| 517 | + | t.Run("registerfunc_33_int64_exceeds_limit", func(t *testing.T) { | |||
| 518 | + | mustPanic(t, "purego: too many stack arguments", func() { | |||
| 519 | + | var fn func( | |||
| 520 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 521 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 522 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 523 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 524 | + | int64, | |||
| 525 | + | ) | |||
| 526 | + | purego.RegisterFunc(&fn, 1) | |||
| 527 | + | }) | |||
| 528 | + | }) | |||
| 427 | 529 | ||||
| 428 | - | var fn func(*byte, uintptr, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64, int64) | 530 | + | t.Run("registerfunc_16_int64_exceeds_ppc64le_limit", func(t *testing.T) { |
| 429 | - | purego.RegisterLibFunc(&fn, lib, "stack_35_int64_exceeds") | 531 | + | if runtime.GOARCH != "ppc64le" { |
| 532 | + | t.Skip("ppc64le retains the 15-argument limit") | |||
| 533 | + | } | |||
| 534 | + | mustPanic(t, "purego: too many stack arguments", func() { | |||
| 535 | + | var fn func( | |||
| 536 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 537 | + | int64, int64, int64, int64, int64, int64, int64, int64, | |||
| 538 | + | ) | |||
| 539 | + | purego.RegisterFunc(&fn, 1) | |||
| 540 | + | }) | |||
| 541 | + | }) | |||
| 542 | + | ||||
| 543 | + | t.Run("syscalln_33_uintptr_exceeds_limit", func(t *testing.T) { | |||
| 544 | + | mustPanic(t, "purego: too many arguments to SyscallN", func() { | |||
| 545 | + | purego.SyscallN(1, | |||
| 546 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 547 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 548 | + | 17, 18, 19, 20, 21, 22, 23, 24, | |||
| 549 | + | 25, 26, 27, 28, 29, 30, 31, 32, | |||
| 550 | + | 33, | |||
| 551 | + | ) | |||
| 552 | + | }) | |||
| 553 | + | }) | |||
| 554 | + | ||||
| 555 | + | t.Run("syscalln_16_uintptr_exceeds_ppc64le_limit", func(t *testing.T) { | |||
| 556 | + | if runtime.GOARCH != "ppc64le" { | |||
| 557 | + | t.Skip("ppc64le retains the 15-argument limit") | |||
| 558 | + | } | |||
| 559 | + | mustPanic(t, "purego: too many arguments to SyscallN", func() { | |||
| 560 | + | purego.SyscallN(1, | |||
| 561 | + | 1, 2, 3, 4, 5, 6, 7, 8, | |||
| 562 | + | 9, 10, 11, 12, 13, 14, 15, 16, | |||
| 563 | + | ) | |||
| 564 | + | }) | |||
| 430 | }) | 565 | }) | ||
| 431 | } | 566 | } | ||
| 432 | 567 | ||||
M internal/cgo/syscall_cgo_unix.go +16 -22
| @@ -16,40 +16,34 @@ package cgo | |||
| 16 | 16 | #include <errno.h> | |
| 17 | 17 | #include <assert.h> | |
| 18 | 18 | ||
| 19 | - | typedef struct syscall15Args { | |
| 19 | + | typedef struct syscallArgs { | |
| 20 | 20 | uintptr_t fn; | |
| 21 | 21 | uintptr_t a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; | |
| 22 | + | uintptr_t a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32; | |
| 22 | 23 | uintptr_t f1, f2, f3, f4, f5, f6, f7, f8; | |
| 23 | - | uintptr_t err; | |
| 24 | - | } syscall15Args; | |
| 24 | + | uintptr_t arm64_r8; | |
| 25 | + | } syscallArgs; | |
| 25 | 26 | ||
| 26 | - | void syscall15(struct syscall15Args *args) { | |
| 27 | + | void syscall15(struct syscallArgs *args) { | |
| 27 | 28 | assert((args->f1|args->f2|args->f3|args->f4|args->f5|args->f6|args->f7|args->f8) == 0); | |
| 28 | 29 | uintptr_t (*func_name)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, | |
| 29 | 30 | uintptr_t a7, uintptr_t a8, uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, | |
| 30 | - | uintptr_t a13, uintptr_t a14, uintptr_t a15); | |
| 31 | + | uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, uintptr_t a17, uintptr_t a18, | |
| 32 | + | uintptr_t a19, uintptr_t a20, uintptr_t a21, uintptr_t a22, uintptr_t a23, uintptr_t a24, | |
| 33 | + | uintptr_t a25, uintptr_t a26, uintptr_t a27, uintptr_t a28, uintptr_t a29, uintptr_t a30, | |
| 34 | + | uintptr_t a31, uintptr_t a32); | |
| 31 | 35 | *(void**)(&func_name) = (void*)(args->fn); | |
| 32 | - | uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9, | |
| 33 | - | args->a10,args->a11,args->a12,args->a13,args->a14,args->a15); | |
| 36 | + | uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9, | |
| 37 | + | args->a10,args->a11,args->a12,args->a13,args->a14,args->a15,args->a16,args->a17,args->a18, | |
| 38 | + | args->a19,args->a20,args->a21,args->a22,args->a23,args->a24,args->a25,args->a26,args->a27, | |
| 39 | + | args->a28,args->a29,args->a30,args->a31,args->a32); | |
| 34 | 40 | args->a1 = r1; | |
| 35 | - | args->err = errno; | |
| 41 | + | args->a3 = errno; | |
| 36 | 42 | } | |
| 37 | 43 | ||
| 38 | 44 | */ | |
| 39 | 45 | import "C" | |
| 40 | 46 | import "unsafe" | |
| 41 | 47 | ||
| 42 | - | // assign purego.syscall15XABI0 to the C version of this function. | |
| 43 | - | var Syscall15XABI0 = unsafe.Pointer(C.syscall15) | |
| 44 | - | ||
| 45 | - | //go:nosplit | |
| 46 | - | func Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |
| 47 | - | args := C.syscall15Args{ | |
| 48 | - | C.uintptr_t(fn), C.uintptr_t(a1), C.uintptr_t(a2), C.uintptr_t(a3), | |
| 49 | - | C.uintptr_t(a4), C.uintptr_t(a5), C.uintptr_t(a6), | |
| 50 | - | C.uintptr_t(a7), C.uintptr_t(a8), C.uintptr_t(a9), C.uintptr_t(a10), C.uintptr_t(a11), C.uintptr_t(a12), | |
| 51 | - | C.uintptr_t(a13), C.uintptr_t(a14), C.uintptr_t(a15), 0, 0, 0, 0, 0, 0, 0, 0, 0, | |
| 52 | - | } | |
| 53 | - | C.syscall15(&args) | |
| 54 | - | return uintptr(args.a1), 0, uintptr(args.err) | |
| 55 | - | } | |
| 48 | + | // assign purego.syscallXABI0 to the C version of this function. | |
| 49 | + | var SyscallXABI0 = unsafe.Pointer(C.syscall15) | |
| @@ -16,40 +16,34 @@ package cgo | |||||
| 16 | #include <errno.h> | 16 | #include <errno.h> | ||
| 17 | #include <assert.h> | 17 | #include <assert.h> | ||
| 18 | 18 | ||||
| 19 | - | typedef struct syscall15Args { | 19 | + | typedef struct syscallArgs { |
| 20 | uintptr_t fn; | 20 | uintptr_t fn; | ||
| 21 | uintptr_t a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; | 21 | uintptr_t a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15; | ||
| 22 | + | uintptr_t a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32; | |||
| 22 | uintptr_t f1, f2, f3, f4, f5, f6, f7, f8; | 23 | uintptr_t f1, f2, f3, f4, f5, f6, f7, f8; | ||
| 23 | - | uintptr_t err; | 24 | + | uintptr_t arm64_r8; |
| 24 | - | } syscall15Args; | 25 | + | } syscallArgs; |
| 25 | 26 | ||||
| 26 | - | void syscall15(struct syscall15Args *args) { | 27 | + | void syscall15(struct syscallArgs *args) { |
| 27 | assert((args->f1|args->f2|args->f3|args->f4|args->f5|args->f6|args->f7|args->f8) == 0); | 28 | assert((args->f1|args->f2|args->f3|args->f4|args->f5|args->f6|args->f7|args->f8) == 0); | ||
| 28 | uintptr_t (*func_name)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, | 29 | uintptr_t (*func_name)(uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, | ||
| 29 | uintptr_t a7, uintptr_t a8, uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, | 30 | uintptr_t a7, uintptr_t a8, uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, | ||
| 30 | - | uintptr_t a13, uintptr_t a14, uintptr_t a15); | 31 | + | uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, uintptr_t a17, uintptr_t a18, |
| 32 | + | uintptr_t a19, uintptr_t a20, uintptr_t a21, uintptr_t a22, uintptr_t a23, uintptr_t a24, | |||
| 33 | + | uintptr_t a25, uintptr_t a26, uintptr_t a27, uintptr_t a28, uintptr_t a29, uintptr_t a30, | |||
| 34 | + | uintptr_t a31, uintptr_t a32); | |||
| 31 | *(void**)(&func_name) = (void*)(args->fn); | 35 | *(void**)(&func_name) = (void*)(args->fn); | ||
| 32 | - | uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9, | 36 | + | uintptr_t r1 = func_name(args->a1,args->a2,args->a3,args->a4,args->a5,args->a6,args->a7,args->a8,args->a9, |
| 33 | - | args->a10,args->a11,args->a12,args->a13,args->a14,args->a15); | 37 | + | args->a10,args->a11,args->a12,args->a13,args->a14,args->a15,args->a16,args->a17,args->a18, |
| 38 | + | args->a19,args->a20,args->a21,args->a22,args->a23,args->a24,args->a25,args->a26,args->a27, | |||
| 39 | + | args->a28,args->a29,args->a30,args->a31,args->a32); | |||
| 34 | args->a1 = r1; | 40 | args->a1 = r1; | ||
| 35 | - | args->err = errno; | 41 | + | args->a3 = errno; |
| 36 | } | 42 | } | ||
| 37 | 43 | ||||
| 38 | */ | 44 | */ | ||
| 39 | import "C" | 45 | import "C" | ||
| 40 | import "unsafe" | 46 | import "unsafe" | ||
| 41 | 47 | ||||
| 42 | - | // assign purego.syscall15XABI0 to the C version of this function. | 48 | + | // assign purego.syscallXABI0 to the C version of this function. |
| 43 | - | var Syscall15XABI0 = unsafe.Pointer(C.syscall15) | 49 | + | var SyscallXABI0 = unsafe.Pointer(C.syscall15) |
| 44 | - | ||||
| 45 | - | //go:nosplit | |||
| 46 | - | func Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |||
| 47 | - | args := C.syscall15Args{ | |||
| 48 | - | C.uintptr_t(fn), C.uintptr_t(a1), C.uintptr_t(a2), C.uintptr_t(a3), | |||
| 49 | - | C.uintptr_t(a4), C.uintptr_t(a5), C.uintptr_t(a6), | |||
| 50 | - | C.uintptr_t(a7), C.uintptr_t(a8), C.uintptr_t(a9), C.uintptr_t(a10), C.uintptr_t(a11), C.uintptr_t(a12), | |||
| 51 | - | C.uintptr_t(a13), C.uintptr_t(a14), C.uintptr_t(a15), 0, 0, 0, 0, 0, 0, 0, 0, 0, | |||
| 52 | - | } | |||
| 53 | - | C.syscall15(&args) | |||
| 54 | - | return uintptr(args.a1), 0, uintptr(args.err) | |||
| 55 | - | } | |||
M struct_386.go +1 -1
| @@ -12,7 +12,7 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl | |||
| 12 | 12 | panic("purego: struct arguments are not supported") | |
| 13 | 13 | } | |
| 14 | 14 | ||
| 15 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | |
| 15 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { | |
| 16 | 16 | panic("purego: struct returns are not supported") | |
| 17 | 17 | } | |
| 18 | 18 | ||
| @@ -12,7 +12,7 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl | |||||
| 12 | panic("purego: struct arguments are not supported") | 12 | panic("purego: struct arguments are not supported") | ||
| 13 | } | 13 | } | ||
| 14 | 14 | ||||
| 15 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | 15 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { |
| 16 | panic("purego: struct returns are not supported") | 16 | panic("purego: struct returns are not supported") | ||
| 17 | } | 17 | } | ||
| 18 | 18 | ||||
M struct_amd64.go +1 -1
| @@ -10,7 +10,7 @@ import ( | |||
| 10 | 10 | "unsafe" | |
| 11 | 11 | ) | |
| 12 | 12 | ||
| 13 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | |
| 13 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { | |
| 14 | 14 | outSize := outType.Size() | |
| 15 | 15 | switch { | |
| 16 | 16 | case outSize == 0: | |
| @@ -10,7 +10,7 @@ import ( | |||||
| 10 | "unsafe" | 10 | "unsafe" | ||
| 11 | ) | 11 | ) | ||
| 12 | 12 | ||||
| 13 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | 13 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { |
| 14 | outSize := outType.Size() | 14 | outSize := outType.Size() | ||
| 15 | switch { | 15 | switch { | ||
| 16 | case outSize == 0: | 16 | case outSize == 0: | ||
M struct_arm.go +1 -1
| @@ -28,7 +28,7 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl | |||
| 28 | 28 | return keepAlive | |
| 29 | 29 | } | |
| 30 | 30 | ||
| 31 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | |
| 31 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { | |
| 32 | 32 | outSize := outType.Size() | |
| 33 | 33 | if outSize == 0 { | |
| 34 | 34 | return reflect.New(outType).Elem() | |
| @@ -28,7 +28,7 @@ func addStruct(v reflect.Value, numInts, numFloats, numStack *int, addInt, addFl | |||||
| 28 | return keepAlive | 28 | return keepAlive | ||
| 29 | } | 29 | } | ||
| 30 | 30 | ||||
| 31 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | 31 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { |
| 32 | outSize := outType.Size() | 32 | outSize := outType.Size() | ||
| 33 | if outSize == 0 { | 33 | if outSize == 0 { | ||
| 34 | return reflect.New(outType).Elem() | 34 | return reflect.New(outType).Elem() | ||
M struct_arm64.go +1 -1
| @@ -14,7 +14,7 @@ import ( | |||
| 14 | 14 | "github.com/ebitengine/purego/internal/strings" | |
| 15 | 15 | ) | |
| 16 | 16 | ||
| 17 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | |
| 17 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { | |
| 18 | 18 | outSize := outType.Size() | |
| 19 | 19 | switch { | |
| 20 | 20 | case outSize == 0: | |
| @@ -14,7 +14,7 @@ import ( | |||||
| 14 | "github.com/ebitengine/purego/internal/strings" | 14 | "github.com/ebitengine/purego/internal/strings" | ||
| 15 | ) | 15 | ) | ||
| 16 | 16 | ||||
| 17 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | 17 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { |
| 18 | outSize := outType.Size() | 18 | outSize := outType.Size() | ||
| 19 | switch { | 19 | switch { | ||
| 20 | case outSize == 0: | 20 | case outSize == 0: | ||
M struct_loong64.go +1 -1
| @@ -9,7 +9,7 @@ import ( | |||
| 9 | 9 | "unsafe" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | |
| 12 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { | |
| 13 | 13 | outSize := outType.Size() | |
| 14 | 14 | switch { | |
| 15 | 15 | case outSize == 0: | |
| @@ -9,7 +9,7 @@ import ( | |||||
| 9 | "unsafe" | 9 | "unsafe" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | func getStruct(outType reflect.Type, syscall syscall15Args) (v reflect.Value) { | 12 | + | func getStruct(outType reflect.Type, syscall syscallArgs) (v reflect.Value) { |
| 13 | outSize := outType.Size() | 13 | outSize := outType.Size() | ||
| 14 | switch { | 14 | switch { | ||
| 15 | case outSize == 0: | 15 | case outSize == 0: | ||
M struct_ppc64le.go +1 -1
| @@ -8,7 +8,7 @@ import ( | |||
| 8 | 8 | "unsafe" | |
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | |
| 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { | |
| 12 | 12 | outSize := outType.Size() | |
| 13 | 13 | ||
| 14 | 14 | switch { | |
| @@ -8,7 +8,7 @@ import ( | |||||
| 8 | "unsafe" | 8 | "unsafe" | ||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { |
| 12 | outSize := outType.Size() | 12 | outSize := outType.Size() | ||
| 13 | 13 | ||||
| 14 | switch { | 14 | switch { | ||
M struct_riscv64.go +1 -1
| @@ -8,7 +8,7 @@ import ( | |||
| 8 | 8 | "unsafe" | |
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | |
| 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { | |
| 12 | 12 | outSize := outType.Size() | |
| 13 | 13 | ||
| 14 | 14 | switch { | |
| @@ -8,7 +8,7 @@ import ( | |||||
| 8 | "unsafe" | 8 | "unsafe" | ||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { |
| 12 | outSize := outType.Size() | 12 | outSize := outType.Size() | ||
| 13 | 13 | ||||
| 14 | switch { | 14 | switch { | ||
M struct_s390x.go +1 -1
| @@ -8,7 +8,7 @@ import ( | |||
| 8 | 8 | "unsafe" | |
| 9 | 9 | ) | |
| 10 | 10 | ||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | |
| 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { | |
| 12 | 12 | outSize := outType.Size() | |
| 13 | 13 | ||
| 14 | 14 | switch { | |
| @@ -8,7 +8,7 @@ import ( | |||||
| 8 | "unsafe" | 8 | "unsafe" | ||
| 9 | ) | 9 | ) | ||
| 10 | 10 | ||||
| 11 | - | func getStruct(outType reflect.Type, syscall syscall15Args) reflect.Value { | 11 | + | func getStruct(outType reflect.Type, syscall syscallArgs) reflect.Value { |
| 12 | outSize := outType.Size() | 12 | outSize := outType.Size() | ||
| 13 | 13 | ||||
| 14 | switch { | 14 | switch { | ||
M sys_386.s +43 -43
| @@ -10,8 +10,8 @@ | |||
| 10 | 10 | #define STACK_SIZE 160 | |
| 11 | 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | |
| 12 | 12 | ||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | |
| 14 | - | // syscall15X takes a pointer to a struct like: | |
| 13 | + | // syscallX calls a function in libc on behalf of the syscall package. | |
| 14 | + | // syscallX takes a pointer to a struct like: | |
| 15 | 15 | // struct { | |
| 16 | 16 | // fn uintptr | |
| 17 | 17 | // a1 uintptr | |
| @@ -22,18 +22,18 @@ | |||
| 22 | 22 | // f16 uintptr | |
| 23 | 23 | // arm64_r8 uintptr | |
| 24 | 24 | // } | |
| 25 | - | // syscall15X must be called on the g0 stack with the | |
| 25 | + | // syscallX must be called on the g0 stack with the | |
| 26 | 26 | // C calling convention (use libcCall). | |
| 27 | 27 | // | |
| 28 | 28 | // On i386 System V ABI, all arguments are passed on the stack. | |
| 29 | 29 | // Return value is in EAX (and EDX for 64-bit values). | |
| 30 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4 | |
| 31 | - | DATA ·syscall15XABI0(SB)/4, $syscall15X(SB) | |
| 32 | - | TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |
| 30 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $4 | |
| 31 | + | DATA ·syscallXABI0(SB)/4, $syscallX(SB) | |
| 32 | + | TEXT syscallX(SB), NOSPLIT|NOFRAME, $0-0 | |
| 33 | 33 | // Called via C calling convention: argument pointer at 4(SP) | |
| 34 | 34 | // NOT via Go calling convention | |
| 35 | 35 | // On i386, the first argument is at 4(SP) after CALL pushes return address | |
| 36 | - | MOVL 4(SP), AX // get pointer to syscall15Args | |
| 36 | + | MOVL 4(SP), AX // get pointer to syscallArgs | |
| 37 | 37 | ||
| 38 | 38 | // Save callee-saved registers | |
| 39 | 39 | PUSHL BP | |
| @@ -50,75 +50,75 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||
| 50 | 50 | MOVL BX, PTR_ADDRESS(SP) // save args pointer | |
| 51 | 51 | ||
| 52 | 52 | // Load function pointer | |
| 53 | - | MOVL syscall15Args_fn(BX), AX | |
| 53 | + | MOVL syscallArgs_fn(BX), AX | |
| 54 | 54 | MOVL AX, (PTR_ADDRESS-4)(SP) // save fn pointer | |
| 55 | 55 | ||
| 56 | 56 | // Push all integer arguments onto the stack (a1-a32) | |
| 57 | 57 | // i386 SysV ABI: arguments pushed right-to-left, but we're | |
| 58 | 58 | // setting up the stack from low to high addresses | |
| 59 | - | MOVL syscall15Args_a1(BX), AX | |
| 59 | + | MOVL syscallArgs_a1(BX), AX | |
| 60 | 60 | MOVL AX, 0(SP) | |
| 61 | - | MOVL syscall15Args_a2(BX), AX | |
| 61 | + | MOVL syscallArgs_a2(BX), AX | |
| 62 | 62 | MOVL AX, 4(SP) | |
| 63 | - | MOVL syscall15Args_a3(BX), AX | |
| 63 | + | MOVL syscallArgs_a3(BX), AX | |
| 64 | 64 | MOVL AX, 8(SP) | |
| 65 | - | MOVL syscall15Args_a4(BX), AX | |
| 65 | + | MOVL syscallArgs_a4(BX), AX | |
| 66 | 66 | MOVL AX, 12(SP) | |
| 67 | - | MOVL syscall15Args_a5(BX), AX | |
| 67 | + | MOVL syscallArgs_a5(BX), AX | |
| 68 | 68 | MOVL AX, 16(SP) | |
| 69 | - | MOVL syscall15Args_a6(BX), AX | |
| 69 | + | MOVL syscallArgs_a6(BX), AX | |
| 70 | 70 | MOVL AX, 20(SP) | |
| 71 | - | MOVL syscall15Args_a7(BX), AX | |
| 71 | + | MOVL syscallArgs_a7(BX), AX | |
| 72 | 72 | MOVL AX, 24(SP) | |
| 73 | - | MOVL syscall15Args_a8(BX), AX | |
| 73 | + | MOVL syscallArgs_a8(BX), AX | |
| 74 | 74 | MOVL AX, 28(SP) | |
| 75 | - | MOVL syscall15Args_a9(BX), AX | |
| 75 | + | MOVL syscallArgs_a9(BX), AX | |
| 76 | 76 | MOVL AX, 32(SP) | |
| 77 | - | MOVL syscall15Args_a10(BX), AX | |
| 77 | + | MOVL syscallArgs_a10(BX), AX | |
| 78 | 78 | MOVL AX, 36(SP) | |
| 79 | - | MOVL syscall15Args_a11(BX), AX | |
| 79 | + | MOVL syscallArgs_a11(BX), AX | |
| 80 | 80 | MOVL AX, 40(SP) | |
| 81 | - | MOVL syscall15Args_a12(BX), AX | |
| 81 | + | MOVL syscallArgs_a12(BX), AX | |
| 82 | 82 | MOVL AX, 44(SP) | |
| 83 | - | MOVL syscall15Args_a13(BX), AX | |
| 83 | + | MOVL syscallArgs_a13(BX), AX | |
| 84 | 84 | MOVL AX, 48(SP) | |
| 85 | - | MOVL syscall15Args_a14(BX), AX | |
| 85 | + | MOVL syscallArgs_a14(BX), AX | |
| 86 | 86 | MOVL AX, 52(SP) | |
| 87 | - | MOVL syscall15Args_a15(BX), AX | |
| 87 | + | MOVL syscallArgs_a15(BX), AX | |
| 88 | 88 | MOVL AX, 56(SP) | |
| 89 | - | MOVL syscall15Args_a16(BX), AX | |
| 89 | + | MOVL syscallArgs_a16(BX), AX | |
| 90 | 90 | MOVL AX, 60(SP) | |
| 91 | - | MOVL syscall15Args_a17(BX), AX | |
| 91 | + | MOVL syscallArgs_a17(BX), AX | |
| 92 | 92 | MOVL AX, 64(SP) | |
| 93 | - | MOVL syscall15Args_a18(BX), AX | |
| 93 | + | MOVL syscallArgs_a18(BX), AX | |
| 94 | 94 | MOVL AX, 68(SP) | |
| 95 | - | MOVL syscall15Args_a19(BX), AX | |
| 95 | + | MOVL syscallArgs_a19(BX), AX | |
| 96 | 96 | MOVL AX, 72(SP) | |
| 97 | - | MOVL syscall15Args_a20(BX), AX | |
| 97 | + | MOVL syscallArgs_a20(BX), AX | |
| 98 | 98 | MOVL AX, 76(SP) | |
| 99 | - | MOVL syscall15Args_a21(BX), AX | |
| 99 | + | MOVL syscallArgs_a21(BX), AX | |
| 100 | 100 | MOVL AX, 80(SP) | |
| 101 | - | MOVL syscall15Args_a22(BX), AX | |
| 101 | + | MOVL syscallArgs_a22(BX), AX | |
| 102 | 102 | MOVL AX, 84(SP) | |
| 103 | - | MOVL syscall15Args_a23(BX), AX | |
| 103 | + | MOVL syscallArgs_a23(BX), AX | |
| 104 | 104 | MOVL AX, 88(SP) | |
| 105 | - | MOVL syscall15Args_a24(BX), AX | |
| 105 | + | MOVL syscallArgs_a24(BX), AX | |
| 106 | 106 | MOVL AX, 92(SP) | |
| 107 | - | MOVL syscall15Args_a25(BX), AX | |
| 107 | + | MOVL syscallArgs_a25(BX), AX | |
| 108 | 108 | MOVL AX, 96(SP) | |
| 109 | - | MOVL syscall15Args_a26(BX), AX | |
| 109 | + | MOVL syscallArgs_a26(BX), AX | |
| 110 | 110 | MOVL AX, 100(SP) | |
| 111 | - | MOVL syscall15Args_a27(BX), AX | |
| 111 | + | MOVL syscallArgs_a27(BX), AX | |
| 112 | 112 | MOVL AX, 104(SP) | |
| 113 | - | MOVL syscall15Args_a28(BX), AX | |
| 113 | + | MOVL syscallArgs_a28(BX), AX | |
| 114 | 114 | MOVL AX, 108(SP) | |
| 115 | - | MOVL syscall15Args_a29(BX), AX | |
| 115 | + | MOVL syscallArgs_a29(BX), AX | |
| 116 | 116 | MOVL AX, 112(SP) | |
| 117 | - | MOVL syscall15Args_a30(BX), AX | |
| 117 | + | MOVL syscallArgs_a30(BX), AX | |
| 118 | 118 | MOVL AX, 116(SP) | |
| 119 | - | MOVL syscall15Args_a31(BX), AX | |
| 119 | + | MOVL syscallArgs_a31(BX), AX | |
| 120 | 120 | MOVL AX, 120(SP) | |
| 121 | - | MOVL syscall15Args_a32(BX), AX | |
| 121 | + | MOVL syscallArgs_a32(BX), AX | |
| 122 | 122 | MOVL AX, 124(SP) | |
| 123 | 123 | ||
| 124 | 124 | // Call the C function | |
| @@ -127,13 +127,13 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||
| 127 | 127 | ||
| 128 | 128 | // Get args pointer back and save results | |
| 129 | 129 | MOVL PTR_ADDRESS(SP), BX | |
| 130 | - | MOVL AX, syscall15Args_a1(BX) // return value r1 | |
| 131 | - | MOVL DX, syscall15Args_a2(BX) // return value r2 (for 64-bit returns) | |
| 130 | + | MOVL AX, syscallArgs_a1(BX) // return value r1 | |
| 131 | + | MOVL DX, syscallArgs_a2(BX) // return value r2 (for 64-bit returns) | |
| 132 | 132 | ||
| 133 | 133 | // Save x87 FPU return value (ST0) to f1 field | |
| 134 | 134 | // On i386 System V ABI, float/double returns are in ST(0) | |
| 135 | 135 | // We save as float64 (8 bytes) to preserve precision | |
| 136 | - | FMOVDP F0, syscall15Args_f1(BX) | |
| 136 | + | FMOVDP F0, syscallArgs_f1(BX) | |
| 137 | 137 | ||
| 138 | 138 | // Clean up stack | |
| 139 | 139 | ADDL $STACK_SIZE, SP | |
| @@ -10,8 +10,8 @@ | |||||
| 10 | #define STACK_SIZE 160 | 10 | #define STACK_SIZE 160 | ||
| 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | ||
| 12 | 12 | ||||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | 13 | + | // syscallX calls a function in libc on behalf of the syscall package. |
| 14 | - | // syscall15X takes a pointer to a struct like: | 14 | + | // syscallX takes a pointer to a struct like: |
| 15 | // struct { | 15 | // struct { | ||
| 16 | // fn uintptr | 16 | // fn uintptr | ||
| 17 | // a1 uintptr | 17 | // a1 uintptr | ||
| @@ -22,18 +22,18 @@ | |||||
| 22 | // f16 uintptr | 22 | // f16 uintptr | ||
| 23 | // arm64_r8 uintptr | 23 | // arm64_r8 uintptr | ||
| 24 | // } | 24 | // } | ||
| 25 | - | // syscall15X must be called on the g0 stack with the | 25 | + | // syscallX must be called on the g0 stack with the |
| 26 | // C calling convention (use libcCall). | 26 | // C calling convention (use libcCall). | ||
| 27 | // | 27 | // | ||
| 28 | // On i386 System V ABI, all arguments are passed on the stack. | 28 | // On i386 System V ABI, all arguments are passed on the stack. | ||
| 29 | // Return value is in EAX (and EDX for 64-bit values). | 29 | // Return value is in EAX (and EDX for 64-bit values). | ||
| 30 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4 | 30 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $4 |
| 31 | - | DATA ·syscall15XABI0(SB)/4, $syscall15X(SB) | 31 | + | DATA ·syscallXABI0(SB)/4, $syscallX(SB) |
| 32 | - | TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | 32 | + | TEXT syscallX(SB), NOSPLIT|NOFRAME, $0-0 |
| 33 | // Called via C calling convention: argument pointer at 4(SP) | 33 | // Called via C calling convention: argument pointer at 4(SP) | ||
| 34 | // NOT via Go calling convention | 34 | // NOT via Go calling convention | ||
| 35 | // On i386, the first argument is at 4(SP) after CALL pushes return address | 35 | // On i386, the first argument is at 4(SP) after CALL pushes return address | ||
| 36 | - | MOVL 4(SP), AX // get pointer to syscall15Args | 36 | + | MOVL 4(SP), AX // get pointer to syscallArgs |
| 37 | 37 | ||||
| 38 | // Save callee-saved registers | 38 | // Save callee-saved registers | ||
| 39 | PUSHL BP | 39 | PUSHL BP | ||
| @@ -50,75 +50,75 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||||
| 50 | MOVL BX, PTR_ADDRESS(SP) // save args pointer | 50 | MOVL BX, PTR_ADDRESS(SP) // save args pointer | ||
| 51 | 51 | ||||
| 52 | // Load function pointer | 52 | // Load function pointer | ||
| 53 | - | MOVL syscall15Args_fn(BX), AX | 53 | + | MOVL syscallArgs_fn(BX), AX |
| 54 | MOVL AX, (PTR_ADDRESS-4)(SP) // save fn pointer | 54 | MOVL AX, (PTR_ADDRESS-4)(SP) // save fn pointer | ||
| 55 | 55 | ||||
| 56 | // Push all integer arguments onto the stack (a1-a32) | 56 | // Push all integer arguments onto the stack (a1-a32) | ||
| 57 | // i386 SysV ABI: arguments pushed right-to-left, but we're | 57 | // i386 SysV ABI: arguments pushed right-to-left, but we're | ||
| 58 | // setting up the stack from low to high addresses | 58 | // setting up the stack from low to high addresses | ||
| 59 | - | MOVL syscall15Args_a1(BX), AX | 59 | + | MOVL syscallArgs_a1(BX), AX |
| 60 | MOVL AX, 0(SP) | 60 | MOVL AX, 0(SP) | ||
| 61 | - | MOVL syscall15Args_a2(BX), AX | 61 | + | MOVL syscallArgs_a2(BX), AX |
| 62 | MOVL AX, 4(SP) | 62 | MOVL AX, 4(SP) | ||
| 63 | - | MOVL syscall15Args_a3(BX), AX | 63 | + | MOVL syscallArgs_a3(BX), AX |
| 64 | MOVL AX, 8(SP) | 64 | MOVL AX, 8(SP) | ||
| 65 | - | MOVL syscall15Args_a4(BX), AX | 65 | + | MOVL syscallArgs_a4(BX), AX |
| 66 | MOVL AX, 12(SP) | 66 | MOVL AX, 12(SP) | ||
| 67 | - | MOVL syscall15Args_a5(BX), AX | 67 | + | MOVL syscallArgs_a5(BX), AX |
| 68 | MOVL AX, 16(SP) | 68 | MOVL AX, 16(SP) | ||
| 69 | - | MOVL syscall15Args_a6(BX), AX | 69 | + | MOVL syscallArgs_a6(BX), AX |
| 70 | MOVL AX, 20(SP) | 70 | MOVL AX, 20(SP) | ||
| 71 | - | MOVL syscall15Args_a7(BX), AX | 71 | + | MOVL syscallArgs_a7(BX), AX |
| 72 | MOVL AX, 24(SP) | 72 | MOVL AX, 24(SP) | ||
| 73 | - | MOVL syscall15Args_a8(BX), AX | 73 | + | MOVL syscallArgs_a8(BX), AX |
| 74 | MOVL AX, 28(SP) | 74 | MOVL AX, 28(SP) | ||
| 75 | - | MOVL syscall15Args_a9(BX), AX | 75 | + | MOVL syscallArgs_a9(BX), AX |
| 76 | MOVL AX, 32(SP) | 76 | MOVL AX, 32(SP) | ||
| 77 | - | MOVL syscall15Args_a10(BX), AX | 77 | + | MOVL syscallArgs_a10(BX), AX |
| 78 | MOVL AX, 36(SP) | 78 | MOVL AX, 36(SP) | ||
| 79 | - | MOVL syscall15Args_a11(BX), AX | 79 | + | MOVL syscallArgs_a11(BX), AX |
| 80 | MOVL AX, 40(SP) | 80 | MOVL AX, 40(SP) | ||
| 81 | - | MOVL syscall15Args_a12(BX), AX | 81 | + | MOVL syscallArgs_a12(BX), AX |
| 82 | MOVL AX, 44(SP) | 82 | MOVL AX, 44(SP) | ||
| 83 | - | MOVL syscall15Args_a13(BX), AX | 83 | + | MOVL syscallArgs_a13(BX), AX |
| 84 | MOVL AX, 48(SP) | 84 | MOVL AX, 48(SP) | ||
| 85 | - | MOVL syscall15Args_a14(BX), AX | 85 | + | MOVL syscallArgs_a14(BX), AX |
| 86 | MOVL AX, 52(SP) | 86 | MOVL AX, 52(SP) | ||
| 87 | - | MOVL syscall15Args_a15(BX), AX | 87 | + | MOVL syscallArgs_a15(BX), AX |
| 88 | MOVL AX, 56(SP) | 88 | MOVL AX, 56(SP) | ||
| 89 | - | MOVL syscall15Args_a16(BX), AX | 89 | + | MOVL syscallArgs_a16(BX), AX |
| 90 | MOVL AX, 60(SP) | 90 | MOVL AX, 60(SP) | ||
| 91 | - | MOVL syscall15Args_a17(BX), AX | 91 | + | MOVL syscallArgs_a17(BX), AX |
| 92 | MOVL AX, 64(SP) | 92 | MOVL AX, 64(SP) | ||
| 93 | - | MOVL syscall15Args_a18(BX), AX | 93 | + | MOVL syscallArgs_a18(BX), AX |
| 94 | MOVL AX, 68(SP) | 94 | MOVL AX, 68(SP) | ||
| 95 | - | MOVL syscall15Args_a19(BX), AX | 95 | + | MOVL syscallArgs_a19(BX), AX |
| 96 | MOVL AX, 72(SP) | 96 | MOVL AX, 72(SP) | ||
| 97 | - | MOVL syscall15Args_a20(BX), AX | 97 | + | MOVL syscallArgs_a20(BX), AX |
| 98 | MOVL AX, 76(SP) | 98 | MOVL AX, 76(SP) | ||
| 99 | - | MOVL syscall15Args_a21(BX), AX | 99 | + | MOVL syscallArgs_a21(BX), AX |
| 100 | MOVL AX, 80(SP) | 100 | MOVL AX, 80(SP) | ||
| 101 | - | MOVL syscall15Args_a22(BX), AX | 101 | + | MOVL syscallArgs_a22(BX), AX |
| 102 | MOVL AX, 84(SP) | 102 | MOVL AX, 84(SP) | ||
| 103 | - | MOVL syscall15Args_a23(BX), AX | 103 | + | MOVL syscallArgs_a23(BX), AX |
| 104 | MOVL AX, 88(SP) | 104 | MOVL AX, 88(SP) | ||
| 105 | - | MOVL syscall15Args_a24(BX), AX | 105 | + | MOVL syscallArgs_a24(BX), AX |
| 106 | MOVL AX, 92(SP) | 106 | MOVL AX, 92(SP) | ||
| 107 | - | MOVL syscall15Args_a25(BX), AX | 107 | + | MOVL syscallArgs_a25(BX), AX |
| 108 | MOVL AX, 96(SP) | 108 | MOVL AX, 96(SP) | ||
| 109 | - | MOVL syscall15Args_a26(BX), AX | 109 | + | MOVL syscallArgs_a26(BX), AX |
| 110 | MOVL AX, 100(SP) | 110 | MOVL AX, 100(SP) | ||
| 111 | - | MOVL syscall15Args_a27(BX), AX | 111 | + | MOVL syscallArgs_a27(BX), AX |
| 112 | MOVL AX, 104(SP) | 112 | MOVL AX, 104(SP) | ||
| 113 | - | MOVL syscall15Args_a28(BX), AX | 113 | + | MOVL syscallArgs_a28(BX), AX |
| 114 | MOVL AX, 108(SP) | 114 | MOVL AX, 108(SP) | ||
| 115 | - | MOVL syscall15Args_a29(BX), AX | 115 | + | MOVL syscallArgs_a29(BX), AX |
| 116 | MOVL AX, 112(SP) | 116 | MOVL AX, 112(SP) | ||
| 117 | - | MOVL syscall15Args_a30(BX), AX | 117 | + | MOVL syscallArgs_a30(BX), AX |
| 118 | MOVL AX, 116(SP) | 118 | MOVL AX, 116(SP) | ||
| 119 | - | MOVL syscall15Args_a31(BX), AX | 119 | + | MOVL syscallArgs_a31(BX), AX |
| 120 | MOVL AX, 120(SP) | 120 | MOVL AX, 120(SP) | ||
| 121 | - | MOVL syscall15Args_a32(BX), AX | 121 | + | MOVL syscallArgs_a32(BX), AX |
| 122 | MOVL AX, 124(SP) | 122 | MOVL AX, 124(SP) | ||
| 123 | 123 | ||||
| 124 | // Call the C function | 124 | // Call the C function | ||
| @@ -127,13 +127,13 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||||
| 127 | 127 | ||||
| 128 | // Get args pointer back and save results | 128 | // Get args pointer back and save results | ||
| 129 | MOVL PTR_ADDRESS(SP), BX | 129 | MOVL PTR_ADDRESS(SP), BX | ||
| 130 | - | MOVL AX, syscall15Args_a1(BX) // return value r1 | 130 | + | MOVL AX, syscallArgs_a1(BX) // return value r1 |
| 131 | - | MOVL DX, syscall15Args_a2(BX) // return value r2 (for 64-bit returns) | 131 | + | MOVL DX, syscallArgs_a2(BX) // return value r2 (for 64-bit returns) |
| 132 | 132 | ||||
| 133 | // Save x87 FPU return value (ST0) to f1 field | 133 | // Save x87 FPU return value (ST0) to f1 field | ||
| 134 | // On i386 System V ABI, float/double returns are in ST(0) | 134 | // On i386 System V ABI, float/double returns are in ST(0) | ||
| 135 | // We save as float64 (8 bytes) to preserve precision | 135 | // We save as float64 (8 bytes) to preserve precision | ||
| 136 | - | FMOVDP F0, syscall15Args_f1(BX) | 136 | + | FMOVDP F0, syscallArgs_f1(BX) |
| 137 | 137 | ||||
| 138 | // Clean up stack | 138 | // Clean up stack | ||
| 139 | ADDL $STACK_SIZE, SP | 139 | ADDL $STACK_SIZE, SP | ||
M sys_amd64.s +71 -37
| @@ -8,11 +8,11 @@ | |||
| 8 | 8 | #include "go_asm.h" | |
| 9 | 9 | #include "funcdata.h" | |
| 10 | 10 | ||
| 11 | - | #define STACK_SIZE 80 | |
| 11 | + | #define STACK_SIZE 224 | |
| 12 | 12 | #define PTR_ADDRESS (STACK_SIZE - 8) | |
| 13 | 13 | ||
| 14 | - | // syscall15X calls a function in libc on behalf of the syscall package. | |
| 15 | - | // syscall15X takes a pointer to a struct like: | |
| 14 | + | // syscallX calls a function in libc on behalf of the syscall package. | |
| 15 | + | // syscallX takes a pointer to a struct like: | |
| 16 | 16 | // struct { | |
| 17 | 17 | // fn uintptr | |
| 18 | 18 | // a1 uintptr | |
| @@ -34,65 +34,99 @@ | |||
| 34 | 34 | // r2 uintptr | |
| 35 | 35 | // err uintptr | |
| 36 | 36 | // } | |
| 37 | - | // syscall15X must be called on the g0 stack with the | |
| 37 | + | // syscallX must be called on the g0 stack with the | |
| 38 | 38 | // C calling convention (use libcCall). | |
| 39 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 40 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 41 | - | TEXT syscall15X(SB), NOSPLIT, $STACK_SIZE | |
| 39 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 40 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 41 | + | TEXT syscallX(SB), NOSPLIT, $STACK_SIZE | |
| 42 | 42 | MOVQ DI, PTR_ADDRESS(SP) // save the pointer | |
| 43 | 43 | MOVQ DI, R11 | |
| 44 | 44 | ||
| 45 | - | MOVQ syscall15Args_f1(R11), X0 // f1 | |
| 46 | - | MOVQ syscall15Args_f2(R11), X1 // f2 | |
| 47 | - | MOVQ syscall15Args_f3(R11), X2 // f3 | |
| 48 | - | MOVQ syscall15Args_f4(R11), X3 // f4 | |
| 49 | - | MOVQ syscall15Args_f5(R11), X4 // f5 | |
| 50 | - | MOVQ syscall15Args_f6(R11), X5 // f6 | |
| 51 | - | MOVQ syscall15Args_f7(R11), X6 // f7 | |
| 52 | - | MOVQ syscall15Args_f8(R11), X7 // f8 | |
| 53 | - | ||
| 54 | - | MOVQ syscall15Args_a1(R11), DI // a1 | |
| 55 | - | MOVQ syscall15Args_a2(R11), SI // a2 | |
| 56 | - | MOVQ syscall15Args_a3(R11), DX // a3 | |
| 57 | - | MOVQ syscall15Args_a4(R11), CX // a4 | |
| 58 | - | MOVQ syscall15Args_a5(R11), R8 // a5 | |
| 59 | - | MOVQ syscall15Args_a6(R11), R9 // a6 | |
| 45 | + | MOVQ syscallArgs_f1(R11), X0 // f1 | |
| 46 | + | MOVQ syscallArgs_f2(R11), X1 // f2 | |
| 47 | + | MOVQ syscallArgs_f3(R11), X2 // f3 | |
| 48 | + | MOVQ syscallArgs_f4(R11), X3 // f4 | |
| 49 | + | MOVQ syscallArgs_f5(R11), X4 // f5 | |
| 50 | + | MOVQ syscallArgs_f6(R11), X5 // f6 | |
| 51 | + | MOVQ syscallArgs_f7(R11), X6 // f7 | |
| 52 | + | MOVQ syscallArgs_f8(R11), X7 // f8 | |
| 53 | + | ||
| 54 | + | MOVQ syscallArgs_a1(R11), DI // a1 | |
| 55 | + | MOVQ syscallArgs_a2(R11), SI // a2 | |
| 56 | + | MOVQ syscallArgs_a3(R11), DX // a3 | |
| 57 | + | MOVQ syscallArgs_a4(R11), CX // a4 | |
| 58 | + | MOVQ syscallArgs_a5(R11), R8 // a5 | |
| 59 | + | MOVQ syscallArgs_a6(R11), R9 // a6 | |
| 60 | 60 | ||
| 61 | 61 | // push the remaining parameters onto the stack | |
| 62 | - | MOVQ syscall15Args_a7(R11), R12 | |
| 62 | + | MOVQ syscallArgs_a7(R11), R12 | |
| 63 | 63 | MOVQ R12, 0(SP) // push a7 | |
| 64 | - | MOVQ syscall15Args_a8(R11), R12 | |
| 64 | + | MOVQ syscallArgs_a8(R11), R12 | |
| 65 | 65 | MOVQ R12, 8(SP) // push a8 | |
| 66 | - | MOVQ syscall15Args_a9(R11), R12 | |
| 66 | + | MOVQ syscallArgs_a9(R11), R12 | |
| 67 | 67 | MOVQ R12, 16(SP) // push a9 | |
| 68 | - | MOVQ syscall15Args_a10(R11), R12 | |
| 68 | + | MOVQ syscallArgs_a10(R11), R12 | |
| 69 | 69 | MOVQ R12, 24(SP) // push a10 | |
| 70 | - | MOVQ syscall15Args_a11(R11), R12 | |
| 70 | + | MOVQ syscallArgs_a11(R11), R12 | |
| 71 | 71 | MOVQ R12, 32(SP) // push a11 | |
| 72 | - | MOVQ syscall15Args_a12(R11), R12 | |
| 72 | + | MOVQ syscallArgs_a12(R11), R12 | |
| 73 | 73 | MOVQ R12, 40(SP) // push a12 | |
| 74 | - | MOVQ syscall15Args_a13(R11), R12 | |
| 74 | + | MOVQ syscallArgs_a13(R11), R12 | |
| 75 | 75 | MOVQ R12, 48(SP) // push a13 | |
| 76 | - | MOVQ syscall15Args_a14(R11), R12 | |
| 76 | + | MOVQ syscallArgs_a14(R11), R12 | |
| 77 | 77 | MOVQ R12, 56(SP) // push a14 | |
| 78 | - | MOVQ syscall15Args_a15(R11), R12 | |
| 78 | + | MOVQ syscallArgs_a15(R11), R12 | |
| 79 | 79 | MOVQ R12, 64(SP) // push a15 | |
| 80 | + | MOVQ syscallArgs_a16(R11), R12 | |
| 81 | + | MOVQ R12, 72(SP) // push a16 | |
| 82 | + | MOVQ syscallArgs_a17(R11), R12 | |
| 83 | + | MOVQ R12, 80(SP) // push a17 | |
| 84 | + | MOVQ syscallArgs_a18(R11), R12 | |
| 85 | + | MOVQ R12, 88(SP) // push a18 | |
| 86 | + | MOVQ syscallArgs_a19(R11), R12 | |
| 87 | + | MOVQ R12, 96(SP) // push a19 | |
| 88 | + | MOVQ syscallArgs_a20(R11), R12 | |
| 89 | + | MOVQ R12, 104(SP) // push a20 | |
| 90 | + | MOVQ syscallArgs_a21(R11), R12 | |
| 91 | + | MOVQ R12, 112(SP) // push a21 | |
| 92 | + | MOVQ syscallArgs_a22(R11), R12 | |
| 93 | + | MOVQ R12, 120(SP) // push a22 | |
| 94 | + | MOVQ syscallArgs_a23(R11), R12 | |
| 95 | + | MOVQ R12, 128(SP) // push a23 | |
| 96 | + | MOVQ syscallArgs_a24(R11), R12 | |
| 97 | + | MOVQ R12, 136(SP) // push a24 | |
| 98 | + | MOVQ syscallArgs_a25(R11), R12 | |
| 99 | + | MOVQ R12, 144(SP) // push a25 | |
| 100 | + | MOVQ syscallArgs_a26(R11), R12 | |
| 101 | + | MOVQ R12, 152(SP) // push a26 | |
| 102 | + | MOVQ syscallArgs_a27(R11), R12 | |
| 103 | + | MOVQ R12, 160(SP) // push a27 | |
| 104 | + | MOVQ syscallArgs_a28(R11), R12 | |
| 105 | + | MOVQ R12, 168(SP) // push a28 | |
| 106 | + | MOVQ syscallArgs_a29(R11), R12 | |
| 107 | + | MOVQ R12, 176(SP) // push a29 | |
| 108 | + | MOVQ syscallArgs_a30(R11), R12 | |
| 109 | + | MOVQ R12, 184(SP) // push a30 | |
| 110 | + | MOVQ syscallArgs_a31(R11), R12 | |
| 111 | + | MOVQ R12, 192(SP) // push a31 | |
| 112 | + | MOVQ syscallArgs_a32(R11), R12 | |
| 113 | + | MOVQ R12, 200(SP) // push a32 | |
| 80 | 114 | XORL AX, AX // vararg: say "no float args" | |
| 81 | 115 | ||
| 82 | - | MOVQ syscall15Args_fn(R11), R10 // fn | |
| 116 | + | MOVQ syscallArgs_fn(R11), R10 // fn | |
| 83 | 117 | CALL R10 | |
| 84 | 118 | ||
| 85 | 119 | MOVQ PTR_ADDRESS(SP), DI // get the pointer back | |
| 86 | - | MOVQ AX, syscall15Args_a1(DI) // r1 | |
| 87 | - | MOVQ DX, syscall15Args_a2(DI) // r2 | |
| 88 | - | MOVQ X0, syscall15Args_f1(DI) // f1 | |
| 89 | - | MOVQ X1, syscall15Args_f2(DI) // f2 | |
| 120 | + | MOVQ AX, syscallArgs_a1(DI) // r1 | |
| 121 | + | MOVQ DX, syscallArgs_a2(DI) // r2 | |
| 122 | + | MOVQ X0, syscallArgs_f1(DI) // f1 | |
| 123 | + | MOVQ X1, syscallArgs_f2(DI) // f2 | |
| 90 | 124 | ||
| 91 | 125 | #ifdef GOOS_darwin | |
| 92 | 126 | CALL purego_error(SB) | |
| 93 | 127 | MOVQ PTR_ADDRESS(SP), DI // reload (DI clobbered by call) | |
| 94 | 128 | MOVQ (AX), AX | |
| 95 | - | MOVQ AX, syscall15Args_a3(DI) // save errno | |
| 129 | + | MOVQ AX, syscallArgs_a3(DI) // save errno | |
| 96 | 130 | #endif | |
| 97 | 131 | ||
| 98 | 132 | XORL AX, AX // no error (it's ignored anyway) | |
| @@ -8,11 +8,11 @@ | |||||
| 8 | #include "go_asm.h" | 8 | #include "go_asm.h" | ||
| 9 | #include "funcdata.h" | 9 | #include "funcdata.h" | ||
| 10 | 10 | ||||
| 11 | - | #define STACK_SIZE 80 | 11 | + | #define STACK_SIZE 224 |
| 12 | #define PTR_ADDRESS (STACK_SIZE - 8) | 12 | #define PTR_ADDRESS (STACK_SIZE - 8) | ||
| 13 | 13 | ||||
| 14 | - | // syscall15X calls a function in libc on behalf of the syscall package. | 14 | + | // syscallX calls a function in libc on behalf of the syscall package. |
| 15 | - | // syscall15X takes a pointer to a struct like: | 15 | + | // syscallX takes a pointer to a struct like: |
| 16 | // struct { | 16 | // struct { | ||
| 17 | // fn uintptr | 17 | // fn uintptr | ||
| 18 | // a1 uintptr | 18 | // a1 uintptr | ||
| @@ -34,65 +34,99 @@ | |||||
| 34 | // r2 uintptr | 34 | // r2 uintptr | ||
| 35 | // err uintptr | 35 | // err uintptr | ||
| 36 | // } | 36 | // } | ||
| 37 | - | // syscall15X must be called on the g0 stack with the | 37 | + | // syscallX must be called on the g0 stack with the |
| 38 | // C calling convention (use libcCall). | 38 | // C calling convention (use libcCall). | ||
| 39 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 39 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 |
| 40 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 40 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 41 | - | TEXT syscall15X(SB), NOSPLIT, $STACK_SIZE | 41 | + | TEXT syscallX(SB), NOSPLIT, $STACK_SIZE |
| 42 | MOVQ DI, PTR_ADDRESS(SP) // save the pointer | 42 | MOVQ DI, PTR_ADDRESS(SP) // save the pointer | ||
| 43 | MOVQ DI, R11 | 43 | MOVQ DI, R11 | ||
| 44 | 44 | ||||
| 45 | - | MOVQ syscall15Args_f1(R11), X0 // f1 | 45 | + | MOVQ syscallArgs_f1(R11), X0 // f1 |
| 46 | - | MOVQ syscall15Args_f2(R11), X1 // f2 | 46 | + | MOVQ syscallArgs_f2(R11), X1 // f2 |
| 47 | - | MOVQ syscall15Args_f3(R11), X2 // f3 | 47 | + | MOVQ syscallArgs_f3(R11), X2 // f3 |
| 48 | - | MOVQ syscall15Args_f4(R11), X3 // f4 | 48 | + | MOVQ syscallArgs_f4(R11), X3 // f4 |
| 49 | - | MOVQ syscall15Args_f5(R11), X4 // f5 | 49 | + | MOVQ syscallArgs_f5(R11), X4 // f5 |
| 50 | - | MOVQ syscall15Args_f6(R11), X5 // f6 | 50 | + | MOVQ syscallArgs_f6(R11), X5 // f6 |
| 51 | - | MOVQ syscall15Args_f7(R11), X6 // f7 | 51 | + | MOVQ syscallArgs_f7(R11), X6 // f7 |
| 52 | - | MOVQ syscall15Args_f8(R11), X7 // f8 | 52 | + | MOVQ syscallArgs_f8(R11), X7 // f8 |
| 53 | - | 53 | + | ||
| 54 | - | MOVQ syscall15Args_a1(R11), DI // a1 | 54 | + | MOVQ syscallArgs_a1(R11), DI // a1 |
| 55 | - | MOVQ syscall15Args_a2(R11), SI // a2 | 55 | + | MOVQ syscallArgs_a2(R11), SI // a2 |
| 56 | - | MOVQ syscall15Args_a3(R11), DX // a3 | 56 | + | MOVQ syscallArgs_a3(R11), DX // a3 |
| 57 | - | MOVQ syscall15Args_a4(R11), CX // a4 | 57 | + | MOVQ syscallArgs_a4(R11), CX // a4 |
| 58 | - | MOVQ syscall15Args_a5(R11), R8 // a5 | 58 | + | MOVQ syscallArgs_a5(R11), R8 // a5 |
| 59 | - | MOVQ syscall15Args_a6(R11), R9 // a6 | 59 | + | MOVQ syscallArgs_a6(R11), R9 // a6 |
| 60 | 60 | ||||
| 61 | // push the remaining parameters onto the stack | 61 | // push the remaining parameters onto the stack | ||
| 62 | - | MOVQ syscall15Args_a7(R11), R12 | 62 | + | MOVQ syscallArgs_a7(R11), R12 |
| 63 | MOVQ R12, 0(SP) // push a7 | 63 | MOVQ R12, 0(SP) // push a7 | ||
| 64 | - | MOVQ syscall15Args_a8(R11), R12 | 64 | + | MOVQ syscallArgs_a8(R11), R12 |
| 65 | MOVQ R12, 8(SP) // push a8 | 65 | MOVQ R12, 8(SP) // push a8 | ||
| 66 | - | MOVQ syscall15Args_a9(R11), R12 | 66 | + | MOVQ syscallArgs_a9(R11), R12 |
| 67 | MOVQ R12, 16(SP) // push a9 | 67 | MOVQ R12, 16(SP) // push a9 | ||
| 68 | - | MOVQ syscall15Args_a10(R11), R12 | 68 | + | MOVQ syscallArgs_a10(R11), R12 |
| 69 | MOVQ R12, 24(SP) // push a10 | 69 | MOVQ R12, 24(SP) // push a10 | ||
| 70 | - | MOVQ syscall15Args_a11(R11), R12 | 70 | + | MOVQ syscallArgs_a11(R11), R12 |
| 71 | MOVQ R12, 32(SP) // push a11 | 71 | MOVQ R12, 32(SP) // push a11 | ||
| 72 | - | MOVQ syscall15Args_a12(R11), R12 | 72 | + | MOVQ syscallArgs_a12(R11), R12 |
| 73 | MOVQ R12, 40(SP) // push a12 | 73 | MOVQ R12, 40(SP) // push a12 | ||
| 74 | - | MOVQ syscall15Args_a13(R11), R12 | 74 | + | MOVQ syscallArgs_a13(R11), R12 |
| 75 | MOVQ R12, 48(SP) // push a13 | 75 | MOVQ R12, 48(SP) // push a13 | ||
| 76 | - | MOVQ syscall15Args_a14(R11), R12 | 76 | + | MOVQ syscallArgs_a14(R11), R12 |
| 77 | MOVQ R12, 56(SP) // push a14 | 77 | MOVQ R12, 56(SP) // push a14 | ||
| 78 | - | MOVQ syscall15Args_a15(R11), R12 | 78 | + | MOVQ syscallArgs_a15(R11), R12 |
| 79 | MOVQ R12, 64(SP) // push a15 | 79 | MOVQ R12, 64(SP) // push a15 | ||
| 80 | + | MOVQ syscallArgs_a16(R11), R12 | |||
| 81 | + | MOVQ R12, 72(SP) // push a16 | |||
| 82 | + | MOVQ syscallArgs_a17(R11), R12 | |||
| 83 | + | MOVQ R12, 80(SP) // push a17 | |||
| 84 | + | MOVQ syscallArgs_a18(R11), R12 | |||
| 85 | + | MOVQ R12, 88(SP) // push a18 | |||
| 86 | + | MOVQ syscallArgs_a19(R11), R12 | |||
| 87 | + | MOVQ R12, 96(SP) // push a19 | |||
| 88 | + | MOVQ syscallArgs_a20(R11), R12 | |||
| 89 | + | MOVQ R12, 104(SP) // push a20 | |||
| 90 | + | MOVQ syscallArgs_a21(R11), R12 | |||
| 91 | + | MOVQ R12, 112(SP) // push a21 | |||
| 92 | + | MOVQ syscallArgs_a22(R11), R12 | |||
| 93 | + | MOVQ R12, 120(SP) // push a22 | |||
| 94 | + | MOVQ syscallArgs_a23(R11), R12 | |||
| 95 | + | MOVQ R12, 128(SP) // push a23 | |||
| 96 | + | MOVQ syscallArgs_a24(R11), R12 | |||
| 97 | + | MOVQ R12, 136(SP) // push a24 | |||
| 98 | + | MOVQ syscallArgs_a25(R11), R12 | |||
| 99 | + | MOVQ R12, 144(SP) // push a25 | |||
| 100 | + | MOVQ syscallArgs_a26(R11), R12 | |||
| 101 | + | MOVQ R12, 152(SP) // push a26 | |||
| 102 | + | MOVQ syscallArgs_a27(R11), R12 | |||
| 103 | + | MOVQ R12, 160(SP) // push a27 | |||
| 104 | + | MOVQ syscallArgs_a28(R11), R12 | |||
| 105 | + | MOVQ R12, 168(SP) // push a28 | |||
| 106 | + | MOVQ syscallArgs_a29(R11), R12 | |||
| 107 | + | MOVQ R12, 176(SP) // push a29 | |||
| 108 | + | MOVQ syscallArgs_a30(R11), R12 | |||
| 109 | + | MOVQ R12, 184(SP) // push a30 | |||
| 110 | + | MOVQ syscallArgs_a31(R11), R12 | |||
| 111 | + | MOVQ R12, 192(SP) // push a31 | |||
| 112 | + | MOVQ syscallArgs_a32(R11), R12 | |||
| 113 | + | MOVQ R12, 200(SP) // push a32 | |||
| 80 | XORL AX, AX // vararg: say "no float args" | 114 | XORL AX, AX // vararg: say "no float args" | ||
| 81 | 115 | ||||
| 82 | - | MOVQ syscall15Args_fn(R11), R10 // fn | 116 | + | MOVQ syscallArgs_fn(R11), R10 // fn |
| 83 | CALL R10 | 117 | CALL R10 | ||
| 84 | 118 | ||||
| 85 | MOVQ PTR_ADDRESS(SP), DI // get the pointer back | 119 | MOVQ PTR_ADDRESS(SP), DI // get the pointer back | ||
| 86 | - | MOVQ AX, syscall15Args_a1(DI) // r1 | 120 | + | MOVQ AX, syscallArgs_a1(DI) // r1 |
| 87 | - | MOVQ DX, syscall15Args_a2(DI) // r2 | 121 | + | MOVQ DX, syscallArgs_a2(DI) // r2 |
| 88 | - | MOVQ X0, syscall15Args_f1(DI) // f1 | 122 | + | MOVQ X0, syscallArgs_f1(DI) // f1 |
| 89 | - | MOVQ X1, syscall15Args_f2(DI) // f2 | 123 | + | MOVQ X1, syscallArgs_f2(DI) // f2 |
| 90 | 124 | ||||
| 91 | #ifdef GOOS_darwin | 125 | #ifdef GOOS_darwin | ||
| 92 | CALL purego_error(SB) | 126 | CALL purego_error(SB) | ||
| 93 | MOVQ PTR_ADDRESS(SP), DI // reload (DI clobbered by call) | 127 | MOVQ PTR_ADDRESS(SP), DI // reload (DI clobbered by call) | ||
| 94 | MOVQ (AX), AX | 128 | MOVQ (AX), AX | ||
| 95 | - | MOVQ AX, syscall15Args_a3(DI) // save errno | 129 | + | MOVQ AX, syscallArgs_a3(DI) // save errno |
| 96 | #endif | 130 | #endif | ||
| 97 | 131 | ||||
| 98 | XORL AX, AX // no error (it's ignored anyway) | 132 | XORL AX, AX // no error (it's ignored anyway) | ||
M sys_arm.s +54 -54
| @@ -10,8 +10,8 @@ | |||
| 10 | 10 | #define STACK_SIZE 128 | |
| 11 | 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | |
| 12 | 12 | ||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | |
| 14 | - | // syscall15X takes a pointer to a struct like: | |
| 13 | + | // syscallX calls a function in libc on behalf of the syscall package. | |
| 14 | + | // syscallX takes a pointer to a struct like: | |
| 15 | 15 | // struct { | |
| 16 | 16 | // fn uintptr | |
| 17 | 17 | // a1 uintptr | |
| @@ -22,12 +22,12 @@ | |||
| 22 | 22 | // f16 uintptr | |
| 23 | 23 | // arm64_r8 uintptr | |
| 24 | 24 | // } | |
| 25 | - | // syscall15X must be called on the g0 stack with the | |
| 25 | + | // syscallX must be called on the g0 stack with the | |
| 26 | 26 | // C calling convention (use libcCall). | |
| 27 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4 | |
| 28 | - | DATA ·syscall15XABI0(SB)/4, $syscall15X(SB) | |
| 29 | - | TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |
| 30 | - | // Called via C calling convention: R0 = pointer to syscall15Args | |
| 27 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $4 | |
| 28 | + | DATA ·syscallXABI0(SB)/4, $syscallX(SB) | |
| 29 | + | TEXT syscallX(SB), NOSPLIT|NOFRAME, $0-0 | |
| 30 | + | // Called via C calling convention: R0 = pointer to syscallArgs | |
| 31 | 31 | // NOT via Go calling convention | |
| 32 | 32 | // Save link register and callee-saved registers first | |
| 33 | 33 | MOVW.W R14, -4(R13) // save LR (decrement and store) | |
| @@ -38,82 +38,82 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||
| 38 | 38 | MOVW R8, PTR_ADDRESS(R13) | |
| 39 | 39 | ||
| 40 | 40 | // Load function pointer first (before anything can corrupt R8) | |
| 41 | - | MOVW syscall15Args_fn(R8), R5 | |
| 41 | + | MOVW syscallArgs_fn(R8), R5 | |
| 42 | 42 | MOVW R5, (PTR_ADDRESS-4)(R13) // save fn at offset 56 | |
| 43 | 43 | ||
| 44 | 44 | // Load floating point arguments | |
| 45 | 45 | // Each float64 spans 2 uintptr slots (8 bytes) on ARM32, so we skip by 2 | |
| 46 | - | MOVD syscall15Args_f1(R8), F0 // f1+f2 -> D0 | |
| 47 | - | MOVD syscall15Args_f3(R8), F1 // f3+f4 -> D1 | |
| 48 | - | MOVD syscall15Args_f5(R8), F2 // f5+f6 -> D2 | |
| 49 | - | MOVD syscall15Args_f7(R8), F3 // f7+f8 -> D3 | |
| 50 | - | MOVD syscall15Args_f9(R8), F4 // f9+f10 -> D4 | |
| 51 | - | MOVD syscall15Args_f11(R8), F5 // f11+f12 -> D5 | |
| 52 | - | MOVD syscall15Args_f13(R8), F6 // f13+f14 -> D6 | |
| 53 | - | MOVD syscall15Args_f15(R8), F7 // f15+f16 -> D7 | |
| 46 | + | MOVD syscallArgs_f1(R8), F0 // f1+f2 -> D0 | |
| 47 | + | MOVD syscallArgs_f3(R8), F1 // f3+f4 -> D1 | |
| 48 | + | MOVD syscallArgs_f5(R8), F2 // f5+f6 -> D2 | |
| 49 | + | MOVD syscallArgs_f7(R8), F3 // f7+f8 -> D3 | |
| 50 | + | MOVD syscallArgs_f9(R8), F4 // f9+f10 -> D4 | |
| 51 | + | MOVD syscallArgs_f11(R8), F5 // f11+f12 -> D5 | |
| 52 | + | MOVD syscallArgs_f13(R8), F6 // f13+f14 -> D6 | |
| 53 | + | MOVD syscallArgs_f15(R8), F7 // f15+f16 -> D7 | |
| 54 | 54 | ||
| 55 | 55 | // Load integer arguments into registers (R0-R3 for ARM EABI) | |
| 56 | - | MOVW syscall15Args_a1(R8), R0 // a1 | |
| 57 | - | MOVW syscall15Args_a2(R8), R1 // a2 | |
| 58 | - | MOVW syscall15Args_a3(R8), R2 // a3 | |
| 59 | - | MOVW syscall15Args_a4(R8), R3 // a4 | |
| 56 | + | MOVW syscallArgs_a1(R8), R0 // a1 | |
| 57 | + | MOVW syscallArgs_a2(R8), R1 // a2 | |
| 58 | + | MOVW syscallArgs_a3(R8), R2 // a3 | |
| 59 | + | MOVW syscallArgs_a4(R8), R3 // a4 | |
| 60 | 60 | ||
| 61 | 61 | // push a5-a32 onto stack | |
| 62 | - | MOVW syscall15Args_a5(R8), R4 | |
| 62 | + | MOVW syscallArgs_a5(R8), R4 | |
| 63 | 63 | MOVW R4, 0(R13) | |
| 64 | - | MOVW syscall15Args_a6(R8), R4 | |
| 64 | + | MOVW syscallArgs_a6(R8), R4 | |
| 65 | 65 | MOVW R4, 4(R13) | |
| 66 | - | MOVW syscall15Args_a7(R8), R4 | |
| 66 | + | MOVW syscallArgs_a7(R8), R4 | |
| 67 | 67 | MOVW R4, 8(R13) | |
| 68 | - | MOVW syscall15Args_a8(R8), R4 | |
| 68 | + | MOVW syscallArgs_a8(R8), R4 | |
| 69 | 69 | MOVW R4, 12(R13) | |
| 70 | - | MOVW syscall15Args_a9(R8), R4 | |
| 70 | + | MOVW syscallArgs_a9(R8), R4 | |
| 71 | 71 | MOVW R4, 16(R13) | |
| 72 | - | MOVW syscall15Args_a10(R8), R4 | |
| 72 | + | MOVW syscallArgs_a10(R8), R4 | |
| 73 | 73 | MOVW R4, 20(R13) | |
| 74 | - | MOVW syscall15Args_a11(R8), R4 | |
| 74 | + | MOVW syscallArgs_a11(R8), R4 | |
| 75 | 75 | MOVW R4, 24(R13) | |
| 76 | - | MOVW syscall15Args_a12(R8), R4 | |
| 76 | + | MOVW syscallArgs_a12(R8), R4 | |
| 77 | 77 | MOVW R4, 28(R13) | |
| 78 | - | MOVW syscall15Args_a13(R8), R4 | |
| 78 | + | MOVW syscallArgs_a13(R8), R4 | |
| 79 | 79 | MOVW R4, 32(R13) | |
| 80 | - | MOVW syscall15Args_a14(R8), R4 | |
| 80 | + | MOVW syscallArgs_a14(R8), R4 | |
| 81 | 81 | MOVW R4, 36(R13) | |
| 82 | - | MOVW syscall15Args_a15(R8), R4 | |
| 82 | + | MOVW syscallArgs_a15(R8), R4 | |
| 83 | 83 | MOVW R4, 40(R13) | |
| 84 | - | MOVW syscall15Args_a16(R8), R4 | |
| 84 | + | MOVW syscallArgs_a16(R8), R4 | |
| 85 | 85 | MOVW R4, 44(R13) | |
| 86 | - | MOVW syscall15Args_a17(R8), R4 | |
| 86 | + | MOVW syscallArgs_a17(R8), R4 | |
| 87 | 87 | MOVW R4, 48(R13) | |
| 88 | - | MOVW syscall15Args_a18(R8), R4 | |
| 88 | + | MOVW syscallArgs_a18(R8), R4 | |
| 89 | 89 | MOVW R4, 52(R13) | |
| 90 | - | MOVW syscall15Args_a19(R8), R4 | |
| 90 | + | MOVW syscallArgs_a19(R8), R4 | |
| 91 | 91 | MOVW R4, 56(R13) | |
| 92 | - | MOVW syscall15Args_a20(R8), R4 | |
| 92 | + | MOVW syscallArgs_a20(R8), R4 | |
| 93 | 93 | MOVW R4, 60(R13) | |
| 94 | - | MOVW syscall15Args_a21(R8), R4 | |
| 94 | + | MOVW syscallArgs_a21(R8), R4 | |
| 95 | 95 | MOVW R4, 64(R13) | |
| 96 | - | MOVW syscall15Args_a22(R8), R4 | |
| 96 | + | MOVW syscallArgs_a22(R8), R4 | |
| 97 | 97 | MOVW R4, 68(R13) | |
| 98 | - | MOVW syscall15Args_a23(R8), R4 | |
| 98 | + | MOVW syscallArgs_a23(R8), R4 | |
| 99 | 99 | MOVW R4, 72(R13) | |
| 100 | - | MOVW syscall15Args_a24(R8), R4 | |
| 100 | + | MOVW syscallArgs_a24(R8), R4 | |
| 101 | 101 | MOVW R4, 76(R13) | |
| 102 | - | MOVW syscall15Args_a25(R8), R4 | |
| 102 | + | MOVW syscallArgs_a25(R8), R4 | |
| 103 | 103 | MOVW R4, 80(R13) | |
| 104 | - | MOVW syscall15Args_a26(R8), R4 | |
| 104 | + | MOVW syscallArgs_a26(R8), R4 | |
| 105 | 105 | MOVW R4, 84(R13) | |
| 106 | - | MOVW syscall15Args_a27(R8), R4 | |
| 106 | + | MOVW syscallArgs_a27(R8), R4 | |
| 107 | 107 | MOVW R4, 88(R13) | |
| 108 | - | MOVW syscall15Args_a28(R8), R4 | |
| 108 | + | MOVW syscallArgs_a28(R8), R4 | |
| 109 | 109 | MOVW R4, 92(R13) | |
| 110 | - | MOVW syscall15Args_a29(R8), R4 | |
| 110 | + | MOVW syscallArgs_a29(R8), R4 | |
| 111 | 111 | MOVW R4, 96(R13) | |
| 112 | - | MOVW syscall15Args_a30(R8), R4 | |
| 112 | + | MOVW syscallArgs_a30(R8), R4 | |
| 113 | 113 | MOVW R4, 100(R13) | |
| 114 | - | MOVW syscall15Args_a31(R8), R4 | |
| 114 | + | MOVW syscallArgs_a31(R8), R4 | |
| 115 | 115 | MOVW R4, 104(R13) | |
| 116 | - | MOVW syscall15Args_a32(R8), R4 | |
| 116 | + | MOVW syscallArgs_a32(R8), R4 | |
| 117 | 117 | MOVW R4, 108(R13) | |
| 118 | 118 | ||
| 119 | 119 | // Load saved function pointer and call | |
| @@ -128,14 +128,14 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||
| 128 | 128 | ADD $STACK_SIZE, R13 | |
| 129 | 129 | ||
| 130 | 130 | // save R0, R1 | |
| 131 | - | MOVW R0, syscall15Args_a1(R8) | |
| 132 | - | MOVW R1, syscall15Args_a2(R8) | |
| 131 | + | MOVW R0, syscallArgs_a1(R8) | |
| 132 | + | MOVW R1, syscallArgs_a2(R8) | |
| 133 | 133 | ||
| 134 | 134 | // save f0-f3 (each float64 spans 2 uintptr slots on ARM32) | |
| 135 | - | MOVD F0, syscall15Args_f1(R8) | |
| 136 | - | MOVD F1, syscall15Args_f3(R8) | |
| 137 | - | MOVD F2, syscall15Args_f5(R8) | |
| 138 | - | MOVD F3, syscall15Args_f7(R8) | |
| 135 | + | MOVD F0, syscallArgs_f1(R8) | |
| 136 | + | MOVD F1, syscallArgs_f3(R8) | |
| 137 | + | MOVD F2, syscallArgs_f5(R8) | |
| 138 | + | MOVD F3, syscallArgs_f7(R8) | |
| 139 | 139 | ||
| 140 | 140 | // Restore callee-saved registers and return | |
| 141 | 141 | MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, R11] | |
| @@ -10,8 +10,8 @@ | |||||
| 10 | #define STACK_SIZE 128 | 10 | #define STACK_SIZE 128 | ||
| 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | 11 | #define PTR_ADDRESS (STACK_SIZE - 4) | ||
| 12 | 12 | ||||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | 13 | + | // syscallX calls a function in libc on behalf of the syscall package. |
| 14 | - | // syscall15X takes a pointer to a struct like: | 14 | + | // syscallX takes a pointer to a struct like: |
| 15 | // struct { | 15 | // struct { | ||
| 16 | // fn uintptr | 16 | // fn uintptr | ||
| 17 | // a1 uintptr | 17 | // a1 uintptr | ||
| @@ -22,12 +22,12 @@ | |||||
| 22 | // f16 uintptr | 22 | // f16 uintptr | ||
| 23 | // arm64_r8 uintptr | 23 | // arm64_r8 uintptr | ||
| 24 | // } | 24 | // } | ||
| 25 | - | // syscall15X must be called on the g0 stack with the | 25 | + | // syscallX must be called on the g0 stack with the |
| 26 | // C calling convention (use libcCall). | 26 | // C calling convention (use libcCall). | ||
| 27 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4 | 27 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $4 |
| 28 | - | DATA ·syscall15XABI0(SB)/4, $syscall15X(SB) | 28 | + | DATA ·syscallXABI0(SB)/4, $syscallX(SB) |
| 29 | - | TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | 29 | + | TEXT syscallX(SB), NOSPLIT|NOFRAME, $0-0 |
| 30 | - | // Called via C calling convention: R0 = pointer to syscall15Args | 30 | + | // Called via C calling convention: R0 = pointer to syscallArgs |
| 31 | // NOT via Go calling convention | 31 | // NOT via Go calling convention | ||
| 32 | // Save link register and callee-saved registers first | 32 | // Save link register and callee-saved registers first | ||
| 33 | MOVW.W R14, -4(R13) // save LR (decrement and store) | 33 | MOVW.W R14, -4(R13) // save LR (decrement and store) | ||
| @@ -38,82 +38,82 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||||
| 38 | MOVW R8, PTR_ADDRESS(R13) | 38 | MOVW R8, PTR_ADDRESS(R13) | ||
| 39 | 39 | ||||
| 40 | // Load function pointer first (before anything can corrupt R8) | 40 | // Load function pointer first (before anything can corrupt R8) | ||
| 41 | - | MOVW syscall15Args_fn(R8), R5 | 41 | + | MOVW syscallArgs_fn(R8), R5 |
| 42 | MOVW R5, (PTR_ADDRESS-4)(R13) // save fn at offset 56 | 42 | MOVW R5, (PTR_ADDRESS-4)(R13) // save fn at offset 56 | ||
| 43 | 43 | ||||
| 44 | // Load floating point arguments | 44 | // Load floating point arguments | ||
| 45 | // Each float64 spans 2 uintptr slots (8 bytes) on ARM32, so we skip by 2 | 45 | // Each float64 spans 2 uintptr slots (8 bytes) on ARM32, so we skip by 2 | ||
| 46 | - | MOVD syscall15Args_f1(R8), F0 // f1+f2 -> D0 | 46 | + | MOVD syscallArgs_f1(R8), F0 // f1+f2 -> D0 |
| 47 | - | MOVD syscall15Args_f3(R8), F1 // f3+f4 -> D1 | 47 | + | MOVD syscallArgs_f3(R8), F1 // f3+f4 -> D1 |
| 48 | - | MOVD syscall15Args_f5(R8), F2 // f5+f6 -> D2 | 48 | + | MOVD syscallArgs_f5(R8), F2 // f5+f6 -> D2 |
| 49 | - | MOVD syscall15Args_f7(R8), F3 // f7+f8 -> D3 | 49 | + | MOVD syscallArgs_f7(R8), F3 // f7+f8 -> D3 |
| 50 | - | MOVD syscall15Args_f9(R8), F4 // f9+f10 -> D4 | 50 | + | MOVD syscallArgs_f9(R8), F4 // f9+f10 -> D4 |
| 51 | - | MOVD syscall15Args_f11(R8), F5 // f11+f12 -> D5 | 51 | + | MOVD syscallArgs_f11(R8), F5 // f11+f12 -> D5 |
| 52 | - | MOVD syscall15Args_f13(R8), F6 // f13+f14 -> D6 | 52 | + | MOVD syscallArgs_f13(R8), F6 // f13+f14 -> D6 |
| 53 | - | MOVD syscall15Args_f15(R8), F7 // f15+f16 -> D7 | 53 | + | MOVD syscallArgs_f15(R8), F7 // f15+f16 -> D7 |
| 54 | 54 | ||||
| 55 | // Load integer arguments into registers (R0-R3 for ARM EABI) | 55 | // Load integer arguments into registers (R0-R3 for ARM EABI) | ||
| 56 | - | MOVW syscall15Args_a1(R8), R0 // a1 | 56 | + | MOVW syscallArgs_a1(R8), R0 // a1 |
| 57 | - | MOVW syscall15Args_a2(R8), R1 // a2 | 57 | + | MOVW syscallArgs_a2(R8), R1 // a2 |
| 58 | - | MOVW syscall15Args_a3(R8), R2 // a3 | 58 | + | MOVW syscallArgs_a3(R8), R2 // a3 |
| 59 | - | MOVW syscall15Args_a4(R8), R3 // a4 | 59 | + | MOVW syscallArgs_a4(R8), R3 // a4 |
| 60 | 60 | ||||
| 61 | // push a5-a32 onto stack | 61 | // push a5-a32 onto stack | ||
| 62 | - | MOVW syscall15Args_a5(R8), R4 | 62 | + | MOVW syscallArgs_a5(R8), R4 |
| 63 | MOVW R4, 0(R13) | 63 | MOVW R4, 0(R13) | ||
| 64 | - | MOVW syscall15Args_a6(R8), R4 | 64 | + | MOVW syscallArgs_a6(R8), R4 |
| 65 | MOVW R4, 4(R13) | 65 | MOVW R4, 4(R13) | ||
| 66 | - | MOVW syscall15Args_a7(R8), R4 | 66 | + | MOVW syscallArgs_a7(R8), R4 |
| 67 | MOVW R4, 8(R13) | 67 | MOVW R4, 8(R13) | ||
| 68 | - | MOVW syscall15Args_a8(R8), R4 | 68 | + | MOVW syscallArgs_a8(R8), R4 |
| 69 | MOVW R4, 12(R13) | 69 | MOVW R4, 12(R13) | ||
| 70 | - | MOVW syscall15Args_a9(R8), R4 | 70 | + | MOVW syscallArgs_a9(R8), R4 |
| 71 | MOVW R4, 16(R13) | 71 | MOVW R4, 16(R13) | ||
| 72 | - | MOVW syscall15Args_a10(R8), R4 | 72 | + | MOVW syscallArgs_a10(R8), R4 |
| 73 | MOVW R4, 20(R13) | 73 | MOVW R4, 20(R13) | ||
| 74 | - | MOVW syscall15Args_a11(R8), R4 | 74 | + | MOVW syscallArgs_a11(R8), R4 |
| 75 | MOVW R4, 24(R13) | 75 | MOVW R4, 24(R13) | ||
| 76 | - | MOVW syscall15Args_a12(R8), R4 | 76 | + | MOVW syscallArgs_a12(R8), R4 |
| 77 | MOVW R4, 28(R13) | 77 | MOVW R4, 28(R13) | ||
| 78 | - | MOVW syscall15Args_a13(R8), R4 | 78 | + | MOVW syscallArgs_a13(R8), R4 |
| 79 | MOVW R4, 32(R13) | 79 | MOVW R4, 32(R13) | ||
| 80 | - | MOVW syscall15Args_a14(R8), R4 | 80 | + | MOVW syscallArgs_a14(R8), R4 |
| 81 | MOVW R4, 36(R13) | 81 | MOVW R4, 36(R13) | ||
| 82 | - | MOVW syscall15Args_a15(R8), R4 | 82 | + | MOVW syscallArgs_a15(R8), R4 |
| 83 | MOVW R4, 40(R13) | 83 | MOVW R4, 40(R13) | ||
| 84 | - | MOVW syscall15Args_a16(R8), R4 | 84 | + | MOVW syscallArgs_a16(R8), R4 |
| 85 | MOVW R4, 44(R13) | 85 | MOVW R4, 44(R13) | ||
| 86 | - | MOVW syscall15Args_a17(R8), R4 | 86 | + | MOVW syscallArgs_a17(R8), R4 |
| 87 | MOVW R4, 48(R13) | 87 | MOVW R4, 48(R13) | ||
| 88 | - | MOVW syscall15Args_a18(R8), R4 | 88 | + | MOVW syscallArgs_a18(R8), R4 |
| 89 | MOVW R4, 52(R13) | 89 | MOVW R4, 52(R13) | ||
| 90 | - | MOVW syscall15Args_a19(R8), R4 | 90 | + | MOVW syscallArgs_a19(R8), R4 |
| 91 | MOVW R4, 56(R13) | 91 | MOVW R4, 56(R13) | ||
| 92 | - | MOVW syscall15Args_a20(R8), R4 | 92 | + | MOVW syscallArgs_a20(R8), R4 |
| 93 | MOVW R4, 60(R13) | 93 | MOVW R4, 60(R13) | ||
| 94 | - | MOVW syscall15Args_a21(R8), R4 | 94 | + | MOVW syscallArgs_a21(R8), R4 |
| 95 | MOVW R4, 64(R13) | 95 | MOVW R4, 64(R13) | ||
| 96 | - | MOVW syscall15Args_a22(R8), R4 | 96 | + | MOVW syscallArgs_a22(R8), R4 |
| 97 | MOVW R4, 68(R13) | 97 | MOVW R4, 68(R13) | ||
| 98 | - | MOVW syscall15Args_a23(R8), R4 | 98 | + | MOVW syscallArgs_a23(R8), R4 |
| 99 | MOVW R4, 72(R13) | 99 | MOVW R4, 72(R13) | ||
| 100 | - | MOVW syscall15Args_a24(R8), R4 | 100 | + | MOVW syscallArgs_a24(R8), R4 |
| 101 | MOVW R4, 76(R13) | 101 | MOVW R4, 76(R13) | ||
| 102 | - | MOVW syscall15Args_a25(R8), R4 | 102 | + | MOVW syscallArgs_a25(R8), R4 |
| 103 | MOVW R4, 80(R13) | 103 | MOVW R4, 80(R13) | ||
| 104 | - | MOVW syscall15Args_a26(R8), R4 | 104 | + | MOVW syscallArgs_a26(R8), R4 |
| 105 | MOVW R4, 84(R13) | 105 | MOVW R4, 84(R13) | ||
| 106 | - | MOVW syscall15Args_a27(R8), R4 | 106 | + | MOVW syscallArgs_a27(R8), R4 |
| 107 | MOVW R4, 88(R13) | 107 | MOVW R4, 88(R13) | ||
| 108 | - | MOVW syscall15Args_a28(R8), R4 | 108 | + | MOVW syscallArgs_a28(R8), R4 |
| 109 | MOVW R4, 92(R13) | 109 | MOVW R4, 92(R13) | ||
| 110 | - | MOVW syscall15Args_a29(R8), R4 | 110 | + | MOVW syscallArgs_a29(R8), R4 |
| 111 | MOVW R4, 96(R13) | 111 | MOVW R4, 96(R13) | ||
| 112 | - | MOVW syscall15Args_a30(R8), R4 | 112 | + | MOVW syscallArgs_a30(R8), R4 |
| 113 | MOVW R4, 100(R13) | 113 | MOVW R4, 100(R13) | ||
| 114 | - | MOVW syscall15Args_a31(R8), R4 | 114 | + | MOVW syscallArgs_a31(R8), R4 |
| 115 | MOVW R4, 104(R13) | 115 | MOVW R4, 104(R13) | ||
| 116 | - | MOVW syscall15Args_a32(R8), R4 | 116 | + | MOVW syscallArgs_a32(R8), R4 |
| 117 | MOVW R4, 108(R13) | 117 | MOVW R4, 108(R13) | ||
| 118 | 118 | ||||
| 119 | // Load saved function pointer and call | 119 | // Load saved function pointer and call | ||
| @@ -128,14 +128,14 @@ TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0 | |||||
| 128 | ADD $STACK_SIZE, R13 | 128 | ADD $STACK_SIZE, R13 | ||
| 129 | 129 | ||||
| 130 | // save R0, R1 | 130 | // save R0, R1 | ||
| 131 | - | MOVW R0, syscall15Args_a1(R8) | 131 | + | MOVW R0, syscallArgs_a1(R8) |
| 132 | - | MOVW R1, syscall15Args_a2(R8) | 132 | + | MOVW R1, syscallArgs_a2(R8) |
| 133 | 133 | ||||
| 134 | // save f0-f3 (each float64 spans 2 uintptr slots on ARM32) | 134 | // save f0-f3 (each float64 spans 2 uintptr slots on ARM32) | ||
| 135 | - | MOVD F0, syscall15Args_f1(R8) | 135 | + | MOVD F0, syscallArgs_f1(R8) |
| 136 | - | MOVD F1, syscall15Args_f3(R8) | 136 | + | MOVD F1, syscallArgs_f3(R8) |
| 137 | - | MOVD F2, syscall15Args_f5(R8) | 137 | + | MOVD F2, syscallArgs_f5(R8) |
| 138 | - | MOVD F3, syscall15Args_f7(R8) | 138 | + | MOVD F3, syscallArgs_f7(R8) |
| 139 | 139 | ||||
| 140 | // Restore callee-saved registers and return | 140 | // Restore callee-saved registers and return | ||
| 141 | MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, R11] | 141 | MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, R11] | ||
M sys_arm64.s +73 -39
| @@ -7,11 +7,11 @@ | |||
| 7 | 7 | #include "go_asm.h" | |
| 8 | 8 | #include "funcdata.h" | |
| 9 | 9 | ||
| 10 | - | #define STACK_SIZE 64 | |
| 10 | + | #define STACK_SIZE 208 | |
| 11 | 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | |
| 12 | 12 | ||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | |
| 14 | - | // syscall15X takes a pointer to a struct like: | |
| 13 | + | // syscallX calls a function in libc on behalf of the syscall package. | |
| 14 | + | // syscallX takes a pointer to a struct like: | |
| 15 | 15 | // struct { | |
| 16 | 16 | // fn uintptr | |
| 17 | 17 | // a1 uintptr | |
| @@ -33,66 +33,100 @@ | |||
| 33 | 33 | // r2 uintptr | |
| 34 | 34 | // err uintptr | |
| 35 | 35 | // } | |
| 36 | - | // syscall15X must be called on the g0 stack with the | |
| 36 | + | // syscallX must be called on the g0 stack with the | |
| 37 | 37 | // C calling convention (use libcCall). | |
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 40 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |
| 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 40 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 41 | 41 | SUB $STACK_SIZE, RSP // push structure pointer | |
| 42 | 42 | MOVD R0, PTR_ADDRESS(RSP) | |
| 43 | 43 | MOVD R0, R9 | |
| 44 | 44 | ||
| 45 | - | FMOVD syscall15Args_f1(R9), F0 // f1 | |
| 46 | - | FMOVD syscall15Args_f2(R9), F1 // f2 | |
| 47 | - | FMOVD syscall15Args_f3(R9), F2 // f3 | |
| 48 | - | FMOVD syscall15Args_f4(R9), F3 // f4 | |
| 49 | - | FMOVD syscall15Args_f5(R9), F4 // f5 | |
| 50 | - | FMOVD syscall15Args_f6(R9), F5 // f6 | |
| 51 | - | FMOVD syscall15Args_f7(R9), F6 // f7 | |
| 52 | - | FMOVD syscall15Args_f8(R9), F7 // f8 | |
| 45 | + | FMOVD syscallArgs_f1(R9), F0 // f1 | |
| 46 | + | FMOVD syscallArgs_f2(R9), F1 // f2 | |
| 47 | + | FMOVD syscallArgs_f3(R9), F2 // f3 | |
| 48 | + | FMOVD syscallArgs_f4(R9), F3 // f4 | |
| 49 | + | FMOVD syscallArgs_f5(R9), F4 // f5 | |
| 50 | + | FMOVD syscallArgs_f6(R9), F5 // f6 | |
| 51 | + | FMOVD syscallArgs_f7(R9), F6 // f7 | |
| 52 | + | FMOVD syscallArgs_f8(R9), F7 // f8 | |
| 53 | 53 | ||
| 54 | - | MOVD syscall15Args_a1(R9), R0 // a1 | |
| 55 | - | MOVD syscall15Args_a2(R9), R1 // a2 | |
| 56 | - | MOVD syscall15Args_a3(R9), R2 // a3 | |
| 57 | - | MOVD syscall15Args_a4(R9), R3 // a4 | |
| 58 | - | MOVD syscall15Args_a5(R9), R4 // a5 | |
| 59 | - | MOVD syscall15Args_a6(R9), R5 // a6 | |
| 60 | - | MOVD syscall15Args_a7(R9), R6 // a7 | |
| 61 | - | MOVD syscall15Args_a8(R9), R7 // a8 | |
| 62 | - | MOVD syscall15Args_arm64_r8(R9), R8 // r8 | |
| 54 | + | MOVD syscallArgs_a1(R9), R0 // a1 | |
| 55 | + | MOVD syscallArgs_a2(R9), R1 // a2 | |
| 56 | + | MOVD syscallArgs_a3(R9), R2 // a3 | |
| 57 | + | MOVD syscallArgs_a4(R9), R3 // a4 | |
| 58 | + | MOVD syscallArgs_a5(R9), R4 // a5 | |
| 59 | + | MOVD syscallArgs_a6(R9), R5 // a6 | |
| 60 | + | MOVD syscallArgs_a7(R9), R6 // a7 | |
| 61 | + | MOVD syscallArgs_a8(R9), R7 // a8 | |
| 62 | + | MOVD syscallArgs_arm64_r8(R9), R8 // r8 | |
| 63 | 63 | ||
| 64 | - | MOVD syscall15Args_a9(R9), R10 | |
| 64 | + | MOVD syscallArgs_a9(R9), R10 | |
| 65 | 65 | MOVD R10, 0(RSP) // push a9 onto stack | |
| 66 | - | MOVD syscall15Args_a10(R9), R10 | |
| 66 | + | MOVD syscallArgs_a10(R9), R10 | |
| 67 | 67 | MOVD R10, 8(RSP) // push a10 onto stack | |
| 68 | - | MOVD syscall15Args_a11(R9), R10 | |
| 68 | + | MOVD syscallArgs_a11(R9), R10 | |
| 69 | 69 | MOVD R10, 16(RSP) // push a11 onto stack | |
| 70 | - | MOVD syscall15Args_a12(R9), R10 | |
| 70 | + | MOVD syscallArgs_a12(R9), R10 | |
| 71 | 71 | MOVD R10, 24(RSP) // push a12 onto stack | |
| 72 | - | MOVD syscall15Args_a13(R9), R10 | |
| 72 | + | MOVD syscallArgs_a13(R9), R10 | |
| 73 | 73 | MOVD R10, 32(RSP) // push a13 onto stack | |
| 74 | - | MOVD syscall15Args_a14(R9), R10 | |
| 74 | + | MOVD syscallArgs_a14(R9), R10 | |
| 75 | 75 | MOVD R10, 40(RSP) // push a14 onto stack | |
| 76 | - | MOVD syscall15Args_a15(R9), R10 | |
| 76 | + | MOVD syscallArgs_a15(R9), R10 | |
| 77 | 77 | MOVD R10, 48(RSP) // push a15 onto stack | |
| 78 | + | MOVD syscallArgs_a16(R9), R10 | |
| 79 | + | MOVD R10, 56(RSP) // push a16 onto stack | |
| 80 | + | MOVD syscallArgs_a17(R9), R10 | |
| 81 | + | MOVD R10, 64(RSP) // push a17 onto stack | |
| 82 | + | MOVD syscallArgs_a18(R9), R10 | |
| 83 | + | MOVD R10, 72(RSP) // push a18 onto stack | |
| 84 | + | MOVD syscallArgs_a19(R9), R10 | |
| 85 | + | MOVD R10, 80(RSP) // push a19 onto stack | |
| 86 | + | MOVD syscallArgs_a20(R9), R10 | |
| 87 | + | MOVD R10, 88(RSP) // push a20 onto stack | |
| 88 | + | MOVD syscallArgs_a21(R9), R10 | |
| 89 | + | MOVD R10, 96(RSP) // push a21 onto stack | |
| 90 | + | MOVD syscallArgs_a22(R9), R10 | |
| 91 | + | MOVD R10, 104(RSP) // push a22 onto stack | |
| 92 | + | MOVD syscallArgs_a23(R9), R10 | |
| 93 | + | MOVD R10, 112(RSP) // push a23 onto stack | |
| 94 | + | MOVD syscallArgs_a24(R9), R10 | |
| 95 | + | MOVD R10, 120(RSP) // push a24 onto stack | |
| 96 | + | MOVD syscallArgs_a25(R9), R10 | |
| 97 | + | MOVD R10, 128(RSP) // push a25 onto stack | |
| 98 | + | MOVD syscallArgs_a26(R9), R10 | |
| 99 | + | MOVD R10, 136(RSP) // push a26 onto stack | |
| 100 | + | MOVD syscallArgs_a27(R9), R10 | |
| 101 | + | MOVD R10, 144(RSP) // push a27 onto stack | |
| 102 | + | MOVD syscallArgs_a28(R9), R10 | |
| 103 | + | MOVD R10, 152(RSP) // push a28 onto stack | |
| 104 | + | MOVD syscallArgs_a29(R9), R10 | |
| 105 | + | MOVD R10, 160(RSP) // push a29 onto stack | |
| 106 | + | MOVD syscallArgs_a30(R9), R10 | |
| 107 | + | MOVD R10, 168(RSP) // push a30 onto stack | |
| 108 | + | MOVD syscallArgs_a31(R9), R10 | |
| 109 | + | MOVD R10, 176(RSP) // push a31 onto stack | |
| 110 | + | MOVD syscallArgs_a32(R9), R10 | |
| 111 | + | MOVD R10, 184(RSP) // push a32 onto stack | |
| 78 | 112 | ||
| 79 | - | MOVD syscall15Args_fn(R9), R10 // fn | |
| 113 | + | MOVD syscallArgs_fn(R9), R10 // fn | |
| 80 | 114 | BL (R10) | |
| 81 | 115 | ||
| 82 | 116 | MOVD PTR_ADDRESS(RSP), R2 // pop structure pointer | |
| 83 | 117 | ADD $STACK_SIZE, RSP | |
| 84 | 118 | ||
| 85 | - | MOVD R0, syscall15Args_a1(R2) // save r1 | |
| 86 | - | MOVD R1, syscall15Args_a2(R2) // save r3 | |
| 87 | - | FMOVD F0, syscall15Args_f1(R2) // save f0 | |
| 88 | - | FMOVD F1, syscall15Args_f2(R2) // save f1 | |
| 89 | - | FMOVD F2, syscall15Args_f3(R2) // save f2 | |
| 90 | - | FMOVD F3, syscall15Args_f4(R2) // save f3 | |
| 119 | + | MOVD R0, syscallArgs_a1(R2) // save r1 | |
| 120 | + | MOVD R1, syscallArgs_a2(R2) // save r3 | |
| 121 | + | FMOVD F0, syscallArgs_f1(R2) // save f0 | |
| 122 | + | FMOVD F1, syscallArgs_f2(R2) // save f1 | |
| 123 | + | FMOVD F2, syscallArgs_f3(R2) // save f2 | |
| 124 | + | FMOVD F3, syscallArgs_f4(R2) // save f3 | |
| 91 | 125 | ||
| 92 | 126 | #ifdef GOOS_darwin | |
| 93 | 127 | BL purego_error(SB) | |
| 94 | 128 | MOVD (R0), R0 | |
| 95 | - | MOVD R0, syscall15Args_a3(R2) // save errno | |
| 129 | + | MOVD R0, syscallArgs_a3(R2) // save errno | |
| 96 | 130 | ||
| 97 | 131 | #endif | |
| 98 | 132 | RET | |
| @@ -7,11 +7,11 @@ | |||||
| 7 | #include "go_asm.h" | 7 | #include "go_asm.h" | ||
| 8 | #include "funcdata.h" | 8 | #include "funcdata.h" | ||
| 9 | 9 | ||||
| 10 | - | #define STACK_SIZE 64 | 10 | + | #define STACK_SIZE 208 |
| 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | ||
| 12 | 12 | ||||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | 13 | + | // syscallX calls a function in libc on behalf of the syscall package. |
| 14 | - | // syscall15X takes a pointer to a struct like: | 14 | + | // syscallX takes a pointer to a struct like: |
| 15 | // struct { | 15 | // struct { | ||
| 16 | // fn uintptr | 16 | // fn uintptr | ||
| 17 | // a1 uintptr | 17 | // a1 uintptr | ||
| @@ -33,66 +33,100 @@ | |||||
| 33 | // r2 uintptr | 33 | // r2 uintptr | ||
| 34 | // err uintptr | 34 | // err uintptr | ||
| 35 | // } | 35 | // } | ||
| 36 | - | // syscall15X must be called on the g0 stack with the | 36 | + | // syscallX must be called on the g0 stack with the |
| 37 | // C calling convention (use libcCall). | 37 | // C calling convention (use libcCall). | ||
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 40 | - | TEXT syscall15X(SB), NOSPLIT, $0 | 40 | + | TEXT syscallX(SB), NOSPLIT, $0 |
| 41 | SUB $STACK_SIZE, RSP // push structure pointer | 41 | SUB $STACK_SIZE, RSP // push structure pointer | ||
| 42 | MOVD R0, PTR_ADDRESS(RSP) | 42 | MOVD R0, PTR_ADDRESS(RSP) | ||
| 43 | MOVD R0, R9 | 43 | MOVD R0, R9 | ||
| 44 | 44 | ||||
| 45 | - | FMOVD syscall15Args_f1(R9), F0 // f1 | 45 | + | FMOVD syscallArgs_f1(R9), F0 // f1 |
| 46 | - | FMOVD syscall15Args_f2(R9), F1 // f2 | 46 | + | FMOVD syscallArgs_f2(R9), F1 // f2 |
| 47 | - | FMOVD syscall15Args_f3(R9), F2 // f3 | 47 | + | FMOVD syscallArgs_f3(R9), F2 // f3 |
| 48 | - | FMOVD syscall15Args_f4(R9), F3 // f4 | 48 | + | FMOVD syscallArgs_f4(R9), F3 // f4 |
| 49 | - | FMOVD syscall15Args_f5(R9), F4 // f5 | 49 | + | FMOVD syscallArgs_f5(R9), F4 // f5 |
| 50 | - | FMOVD syscall15Args_f6(R9), F5 // f6 | 50 | + | FMOVD syscallArgs_f6(R9), F5 // f6 |
| 51 | - | FMOVD syscall15Args_f7(R9), F6 // f7 | 51 | + | FMOVD syscallArgs_f7(R9), F6 // f7 |
| 52 | - | FMOVD syscall15Args_f8(R9), F7 // f8 | 52 | + | FMOVD syscallArgs_f8(R9), F7 // f8 |
| 53 | 53 | ||||
| 54 | - | MOVD syscall15Args_a1(R9), R0 // a1 | 54 | + | MOVD syscallArgs_a1(R9), R0 // a1 |
| 55 | - | MOVD syscall15Args_a2(R9), R1 // a2 | 55 | + | MOVD syscallArgs_a2(R9), R1 // a2 |
| 56 | - | MOVD syscall15Args_a3(R9), R2 // a3 | 56 | + | MOVD syscallArgs_a3(R9), R2 // a3 |
| 57 | - | MOVD syscall15Args_a4(R9), R3 // a4 | 57 | + | MOVD syscallArgs_a4(R9), R3 // a4 |
| 58 | - | MOVD syscall15Args_a5(R9), R4 // a5 | 58 | + | MOVD syscallArgs_a5(R9), R4 // a5 |
| 59 | - | MOVD syscall15Args_a6(R9), R5 // a6 | 59 | + | MOVD syscallArgs_a6(R9), R5 // a6 |
| 60 | - | MOVD syscall15Args_a7(R9), R6 // a7 | 60 | + | MOVD syscallArgs_a7(R9), R6 // a7 |
| 61 | - | MOVD syscall15Args_a8(R9), R7 // a8 | 61 | + | MOVD syscallArgs_a8(R9), R7 // a8 |
| 62 | - | MOVD syscall15Args_arm64_r8(R9), R8 // r8 | 62 | + | MOVD syscallArgs_arm64_r8(R9), R8 // r8 |
| 63 | 63 | ||||
| 64 | - | MOVD syscall15Args_a9(R9), R10 | 64 | + | MOVD syscallArgs_a9(R9), R10 |
| 65 | MOVD R10, 0(RSP) // push a9 onto stack | 65 | MOVD R10, 0(RSP) // push a9 onto stack | ||
| 66 | - | MOVD syscall15Args_a10(R9), R10 | 66 | + | MOVD syscallArgs_a10(R9), R10 |
| 67 | MOVD R10, 8(RSP) // push a10 onto stack | 67 | MOVD R10, 8(RSP) // push a10 onto stack | ||
| 68 | - | MOVD syscall15Args_a11(R9), R10 | 68 | + | MOVD syscallArgs_a11(R9), R10 |
| 69 | MOVD R10, 16(RSP) // push a11 onto stack | 69 | MOVD R10, 16(RSP) // push a11 onto stack | ||
| 70 | - | MOVD syscall15Args_a12(R9), R10 | 70 | + | MOVD syscallArgs_a12(R9), R10 |
| 71 | MOVD R10, 24(RSP) // push a12 onto stack | 71 | MOVD R10, 24(RSP) // push a12 onto stack | ||
| 72 | - | MOVD syscall15Args_a13(R9), R10 | 72 | + | MOVD syscallArgs_a13(R9), R10 |
| 73 | MOVD R10, 32(RSP) // push a13 onto stack | 73 | MOVD R10, 32(RSP) // push a13 onto stack | ||
| 74 | - | MOVD syscall15Args_a14(R9), R10 | 74 | + | MOVD syscallArgs_a14(R9), R10 |
| 75 | MOVD R10, 40(RSP) // push a14 onto stack | 75 | MOVD R10, 40(RSP) // push a14 onto stack | ||
| 76 | - | MOVD syscall15Args_a15(R9), R10 | 76 | + | MOVD syscallArgs_a15(R9), R10 |
| 77 | MOVD R10, 48(RSP) // push a15 onto stack | 77 | MOVD R10, 48(RSP) // push a15 onto stack | ||
| 78 | + | MOVD syscallArgs_a16(R9), R10 | |||
| 79 | + | MOVD R10, 56(RSP) // push a16 onto stack | |||
| 80 | + | MOVD syscallArgs_a17(R9), R10 | |||
| 81 | + | MOVD R10, 64(RSP) // push a17 onto stack | |||
| 82 | + | MOVD syscallArgs_a18(R9), R10 | |||
| 83 | + | MOVD R10, 72(RSP) // push a18 onto stack | |||
| 84 | + | MOVD syscallArgs_a19(R9), R10 | |||
| 85 | + | MOVD R10, 80(RSP) // push a19 onto stack | |||
| 86 | + | MOVD syscallArgs_a20(R9), R10 | |||
| 87 | + | MOVD R10, 88(RSP) // push a20 onto stack | |||
| 88 | + | MOVD syscallArgs_a21(R9), R10 | |||
| 89 | + | MOVD R10, 96(RSP) // push a21 onto stack | |||
| 90 | + | MOVD syscallArgs_a22(R9), R10 | |||
| 91 | + | MOVD R10, 104(RSP) // push a22 onto stack | |||
| 92 | + | MOVD syscallArgs_a23(R9), R10 | |||
| 93 | + | MOVD R10, 112(RSP) // push a23 onto stack | |||
| 94 | + | MOVD syscallArgs_a24(R9), R10 | |||
| 95 | + | MOVD R10, 120(RSP) // push a24 onto stack | |||
| 96 | + | MOVD syscallArgs_a25(R9), R10 | |||
| 97 | + | MOVD R10, 128(RSP) // push a25 onto stack | |||
| 98 | + | MOVD syscallArgs_a26(R9), R10 | |||
| 99 | + | MOVD R10, 136(RSP) // push a26 onto stack | |||
| 100 | + | MOVD syscallArgs_a27(R9), R10 | |||
| 101 | + | MOVD R10, 144(RSP) // push a27 onto stack | |||
| 102 | + | MOVD syscallArgs_a28(R9), R10 | |||
| 103 | + | MOVD R10, 152(RSP) // push a28 onto stack | |||
| 104 | + | MOVD syscallArgs_a29(R9), R10 | |||
| 105 | + | MOVD R10, 160(RSP) // push a29 onto stack | |||
| 106 | + | MOVD syscallArgs_a30(R9), R10 | |||
| 107 | + | MOVD R10, 168(RSP) // push a30 onto stack | |||
| 108 | + | MOVD syscallArgs_a31(R9), R10 | |||
| 109 | + | MOVD R10, 176(RSP) // push a31 onto stack | |||
| 110 | + | MOVD syscallArgs_a32(R9), R10 | |||
| 111 | + | MOVD R10, 184(RSP) // push a32 onto stack | |||
| 78 | 112 | ||||
| 79 | - | MOVD syscall15Args_fn(R9), R10 // fn | 113 | + | MOVD syscallArgs_fn(R9), R10 // fn |
| 80 | BL (R10) | 114 | BL (R10) | ||
| 81 | 115 | ||||
| 82 | MOVD PTR_ADDRESS(RSP), R2 // pop structure pointer | 116 | MOVD PTR_ADDRESS(RSP), R2 // pop structure pointer | ||
| 83 | ADD $STACK_SIZE, RSP | 117 | ADD $STACK_SIZE, RSP | ||
| 84 | 118 | ||||
| 85 | - | MOVD R0, syscall15Args_a1(R2) // save r1 | 119 | + | MOVD R0, syscallArgs_a1(R2) // save r1 |
| 86 | - | MOVD R1, syscall15Args_a2(R2) // save r3 | 120 | + | MOVD R1, syscallArgs_a2(R2) // save r3 |
| 87 | - | FMOVD F0, syscall15Args_f1(R2) // save f0 | 121 | + | FMOVD F0, syscallArgs_f1(R2) // save f0 |
| 88 | - | FMOVD F1, syscall15Args_f2(R2) // save f1 | 122 | + | FMOVD F1, syscallArgs_f2(R2) // save f1 |
| 89 | - | FMOVD F2, syscall15Args_f3(R2) // save f2 | 123 | + | FMOVD F2, syscallArgs_f3(R2) // save f2 |
| 90 | - | FMOVD F3, syscall15Args_f4(R2) // save f3 | 124 | + | FMOVD F3, syscallArgs_f4(R2) // save f3 |
| 91 | 125 | ||||
| 92 | #ifdef GOOS_darwin | 126 | #ifdef GOOS_darwin | ||
| 93 | BL purego_error(SB) | 127 | BL purego_error(SB) | ||
| 94 | MOVD (R0), R0 | 128 | MOVD (R0), R0 | ||
| 95 | - | MOVD R0, syscall15Args_a3(R2) // save errno | 129 | + | MOVD R0, syscallArgs_a3(R2) // save errno |
| 96 | 130 | ||||
| 97 | #endif | 131 | #endif | ||
| 98 | RET | 132 | RET | ||
M sys_loong64.s +71 -37
| @@ -7,11 +7,11 @@ | |||
| 7 | 7 | #include "go_asm.h" | |
| 8 | 8 | #include "funcdata.h" | |
| 9 | 9 | ||
| 10 | - | #define STACK_SIZE 64 | |
| 10 | + | #define STACK_SIZE 208 | |
| 11 | 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | |
| 12 | 12 | ||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | |
| 14 | - | // syscall15X takes a pointer to a struct like: | |
| 13 | + | // syscallX calls a function in libc on behalf of the syscall package. | |
| 14 | + | // syscallX takes a pointer to a struct like: | |
| 15 | 15 | // struct { | |
| 16 | 16 | // fn uintptr | |
| 17 | 17 | // a1 uintptr | |
| @@ -33,51 +33,85 @@ | |||
| 33 | 33 | // r2 uintptr | |
| 34 | 34 | // err uintptr | |
| 35 | 35 | // } | |
| 36 | - | // syscall15X must be called on the g0 stack with the | |
| 36 | + | // syscallX must be called on the g0 stack with the | |
| 37 | 37 | // C calling convention (use libcCall). | |
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 40 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |
| 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 40 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 41 | 41 | // push structure pointer | |
| 42 | 42 | SUBV $STACK_SIZE, R3 | |
| 43 | 43 | MOVV R4, PTR_ADDRESS(R3) | |
| 44 | 44 | MOVV R4, R13 | |
| 45 | 45 | ||
| 46 | - | MOVD syscall15Args_f1(R13), F0 // f1 | |
| 47 | - | MOVD syscall15Args_f2(R13), F1 // f2 | |
| 48 | - | MOVD syscall15Args_f3(R13), F2 // f3 | |
| 49 | - | MOVD syscall15Args_f4(R13), F3 // f4 | |
| 50 | - | MOVD syscall15Args_f5(R13), F4 // f5 | |
| 51 | - | MOVD syscall15Args_f6(R13), F5 // f6 | |
| 52 | - | MOVD syscall15Args_f7(R13), F6 // f7 | |
| 53 | - | MOVD syscall15Args_f8(R13), F7 // f8 | |
| 46 | + | MOVD syscallArgs_f1(R13), F0 // f1 | |
| 47 | + | MOVD syscallArgs_f2(R13), F1 // f2 | |
| 48 | + | MOVD syscallArgs_f3(R13), F2 // f3 | |
| 49 | + | MOVD syscallArgs_f4(R13), F3 // f4 | |
| 50 | + | MOVD syscallArgs_f5(R13), F4 // f5 | |
| 51 | + | MOVD syscallArgs_f6(R13), F5 // f6 | |
| 52 | + | MOVD syscallArgs_f7(R13), F6 // f7 | |
| 53 | + | MOVD syscallArgs_f8(R13), F7 // f8 | |
| 54 | 54 | ||
| 55 | - | MOVV syscall15Args_a1(R13), R4 // a1 | |
| 56 | - | MOVV syscall15Args_a2(R13), R5 // a2 | |
| 57 | - | MOVV syscall15Args_a3(R13), R6 // a3 | |
| 58 | - | MOVV syscall15Args_a4(R13), R7 // a4 | |
| 59 | - | MOVV syscall15Args_a5(R13), R8 // a5 | |
| 60 | - | MOVV syscall15Args_a6(R13), R9 // a6 | |
| 61 | - | MOVV syscall15Args_a7(R13), R10 // a7 | |
| 62 | - | MOVV syscall15Args_a8(R13), R11 // a8 | |
| 55 | + | MOVV syscallArgs_a1(R13), R4 // a1 | |
| 56 | + | MOVV syscallArgs_a2(R13), R5 // a2 | |
| 57 | + | MOVV syscallArgs_a3(R13), R6 // a3 | |
| 58 | + | MOVV syscallArgs_a4(R13), R7 // a4 | |
| 59 | + | MOVV syscallArgs_a5(R13), R8 // a5 | |
| 60 | + | MOVV syscallArgs_a6(R13), R9 // a6 | |
| 61 | + | MOVV syscallArgs_a7(R13), R10 // a7 | |
| 62 | + | MOVV syscallArgs_a8(R13), R11 // a8 | |
| 63 | 63 | ||
| 64 | 64 | // push a9-a15 onto stack | |
| 65 | - | MOVV syscall15Args_a9(R13), R12 | |
| 65 | + | MOVV syscallArgs_a9(R13), R12 | |
| 66 | 66 | MOVV R12, 0(R3) | |
| 67 | - | MOVV syscall15Args_a10(R13), R12 | |
| 67 | + | MOVV syscallArgs_a10(R13), R12 | |
| 68 | 68 | MOVV R12, 8(R3) | |
| 69 | - | MOVV syscall15Args_a11(R13), R12 | |
| 69 | + | MOVV syscallArgs_a11(R13), R12 | |
| 70 | 70 | MOVV R12, 16(R3) | |
| 71 | - | MOVV syscall15Args_a12(R13), R12 | |
| 71 | + | MOVV syscallArgs_a12(R13), R12 | |
| 72 | 72 | MOVV R12, 24(R3) | |
| 73 | - | MOVV syscall15Args_a13(R13), R12 | |
| 73 | + | MOVV syscallArgs_a13(R13), R12 | |
| 74 | 74 | MOVV R12, 32(R3) | |
| 75 | - | MOVV syscall15Args_a14(R13), R12 | |
| 75 | + | MOVV syscallArgs_a14(R13), R12 | |
| 76 | 76 | MOVV R12, 40(R3) | |
| 77 | - | MOVV syscall15Args_a15(R13), R12 | |
| 77 | + | MOVV syscallArgs_a15(R13), R12 | |
| 78 | 78 | MOVV R12, 48(R3) | |
| 79 | + | MOVV syscallArgs_a16(R13), R12 | |
| 80 | + | MOVV R12, 56(R3) | |
| 81 | + | MOVV syscallArgs_a17(R13), R12 | |
| 82 | + | MOVV R12, 64(R3) | |
| 83 | + | MOVV syscallArgs_a18(R13), R12 | |
| 84 | + | MOVV R12, 72(R3) | |
| 85 | + | MOVV syscallArgs_a19(R13), R12 | |
| 86 | + | MOVV R12, 80(R3) | |
| 87 | + | MOVV syscallArgs_a20(R13), R12 | |
| 88 | + | MOVV R12, 88(R3) | |
| 89 | + | MOVV syscallArgs_a21(R13), R12 | |
| 90 | + | MOVV R12, 96(R3) | |
| 91 | + | MOVV syscallArgs_a22(R13), R12 | |
| 92 | + | MOVV R12, 104(R3) | |
| 93 | + | MOVV syscallArgs_a23(R13), R12 | |
| 94 | + | MOVV R12, 112(R3) | |
| 95 | + | MOVV syscallArgs_a24(R13), R12 | |
| 96 | + | MOVV R12, 120(R3) | |
| 97 | + | MOVV syscallArgs_a25(R13), R12 | |
| 98 | + | MOVV R12, 128(R3) | |
| 99 | + | MOVV syscallArgs_a26(R13), R12 | |
| 100 | + | MOVV R12, 136(R3) | |
| 101 | + | MOVV syscallArgs_a27(R13), R12 | |
| 102 | + | MOVV R12, 144(R3) | |
| 103 | + | MOVV syscallArgs_a28(R13), R12 | |
| 104 | + | MOVV R12, 152(R3) | |
| 105 | + | MOVV syscallArgs_a29(R13), R12 | |
| 106 | + | MOVV R12, 160(R3) | |
| 107 | + | MOVV syscallArgs_a30(R13), R12 | |
| 108 | + | MOVV R12, 168(R3) | |
| 109 | + | MOVV syscallArgs_a31(R13), R12 | |
| 110 | + | MOVV R12, 176(R3) | |
| 111 | + | MOVV syscallArgs_a32(R13), R12 | |
| 112 | + | MOVV R12, 184(R3) | |
| 79 | 113 | ||
| 80 | - | MOVV syscall15Args_fn(R13), R12 | |
| 114 | + | MOVV syscallArgs_fn(R13), R12 | |
| 81 | 115 | JAL (R12) | |
| 82 | 116 | ||
| 83 | 117 | // pop structure pointer | |
| @@ -85,12 +119,12 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 85 | 119 | ADDV $STACK_SIZE, R3 | |
| 86 | 120 | ||
| 87 | 121 | // save R4, R5 | |
| 88 | - | MOVV R4, syscall15Args_a1(R13) | |
| 89 | - | MOVV R5, syscall15Args_a2(R13) | |
| 122 | + | MOVV R4, syscallArgs_a1(R13) | |
| 123 | + | MOVV R5, syscallArgs_a2(R13) | |
| 90 | 124 | ||
| 91 | 125 | // save f0-f3 | |
| 92 | - | MOVD F0, syscall15Args_f1(R13) | |
| 93 | - | MOVD F1, syscall15Args_f2(R13) | |
| 94 | - | MOVD F2, syscall15Args_f3(R13) | |
| 95 | - | MOVD F3, syscall15Args_f4(R13) | |
| 126 | + | MOVD F0, syscallArgs_f1(R13) | |
| 127 | + | MOVD F1, syscallArgs_f2(R13) | |
| 128 | + | MOVD F2, syscallArgs_f3(R13) | |
| 129 | + | MOVD F3, syscallArgs_f4(R13) | |
| 96 | 130 | RET | |
| @@ -7,11 +7,11 @@ | |||||
| 7 | #include "go_asm.h" | 7 | #include "go_asm.h" | ||
| 8 | #include "funcdata.h" | 8 | #include "funcdata.h" | ||
| 9 | 9 | ||||
| 10 | - | #define STACK_SIZE 64 | 10 | + | #define STACK_SIZE 208 |
| 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | 11 | #define PTR_ADDRESS (STACK_SIZE - 8) | ||
| 12 | 12 | ||||
| 13 | - | // syscall15X calls a function in libc on behalf of the syscall package. | 13 | + | // syscallX calls a function in libc on behalf of the syscall package. |
| 14 | - | // syscall15X takes a pointer to a struct like: | 14 | + | // syscallX takes a pointer to a struct like: |
| 15 | // struct { | 15 | // struct { | ||
| 16 | // fn uintptr | 16 | // fn uintptr | ||
| 17 | // a1 uintptr | 17 | // a1 uintptr | ||
| @@ -33,51 +33,85 @@ | |||||
| 33 | // r2 uintptr | 33 | // r2 uintptr | ||
| 34 | // err uintptr | 34 | // err uintptr | ||
| 35 | // } | 35 | // } | ||
| 36 | - | // syscall15X must be called on the g0 stack with the | 36 | + | // syscallX must be called on the g0 stack with the |
| 37 | // C calling convention (use libcCall). | 37 | // C calling convention (use libcCall). | ||
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 40 | - | TEXT syscall15X(SB), NOSPLIT, $0 | 40 | + | TEXT syscallX(SB), NOSPLIT, $0 |
| 41 | // push structure pointer | 41 | // push structure pointer | ||
| 42 | SUBV $STACK_SIZE, R3 | 42 | SUBV $STACK_SIZE, R3 | ||
| 43 | MOVV R4, PTR_ADDRESS(R3) | 43 | MOVV R4, PTR_ADDRESS(R3) | ||
| 44 | MOVV R4, R13 | 44 | MOVV R4, R13 | ||
| 45 | 45 | ||||
| 46 | - | MOVD syscall15Args_f1(R13), F0 // f1 | 46 | + | MOVD syscallArgs_f1(R13), F0 // f1 |
| 47 | - | MOVD syscall15Args_f2(R13), F1 // f2 | 47 | + | MOVD syscallArgs_f2(R13), F1 // f2 |
| 48 | - | MOVD syscall15Args_f3(R13), F2 // f3 | 48 | + | MOVD syscallArgs_f3(R13), F2 // f3 |
| 49 | - | MOVD syscall15Args_f4(R13), F3 // f4 | 49 | + | MOVD syscallArgs_f4(R13), F3 // f4 |
| 50 | - | MOVD syscall15Args_f5(R13), F4 // f5 | 50 | + | MOVD syscallArgs_f5(R13), F4 // f5 |
| 51 | - | MOVD syscall15Args_f6(R13), F5 // f6 | 51 | + | MOVD syscallArgs_f6(R13), F5 // f6 |
| 52 | - | MOVD syscall15Args_f7(R13), F6 // f7 | 52 | + | MOVD syscallArgs_f7(R13), F6 // f7 |
| 53 | - | MOVD syscall15Args_f8(R13), F7 // f8 | 53 | + | MOVD syscallArgs_f8(R13), F7 // f8 |
| 54 | 54 | ||||
| 55 | - | MOVV syscall15Args_a1(R13), R4 // a1 | 55 | + | MOVV syscallArgs_a1(R13), R4 // a1 |
| 56 | - | MOVV syscall15Args_a2(R13), R5 // a2 | 56 | + | MOVV syscallArgs_a2(R13), R5 // a2 |
| 57 | - | MOVV syscall15Args_a3(R13), R6 // a3 | 57 | + | MOVV syscallArgs_a3(R13), R6 // a3 |
| 58 | - | MOVV syscall15Args_a4(R13), R7 // a4 | 58 | + | MOVV syscallArgs_a4(R13), R7 // a4 |
| 59 | - | MOVV syscall15Args_a5(R13), R8 // a5 | 59 | + | MOVV syscallArgs_a5(R13), R8 // a5 |
| 60 | - | MOVV syscall15Args_a6(R13), R9 // a6 | 60 | + | MOVV syscallArgs_a6(R13), R9 // a6 |
| 61 | - | MOVV syscall15Args_a7(R13), R10 // a7 | 61 | + | MOVV syscallArgs_a7(R13), R10 // a7 |
| 62 | - | MOVV syscall15Args_a8(R13), R11 // a8 | 62 | + | MOVV syscallArgs_a8(R13), R11 // a8 |
| 63 | 63 | ||||
| 64 | // push a9-a15 onto stack | 64 | // push a9-a15 onto stack | ||
| 65 | - | MOVV syscall15Args_a9(R13), R12 | 65 | + | MOVV syscallArgs_a9(R13), R12 |
| 66 | MOVV R12, 0(R3) | 66 | MOVV R12, 0(R3) | ||
| 67 | - | MOVV syscall15Args_a10(R13), R12 | 67 | + | MOVV syscallArgs_a10(R13), R12 |
| 68 | MOVV R12, 8(R3) | 68 | MOVV R12, 8(R3) | ||
| 69 | - | MOVV syscall15Args_a11(R13), R12 | 69 | + | MOVV syscallArgs_a11(R13), R12 |
| 70 | MOVV R12, 16(R3) | 70 | MOVV R12, 16(R3) | ||
| 71 | - | MOVV syscall15Args_a12(R13), R12 | 71 | + | MOVV syscallArgs_a12(R13), R12 |
| 72 | MOVV R12, 24(R3) | 72 | MOVV R12, 24(R3) | ||
| 73 | - | MOVV syscall15Args_a13(R13), R12 | 73 | + | MOVV syscallArgs_a13(R13), R12 |
| 74 | MOVV R12, 32(R3) | 74 | MOVV R12, 32(R3) | ||
| 75 | - | MOVV syscall15Args_a14(R13), R12 | 75 | + | MOVV syscallArgs_a14(R13), R12 |
| 76 | MOVV R12, 40(R3) | 76 | MOVV R12, 40(R3) | ||
| 77 | - | MOVV syscall15Args_a15(R13), R12 | 77 | + | MOVV syscallArgs_a15(R13), R12 |
| 78 | MOVV R12, 48(R3) | 78 | MOVV R12, 48(R3) | ||
| 79 | + | MOVV syscallArgs_a16(R13), R12 | |||
| 80 | + | MOVV R12, 56(R3) | |||
| 81 | + | MOVV syscallArgs_a17(R13), R12 | |||
| 82 | + | MOVV R12, 64(R3) | |||
| 83 | + | MOVV syscallArgs_a18(R13), R12 | |||
| 84 | + | MOVV R12, 72(R3) | |||
| 85 | + | MOVV syscallArgs_a19(R13), R12 | |||
| 86 | + | MOVV R12, 80(R3) | |||
| 87 | + | MOVV syscallArgs_a20(R13), R12 | |||
| 88 | + | MOVV R12, 88(R3) | |||
| 89 | + | MOVV syscallArgs_a21(R13), R12 | |||
| 90 | + | MOVV R12, 96(R3) | |||
| 91 | + | MOVV syscallArgs_a22(R13), R12 | |||
| 92 | + | MOVV R12, 104(R3) | |||
| 93 | + | MOVV syscallArgs_a23(R13), R12 | |||
| 94 | + | MOVV R12, 112(R3) | |||
| 95 | + | MOVV syscallArgs_a24(R13), R12 | |||
| 96 | + | MOVV R12, 120(R3) | |||
| 97 | + | MOVV syscallArgs_a25(R13), R12 | |||
| 98 | + | MOVV R12, 128(R3) | |||
| 99 | + | MOVV syscallArgs_a26(R13), R12 | |||
| 100 | + | MOVV R12, 136(R3) | |||
| 101 | + | MOVV syscallArgs_a27(R13), R12 | |||
| 102 | + | MOVV R12, 144(R3) | |||
| 103 | + | MOVV syscallArgs_a28(R13), R12 | |||
| 104 | + | MOVV R12, 152(R3) | |||
| 105 | + | MOVV syscallArgs_a29(R13), R12 | |||
| 106 | + | MOVV R12, 160(R3) | |||
| 107 | + | MOVV syscallArgs_a30(R13), R12 | |||
| 108 | + | MOVV R12, 168(R3) | |||
| 109 | + | MOVV syscallArgs_a31(R13), R12 | |||
| 110 | + | MOVV R12, 176(R3) | |||
| 111 | + | MOVV syscallArgs_a32(R13), R12 | |||
| 112 | + | MOVV R12, 184(R3) | |||
| 79 | 113 | ||||
| 80 | - | MOVV syscall15Args_fn(R13), R12 | 114 | + | MOVV syscallArgs_fn(R13), R12 |
| 81 | JAL (R12) | 115 | JAL (R12) | ||
| 82 | 116 | ||||
| 83 | // pop structure pointer | 117 | // pop structure pointer | ||
| @@ -85,12 +119,12 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||||
| 85 | ADDV $STACK_SIZE, R3 | 119 | ADDV $STACK_SIZE, R3 | ||
| 86 | 120 | ||||
| 87 | // save R4, R5 | 121 | // save R4, R5 | ||
| 88 | - | MOVV R4, syscall15Args_a1(R13) | 122 | + | MOVV R4, syscallArgs_a1(R13) |
| 89 | - | MOVV R5, syscall15Args_a2(R13) | 123 | + | MOVV R5, syscallArgs_a2(R13) |
| 90 | 124 | ||||
| 91 | // save f0-f3 | 125 | // save f0-f3 | ||
| 92 | - | MOVD F0, syscall15Args_f1(R13) | 126 | + | MOVD F0, syscallArgs_f1(R13) |
| 93 | - | MOVD F1, syscall15Args_f2(R13) | 127 | + | MOVD F1, syscallArgs_f2(R13) |
| 94 | - | MOVD F2, syscall15Args_f3(R13) | 128 | + | MOVD F2, syscallArgs_f3(R13) |
| 95 | - | MOVD F3, syscall15Args_f4(R13) | 129 | + | MOVD F3, syscallArgs_f4(R13) |
| 96 | RET | 130 | RET | ||
M sys_ppc64le.s +34 -34
| @@ -35,10 +35,10 @@ | |||
| 35 | 35 | #define TOC_SAVE 160 | |
| 36 | 36 | #define ARGP_SAVE 168 | |
| 37 | 37 | ||
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 40 | 40 | ||
| 41 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |
| 41 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 42 | 42 | // Prologue: create stack frame | |
| 43 | 43 | // R3 contains the args pointer on entry | |
| 44 | 44 | MOVD R1, R12 // save old SP | |
| @@ -51,49 +51,49 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 51 | 51 | // Save args pointer (in R3) | |
| 52 | 52 | MOVD R3, ARGP_SAVE(R1) | |
| 53 | 53 | ||
| 54 | - | // R11 := args pointer (syscall15Args*) | |
| 54 | + | // R11 := args pointer (syscallArgs*) | |
| 55 | 55 | MOVD R3, R11 | |
| 56 | 56 | ||
| 57 | 57 | // Load float args into F1-F8 | |
| 58 | - | FMOVD syscall15Args_f1(R11), F1 | |
| 59 | - | FMOVD syscall15Args_f2(R11), F2 | |
| 60 | - | FMOVD syscall15Args_f3(R11), F3 | |
| 61 | - | FMOVD syscall15Args_f4(R11), F4 | |
| 62 | - | FMOVD syscall15Args_f5(R11), F5 | |
| 63 | - | FMOVD syscall15Args_f6(R11), F6 | |
| 64 | - | FMOVD syscall15Args_f7(R11), F7 | |
| 65 | - | FMOVD syscall15Args_f8(R11), F8 | |
| 58 | + | FMOVD syscallArgs_f1(R11), F1 | |
| 59 | + | FMOVD syscallArgs_f2(R11), F2 | |
| 60 | + | FMOVD syscallArgs_f3(R11), F3 | |
| 61 | + | FMOVD syscallArgs_f4(R11), F4 | |
| 62 | + | FMOVD syscallArgs_f5(R11), F5 | |
| 63 | + | FMOVD syscallArgs_f6(R11), F6 | |
| 64 | + | FMOVD syscallArgs_f7(R11), F7 | |
| 65 | + | FMOVD syscallArgs_f8(R11), F8 | |
| 66 | 66 | ||
| 67 | 67 | // Load integer args into R3-R10 | |
| 68 | - | MOVD syscall15Args_a1(R11), R3 | |
| 69 | - | MOVD syscall15Args_a2(R11), R4 | |
| 70 | - | MOVD syscall15Args_a3(R11), R5 | |
| 71 | - | MOVD syscall15Args_a4(R11), R6 | |
| 72 | - | MOVD syscall15Args_a5(R11), R7 | |
| 73 | - | MOVD syscall15Args_a6(R11), R8 | |
| 74 | - | MOVD syscall15Args_a7(R11), R9 | |
| 75 | - | MOVD syscall15Args_a8(R11), R10 | |
| 68 | + | MOVD syscallArgs_a1(R11), R3 | |
| 69 | + | MOVD syscallArgs_a2(R11), R4 | |
| 70 | + | MOVD syscallArgs_a3(R11), R5 | |
| 71 | + | MOVD syscallArgs_a4(R11), R6 | |
| 72 | + | MOVD syscallArgs_a5(R11), R7 | |
| 73 | + | MOVD syscallArgs_a6(R11), R8 | |
| 74 | + | MOVD syscallArgs_a7(R11), R9 | |
| 75 | + | MOVD syscallArgs_a8(R11), R10 | |
| 76 | 76 | ||
| 77 | 77 | // Spill a9-a15 onto the stack (stack parameters start at 96(R1)) | |
| 78 | 78 | // Per ELFv2: parameter save area is 32-95, stack args start at 96 | |
| 79 | 79 | MOVD ARGP_SAVE(R1), R11 // reload args pointer | |
| 80 | - | MOVD syscall15Args_a9(R11), R12 | |
| 80 | + | MOVD syscallArgs_a9(R11), R12 | |
| 81 | 81 | MOVD R12, 96(R1) // a9 at 96(R1) | |
| 82 | - | MOVD syscall15Args_a10(R11), R12 | |
| 82 | + | MOVD syscallArgs_a10(R11), R12 | |
| 83 | 83 | MOVD R12, 104(R1) // a10 at 104(R1) | |
| 84 | - | MOVD syscall15Args_a11(R11), R12 | |
| 84 | + | MOVD syscallArgs_a11(R11), R12 | |
| 85 | 85 | MOVD R12, 112(R1) // a11 at 112(R1) | |
| 86 | - | MOVD syscall15Args_a12(R11), R12 | |
| 86 | + | MOVD syscallArgs_a12(R11), R12 | |
| 87 | 87 | MOVD R12, 120(R1) // a12 at 120(R1) | |
| 88 | - | MOVD syscall15Args_a13(R11), R12 | |
| 88 | + | MOVD syscallArgs_a13(R11), R12 | |
| 89 | 89 | MOVD R12, 128(R1) // a13 at 128(R1) | |
| 90 | - | MOVD syscall15Args_a14(R11), R12 | |
| 90 | + | MOVD syscallArgs_a14(R11), R12 | |
| 91 | 91 | MOVD R12, 136(R1) // a14 at 136(R1) | |
| 92 | - | MOVD syscall15Args_a15(R11), R12 | |
| 92 | + | MOVD syscallArgs_a15(R11), R12 | |
| 93 | 93 | MOVD R12, 144(R1) // a15 at 144(R1) | |
| 94 | 94 | ||
| 95 | 95 | // Call function: load fn and call | |
| 96 | - | MOVD syscall15Args_fn(R11), R12 | |
| 96 | + | MOVD syscallArgs_fn(R11), R12 | |
| 97 | 97 | MOVD R12, CTR | |
| 98 | 98 | BL (CTR) | |
| 99 | 99 | ||
| @@ -104,14 +104,14 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 104 | 104 | MOVD ARGP_SAVE(R1), R11 | |
| 105 | 105 | ||
| 106 | 106 | // Store integer results back (R3, R4) | |
| 107 | - | MOVD R3, syscall15Args_a1(R11) | |
| 108 | - | MOVD R4, syscall15Args_a2(R11) | |
| 107 | + | MOVD R3, syscallArgs_a1(R11) | |
| 108 | + | MOVD R4, syscallArgs_a2(R11) | |
| 109 | 109 | ||
| 110 | 110 | // Store float return values (F1-F4) | |
| 111 | - | FMOVD F1, syscall15Args_f1(R11) | |
| 112 | - | FMOVD F2, syscall15Args_f2(R11) | |
| 113 | - | FMOVD F3, syscall15Args_f3(R11) | |
| 114 | - | FMOVD F4, syscall15Args_f4(R11) | |
| 111 | + | FMOVD F1, syscallArgs_f1(R11) | |
| 112 | + | FMOVD F2, syscallArgs_f2(R11) | |
| 113 | + | FMOVD F3, syscallArgs_f3(R11) | |
| 114 | + | FMOVD F4, syscallArgs_f4(R11) | |
| 115 | 115 | ||
| 116 | 116 | // Epilogue: restore and return | |
| 117 | 117 | MOVD LR_SAVE(R1), R12 | |
| @@ -35,10 +35,10 @@ | |||||
| 35 | #define TOC_SAVE 160 | 35 | #define TOC_SAVE 160 | ||
| 36 | #define ARGP_SAVE 168 | 36 | #define ARGP_SAVE 168 | ||
| 37 | 37 | ||||
| 38 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 38 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 |
| 39 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 39 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 40 | 40 | ||||
| 41 | - | TEXT syscall15X(SB), NOSPLIT, $0 | 41 | + | TEXT syscallX(SB), NOSPLIT, $0 |
| 42 | // Prologue: create stack frame | 42 | // Prologue: create stack frame | ||
| 43 | // R3 contains the args pointer on entry | 43 | // R3 contains the args pointer on entry | ||
| 44 | MOVD R1, R12 // save old SP | 44 | MOVD R1, R12 // save old SP | ||
| @@ -51,49 +51,49 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||||
| 51 | // Save args pointer (in R3) | 51 | // Save args pointer (in R3) | ||
| 52 | MOVD R3, ARGP_SAVE(R1) | 52 | MOVD R3, ARGP_SAVE(R1) | ||
| 53 | 53 | ||||
| 54 | - | // R11 := args pointer (syscall15Args*) | 54 | + | // R11 := args pointer (syscallArgs*) |
| 55 | MOVD R3, R11 | 55 | MOVD R3, R11 | ||
| 56 | 56 | ||||
| 57 | // Load float args into F1-F8 | 57 | // Load float args into F1-F8 | ||
| 58 | - | FMOVD syscall15Args_f1(R11), F1 | 58 | + | FMOVD syscallArgs_f1(R11), F1 |
| 59 | - | FMOVD syscall15Args_f2(R11), F2 | 59 | + | FMOVD syscallArgs_f2(R11), F2 |
| 60 | - | FMOVD syscall15Args_f3(R11), F3 | 60 | + | FMOVD syscallArgs_f3(R11), F3 |
| 61 | - | FMOVD syscall15Args_f4(R11), F4 | 61 | + | FMOVD syscallArgs_f4(R11), F4 |
| 62 | - | FMOVD syscall15Args_f5(R11), F5 | 62 | + | FMOVD syscallArgs_f5(R11), F5 |
| 63 | - | FMOVD syscall15Args_f6(R11), F6 | 63 | + | FMOVD syscallArgs_f6(R11), F6 |
| 64 | - | FMOVD syscall15Args_f7(R11), F7 | 64 | + | FMOVD syscallArgs_f7(R11), F7 |
| 65 | - | FMOVD syscall15Args_f8(R11), F8 | 65 | + | FMOVD syscallArgs_f8(R11), F8 |
| 66 | 66 | ||||
| 67 | // Load integer args into R3-R10 | 67 | // Load integer args into R3-R10 | ||
| 68 | - | MOVD syscall15Args_a1(R11), R3 | 68 | + | MOVD syscallArgs_a1(R11), R3 |
| 69 | - | MOVD syscall15Args_a2(R11), R4 | 69 | + | MOVD syscallArgs_a2(R11), R4 |
| 70 | - | MOVD syscall15Args_a3(R11), R5 | 70 | + | MOVD syscallArgs_a3(R11), R5 |
| 71 | - | MOVD syscall15Args_a4(R11), R6 | 71 | + | MOVD syscallArgs_a4(R11), R6 |
| 72 | - | MOVD syscall15Args_a5(R11), R7 | 72 | + | MOVD syscallArgs_a5(R11), R7 |
| 73 | - | MOVD syscall15Args_a6(R11), R8 | 73 | + | MOVD syscallArgs_a6(R11), R8 |
| 74 | - | MOVD syscall15Args_a7(R11), R9 | 74 | + | MOVD syscallArgs_a7(R11), R9 |
| 75 | - | MOVD syscall15Args_a8(R11), R10 | 75 | + | MOVD syscallArgs_a8(R11), R10 |
| 76 | 76 | ||||
| 77 | // Spill a9-a15 onto the stack (stack parameters start at 96(R1)) | 77 | // Spill a9-a15 onto the stack (stack parameters start at 96(R1)) | ||
| 78 | // Per ELFv2: parameter save area is 32-95, stack args start at 96 | 78 | // Per ELFv2: parameter save area is 32-95, stack args start at 96 | ||
| 79 | MOVD ARGP_SAVE(R1), R11 // reload args pointer | 79 | MOVD ARGP_SAVE(R1), R11 // reload args pointer | ||
| 80 | - | MOVD syscall15Args_a9(R11), R12 | 80 | + | MOVD syscallArgs_a9(R11), R12 |
| 81 | MOVD R12, 96(R1) // a9 at 96(R1) | 81 | MOVD R12, 96(R1) // a9 at 96(R1) | ||
| 82 | - | MOVD syscall15Args_a10(R11), R12 | 82 | + | MOVD syscallArgs_a10(R11), R12 |
| 83 | MOVD R12, 104(R1) // a10 at 104(R1) | 83 | MOVD R12, 104(R1) // a10 at 104(R1) | ||
| 84 | - | MOVD syscall15Args_a11(R11), R12 | 84 | + | MOVD syscallArgs_a11(R11), R12 |
| 85 | MOVD R12, 112(R1) // a11 at 112(R1) | 85 | MOVD R12, 112(R1) // a11 at 112(R1) | ||
| 86 | - | MOVD syscall15Args_a12(R11), R12 | 86 | + | MOVD syscallArgs_a12(R11), R12 |
| 87 | MOVD R12, 120(R1) // a12 at 120(R1) | 87 | MOVD R12, 120(R1) // a12 at 120(R1) | ||
| 88 | - | MOVD syscall15Args_a13(R11), R12 | 88 | + | MOVD syscallArgs_a13(R11), R12 |
| 89 | MOVD R12, 128(R1) // a13 at 128(R1) | 89 | MOVD R12, 128(R1) // a13 at 128(R1) | ||
| 90 | - | MOVD syscall15Args_a14(R11), R12 | 90 | + | MOVD syscallArgs_a14(R11), R12 |
| 91 | MOVD R12, 136(R1) // a14 at 136(R1) | 91 | MOVD R12, 136(R1) // a14 at 136(R1) | ||
| 92 | - | MOVD syscall15Args_a15(R11), R12 | 92 | + | MOVD syscallArgs_a15(R11), R12 |
| 93 | MOVD R12, 144(R1) // a15 at 144(R1) | 93 | MOVD R12, 144(R1) // a15 at 144(R1) | ||
| 94 | 94 | ||||
| 95 | // Call function: load fn and call | 95 | // Call function: load fn and call | ||
| 96 | - | MOVD syscall15Args_fn(R11), R12 | 96 | + | MOVD syscallArgs_fn(R11), R12 |
| 97 | MOVD R12, CTR | 97 | MOVD R12, CTR | ||
| 98 | BL (CTR) | 98 | BL (CTR) | ||
| 99 | 99 | ||||
| @@ -104,14 +104,14 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||||
| 104 | MOVD ARGP_SAVE(R1), R11 | 104 | MOVD ARGP_SAVE(R1), R11 | ||
| 105 | 105 | ||||
| 106 | // Store integer results back (R3, R4) | 106 | // Store integer results back (R3, R4) | ||
| 107 | - | MOVD R3, syscall15Args_a1(R11) | 107 | + | MOVD R3, syscallArgs_a1(R11) |
| 108 | - | MOVD R4, syscall15Args_a2(R11) | 108 | + | MOVD R4, syscallArgs_a2(R11) |
| 109 | 109 | ||||
| 110 | // Store float return values (F1-F4) | 110 | // Store float return values (F1-F4) | ||
| 111 | - | FMOVD F1, syscall15Args_f1(R11) | 111 | + | FMOVD F1, syscallArgs_f1(R11) |
| 112 | - | FMOVD F2, syscall15Args_f2(R11) | 112 | + | FMOVD F2, syscallArgs_f2(R11) |
| 113 | - | FMOVD F3, syscall15Args_f3(R11) | 113 | + | FMOVD F3, syscallArgs_f3(R11) |
| 114 | - | FMOVD F4, syscall15Args_f4(R11) | 114 | + | FMOVD F4, syscallArgs_f4(R11) |
| 115 | 115 | ||||
| 116 | // Epilogue: restore and return | 116 | // Epilogue: restore and return | ||
| 117 | MOVD LR_SAVE(R1), R12 | 117 | MOVD LR_SAVE(R1), R12 | ||
M sys_riscv64.s +83 -50
| @@ -8,22 +8,21 @@ | |||
| 8 | 8 | #include "funcdata.h" | |
| 9 | 9 | ||
| 10 | 10 | // Stack usage: | |
| 11 | - | // 0(SP) - 56(SP): stack args a9-a15 (7 * 8 bytes = 56) | |
| 12 | - | // 56(SP) - 64(SP): saved RA (x1) | |
| 13 | - | // 64(SP) - 72(SP): saved X9 (s1) | |
| 14 | - | // 72(SP) - 80(SP): saved X18 (s2) | |
| 15 | - | // 80(SP) - 88(SP): saved args pointer (original X10) | |
| 16 | - | // 88(SP) - 96(SP): padding | |
| 17 | - | #define STACK_SIZE 96 | |
| 18 | - | #define SAVE_RA 56 | |
| 19 | - | #define SAVE_X9 64 | |
| 20 | - | #define SAVE_X18 72 | |
| 21 | - | #define SAVE_ARGP 80 | |
| 22 | - | ||
| 23 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 24 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 25 | - | ||
| 26 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |
| 11 | + | // 0(SP) - 192(SP): stack args a9-a32 (24 * 8 bytes) | |
| 12 | + | // 192(SP) - 200(SP): saved RA (x1) | |
| 13 | + | // 200(SP) - 208(SP): saved X9 (s1) | |
| 14 | + | // 208(SP) - 216(SP): saved X18 (s2) | |
| 15 | + | // 216(SP) - 224(SP): saved args pointer (original X10) | |
| 16 | + | #define STACK_SIZE 224 | |
| 17 | + | #define SAVE_RA 192 | |
| 18 | + | #define SAVE_X9 200 | |
| 19 | + | #define SAVE_X18 208 | |
| 20 | + | #define SAVE_ARGP 216 | |
| 21 | + | ||
| 22 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 23 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 24 | + | ||
| 25 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 27 | 26 | // Allocate stack frame (keeps 16-byte alignment) | |
| 28 | 27 | SUB $STACK_SIZE, SP | |
| 29 | 28 | ||
| @@ -35,62 +34,96 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 35 | 34 | // Save original args pointer (in a0/X10) | |
| 36 | 35 | MOV X10, SAVE_ARGP(SP) | |
| 37 | 36 | ||
| 38 | - | // X9 := args pointer (syscall15Args*) | |
| 37 | + | // X9 := args pointer (syscallArgs*) | |
| 39 | 38 | MOV X10, X9 | |
| 40 | 39 | ||
| 41 | 40 | // Load float args into fa0-fa7 (F10-F17) | |
| 42 | - | MOVD syscall15Args_f1(X9), F10 | |
| 43 | - | MOVD syscall15Args_f2(X9), F11 | |
| 44 | - | MOVD syscall15Args_f3(X9), F12 | |
| 45 | - | MOVD syscall15Args_f4(X9), F13 | |
| 46 | - | MOVD syscall15Args_f5(X9), F14 | |
| 47 | - | MOVD syscall15Args_f6(X9), F15 | |
| 48 | - | MOVD syscall15Args_f7(X9), F16 | |
| 49 | - | MOVD syscall15Args_f8(X9), F17 | |
| 41 | + | MOVD syscallArgs_f1(X9), F10 | |
| 42 | + | MOVD syscallArgs_f2(X9), F11 | |
| 43 | + | MOVD syscallArgs_f3(X9), F12 | |
| 44 | + | MOVD syscallArgs_f4(X9), F13 | |
| 45 | + | MOVD syscallArgs_f5(X9), F14 | |
| 46 | + | MOVD syscallArgs_f6(X9), F15 | |
| 47 | + | MOVD syscallArgs_f7(X9), F16 | |
| 48 | + | MOVD syscallArgs_f8(X9), F17 | |
| 50 | 49 | ||
| 51 | 50 | // Load integer args into a0-a7 (X10-X17) | |
| 52 | - | MOV syscall15Args_a1(X9), X10 | |
| 53 | - | MOV syscall15Args_a2(X9), X11 | |
| 54 | - | MOV syscall15Args_a3(X9), X12 | |
| 55 | - | MOV syscall15Args_a4(X9), X13 | |
| 56 | - | MOV syscall15Args_a5(X9), X14 | |
| 57 | - | MOV syscall15Args_a6(X9), X15 | |
| 58 | - | MOV syscall15Args_a7(X9), X16 | |
| 59 | - | MOV syscall15Args_a8(X9), X17 | |
| 60 | - | ||
| 61 | - | // Spill a9-a15 onto the stack (C ABI) | |
| 62 | - | MOV syscall15Args_a9(X9), X18 | |
| 51 | + | MOV syscallArgs_a1(X9), X10 | |
| 52 | + | MOV syscallArgs_a2(X9), X11 | |
| 53 | + | MOV syscallArgs_a3(X9), X12 | |
| 54 | + | MOV syscallArgs_a4(X9), X13 | |
| 55 | + | MOV syscallArgs_a5(X9), X14 | |
| 56 | + | MOV syscallArgs_a6(X9), X15 | |
| 57 | + | MOV syscallArgs_a7(X9), X16 | |
| 58 | + | MOV syscallArgs_a8(X9), X17 | |
| 59 | + | ||
| 60 | + | // Spill a9-a32 onto the stack (C ABI) | |
| 61 | + | MOV syscallArgs_a9(X9), X18 | |
| 63 | 62 | MOV X18, 0(SP) | |
| 64 | - | MOV syscall15Args_a10(X9), X18 | |
| 63 | + | MOV syscallArgs_a10(X9), X18 | |
| 65 | 64 | MOV X18, 8(SP) | |
| 66 | - | MOV syscall15Args_a11(X9), X18 | |
| 65 | + | MOV syscallArgs_a11(X9), X18 | |
| 67 | 66 | MOV X18, 16(SP) | |
| 68 | - | MOV syscall15Args_a12(X9), X18 | |
| 67 | + | MOV syscallArgs_a12(X9), X18 | |
| 69 | 68 | MOV X18, 24(SP) | |
| 70 | - | MOV syscall15Args_a13(X9), X18 | |
| 69 | + | MOV syscallArgs_a13(X9), X18 | |
| 71 | 70 | MOV X18, 32(SP) | |
| 72 | - | MOV syscall15Args_a14(X9), X18 | |
| 71 | + | MOV syscallArgs_a14(X9), X18 | |
| 73 | 72 | MOV X18, 40(SP) | |
| 74 | - | MOV syscall15Args_a15(X9), X18 | |
| 73 | + | MOV syscallArgs_a15(X9), X18 | |
| 75 | 74 | MOV X18, 48(SP) | |
| 75 | + | MOV syscallArgs_a16(X9), X18 | |
| 76 | + | MOV X18, 56(SP) | |
| 77 | + | MOV syscallArgs_a17(X9), X18 | |
| 78 | + | MOV X18, 64(SP) | |
| 79 | + | MOV syscallArgs_a18(X9), X18 | |
| 80 | + | MOV X18, 72(SP) | |
| 81 | + | MOV syscallArgs_a19(X9), X18 | |
| 82 | + | MOV X18, 80(SP) | |
| 83 | + | MOV syscallArgs_a20(X9), X18 | |
| 84 | + | MOV X18, 88(SP) | |
| 85 | + | MOV syscallArgs_a21(X9), X18 | |
| 86 | + | MOV X18, 96(SP) | |
| 87 | + | MOV syscallArgs_a22(X9), X18 | |
| 88 | + | MOV X18, 104(SP) | |
| 89 | + | MOV syscallArgs_a23(X9), X18 | |
| 90 | + | MOV X18, 112(SP) | |
| 91 | + | MOV syscallArgs_a24(X9), X18 | |
| 92 | + | MOV X18, 120(SP) | |
| 93 | + | MOV syscallArgs_a25(X9), X18 | |
| 94 | + | MOV X18, 128(SP) | |
| 95 | + | MOV syscallArgs_a26(X9), X18 | |
| 96 | + | MOV X18, 136(SP) | |
| 97 | + | MOV syscallArgs_a27(X9), X18 | |
| 98 | + | MOV X18, 144(SP) | |
| 99 | + | MOV syscallArgs_a28(X9), X18 | |
| 100 | + | MOV X18, 152(SP) | |
| 101 | + | MOV syscallArgs_a29(X9), X18 | |
| 102 | + | MOV X18, 160(SP) | |
| 103 | + | MOV syscallArgs_a30(X9), X18 | |
| 104 | + | MOV X18, 168(SP) | |
| 105 | + | MOV syscallArgs_a31(X9), X18 | |
| 106 | + | MOV X18, 176(SP) | |
| 107 | + | MOV syscallArgs_a32(X9), X18 | |
| 108 | + | MOV X18, 184(SP) | |
| 76 | 109 | ||
| 77 | 110 | // Call fn | |
| 78 | 111 | // IMPORTANT: preserve RA across this call (we saved it above) | |
| 79 | - | MOV syscall15Args_fn(X9), X18 | |
| 112 | + | MOV syscallArgs_fn(X9), X18 | |
| 80 | 113 | CALL X18 | |
| 81 | 114 | ||
| 82 | - | // Restore args pointer (syscall15Args*) for storing results | |
| 115 | + | // Restore args pointer (syscallArgs*) for storing results | |
| 83 | 116 | MOV SAVE_ARGP(SP), X9 | |
| 84 | 117 | ||
| 85 | 118 | // Store results back | |
| 86 | - | MOV X10, syscall15Args_a1(X9) | |
| 87 | - | MOV X11, syscall15Args_a2(X9) | |
| 119 | + | MOV X10, syscallArgs_a1(X9) | |
| 120 | + | MOV X11, syscallArgs_a2(X9) | |
| 88 | 121 | ||
| 89 | 122 | // Store back float return regs if used by your ABI contract | |
| 90 | - | MOVD F10, syscall15Args_f1(X9) | |
| 91 | - | MOVD F11, syscall15Args_f2(X9) | |
| 92 | - | MOVD F12, syscall15Args_f3(X9) | |
| 93 | - | MOVD F13, syscall15Args_f4(X9) | |
| 123 | + | MOVD F10, syscallArgs_f1(X9) | |
| 124 | + | MOVD F11, syscallArgs_f2(X9) | |
| 125 | + | MOVD F12, syscallArgs_f3(X9) | |
| 126 | + | MOVD F13, syscallArgs_f4(X9) | |
| 94 | 127 | ||
| 95 | 128 | // Restore callee-saved regs and return address | |
| 96 | 129 | MOV SAVE_X18(SP), X18 | |
| @@ -8,22 +8,21 @@ | |||||
| 8 | #include "funcdata.h" | 8 | #include "funcdata.h" | ||
| 9 | 9 | ||||
| 10 | // Stack usage: | 10 | // Stack usage: | ||
| 11 | - | // 0(SP) - 56(SP): stack args a9-a15 (7 * 8 bytes = 56) | 11 | + | // 0(SP) - 192(SP): stack args a9-a32 (24 * 8 bytes) |
| 12 | - | // 56(SP) - 64(SP): saved RA (x1) | 12 | + | // 192(SP) - 200(SP): saved RA (x1) |
| 13 | - | // 64(SP) - 72(SP): saved X9 (s1) | 13 | + | // 200(SP) - 208(SP): saved X9 (s1) |
| 14 | - | // 72(SP) - 80(SP): saved X18 (s2) | 14 | + | // 208(SP) - 216(SP): saved X18 (s2) |
| 15 | - | // 80(SP) - 88(SP): saved args pointer (original X10) | 15 | + | // 216(SP) - 224(SP): saved args pointer (original X10) |
| 16 | - | // 88(SP) - 96(SP): padding | 16 | + | #define STACK_SIZE 224 |
| 17 | - | #define STACK_SIZE 96 | 17 | + | #define SAVE_RA 192 |
| 18 | - | #define SAVE_RA 56 | 18 | + | #define SAVE_X9 200 |
| 19 | - | #define SAVE_X9 64 | 19 | + | #define SAVE_X18 208 |
| 20 | - | #define SAVE_X18 72 | 20 | + | #define SAVE_ARGP 216 |
| 21 | - | #define SAVE_ARGP 80 | 21 | + | |
| 22 | - | 22 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 23 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 23 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 24 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 24 | + | |
| 25 | - | 25 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 26 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 27 | // Allocate stack frame (keeps 16-byte alignment) | 26 | // Allocate stack frame (keeps 16-byte alignment) | ||
| 28 | SUB $STACK_SIZE, SP | 27 | SUB $STACK_SIZE, SP | ||
| 29 | 28 | ||||
| @@ -35,62 +34,96 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||||
| 35 | // Save original args pointer (in a0/X10) | 34 | // Save original args pointer (in a0/X10) | ||
| 36 | MOV X10, SAVE_ARGP(SP) | 35 | MOV X10, SAVE_ARGP(SP) | ||
| 37 | 36 | ||||
| 38 | - | // X9 := args pointer (syscall15Args*) | 37 | + | // X9 := args pointer (syscallArgs*) |
| 39 | MOV X10, X9 | 38 | MOV X10, X9 | ||
| 40 | 39 | ||||
| 41 | // Load float args into fa0-fa7 (F10-F17) | 40 | // Load float args into fa0-fa7 (F10-F17) | ||
| 42 | - | MOVD syscall15Args_f1(X9), F10 | 41 | + | MOVD syscallArgs_f1(X9), F10 |
| 43 | - | MOVD syscall15Args_f2(X9), F11 | 42 | + | MOVD syscallArgs_f2(X9), F11 |
| 44 | - | MOVD syscall15Args_f3(X9), F12 | 43 | + | MOVD syscallArgs_f3(X9), F12 |
| 45 | - | MOVD syscall15Args_f4(X9), F13 | 44 | + | MOVD syscallArgs_f4(X9), F13 |
| 46 | - | MOVD syscall15Args_f5(X9), F14 | 45 | + | MOVD syscallArgs_f5(X9), F14 |
| 47 | - | MOVD syscall15Args_f6(X9), F15 | 46 | + | MOVD syscallArgs_f6(X9), F15 |
| 48 | - | MOVD syscall15Args_f7(X9), F16 | 47 | + | MOVD syscallArgs_f7(X9), F16 |
| 49 | - | MOVD syscall15Args_f8(X9), F17 | 48 | + | MOVD syscallArgs_f8(X9), F17 |
| 50 | 49 | ||||
| 51 | // Load integer args into a0-a7 (X10-X17) | 50 | // Load integer args into a0-a7 (X10-X17) | ||
| 52 | - | MOV syscall15Args_a1(X9), X10 | 51 | + | MOV syscallArgs_a1(X9), X10 |
| 53 | - | MOV syscall15Args_a2(X9), X11 | 52 | + | MOV syscallArgs_a2(X9), X11 |
| 54 | - | MOV syscall15Args_a3(X9), X12 | 53 | + | MOV syscallArgs_a3(X9), X12 |
| 55 | - | MOV syscall15Args_a4(X9), X13 | 54 | + | MOV syscallArgs_a4(X9), X13 |
| 56 | - | MOV syscall15Args_a5(X9), X14 | 55 | + | MOV syscallArgs_a5(X9), X14 |
| 57 | - | MOV syscall15Args_a6(X9), X15 | 56 | + | MOV syscallArgs_a6(X9), X15 |
| 58 | - | MOV syscall15Args_a7(X9), X16 | 57 | + | MOV syscallArgs_a7(X9), X16 |
| 59 | - | MOV syscall15Args_a8(X9), X17 | 58 | + | MOV syscallArgs_a8(X9), X17 |
| 60 | - | 59 | + | ||
| 61 | - | // Spill a9-a15 onto the stack (C ABI) | 60 | + | // Spill a9-a32 onto the stack (C ABI) |
| 62 | - | MOV syscall15Args_a9(X9), X18 | 61 | + | MOV syscallArgs_a9(X9), X18 |
| 63 | MOV X18, 0(SP) | 62 | MOV X18, 0(SP) | ||
| 64 | - | MOV syscall15Args_a10(X9), X18 | 63 | + | MOV syscallArgs_a10(X9), X18 |
| 65 | MOV X18, 8(SP) | 64 | MOV X18, 8(SP) | ||
| 66 | - | MOV syscall15Args_a11(X9), X18 | 65 | + | MOV syscallArgs_a11(X9), X18 |
| 67 | MOV X18, 16(SP) | 66 | MOV X18, 16(SP) | ||
| 68 | - | MOV syscall15Args_a12(X9), X18 | 67 | + | MOV syscallArgs_a12(X9), X18 |
| 69 | MOV X18, 24(SP) | 68 | MOV X18, 24(SP) | ||
| 70 | - | MOV syscall15Args_a13(X9), X18 | 69 | + | MOV syscallArgs_a13(X9), X18 |
| 71 | MOV X18, 32(SP) | 70 | MOV X18, 32(SP) | ||
| 72 | - | MOV syscall15Args_a14(X9), X18 | 71 | + | MOV syscallArgs_a14(X9), X18 |
| 73 | MOV X18, 40(SP) | 72 | MOV X18, 40(SP) | ||
| 74 | - | MOV syscall15Args_a15(X9), X18 | 73 | + | MOV syscallArgs_a15(X9), X18 |
| 75 | MOV X18, 48(SP) | 74 | MOV X18, 48(SP) | ||
| 75 | + | MOV syscallArgs_a16(X9), X18 | |||
| 76 | + | MOV X18, 56(SP) | |||
| 77 | + | MOV syscallArgs_a17(X9), X18 | |||
| 78 | + | MOV X18, 64(SP) | |||
| 79 | + | MOV syscallArgs_a18(X9), X18 | |||
| 80 | + | MOV X18, 72(SP) | |||
| 81 | + | MOV syscallArgs_a19(X9), X18 | |||
| 82 | + | MOV X18, 80(SP) | |||
| 83 | + | MOV syscallArgs_a20(X9), X18 | |||
| 84 | + | MOV X18, 88(SP) | |||
| 85 | + | MOV syscallArgs_a21(X9), X18 | |||
| 86 | + | MOV X18, 96(SP) | |||
| 87 | + | MOV syscallArgs_a22(X9), X18 | |||
| 88 | + | MOV X18, 104(SP) | |||
| 89 | + | MOV syscallArgs_a23(X9), X18 | |||
| 90 | + | MOV X18, 112(SP) | |||
| 91 | + | MOV syscallArgs_a24(X9), X18 | |||
| 92 | + | MOV X18, 120(SP) | |||
| 93 | + | MOV syscallArgs_a25(X9), X18 | |||
| 94 | + | MOV X18, 128(SP) | |||
| 95 | + | MOV syscallArgs_a26(X9), X18 | |||
| 96 | + | MOV X18, 136(SP) | |||
| 97 | + | MOV syscallArgs_a27(X9), X18 | |||
| 98 | + | MOV X18, 144(SP) | |||
| 99 | + | MOV syscallArgs_a28(X9), X18 | |||
| 100 | + | MOV X18, 152(SP) | |||
| 101 | + | MOV syscallArgs_a29(X9), X18 | |||
| 102 | + | MOV X18, 160(SP) | |||
| 103 | + | MOV syscallArgs_a30(X9), X18 | |||
| 104 | + | MOV X18, 168(SP) | |||
| 105 | + | MOV syscallArgs_a31(X9), X18 | |||
| 106 | + | MOV X18, 176(SP) | |||
| 107 | + | MOV syscallArgs_a32(X9), X18 | |||
| 108 | + | MOV X18, 184(SP) | |||
| 76 | 109 | ||||
| 77 | // Call fn | 110 | // Call fn | ||
| 78 | // IMPORTANT: preserve RA across this call (we saved it above) | 111 | // IMPORTANT: preserve RA across this call (we saved it above) | ||
| 79 | - | MOV syscall15Args_fn(X9), X18 | 112 | + | MOV syscallArgs_fn(X9), X18 |
| 80 | CALL X18 | 113 | CALL X18 | ||
| 81 | 114 | ||||
| 82 | - | // Restore args pointer (syscall15Args*) for storing results | 115 | + | // Restore args pointer (syscallArgs*) for storing results |
| 83 | MOV SAVE_ARGP(SP), X9 | 116 | MOV SAVE_ARGP(SP), X9 | ||
| 84 | 117 | ||||
| 85 | // Store results back | 118 | // Store results back | ||
| 86 | - | MOV X10, syscall15Args_a1(X9) | 119 | + | MOV X10, syscallArgs_a1(X9) |
| 87 | - | MOV X11, syscall15Args_a2(X9) | 120 | + | MOV X11, syscallArgs_a2(X9) |
| 88 | 121 | ||||
| 89 | // Store back float return regs if used by your ABI contract | 122 | // Store back float return regs if used by your ABI contract | ||
| 90 | - | MOVD F10, syscall15Args_f1(X9) | 123 | + | MOVD F10, syscallArgs_f1(X9) |
| 91 | - | MOVD F11, syscall15Args_f2(X9) | 124 | + | MOVD F11, syscallArgs_f2(X9) |
| 92 | - | MOVD F12, syscall15Args_f3(X9) | 125 | + | MOVD F12, syscallArgs_f3(X9) |
| 93 | - | MOVD F13, syscall15Args_f4(X9) | 126 | + | MOVD F13, syscallArgs_f4(X9) |
| 94 | 127 | ||||
| 95 | // Restore callee-saved regs and return address | 128 | // Restore callee-saved regs and return address | ||
| 96 | MOV SAVE_X18(SP), X18 | 129 | MOV SAVE_X18(SP), X18 | ||
M sys_s390x.s +69 -36
| @@ -24,19 +24,18 @@ | |||
| 24 | 24 | // | |
| 25 | 25 | // We need space for: | |
| 26 | 26 | // - 160 bytes standard frame (with register save area) | |
| 27 | - | // - Stack args a6-a15 (10 * 8 = 80 bytes) | |
| 27 | + | // - Stack args a6-a32 (27 * 8 = 216 bytes) | |
| 28 | 28 | // - Saved args pointer (8 bytes) | |
| 29 | - | // - Padding for alignment | |
| 30 | - | // Total: 264 bytes (rounded to 8-byte alignment) | |
| 29 | + | // Total: 384 bytes | |
| 31 | 30 | ||
| 32 | - | #define STACK_SIZE 264 | |
| 31 | + | #define STACK_SIZE 384 | |
| 33 | 32 | #define STACK_ARGS 160 | |
| 34 | - | #define ARGP_SAVE 248 | |
| 33 | + | #define ARGP_SAVE 376 | |
| 35 | 34 | ||
| 36 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | |
| 37 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | |
| 35 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 | |
| 36 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) | |
| 38 | 37 | ||
| 39 | - | TEXT syscall15X(SB), NOSPLIT, $0 | |
| 38 | + | TEXT syscallX(SB), NOSPLIT, $0 | |
| 40 | 39 | // On entry, R2 contains the args pointer | |
| 41 | 40 | // Save callee-saved registers in caller's frame (per ABI) | |
| 42 | 41 | STMG R6, R15, 48(R15) | |
| @@ -49,61 +48,95 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||
| 49 | 48 | // Save args pointer | |
| 50 | 49 | MOVD R2, ARGP_SAVE(R15) | |
| 51 | 50 | ||
| 52 | - | // R9 := args pointer (syscall15Args*) | |
| 51 | + | // R9 := args pointer (syscallArgs*) | |
| 53 | 52 | MOVD R2, R9 | |
| 54 | 53 | ||
| 55 | 54 | // Load float args into F0, F2, F4, F6 (s390x uses even-numbered FPRs) | |
| 56 | - | FMOVD syscall15Args_f1(R9), F0 | |
| 57 | - | FMOVD syscall15Args_f2(R9), F2 | |
| 58 | - | FMOVD syscall15Args_f3(R9), F4 | |
| 59 | - | FMOVD syscall15Args_f4(R9), F6 | |
| 55 | + | FMOVD syscallArgs_f1(R9), F0 | |
| 56 | + | FMOVD syscallArgs_f2(R9), F2 | |
| 57 | + | FMOVD syscallArgs_f3(R9), F4 | |
| 58 | + | FMOVD syscallArgs_f4(R9), F6 | |
| 60 | 59 | ||
| 61 | 60 | // Load integer args into R2-R6 (5 registers) | |
| 62 | - | MOVD syscall15Args_a1(R9), R2 | |
| 63 | - | MOVD syscall15Args_a2(R9), R3 | |
| 64 | - | MOVD syscall15Args_a3(R9), R4 | |
| 65 | - | MOVD syscall15Args_a4(R9), R5 | |
| 66 | - | MOVD syscall15Args_a5(R9), R6 | |
| 61 | + | MOVD syscallArgs_a1(R9), R2 | |
| 62 | + | MOVD syscallArgs_a2(R9), R3 | |
| 63 | + | MOVD syscallArgs_a3(R9), R4 | |
| 64 | + | MOVD syscallArgs_a4(R9), R5 | |
| 65 | + | MOVD syscallArgs_a5(R9), R6 | |
| 67 | 66 | ||
| 68 | - | // Spill remaining args (a6-a15) onto the stack at 160(R15) | |
| 67 | + | // Spill remaining args (a6-a32) onto the stack at 160(R15) | |
| 69 | 68 | MOVD ARGP_SAVE(R15), R9 // reload args pointer | |
| 70 | - | MOVD syscall15Args_a6(R9), R1 | |
| 69 | + | MOVD syscallArgs_a6(R9), R1 | |
| 71 | 70 | MOVD R1, (STACK_ARGS+0*8)(R15) | |
| 72 | - | MOVD syscall15Args_a7(R9), R1 | |
| 71 | + | MOVD syscallArgs_a7(R9), R1 | |
| 73 | 72 | MOVD R1, (STACK_ARGS+1*8)(R15) | |
| 74 | - | MOVD syscall15Args_a8(R9), R1 | |
| 73 | + | MOVD syscallArgs_a8(R9), R1 | |
| 75 | 74 | MOVD R1, (STACK_ARGS+2*8)(R15) | |
| 76 | - | MOVD syscall15Args_a9(R9), R1 | |
| 75 | + | MOVD syscallArgs_a9(R9), R1 | |
| 77 | 76 | MOVD R1, (STACK_ARGS+3*8)(R15) | |
| 78 | - | MOVD syscall15Args_a10(R9), R1 | |
| 77 | + | MOVD syscallArgs_a10(R9), R1 | |
| 79 | 78 | MOVD R1, (STACK_ARGS+4*8)(R15) | |
| 80 | - | MOVD syscall15Args_a11(R9), R1 | |
| 79 | + | MOVD syscallArgs_a11(R9), R1 | |
| 81 | 80 | MOVD R1, (STACK_ARGS+5*8)(R15) | |
| 82 | - | MOVD syscall15Args_a12(R9), R1 | |
| 81 | + | MOVD syscallArgs_a12(R9), R1 | |
| 83 | 82 | MOVD R1, (STACK_ARGS+6*8)(R15) | |
| 84 | - | MOVD syscall15Args_a13(R9), R1 | |
| 83 | + | MOVD syscallArgs_a13(R9), R1 | |
| 85 | 84 | MOVD R1, (STACK_ARGS+7*8)(R15) | |
| 86 | - | MOVD syscall15Args_a14(R9), R1 | |
| 85 | + | MOVD syscallArgs_a14(R9), R1 | |
| 87 | 86 | MOVD R1, (STACK_ARGS+8*8)(R15) | |
| 88 | - | MOVD syscall15Args_a15(R9), R1 | |
| 87 | + | MOVD syscallArgs_a15(R9), R1 | |
| 89 | 88 | MOVD R1, (STACK_ARGS+9*8)(R15) | |
| 89 | + | MOVD syscallArgs_a16(R9), R1 | |
| 90 | + | MOVD R1, (STACK_ARGS+10*8)(R15) | |
| 91 | + | MOVD syscallArgs_a17(R9), R1 | |
| 92 | + | MOVD R1, (STACK_ARGS+11*8)(R15) | |
| 93 | + | MOVD syscallArgs_a18(R9), R1 | |
| 94 | + | MOVD R1, (STACK_ARGS+12*8)(R15) | |
| 95 | + | MOVD syscallArgs_a19(R9), R1 | |
| 96 | + | MOVD R1, (STACK_ARGS+13*8)(R15) | |
| 97 | + | MOVD syscallArgs_a20(R9), R1 | |
| 98 | + | MOVD R1, (STACK_ARGS+14*8)(R15) | |
| 99 | + | MOVD syscallArgs_a21(R9), R1 | |
| 100 | + | MOVD R1, (STACK_ARGS+15*8)(R15) | |
| 101 | + | MOVD syscallArgs_a22(R9), R1 | |
| 102 | + | MOVD R1, (STACK_ARGS+16*8)(R15) | |
| 103 | + | MOVD syscallArgs_a23(R9), R1 | |
| 104 | + | MOVD R1, (STACK_ARGS+17*8)(R15) | |
| 105 | + | MOVD syscallArgs_a24(R9), R1 | |
| 106 | + | MOVD R1, (STACK_ARGS+18*8)(R15) | |
| 107 | + | MOVD syscallArgs_a25(R9), R1 | |
| 108 | + | MOVD R1, (STACK_ARGS+19*8)(R15) | |
| 109 | + | MOVD syscallArgs_a26(R9), R1 | |
| 110 | + | MOVD R1, (STACK_ARGS+20*8)(R15) | |
| 111 | + | MOVD syscallArgs_a27(R9), R1 | |
| 112 | + | MOVD R1, (STACK_ARGS+21*8)(R15) | |
| 113 | + | MOVD syscallArgs_a28(R9), R1 | |
| 114 | + | MOVD R1, (STACK_ARGS+22*8)(R15) | |
| 115 | + | MOVD syscallArgs_a29(R9), R1 | |
| 116 | + | MOVD R1, (STACK_ARGS+23*8)(R15) | |
| 117 | + | MOVD syscallArgs_a30(R9), R1 | |
| 118 | + | MOVD R1, (STACK_ARGS+24*8)(R15) | |
| 119 | + | MOVD syscallArgs_a31(R9), R1 | |
| 120 | + | MOVD R1, (STACK_ARGS+25*8)(R15) | |
| 121 | + | MOVD syscallArgs_a32(R9), R1 | |
| 122 | + | MOVD R1, (STACK_ARGS+26*8)(R15) | |
| 90 | 123 | ||
| 91 | 124 | // Call function | |
| 92 | - | MOVD syscall15Args_fn(R9), R1 | |
| 125 | + | MOVD syscallArgs_fn(R9), R1 | |
| 93 | 126 | BL (R1) | |
| 94 | 127 | ||
| 95 | 128 | // Restore args pointer for storing results | |
| 96 | 129 | MOVD ARGP_SAVE(R15), R9 | |
| 97 | 130 | ||
| 98 | 131 | // Store integer results back (R2, R3) | |
| 99 | - | MOVD R2, syscall15Args_a1(R9) | |
| 100 | - | MOVD R3, syscall15Args_a2(R9) | |
| 132 | + | MOVD R2, syscallArgs_a1(R9) | |
| 133 | + | MOVD R3, syscallArgs_a2(R9) | |
| 101 | 134 | ||
| 102 | 135 | // Store float return values (F0, F2, F4, F6) | |
| 103 | - | FMOVD F0, syscall15Args_f1(R9) | |
| 104 | - | FMOVD F2, syscall15Args_f2(R9) | |
| 105 | - | FMOVD F4, syscall15Args_f3(R9) | |
| 106 | - | FMOVD F6, syscall15Args_f4(R9) | |
| 136 | + | FMOVD F0, syscallArgs_f1(R9) | |
| 137 | + | FMOVD F2, syscallArgs_f2(R9) | |
| 138 | + | FMOVD F4, syscallArgs_f3(R9) | |
| 139 | + | FMOVD F6, syscallArgs_f4(R9) | |
| 107 | 140 | ||
| 108 | 141 | // Deallocate stack frame | |
| 109 | 142 | ADD $STACK_SIZE, R15 | |
| @@ -24,19 +24,18 @@ | |||||
| 24 | // | 24 | // | ||
| 25 | // We need space for: | 25 | // We need space for: | ||
| 26 | // - 160 bytes standard frame (with register save area) | 26 | // - 160 bytes standard frame (with register save area) | ||
| 27 | - | // - Stack args a6-a15 (10 * 8 = 80 bytes) | 27 | + | // - Stack args a6-a32 (27 * 8 = 216 bytes) |
| 28 | // - Saved args pointer (8 bytes) | 28 | // - Saved args pointer (8 bytes) | ||
| 29 | - | // - Padding for alignment | 29 | + | // Total: 384 bytes |
| 30 | - | // Total: 264 bytes (rounded to 8-byte alignment) | |||
| 31 | 30 | ||||
| 32 | - | #define STACK_SIZE 264 | 31 | + | #define STACK_SIZE 384 |
| 33 | #define STACK_ARGS 160 | 32 | #define STACK_ARGS 160 | ||
| 34 | - | #define ARGP_SAVE 248 | 33 | + | #define ARGP_SAVE 376 |
| 35 | 34 | ||||
| 36 | - | GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8 | 35 | + | GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8 |
| 37 | - | DATA ·syscall15XABI0(SB)/8, $syscall15X(SB) | 36 | + | DATA ·syscallXABI0(SB)/8, $syscallX(SB) |
| 38 | 37 | ||||
| 39 | - | TEXT syscall15X(SB), NOSPLIT, $0 | 38 | + | TEXT syscallX(SB), NOSPLIT, $0 |
| 40 | // On entry, R2 contains the args pointer | 39 | // On entry, R2 contains the args pointer | ||
| 41 | // Save callee-saved registers in caller's frame (per ABI) | 40 | // Save callee-saved registers in caller's frame (per ABI) | ||
| 42 | STMG R6, R15, 48(R15) | 41 | STMG R6, R15, 48(R15) | ||
| @@ -49,61 +48,95 @@ TEXT syscall15X(SB), NOSPLIT, $0 | |||||
| 49 | // Save args pointer | 48 | // Save args pointer | ||
| 50 | MOVD R2, ARGP_SAVE(R15) | 49 | MOVD R2, ARGP_SAVE(R15) | ||
| 51 | 50 | ||||
| 52 | - | // R9 := args pointer (syscall15Args*) | 51 | + | // R9 := args pointer (syscallArgs*) |
| 53 | MOVD R2, R9 | 52 | MOVD R2, R9 | ||
| 54 | 53 | ||||
| 55 | // Load float args into F0, F2, F4, F6 (s390x uses even-numbered FPRs) | 54 | // Load float args into F0, F2, F4, F6 (s390x uses even-numbered FPRs) | ||
| 56 | - | FMOVD syscall15Args_f1(R9), F0 | 55 | + | FMOVD syscallArgs_f1(R9), F0 |
| 57 | - | FMOVD syscall15Args_f2(R9), F2 | 56 | + | FMOVD syscallArgs_f2(R9), F2 |
| 58 | - | FMOVD syscall15Args_f3(R9), F4 | 57 | + | FMOVD syscallArgs_f3(R9), F4 |
| 59 | - | FMOVD syscall15Args_f4(R9), F6 | 58 | + | FMOVD syscallArgs_f4(R9), F6 |
| 60 | 59 | ||||
| 61 | // Load integer args into R2-R6 (5 registers) | 60 | // Load integer args into R2-R6 (5 registers) | ||
| 62 | - | MOVD syscall15Args_a1(R9), R2 | 61 | + | MOVD syscallArgs_a1(R9), R2 |
| 63 | - | MOVD syscall15Args_a2(R9), R3 | 62 | + | MOVD syscallArgs_a2(R9), R3 |
| 64 | - | MOVD syscall15Args_a3(R9), R4 | 63 | + | MOVD syscallArgs_a3(R9), R4 |
| 65 | - | MOVD syscall15Args_a4(R9), R5 | 64 | + | MOVD syscallArgs_a4(R9), R5 |
| 66 | - | MOVD syscall15Args_a5(R9), R6 | 65 | + | MOVD syscallArgs_a5(R9), R6 |
| 67 | 66 | ||||
| 68 | - | // Spill remaining args (a6-a15) onto the stack at 160(R15) | 67 | + | // Spill remaining args (a6-a32) onto the stack at 160(R15) |
| 69 | MOVD ARGP_SAVE(R15), R9 // reload args pointer | 68 | MOVD ARGP_SAVE(R15), R9 // reload args pointer | ||
| 70 | - | MOVD syscall15Args_a6(R9), R1 | 69 | + | MOVD syscallArgs_a6(R9), R1 |
| 71 | MOVD R1, (STACK_ARGS+0*8)(R15) | 70 | MOVD R1, (STACK_ARGS+0*8)(R15) | ||
| 72 | - | MOVD syscall15Args_a7(R9), R1 | 71 | + | MOVD syscallArgs_a7(R9), R1 |
| 73 | MOVD R1, (STACK_ARGS+1*8)(R15) | 72 | MOVD R1, (STACK_ARGS+1*8)(R15) | ||
| 74 | - | MOVD syscall15Args_a8(R9), R1 | 73 | + | MOVD syscallArgs_a8(R9), R1 |
| 75 | MOVD R1, (STACK_ARGS+2*8)(R15) | 74 | MOVD R1, (STACK_ARGS+2*8)(R15) | ||
| 76 | - | MOVD syscall15Args_a9(R9), R1 | 75 | + | MOVD syscallArgs_a9(R9), R1 |
| 77 | MOVD R1, (STACK_ARGS+3*8)(R15) | 76 | MOVD R1, (STACK_ARGS+3*8)(R15) | ||
| 78 | - | MOVD syscall15Args_a10(R9), R1 | 77 | + | MOVD syscallArgs_a10(R9), R1 |
| 79 | MOVD R1, (STACK_ARGS+4*8)(R15) | 78 | MOVD R1, (STACK_ARGS+4*8)(R15) | ||
| 80 | - | MOVD syscall15Args_a11(R9), R1 | 79 | + | MOVD syscallArgs_a11(R9), R1 |
| 81 | MOVD R1, (STACK_ARGS+5*8)(R15) | 80 | MOVD R1, (STACK_ARGS+5*8)(R15) | ||
| 82 | - | MOVD syscall15Args_a12(R9), R1 | 81 | + | MOVD syscallArgs_a12(R9), R1 |
| 83 | MOVD R1, (STACK_ARGS+6*8)(R15) | 82 | MOVD R1, (STACK_ARGS+6*8)(R15) | ||
| 84 | - | MOVD syscall15Args_a13(R9), R1 | 83 | + | MOVD syscallArgs_a13(R9), R1 |
| 85 | MOVD R1, (STACK_ARGS+7*8)(R15) | 84 | MOVD R1, (STACK_ARGS+7*8)(R15) | ||
| 86 | - | MOVD syscall15Args_a14(R9), R1 | 85 | + | MOVD syscallArgs_a14(R9), R1 |
| 87 | MOVD R1, (STACK_ARGS+8*8)(R15) | 86 | MOVD R1, (STACK_ARGS+8*8)(R15) | ||
| 88 | - | MOVD syscall15Args_a15(R9), R1 | 87 | + | MOVD syscallArgs_a15(R9), R1 |
| 89 | MOVD R1, (STACK_ARGS+9*8)(R15) | 88 | MOVD R1, (STACK_ARGS+9*8)(R15) | ||
| 89 | + | MOVD syscallArgs_a16(R9), R1 | |||
| 90 | + | MOVD R1, (STACK_ARGS+10*8)(R15) | |||
| 91 | + | MOVD syscallArgs_a17(R9), R1 | |||
| 92 | + | MOVD R1, (STACK_ARGS+11*8)(R15) | |||
| 93 | + | MOVD syscallArgs_a18(R9), R1 | |||
| 94 | + | MOVD R1, (STACK_ARGS+12*8)(R15) | |||
| 95 | + | MOVD syscallArgs_a19(R9), R1 | |||
| 96 | + | MOVD R1, (STACK_ARGS+13*8)(R15) | |||
| 97 | + | MOVD syscallArgs_a20(R9), R1 | |||
| 98 | + | MOVD R1, (STACK_ARGS+14*8)(R15) | |||
| 99 | + | MOVD syscallArgs_a21(R9), R1 | |||
| 100 | + | MOVD R1, (STACK_ARGS+15*8)(R15) | |||
| 101 | + | MOVD syscallArgs_a22(R9), R1 | |||
| 102 | + | MOVD R1, (STACK_ARGS+16*8)(R15) | |||
| 103 | + | MOVD syscallArgs_a23(R9), R1 | |||
| 104 | + | MOVD R1, (STACK_ARGS+17*8)(R15) | |||
| 105 | + | MOVD syscallArgs_a24(R9), R1 | |||
| 106 | + | MOVD R1, (STACK_ARGS+18*8)(R15) | |||
| 107 | + | MOVD syscallArgs_a25(R9), R1 | |||
| 108 | + | MOVD R1, (STACK_ARGS+19*8)(R15) | |||
| 109 | + | MOVD syscallArgs_a26(R9), R1 | |||
| 110 | + | MOVD R1, (STACK_ARGS+20*8)(R15) | |||
| 111 | + | MOVD syscallArgs_a27(R9), R1 | |||
| 112 | + | MOVD R1, (STACK_ARGS+21*8)(R15) | |||
| 113 | + | MOVD syscallArgs_a28(R9), R1 | |||
| 114 | + | MOVD R1, (STACK_ARGS+22*8)(R15) | |||
| 115 | + | MOVD syscallArgs_a29(R9), R1 | |||
| 116 | + | MOVD R1, (STACK_ARGS+23*8)(R15) | |||
| 117 | + | MOVD syscallArgs_a30(R9), R1 | |||
| 118 | + | MOVD R1, (STACK_ARGS+24*8)(R15) | |||
| 119 | + | MOVD syscallArgs_a31(R9), R1 | |||
| 120 | + | MOVD R1, (STACK_ARGS+25*8)(R15) | |||
| 121 | + | MOVD syscallArgs_a32(R9), R1 | |||
| 122 | + | MOVD R1, (STACK_ARGS+26*8)(R15) | |||
| 90 | 123 | ||||
| 91 | // Call function | 124 | // Call function | ||
| 92 | - | MOVD syscall15Args_fn(R9), R1 | 125 | + | MOVD syscallArgs_fn(R9), R1 |
| 93 | BL (R1) | 126 | BL (R1) | ||
| 94 | 127 | ||||
| 95 | // Restore args pointer for storing results | 128 | // Restore args pointer for storing results | ||
| 96 | MOVD ARGP_SAVE(R15), R9 | 129 | MOVD ARGP_SAVE(R15), R9 | ||
| 97 | 130 | ||||
| 98 | // Store integer results back (R2, R3) | 131 | // Store integer results back (R2, R3) | ||
| 99 | - | MOVD R2, syscall15Args_a1(R9) | 132 | + | MOVD R2, syscallArgs_a1(R9) |
| 100 | - | MOVD R3, syscall15Args_a2(R9) | 133 | + | MOVD R3, syscallArgs_a2(R9) |
| 101 | 134 | ||||
| 102 | // Store float return values (F0, F2, F4, F6) | 135 | // Store float return values (F0, F2, F4, F6) | ||
| 103 | - | FMOVD F0, syscall15Args_f1(R9) | 136 | + | FMOVD F0, syscallArgs_f1(R9) |
| 104 | - | FMOVD F2, syscall15Args_f2(R9) | 137 | + | FMOVD F2, syscallArgs_f2(R9) |
| 105 | - | FMOVD F4, syscall15Args_f3(R9) | 138 | + | FMOVD F4, syscallArgs_f3(R9) |
| 106 | - | FMOVD F6, syscall15Args_f4(R9) | 139 | + | FMOVD F6, syscallArgs_f4(R9) |
| 107 | 140 | ||||
| 108 | // Deallocate stack frame | 141 | // Deallocate stack frame | ||
| 109 | ADD $STACK_SIZE, R15 | 142 | ADD $STACK_SIZE, R15 | ||
M syscall.go +40 -39
| @@ -1,53 +1,44 @@ | |||
| 1 | 1 | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | 3 | ||
| 4 | - | //go:build !386 && !arm && (darwin || freebsd || linux || netbsd || windows) | |
| 4 | + | //go:build !386 && !arm && !ppc64le && (darwin || freebsd || linux || netbsd || windows) | |
| 5 | 5 | ||
| 6 | 6 | package purego | |
| 7 | 7 | ||
| 8 | - | // CDecl marks a function as being called using the __cdecl calling convention as defined in | |
| 9 | - | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | |
| 10 | - | // This is only useful on 386 Windows, but it is safe to use on other platforms. | |
| 11 | - | // | |
| 12 | - | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |
| 13 | - | type CDecl struct{} | |
| 8 | + | import ( | |
| 9 | + | "runtime" | |
| 10 | + | "unsafe" | |
| 11 | + | ) | |
| 14 | 12 | ||
| 15 | 13 | const ( | |
| 16 | - | maxArgs = 15 | |
| 14 | + | maxArgs = 32 | |
| 17 | 15 | ) | |
| 18 | 16 | ||
| 19 | - | type syscall15Args struct { | |
| 20 | - | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | |
| 21 | - | f1, f2, f3, f4, f5, f6, f7, f8 uintptr | |
| 22 | - | arm64_r8 uintptr | |
| 17 | + | type syscallArgs struct { | |
| 18 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | |
| 19 | + | a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr | |
| 20 | + | f1, f2, f3, f4, f5, f6, f7, f8 uintptr | |
| 21 | + | arm64_r8 uintptr | |
| 23 | 22 | } | |
| 24 | 23 | ||
| 25 | - | func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) { | |
| 26 | - | s.fn = fn | |
| 27 | - | s.a1 = ints[0] | |
| 28 | - | s.a2 = ints[1] | |
| 29 | - | s.a3 = ints[2] | |
| 30 | - | s.a4 = ints[3] | |
| 31 | - | s.a5 = ints[4] | |
| 32 | - | s.a6 = ints[5] | |
| 33 | - | s.a7 = ints[6] | |
| 34 | - | s.a8 = ints[7] | |
| 35 | - | s.a9 = ints[8] | |
| 36 | - | s.a10 = ints[9] | |
| 37 | - | s.a11 = ints[10] | |
| 38 | - | s.a12 = ints[11] | |
| 39 | - | s.a13 = ints[12] | |
| 40 | - | s.a14 = ints[13] | |
| 41 | - | s.a15 = ints[14] | |
| 42 | - | s.f1 = floats[0] | |
| 43 | - | s.f2 = floats[1] | |
| 44 | - | s.f3 = floats[2] | |
| 45 | - | s.f4 = floats[3] | |
| 46 | - | s.f5 = floats[4] | |
| 47 | - | s.f6 = floats[5] | |
| 48 | - | s.f7 = floats[6] | |
| 49 | - | s.f8 = floats[7] | |
| 50 | - | s.arm64_r8 = r8 | |
| 24 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { | |
| 25 | + | s := thePool.Get().(*syscallArgs) | |
| 26 | + | *s = syscallArgs{ | |
| 27 | + | fn: fn, | |
| 28 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], | |
| 29 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], | |
| 30 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], | |
| 31 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], a16: sysargs[15], | |
| 32 | + | a17: sysargs[16], a18: sysargs[17], a19: sysargs[18], a20: sysargs[19], | |
| 33 | + | a21: sysargs[20], a22: sysargs[21], a23: sysargs[22], a24: sysargs[23], | |
| 34 | + | a25: sysargs[24], a26: sysargs[25], a27: sysargs[26], a28: sysargs[27], | |
| 35 | + | a29: sysargs[28], a30: sysargs[29], a31: sysargs[30], a32: sysargs[31], | |
| 36 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], | |
| 37 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], | |
| 38 | + | arm64_r8: r8, | |
| 39 | + | } | |
| 40 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) | |
| 41 | + | return s | |
| 51 | 42 | } | |
| 52 | 43 | ||
| 53 | 44 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |
| @@ -76,8 +67,18 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||
| 76 | 67 | if len(args) > maxArgs { | |
| 77 | 68 | panic("purego: too many arguments to SyscallN") | |
| 78 | 69 | } | |
| 70 | + | ||
| 71 | + | // Windows uses syscall.SyscallN in syscall_windows.go. | |
| 72 | + | if runtime.GOOS == "windows" { | |
| 73 | + | return syscall_syscallN(fn, args...) | |
| 74 | + | } | |
| 75 | + | ||
| 79 | 76 | // add padding so there is no out-of-bounds slicing | |
| 80 | 77 | var tmp [maxArgs]uintptr | |
| 81 | 78 | copy(tmp[:], args) | |
| 82 | - | return syscall_syscall15X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14]) | |
| 79 | + | var floats [maxArgs]uintptr | |
| 80 | + | copy(floats[:], tmp[:]) | |
| 81 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |
| 82 | + | defer thePool.Put(s) | |
| 83 | + | return s.a1, s.a2, s.a3 | |
| 83 | 84 | } | |
| @@ -1,53 +1,44 @@ | |||||
| 1 | // SPDX-License-Identifier: Apache-2.0 | 1 | // SPDX-License-Identifier: Apache-2.0 | ||
| 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | 2 | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | ||
| 3 | 3 | ||||
| 4 | - | //go:build !386 && !arm && (darwin || freebsd || linux || netbsd || windows) | 4 | + | //go:build !386 && !arm && !ppc64le && (darwin || freebsd || linux || netbsd || windows) |
| 5 | 5 | ||||
| 6 | package purego | 6 | package purego | ||
| 7 | 7 | ||||
| 8 | - | // CDecl marks a function as being called using the __cdecl calling convention as defined in | 8 | + | import ( |
| 9 | - | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | 9 | + | "runtime" |
| 10 | - | // This is only useful on 386 Windows, but it is safe to use on other platforms. | 10 | + | "unsafe" |
| 11 | - | // | 11 | + | ) |
| 12 | - | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |||
| 13 | - | type CDecl struct{} | |||
| 14 | 12 | ||||
| 15 | const ( | 13 | const ( | ||
| 16 | - | maxArgs = 15 | 14 | + | maxArgs = 32 |
| 17 | ) | 15 | ) | ||
| 18 | 16 | ||||
| 19 | - | type syscall15Args struct { | 17 | + | type syscallArgs struct { |
| 20 | - | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | 18 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr |
| 21 | - | f1, f2, f3, f4, f5, f6, f7, f8 uintptr | 19 | + | a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr |
| 22 | - | arm64_r8 uintptr | 20 | + | f1, f2, f3, f4, f5, f6, f7, f8 uintptr |
| 21 | + | arm64_r8 uintptr | |||
| 23 | } | 22 | } | ||
| 24 | 23 | ||||
| 25 | - | func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) { | 24 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { |
| 26 | - | s.fn = fn | 25 | + | s := thePool.Get().(*syscallArgs) |
| 27 | - | s.a1 = ints[0] | 26 | + | *s = syscallArgs{ |
| 28 | - | s.a2 = ints[1] | 27 | + | fn: fn, |
| 29 | - | s.a3 = ints[2] | 28 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], |
| 30 | - | s.a4 = ints[3] | 29 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], |
| 31 | - | s.a5 = ints[4] | 30 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], |
| 32 | - | s.a6 = ints[5] | 31 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], a16: sysargs[15], |
| 33 | - | s.a7 = ints[6] | 32 | + | a17: sysargs[16], a18: sysargs[17], a19: sysargs[18], a20: sysargs[19], |
| 34 | - | s.a8 = ints[7] | 33 | + | a21: sysargs[20], a22: sysargs[21], a23: sysargs[22], a24: sysargs[23], |
| 35 | - | s.a9 = ints[8] | 34 | + | a25: sysargs[24], a26: sysargs[25], a27: sysargs[26], a28: sysargs[27], |
| 36 | - | s.a10 = ints[9] | 35 | + | a29: sysargs[28], a30: sysargs[29], a31: sysargs[30], a32: sysargs[31], |
| 37 | - | s.a11 = ints[10] | 36 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], |
| 38 | - | s.a12 = ints[11] | 37 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], |
| 39 | - | s.a13 = ints[12] | 38 | + | arm64_r8: r8, |
| 40 | - | s.a14 = ints[13] | 39 | + | } |
| 41 | - | s.a15 = ints[14] | 40 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) |
| 42 | - | s.f1 = floats[0] | 41 | + | return s |
| 43 | - | s.f2 = floats[1] | |||
| 44 | - | s.f3 = floats[2] | |||
| 45 | - | s.f4 = floats[3] | |||
| 46 | - | s.f5 = floats[4] | |||
| 47 | - | s.f6 = floats[5] | |||
| 48 | - | s.f7 = floats[6] | |||
| 49 | - | s.f8 = floats[7] | |||
| 50 | - | s.arm64_r8 = r8 | |||
| 51 | } | 42 | } | ||
| 52 | 43 | ||||
| 53 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | 44 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | ||
| @@ -76,8 +67,18 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||||
| 76 | if len(args) > maxArgs { | 67 | if len(args) > maxArgs { | ||
| 77 | panic("purego: too many arguments to SyscallN") | 68 | panic("purego: too many arguments to SyscallN") | ||
| 78 | } | 69 | } | ||
| 70 | + | ||||
| 71 | + | // Windows uses syscall.SyscallN in syscall_windows.go. | |||
| 72 | + | if runtime.GOOS == "windows" { | |||
| 73 | + | return syscall_syscallN(fn, args...) | |||
| 74 | + | } | |||
| 75 | + | ||||
| 79 | // add padding so there is no out-of-bounds slicing | 76 | // add padding so there is no out-of-bounds slicing | ||
| 80 | var tmp [maxArgs]uintptr | 77 | var tmp [maxArgs]uintptr | ||
| 81 | copy(tmp[:], args) | 78 | copy(tmp[:], args) | ||
| 82 | - | return syscall_syscall15X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14]) | 79 | + | var floats [maxArgs]uintptr |
| 80 | + | copy(floats[:], tmp[:]) | |||
| 81 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |||
| 82 | + | defer thePool.Put(s) | |||
| 83 | + | return s.a1, s.a2, s.a3 | |||
| 83 | } | 84 | } | ||
M syscall_32bit.go +37 -60
| @@ -5,75 +5,42 @@ | |||
| 5 | 5 | ||
| 6 | 6 | package purego | |
| 7 | 7 | ||
| 8 | - | // CDecl marks a function as being called using the __cdecl calling convention as defined in | |
| 9 | - | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | |
| 10 | - | // This is only useful on 386 Windows, but it is safe to use on other platforms. | |
| 11 | - | // | |
| 12 | - | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |
| 13 | - | type CDecl struct{} | |
| 8 | + | import ( | |
| 9 | + | "runtime" | |
| 10 | + | "unsafe" | |
| 11 | + | ) | |
| 14 | 12 | ||
| 15 | 13 | const ( | |
| 16 | 14 | maxArgs = 32 | |
| 17 | 15 | ) | |
| 18 | 16 | ||
| 19 | - | type syscall15Args struct { | |
| 17 | + | type syscallArgs struct { | |
| 20 | 18 | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | |
| 21 | 19 | a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr | |
| 22 | 20 | f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16 uintptr | |
| 23 | 21 | arm64_r8 uintptr | |
| 24 | 22 | } | |
| 25 | 23 | ||
| 26 | - | func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) { | |
| 27 | - | s.fn = fn | |
| 28 | - | s.a1 = ints[0] | |
| 29 | - | s.a2 = ints[1] | |
| 30 | - | s.a3 = ints[2] | |
| 31 | - | s.a4 = ints[3] | |
| 32 | - | s.a5 = ints[4] | |
| 33 | - | s.a6 = ints[5] | |
| 34 | - | s.a7 = ints[6] | |
| 35 | - | s.a8 = ints[7] | |
| 36 | - | s.a9 = ints[8] | |
| 37 | - | s.a10 = ints[9] | |
| 38 | - | s.a11 = ints[10] | |
| 39 | - | s.a12 = ints[11] | |
| 40 | - | s.a13 = ints[12] | |
| 41 | - | s.a14 = ints[13] | |
| 42 | - | s.a15 = ints[14] | |
| 43 | - | s.a16 = ints[15] | |
| 44 | - | s.a17 = ints[16] | |
| 45 | - | s.a18 = ints[17] | |
| 46 | - | s.a19 = ints[18] | |
| 47 | - | s.a20 = ints[19] | |
| 48 | - | s.a21 = ints[20] | |
| 49 | - | s.a22 = ints[21] | |
| 50 | - | s.a23 = ints[22] | |
| 51 | - | s.a24 = ints[23] | |
| 52 | - | s.a25 = ints[24] | |
| 53 | - | s.a26 = ints[25] | |
| 54 | - | s.a27 = ints[26] | |
| 55 | - | s.a28 = ints[27] | |
| 56 | - | s.a29 = ints[28] | |
| 57 | - | s.a30 = ints[29] | |
| 58 | - | s.a31 = ints[30] | |
| 59 | - | s.a32 = ints[31] | |
| 60 | - | s.f1 = floats[0] | |
| 61 | - | s.f2 = floats[1] | |
| 62 | - | s.f3 = floats[2] | |
| 63 | - | s.f4 = floats[3] | |
| 64 | - | s.f5 = floats[4] | |
| 65 | - | s.f6 = floats[5] | |
| 66 | - | s.f7 = floats[6] | |
| 67 | - | s.f8 = floats[7] | |
| 68 | - | s.f9 = floats[8] | |
| 69 | - | s.f10 = floats[9] | |
| 70 | - | s.f11 = floats[10] | |
| 71 | - | s.f12 = floats[11] | |
| 72 | - | s.f13 = floats[12] | |
| 73 | - | s.f14 = floats[13] | |
| 74 | - | s.f15 = floats[14] | |
| 75 | - | s.f16 = floats[15] | |
| 76 | - | s.arm64_r8 = r8 | |
| 24 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { | |
| 25 | + | s := thePool.Get().(*syscallArgs) | |
| 26 | + | *s = syscallArgs{ | |
| 27 | + | fn: fn, | |
| 28 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], | |
| 29 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], | |
| 30 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], | |
| 31 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], a16: sysargs[15], | |
| 32 | + | a17: sysargs[16], a18: sysargs[17], a19: sysargs[18], a20: sysargs[19], | |
| 33 | + | a21: sysargs[20], a22: sysargs[21], a23: sysargs[22], a24: sysargs[23], | |
| 34 | + | a25: sysargs[24], a26: sysargs[25], a27: sysargs[26], a28: sysargs[27], | |
| 35 | + | a29: sysargs[28], a30: sysargs[29], a31: sysargs[30], a32: sysargs[31], | |
| 36 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], | |
| 37 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], | |
| 38 | + | f9: floats[8], f10: floats[9], f11: floats[10], f12: floats[11], | |
| 39 | + | f13: floats[12], f14: floats[13], f15: floats[14], f16: floats[15], | |
| 40 | + | arm64_r8: r8, | |
| 41 | + | } | |
| 42 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) | |
| 43 | + | return s | |
| 77 | 44 | } | |
| 78 | 45 | ||
| 79 | 46 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |
| @@ -102,8 +69,18 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||
| 102 | 69 | if len(args) > maxArgs { | |
| 103 | 70 | panic("purego: too many arguments to SyscallN") | |
| 104 | 71 | } | |
| 105 | - | // add padding so there is no out-of-bounds slicing | |
| 72 | + | ||
| 73 | + | // Windows uses syscall.SyscallN in syscall_windows.go. | |
| 74 | + | if runtime.GOOS == "windows" { | |
| 75 | + | return syscall_syscallN(fn, args...) | |
| 76 | + | } | |
| 77 | + | ||
| 78 | + | // Add padding so there is no out-of-bounds slicing. | |
| 106 | 79 | var tmp [maxArgs]uintptr | |
| 107 | 80 | copy(tmp[:], args) | |
| 108 | - | return syscall_syscall15X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14]) | |
| 81 | + | var floats [16]uintptr | |
| 82 | + | copy(floats[:], tmp[:16]) | |
| 83 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |
| 84 | + | defer thePool.Put(s) | |
| 85 | + | return s.a1, s.a2, s.a3 | |
| 109 | 86 | } | |
| @@ -5,75 +5,42 @@ | |||||
| 5 | 5 | ||||
| 6 | package purego | 6 | package purego | ||
| 7 | 7 | ||||
| 8 | - | // CDecl marks a function as being called using the __cdecl calling convention as defined in | 8 | + | import ( |
| 9 | - | // the [MSDocs] when passed to NewCallback. It must be the first argument to the function. | 9 | + | "runtime" |
| 10 | - | // This is only useful on 386 Windows, but it is safe to use on other platforms. | 10 | + | "unsafe" |
| 11 | - | // | 11 | + | ) |
| 12 | - | // [MSDocs]: https://learn.microsoft.com/en-us/cpp/cpp/cdecl?view=msvc-170 | |||
| 13 | - | type CDecl struct{} | |||
| 14 | 12 | ||||
| 15 | const ( | 13 | const ( | ||
| 16 | maxArgs = 32 | 14 | maxArgs = 32 | ||
| 17 | ) | 15 | ) | ||
| 18 | 16 | ||||
| 19 | - | type syscall15Args struct { | 17 | + | type syscallArgs struct { |
| 20 | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | 18 | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | ||
| 21 | a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr | 19 | a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr | ||
| 22 | f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16 uintptr | 20 | f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16 uintptr | ||
| 23 | arm64_r8 uintptr | 21 | arm64_r8 uintptr | ||
| 24 | } | 22 | } | ||
| 25 | 23 | ||||
| 26 | - | func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uintptr) { | 24 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { |
| 27 | - | s.fn = fn | 25 | + | s := thePool.Get().(*syscallArgs) |
| 28 | - | s.a1 = ints[0] | 26 | + | *s = syscallArgs{ |
| 29 | - | s.a2 = ints[1] | 27 | + | fn: fn, |
| 30 | - | s.a3 = ints[2] | 28 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], |
| 31 | - | s.a4 = ints[3] | 29 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], |
| 32 | - | s.a5 = ints[4] | 30 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], |
| 33 | - | s.a6 = ints[5] | 31 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], a16: sysargs[15], |
| 34 | - | s.a7 = ints[6] | 32 | + | a17: sysargs[16], a18: sysargs[17], a19: sysargs[18], a20: sysargs[19], |
| 35 | - | s.a8 = ints[7] | 33 | + | a21: sysargs[20], a22: sysargs[21], a23: sysargs[22], a24: sysargs[23], |
| 36 | - | s.a9 = ints[8] | 34 | + | a25: sysargs[24], a26: sysargs[25], a27: sysargs[26], a28: sysargs[27], |
| 37 | - | s.a10 = ints[9] | 35 | + | a29: sysargs[28], a30: sysargs[29], a31: sysargs[30], a32: sysargs[31], |
| 38 | - | s.a11 = ints[10] | 36 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], |
| 39 | - | s.a12 = ints[11] | 37 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], |
| 40 | - | s.a13 = ints[12] | 38 | + | f9: floats[8], f10: floats[9], f11: floats[10], f12: floats[11], |
| 41 | - | s.a14 = ints[13] | 39 | + | f13: floats[12], f14: floats[13], f15: floats[14], f16: floats[15], |
| 42 | - | s.a15 = ints[14] | 40 | + | arm64_r8: r8, |
| 43 | - | s.a16 = ints[15] | 41 | + | } |
| 44 | - | s.a17 = ints[16] | 42 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) |
| 45 | - | s.a18 = ints[17] | 43 | + | return s |
| 46 | - | s.a19 = ints[18] | |||
| 47 | - | s.a20 = ints[19] | |||
| 48 | - | s.a21 = ints[20] | |||
| 49 | - | s.a22 = ints[21] | |||
| 50 | - | s.a23 = ints[22] | |||
| 51 | - | s.a24 = ints[23] | |||
| 52 | - | s.a25 = ints[24] | |||
| 53 | - | s.a26 = ints[25] | |||
| 54 | - | s.a27 = ints[26] | |||
| 55 | - | s.a28 = ints[27] | |||
| 56 | - | s.a29 = ints[28] | |||
| 57 | - | s.a30 = ints[29] | |||
| 58 | - | s.a31 = ints[30] | |||
| 59 | - | s.a32 = ints[31] | |||
| 60 | - | s.f1 = floats[0] | |||
| 61 | - | s.f2 = floats[1] | |||
| 62 | - | s.f3 = floats[2] | |||
| 63 | - | s.f4 = floats[3] | |||
| 64 | - | s.f5 = floats[4] | |||
| 65 | - | s.f6 = floats[5] | |||
| 66 | - | s.f7 = floats[6] | |||
| 67 | - | s.f8 = floats[7] | |||
| 68 | - | s.f9 = floats[8] | |||
| 69 | - | s.f10 = floats[9] | |||
| 70 | - | s.f11 = floats[10] | |||
| 71 | - | s.f12 = floats[11] | |||
| 72 | - | s.f13 = floats[12] | |||
| 73 | - | s.f14 = floats[13] | |||
| 74 | - | s.f15 = floats[14] | |||
| 75 | - | s.f16 = floats[15] | |||
| 76 | - | s.arm64_r8 = r8 | |||
| 77 | } | 44 | } | ||
| 78 | 45 | ||||
| 79 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | 46 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | ||
| @@ -102,8 +69,18 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||||
| 102 | if len(args) > maxArgs { | 69 | if len(args) > maxArgs { | ||
| 103 | panic("purego: too many arguments to SyscallN") | 70 | panic("purego: too many arguments to SyscallN") | ||
| 104 | } | 71 | } | ||
| 105 | - | // add padding so there is no out-of-bounds slicing | 72 | + | |
| 73 | + | // Windows uses syscall.SyscallN in syscall_windows.go. | |||
| 74 | + | if runtime.GOOS == "windows" { | |||
| 75 | + | return syscall_syscallN(fn, args...) | |||
| 76 | + | } | |||
| 77 | + | ||||
| 78 | + | // Add padding so there is no out-of-bounds slicing. | |||
| 106 | var tmp [maxArgs]uintptr | 79 | var tmp [maxArgs]uintptr | ||
| 107 | copy(tmp[:], args) | 80 | copy(tmp[:], args) | ||
| 108 | - | return syscall_syscall15X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8], tmp[9], tmp[10], tmp[11], tmp[12], tmp[13], tmp[14]) | 81 | + | var floats [16]uintptr |
| 82 | + | copy(floats[:], tmp[:16]) | |||
| 83 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |||
| 84 | + | defer thePool.Put(s) | |||
| 85 | + | return s.a1, s.a2, s.a3 | |||
| 109 | } | 86 | } | ||
M syscall_cgo_linux.go +1 -6
| @@ -9,12 +9,7 @@ import ( | |||
| 9 | 9 | "github.com/ebitengine/purego/internal/cgo" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | var syscall15XABI0 = uintptr(cgo.Syscall15XABI0) | |
| 13 | - | ||
| 14 | - | //go:nosplit | |
| 15 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |
| 16 | - | return cgo.Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) | |
| 17 | - | } | |
| 12 | + | var syscallXABI0 = uintptr(cgo.SyscallXABI0) | |
| 18 | 13 | ||
| 19 | 14 | func NewCallback(_ any) uintptr { | |
| 20 | 15 | panic("purego: NewCallback on Linux is only supported on 386/amd64/arm64/arm/loong64/ppc64le/riscv64/s390x") | |
| @@ -9,12 +9,7 @@ import ( | |||||
| 9 | "github.com/ebitengine/purego/internal/cgo" | 9 | "github.com/ebitengine/purego/internal/cgo" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | var syscall15XABI0 = uintptr(cgo.Syscall15XABI0) | 12 | + | var syscallXABI0 = uintptr(cgo.SyscallXABI0) |
| 13 | - | ||||
| 14 | - | //go:nosplit | |||
| 15 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |||
| 16 | - | return cgo.Syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) | |||
| 17 | - | } | |||
| 18 | 13 | ||||
| 19 | func NewCallback(_ any) uintptr { | 14 | func NewCallback(_ any) uintptr { | ||
| 20 | panic("purego: NewCallback on Linux is only supported on 386/amd64/arm64/arm/loong64/ppc64le/riscv64/s390x") | 15 | panic("purego: NewCallback on Linux is only supported on 386/amd64/arm64/arm/loong64/ppc64le/riscv64/s390x") | ||
M syscall_notstackargs.go +4 -0
| @@ -35,3 +35,7 @@ type callbackArgs struct { | |||
| 35 | 35 | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |
| 36 | 36 | return nil | |
| 37 | 37 | } | |
| 38 | + | ||
| 39 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |
| 40 | + | return nil | |
| 41 | + | } | |
| @@ -35,3 +35,7 @@ type callbackArgs struct { | |||||
| 35 | func (c *callbackArgs) stackFrame() unsafe.Pointer { | 35 | func (c *callbackArgs) stackFrame() unsafe.Pointer { | ||
| 36 | return nil | 36 | return nil | ||
| 37 | } | 37 | } | ||
| 38 | + | ||||
| 39 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |||
| 40 | + | return nil | |||
| 41 | + | } | |||
A syscall_ppc64le.go +72 -0
| @@ -0,0 +1,72 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | //go:build linux | |
| 5 | + | ||
| 6 | + | package purego | |
| 7 | + | ||
| 8 | + | import ( | |
| 9 | + | "unsafe" | |
| 10 | + | ) | |
| 11 | + | ||
| 12 | + | const ( | |
| 13 | + | maxArgs = 15 | |
| 14 | + | ) | |
| 15 | + | ||
| 16 | + | type syscallArgs struct { | |
| 17 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | |
| 18 | + | f1, f2, f3, f4, f5, f6, f7, f8 uintptr | |
| 19 | + | arm64_r8 uintptr | |
| 20 | + | } | |
| 21 | + | ||
| 22 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { | |
| 23 | + | s := thePool.Get().(*syscallArgs) | |
| 24 | + | *s = syscallArgs{ | |
| 25 | + | fn: fn, | |
| 26 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], | |
| 27 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], | |
| 28 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], | |
| 29 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], | |
| 30 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], | |
| 31 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], | |
| 32 | + | arm64_r8: r8, | |
| 33 | + | } | |
| 34 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) | |
| 35 | + | return s | |
| 36 | + | } | |
| 37 | + | ||
| 38 | + | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |
| 39 | + | // There is an internal maximum number of arguments that SyscallN can take. It panics | |
| 40 | + | // when the maximum is exceeded. It returns the result and the libc error code if there is one. | |
| 41 | + | // | |
| 42 | + | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | |
| 43 | + | // especially point 4. | |
| 44 | + | // | |
| 45 | + | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | |
| 46 | + | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | |
| 47 | + | // for an explanation of why that is. | |
| 48 | + | // | |
| 49 | + | // On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the | |
| 50 | + | // stack. | |
| 51 | + | // | |
| 52 | + | // The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes | |
| 53 | + | // which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect | |
| 54 | + | // their memory location. | |
| 55 | + | // | |
| 56 | + | //go:uintptrescapes | |
| 57 | + | func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |
| 58 | + | if fn == 0 { | |
| 59 | + | panic("purego: fn is nil") | |
| 60 | + | } | |
| 61 | + | if len(args) > maxArgs { | |
| 62 | + | panic("purego: too many arguments to SyscallN") | |
| 63 | + | } | |
| 64 | + | ||
| 65 | + | var tmp [maxArgs]uintptr | |
| 66 | + | copy(tmp[:], args) | |
| 67 | + | var floats [maxArgs]uintptr | |
| 68 | + | copy(floats[:], tmp[:]) | |
| 69 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |
| 70 | + | defer thePool.Put(s) | |
| 71 | + | return s.a1, s.a2, s.a3 | |
| 72 | + | } | |
| @@ -0,0 +1,72 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2022 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | //go:build linux | |||
| 5 | + | ||||
| 6 | + | package purego | |||
| 7 | + | ||||
| 8 | + | import ( | |||
| 9 | + | "unsafe" | |||
| 10 | + | ) | |||
| 11 | + | ||||
| 12 | + | const ( | |||
| 13 | + | maxArgs = 15 | |||
| 14 | + | ) | |||
| 15 | + | ||||
| 16 | + | type syscallArgs struct { | |||
| 17 | + | fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr | |||
| 18 | + | f1, f2, f3, f4, f5, f6, f7, f8 uintptr | |||
| 19 | + | arm64_r8 uintptr | |||
| 20 | + | } | |||
| 21 | + | ||||
| 22 | + | func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs { | |||
| 23 | + | s := thePool.Get().(*syscallArgs) | |||
| 24 | + | *s = syscallArgs{ | |||
| 25 | + | fn: fn, | |||
| 26 | + | a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3], | |||
| 27 | + | a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7], | |||
| 28 | + | a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11], | |||
| 29 | + | a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], | |||
| 30 | + | f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3], | |||
| 31 | + | f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7], | |||
| 32 | + | arm64_r8: r8, | |||
| 33 | + | } | |||
| 34 | + | runtime_cgocall(syscallXABI0, unsafe.Pointer(s)) | |||
| 35 | + | return s | |||
| 36 | + | } | |||
| 37 | + | ||||
| 38 | + | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |||
| 39 | + | // There is an internal maximum number of arguments that SyscallN can take. It panics | |||
| 40 | + | // when the maximum is exceeded. It returns the result and the libc error code if there is one. | |||
| 41 | + | // | |||
| 42 | + | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | |||
| 43 | + | // especially point 4. | |||
| 44 | + | // | |||
| 45 | + | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | |||
| 46 | + | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | |||
| 47 | + | // for an explanation of why that is. | |||
| 48 | + | // | |||
| 49 | + | // On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the | |||
| 50 | + | // stack. | |||
| 51 | + | // | |||
| 52 | + | // The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes | |||
| 53 | + | // which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect | |||
| 54 | + | // their memory location. | |||
| 55 | + | // | |||
| 56 | + | //go:uintptrescapes | |||
| 57 | + | func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||
| 58 | + | if fn == 0 { | |||
| 59 | + | panic("purego: fn is nil") | |||
| 60 | + | } | |||
| 61 | + | if len(args) > maxArgs { | |||
| 62 | + | panic("purego: too many arguments to SyscallN") | |||
| 63 | + | } | |||
| 64 | + | ||||
| 65 | + | var tmp [maxArgs]uintptr | |||
| 66 | + | copy(tmp[:], args) | |||
| 67 | + | var floats [maxArgs]uintptr | |||
| 68 | + | copy(floats[:], tmp[:]) | |||
| 69 | + | s := syscall_SyscallN(fn, tmp[:], floats[:], 0) | |||
| 70 | + | defer thePool.Put(s) | |||
| 71 | + | return s.a1, s.a2, s.a3 | |||
| 72 | + | } | |||
D syscall_stackargs.go +0 -42
| @@ -1,42 +0,0 @@ | |||
| 1 | - | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | - | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |
| 3 | - | ||
| 4 | - | //go:build ppc64le || s390x | |
| 5 | - | ||
| 6 | - | package purego | |
| 7 | - | ||
| 8 | - | import "unsafe" | |
| 9 | - | ||
| 10 | - | // callbackArgs is the argument block passed from the assembly trampoline | |
| 11 | - | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |
| 12 | - | // The assembly fills in the fields before calling callbackWrap, which uses | |
| 13 | - | // them to determine which Go function to invoke and where to read its | |
| 14 | - | // arguments from, and writes the return value back into result. | |
| 15 | - | // | |
| 16 | - | // callbackArgs is only used on Unix. On Windows, callbacks are handled by | |
| 17 | - | // the runtime's own callback mechanism, so this type is compiled but unused, | |
| 18 | - | // serving only as a stub to satisfy cross-platform compilation. | |
| 19 | - | type callbackArgs struct { | |
| 20 | - | index uintptr | |
| 21 | - | // args points to the argument block. | |
| 22 | - | // | |
| 23 | - | // The structure of the arguments goes | |
| 24 | - | // float registers followed by the | |
| 25 | - | // integer registers followed by the stack. | |
| 26 | - | // | |
| 27 | - | // This variable is treated as a contiguous | |
| 28 | - | // block of memory containing all of the arguments | |
| 29 | - | // for this callback. | |
| 30 | - | args unsafe.Pointer | |
| 31 | - | // Below are out-args from callbackWrap | |
| 32 | - | result [1]uintptr | |
| 33 | - | // stackArgs points to stack-passed arguments for architectures where | |
| 34 | - | // they can't be made contiguous with register args (e.g., ppc64le). | |
| 35 | - | // On other architectures, this is nil and stack args are read from | |
| 36 | - | // the end of the args block. | |
| 37 | - | stackArgs unsafe.Pointer | |
| 38 | - | } | |
| 39 | - | ||
| 40 | - | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |
| 41 | - | return c.stackArgs | |
| 42 | - | } | |
| @@ -1,42 +0,0 @@ | |||||
| 1 | - | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | - | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |||
| 3 | - | ||||
| 4 | - | //go:build ppc64le || s390x | |||
| 5 | - | ||||
| 6 | - | package purego | |||
| 7 | - | ||||
| 8 | - | import "unsafe" | |||
| 9 | - | ||||
| 10 | - | // callbackArgs is the argument block passed from the assembly trampoline | |||
| 11 | - | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |||
| 12 | - | // The assembly fills in the fields before calling callbackWrap, which uses | |||
| 13 | - | // them to determine which Go function to invoke and where to read its | |||
| 14 | - | // arguments from, and writes the return value back into result. | |||
| 15 | - | // | |||
| 16 | - | // callbackArgs is only used on Unix. On Windows, callbacks are handled by | |||
| 17 | - | // the runtime's own callback mechanism, so this type is compiled but unused, | |||
| 18 | - | // serving only as a stub to satisfy cross-platform compilation. | |||
| 19 | - | type callbackArgs struct { | |||
| 20 | - | index uintptr | |||
| 21 | - | // args points to the argument block. | |||
| 22 | - | // | |||
| 23 | - | // The structure of the arguments goes | |||
| 24 | - | // float registers followed by the | |||
| 25 | - | // integer registers followed by the stack. | |||
| 26 | - | // | |||
| 27 | - | // This variable is treated as a contiguous | |||
| 28 | - | // block of memory containing all of the arguments | |||
| 29 | - | // for this callback. | |||
| 30 | - | args unsafe.Pointer | |||
| 31 | - | // Below are out-args from callbackWrap | |||
| 32 | - | result [1]uintptr | |||
| 33 | - | // stackArgs points to stack-passed arguments for architectures where | |||
| 34 | - | // they can't be made contiguous with register args (e.g., ppc64le). | |||
| 35 | - | // On other architectures, this is nil and stack args are read from | |||
| 36 | - | // the end of the args block. | |||
| 37 | - | stackArgs unsafe.Pointer | |||
| 38 | - | } | |||
| 39 | - | ||||
| 40 | - | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |||
| 41 | - | return c.stackArgs | |||
| 42 | - | } | |||
A syscall_stackargs_ppc64le.go +30 -0
| @@ -0,0 +1,30 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | package purego | |
| 5 | + | ||
| 6 | + | import "unsafe" | |
| 7 | + | ||
| 8 | + | // callbackArgs is the argument block passed from the assembly trampoline | |
| 9 | + | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |
| 10 | + | type callbackArgs struct { | |
| 11 | + | index uintptr | |
| 12 | + | // args points to the argument block. | |
| 13 | + | // | |
| 14 | + | // The structure of the arguments goes | |
| 15 | + | // float registers followed by the | |
| 16 | + | // integer registers. | |
| 17 | + | args unsafe.Pointer | |
| 18 | + | // Below are out-args from callbackWrap. | |
| 19 | + | result [1]uintptr | |
| 20 | + | // stackArgs points to stack-passed arguments. | |
| 21 | + | stackArgs unsafe.Pointer | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |
| 25 | + | return c.stackArgs | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |
| 29 | + | return nil | |
| 30 | + | } | |
| @@ -0,0 +1,30 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | package purego | |||
| 5 | + | ||||
| 6 | + | import "unsafe" | |||
| 7 | + | ||||
| 8 | + | // callbackArgs is the argument block passed from the assembly trampoline | |||
| 9 | + | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |||
| 10 | + | type callbackArgs struct { | |||
| 11 | + | index uintptr | |||
| 12 | + | // args points to the argument block. | |||
| 13 | + | // | |||
| 14 | + | // The structure of the arguments goes | |||
| 15 | + | // float registers followed by the | |||
| 16 | + | // integer registers. | |||
| 17 | + | args unsafe.Pointer | |||
| 18 | + | // Below are out-args from callbackWrap. | |||
| 19 | + | result [1]uintptr | |||
| 20 | + | // stackArgs points to stack-passed arguments. | |||
| 21 | + | stackArgs unsafe.Pointer | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |||
| 25 | + | return c.stackArgs | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |||
| 29 | + | return nil | |||
| 30 | + | } | |||
A syscall_stackargs_s390x.go +30 -0
| @@ -0,0 +1,30 @@ | |||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |
| 3 | + | ||
| 4 | + | package purego | |
| 5 | + | ||
| 6 | + | import "unsafe" | |
| 7 | + | ||
| 8 | + | // callbackArgs is the argument block passed from the assembly trampoline | |
| 9 | + | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |
| 10 | + | type callbackArgs struct { | |
| 11 | + | index uintptr | |
| 12 | + | // args points to the argument block. | |
| 13 | + | // | |
| 14 | + | // The structure of the arguments goes | |
| 15 | + | // float registers followed by the | |
| 16 | + | // integer registers followed by the stack. | |
| 17 | + | args unsafe.Pointer | |
| 18 | + | // Below are out-args from callbackWrap. | |
| 19 | + | result [1]uintptr | |
| 20 | + | // stackArgs points to stack-passed arguments. | |
| 21 | + | stackArgs unsafe.Pointer | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |
| 25 | + | return c.stackArgs | |
| 26 | + | } | |
| 27 | + | ||
| 28 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |
| 29 | + | return nil | |
| 30 | + | } | |
| @@ -0,0 +1,30 @@ | |||||
| 1 | + | // SPDX-License-Identifier: Apache-2.0 | |||
| 2 | + | // SPDX-FileCopyrightText: 2026 The Ebitengine Authors | |||
| 3 | + | ||||
| 4 | + | package purego | |||
| 5 | + | ||||
| 6 | + | import "unsafe" | |||
| 7 | + | ||||
| 8 | + | // callbackArgs is the argument block passed from the assembly trampoline | |||
| 9 | + | // to callbackWrap when C code calls a Go callback registered with NewCallback. | |||
| 10 | + | type callbackArgs struct { | |||
| 11 | + | index uintptr | |||
| 12 | + | // args points to the argument block. | |||
| 13 | + | // | |||
| 14 | + | // The structure of the arguments goes | |||
| 15 | + | // float registers followed by the | |||
| 16 | + | // integer registers followed by the stack. | |||
| 17 | + | args unsafe.Pointer | |||
| 18 | + | // Below are out-args from callbackWrap. | |||
| 19 | + | result [1]uintptr | |||
| 20 | + | // stackArgs points to stack-passed arguments. | |||
| 21 | + | stackArgs unsafe.Pointer | |||
| 22 | + | } | |||
| 23 | + | ||||
| 24 | + | func (c *callbackArgs) stackFrame() unsafe.Pointer { | |||
| 25 | + | return c.stackArgs | |||
| 26 | + | } | |||
| 27 | + | ||||
| 28 | + | func (c *callbackArgs) intFrame() unsafe.Pointer { | |||
| 29 | + | return nil | |||
| 30 | + | } | |||
M syscall_unix.go +18 -21
| @@ -13,21 +13,10 @@ import ( | |||
| 13 | 13 | "unsafe" | |
| 14 | 14 | ) | |
| 15 | 15 | ||
| 16 | - | var syscall15XABI0 uintptr | |
| 16 | + | var syscallXABI0 uintptr | |
| 17 | 17 | ||
| 18 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |
| 19 | - | args := thePool.Get().(*syscall15Args) | |
| 20 | - | defer thePool.Put(args) | |
| 21 | - | ||
| 22 | - | *args = syscall15Args{ | |
| 23 | - | fn: fn, | |
| 24 | - | a1: a1, a2: a2, a3: a3, a4: a4, a5: a5, a6: a6, a7: a7, a8: a8, | |
| 25 | - | a9: a9, a10: a10, a11: a11, a12: a12, a13: a13, a14: a14, a15: a15, | |
| 26 | - | f1: a1, f2: a2, f3: a3, f4: a4, f5: a5, f6: a6, f7: a7, f8: a8, | |
| 27 | - | } | |
| 28 | - | ||
| 29 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(args)) | |
| 30 | - | return args.a1, args.a2, args.a3 | |
| 18 | + | func syscall_syscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |
| 19 | + | panic("purego: syscall_syscallN is only supported on windows") | |
| 31 | 20 | } | |
| 32 | 21 | ||
| 33 | 22 | // NewCallback converts a Go function to a function pointer conforming to the C calling convention. | |
| @@ -136,10 +125,14 @@ func callbackWrap(a *callbackArgs) { | |||
| 136 | 125 | // stackFrame points to stack-passed arguments. On most architectures this is | |
| 137 | 126 | // contiguous with frame (after register args), but on ppc64le it's separate. | |
| 138 | 127 | var stackFrame *[callbackMaxFrame]uintptr | |
| 128 | + | var intFrame *[callbackMaxFrame]uintptr | |
| 139 | 129 | if sf := a.stackFrame(); sf != nil { | |
| 140 | 130 | // Only ppc64le uses separate stackArgs pointer due to NOSPLIT constraints | |
| 141 | 131 | stackFrame = (*[callbackMaxFrame]uintptr)(sf) | |
| 142 | 132 | } | |
| 133 | + | if intf := a.intFrame(); intf != nil { | |
| 134 | + | intFrame = (*[callbackMaxFrame]uintptr)(intf) | |
| 135 | + | } | |
| 143 | 136 | // floatsN and intsN track the number of register slots used, not argument count. | |
| 144 | 137 | // This distinction matters on ARM32 where float64 uses 2 slots (32-bit registers). | |
| 145 | 138 | var floatsN int | |
| @@ -147,7 +140,7 @@ func callbackWrap(a *callbackArgs) { | |||
| 147 | 140 | // On amd64/loong64/ppc64le/riscv64/s390x, when returning a struct larger than | |
| 148 | 141 | // maxRegAllocStructSize, the caller passes a hidden pointer in the first integer | |
| 149 | 142 | // register. Skip it to avoid misreading it as the first function argument. | |
| 150 | - | if (runtime.GOARCH == "amd64" || runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") && | |
| 143 | + | if (runtime.GOARCH == "amd64" || runtime.GOARCH == "loong64" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") && | |
| 151 | 144 | fnType.NumOut() == 1 && fnType.Out(0).Kind() == reflect.Struct && | |
| 152 | 145 | fnType.Out(0).Size() > maxRegAllocStructSize { | |
| 153 | 146 | intsN = 1 | |
| @@ -227,13 +220,17 @@ func callbackWrap(a *callbackArgs) { | |||
| 227 | 220 | stackSlot += slots | |
| 228 | 221 | } | |
| 229 | 222 | } else { | |
| 230 | - | // the integers begin after the floats in frame | |
| 231 | - | pos := intsN + numOfFloatRegisters() | |
| 232 | - | if runtime.GOARCH == "s390x" { | |
| 233 | - | // s390x big-endian: sub-8-byte values are right-justified in GPR slot | |
| 234 | - | args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[pos]), inType) | |
| 223 | + | if intFrame != nil { | |
| 224 | + | args[i] = reflect.NewAt(inType, unsafe.Pointer(&intFrame[intsN])).Elem() | |
| 235 | 225 | } else { | |
| 236 | - | args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[pos])).Elem() | |
| 226 | + | // the integers begin after the floats in frame | |
| 227 | + | pos := intsN + numOfFloatRegisters() | |
| 228 | + | if runtime.GOARCH == "s390x" { | |
| 229 | + | // s390x big-endian: sub-8-byte values are right-justified in GPR slot | |
| 230 | + | args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[pos]), inType) | |
| 231 | + | } else { | |
| 232 | + | args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[pos])).Elem() | |
| 233 | + | } | |
| 237 | 234 | } | |
| 238 | 235 | } | |
| 239 | 236 | intsN += slots | |
| @@ -13,21 +13,10 @@ import ( | |||||
| 13 | "unsafe" | 13 | "unsafe" | ||
| 14 | ) | 14 | ) | ||
| 15 | 15 | ||||
| 16 | - | var syscall15XABI0 uintptr | 16 | + | var syscallXABI0 uintptr |
| 17 | 17 | ||||
| 18 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | 18 | + | func syscall_syscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { |
| 19 | - | args := thePool.Get().(*syscall15Args) | 19 | + | panic("purego: syscall_syscallN is only supported on windows") |
| 20 | - | defer thePool.Put(args) | |||
| 21 | - | ||||
| 22 | - | *args = syscall15Args{ | |||
| 23 | - | fn: fn, | |||
| 24 | - | a1: a1, a2: a2, a3: a3, a4: a4, a5: a5, a6: a6, a7: a7, a8: a8, | |||
| 25 | - | a9: a9, a10: a10, a11: a11, a12: a12, a13: a13, a14: a14, a15: a15, | |||
| 26 | - | f1: a1, f2: a2, f3: a3, f4: a4, f5: a5, f6: a6, f7: a7, f8: a8, | |||
| 27 | - | } | |||
| 28 | - | ||||
| 29 | - | runtime_cgocall(syscall15XABI0, unsafe.Pointer(args)) | |||
| 30 | - | return args.a1, args.a2, args.a3 | |||
| 31 | } | 20 | } | ||
| 32 | 21 | ||||
| 33 | // NewCallback converts a Go function to a function pointer conforming to the C calling convention. | 22 | // NewCallback converts a Go function to a function pointer conforming to the C calling convention. | ||
| @@ -136,10 +125,14 @@ func callbackWrap(a *callbackArgs) { | |||||
| 136 | // stackFrame points to stack-passed arguments. On most architectures this is | 125 | // stackFrame points to stack-passed arguments. On most architectures this is | ||
| 137 | // contiguous with frame (after register args), but on ppc64le it's separate. | 126 | // contiguous with frame (after register args), but on ppc64le it's separate. | ||
| 138 | var stackFrame *[callbackMaxFrame]uintptr | 127 | var stackFrame *[callbackMaxFrame]uintptr | ||
| 128 | + | var intFrame *[callbackMaxFrame]uintptr | |||
| 139 | if sf := a.stackFrame(); sf != nil { | 129 | if sf := a.stackFrame(); sf != nil { | ||
| 140 | // Only ppc64le uses separate stackArgs pointer due to NOSPLIT constraints | 130 | // Only ppc64le uses separate stackArgs pointer due to NOSPLIT constraints | ||
| 141 | stackFrame = (*[callbackMaxFrame]uintptr)(sf) | 131 | stackFrame = (*[callbackMaxFrame]uintptr)(sf) | ||
| 142 | } | 132 | } | ||
| 133 | + | if intf := a.intFrame(); intf != nil { | |||
| 134 | + | intFrame = (*[callbackMaxFrame]uintptr)(intf) | |||
| 135 | + | } | |||
| 143 | // floatsN and intsN track the number of register slots used, not argument count. | 136 | // floatsN and intsN track the number of register slots used, not argument count. | ||
| 144 | // This distinction matters on ARM32 where float64 uses 2 slots (32-bit registers). | 137 | // This distinction matters on ARM32 where float64 uses 2 slots (32-bit registers). | ||
| 145 | var floatsN int | 138 | var floatsN int | ||
| @@ -147,7 +140,7 @@ func callbackWrap(a *callbackArgs) { | |||||
| 147 | // On amd64/loong64/ppc64le/riscv64/s390x, when returning a struct larger than | 140 | // On amd64/loong64/ppc64le/riscv64/s390x, when returning a struct larger than | ||
| 148 | // maxRegAllocStructSize, the caller passes a hidden pointer in the first integer | 141 | // maxRegAllocStructSize, the caller passes a hidden pointer in the first integer | ||
| 149 | // register. Skip it to avoid misreading it as the first function argument. | 142 | // register. Skip it to avoid misreading it as the first function argument. | ||
| 150 | - | if (runtime.GOARCH == "amd64" || runtime.GOARCH == "loong64" || runtime.GOARCH == "ppc64le" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") && | 143 | + | if (runtime.GOARCH == "amd64" || runtime.GOARCH == "loong64" || runtime.GOARCH == "riscv64" || runtime.GOARCH == "s390x") && |
| 151 | fnType.NumOut() == 1 && fnType.Out(0).Kind() == reflect.Struct && | 144 | fnType.NumOut() == 1 && fnType.Out(0).Kind() == reflect.Struct && | ||
| 152 | fnType.Out(0).Size() > maxRegAllocStructSize { | 145 | fnType.Out(0).Size() > maxRegAllocStructSize { | ||
| 153 | intsN = 1 | 146 | intsN = 1 | ||
| @@ -227,13 +220,17 @@ func callbackWrap(a *callbackArgs) { | |||||
| 227 | stackSlot += slots | 220 | stackSlot += slots | ||
| 228 | } | 221 | } | ||
| 229 | } else { | 222 | } else { | ||
| 230 | - | // the integers begin after the floats in frame | 223 | + | if intFrame != nil { |
| 231 | - | pos := intsN + numOfFloatRegisters() | 224 | + | args[i] = reflect.NewAt(inType, unsafe.Pointer(&intFrame[intsN])).Elem() |
| 232 | - | if runtime.GOARCH == "s390x" { | |||
| 233 | - | // s390x big-endian: sub-8-byte values are right-justified in GPR slot | |||
| 234 | - | args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[pos]), inType) | |||
| 235 | } else { | 225 | } else { | ||
| 236 | - | args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[pos])).Elem() | 226 | + | // the integers begin after the floats in frame |
| 227 | + | pos := intsN + numOfFloatRegisters() | |||
| 228 | + | if runtime.GOARCH == "s390x" { | |||
| 229 | + | // s390x big-endian: sub-8-byte values are right-justified in GPR slot | |||
| 230 | + | args[i] = callbackArgFromSlotBigEndian(unsafe.Pointer(&frame[pos]), inType) | |||
| 231 | + | } else { | |||
| 232 | + | args[i] = reflect.NewAt(inType, unsafe.Pointer(&frame[pos])).Elem() | |||
| 233 | + | } | |||
| 237 | } | 234 | } | ||
| 238 | } | 235 | } | ||
| 239 | intsN += slots | 236 | intsN += slots | ||
M syscall_windows.go +3 -3
| @@ -9,10 +9,10 @@ import ( | |||
| 9 | 9 | "unsafe" | |
| 10 | 10 | ) | |
| 11 | 11 | ||
| 12 | - | var syscall15XABI0 uintptr | |
| 12 | + | var syscallXABI0 uintptr | |
| 13 | 13 | ||
| 14 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | |
| 15 | - | r1, r2, errno := syscall.Syscall15(fn, 15, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) | |
| 14 | + | func syscall_syscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |
| 15 | + | r1, r2, errno := syscall.SyscallN(fn, args...) | |
| 16 | 16 | return r1, r2, uintptr(errno) | |
| 17 | 17 | } | |
| 18 | 18 | ||
| @@ -9,10 +9,10 @@ import ( | |||||
| 9 | "unsafe" | 9 | "unsafe" | ||
| 10 | ) | 10 | ) | ||
| 11 | 11 | ||||
| 12 | - | var syscall15XABI0 uintptr | 12 | + | var syscallXABI0 uintptr |
| 13 | 13 | ||||
| 14 | - | func syscall_syscall15X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 uintptr) (r1, r2, err uintptr) { | 14 | + | func syscall_syscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { |
| 15 | - | r1, r2, errno := syscall.Syscall15(fn, 15, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) | 15 | + | r1, r2, errno := syscall.SyscallN(fn, args...) |
| 16 | return r1, r2, uintptr(errno) | 16 | return r1, r2, uintptr(errno) | ||
| 17 | } | 17 | } | ||
| 18 | 18 | ||||
M testdata/abitest/abi_test.c +38 -0
| @@ -129,3 +129,41 @@ void stack_25_int64_exceeds(char *buf, size_t bufsize, int64_t a1, int64_t a2, i | |||
| 129 | 129 | snprintf(buf, bufsize, "%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64, | |
| 130 | 130 | a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25); | |
| 131 | 131 | } | |
| 132 | + | ||
| 133 | + | uintptr_t stack_20_uintptr( | |
| 134 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, | |
| 135 | + | uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9, uintptr_t a10, | |
| 136 | + | uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, | |
| 137 | + | uintptr_t a16, uintptr_t a17, uintptr_t a18, uintptr_t a19, uintptr_t a20 | |
| 138 | + | ) { | |
| 139 | + | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + | |
| 140 | + | a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20; | |
| 141 | + | } | |
| 142 | + | ||
| 143 | + | uintptr_t stack_32_uintptr( | |
| 144 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, | |
| 145 | + | uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, | |
| 146 | + | uintptr_t a17, uintptr_t a18, uintptr_t a19, uintptr_t a20, uintptr_t a21, uintptr_t a22, uintptr_t a23, uintptr_t a24, | |
| 147 | + | uintptr_t a25, uintptr_t a26, uintptr_t a27, uintptr_t a28, uintptr_t a29, uintptr_t a30, uintptr_t a31, uintptr_t a32 | |
| 148 | + | ) { | |
| 149 | + | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + | |
| 150 | + | a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + | |
| 151 | + | a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24 + | |
| 152 | + | a25 + a26 + a27 + a28 + a29 + a30 + a31 + a32; | |
| 153 | + | } | |
| 154 | + | ||
| 155 | + | double stack_32_mixed_int_float( | |
| 156 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, | |
| 157 | + | uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, | |
| 158 | + | double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, | |
| 159 | + | double f9, double f10, double f11, double f12, double f13, double f14, double f15, double f16 | |
| 160 | + | ) { | |
| 161 | + | return (double)a1 * 1 + (double)a2 * 2 + (double)a3 * 3 + (double)a4 * 4 + | |
| 162 | + | (double)a5 * 5 + (double)a6 * 6 + (double)a7 * 7 + (double)a8 * 8 + | |
| 163 | + | (double)a9 * 9 + (double)a10 * 10 + (double)a11 * 11 + (double)a12 * 12 + | |
| 164 | + | (double)a13 * 13 + (double)a14 * 14 + (double)a15 * 15 + (double)a16 * 16 + | |
| 165 | + | f1 * 17 + f2 * 18 + f3 * 19 + f4 * 20 + | |
| 166 | + | f5 * 21 + f6 * 22 + f7 * 23 + f8 * 24 + | |
| 167 | + | f9 * 25 + f10 * 26 + f11 * 27 + f12 * 28 + | |
| 168 | + | f13 * 29 + f14 * 30 + f15 * 31 + f16 * 32; | |
| 169 | + | } | |
| @@ -129,3 +129,41 @@ void stack_25_int64_exceeds(char *buf, size_t bufsize, int64_t a1, int64_t a2, i | |||||
| 129 | snprintf(buf, bufsize, "%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64, | 129 | snprintf(buf, bufsize, "%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64 ":%" PRId64, | ||
| 130 | a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25); | 130 | a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25); | ||
| 131 | } | 131 | } | ||
| 132 | + | ||||
| 133 | + | uintptr_t stack_20_uintptr( | |||
| 134 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, | |||
| 135 | + | uintptr_t a6, uintptr_t a7, uintptr_t a8, uintptr_t a9, uintptr_t a10, | |||
| 136 | + | uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, | |||
| 137 | + | uintptr_t a16, uintptr_t a17, uintptr_t a18, uintptr_t a19, uintptr_t a20 | |||
| 138 | + | ) { | |||
| 139 | + | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9 + a10 + | |||
| 140 | + | a11 + a12 + a13 + a14 + a15 + a16 + a17 + a18 + a19 + a20; | |||
| 141 | + | } | |||
| 142 | + | ||||
| 143 | + | uintptr_t stack_32_uintptr( | |||
| 144 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, | |||
| 145 | + | uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, | |||
| 146 | + | uintptr_t a17, uintptr_t a18, uintptr_t a19, uintptr_t a20, uintptr_t a21, uintptr_t a22, uintptr_t a23, uintptr_t a24, | |||
| 147 | + | uintptr_t a25, uintptr_t a26, uintptr_t a27, uintptr_t a28, uintptr_t a29, uintptr_t a30, uintptr_t a31, uintptr_t a32 | |||
| 148 | + | ) { | |||
| 149 | + | return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + | |||
| 150 | + | a9 + a10 + a11 + a12 + a13 + a14 + a15 + a16 + | |||
| 151 | + | a17 + a18 + a19 + a20 + a21 + a22 + a23 + a24 + | |||
| 152 | + | a25 + a26 + a27 + a28 + a29 + a30 + a31 + a32; | |||
| 153 | + | } | |||
| 154 | + | ||||
| 155 | + | double stack_32_mixed_int_float( | |||
| 156 | + | uintptr_t a1, uintptr_t a2, uintptr_t a3, uintptr_t a4, uintptr_t a5, uintptr_t a6, uintptr_t a7, uintptr_t a8, | |||
| 157 | + | uintptr_t a9, uintptr_t a10, uintptr_t a11, uintptr_t a12, uintptr_t a13, uintptr_t a14, uintptr_t a15, uintptr_t a16, | |||
| 158 | + | double f1, double f2, double f3, double f4, double f5, double f6, double f7, double f8, | |||
| 159 | + | double f9, double f10, double f11, double f12, double f13, double f14, double f15, double f16 | |||
| 160 | + | ) { | |||
| 161 | + | return (double)a1 * 1 + (double)a2 * 2 + (double)a3 * 3 + (double)a4 * 4 + | |||
| 162 | + | (double)a5 * 5 + (double)a6 * 6 + (double)a7 * 7 + (double)a8 * 8 + | |||
| 163 | + | (double)a9 * 9 + (double)a10 * 10 + (double)a11 * 11 + (double)a12 * 12 + | |||
| 164 | + | (double)a13 * 13 + (double)a14 * 14 + (double)a15 * 15 + (double)a16 * 16 + | |||
| 165 | + | f1 * 17 + f2 * 18 + f3 * 19 + f4 * 20 + | |||
| 166 | + | f5 * 21 + f6 * 22 + f7 * 23 + f8 * 24 + | |||
| 167 | + | f9 * 25 + f10 * 26 + f11 * 27 + f12 * 28 + | |||
| 168 | + | f13 * 29 + f14 * 30 + f15 * 31 + f16 * 32; | |||
| 169 | + | } | |||