github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/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 69 // Check if vector code should be used. If not aligned, then handle those 70 // first up to the aligned bytes. 71 72 if len(p) >= 4*vecMinLen { 73 if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { 74 align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) 75 newlen := vecMinLen - align 76 crc = ppc64SlicingUpdateBy8(crc, archIeeeTable8, p[:newlen]) 77 p = p[newlen:] 78 } 79 aligned := len(p) & ^vecAlignMask 80 crc = vectorCrc32(crc, crcIEEE, p[:aligned]) 81 p = p[aligned:] 82 } 83 if len(p) == 0 { 84 return crc 85 } 86 return ppc64SlicingUpdateBy8(crc, archIeeeTable8, p) 87 }