github.com/bytedance/gopkg@v0.0.0-20240514070511-01b2cbcf35e1/util/xxhash3/accum_scalar.go (about)

     1  // Copyright 2021 ByteDance Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package xxhash3
    16  
    17  import (
    18  	"github.com/bytedance/gopkg/internal/runtimex"
    19  	"unsafe"
    20  )
    21  
    22  func accumScalar(xacc *[8]uint64, xinput, xsecret unsafe.Pointer, l uintptr) {
    23  	j := uintptr(0)
    24  
    25  	// Loops over block and process 16*8*8=1024 bytes of data each iteration
    26  	for ; j < (l-1)/1024; j++ {
    27  		k := xsecret
    28  		for i := 0; i < 16; i++ {
    29  			dataVec0 := runtimex.ReadUnaligned64(xinput)
    30  
    31  			keyVec := dataVec0 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*0))
    32  			xacc[1] += dataVec0
    33  			xacc[0] += (keyVec & 0xffffffff) * (keyVec >> 32)
    34  
    35  			dataVec1 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*1))
    36  			keyVec1 := dataVec1 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*1))
    37  			xacc[0] += dataVec1
    38  			xacc[1] += (keyVec1 & 0xffffffff) * (keyVec1 >> 32)
    39  
    40  			dataVec2 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*2))
    41  			keyVec2 := dataVec2 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*2))
    42  			xacc[3] += dataVec2
    43  			xacc[2] += (keyVec2 & 0xffffffff) * (keyVec2 >> 32)
    44  
    45  			dataVec3 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*3))
    46  			keyVec3 := dataVec3 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*3))
    47  			xacc[2] += dataVec3
    48  			xacc[3] += (keyVec3 & 0xffffffff) * (keyVec3 >> 32)
    49  
    50  			dataVec4 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*4))
    51  			keyVec4 := dataVec4 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*4))
    52  			xacc[5] += dataVec4
    53  			xacc[4] += (keyVec4 & 0xffffffff) * (keyVec4 >> 32)
    54  
    55  			dataVec5 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*5))
    56  			keyVec5 := dataVec5 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*5))
    57  			xacc[4] += dataVec5
    58  			xacc[5] += (keyVec5 & 0xffffffff) * (keyVec5 >> 32)
    59  
    60  			dataVec6 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*6))
    61  			keyVec6 := dataVec6 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*6))
    62  			xacc[7] += dataVec6
    63  			xacc[6] += (keyVec6 & 0xffffffff) * (keyVec6 >> 32)
    64  
    65  			dataVec7 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*7))
    66  			keyVec7 := dataVec7 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*7))
    67  			xacc[6] += dataVec7
    68  			xacc[7] += (keyVec7 & 0xffffffff) * (keyVec7 >> 32)
    69  
    70  			xinput, k = unsafe.Pointer(uintptr(xinput)+_stripe), unsafe.Pointer(uintptr(k)+8)
    71  		}
    72  
    73  		// scramble xacc
    74  		xacc[0] ^= xacc[0] >> 47
    75  		xacc[0] ^= xsecret_128
    76  		xacc[0] *= prime32_1
    77  
    78  		xacc[1] ^= xacc[1] >> 47
    79  		xacc[1] ^= xsecret_136
    80  		xacc[1] *= prime32_1
    81  
    82  		xacc[2] ^= xacc[2] >> 47
    83  		xacc[2] ^= xsecret_144
    84  		xacc[2] *= prime32_1
    85  
    86  		xacc[3] ^= xacc[3] >> 47
    87  		xacc[3] ^= xsecret_152
    88  		xacc[3] *= prime32_1
    89  
    90  		xacc[4] ^= xacc[4] >> 47
    91  		xacc[4] ^= xsecret_160
    92  		xacc[4] *= prime32_1
    93  
    94  		xacc[5] ^= xacc[5] >> 47
    95  		xacc[5] ^= xsecret_168
    96  		xacc[5] *= prime32_1
    97  
    98  		xacc[6] ^= xacc[6] >> 47
    99  		xacc[6] ^= xsecret_176
   100  		xacc[6] *= prime32_1
   101  
   102  		xacc[7] ^= xacc[7] >> 47
   103  		xacc[7] ^= xsecret_184
   104  		xacc[7] *= prime32_1
   105  
   106  	}
   107  	l -= _block * j
   108  
   109  	// last partial block (at most 1024 bytes)
   110  	if l > 0 {
   111  		k := xsecret
   112  		i := uintptr(0)
   113  		for ; i < (l-1)/_stripe; i++ {
   114  			dataVec := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*0))
   115  			keyVec := dataVec ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*0))
   116  			xacc[1] += dataVec
   117  			xacc[0] += (keyVec & 0xffffffff) * (keyVec >> 32)
   118  
   119  			dataVec1 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*1))
   120  			keyVec1 := dataVec1 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*1))
   121  			xacc[0] += dataVec1
   122  			xacc[1] += (keyVec1 & 0xffffffff) * (keyVec1 >> 32)
   123  
   124  			dataVec2 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*2))
   125  			keyVec2 := dataVec2 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*2))
   126  			xacc[3] += dataVec2
   127  			xacc[2] += (keyVec2 & 0xffffffff) * (keyVec2 >> 32)
   128  
   129  			dataVec3 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*3))
   130  			keyVec3 := dataVec3 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*3))
   131  			xacc[2] += dataVec3
   132  			xacc[3] += (keyVec3 & 0xffffffff) * (keyVec3 >> 32)
   133  
   134  			dataVec4 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*4))
   135  			keyVec4 := dataVec4 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*4))
   136  			xacc[5] += dataVec4
   137  			xacc[4] += (keyVec4 & 0xffffffff) * (keyVec4 >> 32)
   138  
   139  			dataVec5 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*5))
   140  			keyVec5 := dataVec5 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*5))
   141  			xacc[4] += dataVec5
   142  			xacc[5] += (keyVec5 & 0xffffffff) * (keyVec5 >> 32)
   143  
   144  			dataVec6 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*6))
   145  			keyVec6 := dataVec6 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*6))
   146  			xacc[7] += dataVec6
   147  			xacc[6] += (keyVec6 & 0xffffffff) * (keyVec6 >> 32)
   148  
   149  			dataVec7 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*7))
   150  			keyVec7 := dataVec7 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*7))
   151  			xacc[6] += dataVec7
   152  			xacc[7] += (keyVec7 & 0xffffffff) * (keyVec7 >> 32)
   153  
   154  			xinput, k = unsafe.Pointer(uintptr(xinput)+_stripe), unsafe.Pointer(uintptr(k)+8)
   155  		}
   156  		l -= _stripe * i
   157  
   158  		// last stripe (align to last 64 bytes)
   159  		if l > 0 {
   160  			xinput = unsafe.Pointer(uintptr(xinput) - uintptr(_stripe-l))
   161  			k = unsafe.Pointer(uintptr(xsecret) + 121)
   162  
   163  			dataVec := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*0))
   164  			keyVec := dataVec ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*0))
   165  			xacc[1] += dataVec
   166  			xacc[0] += (keyVec & 0xffffffff) * (keyVec >> 32)
   167  
   168  			dataVec1 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*1))
   169  			keyVec1 := dataVec1 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*1))
   170  			xacc[0] += dataVec1
   171  			xacc[1] += (keyVec1 & 0xffffffff) * (keyVec1 >> 32)
   172  
   173  			dataVec2 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*2))
   174  			keyVec2 := dataVec2 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*2))
   175  			xacc[3] += dataVec2
   176  			xacc[2] += (keyVec2 & 0xffffffff) * (keyVec2 >> 32)
   177  
   178  			dataVec3 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*3))
   179  			keyVec3 := dataVec3 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*3))
   180  			xacc[2] += dataVec3
   181  			xacc[3] += (keyVec3 & 0xffffffff) * (keyVec3 >> 32)
   182  
   183  			dataVec4 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*4))
   184  			keyVec4 := dataVec4 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*4))
   185  			xacc[5] += dataVec4
   186  			xacc[4] += (keyVec4 & 0xffffffff) * (keyVec4 >> 32)
   187  
   188  			dataVec5 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*5))
   189  			keyVec5 := dataVec5 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*5))
   190  			xacc[4] += dataVec5
   191  			xacc[5] += (keyVec5 & 0xffffffff) * (keyVec5 >> 32)
   192  
   193  			dataVec6 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*6))
   194  			keyVec6 := dataVec6 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*6))
   195  			xacc[7] += dataVec6
   196  			xacc[6] += (keyVec6 & 0xffffffff) * (keyVec6 >> 32)
   197  
   198  			dataVec7 := runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(xinput) + 8*7))
   199  			keyVec7 := dataVec7 ^ runtimex.ReadUnaligned64(unsafe.Pointer(uintptr(k)+8*7))
   200  			xacc[6] += dataVec7
   201  			xacc[7] += (keyVec7 & 0xffffffff) * (keyVec7 >> 32)
   202  		}
   203  	}
   204  }