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