...

Source file src/pkg/hash/crc32/crc32_ppc64le.go

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

View as plain text