1
2
3
4
5
6 package main
7
8 import (
9 "flag"
10 "fmt"
11 "os"
12 "os/exec"
13 "path/filepath"
14 "strings"
15 )
16
17 const defaultLocalISA = "ISA_A64_xml_A_profile-2026-03_96/ISA_A64_xml_A_profile_2026-03_96-2026-03_rel"
18 const defaultXedPath = "$XEDPATH" + string(filepath.ListSeparator) + "./simdgen/xeddata" + string(filepath.ListSeparator) + "$HOME/xed/obj/dgen"
19 const defaultArm64Path = "$ARM64_ISA_PATH" + string(filepath.ListSeparator) + "./simdgen/armdata" + string(filepath.ListSeparator) + "$HOME/Downloads/" + defaultLocalISA
20
21 var (
22 flagTmplgen = flag.Bool("tmplgen", true, "run tmplgen generator")
23 flagSimdgen = flag.Bool("simdgen", true, "run simdgen generator")
24 flagWasmgen = flag.Bool("wasmgen", true, "run wasmgen generator")
25 flagMidway = flag.Bool("midway", true, "run midway generator")
26
27 flagN = flag.Bool("n", false, "dry run")
28 flagXedPath = flag.String("xedPath", defaultXedPath, "load XED datafile from `path`, which must be the XED obj/dgen directory")
29 flagArm64Path = flag.String("arm64Path", defaultArm64Path, "load ARM64 ISA XML definitions from `path`")
30
31 flagGoRoot = flag.String("goroot", "", "destination go dev tree for generated files")
32 )
33
34 var goRoot string
35
36 func main() {
37 flag.Parse()
38 if flag.NArg() > 0 {
39 flag.Usage()
40 os.Exit(1)
41 }
42
43 if *flagXedPath == defaultXedPath {
44
45
46 *flagXedPath = os.ExpandEnv(defaultXedPath)
47 }
48
49 if *flagArm64Path == defaultArm64Path {
50
51
52 *flagArm64Path = os.ExpandEnv(defaultArm64Path)
53 }
54
55 var err error
56 goRoot, err = resolveGOROOT()
57 if err != nil {
58 fmt.Fprintln(os.Stderr, err)
59 os.Exit(1)
60 }
61
62 if *flagSimdgen {
63 fmt.Fprintln(os.Stderr, "# This may take a few minutes...")
64 }
65
66 if *flagTmplgen {
67 doTmplgen()
68 }
69
70 if *flagWasmgen || *flagSimdgen {
71 ssaGenPath := prettyPath(".", filepath.Join(goRoot, "src", "cmd", "compile", "internal", "ssa", "_gen"))
72
73
74 removeSimdGenericOps(ssaGenPath)
75
76 if *flagWasmgen {
77 doWasmgen()
78 }
79 if *flagSimdgen {
80 doSimdgen()
81 }
82 ssaGen(ssaGenPath)
83 }
84
85 if *flagMidway {
86 doMidway()
87 }
88 }
89
90 func removeSimdGenericOps(ssaGenPath string) {
91 ssaSimdGenericOps := filepath.Join(ssaGenPath, "simdgenericOps.go")
92 if _, err := os.Stat(ssaSimdGenericOps); err == nil {
93 if err = os.Remove(ssaSimdGenericOps); err != nil {
94 fmt.Fprintf(os.Stderr, "Failed to delete %s before regenerating it, %v\n", ssaSimdGenericOps, err)
95 os.Exit(1)
96 }
97 }
98 }
99
100 func ssaGen(ssaGenPath string) {
101
102 goRun("-C", ssaGenPath, ".")
103
104 fmt.Fprintln(os.Stderr, "# Compiler changed. Consider running \"go install cmd/compile\"")
105 }
106
107 func doTmplgen() {
108 goRun("-C", "tmplgen", ".")
109 }
110
111 func doWasmgen() {
112 goRun("-C", "wasmgen", ".")
113 }
114
115 func doMidway() {
116 goRun("-C", "midway", ".")
117 }
118
119 func doSimdgen() {
120 xedPath, err := resolveXEDPath(*flagXedPath)
121 if err != nil {
122 fmt.Fprintln(os.Stderr, err)
123 os.Exit(1)
124 }
125
126 armPath, err := resolveARMPath(*flagArm64Path)
127 if err != nil {
128 fmt.Fprintln(os.Stderr, err)
129 os.Exit(1)
130 }
131
132 goRun("-C", "simdgen", ".", "-o", "godefs", "-goroot", goRoot, "-arch", "arm64", "-arm64Path", prettyPath("./simdgen", armPath), "go_arm64.yaml", "types.yaml", "categories.yaml")
133
134
135 goRun("-C", "simdgen", ".", "-o", "godefs", "-goroot", goRoot, "-arch", "amd64", "-xedPath", prettyPath("./simdgen", xedPath), "go_amd64.yaml", "types.yaml", "categories.yaml")
136 }
137
138
139
140 func resolveXEDPath(pathList string) (xedPath string, err error) {
141 for _, path := range filepath.SplitList(pathList) {
142 if path == "" {
143
144 continue
145 }
146 if _, err := os.Stat(filepath.Join(path, "all-dec-instructions.txt")); err == nil {
147 return filepath.Abs(path)
148 }
149 }
150 return "", fmt.Errorf("set $XEDPATH or -xedPath to the XED obj/dgen directory")
151 }
152
153 func resolveARMPath(pathList string) (armPath string, err error) {
154 for _, path := range filepath.SplitList(pathList) {
155 if path == "" {
156
157 continue
158 }
159 if _, err := os.Stat(filepath.Join(path, "abs_advsimd.xml")); err == nil {
160 return filepath.Abs(path)
161 }
162 }
163 return "", fmt.Errorf("set $ARM64_ISA_PATH or -armPath to the ARM64 ISA specification directory")
164 }
165
166 func resolveGOROOT() (goRoot string, err error) {
167 goRoot = *flagGoRoot
168 if goRoot != "" {
169 return
170 }
171
172
173 cwd, err := os.Getwd()
174 if err != nil {
175 return "", fmt.Errorf("Getwd error: %s", err)
176 }
177 goRoot, err = filepath.Abs(filepath.Join(cwd, "..", "..", "..", ".."))
178 if err != nil {
179 return "", fmt.Errorf("Abs path error: %s", err)
180 }
181 _, err = os.Stat(filepath.Join(goRoot, "src", "simd", "archsimd", "_gen"))
182 if err != nil {
183 return "", fmt.Errorf("-goroot not specified and not run in src/simd/archsimd/_gen")
184 }
185
186 return
187 }
188
189 func goRun(args ...string) {
190 exe := "go"
191 cmd := exec.Command(exe, append([]string{"run"}, args...)...)
192 run(cmd)
193 }
194
195 func run(cmd *exec.Cmd) {
196 cmd.Stdout = os.Stdout
197 cmd.Stderr = os.Stderr
198 fmt.Fprintf(os.Stderr, "%s\n", cmdString(cmd))
199 if *flagN {
200 return
201 }
202 if err := cmd.Run(); err != nil {
203 fmt.Fprintf(os.Stderr, "%s failed: %s\n", cmd, err)
204 os.Exit(1)
205 }
206 }
207
208 func prettyPath(base, path string) string {
209 base, err := filepath.Abs(base)
210 if err != nil {
211 return path
212 }
213 p, err := filepath.Rel(base, path)
214 if err != nil {
215 return path
216 }
217 return p
218 }
219
220 func cmdString(cmd *exec.Cmd) string {
221
222
223
224 var buf strings.Builder
225
226 cmdPath, err := exec.LookPath(filepath.Base(cmd.Path))
227 if err == nil && cmdPath == cmd.Path {
228 cmdPath = filepath.Base(cmdPath)
229 } else {
230 cmdPath = prettyPath(".", cmd.Path)
231 }
232 buf.WriteString(cmdPath)
233
234 for _, arg := range cmd.Args[1:] {
235 buf.WriteByte(' ')
236 buf.WriteString(arg)
237 }
238
239 return buf.String()
240 }
241
View as plain text