github.com/ice-blockchain/go/src@v0.0.0-20240403114104-1564d284e521/hash/crc32/crc32_ppc64le.go (about) 1 // Copyright 2017 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 ( 8 "unsafe" 9 ) 10 11 const ( 12 vecMinLen = 16 13 vecAlignMask = 15 // align to 16 bytes 14 crcIEEE = 1 15 crcCast = 2 16 ) 17 18 //go:noescape 19 func ppc64SlicingUpdateBy8(crc uint32, table8 *slicing8Table, p []byte) uint32 20 21 // this function requires the buffer to be 16 byte aligned and > 16 bytes long. 22 // 23 //go:noescape 24 func vectorCrc32(crc uint32, poly uint32, p []byte) uint32 25 26 var archCastagnoliTable8 *slicing8Table 27 28 func archInitCastagnoli() { 29 archCastagnoliTable8 = slicingMakeTable(Castagnoli) 30 } 31 32 func archUpdateCastagnoli(crc uint32, p []byte) uint32 { 33 if len(p) >= 4*vecMinLen { 34 // If not aligned then process the initial unaligned bytes 35 36 if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { 37 align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) 38 newlen := vecMinLen - align 39 crc = ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p[:newlen]) 40 p = p[newlen:] 41 } 42 // p should be aligned now 43 aligned := len(p) & ^vecAlignMask 44 crc = vectorCrc32(crc, crcCast, p[:aligned]) 45 p = p[aligned:] 46 } 47 if len(p) == 0 { 48 return crc 49 } 50 return ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p) 51 } 52 53 func archAvailableIEEE() bool { 54 return true 55 } 56 func archAvailableCastagnoli() bool { 57 return true 58 } 59 60 var archIeeeTable8 *slicing8Table 61 62 func archInitIEEE() { 63 // We still use slicing-by-8 for small buffers. 64 archIeeeTable8 = slicingMakeTable(IEEE) 65 } 66 67 // archUpdateIEEE calculates the checksum of p using vectorizedIEEE. 68 func archUpdateIEEE(crc uint32, p []byte) uint32 { 69 70 // Check if vector code should be used. If not aligned, then handle those 71 // first up to the aligned bytes. 72 73 if len(p) >= 4*vecMinLen { 74 if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { 75 align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) 76 newlen := vecMinLen - align 77 crc = ppc64SlicingUpdateBy8(crc, archIeeeTable8, p[:newlen]) 78 p = p[newlen:] 79 } 80 aligned := len(p) & ^vecAlignMask 81 crc = vectorCrc32(crc, crcIEEE, p[:aligned]) 82 p = p[aligned:] 83 } 84 if len(p) == 0 { 85 return crc 86 } 87 return ppc64SlicingUpdateBy8(crc, archIeeeTable8, p) 88 }