| // Copyright 2026 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 | |
| package archsimd | |
| import "unsafe" | |
| // LoadUint32x4Part loads a Int32x4 from the slice s. | |
| // If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 4 or more elements, the function is equivalent to LoadUint32x4. | |
| func LoadUint32x4Part(s []uint32) (Uint32x4, int) { | |
| l := len(s) | |
| if l >= 4 { | |
| return LoadUint32x4(s), 4 | |
| } | |
| var x Uint32x4 | |
| if l == 0 { | |
| return x, 0 | |
| } | |
| if l >= 2 { // 2,3 | |
| x = x.ReshapeToUint64s().SetElem(0, *uint64atP32(&s[0])).ReshapeToUint32s() | |
| if l == 3 { | |
| x = x.SetElem(2, s[2]) | |
| } | |
| } else { // l == 1 | |
| x = x.SetElem(0, s[0]) | |
| } | |
| return x, l | |
| } | |
| // StorePart stores the elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 4 or more elements, the method is equivalent to x.Store. | |
| func (x Uint32x4) StorePart(s []uint32) int { | |
| l := len(s) | |
| if l >= 4 { | |
| x.Store(s) | |
| return 4 | |
| } | |
| if l == 0 { | |
| return 0 | |
| } | |
| if l >= 2 { // 2,3 | |
| *uint64atP32(&s[0]) = x.ReshapeToUint64s().GetElem(0) | |
| if l == 3 { | |
| s[2] = x.GetElem(2) | |
| } | |
| } else { // l == 1 | |
| s[0] = x.GetElem(0) | |
| } | |
| return l | |
| } | |
| // LoadUint64x2Part loads a Int64x2 from the slice s. | |
| // If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 2 or more elements, the function is equivalent to LoadUint64x2. | |
| func LoadUint64x2Part(s []uint64) (Uint64x2, int) { | |
| l := len(s) | |
| if l >= 2 { | |
| return LoadUint64x2(s), 2 | |
| } | |
| var x Uint64x2 | |
| if l == 0 { | |
| return x, 0 | |
| } | |
| // l == 1 | |
| x = x.SetElem(0, s[0]) | |
| return x, 1 | |
| } | |
| // StorePart stores the elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 2 or more elements, the method is equivalent to x.Store. | |
| func (x Uint64x2) StorePart(s []uint64) int { | |
| l := len(s) | |
| if l >= 2 { | |
| x.Store(s) | |
| return 2 | |
| } | |
| if l == 0 { | |
| return 0 | |
| } | |
| // l == 1 | |
| s[0] = x.GetElem(0) | |
| return 1 | |
| } | |
| // LoadInt32x4Part loads a Int32x4 from the slice s. | |
| // If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 4 or more elements, the function is equivalent to LoadInt32x4. | |
| func LoadInt32x4Part(s []int32) (Int32x4, int) { | |
| if len(s) == 0 { | |
| var zero Int32x4 | |
| return zero, 0 | |
| } | |
| t := unsafe.Slice((*uint32)(unsafe.Pointer(&s[0])), len(s)) | |
| v, l := LoadUint32x4Part(t) | |
| return v.BitsToInt32(), l | |
| } | |
| // StorePart stores the 4 elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 4 or more elements, the method is equivalent to x.Store. | |
| func (x Int32x4) StorePart(s []int32) int { | |
| if len(s) == 0 { | |
| return 0 | |
| } | |
| t := unsafe.Slice((*uint32)(unsafe.Pointer(&s[0])), len(s)) | |
| return x.ToBits().StorePart(t) | |
| } | |
| // LoadInt64x2Part loads a Int64x2 from the slice s. | |
| // If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 2 or more elements, the function is equivalent to LoadInt64x2. | |
| func LoadInt64x2Part(s []int64) (Int64x2, int) { | |
| if len(s) == 0 { | |
| var zero Int64x2 | |
| return zero, 0 | |
| } | |
| t := unsafe.Slice((*uint64)(unsafe.Pointer(&s[0])), len(s)) | |
| v, l := LoadUint64x2Part(t) | |
| return v.BitsToInt64(), l | |
| } | |
| // StorePart stores the 2 elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 2 or more elements, the method is equivalent to x.Store. | |
| func (x Int64x2) StorePart(s []int64) int { | |
| if len(s) == 0 { | |
| return 0 | |
| } | |
| t := unsafe.Slice((*uint64)(unsafe.Pointer(&s[0])), len(s)) | |
| return x.ToBits().StorePart(t) | |
| } | |
| // LoadFloat32x4Part loads a Float32x4 from the slice s. | |
| // If s has fewer than 4 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 4 or more elements, the function is equivalent to LoadFloat32x4. | |
| func LoadFloat32x4Part(s []float32) (Float32x4, int) { | |
| l := len(s) | |
| if l >= 4 { | |
| return LoadFloat32x4(s), 4 | |
| } | |
| var x Float32x4 | |
| if l == 0 { | |
| return x, l | |
| } | |
| if l >= 2 { // 2,3 | |
| x = x.ToBits().ReshapeToUint64s().BitsToFloat64().SetElem(0, *float64atP32(&s[0])).ToBits().ReshapeToUint32s().BitsToFloat32() | |
| if l == 3 { | |
| x = x.SetElem(2, s[2]) | |
| } | |
| } else { // l == 1 | |
| x = x.SetElem(0, s[0]) | |
| } | |
| return x, l | |
| } | |
| // StorePart stores the elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 4 or more elements, the method is equivalent to x.Store. | |
| func (x Float32x4) StorePart(s []float32) int { | |
| l := len(s) | |
| if l >= 4 { | |
| x.Store(s) | |
| return 4 | |
| } | |
| if l == 0 { | |
| return 0 | |
| } | |
| if l >= 2 { // 2,3( | |
| *float64atP32(&s[0]) = x.ToBits().ReshapeToUint64s().BitsToFloat64().GetElem(0) | |
| if l == 3 { | |
| s[2] = x.GetElem(2) | |
| } | |
| } else { // l == 1 | |
| s[0] = x.GetElem(0) | |
| } | |
| return l | |
| } | |
| // LoadFloat64x2Part loads a Float64x2 from the slice s. | |
| // If s has fewer than 2 elements, the remaining elements of the vector are filled with zeroes. | |
| // If s has 2 or more elements, the function is equivalent to LoadFloat64x2. | |
| func LoadFloat64x2Part(s []float64) (Float64x2, int) { | |
| l := len(s) | |
| if l >= 2 { | |
| return LoadFloat64x2(s), 2 | |
| } | |
| var x Float64x2 | |
| if l == 0 { | |
| return x, l | |
| } | |
| // l == 1 | |
| x = x.SetElem(0, s[0]) | |
| return x, l | |
| } | |
| // StorePart stores the elements of x into the slice s. | |
| // It stores as many elements as will fit in s. | |
| // If s has 2 or more elements, the method is equivalent to x.Store. | |
| func (x Float64x2) StorePart(s []float64) int { | |
| l := len(s) | |
| if l >= 2 { | |
| x.Store(s) | |
| return 2 | |
| } | |
| if l == 0 { | |
| return 0 | |
| } | |
| // l == 1 | |
| s[0] = x.GetElem(0) | |
| return l | |
| } |