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  

View as plain text