mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/compile: handle GetG on ARM
Use hardware g register (R10) for GetG, allow g to appear at LHS of some ops. Progress on SSA backend for ARM. Now everything compiles and runs. Updates #15365. Change-Id: Icdf93585579faa86cc29b1e17ab7c90f0119fc4e Reviewed-on: https://go-review.googlesource.com/23952 Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
0393ed8201
commit
93b8aab5c9
6 changed files with 151 additions and 115 deletions
|
|
@ -206,6 +206,7 @@ type regAllocState struct {
|
|||
numRegs register
|
||||
SPReg register
|
||||
SBReg register
|
||||
GReg register
|
||||
allocatable regMask
|
||||
|
||||
// for each block, its primary predecessor.
|
||||
|
|
@ -449,12 +450,18 @@ func (s *regAllocState) init(f *Func) {
|
|||
if s.registers[r].Name() == "SB" {
|
||||
s.SBReg = r
|
||||
}
|
||||
if s.registers[r].Name() == "g" {
|
||||
s.GReg = r
|
||||
}
|
||||
}
|
||||
|
||||
// Figure out which registers we're allowed to use.
|
||||
s.allocatable = s.f.Config.gpRegMask | s.f.Config.fpRegMask | s.f.Config.flagRegMask
|
||||
s.allocatable &^= 1 << s.SPReg
|
||||
s.allocatable &^= 1 << s.SBReg
|
||||
if s.f.Config.hasGReg {
|
||||
s.allocatable &^= 1 << s.GReg
|
||||
}
|
||||
if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
|
||||
s.allocatable &^= 1 << uint(s.f.Config.FPReg)
|
||||
}
|
||||
|
|
@ -937,6 +944,26 @@ func (s *regAllocState) regalloc(f *Func) {
|
|||
s.advanceUses(v)
|
||||
continue
|
||||
}
|
||||
if v.Op == OpGetG && s.f.Config.hasGReg {
|
||||
// use hardware g register
|
||||
if s.regs[s.GReg].v != nil {
|
||||
s.freeReg(s.GReg) // kick out the old value
|
||||
}
|
||||
s.assignReg(s.GReg, v, v)
|
||||
b.Values = append(b.Values, v)
|
||||
s.advanceUses(v)
|
||||
// spill unconditionally, will be deleted if never used
|
||||
spill := b.NewValue1(v.Line, OpStoreReg, v.Type, v)
|
||||
s.setOrig(spill, v)
|
||||
s.values[v.ID].spill = spill
|
||||
s.values[v.ID].spillUsed = false
|
||||
if loop != nil {
|
||||
loop.spills = append(loop.spills, v)
|
||||
nSpillsInner++
|
||||
}
|
||||
nSpills++
|
||||
continue
|
||||
}
|
||||
if v.Op == OpArg {
|
||||
// Args are "pre-spilled" values. We don't allocate
|
||||
// any register here. We just set up the spill pointer to
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue