github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/hash/crc32/crc32_ppc64le.go (about)

     1  // Copyright 2017 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  // +build ignore
     6  
     7  package crc32
     8  
     9  import (
    10  	"unsafe"
    11  )
    12  
    13  const (
    14  	vecMinLen    = 16
    15  	vecAlignMask = 15 // align to 16 bytes
    16  	crcIEEE      = 1
    17  	crcCast      = 2
    18  )
    19  
    20  //go:noescape
    21  func ppc64SlicingUpdateBy8(crc uint32, table8 *slicing8Table, p []byte) uint32
    22  
    23  // this function requires the buffer to be 16 byte aligned and > 16 bytes long
    24  //go:noescape
    25  func vectorCrc32(crc uint32, poly uint32, p []byte) uint32
    26  
    27  var archCastagnoliTable8 *slicing8Table
    28  
    29  func archInitCastagnoli() {
    30  	archCastagnoliTable8 = slicingMakeTable(Castagnoli)
    31  }
    32  
    33  func archUpdateCastagnoli(crc uint32, p []byte) uint32 {
    34  	if len(p) >= 4*vecMinLen {
    35  		// If not aligned then process the initial unaligned bytes
    36  
    37  		if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 {
    38  			align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask)
    39  			newlen := vecMinLen - align
    40  			crc = ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p[:newlen])
    41  			p = p[newlen:]
    42  		}
    43  		// p should be aligned now
    44  		aligned := len(p) & ^vecAlignMask
    45  		crc = vectorCrc32(crc, crcCast, p[:aligned])
    46  		p = p[aligned:]
    47  	}
    48  	if len(p) == 0 {
    49  		return crc
    50  	}
    51  	return ppc64SlicingUpdateBy8(crc, archCastagnoliTable8, p)
    52  }
    53  
    54  func archAvailableIEEE() bool {
    55  	return true
    56  }
    57  func archAvailableCastagnoli() bool {
    58  	return true
    59  }
    60  
    61  var archIeeeTable8 *slicing8Table
    62  
    63  func archInitIEEE() {
    64  	// We still use slicing-by-8 for small buffers.
    65  	archIeeeTable8 = slicingMakeTable(IEEE)
    66  }
    67  
    68  // archUpdateIEEE calculates the checksum of p using vectorizedIEEE.
    69  func archUpdateIEEE(crc uint32, p []byte) uint32 {
    70  
    71  	// Check if vector code should be used.  If not aligned, then handle those
    72  	// first up to the aligned bytes.
    73  
    74  	if len(p) >= 4*vecMinLen {
    75  		if uint64(uintptr(unsafe.Pointer(&p[0])))&uint64(vecAlignMask) != 0 {
    76  			align := uint64(uintptr(unsafe.Pointer(&p[0]))) & uint64(vecAlignMask)
    77  			newlen := vecMinLen - align
    78  			crc = ppc64SlicingUpdateBy8(crc, archIeeeTable8, p[:newlen])
    79  			p = p[newlen:]
    80  		}
    81  		aligned := len(p) & ^vecAlignMask
    82  		crc = vectorCrc32(crc, crcIEEE, p[:aligned])
    83  		p = p[aligned:]
    84  	}
    85  	if len(p) == 0 {
    86  		return crc
    87  	}
    88  	return ppc64SlicingUpdateBy8(crc, archIeeeTable8, p)
    89  }