github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/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 castagnoliInitArch() (needGenericTables bool) {
    29  	return true
    30  }
    31  
    32  func genericCastagnoli(crc uint32, p []byte) uint32 {
    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 genericIEEE(crc uint32, p []byte) uint32 {
    41  	// Use slicing-by-8 on larger inputs.
    42  	if len(p) >= sliceBy8Cutoff {
    43  		ieeeTable8Once.Do(func() {
    44  			ieeeTable8 = makeTable8(IEEE)
    45  		})
    46  		return updateSlicingBy8(crc, ieeeTable8, p)
    47  	}
    48  	return update(crc, IEEETable, p)
    49  }
    50  
    51  // updateCastagnoli calculates the checksum of p using
    52  // vectorizedCastagnoli if possible and falling back onto
    53  // genericCastagnoli as needed.
    54  func updateCastagnoli(crc uint32, p []byte) uint32 {
    55  	// Use vectorized function if vector facility is available and
    56  	// data length is above threshold.
    57  	if hasVX && len(p) >= vxMinLen {
    58  		aligned := len(p) & ^vxAlignMask
    59  		crc = vectorizedCastagnoli(crc, p[:aligned])
    60  		p = p[aligned:]
    61  		// process remaining data
    62  		if len(p) > 0 {
    63  			crc = genericCastagnoli(crc, p)
    64  		}
    65  		return crc
    66  	}
    67  	return genericCastagnoli(crc, p)
    68  }
    69  
    70  // updateIEEE calculates the checksum of p using vectorizedIEEE if
    71  // possible and falling back onto genericIEEE as needed.
    72  func updateIEEE(crc uint32, p []byte) uint32 {
    73  	// Use vectorized function if vector facility is available and
    74  	// data length is above threshold.
    75  	if hasVX && len(p) >= vxMinLen {
    76  		aligned := len(p) & ^vxAlignMask
    77  		crc = vectorizedIEEE(crc, p[:aligned])
    78  		p = p[aligned:]
    79  		// process remaining data
    80  		if len(p) > 0 {
    81  			crc = genericIEEE(crc, p)
    82  		}
    83  		return crc
    84  	}
    85  	return genericIEEE(crc, p)
    86  }