1
0
mirror of https://github.com/golang/go synced 2024-11-19 11:14:47 -07:00

cmd/compile: remove amd64 code from package gc and the core gen tool

Parts of the SSA compiler in package gc contain amd64-specific code,
most notably Prog generation. Move this code into package amd64, so that
other architectures can be added more easily.

In package gc, this change is just moving code. There are no functional
changes or even any larger structural changes beyond changing function
names (mostly for export).

In the cmd/compile/internal/ssa/gen tool, more information is included
in arch to remove the AMD64-specific behavior in the main portion of the
tool. The generated opGen.go is identical.

Change-Id: I8eb37c6e6df6de1b65fa7dab6f3bc32c29daf643
Reviewed-on: https://go-review.googlesource.com/20609
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Michael Pratt 2016-03-12 14:07:40 -08:00
parent b1a6e07919
commit a4e31d42ee
10 changed files with 1319 additions and 1251 deletions

View File

@ -110,6 +110,11 @@ func Main() {
gc.Thearch.Doregbits = doregbits gc.Thearch.Doregbits = doregbits
gc.Thearch.Regnames = regnames gc.Thearch.Regnames = regnames
gc.Thearch.SSARegToReg = ssaRegToReg
gc.Thearch.SSAMarkMoves = ssaMarkMoves
gc.Thearch.SSAGenValue = ssaGenValue
gc.Thearch.SSAGenBlock = ssaGenBlock
gc.Main() gc.Main()
gc.Exit(0) gc.Exit(0)
} }

File diff suppressed because it is too large Load Diff

View File

@ -868,10 +868,10 @@ func gen(n *Node) {
Cgen_checknil(n.Left) Cgen_checknil(n.Left)
case OVARKILL: case OVARKILL:
gvarkill(n.Left) Gvarkill(n.Left)
case OVARLIVE: case OVARLIVE:
gvarlive(n.Left) Gvarlive(n.Left)
} }
ret: ret:

View File

@ -6,6 +6,7 @@ package gc
import ( import (
"bytes" "bytes"
"cmd/compile/internal/ssa"
"cmd/internal/obj" "cmd/internal/obj"
) )
@ -561,6 +562,19 @@ type Arch struct {
Doregbits func(int) uint64 Doregbits func(int) uint64
Regnames func(*int) []string Regnames func(*int) []string
Use387 bool // should 8g use 387 FP instructions instead of sse2. Use387 bool // should 8g use 387 FP instructions instead of sse2.
// SSARegToReg maps ssa register numbers to obj register numbers.
SSARegToReg []int16
// SSAMarkMoves marks any MOVXconst ops that need to avoid clobbering flags.
SSAMarkMoves func(*SSAGenState, *ssa.Block)
// SSAGenValue emits Prog(s) for the Value.
SSAGenValue func(*SSAGenState, *ssa.Value)
// SSAGenBlock emits end-of-block Progs. SSAGenValue should be called
// for all values in the block before SSAGenBlock.
SSAGenBlock func(s *SSAGenState, b, next *ssa.Block)
} }
var pcloc int32 var pcloc int32

View File

@ -108,11 +108,11 @@ func Gvardef(n *Node) {
gvardefx(n, obj.AVARDEF) gvardefx(n, obj.AVARDEF)
} }
func gvarkill(n *Node) { func Gvarkill(n *Node) {
gvardefx(n, obj.AVARKILL) gvardefx(n, obj.AVARKILL)
} }
func gvarlive(n *Node) { func Gvarlive(n *Node) {
gvardefx(n, obj.AVARLIVE) gvardefx(n, obj.AVARLIVE)
} }

File diff suppressed because it is too large Load Diff

View File

@ -531,5 +531,12 @@ func init() {
{name: "NAN"}, // FP, unordered comparison (parity one) {name: "NAN"}, // FP, unordered comparison (parity one)
} }
archs = append(archs, arch{"AMD64", AMD64ops, AMD64blocks, regNamesAMD64}) archs = append(archs, arch{
name: "AMD64",
pkg: "cmd/internal/obj/x86",
genfile: "../../amd64/ssa.go",
ops: AMD64ops,
blocks: AMD64blocks,
regnames: regNamesAMD64,
})
} }

View File

@ -9,5 +9,9 @@ var decOps = []opData{}
var decBlocks = []blockData{} var decBlocks = []blockData{}
func init() { func init() {
archs = append(archs, arch{"dec", decOps, decBlocks, nil}) archs = append(archs, arch{
name: "dec",
ops: decOps,
blocks: decBlocks,
})
} }

View File

@ -413,5 +413,9 @@ var genericBlocks = []blockData{
} }
func init() { func init() {
archs = append(archs, arch{"generic", genericOps, genericBlocks, nil}) archs = append(archs, arch{
name: "generic",
ops: genericOps,
blocks: genericBlocks,
})
} }

View File

@ -14,12 +14,15 @@ import (
"go/format" "go/format"
"io/ioutil" "io/ioutil"
"log" "log"
"path"
"regexp" "regexp"
"sort" "sort"
) )
type arch struct { type arch struct {
name string name string
pkg string // obj package to import for this arch.
genfile string // source file containing opcode code generation.
ops []opData ops []opData
blocks []blockData blocks []blockData
regnames []string regnames []string
@ -81,7 +84,11 @@ func genOp() {
fmt.Fprintln(w, "import (") fmt.Fprintln(w, "import (")
fmt.Fprintln(w, "\"cmd/internal/obj\"") fmt.Fprintln(w, "\"cmd/internal/obj\"")
fmt.Fprintln(w, "\"cmd/internal/obj/x86\"") for _, a := range archs {
if a.pkg != "" {
fmt.Fprintf(w, "%q\n", a.pkg)
}
}
fmt.Fprintln(w, ")") fmt.Fprintln(w, ")")
// generate Block* declarations // generate Block* declarations
@ -123,6 +130,8 @@ func genOp() {
fmt.Fprintln(w, " { name: \"OpInvalid\" },") fmt.Fprintln(w, " { name: \"OpInvalid\" },")
for _, a := range archs { for _, a := range archs {
fmt.Fprintln(w) fmt.Fprintln(w)
pkg := path.Base(a.pkg)
for _, v := range a.ops { for _, v := range a.ops {
fmt.Fprintln(w, "{") fmt.Fprintln(w, "{")
fmt.Fprintf(w, "name:\"%s\",\n", v.name) fmt.Fprintf(w, "name:\"%s\",\n", v.name)
@ -152,7 +161,7 @@ func genOp() {
continue continue
} }
if v.asm != "" { if v.asm != "" {
fmt.Fprintf(w, "asm: x86.A%s,\n", v.asm) fmt.Fprintf(w, "asm: %s.A%s,\n", pkg, v.asm)
} }
fmt.Fprintln(w, "reg:regInfo{") fmt.Fprintln(w, "reg:regInfo{")
@ -210,24 +219,26 @@ func genOp() {
log.Fatalf("can't write output: %v\n", err) log.Fatalf("can't write output: %v\n", err)
} }
// Check that ../gc/ssa.go handles all the arch-specific opcodes. // Check that the arch genfile handles all the arch-specific opcodes.
// This is very much a hack, but it is better than nothing. // This is very much a hack, but it is better than nothing.
ssa, err := ioutil.ReadFile("../../gc/ssa.go")
if err != nil {
log.Fatalf("can't read ../../gc/ssa.go: %v", err)
}
for _, a := range archs { for _, a := range archs {
if a.name == "generic" { if a.genfile == "" {
continue continue
} }
src, err := ioutil.ReadFile(a.genfile)
if err != nil {
log.Fatalf("can't read %s: %v", a.genfile, err)
}
for _, v := range a.ops { for _, v := range a.ops {
pattern := fmt.Sprintf("\\Wssa[.]Op%s%s\\W", a.name, v.name) pattern := fmt.Sprintf("\\Wssa[.]Op%s%s\\W", a.name, v.name)
match, err := regexp.Match(pattern, ssa) match, err := regexp.Match(pattern, src)
if err != nil { if err != nil {
log.Fatalf("bad opcode regexp %s: %v", pattern, err) log.Fatalf("bad opcode regexp %s: %v", pattern, err)
} }
if !match { if !match {
log.Fatalf("Op%s%s has no code generation in ../../gc/ssa.go", a.name, v.name) log.Fatalf("Op%s%s has no code generation in %s", a.name, v.name, a.genfile)
} }
} }
} }