github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/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 return update(crc, castagnoliTable, p) 34 } 35 36 func updateIEEE(crc uint32, p []byte) uint32 { 37 if useFastIEEE && len(p) >= 64 { 38 left := len(p) & 15 39 do := len(p) - left 40 crc = ^ieeeCLMUL(^crc, p[:do]) 41 if left > 0 { 42 crc = update(crc, IEEETable, p[do:]) 43 } 44 return crc 45 } 46 47 // only use slicing-by-8 when input is >= 4KB 48 if len(p) >= 4096 { 49 ieeeTable8Once.Do(func() { 50 ieeeTable8 = makeTable8(IEEE) 51 }) 52 return updateSlicingBy8(crc, ieeeTable8, p) 53 } 54 55 return update(crc, IEEETable, p) 56 }