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 defaultXedPath = "$XEDPATH" + string(filepath.ListSeparator) + "./simdgen/xeddata" + string(filepath.ListSeparator) + "$HOME/xed/obj/dgen"
18
19 var (
20 flagTmplgen = flag.Bool("tmplgen", true, "run tmplgen generator")
21 flagSimdgen = flag.Bool("simdgen", true, "run simdgen generator")
22
23 flagN = flag.Bool("n", false, "dry run")
24 flagXedPath = flag.String("xedPath", defaultXedPath, "load XED datafile from `path`, which must be the XED obj/dgen directory")
25 )
26
27 var goRoot string
28
29 func main() {
30 flag.Parse()
31 if flag.NArg() > 0 {
32 flag.Usage()
33 os.Exit(1)
34 }
35
36 if *flagXedPath == defaultXedPath {
37
38
39 *flagXedPath = os.ExpandEnv(defaultXedPath)
40 }
41
42 var err error
43 goRoot, err = resolveGOROOT()
44 if err != nil {
45 fmt.Fprintln(os.Stderr, err)
46 os.Exit(1)
47 }
48
49 if *flagTmplgen {
50 doTmplgen()
51 }
52 if *flagSimdgen {
53 doSimdgen()
54 }
55 }
56
57 func doTmplgen() {
58 goRun("-C", "tmplgen", ".")
59 }
60
61 func doSimdgen() {
62 xedPath, err := resolveXEDPath(*flagXedPath)
63 if err != nil {
64 fmt.Fprintln(os.Stderr, err)
65 os.Exit(1)
66 }
67
68
69 goRun("-C", "simdgen", ".", "-o", "godefs", "-goroot", goRoot, "-xedPath", prettyPath("./simdgen", xedPath), "go.yaml", "types.yaml", "categories.yaml")
70
71
72 goRun("-C", prettyPath(".", filepath.Join(goRoot, "src", "cmd", "compile", "internal", "ssa", "_gen")), ".")
73 }
74
75 func resolveXEDPath(pathList string) (xedPath string, err error) {
76 for _, path := range filepath.SplitList(pathList) {
77 if path == "" {
78
79 continue
80 }
81 if _, err := os.Stat(filepath.Join(path, "all-dec-instructions.txt")); err == nil {
82 return filepath.Abs(path)
83 }
84 }
85 return "", fmt.Errorf("set $XEDPATH or -xedPath to the XED obj/dgen directory")
86 }
87
88 func resolveGOROOT() (goRoot string, err error) {
89 cmd := exec.Command("go", "env", "GOROOT")
90 cmd.Stderr = os.Stderr
91 out, err := cmd.Output()
92 if err != nil {
93 return "", fmt.Errorf("%s: %s", cmd, err)
94 }
95 goRoot = strings.TrimSuffix(string(out), "\n")
96 return goRoot, nil
97 }
98
99 func goRun(args ...string) {
100 exe := filepath.Join(goRoot, "bin", "go")
101 cmd := exec.Command(exe, append([]string{"run"}, args...)...)
102 run(cmd)
103 }
104
105 func run(cmd *exec.Cmd) {
106 cmd.Stdout = os.Stdout
107 cmd.Stderr = os.Stderr
108 fmt.Fprintf(os.Stderr, "%s\n", cmdString(cmd))
109 if *flagN {
110 return
111 }
112 if err := cmd.Run(); err != nil {
113 fmt.Fprintf(os.Stderr, "%s failed: %s\n", cmd, err)
114 }
115 }
116
117 func prettyPath(base, path string) string {
118 base, err := filepath.Abs(base)
119 if err != nil {
120 return path
121 }
122 p, err := filepath.Rel(base, path)
123 if err != nil {
124 return path
125 }
126 return p
127 }
128
129 func cmdString(cmd *exec.Cmd) string {
130
131
132
133 var buf strings.Builder
134
135 cmdPath, err := exec.LookPath(filepath.Base(cmd.Path))
136 if err == nil && cmdPath == cmd.Path {
137 cmdPath = filepath.Base(cmdPath)
138 } else {
139 cmdPath = prettyPath(".", cmd.Path)
140 }
141 buf.WriteString(cmdPath)
142
143 for _, arg := range cmd.Args[1:] {
144 buf.WriteByte(' ')
145 buf.WriteString(arg)
146 }
147
148 return buf.String()
149 }
150
View as plain text