blob: 5c2c53a02b896e52db334dc9a30f25037b6d6df9 [file]
// Copyright 2015 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 ssacompile
import (
"cmd/compile/internal/abi"
"cmd/compile/internal/base"
"cmd/compile/internal/ssa"
"cmd/compile/internal/ssa/ssaop"
"cmd/compile/internal/ssarewrite/rewrite386"
"cmd/compile/internal/ssarewrite/rewrite386splitload"
"cmd/compile/internal/ssarewrite/rewriteamd64"
"cmd/compile/internal/ssarewrite/rewriteamd64latelower"
"cmd/compile/internal/ssarewrite/rewriteamd64splitload"
"cmd/compile/internal/ssarewrite/rewritearm"
"cmd/compile/internal/ssarewrite/rewritearm64"
"cmd/compile/internal/ssarewrite/rewritearm64latelower"
"cmd/compile/internal/ssarewrite/rewriteloong64"
"cmd/compile/internal/ssarewrite/rewriteloong64latelower"
"cmd/compile/internal/ssarewrite/rewritemips"
"cmd/compile/internal/ssarewrite/rewritemips64"
"cmd/compile/internal/ssarewrite/rewritemips64latelower"
"cmd/compile/internal/ssarewrite/rewriteppc64"
"cmd/compile/internal/ssarewrite/rewriteppc64latelower"
"cmd/compile/internal/ssarewrite/rewriteriscv64"
"cmd/compile/internal/ssarewrite/rewriteriscv64latelower"
"cmd/compile/internal/ssarewrite/rewrites390x"
"cmd/compile/internal/ssarewrite/rewritewasm"
"cmd/internal/obj"
)
func NewConfig(softFloat bool) *ssa.Config {
types_ := ssa.NewTypes()
return newConfig(base.Ctxt.Arch.Name, *types_, base.Ctxt, base.Flag.N == 0, softFloat)
}
// newConfig returns a new configuration object for the given architecture.
func newConfig(arch string, types ssa.Types, ctxt *obj.Link, optimize, softfloat bool) *ssa.Config {
c := &ssa.Config{Arch: arch, Types: types}
switch arch {
case "amd64":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewriteamd64.RewriteBlock
c.LowerValue = rewriteamd64.RewriteValue
c.LateLowerBlock = rewriteamd64latelower.RewriteBlock
c.LateLowerValue = rewriteamd64latelower.RewriteValue
c.SplitLoad = rewriteamd64splitload.RewriteValue
c.Registers = registersAMD64[:]
c.GpRegMask = gpRegMaskAMD64
c.FpRegMask = fpRegMaskAMD64
c.SimdRegMask = simdRegMaskAMD64
c.SpecialRegMask = specialRegMaskAMD64
c.IntParamRegs = paramIntRegAMD64
c.FloatParamRegs = paramFloatRegAMD64
c.FPReg = framepointerRegAMD64
c.LinkReg = linkRegAMD64
c.HasGReg = true
c.UnalignedOK = true
c.HaveBswap64 = true
c.HaveBswap32 = true
c.HaveBswap16 = true
c.HaveCondSelect = true
case "386":
c.PtrSize = 4
c.RegSize = 4
c.LowerBlock = rewrite386.RewriteBlock
c.LowerValue = rewrite386.RewriteValue
c.SplitLoad = rewrite386splitload.RewriteValue
c.Registers = registers386[:]
c.GpRegMask = gpRegMask386
c.FpRegMask = fpRegMask386
c.FPReg = framepointerReg386
c.LinkReg = linkReg386
c.HasGReg = false
c.UnalignedOK = true
c.HaveBswap32 = true
c.HaveBswap16 = true
case "arm":
c.PtrSize = 4
c.RegSize = 4
c.LowerBlock = rewritearm.RewriteBlock
c.LowerValue = rewritearm.RewriteValue
c.Registers = registersARM[:]
c.GpRegMask = gpRegMaskARM
c.FpRegMask = fpRegMaskARM
c.FPReg = framepointerRegARM
c.LinkReg = linkRegARM
c.HasGReg = true
case "arm64":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewritearm64.RewriteBlock
c.LowerValue = rewritearm64.RewriteValue
c.LateLowerBlock = rewritearm64latelower.RewriteBlock
c.LateLowerValue = rewritearm64latelower.RewriteValue
c.Registers = registersARM64[:]
c.GpRegMask = gpRegMaskARM64
c.FpRegMask = fpRegMaskARM64
c.SimdRegMask = simdRegMaskARM64
c.SpecialRegMask = specialRegMaskARM64
c.IntParamRegs = paramIntRegARM64
c.FloatParamRegs = paramFloatRegARM64
c.FPReg = framepointerRegARM64
c.LinkReg = linkRegARM64
c.HasGReg = true
c.UnalignedOK = true
c.HaveBswap64 = true
c.HaveBswap32 = true
c.HaveBswap16 = true
c.HaveCondSelect = true
case "ppc64":
c.BigEndian = true
fallthrough
case "ppc64le":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewriteppc64.RewriteBlock
c.LowerValue = rewriteppc64.RewriteValue
c.LateLowerBlock = rewriteppc64latelower.RewriteBlock
c.LateLowerValue = rewriteppc64latelower.RewriteValue
c.Registers = registersPPC64[:]
c.GpRegMask = gpRegMaskPPC64
c.FpRegMask = fpRegMaskPPC64
c.SpecialRegMask = specialRegMaskPPC64
c.IntParamRegs = paramIntRegPPC64
c.FloatParamRegs = paramFloatRegPPC64
c.FPReg = framepointerRegPPC64
c.LinkReg = linkRegPPC64
c.HasGReg = true
c.UnalignedOK = true
// Note: ppc64 has register bswap ops only when GOPPC64>=10.
// But it has bswap+load and bswap+store ops for all ppc64 variants.
// That is the sense we're using them here - they are only used
// in contexts where they can be merged with a load or store.
c.HaveBswap64 = true
c.HaveBswap32 = true
c.HaveBswap16 = true
c.HaveCondSelect = true
case "mips64":
c.BigEndian = true
fallthrough
case "mips64le":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewritemips64.RewriteBlock
c.LowerValue = rewritemips64.RewriteValue
c.LateLowerBlock = rewritemips64latelower.RewriteBlock
c.LateLowerValue = rewritemips64latelower.RewriteValue
c.Registers = registersMIPS64[:]
c.GpRegMask = gpRegMaskMIPS64
c.FpRegMask = fpRegMaskMIPS64
c.SpecialRegMask = specialRegMaskMIPS64
c.FPReg = framepointerRegMIPS64
c.LinkReg = linkRegMIPS64
c.HasGReg = true
case "loong64":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewriteloong64.RewriteBlock
c.LowerValue = rewriteloong64.RewriteValue
c.LateLowerBlock = rewriteloong64latelower.RewriteBlock
c.LateLowerValue = rewriteloong64latelower.RewriteValue
c.Registers = registersLOONG64[:]
c.GpRegMask = gpRegMaskLOONG64
c.FpRegMask = fpRegMaskLOONG64
c.IntParamRegs = paramIntRegLOONG64
c.FloatParamRegs = paramFloatRegLOONG64
c.FPReg = framepointerRegLOONG64
c.LinkReg = linkRegLOONG64
c.HasGReg = true
c.UnalignedOK = true
c.HaveBswap64 = true
c.HaveBswap32 = true
c.HaveBswap16 = true
c.HaveCondSelect = true
case "s390x":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewrites390x.RewriteBlock
c.LowerValue = rewrites390x.RewriteValue
c.Registers = registersS390X[:]
c.GpRegMask = gpRegMaskS390X
c.FpRegMask = fpRegMaskS390X
c.IntParamRegs = paramIntRegS390X
c.FloatParamRegs = paramFloatRegS390X
c.FPReg = framepointerRegS390X
c.LinkReg = linkRegS390X
c.HasGReg = true
c.BigEndian = true
c.UnalignedOK = true
c.HaveBswap64 = true
c.HaveBswap32 = true
c.HaveBswap16 = true // only for loads&stores, see ppc64 comment
case "mips":
c.BigEndian = true
fallthrough
case "mipsle":
c.PtrSize = 4
c.RegSize = 4
c.LowerBlock = rewritemips.RewriteBlock
c.LowerValue = rewritemips.RewriteValue
c.Registers = registersMIPS[:]
c.GpRegMask = gpRegMaskMIPS
c.FpRegMask = fpRegMaskMIPS
c.SpecialRegMask = specialRegMaskMIPS
c.FPReg = framepointerRegMIPS
c.LinkReg = linkRegMIPS
c.HasGReg = true
case "riscv64":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewriteriscv64.RewriteBlock
c.LowerValue = rewriteriscv64.RewriteValue
c.LateLowerBlock = rewriteriscv64latelower.RewriteBlock
c.LateLowerValue = rewriteriscv64latelower.RewriteValue
c.Registers = registersRISCV64[:]
c.GpRegMask = gpRegMaskRISCV64
c.FpRegMask = fpRegMaskRISCV64
c.IntParamRegs = paramIntRegRISCV64
c.FloatParamRegs = paramFloatRegRISCV64
c.FPReg = framepointerRegRISCV64
c.HasGReg = true
case "wasm":
c.PtrSize = 8
c.RegSize = 8
c.LowerBlock = rewritewasm.RewriteBlock
c.LowerValue = rewritewasm.RewriteValue
c.Registers = registersWasm[:]
c.GpRegMask = gpRegMaskWasm
c.FpRegMask = fpRegMaskWasm
c.Fp32RegMask = fp32RegMaskWasm
c.Fp64RegMask = fp64RegMaskWasm
c.SimdRegMask = simdRegMaskWasm
c.FPReg = framepointerRegWasm
c.LinkReg = linkRegWasm
c.HasGReg = true
c.UnalignedOK = true
c.HaveCondSelect = true
default:
ctxt.Diag("arch %s not implemented", arch)
}
c.Ctxt = ctxt
c.Optimize = optimize
c.SoftFloat = softfloat
if softfloat {
c.FloatParamRegs = nil // no FP registers in softfloat mode
}
c.ABI0 = abi.NewABIConfig(0, 0, ctxt.Arch.FixedFrameSize, 0)
c.ABI1 = abi.NewABIConfig(len(c.IntParamRegs), len(c.FloatParamRegs), ctxt.Arch.FixedFrameSize, 1)
if ctxt.Flag_shared {
// LoweredWB is secretly a CALL and CALLs on 386 in
// shared mode get rewritten by obj6.go to go through
// the GOT, which clobbers BX.
ssaop.OpcodeTable[ssaop.Op386LoweredWB].Reg.Clobbers = ssaop.OpcodeTable[ssaop.Op386LoweredWB].Reg.Clobbers.AddReg(3) // BX
}
c.BuildRecipes(arch)
return c
}