// Copyright 2017 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package crc32 import ( "unsafe" ) const ( vecMinLen = 16 vecAlignMask = 15 // align to 16 bytes crcIEEE = 1 crcCast = 2 ) //go:noescape func ppc64SlicingUpdateBy8(crc uint32, table8 *slicing8Table, p []byte) uint32 // this function requires the buffer to be 16 byte aligned and > 16 bytes long //go:noescape func vectorCrc32(crc uint32, poly uint32, p []byte) uint32 var archCastagnoliTable8 *slicing8Table func archInitCastagnoli() { archCastagnoliTable8 = slicingMakeTable(Castagnoli) } func archUpdateCastagnoli(crc uint32, p []byte) uint32 { if len(p) >= 4*vecMinLen { // If not aligned then process the initial unaligned bytes if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) newlen := vecMinLen - align crc = ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p[:newlen]) p = p[newlen:] } // p should be aligned now aligned := len(p) & ^vecAlignMask crc = vectorCrc32(crc, crcCast, p[:aligned]) p = p[aligned:] } if len(p) == 0 { return crc } return ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p) } func archAvailableIEEE() bool { return true } func archAvailableCastagnoli() bool { return true } var archIeeeTable8 *slicing8Table func archInitIEEE() { // We still use slicing-by-8 for small buffers. archIeeeTable8 = slicingMakeTable(IEEE) } // archUpdateIEEE calculates the checksum of p using vectorizedIEEE. func archUpdateIEEE(crc uint32, p []byte) uint32 { // Check if vector code should be used. If not aligned, then handle those // first up to the aligned bytes. if len(p) >= 4*vecMinLen { if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) newlen := vecMinLen - align crc = ppc64SlicingUpdateBy8(crc, archIeeeTable8, p[:newlen]) p = p[newlen:] } aligned := len(p) & ^vecAlignMask crc = vectorCrc32(crc, crcIEEE, p[:aligned]) p = p[aligned:] } if len(p) == 0 { return crc } return ppc64SlicingUpdateBy8(crc, archIeeeTable8, p) }