simd: create a single file for simd types shared by stubs and emulation

(Should be) no changes to generated anything, just better organization

Change-Id: I4d00c9f17b5aad7f49bafce64b8af6841d21c32a
Reviewed-on: https://go-review.googlesource.com/c/go/+/789662
TryBot-Bypass: David Chase <drchase@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
diff --git a/src/simd/archsimd/_gen/midway/intersect_simd_ops.go b/src/simd/archsimd/_gen/midway/intersect_simd_ops.go
index de8f070..e91c527 100644
--- a/src/simd/archsimd/_gen/midway/intersect_simd_ops.go
+++ b/src/simd/archsimd/_gen/midway/intersect_simd_ops.go
@@ -218,6 +218,7 @@
 		return recvType
 	}
 
+	// Record existing emulated methods
 	emulated := make(map[TypeMethod]bool)
 	f, err := parser.ParseFile(fset, emulatedFile, nil, parser.ParseComments)
 	if err != nil {
@@ -327,17 +328,122 @@
 		}
 	}
 
-	intersectionByElem := make(map[string][]string)
+	type ElemMethod struct {
+		e, m string
+	}
 
-	doWrites := func(w io.Writer) {
+	intersectionByElem := make(map[string][]string)
+	signatureByElemMethod := make(map[ElemMethod]*ast.FuncDecl)
+
+	// elems is a slice of stems of vector types.
+	elems := []string{"Int8", "Int16", "Int32", "Int64", "Uint8", "Uint16", "Uint32", "Uint64", "Float32", "Float64", "Mask8", "Mask16", "Mask32", "Mask64"}
+
+	for _, elem := range elems {
+		type128 := map128[elem]
+		type256 := map256[elem]
+		type512 := map512[elem]
+
+		methods128w := methodsByType[combine("wasm", type128)]
+		methods128n := methodsByType[combine("arm64", type128)]
+		methods128 := methodsByType[combine("amd64", type128)]
+		methods256 := methodsByType[combine("amd64", type256)]
+		methods512 := methodsByType[combine("amd64", type512)]
+
+		var intersection []string
+		var missingNames []string
+		for m := range allMethodNames {
+			if wasm128, arm128, amd128, amd256, amd512 :=
+				methods128w[m] == nil, methods128n[m] == nil, methods128[m] == nil, methods256[m] == nil, methods512[m] == nil; !wasm128 && !arm128 && !amd128 && !amd256 && !amd512 {
+				intersection = append(intersection, m)
+				signatureByElemMethod[ElemMethod{elem, m}] = methods512[m] // Use 512-bit signature (arbitrary choice, they should match)
+			} else if !(wasm128 && arm128 && amd128 && amd256 && amd512) {
+				missing[m] = whyMissing{wasm128, arm128, amd128, amd256, amd512}
+				missingNames = append(missingNames, m)
+			}
+		}
+		sort.Strings(missingNames)
+
+		for _, m := range missingNames {
+			pv("Missing implementation for %ss.%s on %s\n", elem, m, missing[m].String())
+		}
+
+		sort.Strings(intersection)
+
+		intersectionByElem[elem] = intersection
+	}
+
+	// xlateType translates a type by replacing instances of types with keys in knownReceivers with their values,
+	// and generates the string representation of the resulting type.  E.g., []Int8x32 -> []Int8s
+	// (because Int8x32 -> Int8s in knownReceivers
+	var xlateType func(ast.Expr) string
+	xlateType = func(e ast.Expr) string {
+		switch t := e.(type) {
+		case *ast.Ident:
+			if mapped, ok := knownReceivers[t.Name]; ok {
+				return mapped
+			}
+			return t.Name
+		case *ast.StarExpr:
+			return "*" + xlateType(t.X)
+		case *ast.ArrayType:
+			lenStr := ""
+			if t.Len != nil {
+				var buf strings.Builder
+				format.Node(&buf, token.NewFileSet(), t.Len)
+				lenStr = buf.String()
+			}
+			return "[" + lenStr + "]" + xlateType(t.Elt)
+		case *ast.SelectorExpr:
+			return xlateType(t.X) + "." + t.Sel.Name
+		case *ast.Ellipsis:
+			return "..." + xlateType(t.Elt)
+		default:
+			var buf strings.Builder
+			format.Node(&buf, token.NewFileSet(), t)
+			return buf.String()
+		}
+	}
+
+	toScalar := func(s string) string {
+		if strings.HasPrefix(s, "Mask") {
+			return "int" + s[4:]
+		}
+		return strings.ToLower(s)
+	}
+
+	doTypes := func(w io.Writer) {
+
+		pf := func(f string, s ...any) { fmt.Fprintf(w, f, s...) }
+
+		fmt.Fprintln(w,
+			`// Code generated by 'go run -C $GOROOT/src/simd/archsimd/_gen/midway'; DO NOT EDIT.
+
+//go:build goexperiment.simd
+
+// Scalable vector types for rewriting and emulation
+
+package simd
+
+import "simd/internal/bridge"
+
+// internal SIMD marker, and hard dependence on simd/internal/bridge
+type _simd bridge.ZeroSized
+`)
+
+		for _, elem := range elems {
+			if c := comments.Types[elem+"s"]; c != "" {
+				pf("// %s\n", c)
+			}
+			pf("type %ss struct {\n\t_       _simd\n\ta, b uint64 // the actual vector size may be larger.\n}\n", elem)
+		}
+	}
+
+	doMethods := func(w io.Writer) {
 
 		p := func(s ...any) { fmt.Fprint(w, s...) }
 		pf := func(f string, s ...any) { fmt.Fprintf(w, f, s...) }
 		nl := func() { fmt.Fprintln(w) }
 
-		// elems is a slice of stems of vector types.
-		elems := []string{"Int8", "Int16", "Int32", "Int64", "Uint8", "Uint16", "Uint32", "Uint64", "Float32", "Float64", "Mask8", "Mask16", "Mask32", "Mask64"}
-
 		fmt.Fprintln(w,
 			`// Code generated by 'go run -C $GOROOT/src/simd/archsimd/_gen/midway'; DO NOT EDIT.
 
@@ -347,90 +453,10 @@
 
 package simd
 
-import "simd/internal/bridge"
-
-// internal SIMD marker, and hard dependence on simd/internal/bridge
-type _simd bridge.ZeroSized
 `)
 
-		sigForMethod := make(map[string]*ast.FuncDecl)
-
-		// xlateType translates a type by replacing instances of types with keys in knownReceivers with their values,
-		// and generates the string representation of the resulting type.  E.g., []Int8x32 -> []Int8s
-		// (because Int8x32 -> Int8s in knownReceivers
-		var xlateType func(ast.Expr) string
-		xlateType = func(e ast.Expr) string {
-			switch t := e.(type) {
-			case *ast.Ident:
-				if mapped, ok := knownReceivers[t.Name]; ok {
-					return mapped
-				}
-				return t.Name
-			case *ast.StarExpr:
-				return "*" + xlateType(t.X)
-			case *ast.ArrayType:
-				lenStr := ""
-				if t.Len != nil {
-					var buf strings.Builder
-					format.Node(&buf, token.NewFileSet(), t.Len)
-					lenStr = buf.String()
-				}
-				return "[" + lenStr + "]" + xlateType(t.Elt)
-			case *ast.SelectorExpr:
-				return xlateType(t.X) + "." + t.Sel.Name
-			case *ast.Ellipsis:
-				return "..." + xlateType(t.Elt)
-			default:
-				var buf strings.Builder
-				format.Node(&buf, token.NewFileSet(), t)
-				return buf.String()
-			}
-		}
-
-		toScalar := func(s string) string {
-			if strings.HasPrefix(s, "Mask") {
-				return "int" + s[4:]
-			}
-			return strings.ToLower(s)
-		}
-
 		for _, elem := range elems {
-			type128 := map128[elem]
-			type256 := map256[elem]
-			type512 := map512[elem]
-
-			methods128w := methodsByType[combine("wasm", type128)]
-			methods128n := methodsByType[combine("arm64", type128)]
-			methods128 := methodsByType[combine("amd64", type128)]
-			methods256 := methodsByType[combine("amd64", type256)]
-			methods512 := methodsByType[combine("amd64", type512)]
-
-			var intersection []string
-			var missingNames []string
-			for m := range allMethodNames {
-				if wasm128, arm128, amd128, amd256, amd512 :=
-					methods128w[m] == nil, methods128n[m] == nil, methods128[m] == nil, methods256[m] == nil, methods512[m] == nil; !wasm128 && !arm128 && !amd128 && !amd256 && !amd512 {
-					intersection = append(intersection, m)
-					sigForMethod[m] = methods512[m] // Use 512-bit signature (arbitrary choice, they should match)
-				} else if !(wasm128 && arm128 && amd128 && amd256 && amd512) {
-					missing[m] = whyMissing{wasm128, arm128, amd128, amd256, amd512}
-					missingNames = append(missingNames, m)
-				}
-			}
-			sort.Strings(missingNames)
-
-			for _, m := range missingNames {
-				pv("Missing implementation for %ss.%s on %s\n", elem, m, missing[m].String())
-			}
-
-			sort.Strings(intersection)
-
-			intersectionByElem[elem] = intersection
-
-			if c := comments.Types[elem+"s"]; c != "" {
-				pf("// %s\n", c)
-			}
-			pf("type %ss struct {\n\t_       _simd\n\tatLeast [2]uint64 // the actual vector size may be larger.\n}\n", elem)
+			intersection := intersectionByElem[elem]
 
 			if elem[0] != 'M' {
 				// cannot load masks
@@ -461,11 +487,10 @@
 					pf("// %s\n", broadcastComment)
 				}
 				pf("func Broadcast%ss(%s) %ss\n", elem, toScalar(elem), elem)
-
 			}
 
 			for _, m := range intersection {
-				fd := sigForMethod[m]
+				fd := signatureByElemMethod[ElemMethod{elem, m}]
 				elems := elem + "s"
 				methodComment := ""
 				if typeMethods, ok := comments.Methods[elem+"s"]; ok {
@@ -532,7 +557,10 @@
 			}
 		}
 	}
-	formatAndWrite(*goRoot+"/src/simd/simd.go", doWrites)
+
+	formatAndWrite(*goRoot+"/src/simd/simd_types.go", doTypes)
+	formatAndWrite(*goRoot+"/src/simd/simd_stubs.go", doMethods)
+
 	var extraMocks []TypeMethod
 	for x := range emulated {
 		extraMocks = append(extraMocks, x)
@@ -548,8 +576,6 @@
 		pw("%s contains %s.%s missing from intersected methods\n", emulatedFile, x.t, x.m)
 	}
 
-	elems := []string{"Int8", "Int16", "Int32", "Int64", "Uint8", "Uint16", "Uint32", "Uint64", "Float32", "Float64", "Mask8", "Mask16", "Mask32", "Mask64"}
-
 	for _, aaf := range archAndFiles {
 		arch := aaf.arch
 		doArchWrites := func(w io.Writer) {
diff --git a/src/simd/simd_emulated.go b/src/simd/simd_emulated.go
index f23c5c4..d6d5607 100644
--- a/src/simd/simd_emulated.go
+++ b/src/simd/simd_emulated.go
@@ -10,7 +10,6 @@
 	"fmt"
 	"math"
 	"math/bits"
-	"simd/internal/bridge"
 )
 
 // VectorSize returns the bit length of the emulated vector (fixed to 128).
@@ -33,14 +32,6 @@
 	return false
 }
 
-type _simd bridge.ZeroSized
-
-// Int8s represents a 128-bit vector of 16 int8 elements.
-type Int8s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadInt8s loads a slice of int8 into an Int8s vector.
 func LoadInt8s(s []int8) Int8s {
 	var a, b uint64
@@ -355,12 +346,6 @@
 	return Uint8s{a: x.a, b: x.b}
 }
 
-// Int16s represents a 128-bit vector of 8 int16 elements.
-type Int16s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadInt16s loads a slice of int16 into an Int16s vector.
 func LoadInt16s(s []int16) Int16s {
 	var a, b uint64
@@ -717,12 +702,6 @@
 	return Uint16s{a: x.a, b: x.b}
 }
 
-// Int32s represents a 128-bit vector of 4 int32 elements.
-type Int32s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadInt32s loads a slice of int32 into an Int32s vector.
 func LoadInt32s(s []int32) Int32s {
 	var a, b uint64
@@ -1056,12 +1035,6 @@
 	return Uint32s{a: x.a, b: x.b}
 }
 
-// Int64s represents a 128-bit vector of 2 int64 elements.
-type Int64s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadInt64s loads a slice of int64 into an Int64s vector.
 func LoadInt64s(s []int64) Int64s {
 	var a, b uint64
@@ -1293,12 +1266,6 @@
 	return Uint64s{a: x.a, b: x.b}
 }
 
-// Uint8s represents a 128-bit vector of 16 uint8 elements.
-type Uint8s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadUint8s loads a slice of uint8 into an Uint8s vector.
 func LoadUint8s(s []uint8) Uint8s {
 	var a, b uint64
@@ -1556,12 +1523,6 @@
 	return Uint64s{a: x.a, b: x.b}
 }
 
-// Uint16s represents a 128-bit vector of 8 uint16 elements.
-type Uint16s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadUint16s loads a slice of uint16 into an Uint16s vector.
 func LoadUint16s(s []uint16) Uint16s {
 	var a, b uint64
@@ -1905,12 +1866,6 @@
 	return Uint8s{a: x.a, b: x.b}
 }
 
-// Uint32s represents a 128-bit vector of 4 uint32 elements.
-type Uint32s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadUint32s loads a slice of uint32 into an Uint32s vector.
 func LoadUint32s(s []uint32) Uint32s {
 	var a, b uint64
@@ -2221,12 +2176,6 @@
 	return Uint8s{a: x.a, b: x.b}
 }
 
-// Uint64s represents a 128-bit vector of 2 uint64 elements.
-type Uint64s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadUint64s loads a slice of uint64 into an Uint64s vector.
 func LoadUint64s(s []uint64) Uint64s {
 	var a, b uint64
@@ -2463,12 +2412,6 @@
 	return Uint8s{a: x.a, b: x.b}
 }
 
-// Float32s represents a 128-bit vector of 4 float32 elements.
-type Float32s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadFloat32s loads a slice of float32 into an Float32s vector.
 func LoadFloat32s(s []float32) Float32s {
 	var a, b uint64
@@ -2751,12 +2694,6 @@
 	return Uint32s{a: x.a, b: x.b}
 }
 
-// Float64s represents a 128-bit vector of 2 float64 elements.
-type Float64s struct {
-	_    _simd
-	a, b uint64
-}
-
 // LoadFloat64s loads a slice of float64 into an Float64s vector.
 func LoadFloat64s(s []float64) Float64s {
 	var a, b uint64
@@ -3020,12 +2957,6 @@
 	return Uint64s{a: x.a, b: x.b}
 }
 
-// Mask8s represents a 128-bit mask vector for 16 int8/uint8 elements.
-type Mask8s struct {
-	_    _simd
-	a, b uint64
-}
-
 func (x *Mask8s) set(i int, v bool) {
 	if v {
 		if i < 8 {
@@ -3058,12 +2989,6 @@
 	return Int8s{a: x.a, b: x.b}
 }
 
-// Mask16s represents a 128-bit mask vector for 8 int16/uint16 elements.
-type Mask16s struct {
-	_    _simd
-	a, b uint64
-}
-
 func (x *Mask16s) set(i int, v bool) {
 	if v {
 		if i < 4 {
@@ -3096,12 +3021,6 @@
 	return Int16s{a: x.a, b: x.b}
 }
 
-// Mask32s represents a 128-bit mask vector for 4 int32/uint32/float32 elements.
-type Mask32s struct {
-	_    _simd
-	a, b uint64
-}
-
 func (x *Mask32s) set(i int, v bool) {
 	if v {
 		if i < 2 {
@@ -3134,12 +3053,6 @@
 	return Int32s{a: x.a, b: x.b}
 }
 
-// Mask64s represents a 128-bit mask vector for 2 int64/uint64/float64 elements.
-type Mask64s struct {
-	_    _simd
-	a, b uint64
-}
-
 func (x *Mask64s) set(i int, v bool) {
 	if v {
 		if i == 0 {
diff --git a/src/simd/simd.go b/src/simd/simd_stubs.go
similarity index 93%
rename from src/simd/simd.go
rename to src/simd/simd_stubs.go
index d390e45..6cb5921 100644
--- a/src/simd/simd.go
+++ b/src/simd/simd_stubs.go
@@ -6,17 +6,6 @@
 
 package simd
 
-import "simd/internal/bridge"
-
-// internal SIMD marker, and hard dependence on simd/internal/bridge
-type _simd bridge.ZeroSized
-
-// Int8s represents a vector of 8-bit signed integers.
-type Int8s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadInt8 loads a slice of int8 into an Int8s vector.
 func LoadInt8s([]int8) Int8s
 
@@ -113,12 +102,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Int8s) Xor(y Int8s) Int8s
 
-// Int16s represents a vector of 16-bit signed integers.
-type Int16s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadInt16 loads a slice of int16 into an Int16s vector.
 func LoadInt16s([]int16) Int16s
 
@@ -227,12 +210,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Int16s) Xor(y Int16s) Int16s
 
-// Int32s represents a vector of 32-bit signed integers.
-type Int32s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadInt32 loads a slice of int32 into an Int32s vector.
 func LoadInt32s([]int32) Int32s
 
@@ -338,12 +315,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Int32s) Xor(y Int32s) Int32s
 
-// Int64s represents a vector of 64-bit signed integers.
-type Int64s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadInt64 loads a slice of int64 into an Int64s vector.
 func LoadInt64s([]int64) Int64s
 
@@ -431,12 +402,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Int64s) Xor(y Int64s) Int64s
 
-// Uint8s represents a vector of 8-bit unsigned integers.
-type Uint8s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadUint8 loads a slice of uint8 into an Uint8s vector.
 func LoadUint8s([]uint8) Uint8s
 
@@ -524,12 +489,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Uint8s) Xor(y Uint8s) Uint8s
 
-// Uint16s represents a vector of 16-bit unsigned integers.
-type Uint16s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadUint16 loads a slice of uint16 into an Uint16s vector.
 func LoadUint16s([]uint16) Uint16s
 
@@ -641,12 +600,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Uint16s) Xor(y Uint16s) Uint16s
 
-// Uint32s represents a vector of 32-bit unsigned integers.
-type Uint32s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadUint32 loads a slice of uint32 into an Uint32s vector.
 func LoadUint32s([]uint32) Uint32s
 
@@ -752,12 +705,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Uint32s) Xor(y Uint32s) Uint32s
 
-// Uint64s represents a vector of 64-bit unsigned integers.
-type Uint64s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadUint64 loads a slice of uint64 into an Uint64s vector.
 func LoadUint64s([]uint64) Uint64s
 
@@ -886,12 +833,6 @@
 // Xor returns the bitwise XOR of x and y.
 func (x Uint64s) Xor(y Uint64s) Uint64s
 
-// Float32s represents a vector of 32-bit floating-point numbers.
-type Float32s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadFloat32 loads a slice of float32 into an Float32s vector.
 func LoadFloat32s([]float32) Float32s
 
@@ -973,12 +914,6 @@
 // ToBits reinterprets the vector bits as an unsigned integer vector.
 func (x Float32s) ToBits() Uint32s
 
-// Float64s represents a vector of 64-bit floating-point numbers.
-type Float64s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // LoadFloat64 loads a slice of float64 into an Float64s vector.
 func LoadFloat64s([]float64) Float64s
 
@@ -1057,12 +992,6 @@
 // ToBits reinterprets the vector bits as an unsigned integer vector.
 func (x Float64s) ToBits() Uint64s
 
-// Mask8s represents a boolean mask for Int8s/Uint8s vectors.
-type Mask8s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // And returns the bitwise AND of x and y.
 func (x Mask8s) And(y Mask8s) Mask8s
 
@@ -1075,12 +1004,6 @@
 // ToInt8s converts the mask to an Int8s vector.
 func (x Mask8s) ToInt8s() (to Int8s)
 
-// Mask16s represents a boolean mask for Int16s/Uint16s vectors.
-type Mask16s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // And returns the bitwise AND of x and y.
 func (x Mask16s) And(y Mask16s) Mask16s
 
@@ -1093,12 +1016,6 @@
 // ToInt16s converts the mask to an Int16s vector.
 func (x Mask16s) ToInt16s() (to Int16s)
 
-// Mask32s represents a boolean mask for Int32s/Uint32s vectors.
-type Mask32s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // And returns the bitwise AND of x and y.
 func (x Mask32s) And(y Mask32s) Mask32s
 
@@ -1111,12 +1028,6 @@
 // ToInt32s converts the mask to an Int32s vector.
 func (x Mask32s) ToInt32s() (to Int32s)
 
-// Mask64s represents a boolean mask for Int64s/Uint64s vectors.
-type Mask64s struct {
-	_       _simd
-	atLeast [2]uint64 // the actual vector size may be larger.
-}
-
 // And returns the bitwise AND of x and y.
 func (x Mask64s) And(y Mask64s) Mask64s
 
diff --git a/src/simd/simd_types.go b/src/simd/simd_types.go
new file mode 100644
index 0000000..fccaa2a
--- /dev/null
+++ b/src/simd/simd_types.go
@@ -0,0 +1,96 @@
+// Code generated by 'go run -C $GOROOT/src/simd/archsimd/_gen/midway'; DO NOT EDIT.
+
+//go:build goexperiment.simd
+
+// Scalable vector types for rewriting and emulation
+
+package simd
+
+import "simd/internal/bridge"
+
+// internal SIMD marker, and hard dependence on simd/internal/bridge
+type _simd bridge.ZeroSized
+
+// Int8s represents a vector of 8-bit signed integers.
+type Int8s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Int16s represents a vector of 16-bit signed integers.
+type Int16s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Int32s represents a vector of 32-bit signed integers.
+type Int32s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Int64s represents a vector of 64-bit signed integers.
+type Int64s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Uint8s represents a vector of 8-bit unsigned integers.
+type Uint8s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Uint16s represents a vector of 16-bit unsigned integers.
+type Uint16s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Uint32s represents a vector of 32-bit unsigned integers.
+type Uint32s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Uint64s represents a vector of 64-bit unsigned integers.
+type Uint64s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Float32s represents a vector of 32-bit floating-point numbers.
+type Float32s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Float64s represents a vector of 64-bit floating-point numbers.
+type Float64s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Mask8s represents a boolean mask for Int8s/Uint8s vectors.
+type Mask8s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Mask16s represents a boolean mask for Int16s/Uint16s vectors.
+type Mask16s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Mask32s represents a boolean mask for Int32s/Uint32s vectors.
+type Mask32s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}
+
+// Mask64s represents a boolean mask for Int64s/Uint64s vectors.
+type Mask64s struct {
+	_    _simd
+	a, b uint64 // the actual vector size may be larger.
+}