// Copyright 2025 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. //go:build goexperiment.simd && amd64 package archsimd // Implementation of all the {Int,Uint}{8,16} load and store slice part // functions and methods for 256-bit vectors. /* These two masks are used by generated code */ var vecMask64 = [16]int64{ -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, } var vecMask32 = [32]int32{ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } /* 256-bit int vector loads and stores made from 128-bit parts */ // LoadInt8x32Part loads a Int8x32 from the slice s. // If s has fewer than 32 elements, the remaining elements of the vector are filled with zeroes. // If s has 32 or more elements, the function is equivalent to LoadInt8x32Slice. func LoadInt8x32Part(s []int8) (Int8x32, int) { l := len(s) if l >= 32 { return LoadInt8x32(s), 32 } var x Int8x32 if l == 0 { return x, 0 } if l > 16 { v, _ := LoadInt8x16Part(s[16:]) return x.SetLo(LoadInt8x16(s)).SetHi(v), l } else { v, _ := LoadInt8x16Part(s) return x.SetLo(v), l } } // LoadInt16x16Part loads a Int16x16 from the slice s. // If s has fewer than 16 elements, the remaining elements of the vector are filled with zeroes. // If s has 16 or more elements, the function is equivalent to LoadInt16x16Slice. func LoadInt16x16Part(s []int16) (Int16x16, int) { l := len(s) if l >= 16 { return LoadInt16x16(s), 16 } var x Int16x16 if l == 0 { return x, 0 } if l > 8 { v, _ := LoadInt16x8Part(s[8:]) return x.SetLo(LoadInt16x8(s)).SetHi(v), l } else { v, _ := LoadInt16x8Part(s) return x.SetLo(v), l } } // StorePart stores the elements of x into the slice s. // It stores as many elements as will fit in s. // If s has 32 or more elements, the method is equivalent to x.StoreSlice. func (x Int8x32) StorePart(s []int8) int { l := len(s) if l >= 32 { x.Store(s) return 32 } if l == 0 { return 0 } if l > 16 { x.GetLo().Store(s) x.GetHi().StorePart(s[16:]) } else { // fits in one x.GetLo().StorePart(s) } return l } // StorePart stores the elements of x into the slice s. // It stores as many elements as will fit in s. // If s has 16 or more elements, the method is equivalent to x.StoreSlice. func (x Int16x16) StorePart(s []int16) int { l := len(s) if l >= 16 { x.Store(s) return 16 } if l == 0 { return 0 } if l > 8 { x.GetLo().Store(s) x.GetHi().StorePart(s[8:]) } else { // fits in one x.GetLo().StorePart(s) } return l }