crc32_ppc64le.mx raw
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 }
89