blob: b1b5d5e7ba5869428fddff627a36378debf7d417 [file] [log] [blame]
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"bytes"
"fmt"
"strconv"
"strings"
)
/*
* Helpers for building cmd/gc.
*/
// gcopnames creates opnames.h from go.h.
// It finds the OXXX enum, pulls out all the constants
// from OXXX to OEND, and writes a table mapping
// op to string.
func gcopnames(dir, file string) {
var out bytes.Buffer
fmt.Fprintf(&out, "// auto generated by go tool dist\n")
fmt.Fprintf(&out, "static char *opnames[] = {\n")
in := readfile(pathf("%s/go.h", dir))
lines := splitlines(in)
i := 0
for i < len(lines) && !strings.Contains(lines[i], "OXXX") {
i++
}
for _, line := range lines[i:] {
if i := strings.Index(line, "//"); i >= 0 {
line = line[:i]
}
for _, field := range splitfields(line) {
field = strings.TrimPrefix(field, "O")
field = strings.TrimSuffix(field, ",")
fmt.Fprintf(&out, "\t[O%s] = \"%s\",\n", field, field)
}
if strings.Contains(line, "OEND") {
break
}
}
fmt.Fprintf(&out, "};\n")
writefile(out.String(), file, 0)
}
// mkanames reads [5689].out.h and writes anames[5689].c
// The format is much the same as the Go opcodes above.
// It also writes out cnames array for C_* constants and the dnames
// array for D_* constants.
func mkanames(dir, file string) {
ch := file[len(file)-3]
targ := pathf("%s/../cmd/%cl/%c.out.h", dir, ch, ch)
in := readfile(targ)
lines := splitlines(in)
// Include link.h so that the extern declaration there is
// checked against the non-extern declaration we are generating.
var out bytes.Buffer
fmt.Fprintf(&out, "// auto generated by go tool dist\n")
fmt.Fprintf(&out, "#include <u.h>\n")
fmt.Fprintf(&out, "#include <libc.h>\n")
fmt.Fprintf(&out, "#include <bio.h>\n")
fmt.Fprintf(&out, "#include <link.h>\n")
fmt.Fprintf(&out, "#include \"../cmd/%cl/%c.out.h\"\n", ch, ch)
fmt.Fprintf(&out, "\n")
fmt.Fprintf(&out, "char* anames%c[] = {\n", ch)
for _, line := range lines {
if strings.HasPrefix(line, "\tA") {
if i := strings.Index(line, ","); i >= 0 {
line = line[:i]
}
if i := strings.Index(line, "\n"); i >= 0 {
line = line[:i]
}
line = line[2:]
fmt.Fprintf(&out, "\t\"%s\",\n", line)
}
}
fmt.Fprintf(&out, "};\n")
j := 0
var out2 bytes.Buffer
fmt.Fprintf(&out2, "char* cnames%c[] = {\n", ch)
for _, line := range lines {
if strings.HasPrefix(line, "\tC_") {
if i := strings.Index(line, ","); i >= 0 {
line = line[:i]
}
if i := strings.Index(line, "\n"); i >= 0 {
line = line[:i]
}
line = line[3:]
fmt.Fprintf(&out2, "\t\"%s\",\n", line)
j++
}
}
fmt.Fprintf(&out2, "};\n")
if j > 0 {
out.Write(out2.Bytes())
}
var dnames [128][]string
j = 0
unknown := false
n := -1
for _, line := range lines {
if strings.HasPrefix(line, "\tD_") {
if i := strings.Index(line, ","); i >= 0 {
line = line[:i]
}
// Parse explicit value, if any
if i := strings.Index(line, "="); i >= 0 {
value := strings.TrimSpace(line[i+1:])
line = strings.TrimSpace(line[:i])
var err error
n, err = strconv.Atoi(value)
if err != nil {
// We can't do anything about
// non-numeric values or anything that
// follows.
unknown = true
continue
}
unknown = false
} else {
n++
}
if unknown || n < 0 || n >= len(dnames) {
continue
}
line = strings.TrimSpace(line)
line = line[len("D_"):]
if strings.Contains(line, "LAST") {
continue
}
dnames[n] = append(dnames[n], line)
j++
}
}
if j > 0 {
fmt.Fprintf(&out, "char* dnames%c[D_LAST] = {\n", ch)
for _, d := range dnames {
if len(d) == 0 {
continue
}
fmt.Fprintf(&out, "\t[D_%s] = \"", d[0])
for k, name := range d {
if k > 0 {
fmt.Fprintf(&out, "/")
}
fmt.Fprintf(&out, "%s", name)
}
fmt.Fprintf(&out, "\",\n")
}
fmt.Fprintf(&out, "};\n")
}
writefile(out.String(), file, 0)
}