| // 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 |
| } |