galois_amd64.go 1.9 KB

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