galois_amd64.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //+build !noasm
  2. //+build !appengine
  3. // Copyright 2015, Klaus Post, see LICENSE for details.
  4. package reedsolomon
  5. //go:noescape
  6. func galMulSSSE3(low, high, in, out []byte)
  7. //go:noescape
  8. func galMulSSSE3Xor(low, high, in, out []byte)
  9. //go:noescape
  10. func galMulAVX2Xor(low, high, in, out []byte)
  11. //go:noescape
  12. func galMulAVX2(low, high, in, out []byte)
  13. //go:noescape
  14. func sSE2XorSlice(in, out []byte)
  15. // This is what the assembler routines do in blocks of 16 bytes:
  16. /*
  17. func galMulSSSE3(low, high, in, out []byte) {
  18. for n, input := range in {
  19. l := input & 0xf
  20. h := input >> 4
  21. out[n] = low[l] ^ high[h]
  22. }
  23. }
  24. func galMulSSSE3Xor(low, high, in, out []byte) {
  25. for n, input := range in {
  26. l := input & 0xf
  27. h := input >> 4
  28. out[n] ^= low[l] ^ high[h]
  29. }
  30. }
  31. */
  32. func galMulSlice(c byte, in, out []byte, ssse3, avx2 bool) {
  33. var done int
  34. if avx2 {
  35. galMulAVX2(mulTableLow[c][:], mulTableHigh[c][:], in, out)
  36. done = (len(in) >> 5) << 5
  37. } else if ssse3 {
  38. galMulSSSE3(mulTableLow[c][:], mulTableHigh[c][:], in, out)
  39. done = (len(in) >> 4) << 4
  40. }
  41. remain := len(in) - done
  42. if remain > 0 {
  43. mt := mulTable[c]
  44. for i := done; i < len(in); i++ {
  45. out[i] = mt[in[i]]
  46. }
  47. }
  48. }
  49. func galMulSliceXor(c byte, in, out []byte, ssse3, avx2 bool) {
  50. var done int
  51. if avx2 {
  52. galMulAVX2Xor(mulTableLow[c][:], mulTableHigh[c][:], in, out)
  53. done = (len(in) >> 5) << 5
  54. } else if ssse3 {
  55. galMulSSSE3Xor(mulTableLow[c][:], mulTableHigh[c][:], in, out)
  56. done = (len(in) >> 4) << 4
  57. }
  58. remain := len(in) - done
  59. if remain > 0 {
  60. mt := mulTable[c]
  61. for i := done; i < len(in); i++ {
  62. out[i] ^= mt[in[i]]
  63. }
  64. }
  65. }
  66. // slice galois add
  67. func sliceXor(in, out []byte, sse2 bool) {
  68. var done int
  69. if sse2 {
  70. sSE2XorSlice(in, out)
  71. done = (len(in) >> 4) << 4
  72. }
  73. remain := len(in) - done
  74. if remain > 0 {
  75. for i := done; i < len(in); i++ {
  76. out[i] ^= in[i]
  77. }
  78. }
  79. }