github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/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 import "internal/cpu" 8 9 const ( 10 vxMinLen = 64 11 vxAlignMask = 15 // align to 16 bytes 12 ) 13 14 // hasVX reports whether the machine has the z/Architecture 15 // vector facility installed and enabled. 16 var hasVX = cpu.S390X.HasVX 17 18 // vectorizedCastagnoli implements CRC32 using vector instructions. 19 // It is defined in crc32_s390x.s. 20 // 21 //go:noescape 22 func vectorizedCastagnoli(crc uint32, p []byte) uint32 23 24 // vectorizedIEEE implements CRC32 using vector instructions. 25 // It is defined in crc32_s390x.s. 26 // 27 //go:noescape 28 func vectorizedIEEE(crc uint32, p []byte) uint32 29 30 func archAvailableCastagnoli() bool { 31 return hasVX 32 } 33 34 var archCastagnoliTable8 *slicing8Table 35 36 func archInitCastagnoli() { 37 if !hasVX { 38 panic("not available") 39 } 40 // We still use slicing-by-8 for small buffers. 41 archCastagnoliTable8 = slicingMakeTable(Castagnoli) 42 } 43 44 // archUpdateCastagnoli calculates the checksum of p using 45 // vectorizedCastagnoli. 46 func archUpdateCastagnoli(crc uint32, p []byte) uint32 { 47 if !hasVX { 48 panic("not available") 49 } 50 // Use vectorized function if data length is above threshold. 51 if len(p) >= vxMinLen { 52 aligned := len(p) & ^vxAlignMask 53 crc = vectorizedCastagnoli(crc, p[:aligned]) 54 p = p[aligned:] 55 } 56 if len(p) == 0 { 57 return crc 58 } 59 return slicingUpdate(crc, archCastagnoliTable8, p) 60 } 61 62 func archAvailableIEEE() bool { 63 return hasVX 64 } 65 66 var archIeeeTable8 *slicing8Table 67 68 func archInitIEEE() { 69 if !hasVX { 70 panic("not available") 71 } 72 // We still use slicing-by-8 for small buffers. 73 archIeeeTable8 = slicingMakeTable(IEEE) 74 } 75 76 // archUpdateIEEE calculates the checksum of p using vectorizedIEEE. 77 func archUpdateIEEE(crc uint32, p []byte) uint32 { 78 if !hasVX { 79 panic("not available") 80 } 81 // Use vectorized function if data length is above threshold. 82 if len(p) >= vxMinLen { 83 aligned := len(p) & ^vxAlignMask 84 crc = vectorizedIEEE(crc, p[:aligned]) 85 p = p[aligned:] 86 } 87 if len(p) == 0 { 88 return crc 89 } 90 return slicingUpdate(crc, archIeeeTable8, p) 91 }