github.com/corona10/go@v0.0.0-20180224231303-7a218942be57/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 archAvailableCastagnoli() bool {
    29  	return hasVX
    30  }
    31  
    32  var archCastagnoliTable8 *slicing8Table
    33  
    34  func archInitCastagnoli() {
    35  	if !hasVX {
    36  		panic("not available")
    37  	}
    38  	// We still use slicing-by-8 for small buffers.
    39  	archCastagnoliTable8 = slicingMakeTable(Castagnoli)
    40  }
    41  
    42  // archUpdateCastagnoli calculates the checksum of p using
    43  // vectorizedCastagnoli.
    44  func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
    45  	if !hasVX {
    46  		panic("not available")
    47  	}
    48  	// Use vectorized function if data length is above threshold.
    49  	if len(p) >= vxMinLen {
    50  		aligned := len(p) & ^vxAlignMask
    51  		crc = vectorizedCastagnoli(crc, p[:aligned])
    52  		p = p[aligned:]
    53  	}
    54  	if len(p) == 0 {
    55  		return crc
    56  	}
    57  	return slicingUpdate(crc, archCastagnoliTable8, p)
    58  }
    59  
    60  func archAvailableIEEE() bool {
    61  	return hasVX
    62  }
    63  
    64  var archIeeeTable8 *slicing8Table
    65  
    66  func archInitIEEE() {
    67  	if !hasVX {
    68  		panic("not available")
    69  	}
    70  	// We still use slicing-by-8 for small buffers.
    71  	archIeeeTable8 = slicingMakeTable(IEEE)
    72  }
    73  
    74  // archUpdateIEEE calculates the checksum of p using vectorizedIEEE.
    75  func archUpdateIEEE(crc uint32, p []byte) uint32 {
    76  	if !hasVX {
    77  		panic("not available")
    78  	}
    79  	// Use vectorized function if data length is above threshold.
    80  	if len(p) >= vxMinLen {
    81  		aligned := len(p) & ^vxAlignMask
    82  		crc = vectorizedIEEE(crc, p[:aligned])
    83  		p = p[aligned:]
    84  	}
    85  	if len(p) == 0 {
    86  		return crc
    87  	}
    88  	return slicingUpdate(crc, archIeeeTable8, p)
    89  }