mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.ssa] cmd/compile: respect stack slot width when storing/loading registers
Prior to this, we were smashing our own stack, which caused the crypto/sha256 tests to fail. Change-Id: I7dd94cf466d175b3be0cd65f9c4fe8b1223081fe Reviewed-on: https://go-review.googlesource.com/12660 Reviewed-by: Daniel Morsing <daniel.morsing@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
db5232620a
commit
0bb2a50a55
4 changed files with 31 additions and 16 deletions
|
|
@ -1639,23 +1639,23 @@ func genValue(v *ssa.Value) {
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = y
|
p.To.Reg = y
|
||||||
}
|
}
|
||||||
case ssa.OpLoadReg8:
|
case ssa.OpLoadReg:
|
||||||
if v.Type.IsFlags() {
|
if v.Type.IsFlags() {
|
||||||
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
v.Unimplementedf("load flags not implemented: %v", v.LongString())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p := Prog(x86.AMOVQ)
|
p := Prog(movSize(v.Type.Size()))
|
||||||
p.From.Type = obj.TYPE_MEM
|
p.From.Type = obj.TYPE_MEM
|
||||||
p.From.Reg = x86.REG_SP
|
p.From.Reg = x86.REG_SP
|
||||||
p.From.Offset = localOffset(v.Args[0])
|
p.From.Offset = localOffset(v.Args[0])
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = regnum(v)
|
p.To.Reg = regnum(v)
|
||||||
case ssa.OpStoreReg8:
|
case ssa.OpStoreReg:
|
||||||
if v.Type.IsFlags() {
|
if v.Type.IsFlags() {
|
||||||
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
v.Unimplementedf("store flags not implemented: %v", v.LongString())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p := Prog(x86.AMOVQ)
|
p := Prog(movSize(v.Type.Size()))
|
||||||
p.From.Type = obj.TYPE_REG
|
p.From.Type = obj.TYPE_REG
|
||||||
p.From.Reg = regnum(v.Args[0])
|
p.From.Reg = regnum(v.Args[0])
|
||||||
p.To.Type = obj.TYPE_MEM
|
p.To.Type = obj.TYPE_MEM
|
||||||
|
|
@ -1711,6 +1711,23 @@ func genValue(v *ssa.Value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// movSize returns the MOV instruction of the given width.
|
||||||
|
func movSize(width int64) (asm int) {
|
||||||
|
switch width {
|
||||||
|
case 1:
|
||||||
|
asm = x86.AMOVB
|
||||||
|
case 2:
|
||||||
|
asm = x86.AMOVW
|
||||||
|
case 4:
|
||||||
|
asm = x86.AMOVL
|
||||||
|
case 8:
|
||||||
|
asm = x86.AMOVQ
|
||||||
|
default:
|
||||||
|
panic(fmt.Errorf("bad movSize %d", width))
|
||||||
|
}
|
||||||
|
return asm
|
||||||
|
}
|
||||||
|
|
||||||
// movZero generates a register indirect move with a 0 immediate and keeps track of bytes left and next offset
|
// movZero generates a register indirect move with a 0 immediate and keeps track of bytes left and next offset
|
||||||
func movZero(as int, width int64, nbytes int64, offset int64, regnum int16) (nleft int64, noff int64) {
|
func movZero(as int, width int64, nbytes int64, offset int64, regnum int16) (nleft int64, noff int64) {
|
||||||
p := Prog(as)
|
p := Prog(as)
|
||||||
|
|
|
||||||
|
|
@ -178,10 +178,8 @@ var genericOps = []opData{
|
||||||
// semantically identical to OpCopy; they do not take/return
|
// semantically identical to OpCopy; they do not take/return
|
||||||
// stores like regular memory ops do. We can get away without memory
|
// stores like regular memory ops do. We can get away without memory
|
||||||
// args because we know there is no aliasing of spill slots on the stack.
|
// args because we know there is no aliasing of spill slots on the stack.
|
||||||
// TODO: remove these, make them arch-specific ops stored
|
{name: "StoreReg"},
|
||||||
// in the fields of Config instead.
|
{name: "LoadReg"},
|
||||||
{name: "StoreReg8"},
|
|
||||||
{name: "LoadReg8"},
|
|
||||||
|
|
||||||
// Used during ssa construction. Like Copy, but the arg has not been specified yet.
|
// Used during ssa construction. Like Copy, but the arg has not been specified yet.
|
||||||
{name: "FwdRef"},
|
{name: "FwdRef"},
|
||||||
|
|
|
||||||
|
|
@ -243,8 +243,8 @@ const (
|
||||||
OpStringMake
|
OpStringMake
|
||||||
OpStringPtr
|
OpStringPtr
|
||||||
OpStringLen
|
OpStringLen
|
||||||
OpStoreReg8
|
OpStoreReg
|
||||||
OpLoadReg8
|
OpLoadReg
|
||||||
OpFwdRef
|
OpFwdRef
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1590,11 +1590,11 @@ var opcodeTable = [...]opInfo{
|
||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "StoreReg8",
|
name: "StoreReg",
|
||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "LoadReg8",
|
name: "LoadReg",
|
||||||
generic: true,
|
generic: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -240,7 +240,7 @@ func regalloc(f *Func) {
|
||||||
c := regs[r].c
|
c := regs[r].c
|
||||||
if regs[r].dirty && lastUse[x.ID] > idx {
|
if regs[r].dirty && lastUse[x.ID] > idx {
|
||||||
// Write x back to home. Its value is currently held in c.
|
// Write x back to home. Its value is currently held in c.
|
||||||
x.Op = OpStoreReg8
|
x.Op = OpStoreReg
|
||||||
x.Aux = nil
|
x.Aux = nil
|
||||||
x.resetArgs()
|
x.resetArgs()
|
||||||
x.AddArg(c)
|
x.AddArg(c)
|
||||||
|
|
@ -276,7 +276,7 @@ func regalloc(f *Func) {
|
||||||
c = b.NewValue1(w.Line, OpCopy, w.Type, regs[s].c)
|
c = b.NewValue1(w.Line, OpCopy, w.Type, regs[s].c)
|
||||||
} else {
|
} else {
|
||||||
// Load from home location
|
// Load from home location
|
||||||
c = b.NewValue1(w.Line, OpLoadReg8, w.Type, w)
|
c = b.NewValue1(w.Line, OpLoadReg, w.Type, w)
|
||||||
}
|
}
|
||||||
home = setloc(home, c, ®isters[r])
|
home = setloc(home, c, ®isters[r])
|
||||||
// Remember what we did
|
// Remember what we did
|
||||||
|
|
@ -319,7 +319,7 @@ func regalloc(f *Func) {
|
||||||
c := regs[r].c
|
c := regs[r].c
|
||||||
if regs[r].dirty && lastUse[x.ID] > idx {
|
if regs[r].dirty && lastUse[x.ID] > idx {
|
||||||
// Write x back to home. Its value is currently held in c.
|
// Write x back to home. Its value is currently held in c.
|
||||||
x.Op = OpStoreReg8
|
x.Op = OpStoreReg
|
||||||
x.Aux = nil
|
x.Aux = nil
|
||||||
x.resetArgs()
|
x.resetArgs()
|
||||||
x.AddArg(c)
|
x.AddArg(c)
|
||||||
|
|
@ -373,7 +373,7 @@ func regalloc(f *Func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change v to be a copy of c
|
// change v to be a copy of c
|
||||||
v.Op = OpStoreReg8
|
v.Op = OpStoreReg
|
||||||
v.Aux = nil
|
v.Aux = nil
|
||||||
v.resetArgs()
|
v.resetArgs()
|
||||||
v.AddArg(c)
|
v.AddArg(c)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue