var leaptr = x86.ALEAQ
-func Init() {
- gc.Thearch.LinkArch = &x86.Linkamd64
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &x86.Linkamd64
if obj.GOARCH == "amd64p32" {
- gc.Thearch.LinkArch = &x86.Linkamd64p32
+ arch.LinkArch = &x86.Linkamd64p32
leaptr = x86.ALEAL
}
- gc.Thearch.REGSP = x86.REGSP
- gc.Thearch.MAXWIDTH = 1 << 50
+ arch.REGSP = x86.REGSP
+ arch.MAXWIDTH = 1 << 50
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = ssaMarkMoves
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = ssaMarkMoves
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"cmd/internal/obj/arm"
)
-func Init() {
- gc.Thearch.LinkArch = &arm.Linkarm
- gc.Thearch.REGSP = arm.REGSP
- gc.Thearch.MAXWIDTH = (1 << 32) - 1
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &arm.Linkarm
+ arch.REGSP = arm.REGSP
+ arch.MAXWIDTH = (1 << 32) - 1
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"cmd/internal/obj/arm64"
)
-func Init() {
- gc.Thearch.LinkArch = &arm64.Linkarm64
- gc.Thearch.REGSP = arm64.REGSP
- gc.Thearch.MAXWIDTH = 1 << 50
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &arm64.Linkarm64
+ arch.REGSP = arm64.REGSP
+ arch.MAXWIDTH = 1 << 50
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
// Main parses flags and Go source files specified in the command-line
// arguments, type-checks the parsed Go package, compiles functions to machine
// code, and finally writes the compiled package definition to disk.
-func Main() {
+func Main(archInit func(*Arch)) {
timings.Start("fe", "init")
defer hidePanic()
+ archInit(&Thearch)
+
Ctxt = obj.Linknew(Thearch.LinkArch)
Ctxt.DebugInfo = debuginfo
Ctxt.DiagFunc = yyerror
next = f.Blocks[i+1]
}
x := pc
+ s.SetPos(b.Pos)
Thearch.SSAGenBlock(&s, b, next)
if logProgs {
for ; x != pc; x = x.Link {
"cmd/internal/obj/mips"
)
-func Init() {
- gc.Thearch.LinkArch = &mips.Linkmips
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &mips.Linkmips
if obj.GOARCH == "mipsle" {
- gc.Thearch.LinkArch = &mips.Linkmipsle
+ arch.LinkArch = &mips.Linkmipsle
}
- gc.Thearch.REGSP = mips.REGSP
- gc.Thearch.MAXWIDTH = (1 << 31) - 1
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.REGSP = mips.REGSP
+ arch.MAXWIDTH = (1 << 31) - 1
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
+ arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"cmd/internal/obj/mips"
)
-func Init() {
- gc.Thearch.LinkArch = &mips.Linkmips64
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &mips.Linkmips64
if obj.GOARCH == "mips64le" {
- gc.Thearch.LinkArch = &mips.Linkmips64le
+ arch.LinkArch = &mips.Linkmips64le
}
- gc.Thearch.REGSP = mips.REGSP
- gc.Thearch.MAXWIDTH = 1 << 50
+ arch.REGSP = mips.REGSP
+ arch.MAXWIDTH = 1 << 50
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = func(s *gc.SSAGenState, b *ssa.Block) {}
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"cmd/internal/obj/ppc64"
)
-func Init() {
- gc.Thearch.LinkArch = &ppc64.Linkppc64
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &ppc64.Linkppc64
if obj.GOARCH == "ppc64le" {
- gc.Thearch.LinkArch = &ppc64.Linkppc64le
+ arch.LinkArch = &ppc64.Linkppc64le
}
- gc.Thearch.REGSP = ppc64.REGSP
- gc.Thearch.MAXWIDTH = 1 << 50
+ arch.REGSP = ppc64.REGSP
+ arch.MAXWIDTH = 1 << 50
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop2
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop2
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = ssaMarkMoves
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = ssaMarkMoves
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
initvariants()
initproginfo()
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
-
case ssa.BlockDefer:
// defer returns in R3:
// 0 if we should continue executing
"cmd/internal/obj/s390x"
)
-func Init() {
- gc.Thearch.LinkArch = &s390x.Links390x
- gc.Thearch.REGSP = s390x.REGSP
- gc.Thearch.MAXWIDTH = 1 << 50
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &s390x.Links390x
+ arch.REGSP = s390x.REGSP
+ arch.MAXWIDTH = 1 << 50
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = ssaMarkMoves
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = ssaMarkMoves
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
}
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"math"
)
-// Generates code for v using 387 instructions. Reports whether
-// the instruction was handled by this routine.
-func ssaGenValue387(s *gc.SSAGenState, v *ssa.Value) bool {
+// Generates code for v using 387 instructions.
+func ssaGenValue387(s *gc.SSAGenState, v *ssa.Value) {
// The SSA compiler pretends that it has an SSE backend.
// If we don't have one of those, we need to translate
// all the SSE ops to equivalent 387 ops. That's what this
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_F0
popAndSave(s, v)
- return true
+
case ssa.Op386MOVSSconst2, ssa.Op386MOVSDconst2:
p := gc.Prog(loadPush(v.Type))
p.From.Type = obj.TYPE_MEM
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_F0
popAndSave(s, v)
- return true
case ssa.Op386MOVSSload, ssa.Op386MOVSDload, ssa.Op386MOVSSloadidx1, ssa.Op386MOVSDloadidx1, ssa.Op386MOVSSloadidx4, ssa.Op386MOVSDloadidx8:
p := gc.Prog(loadPush(v.Type))
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_F0
popAndSave(s, v)
- return true
case ssa.Op386MOVSSstore, ssa.Op386MOVSDstore:
// Push to-be-stored value on top of stack.
p.To.Type = obj.TYPE_MEM
p.To.Reg = v.Args[0].Reg()
gc.AddAux(&p.To, v)
- return true
case ssa.Op386MOVSSstoreidx1, ssa.Op386MOVSDstoreidx1, ssa.Op386MOVSSstoreidx4, ssa.Op386MOVSDstoreidx8:
push(s, v.Args[2])
p.To.Scale = 8
p.To.Index = v.Args[1].Reg()
}
- return true
case ssa.Op386ADDSS, ssa.Op386ADDSD, ssa.Op386SUBSS, ssa.Op386SUBSD,
ssa.Op386MULSS, ssa.Op386MULSD, ssa.Op386DIVSS, ssa.Op386DIVSD:
s.AddrScratch(&p.From)
}
- return true
-
case ssa.Op386UCOMISS, ssa.Op386UCOMISD:
push(s, v.Args[0])
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_AX
- return true
-
case ssa.Op386SQRTSD:
push(s, v.Args[0])
gc.Prog(x86.AFSQRT)
popAndSave(s, v)
- return true
case ssa.Op386FCHS:
push(s, v.Args[0])
gc.Prog(x86.AFCHS)
popAndSave(s, v)
- return true
case ssa.Op386CVTSL2SS, ssa.Op386CVTSL2SD:
p := gc.Prog(x86.AMOVL)
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_F0
popAndSave(s, v)
- return true
case ssa.Op386CVTTSD2SL, ssa.Op386CVTTSS2SL:
push(s, v.Args[0])
p = gc.Prog(x86.AFLDCW)
s.AddrScratch(&p.From)
p.From.Offset += 4
- return true
case ssa.Op386CVTSS2SD:
// float32 -> float64 is a nop
push(s, v.Args[0])
popAndSave(s, v)
- return true
case ssa.Op386CVTSD2SS:
// Round to nearest float32.
p.To.Type = obj.TYPE_REG
p.To.Reg = x86.REG_F0
popAndSave(s, v)
- return true
case ssa.OpLoadReg:
if !v.Type.IsFloat() {
- return false
+ ssaGenValue(s, v)
+ return
}
// Load+push the value we need.
p := gc.Prog(loadPush(v.Type))
p.To.Reg = x86.REG_F0
// Move the value to its assigned register.
popAndSave(s, v)
- return true
case ssa.OpStoreReg:
if !v.Type.IsFloat() {
- return false
+ ssaGenValue(s, v)
+ return
}
push(s, v.Args[0])
var op obj.As
p.From.Type = obj.TYPE_REG
p.From.Reg = x86.REG_F0
gc.AddrAuto(&p.To, v)
- return true
case ssa.OpCopy:
if !v.Type.IsFloat() {
- return false
+ ssaGenValue(s, v)
+ return
}
push(s, v.Args[0])
popAndSave(s, v)
- return true
case ssa.Op386CALLstatic, ssa.Op386CALLclosure, ssa.Op386CALLinter:
- flush387(s) // Calls must empty the FP stack.
- return false // then issue the call as normal
+ flush387(s) // Calls must empty the FP stack.
+ fallthrough // then issue the call as normal
+ default:
+ ssaGenValue(s, v)
}
- return false
}
// push pushes v onto the floating-point stack. v must be in a register.
delete(s.SSEto387, k)
}
}
+
+func ssaGenBlock387(s *gc.SSAGenState, b, next *ssa.Block) {
+ // Empty the 387's FP stack before the block ends.
+ flush387(s)
+
+ ssaGenBlock(s, b, next)
+}
"os"
)
-func Init() {
- gc.Thearch.LinkArch = &x86.Link386
- gc.Thearch.REGSP = x86.REGSP
+func Init(arch *gc.Arch) {
+ arch.LinkArch = &x86.Link386
+ arch.REGSP = x86.REGSP
switch v := obj.GO386; v {
case "387":
- gc.Thearch.Use387 = true
+ arch.Use387 = true
+ arch.SSAGenValue = ssaGenValue387
+ arch.SSAGenBlock = ssaGenBlock387
case "sse2":
+ arch.SSAGenValue = ssaGenValue
+ arch.SSAGenBlock = ssaGenBlock
default:
fmt.Fprintf(os.Stderr, "unsupported setting GO386=%s\n", v)
gc.Exit(1)
}
- gc.Thearch.MAXWIDTH = (1 << 32) - 1
+ arch.MAXWIDTH = (1 << 32) - 1
- gc.Thearch.Defframe = defframe
- gc.Thearch.Ginsnop = ginsnop
- gc.Thearch.Proginfo = proginfo
+ arch.Defframe = defframe
+ arch.Ginsnop = ginsnop
+ arch.Proginfo = proginfo
- gc.Thearch.SSAMarkMoves = ssaMarkMoves
- gc.Thearch.SSAGenValue = ssaGenValue
- gc.Thearch.SSAGenBlock = ssaGenBlock
+ arch.SSAMarkMoves = ssaMarkMoves
}
}
func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
- if gc.Thearch.Use387 {
- if ssaGenValue387(s, v) {
- return // v was handled by 387 generation.
- }
- }
-
switch v.Op {
case ssa.Op386ADDL:
r := v.Reg()
}
func ssaGenBlock(s *gc.SSAGenState, b, next *ssa.Block) {
- s.SetPos(b.Pos)
-
- if gc.Thearch.Use387 {
- // Empty the 387's FP stack before the block ends.
- flush387(s)
- }
-
switch b.Kind {
case ssa.BlockPlain:
if b.Succs[0].Block() != next {
"os"
)
+var archInits = map[string]func(*gc.Arch){
+ "386": x86.Init,
+ "amd64": amd64.Init,
+ "amd64p32": amd64.Init,
+ "arm": arm.Init,
+ "arm64": arm64.Init,
+ "mips": mips.Init,
+ "mipsle": mips.Init,
+ "mips64": mips64.Init,
+ "mips64le": mips64.Init,
+ "ppc64": ppc64.Init,
+ "ppc64le": ppc64.Init,
+ "s390x": s390x.Init,
+}
+
func main() {
// disable timestamps for reproducible output
log.SetFlags(0)
log.SetPrefix("compile: ")
- switch obj.GOARCH {
- default:
+ archInit, ok := archInits[obj.GOARCH]
+ if !ok {
fmt.Fprintf(os.Stderr, "compile: unknown architecture %q\n", obj.GOARCH)
os.Exit(2)
- case "386":
- x86.Init()
- case "amd64", "amd64p32":
- amd64.Init()
- case "arm":
- arm.Init()
- case "arm64":
- arm64.Init()
- case "mips", "mipsle":
- mips.Init()
- case "mips64", "mips64le":
- mips64.Init()
- case "ppc64", "ppc64le":
- ppc64.Init()
- case "s390x":
- s390x.Init()
}
- gc.Main()
+ gc.Main(archInit)
gc.Exit(0)
}