1// Copyright 2016 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 5package crc32 6 7import "internal/cpu" 8 9const ( 10 vxMinLen = 64 11 vxAlignMask = 15 // align to 16 bytes 12) 13 14// hasVX reports whether the machine has the z/Architecture 15// vector facility installed and enabled. 16var hasVX = cpu.S390X.HasVX 17 18// vectorizedCastagnoli implements CRC32 using vector instructions. 19// It is defined in crc32_s390x.s. 20// 21//go:noescape 22func vectorizedCastagnoli(crc uint32, p []byte) uint32 23 24// vectorizedIEEE implements CRC32 using vector instructions. 25// It is defined in crc32_s390x.s. 26// 27//go:noescape 28func vectorizedIEEE(crc uint32, p []byte) uint32 29 30func archAvailableCastagnoli() bool { 31 return hasVX 32} 33 34var archCastagnoliTable8 *slicing8Table 35 36func archInitCastagnoli() { 37 if !hasVX { 38 panic("not available") 39 } 40 // We still use slicing-by-8 for small buffers. 41 archCastagnoliTable8 = slicingMakeTable(Castagnoli) 42} 43 44// archUpdateCastagnoli calculates the checksum of p using 45// vectorizedCastagnoli. 46func archUpdateCastagnoli(crc uint32, p []byte) uint32 { 47 if !hasVX { 48 panic("not available") 49 } 50 // Use vectorized function if data length is above threshold. 51 if len(p) >= vxMinLen { 52 aligned := len(p) & ^vxAlignMask 53 crc = vectorizedCastagnoli(crc, p[:aligned]) 54 p = p[aligned:] 55 } 56 if len(p) == 0 { 57 return crc 58 } 59 return slicingUpdate(crc, archCastagnoliTable8, p) 60} 61 62func archAvailableIEEE() bool { 63 return hasVX 64} 65 66var archIeeeTable8 *slicing8Table 67 68func archInitIEEE() { 69 if !hasVX { 70 panic("not available") 71 } 72 // We still use slicing-by-8 for small buffers. 73 archIeeeTable8 = slicingMakeTable(IEEE) 74} 75 76// archUpdateIEEE calculates the checksum of p using vectorizedIEEE. 77func archUpdateIEEE(crc uint32, p []byte) uint32 { 78 if !hasVX { 79 panic("not available") 80 } 81 // Use vectorized function if data length is above threshold. 82 if len(p) >= vxMinLen { 83 aligned := len(p) & ^vxAlignMask 84 crc = vectorizedIEEE(crc, p[:aligned]) 85 p = p[aligned:] 86 } 87 if len(p) == 0 { 88 return crc 89 } 90 return slicingUpdate(crc, archIeeeTable8, p) 91} 92