mirror of
https://github.com/golang/go
synced 2024-11-19 12:04:43 -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:
parent
b1a6e07919
commit
a4e31d42ee
@ -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)
|
||||||
}
|
}
|
||||||
|
1208
src/cmd/compile/internal/amd64/ssa.go
Normal file
1208
src/cmd/compile/internal/amd64/ssa.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -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
|
|||||||
|
|
||||||
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
|
||||||
|
@ -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
@ -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{}
|
|||||||
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{
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 (
|
|||||||
"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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user