dispatch.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package native
  2. import (
  3. "unsafe"
  4. `github.com/klauspost/cpuid/v2`
  5. "github.com/cloudwego/base64x/internal/rt"
  6. "github.com/cloudwego/base64x/internal/native/avx2"
  7. "github.com/cloudwego/base64x/internal/native/sse"
  8. )
  9. var (
  10. hasAVX2 = cpuid.CPU.Has(cpuid.AVX2)
  11. hasSSE = cpuid.CPU.Has(cpuid.SSE)
  12. )
  13. var (
  14. S_b64decode uintptr
  15. S_b64encode uintptr
  16. )
  17. var (
  18. F_b64decode func(out unsafe.Pointer, src unsafe.Pointer, len int, mod int) (ret int)
  19. F_b64encode func(out unsafe.Pointer, src unsafe.Pointer, mod int)
  20. )
  21. func useAVX2() {
  22. avx2.Use()
  23. S_b64decode = avx2.S_b64decode
  24. S_b64encode = avx2.S_b64encode
  25. F_b64decode = avx2.F_b64decode
  26. F_b64encode = avx2.F_b64encode
  27. }
  28. func useSSE() {
  29. sse.Use()
  30. S_b64decode = sse.S_b64decode
  31. S_b64encode = sse.S_b64encode
  32. F_b64decode = sse.F_b64decode
  33. F_b64encode = sse.F_b64encode
  34. }
  35. //go:nosplit
  36. func B64Decode(out *[]byte, src unsafe.Pointer, len int, mod int) (ret int) {
  37. return F_b64decode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), len, mod)
  38. }
  39. //go:nosplit
  40. func B64Encode(out *[]byte, src *[]byte, mod int) {
  41. F_b64encode(rt.NoEscape(unsafe.Pointer(out)), rt.NoEscape(unsafe.Pointer(src)), mod)
  42. }
  43. func init() {
  44. if hasAVX2 {
  45. useAVX2()
  46. } else if hasSSE {
  47. useSSE()
  48. } else {
  49. panic("Unsupported CPU, lacks of AVX2 or SSE CPUID Flag. maybe it's too old to run Sonic.")
  50. }
  51. }