mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/compile: use MOVWaddr for address on ARM
Introduce an op MOVWaddr for addresses on ARM, instead of overuse ADDconst. Mark MOVWaddr as rematerializable. This fixes a liveness problem: if it were not rematerializable, the address of a variable may be spilled and later use of the address may just load the spilled value without mentioning the variable, and the liveness code may think it is dead prematurely. Update #15365. Change-Id: Ib0b0fa826bdb75c9e6bb362b95c6cf132cc6b1c0 Reviewed-on: https://go-review.googlesource.com/23942 Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
e3a6d00876
commit
c40dcff2f2
5 changed files with 426 additions and 93 deletions
|
|
@ -295,37 +295,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
p.Reg = r1
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = r
|
||||
case ssa.OpARMADDconst:
|
||||
if v.Aux != nil {
|
||||
switch v.Aux.(type) {
|
||||
default:
|
||||
v.Fatalf("aux is of unknown type %T", v.Aux)
|
||||
case *ssa.ExternSymbol:
|
||||
reg := v.Args[0].Block.Func.RegAlloc[v.Args[0].ID].(*ssa.Register)
|
||||
if reg.Name() != "SB" {
|
||||
v.Fatalf("extern symbol with non-SB base register %s", reg.Name())
|
||||
}
|
||||
case *ssa.ArgSymbol,
|
||||
*ssa.AutoSymbol:
|
||||
reg := v.Args[0].Block.Func.RegAlloc[v.Args[0].ID].(*ssa.Register)
|
||||
if reg.Name() != "SP" {
|
||||
v.Fatalf("arg/auto symbol with non-SP base register %s", reg.Name())
|
||||
}
|
||||
}
|
||||
// MOVW $sym+off(base), R
|
||||
// the assembler expands it as the following:
|
||||
// - base is SP: add constant offset to SP (R13)
|
||||
// when constant is large, tmp register (R11) may be used
|
||||
// - base is SB: load external address from constant pool (use relocation)
|
||||
p := gc.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
gc.AddAux(&p.From, v)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = gc.SSARegNum(v)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
case ssa.OpARMSUBconst,
|
||||
case ssa.OpARMADDconst,
|
||||
ssa.OpARMSUBconst,
|
||||
ssa.OpARMRSBconst,
|
||||
ssa.OpARMANDconst,
|
||||
ssa.OpARMORconst,
|
||||
|
|
@ -407,6 +378,46 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
|||
p.From.Type = obj.TYPE_CONST
|
||||
p.From.Offset = v.AuxInt
|
||||
p.Reg = gc.SSARegNum(v.Args[0])
|
||||
case ssa.OpARMMOVWaddr:
|
||||
if v.Aux == nil {
|
||||
// MOVW $off(SP), R
|
||||
reg := v.Args[0].Block.Func.RegAlloc[v.Args[0].ID].(*ssa.Register)
|
||||
if reg.Name() != "SP" {
|
||||
v.Fatalf("arg/auto symbol with non-SP base register %s", reg.Name())
|
||||
}
|
||||
p := gc.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
p.From.Reg = arm.REGSP
|
||||
p.From.Offset = v.AuxInt
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = gc.SSARegNum(v)
|
||||
break
|
||||
}
|
||||
// MOVW $sym+off(base), R
|
||||
// the assembler expands it as the following:
|
||||
// - base is SP: add constant offset to SP (R13)
|
||||
// when constant is large, tmp register (R11) may be used
|
||||
// - base is SB: load external address from constant pool (use relocation)
|
||||
switch v.Aux.(type) {
|
||||
default:
|
||||
v.Fatalf("aux is of unknown type %T", v.Aux)
|
||||
case *ssa.ExternSymbol:
|
||||
reg := v.Args[0].Block.Func.RegAlloc[v.Args[0].ID].(*ssa.Register)
|
||||
if reg.Name() != "SB" {
|
||||
v.Fatalf("extern symbol with non-SB base register %s", reg.Name())
|
||||
}
|
||||
case *ssa.ArgSymbol,
|
||||
*ssa.AutoSymbol:
|
||||
reg := v.Args[0].Block.Func.RegAlloc[v.Args[0].ID].(*ssa.Register)
|
||||
if reg.Name() != "SP" {
|
||||
v.Fatalf("arg/auto symbol with non-SP base register %s", reg.Name())
|
||||
}
|
||||
}
|
||||
p := gc.Prog(arm.AMOVW)
|
||||
p.From.Type = obj.TYPE_ADDR
|
||||
gc.AddAux(&p.From, v)
|
||||
p.To.Type = obj.TYPE_REG
|
||||
p.To.Reg = gc.SSARegNum(v)
|
||||
case ssa.OpARMMOVBload,
|
||||
ssa.OpARMMOVBUload,
|
||||
ssa.OpARMMOVHload,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue