github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/hash/crc32/crc32_s390x.go (about)

     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  
     5  package crc32
     6  
     7  const (
     8  	vxMinLen    = 64
     9  	vxAlignMask = 15 // align to 16 bytes
    10  )
    11  
    12  // hasVectorFacility reports whether the machine has the z/Architecture
    13  // vector facility installed and enabled.
    14  func hasVectorFacility() bool
    15  
    16  var hasVX = hasVectorFacility()
    17  
    18  // vectorizedCastagnoli implements CRC32 using vector instructions.
    19  // It is defined in crc32_s390x.s.
    20  //go:noescape
    21  func vectorizedCastagnoli(crc uint32, p []byte) uint32
    22  
    23  // vectorizedIEEE implements CRC32 using vector instructions.
    24  // It is defined in crc32_s390x.s.
    25  //go:noescape
    26  func vectorizedIEEE(crc uint32, p []byte) uint32
    27  
    28  func genericCastagnoli(crc uint32, p []byte) uint32 {
    29  	// Use slicing-by-8 on larger inputs.
    30  	if len(p) >= sliceBy8Cutoff {
    31  		return updateSlicingBy8(crc, castagnoliTable8, p)
    32  	}
    33  	return update(crc, castagnoliTable, p)
    34  }
    35  
    36  func genericIEEE(crc uint32, p []byte) uint32 {
    37  	// Use slicing-by-8 on larger inputs.
    38  	if len(p) >= sliceBy8Cutoff {
    39  		ieeeTable8Once.Do(func() {
    40  			ieeeTable8 = makeTable8(IEEE)
    41  		})
    42  		return updateSlicingBy8(crc, ieeeTable8, p)
    43  	}
    44  	return update(crc, IEEETable, p)
    45  }
    46  
    47  // updateCastagnoli calculates the checksum of p using
    48  // vectorizedCastagnoli if possible and falling back onto
    49  // genericCastagnoli as needed.
    50  func updateCastagnoli(crc uint32, p []byte) uint32 {
    51  	// Use vectorized function if vector facility is available and
    52  	// data length is above threshold.
    53  	if hasVX && len(p) >= vxMinLen {
    54  		aligned := len(p) & ^vxAlignMask
    55  		crc = vectorizedCastagnoli(crc, p[:aligned])
    56  		p = p[aligned:]
    57  		// process remaining data
    58  		if len(p) > 0 {
    59  			crc = genericCastagnoli(crc, p)
    60  		}
    61  		return crc
    62  	}
    63  	return genericCastagnoli(crc, p)
    64  }
    65  
    66  // updateIEEE calculates the checksum of p using vectorizedIEEE if
    67  // possible and falling back onto genericIEEE as needed.
    68  func updateIEEE(crc uint32, p []byte) uint32 {
    69  	// Use vectorized function if vector facility is available and
    70  	// data length is above threshold.
    71  	if hasVX && len(p) >= vxMinLen {
    72  		aligned := len(p) & ^vxAlignMask
    73  		crc = vectorizedIEEE(crc, p[:aligned])
    74  		p = p[aligned:]
    75  		// process remaining data
    76  		if len(p) > 0 {
    77  			crc = genericIEEE(crc, p)
    78  		}
    79  		return crc
    80  	}
    81  	return genericIEEE(crc, p)
    82  }