golang.org/x/arch@v0.17.0/internal/simdgen/godefs.go (about) 1 // Copyright 2025 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 main 6 7 import ( 8 "fmt" 9 "io" 10 "log" 11 12 "golang.org/x/arch/internal/unify" 13 ) 14 15 type Operation struct { 16 Go string // Go method name 17 Category *string // General operation category (optional) 18 19 GoArch string // GOARCH for this definition 20 Asm string // Assembly mnemonic 21 22 In []Operand // Arguments 23 Out []Operand // Results 24 } 25 26 type Operand struct { 27 Go string // Go type of this operand 28 AsmPos int // Position of this operand in the assembly instruction 29 30 Base string // Base Go type ("int", "uint", "float") 31 Bits int // Element bit width 32 W int // Total vector bit width 33 } 34 35 func writeGoDefs(w io.Writer, cl unify.Closure) { 36 // TODO: Merge operations with the same signature but multiple 37 // implementations (e.g., SSE vs AVX) 38 39 // TODO: This code is embarrassing, but I'm very tired. 40 41 var op Operation 42 for def := range cl.All() { 43 if !def.Exact() { 44 continue 45 } 46 if err := def.Decode(&op); err != nil { 47 log.Println(err.Error()) 48 continue 49 } 50 51 fmt.Fprintf(w, "func (x %s) %s(", op.In[0].Go, op.Go) 52 for i, arg := range op.In[1:] { 53 if i > 0 { 54 fmt.Fprint(w, ", ") 55 } 56 fmt.Fprintf(w, "%c %s", 'y'+i, arg.Go) 57 } 58 fmt.Fprintf(w, ") (") 59 for i, res := range op.Out { 60 if i > 0 { 61 fmt.Fprint(w, ", ") 62 } 63 fmt.Fprintf(w, "%c %s", 'o'+i, res.Go) 64 } 65 fmt.Fprintf(w, ") {\n") 66 67 asmPosToArg := make(map[int]byte) 68 asmPosToRes := make(map[int]byte) 69 for i, arg := range op.In { 70 asmPosToArg[arg.AsmPos] = 'x' + byte(i) 71 } 72 for i, res := range op.Out { 73 asmPosToRes[res.AsmPos] = 'o' + byte(i) 74 } 75 fmt.Fprintf(w, "\t// %s", op.Asm) 76 for i := 0; ; i++ { 77 arg, okArg := asmPosToArg[i] 78 if okArg { 79 fmt.Fprintf(w, " %c", arg) 80 } 81 res, okRes := asmPosToRes[i] 82 if okRes { 83 if okArg { 84 fmt.Fprintf(w, "/") 85 } else { 86 fmt.Fprintf(w, " ") 87 } 88 fmt.Fprintf(w, "%c", res) 89 } 90 if !okArg && !okRes { 91 break 92 } 93 } 94 fmt.Fprintf(w, "\n") 95 96 fmt.Fprintf(w, "}\n") 97 } 98 }