Commit a4e31d42 authored by Michael Pratt's avatar Michael Pratt

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/20609Reviewed-by: 's avatarKeith Randall <khr@golang.org>
Reviewed-by: 's avatarMichael Pratt <mpratt@google.com>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent b1a6e079
...@@ -110,6 +110,11 @@ func Main() { ...@@ -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)
} }
This diff is collapsed.
...@@ -868,10 +868,10 @@ func gen(n *Node) { ...@@ -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:
......
...@@ -6,6 +6,7 @@ package gc ...@@ -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 { ...@@ -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
......
...@@ -108,11 +108,11 @@ func Gvardef(n *Node) { ...@@ -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)
} }
......
This diff is collapsed.
...@@ -531,5 +531,12 @@ func init() { ...@@ -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,
})
} }
...@@ -9,5 +9,9 @@ var decOps = []opData{} ...@@ -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,
})
} }
...@@ -413,5 +413,9 @@ var genericBlocks = []blockData{ ...@@ -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,
})
} }
...@@ -14,12 +14,15 @@ import ( ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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() { ...@@ -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)
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment