Source file src/simd/internal/spec/types.go
1 // Copyright 2026 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package spec 6 7 import ( 8 "unsafe" 9 ) 10 11 // Element types 12 13 // Floats is all float element types. 14 type Floats interface { 15 float32 | float64 16 } 17 18 // Ints is all signed int element types. 19 type Ints interface { 20 int8 | int16 | int32 | int64 21 } 22 23 // Uints is all unsigned uint element types. 24 type Uints interface { 25 uint8 | uint16 | uint32 | uint64 26 } 27 28 // Nums is all numeric element types. 29 type Nums interface { 30 Floats | Ints | Uints 31 } 32 33 // Mask element types can be used in a Vec to represent a mask. 34 // 35 // We use uintN types for these so that regular math for element width and lanes 36 // work as expected. In a sense, these act like a "wide mask": logically these 37 // are bool values, represented as either 0 for false or ^0 for true. 38 type ( 39 Mask8 uint8 40 Mask16 uint16 41 Mask32 uint32 42 Mask64 uint64 43 ) 44 45 // MaskElt is all mask element types. In function signatures, these must always 46 // be used as the element to a Vec type. They cannot be standalone. 47 type MaskElt interface { 48 Mask8 | Mask16 | Mask32 | Mask64 49 } 50 51 // Elt is all regular (non-mask) vector element types. 52 type Elt interface { 53 Nums 54 } 55 56 // EltOrMask is a constraint that accepts any regular vector element type or 57 // mask element type. 58 // 59 // This type is known to specgen. 60 type EltOrMask interface { 61 Elt | MaskElt 62 } 63 64 // Widths 65 66 // Width is a constraint that accepts any type representing a vector width. 67 // 68 // This type is known to specgen. 69 type Width interface { 70 Width128 | Width256 | Width512 | WidthScalable 71 bits() int // Minimum is 128 72 } 73 74 // FixedWidth is a constraint for all fixed (non-scalable) vector width types. 75 type FixedWidth interface { 76 Width128 | Width256 | Width512 77 bits() int 78 } 79 80 type Width128 struct{} 81 82 func (Width128) bits() int { return 128 } 83 84 type Width256 struct{} 85 86 func (Width256) bits() int { return 256 } 87 88 type Width512 struct{} 89 90 func (Width512) bits() int { return 512 } 91 92 // scalableWidth is the bit width to use for scalable vectors when executing the 93 // spec. This is intentionally set to be large and different from any hardware 94 // platform we support. 95 // 96 // TODO: For testing against the spec, do we need a way to match this to the 97 // hardware we're testing on? 98 const scalableWidth = 4096 99 100 // WidthScalable is the width representing scalable vectors. At a spec level, 101 // the actual width this represents is completely symbolic, but when executing 102 // the spec, we concretely interpret this as [scalableWidth] bits. 103 // 104 // This type is known to specgen. 105 type WidthScalable struct{} 106 107 func (WidthScalable) bits() int { return scalableWidth } 108 109 // Vectors 110 111 // Vec is a vector or mask consisting of the given element type E expanded out 112 // to W total bits. 113 // 114 // This is implemented as a Go slice, which must have length `width[W]() / elemBits[E]()`. 115 // 116 // This type is known to specgen. 117 type Vec[E EltOrMask, W Width] []E 118 119 func (v Vec[E, W]) len() int { 120 return lanes[E, W]() 121 } 122 123 func makeVec[E EltOrMask, W Width]() Vec[E, W] { 124 return make([]E, lanes[E, W]()) 125 } 126 127 func elemBits[E EltOrMask]() int { 128 return 8 * int(unsafe.Sizeof(*new(E))) 129 } 130 131 func width[W Width]() int { 132 return (*(new(W))).bits() 133 } 134 135 func lanes[E EltOrMask, W Width]() int { 136 return width[W]() / elemBits[E]() 137 } 138 139 // Other types 140 141 // Array represents an array of lanes[E,W]() elements. 142 // 143 // The static generator will translate this to a Go array type. 144 // 145 // This type is known to specgen. 146 type Array[E Elt, W Width] []E 147