github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 // +build ignore 6 7 package crc32 8 9 import ( 10 "unsafe" 11 ) 12 13 const ( 14 vecMinLen = 16 15 vecAlignMask = 15 // align to 16 bytes 16 crcIEEE = 1 17 crcCast = 2 18 ) 19 20 //go:noescape 21 func ppc64SlicingUpdateBy8(crc uint32, table8 *slicing8Table, p []byte) uint32 22 23 // this function requires the buffer to be 16 byte aligned and > 16 bytes long 24 //go:noescape 25 func vectorCrc32(crc uint32, poly uint32, p []byte) uint32 26 27 var archCastagnoliTable8 *slicing8Table 28 29 func archInitCastagnoli() { 30 archCastagnoliTable8 = slicingMakeTable(Castagnoli) 31 } 32 33 func archUpdateCastagnoli(crc uint32, p []byte) uint32 { 34 if len(p) >= 4*vecMinLen { 35 // If not aligned then process the initial unaligned bytes 36 37 if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { 38 align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) 39 newlen := vecMinLen - align 40 crc = ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p[:newlen]) 41 p = p[newlen:] 42 } 43 // p should be aligned now 44 aligned := len(p) & ^vecAlignMask 45 crc = vectorCrc32(crc, crcCast, p[:aligned]) 46 p = p[aligned:] 47 } 48 if len(p) == 0 { 49 return crc 50 } 51 return ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p) 52 } 53 54 func archAvailableIEEE() bool { 55 return true 56 } 57 func archAvailableCastagnoli() bool { 58 return true 59 } 60 61 var archIeeeTable8 *slicing8Table 62 63 func archInitIEEE() { 64 // We still use slicing-by-8 for small buffers. 65 archIeeeTable8 = slicingMakeTable(IEEE) 66 } 67 68 // archUpdateIEEE calculates the checksum of p using vectorizedIEEE. 69 func archUpdateIEEE(crc uint32, p []byte) uint32 { 70 71 // Check if vector code should be used. If not aligned, then handle those 72 // first up to the aligned bytes. 73 74 if len(p) >= 4*vecMinLen { 75 if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 { 76 align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask) 77 newlen := vecMinLen - align 78 crc = ppc64SlicingUpdateBy8(crc, archIeeeTable8, p[:newlen]) 79 p = p[newlen:] 80 } 81 aligned := len(p) & ^vecAlignMask 82 crc = vectorCrc32(crc, crcIEEE, p[:aligned]) 83 p = p[aligned:] 84 } 85 if len(p) == 0 { 86 return crc 87 } 88 return ppc64SlicingUpdateBy8(crc, archIeeeTable8, p) 89 }