mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.simd] cmd/compile: fix LoadReg so it is aware of register target
SIMD code generation created interesting new type/register combintations. Change-Id: I9c9a73bf51f6cb54551db1fdc88f9dd1eef7ab26 Reviewed-on: https://go-review.googlesource.com/c/go/+/695895 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Junyang Shao <shaojunyang@google.com>
This commit is contained in:
parent
d5dea86993
commit
e001300cf2
1 changed files with 37 additions and 7 deletions
|
|
@ -47,8 +47,8 @@ func isFPReg(r int16) bool {
|
|||
return x86.REG_X0 <= r && r <= x86.REG_Z31
|
||||
}
|
||||
|
||||
// loadByType returns the load instruction of the given type.
|
||||
func loadByType(t *types.Type) obj.As {
|
||||
// loadByTypeAndReg returns the load instruction of the given type/register.
|
||||
func loadByTypeAndReg(t *types.Type, r int16) obj.As {
|
||||
// Avoid partial register write
|
||||
if !t.IsFloat() {
|
||||
switch t.Size() {
|
||||
|
|
@ -59,7 +59,37 @@ func loadByType(t *types.Type) obj.As {
|
|||
}
|
||||
}
|
||||
// Otherwise, there's no difference between load and store opcodes.
|
||||
return storeByType(t)
|
||||
return storeByTypeAndReg(t, r)
|
||||
}
|
||||
|
||||
// storeByTypeAndReg returns the store instruction of the given type/register.
|
||||
func storeByTypeAndReg(t *types.Type, r int16) obj.As {
|
||||
width := t.Size()
|
||||
if t.IsSIMD() {
|
||||
return simdMov(width)
|
||||
}
|
||||
if isFPReg(r) {
|
||||
switch width {
|
||||
case 4:
|
||||
return x86.AMOVSS
|
||||
case 8:
|
||||
return x86.AMOVSD
|
||||
}
|
||||
} else {
|
||||
switch width {
|
||||
case 1:
|
||||
return x86.AMOVB
|
||||
case 2:
|
||||
return x86.AMOVW
|
||||
case 4:
|
||||
return x86.AMOVL
|
||||
case 8:
|
||||
return x86.AMOVQ
|
||||
case 16:
|
||||
return x86.AMOVUPS
|
||||
}
|
||||
}
|
||||
panic(fmt.Sprintf("bad store type %v", t))
|
||||
}
|
||||
|
||||
// storeByType returns the store instruction of the given type.
|
||||
|
|
@ -1171,10 +1201,10 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
|||
v.Fatalf("load flags not implemented: %v", v.LongString())
|
||||
return
|
||||
}
|
||||
p := s.Prog(loadByType(v.Type))
|
||||
r := v.Reg()
|
||||
p := s.Prog(loadByTypeAndReg(v.Type, r))
|
||||
ssagen.AddrAuto(&p.From, v.Args[0])
|
||||
p.To.Type = obj.TYPE_REG
|
||||
r := v.Reg()
|
||||
if v.Type.IsSIMD() {
|
||||
r = simdOrMaskReg(v)
|
||||
}
|
||||
|
|
@ -1206,7 +1236,7 @@ func ssaGenValue(s *ssagen.State, v *ssa.Value) {
|
|||
// Pass the spill/unspill information along to the assembler, offset by size of return PC pushed on stack.
|
||||
addr := ssagen.SpillSlotAddr(ap, x86.REG_SP, v.Block.Func.Config.PtrSize)
|
||||
s.FuncInfo().AddSpill(
|
||||
obj.RegSpill{Reg: ap.Reg, Addr: addr, Unspill: loadByType(ap.Type), Spill: storeByType(ap.Type)})
|
||||
obj.RegSpill{Reg: ap.Reg, Addr: addr, Unspill: loadByTypeAndReg(ap.Type, ap.Reg), Spill: storeByType(ap.Type)})
|
||||
}
|
||||
v.Block.Func.RegArgs = nil
|
||||
ssagen.CheckArgReg(v)
|
||||
|
|
@ -2090,7 +2120,7 @@ func ssaGenBlock(s *ssagen.State, b, next *ssa.Block) {
|
|||
}
|
||||
|
||||
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 := s.Prog(loadByTypeAndReg(t, reg))
|
||||
p.From.Type = obj.TYPE_MEM
|
||||
p.From.Name = obj.NAME_AUTO
|
||||
p.From.Sym = n.Linksym()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue