crc32_s390x.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build s390x
  5. package crc32
  6. const (
  7. vxMinLen = 64
  8. vxAlignMask = 15 // align to 16 bytes
  9. )
  10. // hasVectorFacility reports whether the machine has the z/Architecture
  11. // vector facility installed and enabled.
  12. func hasVectorFacility() bool
  13. var hasVX = hasVectorFacility()
  14. // vectorizedCastagnoli implements CRC32 using vector instructions.
  15. // It is defined in crc32_s390x.s.
  16. //go:noescape
  17. func vectorizedCastagnoli(crc uint32, p []byte) uint32
  18. // vectorizedIEEE implements CRC32 using vector instructions.
  19. // It is defined in crc32_s390x.s.
  20. //go:noescape
  21. func vectorizedIEEE(crc uint32, p []byte) uint32
  22. func archAvailableCastagnoli() bool {
  23. return hasVX
  24. }
  25. var archCastagnoliTable8 *slicing8Table
  26. func archInitCastagnoli() {
  27. if !hasVX {
  28. panic("not available")
  29. }
  30. // We still use slicing-by-8 for small buffers.
  31. archCastagnoliTable8 = slicingMakeTable(Castagnoli)
  32. }
  33. // archUpdateCastagnoli calculates the checksum of p using
  34. // vectorizedCastagnoli.
  35. func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
  36. if !hasVX {
  37. panic("not available")
  38. }
  39. // Use vectorized function if data length is above threshold.
  40. if len(p) >= vxMinLen {
  41. aligned := len(p) & ^vxAlignMask
  42. crc = vectorizedCastagnoli(crc, p[:aligned])
  43. p = p[aligned:]
  44. }
  45. if len(p) == 0 {
  46. return crc
  47. }
  48. return slicingUpdate(crc, archCastagnoliTable8, p)
  49. }
  50. func archAvailableIEEE() bool {
  51. return hasVX
  52. }
  53. var archIeeeTable8 *slicing8Table
  54. func archInitIEEE() {
  55. if !hasVX {
  56. panic("not available")
  57. }
  58. // We still use slicing-by-8 for small buffers.
  59. archIeeeTable8 = slicingMakeTable(IEEE)
  60. }
  61. // archUpdateIEEE calculates the checksum of p using vectorizedIEEE.
  62. func archUpdateIEEE(crc uint32, p []byte) uint32 {
  63. if !hasVX {
  64. panic("not available")
  65. }
  66. // Use vectorized function if data length is above threshold.
  67. if len(p) >= vxMinLen {
  68. aligned := len(p) & ^vxAlignMask
  69. crc = vectorizedIEEE(crc, p[:aligned])
  70. p = p[aligned:]
  71. }
  72. if len(p) == 0 {
  73. return crc
  74. }
  75. return slicingUpdate(crc, archIeeeTable8, p)
  76. }