Initial QSfera import
This commit is contained in:
+88
@@ -0,0 +1,88 @@
|
||||
// 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)
|
||||
}
|
||||
Reference in New Issue
Block a user