mirror of
https://github.com/golang/go
synced 2024-09-15 22:20:06 +00:00
[dev.typeparams] cmd/compile: add arg/result register load/spill code on ARM64
Add code that loads results into registers (used in defer return code path) and spills argument registers (used for partially lived in-register args). Move some code from the amd64 package to a common place. Change-Id: I8d59b68693048fdba86e10769c4ac58de5fcfb64 Reviewed-on: https://go-review.googlesource.com/c/go/+/322851 Trust: Cherry Mui <cherryyz@google.com> Run-TryBot: Cherry Mui <cherryyz@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Than McIntosh <thanm@google.com>
This commit is contained in:
parent
1ec056244e
commit
06df0ee7fa
|
@ -23,6 +23,6 @@ func Init(arch *ssagen.ArchInfo) {
|
||||||
arch.SSAMarkMoves = ssaMarkMoves
|
arch.SSAMarkMoves = ssaMarkMoves
|
||||||
arch.SSAGenValue = ssaGenValue
|
arch.SSAGenValue = ssaGenValue
|
||||||
arch.SSAGenBlock = ssaGenBlock
|
arch.SSAGenBlock = ssaGenBlock
|
||||||
arch.LoadRegResults = loadRegResults
|
arch.LoadRegResult = loadRegResult
|
||||||
arch.SpillArgReg = spillArgReg
|
arch.SpillArgReg = spillArgReg
|
||||||
}
|
}
|
||||||
|
|
|
@ -1354,20 +1354,15 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadRegResults(s *ssagen.State, f *ssa.Func) {
|
func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
|
||||||
for _, o := range f.OwnAux.ABIInfo().OutParams() {
|
p := s.Prog(loadByType(t))
|
||||||
n := o.Name.(*ir.Name)
|
p.From.Type = obj.TYPE_MEM
|
||||||
rts, offs := o.RegisterTypesAndOffsets()
|
p.From.Name = obj.NAME_AUTO
|
||||||
for i := range o.Registers {
|
p.From.Sym = n.Linksym()
|
||||||
p := s.Prog(loadByType(rts[i]))
|
p.From.Offset = n.FrameOffset() + off
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_REG
|
||||||
p.From.Name = obj.NAME_AUTO
|
p.To.Reg = reg
|
||||||
p.From.Sym = n.Linksym()
|
return p
|
||||||
p.From.Offset = n.FrameOffset() + offs[i]
|
|
||||||
p.To.Type = obj.TYPE_REG
|
|
||||||
p.To.Reg = ssa.ObjRegForAbiReg(o.Registers[i], f.Config)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
|
func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
|
||||||
|
|
|
@ -23,4 +23,6 @@ func Init(arch *ssagen.ArchInfo) {
|
||||||
arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
|
arch.SSAMarkMoves = func(s *ssagen.State, b *ssa.Block) {}
|
||||||
arch.SSAGenValue = ssaGenValue
|
arch.SSAGenValue = ssaGenValue
|
||||||
arch.SSAGenBlock = ssaGenBlock
|
arch.SSAGenBlock = ssaGenBlock
|
||||||
|
arch.LoadRegResult = loadRegResult
|
||||||
|
arch.SpillArgReg = spillArgReg
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"cmd/compile/internal/base"
|
"cmd/compile/internal/base"
|
||||||
"cmd/compile/internal/ir"
|
"cmd/compile/internal/ir"
|
||||||
"cmd/compile/internal/logopt"
|
"cmd/compile/internal/logopt"
|
||||||
|
"cmd/compile/internal/objw"
|
||||||
"cmd/compile/internal/ssa"
|
"cmd/compile/internal/ssa"
|
||||||
"cmd/compile/internal/ssagen"
|
"cmd/compile/internal/ssagen"
|
||||||
"cmd/compile/internal/types"
|
"cmd/compile/internal/types"
|
||||||
|
@ -1278,3 +1279,22 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
||||||
b.Fatalf("branch not implemented: %s", b.LongString())
|
b.Fatalf("branch not implemented: %s", b.LongString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadRegResult(s *ssagen.State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
|
||||||
|
p := s.Prog(loadByType(t))
|
||||||
|
p.From.Type = obj.TYPE_MEM
|
||||||
|
p.From.Name = obj.NAME_AUTO
|
||||||
|
p.From.Sym = n.Linksym()
|
||||||
|
p.From.Offset = n.FrameOffset() + off
|
||||||
|
p.To.Type = obj.TYPE_REG
|
||||||
|
p.To.Reg = reg
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func spillArgReg(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog {
|
||||||
|
p = pp.Append(p, storeByType(t), obj.TYPE_REG, reg, 0, obj.TYPE_MEM, 0, n.FrameOffset()+off)
|
||||||
|
p.To.Name = obj.NAME_PARAM
|
||||||
|
p.To.Sym = n.Linksym()
|
||||||
|
p.Pos = p.Pos.WithNotStmt()
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
|
@ -42,10 +42,10 @@ type ArchInfo struct {
|
||||||
// for all values in the block before SSAGenBlock.
|
// for all values in the block before SSAGenBlock.
|
||||||
SSAGenBlock func(s *State, b, next *ssa.Block)
|
SSAGenBlock func(s *State, b, next *ssa.Block)
|
||||||
|
|
||||||
// LoadRegResults emits instructions that loads register-assigned results
|
// LoadRegResult emits instructions that loads register-assigned result
|
||||||
// into registers. They are already in memory (PPARAMOUT nodes).
|
// at n+off (n is PPARAMOUT) to register reg. The result is already in
|
||||||
// Used in open-coded defer return path.
|
// memory. Used in open-coded defer return path.
|
||||||
LoadRegResults func(s *State, f *ssa.Func)
|
LoadRegResult func(s *State, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
|
||||||
|
|
||||||
// SpillArgReg emits instructions that spill reg to n+off.
|
// SpillArgReg emits instructions that spill reg to n+off.
|
||||||
SpillArgReg func(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
|
SpillArgReg func(pp *objw.Progs, p *obj.Prog, f *ssa.Func, t *types.Type, reg int16, n *ir.Name, off int64) *obj.Prog
|
||||||
|
|
|
@ -6930,8 +6930,12 @@ func genssa(f *ssa.Func, pp *objw.Progs) {
|
||||||
// recovers a panic, it will return to caller with right results.
|
// recovers a panic, it will return to caller with right results.
|
||||||
// The results are already in memory, because they are not SSA'd
|
// The results are already in memory, because they are not SSA'd
|
||||||
// when the function has defers (see canSSAName).
|
// when the function has defers (see canSSAName).
|
||||||
if f.OwnAux.ABIInfo().OutRegistersUsed() != 0 {
|
for _, o := range f.OwnAux.ABIInfo().OutParams() {
|
||||||
Arch.LoadRegResults(&s, f)
|
n := o.Name.(*ir.Name)
|
||||||
|
rts, offs := o.RegisterTypesAndOffsets()
|
||||||
|
for i := range o.Registers {
|
||||||
|
Arch.LoadRegResult(&s, f, rts[i], ssa.ObjRegForAbiReg(o.Registers[i], f.Config), n, offs[i])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pp.Prog(obj.ARET)
|
pp.Prog(obj.ARET)
|
||||||
|
|
Loading…
Reference in a new issue