chore: switch purego dependency to bnema/purego fork
Replace local path replace directive with GitHub URL pointing to bnema/purego@91aa177 to avoid accidental pushes to upstream.
- commit
- 8b029581aa8aebd90aa84a2b638058062afa9bdd
- author
- brice · · 2026-03-23 19:51 UTC
- parent
- f14f9b6
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
51 files · +1860 -488
M go.mod +2 -0
| @@ -3,3 +3,5 @@ module github.com/bnema/puregotk | |||
| 3 | 3 | go 1.26.1 | |
| 4 | 4 | ||
| 5 | 5 | require github.com/ebitengine/purego v0.10.0 | |
| 6 | + | ||
| 7 | + | replace github.com/ebitengine/purego => github.com/bnema/purego v0.0.0-20260323095903-91aa177a2704 | |
| @@ -3,3 +3,5 @@ module github.com/bnema/puregotk | |||||
| 3 | go 1.26.1 | 3 | go 1.26.1 | ||
| 4 | 4 | ||||
| 5 | require github.com/ebitengine/purego v0.10.0 | 5 | require github.com/ebitengine/purego v0.10.0 | ||
| 6 | + | ||||
| 7 | + | replace github.com/ebitengine/purego => github.com/bnema/purego v0.0.0-20260323095903-91aa177a2704 | |||
M go.sum +2 -2 generated file: collapsed
M vendor/github.com/ebitengine/purego/README.md +3 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/dlfcn_nocgo_netbsd.go +2 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/func.go +220 -107 generated file: collapsed
A vendor/github.com/ebitengine/purego/hostlayout_go123.go +12 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/hostlayout_nogo123.go +11 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/abi_riscv64.h +72 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/asm_riscv64.s +14 -55 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/go_freebsd.go +4 -25 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/go_linux.go +4 -25 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/go_netbsd.go +4 -25 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/libcgo_netbsd.go +2 -2 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/linux.go +184 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/netbsd.go +1 -1 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_386.s +18 -4 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_amd64.s +1 -1 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm.s +44 -3 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_arm64.s +1 -4 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_386.s +78 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_amd64.s +69 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_arm.s +69 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_arm64.s +60 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_loong64.s +60 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_ppc64le.s +69 -0 generated file: collapsed
A vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_linux_riscv64.s +60 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_loong64.s +1 -11 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_ppc64le.s +30 -129 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/trampolines_riscv64.s +11 -7 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/zsymbols_linux.go +110 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/internal/fakecgo/ztrampolines_linux.s +30 -0 generated file: collapsed
M vendor/github.com/ebitengine/purego/struct_386.go +12 -1 generated file: collapsed
M vendor/github.com/ebitengine/purego/struct_amd64.go +162 -0
| @@ -6,6 +6,7 @@ package purego | |||
| 6 | 6 | import ( | |
| 7 | 7 | "math" | |
| 8 | 8 | "reflect" | |
| 9 | + | "runtime" | |
| 9 | 10 | "unsafe" | |
| 10 | 11 | ) | |
| 11 | 12 | ||
| @@ -284,3 +285,164 @@ func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int | |||
| 284 | 285 | func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) { | |
| 285 | 286 | panic("purego: bundleStackArgs should not be called on amd64") | |
| 286 | 287 | } | |
| 288 | + | ||
| 289 | + | // getCallbackStruct reads a struct argument from the callback frame on amd64. | |
| 290 | + | // It mirrors the SysV AMD64 ABI rules used by addStruct for the Go→C path. | |
| 291 | + | // | |
| 292 | + | // getCallbackStruct is only used on Unix. On Windows, callbacks are handled by | |
| 293 | + | // the runtime's own callback mechanism, so this function is compiled but unused. | |
| 294 | + | // | |
| 295 | + | // SysV AMD64 struct argument passing rules: | |
| 296 | + | // - Struct > 16 bytes (postMerger): passed on the stack as raw bytes | |
| 297 | + | // - Struct ≤ 16 bytes: classify each eightbyte (INTEGER or SSE), | |
| 298 | + | // read from the appropriate register class | |
| 299 | + | // - If not enough registers for all eightbytes: entire struct goes on the stack | |
| 300 | + | func getCallbackStruct(inType reflect.Type, frame unsafe.Pointer, floatsN *int, intsN *int, stackSlot *int, stackByteOffset *uintptr) reflect.Value { | |
| 301 | + | switch runtime.GOOS { | |
| 302 | + | case "darwin", "freebsd", "linux", "netbsd": | |
| 303 | + | default: | |
| 304 | + | panic("purego: getCallbackStruct is not supported on " + runtime.GOOS) | |
| 305 | + | } | |
| 306 | + | ||
| 307 | + | f := (*[callbackMaxFrame]uintptr)(frame) | |
| 308 | + | size := inType.Size() | |
| 309 | + | ||
| 310 | + | // Structs > 16 bytes are passed on the stack as raw bytes (SysV ABI MEMORY class). | |
| 311 | + | if postMerger(inType) { | |
| 312 | + | numSlots := int((size + 7) / 8) | |
| 313 | + | v := reflect.NewAt(inType, unsafe.Pointer(&f[*stackSlot])).Elem() | |
| 314 | + | *stackSlot += numSlots | |
| 315 | + | return v | |
| 316 | + | } | |
| 317 | + | ||
| 318 | + | // Struct ≤ 16 bytes: classify each eightbyte and read from the appropriate register. | |
| 319 | + | numEightbytes := int((size + 7) / 8) | |
| 320 | + | ||
| 321 | + | // Count how many integer and SSE registers this struct needs. | |
| 322 | + | var needInts, needFloats int | |
| 323 | + | for i := 0; i < numEightbytes; i++ { | |
| 324 | + | class := classifyEightbyte(inType, uintptr(i)*8, uintptr(i)*8+8) | |
| 325 | + | if class == _SSE { | |
| 326 | + | needFloats++ | |
| 327 | + | } else { | |
| 328 | + | needInts++ | |
| 329 | + | } | |
| 330 | + | } | |
| 331 | + | ||
| 332 | + | // If not enough registers for all eightbytes, the entire struct goes on the stack. | |
| 333 | + | if *intsN+needInts > numOfIntegerRegisters() || *floatsN+needFloats > numOfFloatRegisters() { | |
| 334 | + | v := reflect.NewAt(inType, unsafe.Pointer(&f[*stackSlot])).Elem() | |
| 335 | + | *stackSlot += numEightbytes | |
| 336 | + | return v | |
| 337 | + | } | |
| 338 | + | ||
| 339 | + | // Read each eightbyte from its appropriate register class. | |
| 340 | + | var r1, r2 uintptr | |
| 341 | + | for i := 0; i < numEightbytes; i++ { | |
| 342 | + | class := classifyEightbyte(inType, uintptr(i)*8, uintptr(i)*8+8) | |
| 343 | + | if class == _SSE { | |
| 344 | + | if i == 0 { | |
| 345 | + | r1 = f[*floatsN] | |
| 346 | + | } else { | |
| 347 | + | r2 = f[*floatsN] | |
| 348 | + | } | |
| 349 | + | *floatsN++ | |
| 350 | + | } else { | |
| 351 | + | if i == 0 { | |
| 352 | + | r1 = f[numOfFloatRegisters()+*intsN] | |
| 353 | + | } else { | |
| 354 | + | r2 = f[numOfFloatRegisters()+*intsN] | |
| 355 | + | } | |
| 356 | + | *intsN++ | |
| 357 | + | } | |
| 358 | + | } | |
| 359 | + | ||
| 360 | + | if numEightbytes == 1 { | |
| 361 | + | return reflect.NewAt(inType, unsafe.Pointer(&struct{ a uintptr }{r1})).Elem() | |
| 362 | + | } | |
| 363 | + | return reflect.NewAt(inType, unsafe.Pointer(&struct{ a, b uintptr }{r1, r2})).Elem() | |
| 364 | + | } | |
| 365 | + | ||
| 366 | + | func setStruct(a *callbackArgs, ret reflect.Value) { | |
| 367 | + | outSize := ret.Type().Size() | |
| 368 | + | switch { | |
| 369 | + | case outSize == 0: | |
| 370 | + | return | |
| 371 | + | case outSize <= 16: | |
| 372 | + | // Copy the struct's raw bytes (including padding) into a buffer. | |
| 373 | + | var buf [2]uintptr | |
| 374 | + | reflect.NewAt(ret.Type(), unsafe.Pointer(&buf[0])).Elem().Set(ret) | |
| 375 | + | // Classify each eightbyte by the SysV ABI rules (§3.2.3, rule 4d | |
| 376 | + | // of https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf). | |
| 377 | + | // INTEGER wins over SSE for mixed eightbytes. Place INTEGER eightbytes in | |
| 378 | + | // result[0]/result[1] (AX/DX) and SSE eightbytes in result[2]/result[3] | |
| 379 | + | // (XMM0/XMM1). | |
| 380 | + | // Assign each eightbyte to the next available register of the | |
| 381 | + | // appropriate class. The ABI counts integer (AX, DX) and SSE | |
| 382 | + | // (XMM0, XMM1) return registers independently. | |
| 383 | + | var numInts int | |
| 384 | + | var numFloats int | |
| 385 | + | for i := 0; i < 2 && uintptr(i)*8 < outSize; i++ { | |
| 386 | + | class := classifyEightbyte(ret.Type(), uintptr(i)*8, uintptr(i)*8+8) | |
| 387 | + | if class == _SSE { | |
| 388 | + | switch numFloats { | |
| 389 | + | case 0: | |
| 390 | + | a.result[2] = buf[i] | |
| 391 | + | case 1: | |
| 392 | + | a.result[3] = buf[i] | |
| 393 | + | } | |
| 394 | + | numFloats++ | |
| 395 | + | } else { | |
| 396 | + | switch numInts { | |
| 397 | + | case 0: | |
| 398 | + | a.result[0] = buf[i] | |
| 399 | + | case 1: | |
| 400 | + | a.result[1] = buf[i] | |
| 401 | + | } | |
| 402 | + | numInts++ | |
| 403 | + | } | |
| 404 | + | } | |
| 405 | + | default: | |
| 406 | + | // Structs > 16 bytes are returned by hidden pointer. | |
| 407 | + | // a.result[0] contains the pointer passed by the caller in RDI. | |
| 408 | + | // Write the struct through this pointer. | |
| 409 | + | reflect.NewAt(ret.Type(), *(*unsafe.Pointer)(unsafe.Pointer(&a.result[0]))).Elem().Set(ret) | |
| 410 | + | } | |
| 411 | + | } | |
| 412 | + | ||
| 413 | + | // classifyEightbyte returns the SysV ABI class for the byte range [start, end) | |
| 414 | + | // within a type, by examining all scalar fields that overlap that range. | |
| 415 | + | func classifyEightbyte(t reflect.Type, start, end uintptr) int { | |
| 416 | + | return doClassifyEightbyte(t, 0, start, end) | |
| 417 | + | } | |
| 418 | + | ||
| 419 | + | func doClassifyEightbyte(t reflect.Type, base, start, end uintptr) int { | |
| 420 | + | switch t.Kind() { | |
| 421 | + | case reflect.Struct: | |
| 422 | + | class := _NO_CLASS | |
| 423 | + | for i := 0; i < t.NumField(); i++ { | |
| 424 | + | f := t.Field(i) | |
| 425 | + | class |= doClassifyEightbyte(f.Type, base+f.Offset, start, end) | |
| 426 | + | } | |
| 427 | + | return class | |
| 428 | + | case reflect.Array: | |
| 429 | + | class := _NO_CLASS | |
| 430 | + | elemSize := t.Elem().Size() | |
| 431 | + | for i := 0; i < t.Len(); i++ { | |
| 432 | + | class |= doClassifyEightbyte(t.Elem(), base+uintptr(i)*elemSize, start, end) | |
| 433 | + | } | |
| 434 | + | return class | |
| 435 | + | default: | |
| 436 | + | fStart := base | |
| 437 | + | fEnd := base + t.Size() | |
| 438 | + | if fStart >= end || fEnd <= start { | |
| 439 | + | return _NO_CLASS | |
| 440 | + | } | |
| 441 | + | switch t.Kind() { | |
| 442 | + | case reflect.Float32, reflect.Float64: | |
| 443 | + | return _SSE | |
| 444 | + | default: | |
| 445 | + | return _INTEGER | |
| 446 | + | } | |
| 447 | + | } | |
| 448 | + | } | |
| @@ -6,6 +6,7 @@ package purego | |||||
| 6 | import ( | 6 | import ( | ||
| 7 | "math" | 7 | "math" | ||
| 8 | "reflect" | 8 | "reflect" | ||
| 9 | + | "runtime" | |||
| 9 | "unsafe" | 10 | "unsafe" | ||
| 10 | ) | 11 | ) | ||
| 11 | 12 | ||||
| @@ -284,3 +285,164 @@ func collectStackArgs(args []reflect.Value, startIdx int, numInts, numFloats int | |||||
| 284 | func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) { | 285 | func bundleStackArgs(stackArgs []reflect.Value, addStack func(uintptr)) { | ||
| 285 | panic("purego: bundleStackArgs should not be called on amd64") | 286 | panic("purego: bundleStackArgs should not be called on amd64") | ||
| 286 | } | 287 | } | ||
| 288 | + | ||||
| 289 | + | // getCallbackStruct reads a struct argument from the callback frame on amd64. | |||
| 290 | + | // It mirrors the SysV AMD64 ABI rules used by addStruct for the Go→C path. | |||
| 291 | + | // | |||
| 292 | + | // getCallbackStruct is only used on Unix. On Windows, callbacks are handled by | |||
| 293 | + | // the runtime's own callback mechanism, so this function is compiled but unused. | |||
| 294 | + | // | |||
| 295 | + | // SysV AMD64 struct argument passing rules: | |||
| 296 | + | // - Struct > 16 bytes (postMerger): passed on the stack as raw bytes | |||
| 297 | + | // - Struct ≤ 16 bytes: classify each eightbyte (INTEGER or SSE), | |||
| 298 | + | // read from the appropriate register class | |||
| 299 | + | // - If not enough registers for all eightbytes: entire struct goes on the stack | |||
| 300 | + | func getCallbackStruct(inType reflect.Type, frame unsafe.Pointer, floatsN *int, intsN *int, stackSlot *int, stackByteOffset *uintptr) reflect.Value { | |||
| 301 | + | switch runtime.GOOS { | |||
| 302 | + | case "darwin", "freebsd", "linux", "netbsd": | |||
| 303 | + | default: | |||
| 304 | + | panic("purego: getCallbackStruct is not supported on " + runtime.GOOS) | |||
| 305 | + | } | |||
| 306 | + | ||||
| 307 | + | f := (*[callbackMaxFrame]uintptr)(frame) | |||
| 308 | + | size := inType.Size() | |||
| 309 | + | ||||
| 310 | + | // Structs > 16 bytes are passed on the stack as raw bytes (SysV ABI MEMORY class). | |||
| 311 | + | if postMerger(inType) { | |||
| 312 | + | numSlots := int((size + 7) / 8) | |||
| 313 | + | v := reflect.NewAt(inType, unsafe.Pointer(&f[*stackSlot])).Elem() | |||
| 314 | + | *stackSlot += numSlots | |||
| 315 | + | return v | |||
| 316 | + | } | |||
| 317 | + | ||||
| 318 | + | // Struct ≤ 16 bytes: classify each eightbyte and read from the appropriate register. | |||
| 319 | + | numEightbytes := int((size + 7) / 8) | |||
| 320 | + | ||||
| 321 | + | // Count how many integer and SSE registers this struct needs. | |||
| 322 | + | var needInts, needFloats int | |||
| 323 | + | for i := 0; i < numEightbytes; i++ { | |||
| 324 | + | class := classifyEightbyte(inType, uintptr(i)*8, uintptr(i)*8+8) | |||
| 325 | + | if class == _SSE { | |||
| 326 | + | needFloats++ | |||
| 327 | + | } else { | |||
| 328 | + | needInts++ | |||
| 329 | + | } | |||
| 330 | + | } | |||
| 331 | + | ||||
| 332 | + | // If not enough registers for all eightbytes, the entire struct goes on the stack. | |||
| 333 | + | if *intsN+needInts > numOfIntegerRegisters() || *floatsN+needFloats > numOfFloatRegisters() { | |||
| 334 | + | v := reflect.NewAt(inType, unsafe.Pointer(&f[*stackSlot])).Elem() | |||
| 335 | + | *stackSlot += numEightbytes | |||
| 336 | + | return v | |||
| 337 | + | } | |||
| 338 | + | ||||
| 339 | + | // Read each eightbyte from its appropriate register class. | |||
| 340 | + | var r1, r2 uintptr | |||
| 341 | + | for i := 0; i < numEightbytes; i++ { | |||
| 342 | + | class := classifyEightbyte(inType, uintptr(i)*8, uintptr(i)*8+8) | |||
| 343 | + | if class == _SSE { | |||
| 344 | + | if i == 0 { | |||
| 345 | + | r1 = f[*floatsN] | |||
| 346 | + | } else { | |||
| 347 | + | r2 = f[*floatsN] | |||
| 348 | + | } | |||
| 349 | + | *floatsN++ | |||
| 350 | + | } else { | |||
| 351 | + | if i == 0 { | |||
| 352 | + | r1 = f[numOfFloatRegisters()+*intsN] | |||
| 353 | + | } else { | |||
| 354 | + | r2 = f[numOfFloatRegisters()+*intsN] | |||
| 355 | + | } | |||
| 356 | + | *intsN++ | |||
| 357 | + | } | |||
| 358 | + | } | |||
| 359 | + | ||||
| 360 | + | if numEightbytes == 1 { | |||
| 361 | + | return reflect.NewAt(inType, unsafe.Pointer(&struct{ a uintptr }{r1})).Elem() | |||
| 362 | + | } | |||
| 363 | + | return reflect.NewAt(inType, unsafe.Pointer(&struct{ a, b uintptr }{r1, r2})).Elem() | |||
| 364 | + | } | |||
| 365 | + | ||||
| 366 | + | func setStruct(a *callbackArgs, ret reflect.Value) { | |||
| 367 | + | outSize := ret.Type().Size() | |||
| 368 | + | switch { | |||
| 369 | + | case outSize == 0: | |||
| 370 | + | return | |||
| 371 | + | case outSize <= 16: | |||
| 372 | + | // Copy the struct's raw bytes (including padding) into a buffer. | |||
| 373 | + | var buf [2]uintptr | |||
| 374 | + | reflect.NewAt(ret.Type(), unsafe.Pointer(&buf[0])).Elem().Set(ret) | |||
| 375 | + | // Classify each eightbyte by the SysV ABI rules (§3.2.3, rule 4d | |||
| 376 | + | // of https://refspecs.linuxbase.org/elf/x86_64-abi-0.99.pdf). | |||
| 377 | + | // INTEGER wins over SSE for mixed eightbytes. Place INTEGER eightbytes in | |||
| 378 | + | // result[0]/result[1] (AX/DX) and SSE eightbytes in result[2]/result[3] | |||
| 379 | + | // (XMM0/XMM1). | |||
| 380 | + | // Assign each eightbyte to the next available register of the | |||
| 381 | + | // appropriate class. The ABI counts integer (AX, DX) and SSE | |||
| 382 | + | // (XMM0, XMM1) return registers independently. | |||
| 383 | + | var numInts int | |||
| 384 | + | var numFloats int | |||
| 385 | + | for i := 0; i < 2 && uintptr(i)*8 < outSize; i++ { | |||
| 386 | + | class := classifyEightbyte(ret.Type(), uintptr(i)*8, uintptr(i)*8+8) | |||
| 387 | + | if class == _SSE { | |||
| 388 | + | switch numFloats { | |||
| 389 | + | case 0: | |||
| 390 | + | a.result[2] = buf[i] | |||
| 391 | + | case 1: | |||
| 392 | + | a.result[3] = buf[i] | |||
| 393 | + | } | |||
| 394 | + | numFloats++ | |||
| 395 | + | } else { | |||
| 396 | + | switch numInts { | |||
| 397 | + | case 0: | |||
| 398 | + | a.result[0] = buf[i] | |||
| 399 | + | case 1: | |||
| 400 | + | a.result[1] = buf[i] | |||
| 401 | + | } | |||
| 402 | + | numInts++ | |||
| 403 | + | } | |||
| 404 | + | } | |||
| 405 | + | default: | |||
| 406 | + | // Structs > 16 bytes are returned by hidden pointer. | |||
| 407 | + | // a.result[0] contains the pointer passed by the caller in RDI. | |||
| 408 | + | // Write the struct through this pointer. | |||
| 409 | + | reflect.NewAt(ret.Type(), *(*unsafe.Pointer)(unsafe.Pointer(&a.result[0]))).Elem().Set(ret) | |||
| 410 | + | } | |||
| 411 | + | } | |||
| 412 | + | ||||
| 413 | + | // classifyEightbyte returns the SysV ABI class for the byte range [start, end) | |||
| 414 | + | // within a type, by examining all scalar fields that overlap that range. | |||
| 415 | + | func classifyEightbyte(t reflect.Type, start, end uintptr) int { | |||
| 416 | + | return doClassifyEightbyte(t, 0, start, end) | |||
| 417 | + | } | |||
| 418 | + | ||||
| 419 | + | func doClassifyEightbyte(t reflect.Type, base, start, end uintptr) int { | |||
| 420 | + | switch t.Kind() { | |||
| 421 | + | case reflect.Struct: | |||
| 422 | + | class := _NO_CLASS | |||
| 423 | + | for i := 0; i < t.NumField(); i++ { | |||
| 424 | + | f := t.Field(i) | |||
| 425 | + | class |= doClassifyEightbyte(f.Type, base+f.Offset, start, end) | |||
| 426 | + | } | |||
| 427 | + | return class | |||
| 428 | + | case reflect.Array: | |||
| 429 | + | class := _NO_CLASS | |||
| 430 | + | elemSize := t.Elem().Size() | |||
| 431 | + | for i := 0; i < t.Len(); i++ { | |||
| 432 | + | class |= doClassifyEightbyte(t.Elem(), base+uintptr(i)*elemSize, start, end) | |||
| 433 | + | } | |||
| 434 | + | return class | |||
| 435 | + | default: | |||
| 436 | + | fStart := base | |||
| 437 | + | fEnd := base + t.Size() | |||
| 438 | + | if fStart >= end || fEnd <= start { | |||
| 439 | + | return _NO_CLASS | |||
| 440 | + | } | |||
| 441 | + | switch t.Kind() { | |||
| 442 | + | case reflect.Float32, reflect.Float64: | |||
| 443 | + | return _SSE | |||
| 444 | + | default: | |||
| 445 | + | return _INTEGER | |||
| 446 | + | } | |||
| 447 | + | } | |||
| 448 | + | } | |||