github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/src/hash/crc32/crc32_amd64.go (about) 1 // Copyright 2011 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 // This file contains the code to call the SSE 4.2 version of the Castagnoli 8 // and IEEE CRC. 9 10 // haveSSE41/haveSSE42/haveCLMUL are defined in crc_amd64.s and use 11 // CPUID to test for SSE 4.1, 4.2 and CLMUL support. 12 func haveSSE41() bool 13 func haveSSE42() bool 14 func haveCLMUL() bool 15 16 // castagnoliSSE42 is defined in crc_amd64.s and uses the SSE4.2 CRC32 17 // instruction. 18 //go:noescape 19 func castagnoliSSE42(crc uint32, p []byte) uint32 20 21 // ieeeCLMUL is defined in crc_amd64.s and uses the PCLMULQDQ 22 // instruction as well as SSE 4.1. 23 //go:noescape 24 func ieeeCLMUL(crc uint32, p []byte) uint32 25 26 var sse42 = haveSSE42() 27 var useFastIEEE = haveCLMUL() && haveSSE41() 28 29 func updateCastagnoli(crc uint32, p []byte) uint32 { 30 if sse42 { 31 return castagnoliSSE42(crc, p) 32 } 33 // Use slicing-by-8 on larger inputs. 34 if len(p) >= sliceBy8Cutoff { 35 return updateSlicingBy8(crc, castagnoliTable8, p) 36 } 37 return update(crc, castagnoliTable, p) 38 } 39 40 func updateIEEE(crc uint32, p []byte) uint32 { 41 if useFastIEEE && len(p) >= 64 { 42 left := len(p) & 15 43 do := len(p) - left 44 crc = ^ieeeCLMUL(^crc, p[:do]) 45 if left > 0 { 46 crc = update(crc, IEEETable, p[do:]) 47 } 48 return crc 49 } 50 51 // Use slicing-by-8 on larger inputs. 52 if len(p) >= sliceBy8Cutoff { 53 ieeeTable8Once.Do(func() { 54 ieeeTable8 = makeTable8(IEEE) 55 }) 56 return updateSlicingBy8(crc, ieeeTable8, p) 57 } 58 59 return update(crc, IEEETable, p) 60 }