Type switch without default case; unhandled types will silently do nothing. Add a default case for safety
switch e := any(y).(type) {
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++ {
Same data, no extra tab — call code_get_file + code_get_findings over MCP from Claude/Cursor/Copilot.