Source file src/simd/archsimd/_gen/specgen/specexpr/shape.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 specexpr
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  )
    11  
    12  // MinWidth is the minimum vector width, in bits.
    13  const MinWidth = Int(128)
    14  
    15  type Type interface {
    16  	isType()
    17  	String() string
    18  }
    19  
    20  type Basic struct {
    21  	Base string // "int", "uint", "float", "Mask", etc
    22  	Bits Int    // 0 if unsized, otherwise >= 8
    23  }
    24  
    25  var MakeBasic = MakeFunc2("Basic", func(base string, bits Int) (any, error) {
    26  	// Perform width rounding.
    27  	bits = max(8, bits)
    28  	return Basic{Base: base, Bits: bits}, nil
    29  })
    30  
    31  func (t Basic) isType() {}
    32  func (t Basic) String() string {
    33  	if t.Bits == 0 {
    34  		return t.Base
    35  	}
    36  	return fmt.Sprintf("%s%d", t.Base, t.Bits)
    37  }
    38  
    39  type Vector struct {
    40  	Elem  Basic // Must have Bits != 0
    41  	Width Num   // Bit width
    42  }
    43  
    44  var MakeVector = MakeFunc2("VectorW", func(elem Basic, w Num) (any, error) {
    45  	if !w.ValidWidth() {
    46  		return nil, fmt.Errorf("invalid width %s", w)
    47  	}
    48  	return Vector{Elem: elem, Width: w}, nil
    49  })
    50  
    51  var makeVectorL = MakeFunc2("VectorL", func(elem Basic, l Num) (any, error) {
    52  	w, _ := l.Mul(elem.Bits)
    53  	if w2, ok := w.(Int); ok {
    54  		// Perform width rounding
    55  		w = max(MinWidth, w2)
    56  	}
    57  	if !w.ValidWidth() {
    58  		return nil, fmt.Errorf("invalid width %s", w)
    59  	}
    60  	return Vector{Elem: elem, Width: w}, nil
    61  })
    62  
    63  func (t Vector) isType() {}
    64  func (t Vector) String() string {
    65  	var buf strings.Builder
    66  	if t.Elem.Base == "" {
    67  		buf.WriteString("<bad Elem>")
    68  	} else {
    69  		buf.WriteString(strings.ToTitle(t.Elem.Base[:1]))
    70  		buf.WriteString(t.Elem.Base[1:])
    71  		fmt.Fprintf(&buf, "%d", t.Elem.Bits)
    72  	}
    73  	if t.Scalable() {
    74  		buf.WriteString("s")
    75  	} else {
    76  		l, err := t.Width.Div(t.Elem.Bits)
    77  		if err == nil {
    78  			fmt.Fprintf(&buf, "x%d", l)
    79  		} else {
    80  			// Bad width, but we can print it anyway
    81  			fmt.Fprintf(&buf, "w%s", t.Width)
    82  		}
    83  	}
    84  	return buf.String()
    85  }
    86  func (t Vector) Scalable() bool {
    87  	sw, ok := t.Width.(ScalableWidth)
    88  	return ok && sw.ValidWidth()
    89  }
    90  
    91  type Pointer struct {
    92  	Elem Type
    93  }
    94  
    95  var MakePointer = MakeFunc1("Pointer", func(elem Type) (any, error) {
    96  	return Pointer{elem}, nil
    97  })
    98  
    99  func (t Pointer) isType() {}
   100  func (t Pointer) String() string {
   101  	return "*" + t.Elem.String()
   102  }
   103  
   104  type Array struct {
   105  	Elem Type
   106  	Len  Int
   107  }
   108  
   109  var MakeArray = MakeFunc2("Array", func(elem Type, len Int) (any, error) {
   110  	return Array{elem, len}, nil
   111  })
   112  
   113  func (t Array) isType() {}
   114  func (t Array) String() string {
   115  	return fmt.Sprintf("[%d]%s", t.Len, t.Elem)
   116  }
   117  
   118  type Slice struct {
   119  	Elem Type
   120  }
   121  
   122  var MakeSlice = MakeFunc1("Slice", func(elem Type) (any, error) {
   123  	return Slice{elem}, nil
   124  })
   125  
   126  func (t Slice) isType() {}
   127  func (t Slice) String() string {
   128  	return "[]" + t.Elem.String()
   129  }
   130  

View as plain text