blob: b59aa5b5a472cb551338a2c71ceea475a580293e [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"
"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.
func mkanames(dir, file string) {
ch := file[len(file)-3]
targ := pathf("%s/../cmd/%cl/%c.out.h", dir, ch, ch)
in := readfile(pathf("%s/../../include/link.h", dir)) + 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 {
// Use all A names found in the headers,
// except don't use A_ARCHSPECIFIC (left to arch to define),
// and don't use any aliases (= A...),
// except do use the arch-defined alias for A_ARCHSPECIFIC.
if strings.Contains(line, ";") {
continue
}
if strings.HasPrefix(line, "\tA") && !strings.Contains(line, "\tA_") && (!strings.Contains(line, "= A") || strings.Contains(line, "= A_ARCHSPECIFIC")) {
if i := strings.Index(line, ","); i >= 0 {
line = line[:i]
}
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", strings.TrimSpace(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())
}
writefile(out.String(), file, 0)
}