xor_amd64.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package xor
  2. import "github.com/templexxx/cpufeat"
  3. func init() {
  4. getEXT()
  5. }
  6. func getEXT() {
  7. if cpufeat.X86.HasAVX2 {
  8. extension = avx2
  9. } else {
  10. extension = sse2
  11. }
  12. return
  13. }
  14. func xorBytes(dst, src0, src1 []byte, size int) {
  15. switch extension {
  16. case avx2:
  17. bytesAVX2(dst, src0, src1, size)
  18. default:
  19. bytesSSE2(dst, src0, src1, size)
  20. }
  21. }
  22. // non-temporal hint store
  23. const nontmp = 8 * 1024
  24. const avx2loopsize = 128
  25. func bytesAVX2(dst, src0, src1 []byte, size int) {
  26. if size < avx2loopsize {
  27. bytesAVX2mini(dst, src0, src1, size)
  28. } else if size >= avx2loopsize && size <= nontmp {
  29. bytesAVX2small(dst, src0, src1, size)
  30. } else {
  31. bytesAVX2big(dst, src0, src1, size)
  32. }
  33. }
  34. const sse2loopsize = 64
  35. func bytesSSE2(dst, src0, src1 []byte, size int) {
  36. if size < sse2loopsize {
  37. bytesSSE2mini(dst, src0, src1, size)
  38. } else if size >= sse2loopsize && size <= nontmp {
  39. bytesSSE2small(dst, src0, src1, size)
  40. } else {
  41. bytesSSE2big(dst, src0, src1, size)
  42. }
  43. }
  44. func xorMatrix(dst []byte, src [][]byte) {
  45. switch extension {
  46. case avx2:
  47. matrixAVX2(dst, src)
  48. default:
  49. matrixSSE2(dst, src)
  50. }
  51. }
  52. func matrixAVX2(dst []byte, src [][]byte) {
  53. size := len(dst)
  54. if size > nontmp {
  55. matrixAVX2big(dst, src)
  56. } else {
  57. matrixAVX2small(dst, src)
  58. }
  59. }
  60. func matrixSSE2(dst []byte, src [][]byte) {
  61. size := len(dst)
  62. if size > nontmp {
  63. matrixSSE2big(dst, src)
  64. } else {
  65. matrixSSE2small(dst, src)
  66. }
  67. }
  68. //go:noescape
  69. func xorSrc0(dst, src0, src1 []byte)
  70. //go:noescape
  71. func xorSrc1(dst, src0, src1 []byte)
  72. //go:noescape
  73. func bytesAVX2mini(dst, src0, src1 []byte, size int)
  74. //go:noescape
  75. func bytesAVX2big(dst, src0, src1 []byte, size int)
  76. //go:noescape
  77. func bytesAVX2small(dst, src0, src1 []byte, size int)
  78. //go:noescape
  79. func bytesSSE2mini(dst, src0, src1 []byte, size int)
  80. //go:noescape
  81. func bytesSSE2small(dst, src0, src1 []byte, size int)
  82. //go:noescape
  83. func bytesSSE2big(dst, src0, src1 []byte, size int)
  84. //go:noescape
  85. func matrixAVX2small(dst []byte, src [][]byte)
  86. //go:noescape
  87. func matrixAVX2big(dst []byte, src [][]byte)
  88. //go:noescape
  89. func matrixSSE2small(dst []byte, src [][]byte)
  90. //go:noescape
  91. func matrixSSE2big(dst []byte, src [][]byte)
  92. //go:noescape
  93. func hasAVX2() bool
  94. //go:noescape
  95. func hasSSE2() bool