1
2
3
4
5
6
7
8
9
10
11
12
13
14 package sgutil
15
16 import (
17 "fmt"
18 "io"
19 "sort"
20 "text/template"
21 )
22
23 const simdGenericOpsTmpl = `package main
24
25 func init() {
26 additionalGenericOps["{{.ArchKey}}"] = []opData{
27 {{- range .Ops }}
28 {name: "{{.OpName}}", argLength: {{.OpInLen}}{{if .Comm}}, commutative: true{{end}}{{if .HasAux}}, aux: "UInt8"{{end}}},
29 {{- end }}
30 }
31 }
32 `
33
34
35 func TemplateNamed(name, temp string) *template.Template {
36 t, err := template.New(name).Parse(temp)
37 if err != nil {
38 panic(fmt.Errorf("failed to parse template %s: %w", name, err))
39 }
40 return t
41 }
42
43
44 type GenericOpsData struct {
45 OpName string
46 OpInLen int
47 Comm bool
48 HasAux bool
49 }
50
51
52 func WriteSIMDGenericOps(w io.Writer, ops []GenericOpsData, archKey string) {
53 sort.Slice(ops, func(i, j int) bool {
54 return CompareNatural(ops[i].OpName, ops[j].OpName) < 0
55 })
56
57 var deduped []GenericOpsData
58 for _, op := range ops {
59 if len(deduped) > 0 && deduped[len(deduped)-1].OpName == op.OpName {
60 if deduped[len(deduped)-1].OpInLen != op.OpInLen ||
61 deduped[len(deduped)-1].Comm != op.Comm ||
62 deduped[len(deduped)-1].HasAux != op.HasAux {
63 panic(fmt.Sprintf("conflicting generic op definition for %s", op.OpName))
64 }
65 continue
66 }
67 deduped = append(deduped, op)
68 }
69
70 type templateData struct {
71 Header string
72 ArchKey string
73 Ops []GenericOpsData
74 }
75
76 t := TemplateNamed("simdgenericOps", simdGenericOpsTmpl)
77 err := t.Execute(w, templateData{
78 ArchKey: archKey,
79 Ops: deduped,
80 })
81 if err != nil {
82 panic(fmt.Errorf("failed to execute template: %w", err))
83 }
84 }
85
View as plain text