github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/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 func castagnoliSSE42(crc uint32, p []byte) uint32 19 20 // ieeeCLMUL is defined in crc_amd64.s and uses the PCLMULQDQ 21 // instruction as well as SSE 4.1. 22 func ieeeCLMUL(crc uint32, p []byte) uint32 23 24 var sse42 = haveSSE42() 25 var useFastIEEE = haveCLMUL() && haveSSE41() 26 27 func updateCastagnoli(crc uint32, p []byte) uint32 { 28 if sse42 { 29 return castagnoliSSE42(crc, p) 30 } 31 return update(crc, castagnoliTable, p) 32 } 33 34 func updateIEEE(crc uint32, p []byte) uint32 { 35 if useFastIEEE && len(p) >= 64 { 36 left := len(p) & 15 37 do := len(p) - left 38 crc = ^ieeeCLMUL(^crc, p[:do]) 39 if left > 0 { 40 crc = update(crc, IEEETable, p[do:]) 41 } 42 return crc 43 } 44 45 // only use slicing-by-8 when input is >= 4KB 46 if len(p) >= 4096 { 47 iEEETable8Once.Do(func() { 48 iEEETable8 = makeTable8(IEEE) 49 }) 50 return updateSlicingBy8(crc, iEEETable8, p) 51 } 52 53 return update(crc, IEEETable, p) 54 }