src/simd/simd_emulated.go GO 3,276 lines View on github.com → Search inside
File is large — showing lines 1–2,000 of 3,276.
1// Copyright 2026 The Go Authors. All rights reserved.2// Use of this source code is governed by a BSD-style3// license that can be found in the LICENSE file.45//go:build goexperiment.simd && !(amd64 || wasm || arm64)67package simd89import (10	"internal/strconv"11	"math"12	"math/bits"13)1415// VectorBitSize returns the bit length of the emulated vector (fixed to 128).16func VectorBitSize() int {17	return 12818}1920// Emulated returns whether simd is emulated.21func Emulated() bool {22	return true23}2425// HasHardwareCarrylessMultiply returns whether this platform26// has a hardware-implemented version of carryless multiply.27// With default GODEBUG=simd settings, if this is false,28// it is emulated and merely slow, but with non-default settings29// this can indicate the possibility of a missing instruction30// that will fail ("SIGILL") if it is executed.31func HasHardwareCarrylessMultiply() bool {32	return false33}3435type number interface {36	~int8 | ~int16 | ~int32 | ~int64 | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~float32 | ~float6437}3839func sliceToString[T number](x []T) string {40	s := ""41	pfx := "{"42	for _, y := range x {43		s += pfx44		pfx = ","45		switch e := any(y).(type) {46		case int8:47			s += strconv.Itoa(int(e))48		case int16:49			s += strconv.Itoa(int(e))50		case int32:51			s += strconv.Itoa(int(e))52		case int64:53			s += strconv.FormatInt(int64(e), 10)54		case uint8:55			s += strconv.FormatUint(uint64(e), 10)56		case uint16:57			s += strconv.FormatUint(uint64(e), 10)58		case uint32:59			s += strconv.FormatUint(uint64(e), 10)60		case uint64:61			s += strconv.FormatUint(uint64(e), 10)62		case float32:63			s += strconv.FormatFloat(float64(e), 'g', -1, 32)64		case float64:65			s += strconv.FormatFloat(e, 'g', -1, 64)66		}67	}68	s += "}"69	return s70}7172// LoadInt8s loads a slice of int8 into an Int8s vector.73func LoadInt8s(s []int8) Int8s {74	var a, b uint6475	for i := 0; i < 16; i++ {76		val := uint64(uint8(s[i]))77		if i < 8 {78			a |= val << (8 * i)79		} else {80			b |= val << (8 * (i - 8))81		}82	}83	return Int8s{a: a, b: b}84}8586// LoadInt8sPart loads a partial slice of int8 into an Int8s vector.87func LoadInt8sPart(s []int8) (Int8s, int) {88	var a, b uint6489	n := len(s)90	if n > 16 {91		n = 1692	}93	for i := 0; i < n; i++ {94		val := uint64(uint8(s[i]))95		if i < 8 {96			a |= val << (8 * i)97		} else {98			b |= val << (8 * (i - 8))99		}100	}101	return Int8s{a: a, b: b}, n102}103104func (x Int8s) get(i int) int8 {105	if i < 8 {106		return int8(x.a >> (8 * i))107	}108	return int8(x.b >> (8 * (i - 8)))109}110111func (x *Int8s) set(i int, v int8) {112	val := uint64(uint8(v))113	if i < 8 {114		mask := uint64(0xff) << (8 * i)115		x.a = (x.a &^ mask) | (val << (8 * i))116	} else {117		mask := uint64(0xff) << (8 * (i - 8))118		x.b = (x.b &^ mask) | (val << (8 * (i - 8)))119	}120}121122// Abs returns the element-wise absolute value of x.123func (x Int8s) Abs() Int8s {124	var res Int8s125	for i := 0; i < 16; i++ {126		v := x.get(i)127		if v < 0 {128			res.set(i, -v)129		} else {130			res.set(i, v)131		}132	}133	return res134}135136// Add returns the element-wise sum of x and y.137func (x Int8s) Add(y Int8s) Int8s {138	var res Int8s139	for i := 0; i < 16; i++ {140		res.set(i, x.get(i)+y.get(i))141	}142	return res143}144145// AddSaturated returns the element-wise saturated sum of x and y.146func (x Int8s) AddSaturated(y Int8s) Int8s {147	var res Int8s148	for i := 0; i < 16; i++ {149		sum := int(x.get(i)) + int(y.get(i))150		if sum > math.MaxInt8 {151			res.set(i, math.MaxInt8)152		} else if sum < math.MinInt8 {153			res.set(i, math.MinInt8)154		} else {155			res.set(i, int8(sum))156		}157	}158	return res159}160161// And returns the bitwise AND of x and y.162func (x Int8s) And(y Int8s) Int8s {163	return Int8s{a: x.a & y.a, b: x.b & y.b}164}165166// AndNot returns the bitwise AND NOT of x and y.167func (x Int8s) AndNot(y Int8s) Int8s {168	return Int8s{a: x.a &^ y.a, b: x.b &^ y.b}169}170171// Equal returns a mask indicating where x and y are equal.172func (x Int8s) Equal(y Int8s) Mask8s {173	var res Mask8s174	for i := 0; i < 16; i++ {175		if x.get(i) == y.get(i) {176			res.set(i, true)177		}178	}179	return res180}181182// Greater returns a mask indicating where x is greater than y.183func (x Int8s) Greater(y Int8s) Mask8s {184	var res Mask8s185	for i := 0; i < 16; i++ {186		if x.get(i) > y.get(i) {187			res.set(i, true)188		}189	}190	return res191}192193// GreaterEqual returns a mask indicating where x is greater than or equal to y.194func (x Int8s) GreaterEqual(y Int8s) Mask8s {195	var res Mask8s196	for i := 0; i < 16; i++ {197		if x.get(i) >= y.get(i) {198			res.set(i, true)199		}200	}201	return res202}203204// Less returns a mask indicating where x is less than y.205func (x Int8s) Less(y Int8s) Mask8s {206	var res Mask8s207	for i := 0; i < 16; i++ {208		if x.get(i) < y.get(i) {209			res.set(i, true)210		}211	}212	return res213}214215// LessEqual returns a mask indicating where x is less than or equal to y.216func (x Int8s) LessEqual(y Int8s) Mask8s {217	var res Mask8s218	for i := 0; i < 16; i++ {219		if x.get(i) <= y.get(i) {220			res.set(i, true)221		}222	}223	return res224}225226// NotEqual returns a mask indicating where x and y are not equal.227func (x Int8s) NotEqual(y Int8s) Mask8s {228	var res Mask8s229	for i := 0; i < 16; i++ {230		if x.get(i) != y.get(i) {231			res.set(i, true)232		}233	}234	return res235}236237// Len returns the number of elements in the vector.238func (x Int8s) Len() int {239	return 16240}241242// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.243func (x Int8s) Masked(mask Mask8s) Int8s {244	return Int8s{a: x.a & mask.a, b: x.b & mask.b}245}246247// Max returns the element-wise maximum of x and y.248func (x Int8s) Max(y Int8s) Int8s {249	var res Int8s250	for i := 0; i < 16; i++ {251		vx := x.get(i)252		vy := y.get(i)253		if vx > vy {254			res.set(i, vx)255		} else {256			res.set(i, vy)257		}258	}259	return res260}261262// Mul returns the element-wise product of x and y.263func (x Int8s) Mul(y Int8s) Int8s {264	var res Int8s265	for i := 0; i < 16; i++ {266		res.set(i, x.get(i)*y.get(i))267	}268	return res269}270271// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.272func (x Int8s) IfElse(mask Mask8s, y Int8s) Int8s {273	return Int8s{274		a: (x.a & mask.a) | (y.a &^ mask.a),275		b: (x.b & mask.b) | (y.b &^ mask.b),276	}277}278279// Min returns the element-wise minimum of x and y.280func (x Int8s) Min(y Int8s) Int8s {281	var res Int8s282	for i := 0; i < 16; i++ {283		vx := x.get(i)284		vy := y.get(i)285		if vx < vy {286			res.set(i, vx)287		} else {288			res.set(i, vy)289		}290	}291	return res292}293294// Neg returns the element-wise negation of x.295func (x Int8s) Neg() Int8s {296	var res Int8s297	for i := 0; i < 16; i++ {298		res.set(i, -x.get(i))299	}300	return res301}302303// Not returns the bitwise NOT of x.304func (x Int8s) Not() Int8s {305	return Int8s{a: ^x.a, b: ^x.b}306}307308// Or returns the bitwise OR of x and y.309func (x Int8s) Or(y Int8s) Int8s {310	return Int8s{a: x.a | y.a, b: x.b | y.b}311}312313// Store stores the vector elements into the slice s.314func (x Int8s) Store(s []int8) {315	for i := 0; i < 16 && i < len(s); i++ {316		s[i] = x.get(i)317	}318}319320// StorePart stores a partial vector into the slice s.321func (x Int8s) StorePart(s []int8) int {322	x.Store(s)323	return min(len(s), x.Len())324}325326// String returns a string representation of the vector.327func (x Int8s) String() string {328	var parts [16]int8329	for i := 0; i < 16; i++ {330		parts[i] = x.get(i)331	}332	return sliceToString(parts[:])333}334335// Sub returns the element-wise difference of x and y.336func (x Int8s) Sub(y Int8s) Int8s {337	var res Int8s338	for i := 0; i < 16; i++ {339		res.set(i, x.get(i)-y.get(i))340	}341	return res342}343344// SubSaturated returns the element-wise saturated difference of x and y.345func (x Int8s) SubSaturated(y Int8s) Int8s {346	var res Int8s347	for i := 0; i < 16; i++ {348		diff := int(x.get(i)) - int(y.get(i))349		if diff > math.MaxInt8 {350			res.set(i, math.MaxInt8)351		} else if diff < math.MinInt8 {352			res.set(i, math.MinInt8)353		} else {354			res.set(i, int8(diff))355		}356	}357	return res358}359360// ToMask returns a mask representation of the vector.361func (x Int8s) ToMask() Mask8s {362	var res Mask8s363	for i := 0; i < 16; i++ {364		if x.get(i) != 0 {365			res.set(i, true)366		}367	}368	return res369}370371// Xor returns the bitwise XOR of x and y.372func (x Int8s) Xor(y Int8s) Int8s {373	return Int8s{a: x.a ^ y.a, b: x.b ^ y.b}374}375376// ConvertToUint8 converts the vector elements to uint8.377func (x Int8s) ConvertToUint8() Uint8s {378	return Uint8s{a: x.a, b: x.b}379}380381// ToBits reinterprets the vector bits as a Uint8s vector.382func (x Int8s) ToBits() Uint8s {383	return Uint8s{a: x.a, b: x.b}384}385386// LoadInt16s loads a slice of int16 into an Int16s vector.387func LoadInt16s(s []int16) Int16s {388	var a, b uint64389	for i := 0; i < 8; i++ {390		val := uint64(uint16(s[i]))391		if i < 4 {392			a |= val << (16 * i)393		} else {394			b |= val << (16 * (i - 4))395		}396	}397	return Int16s{a: a, b: b}398}399400// LoadInt16sPart loads a partial slice of int16 into an Int16s vector.401func LoadInt16sPart(s []int16) (Int16s, int) {402	var a, b uint64403	n := len(s)404	if n > 8 {405		n = 8406	}407	for i := 0; i < n; i++ {408		val := uint64(uint16(s[i]))409		if i < 4 {410			a |= val << (16 * i)411		} else {412			b |= val << (16 * (i - 4))413		}414	}415	return Int16s{a: a, b: b}, n416}417418func (x Int16s) get(i int) int16 {419	if i < 4 {420		return int16(x.a >> (16 * i))421	}422	return int16(x.b >> (16 * (i - 4)))423}424425func (x *Int16s) set(i int, v int16) {426	val := uint64(uint16(v))427	if i < 4 {428		mask := uint64(0xffff) << (16 * i)429		x.a = (x.a &^ mask) | (val << (16 * i))430	} else {431		mask := uint64(0xffff) << (16 * (i - 4))432		x.b = (x.b &^ mask) | (val << (16 * (i - 4)))433	}434}435436// Abs returns the element-wise absolute value of x.437func (x Int16s) Abs() Int16s {438	var res Int16s439	for i := 0; i < 8; i++ {440		v := x.get(i)441		if v < 0 {442			res.set(i, -v)443		} else {444			res.set(i, v)445		}446	}447	return res448}449450// Add returns the element-wise sum of x and y.451func (x Int16s) Add(y Int16s) Int16s {452	var res Int16s453	for i := 0; i < 8; i++ {454		res.set(i, x.get(i)+y.get(i))455	}456	return res457}458459// AddSaturated returns the element-wise saturated sum of x and y.460func (x Int16s) AddSaturated(y Int16s) Int16s {461	var res Int16s462	for i := 0; i < 8; i++ {463		sum := int(x.get(i)) + int(y.get(i))464		if sum > math.MaxInt16 {465			res.set(i, math.MaxInt16)466		} else if sum < math.MinInt16 {467			res.set(i, math.MinInt16)468		} else {469			res.set(i, int16(sum))470		}471	}472	return res473}474475// And returns the bitwise AND of x and y.476func (x Int16s) And(y Int16s) Int16s {477	return Int16s{a: x.a & y.a, b: x.b & y.b}478}479480// AndNot returns the bitwise AND NOT of x and y.481func (x Int16s) AndNot(y Int16s) Int16s {482	return Int16s{a: x.a &^ y.a, b: x.b &^ y.b}483}484485// Equal returns a mask indicating where x and y are equal.486func (x Int16s) Equal(y Int16s) Mask16s {487	var res Mask16s488	for i := 0; i < 8; i++ {489		if x.get(i) == y.get(i) {490			res.set(i, true)491		}492	}493	return res494}495496// Greater returns a mask indicating where x is greater than y.497func (x Int16s) Greater(y Int16s) Mask16s {498	var res Mask16s499	for i := 0; i < 8; i++ {500		if x.get(i) > y.get(i) {501			res.set(i, true)502		}503	}504	return res505}506507// GreaterEqual returns a mask indicating where x is greater than or equal to y.508func (x Int16s) GreaterEqual(y Int16s) Mask16s {509	var res Mask16s510	for i := 0; i < 8; i++ {511		if x.get(i) >= y.get(i) {512			res.set(i, true)513		}514	}515	return res516}517518// Less returns a mask indicating where x is less than y.519func (x Int16s) Less(y Int16s) Mask16s {520	var res Mask16s521	for i := 0; i < 8; i++ {522		if x.get(i) < y.get(i) {523			res.set(i, true)524		}525	}526	return res527}528529// LessEqual returns a mask indicating where x is less than or equal to y.530func (x Int16s) LessEqual(y Int16s) Mask16s {531	var res Mask16s532	for i := 0; i < 8; i++ {533		if x.get(i) <= y.get(i) {534			res.set(i, true)535		}536	}537	return res538}539540// NotEqual returns a mask indicating where x and y are not equal.541func (x Int16s) NotEqual(y Int16s) Mask16s {542	var res Mask16s543	for i := 0; i < 8; i++ {544		if x.get(i) != y.get(i) {545			res.set(i, true)546		}547	}548	return res549}550551// Len returns the number of elements in the vector.552func (x Int16s) Len() int {553	return 8554}555556// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.557func (x Int16s) Masked(mask Mask16s) Int16s {558	return Int16s{a: x.a & mask.a, b: x.b & mask.b}559}560561// Max returns the element-wise maximum of x and y.562func (x Int16s) Max(y Int16s) Int16s {563	var res Int16s564	for i := 0; i < 8; i++ {565		vx := x.get(i)566		vy := y.get(i)567		if vx > vy {568			res.set(i, vx)569		} else {570			res.set(i, vy)571		}572	}573	return res574}575576// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.577func (x Int16s) IfElse(mask Mask16s, y Int16s) Int16s {578	return Int16s{579		a: (x.a & mask.a) | (y.a &^ mask.a),580		b: (x.b & mask.b) | (y.b &^ mask.b),581	}582}583584// Min returns the element-wise minimum of x and y.585func (x Int16s) Min(y Int16s) Int16s {586	var res Int16s587	for i := 0; i < 8; i++ {588		vx := x.get(i)589		vy := y.get(i)590		if vx < vy {591			res.set(i, vx)592		} else {593			res.set(i, vy)594		}595	}596	return res597}598599// Mul returns the element-wise product of x and y.600func (x Int16s) Mul(y Int16s) Int16s {601	var res Int16s602	for i := 0; i < 8; i++ {603		res.set(i, x.get(i)*y.get(i))604	}605	return res606}607608// Neg returns the element-wise negation of x.609func (x Int16s) Neg() Int16s {610	var res Int16s611	for i := 0; i < 8; i++ {612		res.set(i, -x.get(i))613	}614	return res615}616617// Not returns the bitwise NOT of x.618func (x Int16s) Not() Int16s {619	return Int16s{a: ^x.a, b: ^x.b}620}621622// Or returns the bitwise OR of x and y.623func (x Int16s) Or(y Int16s) Int16s {624	return Int16s{a: x.a | y.a, b: x.b | y.b}625}626627// ShiftAllLeft shifts all elements left by y bits.628func (x Int16s) ShiftAllLeft(y uint8) Int16s {629	var res Int16s630	for i := 0; i < 8; i++ {631		res.set(i, x.get(i)<<y)632	}633	return res634}635636// ShiftAllRight shifts all elements right by y bits.637func (x Int16s) ShiftAllRight(y uint8) Int16s {638	var res Int16s639	for i := 0; i < 8; i++ {640		res.set(i, x.get(i)>>y)641	}642	return res643}644645// RotateAllLeft rotates all elements left by dist bits.646func (x Int16s) RotateAllLeft(dist uint64) Int16s {647	var res Int16s648	d := dist & 15649	for i := 0; i < 8; i++ {650		u := uint16(x.get(i))651		r := (u << d) | (u >> ((16 - d) & 15))652		res.set(i, int16(r))653	}654	return res655}656657// RotateAllRight rotates all elements right by dist bits.658func (x Int16s) RotateAllRight(dist uint64) Int16s {659	var res Int16s660	d := dist & 15661	for i := 0; i < 8; i++ {662		u := uint16(x.get(i))663		r := (u >> d) | (u << ((16 - d) & 15))664		res.set(i, int16(r))665	}666	return res667}668669// Store stores the vector elements into the slice s.670func (x Int16s) Store(s []int16) {671	for i := 0; i < 8 && i < len(s); i++ {672		s[i] = x.get(i)673	}674}675676// StorePart stores a partial vector into the slice s.677func (x Int16s) StorePart(s []int16) int {678	x.Store(s)679	return min(len(s), x.Len())680}681682// String returns a string representation of the vector.683func (x Int16s) String() string {684	var parts [8]int16685	for i := 0; i < 8; i++ {686		parts[i] = x.get(i)687	}688	return sliceToString(parts[:])689}690691// Sub returns the element-wise difference of x and y.692func (x Int16s) Sub(y Int16s) Int16s {693	var res Int16s694	for i := 0; i < 8; i++ {695		res.set(i, x.get(i)-y.get(i))696	}697	return res698}699700// SubSaturated returns the element-wise saturated difference of x and y.701func (x Int16s) SubSaturated(y Int16s) Int16s {702	var res Int16s703	for i := 0; i < 8; i++ {704		diff := int(x.get(i)) - int(y.get(i))705		if diff > math.MaxInt16 {706			res.set(i, math.MaxInt16)707		} else if diff < math.MinInt16 {708			res.set(i, math.MinInt16)709		} else {710			res.set(i, int16(diff))711		}712	}713	return res714}715716// ToMask returns a mask representation of the vector.717func (x Int16s) ToMask() Mask16s {718	var res Mask16s719	for i := 0; i < 8; i++ {720		if x.get(i) != 0 {721			res.set(i, true)722		}723	}724	return res725}726727// Xor returns the bitwise XOR of x and y.728func (x Int16s) Xor(y Int16s) Int16s {729	return Int16s{a: x.a ^ y.a, b: x.b ^ y.b}730}731732// ConvertToUint16 converts the vector elements to uint16.733func (x Int16s) ConvertToUint16() Uint16s {734	return Uint16s{a: x.a, b: x.b}735}736737// ToBits reinterprets the vector bits as a Uint16s vector.738func (x Int16s) ToBits() Uint16s {739	return Uint16s{a: x.a, b: x.b}740}741742// LoadInt32s loads a slice of int32 into an Int32s vector.743func LoadInt32s(s []int32) Int32s {744	var a, b uint64745	for i := 0; i < 4; i++ {746		val := uint64(uint32(s[i]))747		if i < 2 {748			a |= val << (32 * i)749		} else {750			b |= val << (32 * (i - 2))751		}752	}753	return Int32s{a: a, b: b}754}755756// LoadInt32sPart loads a partial slice of int32 into an Int32s vector.757func LoadInt32sPart(s []int32) (Int32s, int) {758	var a, b uint64759	n := len(s)760	if n > 4 {761		n = 4762	}763	for i := 0; i < n; i++ {764		val := uint64(uint32(s[i]))765		if i < 2 {766			a |= val << (32 * i)767		} else {768			b |= val << (32 * (i - 2))769		}770	}771	return Int32s{a: a, b: b}, n772}773774func (x Int32s) get(i int) int32 {775	if i < 2 {776		return int32(x.a >> (32 * i))777	}778	return int32(x.b >> (32 * (i - 2)))779}780781func (x *Int32s) set(i int, v int32) {782	val := uint64(uint32(v))783	if i < 2 {784		mask := uint64(0xffffffff) << (32 * i)785		x.a = (x.a &^ mask) | (val << (32 * i))786	} else {787		mask := uint64(0xffffffff) << (32 * (i - 2))788		x.b = (x.b &^ mask) | (val << (32 * (i - 2)))789	}790}791792// Abs returns the element-wise absolute value of x.793func (x Int32s) Abs() Int32s {794	var res Int32s795	for i := 0; i < 4; i++ {796		v := x.get(i)797		if v < 0 {798			res.set(i, -v)799		} else {800			res.set(i, v)801		}802	}803	return res804}805806// Add returns the element-wise sum of x and y.807func (x Int32s) Add(y Int32s) Int32s {808	var res Int32s809	for i := 0; i < 4; i++ {810		res.set(i, x.get(i)+y.get(i))811	}812	return res813}814815// And returns the bitwise AND of x and y.816func (x Int32s) And(y Int32s) Int32s {817	return Int32s{a: x.a & y.a, b: x.b & y.b}818}819820// AndNot returns the bitwise AND NOT of x and y.821func (x Int32s) AndNot(y Int32s) Int32s {822	return Int32s{a: x.a &^ y.a, b: x.b &^ y.b}823}824825// ConvertToFloat32 converts the vector elements to float32.826func (x Int32s) ConvertToFloat32() Float32s {827	var res Float32s828	for i := 0; i < 4; i++ {829		res.set(i, float32(x.get(i)))830	}831	return res832}833834// Equal returns a mask indicating where x and y are equal.835func (x Int32s) Equal(y Int32s) Mask32s {836	var res Mask32s837	for i := 0; i < 4; i++ {838		if x.get(i) == y.get(i) {839			res.set(i, true)840		}841	}842	return res843}844845// Greater returns a mask indicating where x is greater than y.846func (x Int32s) Greater(y Int32s) Mask32s {847	var res Mask32s848	for i := 0; i < 4; i++ {849		if x.get(i) > y.get(i) {850			res.set(i, true)851		}852	}853	return res854}855856// GreaterEqual returns a mask indicating where x is greater than or equal to y.857func (x Int32s) GreaterEqual(y Int32s) Mask32s {858	var res Mask32s859	for i := 0; i < 4; i++ {860		if x.get(i) >= y.get(i) {861			res.set(i, true)862		}863	}864	return res865}866867// Less returns a mask indicating where x is less than y.868func (x Int32s) Less(y Int32s) Mask32s {869	var res Mask32s870	for i := 0; i < 4; i++ {871		if x.get(i) < y.get(i) {872			res.set(i, true)873		}874	}875	return res876}877878// LessEqual returns a mask indicating where x is less than or equal to y.879func (x Int32s) LessEqual(y Int32s) Mask32s {880	var res Mask32s881	for i := 0; i < 4; i++ {882		if x.get(i) <= y.get(i) {883			res.set(i, true)884		}885	}886	return res887}888889// NotEqual returns a mask indicating where x and y are not equal.890func (x Int32s) NotEqual(y Int32s) Mask32s {891	var res Mask32s892	for i := 0; i < 4; i++ {893		if x.get(i) != y.get(i) {894			res.set(i, true)895		}896	}897	return res898}899900// Len returns the number of elements in the vector.901func (x Int32s) Len() int {902	return 4903}904905// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.906func (x Int32s) Masked(mask Mask32s) Int32s {907	return Int32s{a: x.a & mask.a, b: x.b & mask.b}908}909910// Max returns the element-wise maximum of x and y.911func (x Int32s) Max(y Int32s) Int32s {912	var res Int32s913	for i := 0; i < 4; i++ {914		vx := x.get(i)915		vy := y.get(i)916		if vx > vy {917			res.set(i, vx)918		} else {919			res.set(i, vy)920		}921	}922	return res923}924925// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.926func (x Int32s) IfElse(mask Mask32s, y Int32s) Int32s {927	return Int32s{928		a: (x.a & mask.a) | (y.a &^ mask.a),929		b: (x.b & mask.b) | (y.b &^ mask.b),930	}931}932933// Min returns the element-wise minimum of x and y.934func (x Int32s) Min(y Int32s) Int32s {935	var res Int32s936	for i := 0; i < 4; i++ {937		vx := x.get(i)938		vy := y.get(i)939		if vx < vy {940			res.set(i, vx)941		} else {942			res.set(i, vy)943		}944	}945	return res946}947948// Mul returns the element-wise product of x and y.949func (x Int32s) Mul(y Int32s) Int32s {950	var res Int32s951	for i := 0; i < 4; i++ {952		res.set(i, x.get(i)*y.get(i))953	}954	return res955}956957// Neg returns the element-wise negation of x.958func (x Int32s) Neg() Int32s {959	var res Int32s960	for i := 0; i < 4; i++ {961		res.set(i, -x.get(i))962	}963	return res964}965966// Not returns the bitwise NOT of x.967func (x Int32s) Not() Int32s {968	return Int32s{a: ^x.a, b: ^x.b}969}970971// Or returns the bitwise OR of x and y.972func (x Int32s) Or(y Int32s) Int32s {973	return Int32s{a: x.a | y.a, b: x.b | y.b}974}975976// ShiftAllLeft shifts all elements left by y bits.977func (x Int32s) ShiftAllLeft(y uint8) Int32s {978	var res Int32s979	for i := 0; i < 4; i++ {980		res.set(i, x.get(i)<<y)981	}982	return res983}984985// ShiftAllRight shifts all elements right by y bits.986func (x Int32s) ShiftAllRight(y uint8) Int32s {987	var res Int32s988	for i := 0; i < 4; i++ {989		res.set(i, x.get(i)>>y)990	}991	return res992}993994// RotateAllLeft rotates all elements left by dist bits.995func (x Int32s) RotateAllLeft(dist uint64) Int32s {996	var res Int32s997	d := dist & 31998	for i := 0; i < 4; i++ {999		u := uint32(x.get(i))1000		r := (u << d) | (u >> ((32 - d) & 31))1001		res.set(i, int32(r))1002	}1003	return res1004}10051006// RotateAllRight rotates all elements right by dist bits.1007func (x Int32s) RotateAllRight(dist uint64) Int32s {1008	var res Int32s1009	d := dist & 311010	for i := 0; i < 4; i++ {1011		u := uint32(x.get(i))1012		r := (u >> d) | (u << ((32 - d) & 31))1013		res.set(i, int32(r))1014	}1015	return res1016}10171018// Store stores the vector elements into the slice s.1019func (x Int32s) Store(s []int32) {1020	for i := 0; i < 4 && i < len(s); i++ {1021		s[i] = x.get(i)1022	}1023}10241025// StorePart stores a partial vector into the slice s.1026func (x Int32s) StorePart(s []int32) int {1027	x.Store(s)1028	return min(len(s), x.Len())1029}10301031// String returns a string representation of the vector.1032func (x Int32s) String() string {1033	var parts [4]int321034	for i := 0; i < 4; i++ {1035		parts[i] = x.get(i)1036	}1037	return sliceToString(parts[:])1038}10391040// Sub returns the element-wise difference of x and y.1041func (x Int32s) Sub(y Int32s) Int32s {1042	var res Int32s1043	for i := 0; i < 4; i++ {1044		res.set(i, x.get(i)-y.get(i))1045	}1046	return res1047}10481049// ToMask returns a mask representation of the vector.1050func (x Int32s) ToMask() Mask32s {1051	var res Mask32s1052	for i := 0; i < 4; i++ {1053		if x.get(i) != 0 {1054			res.set(i, true)1055		}1056	}1057	return res1058}10591060// Xor returns the bitwise XOR of x and y.1061func (x Int32s) Xor(y Int32s) Int32s {1062	return Int32s{a: x.a ^ y.a, b: x.b ^ y.b}1063}10641065// ConvertToUint32 converts the vector elements to uint32.1066func (x Int32s) ConvertToUint32() Uint32s {1067	return Uint32s{a: x.a, b: x.b}1068}10691070// ToBits reinterprets the vector bits as a Uint32s vector.1071func (x Int32s) ToBits() Uint32s {1072	return Uint32s{a: x.a, b: x.b}1073}10741075// LoadInt64s loads a slice of int64 into an Int64s vector.1076func LoadInt64s(s []int64) Int64s {1077	var a, b uint641078	a = uint64(s[0])1079	b = uint64(s[1])1080	return Int64s{a: a, b: b}1081}10821083// LoadInt64sPart loads a partial slice of int64 into an Int64s vector.1084func LoadInt64sPart(s []int64) (Int64s, int) {1085	var a, b uint641086	if len(s) > 0 {1087		a = uint64(s[0])1088	}1089	if len(s) > 1 {1090		b = uint64(s[1])1091	}1092	return Int64s{a: a, b: b}, len(s)1093}10941095func (x Int64s) get(i int) int64 {1096	if i == 0 {1097		return int64(x.a)1098	}1099	return int64(x.b)1100}11011102func (x *Int64s) set(i int, v int64) {1103	if i == 0 {1104		x.a = uint64(v)1105	} else {1106		x.b = uint64(v)1107	}1108}11091110// Add returns the element-wise sum of x and y.1111func (x Int64s) Add(y Int64s) Int64s {1112	return Int64s{a: x.a + y.a, b: x.b + y.b}1113}11141115// And returns the bitwise AND of x and y.1116func (x Int64s) And(y Int64s) Int64s {1117	return Int64s{a: x.a & y.a, b: x.b & y.b}1118}11191120// AndNot returns the bitwise AND NOT of x and y.1121func (x Int64s) AndNot(y Int64s) Int64s {1122	return Int64s{a: x.a &^ y.a, b: x.b &^ y.b}1123}11241125// Equal returns a mask indicating where x and y are equal.1126func (x Int64s) Equal(y Int64s) Mask64s {1127	var res Mask64s1128	if x.a == y.a {1129		res.a = ^uint64(0)1130	}1131	if x.b == y.b {1132		res.b = ^uint64(0)1133	}1134	return res1135}11361137// Greater returns a mask indicating where x is greater than y.1138func (x Int64s) Greater(y Int64s) Mask64s {1139	var res Mask64s1140	if int64(x.a) > int64(y.a) {1141		res.a = ^uint64(0)1142	}1143	if int64(x.b) > int64(y.b) {1144		res.b = ^uint64(0)1145	}1146	return res1147}11481149// GreaterEqual returns a mask indicating where x is greater than or equal to y.1150func (x Int64s) GreaterEqual(y Int64s) Mask64s {1151	var res Mask64s1152	if int64(x.a) >= int64(y.a) {1153		res.a = ^uint64(0)1154	}1155	if int64(x.b) >= int64(y.b) {1156		res.b = ^uint64(0)1157	}1158	return res1159}11601161// Less returns a mask indicating where x is less than y.1162func (x Int64s) Less(y Int64s) Mask64s {1163	var res Mask64s1164	if int64(x.a) < int64(y.a) {1165		res.a = ^uint64(0)1166	}1167	if int64(x.b) < int64(y.b) {1168		res.b = ^uint64(0)1169	}1170	return res1171}11721173// LessEqual returns a mask indicating where x is less than or equal to y.1174func (x Int64s) LessEqual(y Int64s) Mask64s {1175	var res Mask64s1176	if int64(x.a) <= int64(y.a) {1177		res.a = ^uint64(0)1178	}1179	if int64(x.b) <= int64(y.b) {1180		res.b = ^uint64(0)1181	}1182	return res1183}11841185// NotEqual returns a mask indicating where x and y are not equal.1186func (x Int64s) NotEqual(y Int64s) Mask64s {1187	var res Mask64s1188	if x.a != y.a {1189		res.a = ^uint64(0)1190	}1191	if x.b != y.b {1192		res.b = ^uint64(0)1193	}1194	return res1195}11961197// Len returns the number of elements in the vector.1198func (x Int64s) Len() int {1199	return 21200}12011202// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.1203func (x Int64s) Masked(mask Mask64s) Int64s {1204	return Int64s{a: x.a & mask.a, b: x.b & mask.b}1205}12061207// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.1208func (x Int64s) IfElse(mask Mask64s, y Int64s) Int64s {1209	return Int64s{1210		a: (x.a & mask.a) | (y.a &^ mask.a),1211		b: (x.b & mask.b) | (y.b &^ mask.b),1212	}1213}12141215// Neg returns the element-wise negation of x.1216func (x Int64s) Neg() Int64s {1217	return Int64s{a: uint64(-int64(x.a)), b: uint64(-int64(x.b))}1218}12191220// Not returns the bitwise NOT of x.1221func (x Int64s) Not() Int64s {1222	return Int64s{a: ^x.a, b: ^x.b}1223}12241225// Or returns the bitwise OR of x and y.1226func (x Int64s) Or(y Int64s) Int64s {1227	return Int64s{a: x.a | y.a, b: x.b | y.b}1228}12291230// ShiftAllLeft shifts all elements left by y bits.1231func (x Int64s) ShiftAllLeft(y uint8) Int64s {1232	return Int64s{a: x.a << y, b: x.b << y}1233}12341235// RotateAllLeft rotates all elements left by dist bits.1236func (x Int64s) RotateAllLeft(dist uint64) Int64s {1237	d := dist & 631238	return Int64s{1239		a: (x.a << d) | (x.a >> ((64 - d) & 63)),1240		b: (x.b << d) | (x.b >> ((64 - d) & 63)),1241	}1242}12431244// RotateAllRight rotates all elements right by dist bits.1245func (x Int64s) RotateAllRight(dist uint64) Int64s {1246	d := dist & 631247	return Int64s{1248		a: (x.a >> d) | (x.a << ((64 - d) & 63)),1249		b: (x.b >> d) | (x.b << ((64 - d) & 63)),1250	}1251}12521253// Store stores the vector elements into the slice s.1254func (x Int64s) Store(s []int64) {1255	if len(s) > 0 {1256		s[0] = int64(x.a)1257	}1258	if len(s) > 1 {1259		s[1] = int64(x.b)1260	}1261}12621263// StorePart stores a partial vector into the slice s.1264func (x Int64s) StorePart(s []int64) int {1265	x.Store(s)1266	return min(len(s), x.Len())1267}12681269// String returns a string representation of the vector.1270func (x Int64s) String() string {1271	return sliceToString([]int64{int64(x.a), int64(x.b)})1272}12731274// Sub returns the element-wise difference of x and y.1275func (x Int64s) Sub(y Int64s) Int64s {1276	return Int64s{a: x.a - y.a, b: x.b - y.b}1277}12781279// ToMask returns a mask representation of the vector.1280func (x Int64s) ToMask() Mask64s {1281	var res Mask64s1282	if x.a != 0 {1283		res.a = ^uint64(0)1284	}1285	if x.b != 0 {1286		res.b = ^uint64(0)1287	}1288	return res1289}12901291// Xor returns the bitwise XOR of x and y.1292func (x Int64s) Xor(y Int64s) Int64s {1293	return Int64s{a: x.a ^ y.a, b: x.b ^ y.b}1294}12951296// ConvertToUint64 converts the vector elements to uint64.1297func (x Int64s) ConvertToUint64() Uint64s {1298	return Uint64s{a: x.a, b: x.b}1299}13001301// ToBits reinterprets the vector bits as a Uint64s vector.1302func (x Int64s) ToBits() Uint64s {1303	return Uint64s{a: x.a, b: x.b}1304}13051306// LoadUint8s loads a slice of uint8 into an Uint8s vector.1307func LoadUint8s(s []uint8) Uint8s {1308	var a, b uint641309	for i := 0; i < 16; i++ {1310		val := uint64(s[i])1311		if i < 8 {1312			a |= val << (8 * i)1313		} else {1314			b |= val << (8 * (i - 8))1315		}1316	}1317	return Uint8s{a: a, b: b}1318}13191320// LoadUint8sPart loads a partial slice of uint8 into an Uint8s vector.1321func LoadUint8sPart(s []uint8) (Uint8s, int) {1322	var a, b uint641323	n := len(s)1324	if n > 16 {1325		n = 161326	}1327	for i := 0; i < n; i++ {1328		val := uint64(s[i])1329		if i < 8 {1330			a |= val << (8 * i)1331		} else {1332			b |= val << (8 * (i - 8))1333		}1334	}1335	return Uint8s{a: a, b: b}, n1336}13371338func (x Uint8s) get(i int) uint8 {1339	if i < 8 {1340		return uint8(x.a >> (8 * i))1341	}1342	return uint8(x.b >> (8 * (i - 8)))1343}13441345func (x *Uint8s) set(i int, v uint8) {1346	val := uint64(v)1347	if i < 8 {1348		mask := uint64(0xff) << (8 * i)1349		x.a = (x.a &^ mask) | (val << (8 * i))1350	} else {1351		mask := uint64(0xff) << (8 * (i - 8))1352		x.b = (x.b &^ mask) | (val << (8 * (i - 8)))1353	}1354}13551356// Add returns the element-wise sum of x and y.1357func (x Uint8s) Add(y Uint8s) Uint8s {1358	var res Uint8s1359	for i := 0; i < 16; i++ {1360		res.set(i, x.get(i)+y.get(i))1361	}1362	return res1363}13641365// AddSaturated returns the element-wise saturated sum of x and y.1366func (x Uint8s) AddSaturated(y Uint8s) Uint8s {1367	var res Uint8s1368	for i := 0; i < 16; i++ {1369		sum := int(x.get(i)) + int(y.get(i))1370		if sum > math.MaxUint8 {1371			res.set(i, math.MaxUint8)1372		} else {1373			res.set(i, uint8(sum))1374		}1375	}1376	return res1377}13781379// And returns the bitwise AND of x and y.1380func (x Uint8s) And(y Uint8s) Uint8s {1381	return Uint8s{a: x.a & y.a, b: x.b & y.b}1382}13831384// AndNot returns the bitwise AND NOT of x and y.1385func (x Uint8s) AndNot(y Uint8s) Uint8s {1386	return Uint8s{a: x.a &^ y.a, b: x.b &^ y.b}1387}13881389// Average returns the element-wise average of x and y.1390func (x Uint8s) Average(y Uint8s) Uint8s {1391	var res Uint8s1392	for i := 0; i < 16; i++ {1393		res.set(i, uint8((int(x.get(i))+int(y.get(i))+1)>>1))1394	}1395	return res1396}13971398// Equal returns a mask indicating where x and y are equal.1399func (x Uint8s) Equal(y Uint8s) Mask8s {1400	var res Mask8s1401	for i := 0; i < 16; i++ {1402		if x.get(i) == y.get(i) {1403			res.set(i, true)1404		}1405	}1406	return res1407}14081409// NotEqual returns a mask indicating where x and y are not equal.1410func (x Uint8s) NotEqual(y Uint8s) Mask8s {1411	var res Mask8s1412	for i := 0; i < 16; i++ {1413		if x.get(i) != y.get(i) {1414			res.set(i, true)1415		}1416	}1417	return res1418}14191420// Len returns the number of elements in the vector.1421func (x Uint8s) Len() int {1422	return 161423}14241425// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.1426func (x Uint8s) Masked(mask Mask8s) Uint8s {1427	return Uint8s{a: x.a & mask.a, b: x.b & mask.b}1428}14291430// Max returns the element-wise maximum of x and y.1431func (x Uint8s) Max(y Uint8s) Uint8s {1432	var res Uint8s1433	for i := 0; i < 16; i++ {1434		vx := x.get(i)1435		vy := y.get(i)1436		if vx > vy {1437			res.set(i, vx)1438		} else {1439			res.set(i, vy)1440		}1441	}1442	return res1443}14441445// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.1446func (x Uint8s) IfElse(mask Mask8s, y Uint8s) Uint8s {1447	return Uint8s{1448		a: (x.a & mask.a) | (y.a &^ mask.a),1449		b: (x.b & mask.b) | (y.b &^ mask.b),1450	}1451}14521453// Min returns the element-wise minimum of x and y.1454func (x Uint8s) Min(y Uint8s) Uint8s {1455	var res Uint8s1456	for i := 0; i < 16; i++ {1457		vx := x.get(i)1458		vy := y.get(i)1459		if vx < vy {1460			res.set(i, vx)1461		} else {1462			res.set(i, vy)1463		}1464	}1465	return res1466}14671468// Mul returns the element-wise product of x and y.1469func (x Uint8s) Mul(y Uint8s) Uint8s {1470	var res Uint8s1471	for i := 0; i < 16; i++ {1472		res.set(i, x.get(i)*y.get(i))1473	}1474	return res1475}14761477// Not returns the bitwise NOT of x.1478func (x Uint8s) Not() Uint8s {1479	return Uint8s{a: ^x.a, b: ^x.b}1480}14811482// Or returns the bitwise OR of x and y.1483func (x Uint8s) Or(y Uint8s) Uint8s {1484	return Uint8s{a: x.a | y.a, b: x.b | y.b}1485}14861487// Store stores the vector elements into the slice s.1488func (x Uint8s) Store(s []uint8) {1489	for i := 0; i < 16 && i < len(s); i++ {1490		s[i] = x.get(i)1491	}1492}14931494// StorePart stores a partial vector into the slice s.1495func (x Uint8s) StorePart(s []uint8) int {1496	x.Store(s)1497	return min(len(s), x.Len())1498}14991500// String returns a string representation of the vector.1501func (x Uint8s) String() string {1502	var parts [16]uint81503	for i := 0; i < 16; i++ {1504		parts[i] = x.get(i)1505	}1506	return sliceToString(parts[:])1507}15081509// Sub returns the element-wise difference of x and y.1510func (x Uint8s) Sub(y Uint8s) Uint8s {1511	var res Uint8s1512	for i := 0; i < 16; i++ {1513		res.set(i, x.get(i)-y.get(i))1514	}1515	return res1516}15171518// SubSaturated returns the element-wise saturated difference of x and y.1519func (x Uint8s) SubSaturated(y Uint8s) Uint8s {1520	var res Uint8s1521	for i := 0; i < 16; i++ {1522		vx := x.get(i)1523		vy := y.get(i)1524		if vx < vy {1525			res.set(i, 0)1526		} else {1527			res.set(i, vx-vy)1528		}1529	}1530	return res1531}15321533// Xor returns the bitwise XOR of x and y.1534func (x Uint8s) Xor(y Uint8s) Uint8s {1535	return Uint8s{a: x.a ^ y.a, b: x.b ^ y.b}1536}15371538// BitsToInt8 reinterprets the vector bits as an Int8s vector.1539func (x Uint8s) BitsToInt8() Int8s {1540	return Int8s{a: x.a, b: x.b}1541}15421543// ConvertToInt8 converts the vector elements to int8.1544func (x Uint8s) ConvertToInt8() Int8s {1545	return Int8s{a: x.a, b: x.b}1546}15471548// ReshapeToUint16s reinterprets the vector bits as a Uint16s vector.1549func (x Uint8s) ReshapeToUint16s() Uint16s {1550	return Uint16s{a: x.a, b: x.b}1551}15521553// ReshapeToUint32s reinterprets the vector bits as a Uint32s vector.1554func (x Uint8s) ReshapeToUint32s() Uint32s {1555	return Uint32s{a: x.a, b: x.b}1556}15571558// ReshapeToUint64s reinterprets the vector bits as a Uint64s vector.1559func (x Uint8s) ReshapeToUint64s() Uint64s {1560	return Uint64s{a: x.a, b: x.b}1561}15621563// LoadUint16s loads a slice of uint16 into an Uint16s vector.1564func LoadUint16s(s []uint16) Uint16s {1565	var a, b uint641566	for i := 0; i < 8; i++ {1567		val := uint64(s[i])1568		if i < 4 {1569			a |= val << (16 * i)1570		} else {1571			b |= val << (16 * (i - 4))1572		}1573	}1574	return Uint16s{a: a, b: b}1575}15761577// LoadUint16sPart loads a partial slice of uint16 into an Uint16s vector.1578func LoadUint16sPart(s []uint16) (Uint16s, int) {1579	var a, b uint641580	n := len(s)1581	if n > 8 {1582		n = 81583	}1584	for i := 0; i < n; i++ {1585		val := uint64(s[i])1586		if i < 4 {1587			a |= val << (16 * i)1588		} else {1589			b |= val << (16 * (i - 4))1590		}1591	}1592	return Uint16s{a: a, b: b}, n1593}15941595func (x Uint16s) get(i int) uint16 {1596	if i < 4 {1597		return uint16(x.a >> (16 * i))1598	}1599	return uint16(x.b >> (16 * (i - 4)))1600}16011602func (x *Uint16s) set(i int, v uint16) {1603	val := uint64(v)1604	if i < 4 {1605		mask := uint64(0xffff) << (16 * i)1606		x.a = (x.a &^ mask) | (val << (16 * i))1607	} else {1608		mask := uint64(0xffff) << (16 * (i - 4))1609		x.b = (x.b &^ mask) | (val << (16 * (i - 4)))1610	}1611}16121613// Add returns the element-wise sum of x and y.1614func (x Uint16s) Add(y Uint16s) Uint16s {1615	var res Uint16s1616	for i := 0; i < 8; i++ {1617		res.set(i, x.get(i)+y.get(i))1618	}1619	return res1620}16211622// AddSaturated returns the element-wise saturated sum of x and y.1623func (x Uint16s) AddSaturated(y Uint16s) Uint16s {1624	var res Uint16s1625	for i := 0; i < 8; i++ {1626		sum := int(x.get(i)) + int(y.get(i))1627		if sum > math.MaxUint16 {1628			res.set(i, math.MaxUint16)1629		} else {1630			res.set(i, uint16(sum))1631		}1632	}1633	return res1634}16351636// And returns the bitwise AND of x and y.1637func (x Uint16s) And(y Uint16s) Uint16s {1638	return Uint16s{a: x.a & y.a, b: x.b & y.b}1639}16401641// AndNot returns the bitwise AND NOT of x and y.1642func (x Uint16s) AndNot(y Uint16s) Uint16s {1643	return Uint16s{a: x.a &^ y.a, b: x.b &^ y.b}1644}16451646// Average returns the element-wise average of x and y.1647func (x Uint16s) Average(y Uint16s) Uint16s {1648	var res Uint16s1649	for i := 0; i < 8; i++ {1650		res.set(i, uint16((int(x.get(i))+int(y.get(i))+1)>>1))1651	}1652	return res1653}16541655// Equal returns a mask indicating where x and y are equal.1656func (x Uint16s) Equal(y Uint16s) Mask16s {1657	var res Mask16s1658	for i := 0; i < 8; i++ {1659		if x.get(i) == y.get(i) {1660			res.set(i, true)1661		}1662	}1663	return res1664}16651666// Greater returns a mask indicating where x is greater than y.1667func (x Uint16s) Greater(y Uint16s) Mask16s {1668	var res Mask16s1669	for i := 0; i < 8; i++ {1670		if x.get(i) > y.get(i) {1671			res.set(i, true)1672		}1673	}1674	return res1675}16761677// GreaterEqual returns a mask indicating where x is greater than or equal to y.1678func (x Uint16s) GreaterEqual(y Uint16s) Mask16s {1679	var res Mask16s1680	for i := 0; i < 8; i++ {1681		if x.get(i) >= y.get(i) {1682			res.set(i, true)1683		}1684	}1685	return res1686}16871688// Less returns a mask indicating where x is less than y.1689func (x Uint16s) Less(y Uint16s) Mask16s {1690	var res Mask16s1691	for i := 0; i < 8; i++ {1692		if x.get(i) < y.get(i) {1693			res.set(i, true)1694		}1695	}1696	return res1697}16981699// LessEqual returns a mask indicating where x is less than or equal to y.1700func (x Uint16s) LessEqual(y Uint16s) Mask16s {1701	var res Mask16s1702	for i := 0; i < 8; i++ {1703		if x.get(i) <= y.get(i) {1704			res.set(i, true)1705		}1706	}1707	return res1708}17091710// NotEqual returns a mask indicating where x and y are not equal.1711func (x Uint16s) NotEqual(y Uint16s) Mask16s {1712	var res Mask16s1713	for i := 0; i < 8; i++ {1714		if x.get(i) != y.get(i) {1715			res.set(i, true)1716		}1717	}1718	return res1719}17201721// Len returns the number of elements in the vector.1722func (x Uint16s) Len() int {1723	return 81724}17251726// Masked returns a new vector with elements from x where mask is true, and zero elsewhere.1727func (x Uint16s) Masked(mask Mask16s) Uint16s {1728	return Uint16s{a: x.a & mask.a, b: x.b & mask.b}1729}17301731// Max returns the element-wise maximum of x and y.1732func (x Uint16s) Max(y Uint16s) Uint16s {1733	var res Uint16s1734	for i := 0; i < 8; i++ {1735		vx := x.get(i)1736		vy := y.get(i)1737		if vx > vy {1738			res.set(i, vx)1739		} else {1740			res.set(i, vy)1741		}1742	}1743	return res1744}17451746// IfElse returns a new vector with elements from x where mask is true, and y where mask is false.1747func (x Uint16s) IfElse(mask Mask16s, y Uint16s) Uint16s {1748	return Uint16s{1749		a: (x.a & mask.a) | (y.a &^ mask.a),1750		b: (x.b & mask.b) | (y.b &^ mask.b),1751	}1752}17531754// Min returns the element-wise minimum of x and y.1755func (x Uint16s) Min(y Uint16s) Uint16s {1756	var res Uint16s1757	for i := 0; i < 8; i++ {1758		vx := x.get(i)1759		vy := y.get(i)1760		if vx < vy {1761			res.set(i, vx)1762		} else {1763			res.set(i, vy)1764		}1765	}1766	return res1767}17681769// Mul returns the element-wise product of x and y.1770func (x Uint16s) Mul(y Uint16s) Uint16s {1771	var res Uint16s1772	for i := 0; i < 8; i++ {1773		res.set(i, x.get(i)*y.get(i))1774	}1775	return res1776}17771778// Not returns the bitwise NOT of x.1779func (x Uint16s) Not() Uint16s {1780	return Uint16s{a: ^x.a, b: ^x.b}1781}17821783// Or returns the bitwise OR of x and y.1784func (x Uint16s) Or(y Uint16s) Uint16s {1785	return Uint16s{a: x.a | y.a, b: x.b | y.b}1786}17871788// ShiftAllLeft shifts all elements left by y bits.1789func (x Uint16s) ShiftAllLeft(y uint8) Uint16s {1790	var res Uint16s1791	for i := 0; i < 8; i++ {1792		res.set(i, x.get(i)<<y)1793	}1794	return res1795}17961797// ShiftAllRight shifts all elements right by y bits.1798func (x Uint16s) ShiftAllRight(y uint8) Uint16s {1799	var res Uint16s1800	for i := 0; i < 8; i++ {1801		res.set(i, x.get(i)>>y)1802	}1803	return res1804}18051806// RotateAllLeft rotates all elements left by dist bits.1807func (x Uint16s) RotateAllLeft(dist uint64) Uint16s {1808	var res Uint16s1809	d := dist & 151810	for i := 0; i < 8; i++ {1811		u := x.get(i)1812		r := (u << d) | (u >> ((16 - d) & 15))1813		res.set(i, r)1814	}1815	return res1816}18171818// RotateAllRight rotates all elements right by dist bits.1819func (x Uint16s) RotateAllRight(dist uint64) Uint16s {1820	var res Uint16s1821	d := dist & 151822	for i := 0; i < 8; i++ {1823		u := x.get(i)1824		r := (u >> d) | (u << ((16 - d) & 15))1825		res.set(i, r)1826	}1827	return res1828}18291830// Store stores the vector elements into the slice s.1831func (x Uint16s) Store(s []uint16) {1832	for i := 0; i < 8 && i < len(s); i++ {1833		s[i] = x.get(i)1834	}1835}18361837// StorePart stores a partial vector into the slice s.1838func (x Uint16s) StorePart(s []uint16) int {1839	x.Store(s)1840	return min(len(s), x.Len())1841}18421843// String returns a string representation of the vector.1844func (x Uint16s) String() string {1845	var parts [8]uint161846	for i := 0; i < 8; i++ {1847		parts[i] = x.get(i)1848	}1849	return sliceToString(parts[:])1850}18511852// Sub returns the element-wise difference of x and y.1853func (x Uint16s) Sub(y Uint16s) Uint16s {1854	var res Uint16s1855	for i := 0; i < 8; i++ {1856		res.set(i, x.get(i)-y.get(i))1857	}1858	return res1859}18601861// SubSaturated returns the element-wise saturated difference of x and y.1862func (x Uint16s) SubSaturated(y Uint16s) Uint16s {1863	var res Uint16s1864	for i := 0; i < 8; i++ {1865		vx := x.get(i)1866		vy := y.get(i)1867		if vx < vy {1868			res.set(i, 0)1869		} else {1870			res.set(i, vx-vy)1871		}1872	}1873	return res1874}18751876// Xor returns the bitwise XOR of x and y.1877func (x Uint16s) Xor(y Uint16s) Uint16s {1878	return Uint16s{a: x.a ^ y.a, b: x.b ^ y.b}1879}18801881// BitsToInt16 reinterprets the vector bits as an Int16s vector.1882func (x Uint16s) BitsToInt16() Int16s {1883	return Int16s{a: x.a, b: x.b}1884}18851886// ConvertToInt16 converts the vector elements to int16.1887func (x Uint16s) ConvertToInt16() Int16s {1888	return Int16s{a: x.a, b: x.b}1889}18901891// ReshapeToUint32s reinterprets the vector bits as a Uint32s vector.1892func (x Uint16s) ReshapeToUint32s() Uint32s {1893	return Uint32s{a: x.a, b: x.b}1894}18951896// ReshapeToUint64s reinterprets the vector bits as a Uint64s vector.1897func (x Uint16s) ReshapeToUint64s() Uint64s {1898	return Uint64s{a: x.a, b: x.b}1899}19001901// ReshapeToUint8s reinterprets the vector bits as a Uint8s vector.1902func (x Uint16s) ReshapeToUint8s() Uint8s {1903	return Uint8s{a: x.a, b: x.b}1904}19051906// LoadUint32s loads a slice of uint32 into an Uint32s vector.1907func LoadUint32s(s []uint32) Uint32s {1908	var a, b uint641909	for i := 0; i < 4; i++ {1910		val := uint64(s[i])1911		if i < 2 {1912			a |= val << (32 * i)1913		} else {1914			b |= val << (32 * (i - 2))1915		}1916	}1917	return Uint32s{a: a, b: b}1918}19191920// LoadUint32sPart loads a partial slice of uint32 into an Uint32s vector.1921func LoadUint32sPart(s []uint32) (Uint32s, int) {1922	var a, b uint641923	n := len(s)1924	if n > 4 {1925		n = 41926	}1927	for i := 0; i < n; i++ {1928		val := uint64(s[i])1929		if i < 2 {1930			a |= val << (32 * i)1931		} else {1932			b |= val << (32 * (i - 2))1933		}1934	}1935	return Uint32s{a: a, b: b}, n1936}19371938func (x Uint32s) get(i int) uint32 {1939	if i < 2 {1940		return uint32(x.a >> (32 * i))1941	}1942	return uint32(x.b >> (32 * (i - 2)))1943}19441945func (x *Uint32s) set(i int, v uint32) {1946	val := uint64(v)1947	if i < 2 {1948		mask := uint64(0xffffffff) << (32 * i)1949		x.a = (x.a &^ mask) | (val << (32 * i))1950	} else {1951		mask := uint64(0xffffffff) << (32 * (i - 2))1952		x.b = (x.b &^ mask) | (val << (32 * (i - 2)))1953	}1954}19551956// Add returns the element-wise sum of x and y.1957func (x Uint32s) Add(y Uint32s) Uint32s {1958	var res Uint32s1959	for i := 0; i < 4; i++ {1960		res.set(i, x.get(i)+y.get(i))1961	}1962	return res1963}19641965// And returns the bitwise AND of x and y.1966func (x Uint32s) And(y Uint32s) Uint32s {1967	return Uint32s{a: x.a & y.a, b: x.b & y.b}1968}19691970// AndNot returns the bitwise AND NOT of x and y.1971func (x Uint32s) AndNot(y Uint32s) Uint32s {1972	return Uint32s{a: x.a &^ y.a, b: x.b &^ y.b}1973}19741975// Equal returns a mask indicating where x and y are equal.1976func (x Uint32s) Equal(y Uint32s) Mask32s {1977	var res Mask32s1978	for i := 0; i < 4; i++ {1979		if x.get(i) == y.get(i) {1980			res.set(i, true)1981		}1982	}1983	return res1984}19851986// Greater returns a mask indicating where x is greater than y.1987func (x Uint32s) Greater(y Uint32s) Mask32s {1988	var res Mask32s1989	for i := 0; i < 4; i++ {1990		if x.get(i) > y.get(i) {1991			res.set(i, true)1992		}1993	}1994	return res1995}19961997// GreaterEqual returns a mask indicating where x is greater than or equal to y.1998func (x Uint32s) GreaterEqual(y Uint32s) Mask32s {1999	var res Mask32s2000	for i := 0; i < 4; i++ {

Code quality findings 1

Type switch without default case; unhandled types will silently do nothing. Add a default case for safety
info correctness unchecked-type-switch
switch e := any(y).(type) {

Get this view in your editor

Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.