Source file src/hash/crc32/crc32_s390x.go

     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  import "internal/cpu"
     8  
     9  const (
    10  	vxMinLen    = 64
    11  	vxAlignMask = 15 // align to 16 bytes
    12  )
    13  
    14  // hasVX reports whether the machine has the z/Architecture
    15  // vector facility installed and enabled.
    16  var hasVX = cpu.S390X.HasVX
    17  
    18  // vectorizedCastagnoli implements CRC32 using vector instructions.
    19  // It is defined in crc32_s390x.s.
    20  //
    21  //go:noescape
    22  func vectorizedCastagnoli(crc uint32, p []byte) uint32
    23  
    24  // vectorizedIEEE implements CRC32 using vector instructions.
    25  // It is defined in crc32_s390x.s.
    26  //
    27  //go:noescape
    28  func vectorizedIEEE(crc uint32, p []byte) uint32
    29  
    30  func archAvailableCastagnoli() bool {
    31  	return hasVX
    32  }
    33  
    34  var archCastagnoliTable8 *slicing8Table
    35  
    36  func archInitCastagnoli() {
    37  	if !hasVX {
    38  		panic("not available")
    39  	}
    40  	// We still use slicing-by-8 for small buffers.
    41  	archCastagnoliTable8 = slicingMakeTable(Castagnoli)
    42  }
    43  
    44  // archUpdateCastagnoli calculates the checksum of p using
    45  // vectorizedCastagnoli.
    46  func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
    47  	if !hasVX {
    48  		panic("not available")
    49  	}
    50  	// Use vectorized function if data length is above threshold.
    51  	if len(p) >= vxMinLen {
    52  		aligned := len(p) & ^vxAlignMask
    53  		crc = vectorizedCastagnoli(crc, p[:aligned])
    54  		p = p[aligned:]
    55  	}
    56  	if len(p) == 0 {
    57  		return crc
    58  	}
    59  	return slicingUpdate(crc, archCastagnoliTable8, p)
    60  }
    61  
    62  func archAvailableIEEE() bool {
    63  	return hasVX
    64  }
    65  
    66  var archIeeeTable8 *slicing8Table
    67  
    68  func archInitIEEE() {
    69  	if !hasVX {
    70  		panic("not available")
    71  	}
    72  	// We still use slicing-by-8 for small buffers.
    73  	archIeeeTable8 = slicingMakeTable(IEEE)
    74  }
    75  
    76  // archUpdateIEEE calculates the checksum of p using vectorizedIEEE.
    77  func archUpdateIEEE(crc uint32, p []byte) uint32 {
    78  	if !hasVX {
    79  		panic("not available")
    80  	}
    81  	// Use vectorized function if data length is above threshold.
    82  	if len(p) >= vxMinLen {
    83  		aligned := len(p) & ^vxAlignMask
    84  		crc = vectorizedIEEE(crc, p[:aligned])
    85  		p = p[aligned:]
    86  	}
    87  	if len(p) == 0 {
    88  		return crc
    89  	}
    90  	return slicingUpdate(crc, archIeeeTable8, p)
    91  }
    92  

View as plain text