github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/hash/crc32/crc32_s390x.go (about) 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 5 package crc32 6 7 const ( 8 vxMinLen = 64 9 vxAlignMask = 15 // align to 16 bytes 10 ) 11 12 // hasVectorFacility reports whether the machine has the z/Architecture 13 // vector facility installed and enabled. 14 func hasVectorFacility() bool 15 16 var hasVX = hasVectorFacility() 17 18 // vectorizedCastagnoli implements CRC32 using vector instructions. 19 // It is defined in crc32_s390x.s. 20 //go:noescape 21 func vectorizedCastagnoli(crc uint32, p []byte) uint32 22 23 // vectorizedIEEE implements CRC32 using vector instructions. 24 // It is defined in crc32_s390x.s. 25 //go:noescape 26 func vectorizedIEEE(crc uint32, p []byte) uint32 27 28 func genericCastagnoli(crc uint32, p []byte) uint32 { 29 // Use slicing-by-8 on larger inputs. 30 if len(p) >= sliceBy8Cutoff { 31 return updateSlicingBy8(crc, castagnoliTable8, p) 32 } 33 return update(crc, castagnoliTable, p) 34 } 35 36 func genericIEEE(crc uint32, p []byte) uint32 { 37 // Use slicing-by-8 on larger inputs. 38 if len(p) >= sliceBy8Cutoff { 39 ieeeTable8Once.Do(func() { 40 ieeeTable8 = makeTable8(IEEE) 41 }) 42 return updateSlicingBy8(crc, ieeeTable8, p) 43 } 44 return update(crc, IEEETable, p) 45 } 46 47 // updateCastagnoli calculates the checksum of p using 48 // vectorizedCastagnoli if possible and falling back onto 49 // genericCastagnoli as needed. 50 func updateCastagnoli(crc uint32, p []byte) uint32 { 51 // Use vectorized function if vector facility is available and 52 // data length is above threshold. 53 if hasVX && len(p) >= vxMinLen { 54 aligned := len(p) & ^vxAlignMask 55 crc = vectorizedCastagnoli(crc, p[:aligned]) 56 p = p[aligned:] 57 // process remaining data 58 if len(p) > 0 { 59 crc = genericCastagnoli(crc, p) 60 } 61 return crc 62 } 63 return genericCastagnoli(crc, p) 64 } 65 66 // updateIEEE calculates the checksum of p using vectorizedIEEE if 67 // possible and falling back onto genericIEEE as needed. 68 func updateIEEE(crc uint32, p []byte) uint32 { 69 // Use vectorized function if vector facility is available and 70 // data length is above threshold. 71 if hasVX && len(p) >= vxMinLen { 72 aligned := len(p) & ^vxAlignMask 73 crc = vectorizedIEEE(crc, p[:aligned]) 74 p = p[aligned:] 75 // process remaining data 76 if len(p) > 0 { 77 crc = genericIEEE(crc, p) 78 } 79 return crc 80 } 81 return genericIEEE(crc, p) 82 }