mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: request r12 for indirect calls on ppc64le
On ppc64le, functions compiled with -shared expect r12 to hold the function's address for indirect calls. Previously this was enforced by generating a move instruction if the address wasn't already in r12. This change avoids that extra move by requesting r12 in the CALL ops that do indirect calls. As a result of adding support for plugins on ppc64le, it was discovered that there would be more cases where this extra move was needed, so this seemed like a better solution. Updates #20756 Change-Id: I6770885a46990f78c6d2902a715dcdaa822192a1 Reviewed-on: https://go-review.googlesource.com/62890 Run-TryBot: Lynn Boger <laboger@linux.vnet.ibm.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Crawshaw <crawshaw@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
This commit is contained in:
parent
818353022e
commit
b74b43de68
4 changed files with 11 additions and 25 deletions
|
|
@ -1088,17 +1088,8 @@ func ssaGenValue(s *gc.SSAGenState, v *ssa.Value) {
|
||||||
p.To.Type = obj.TYPE_REG
|
p.To.Type = obj.TYPE_REG
|
||||||
p.To.Reg = ppc64.REG_CTR
|
p.To.Reg = ppc64.REG_CTR
|
||||||
|
|
||||||
if gc.Ctxt.Flag_shared && p.From.Reg != ppc64.REG_R12 {
|
if v.Args[0].Reg() != ppc64.REG_R12 {
|
||||||
// Make sure function pointer is in R12 as well when
|
v.Fatalf("Function address for %v should be in R12 %d but is in %d", v.LongString(), ppc64.REG_R12, p.From.Reg)
|
||||||
// compiling Go into PIC.
|
|
||||||
// TODO(mwhudson): it would obviously be better to
|
|
||||||
// change the register allocation to put the value in
|
|
||||||
// R12 already, but I don't know how to do that.
|
|
||||||
// TODO: We have the technology now to implement TODO above.
|
|
||||||
q := s.Prog(ppc64.AMOVD)
|
|
||||||
q.From = p.From
|
|
||||||
q.To.Type = obj.TYPE_REG
|
|
||||||
q.To.Reg = ppc64.REG_R12
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pp := s.Call(v)
|
pp := s.Call(v)
|
||||||
|
|
|
||||||
|
|
@ -128,8 +128,9 @@ func init() {
|
||||||
// cr = buildReg("CR")
|
// cr = buildReg("CR")
|
||||||
// ctr = buildReg("CTR")
|
// ctr = buildReg("CTR")
|
||||||
// lr = buildReg("LR")
|
// lr = buildReg("LR")
|
||||||
tmp = buildReg("R31")
|
tmp = buildReg("R31")
|
||||||
ctxt = buildReg("R11")
|
ctxt = buildReg("R11")
|
||||||
|
callptr = buildReg("R12")
|
||||||
// tls = buildReg("R13")
|
// tls = buildReg("R13")
|
||||||
gp01 = regInfo{inputs: nil, outputs: []regMask{gp}}
|
gp01 = regInfo{inputs: nil, outputs: []regMask{gp}}
|
||||||
gp11 = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
|
gp11 = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
|
||||||
|
|
@ -320,8 +321,8 @@ func init() {
|
||||||
{name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
|
{name: "MOVDconvert", argLength: 2, reg: gp11, asm: "MOVD"},
|
||||||
|
|
||||||
{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
|
{name: "CALLstatic", argLength: 1, reg: regInfo{clobbers: callerSave}, aux: "SymOff", clobberFlags: true, call: true, symEffect: "None"}, // call static function aux.(*obj.LSym). arg0=mem, auxint=argsize, returns mem
|
||||||
{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{gp | sp, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
|
{name: "CALLclosure", argLength: 3, reg: regInfo{inputs: []regMask{callptr, ctxt, 0}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call function via closure. arg0=codeptr, arg1=closure, arg2=mem, auxint=argsize, returns mem
|
||||||
{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{gp}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
|
{name: "CALLinter", argLength: 2, reg: regInfo{inputs: []regMask{callptr}, clobbers: callerSave}, aux: "Int64", clobberFlags: true, call: true}, // call fn by pointer. arg0=codeptr, arg1=mem, auxint=argsize, returns mem
|
||||||
|
|
||||||
// large or unaligned zeroing
|
// large or unaligned zeroing
|
||||||
// arg0 = address of memory to zero (in R3, changed as side effect)
|
// arg0 = address of memory to zero (in R3, changed as side effect)
|
||||||
|
|
|
||||||
|
|
@ -18004,8 +18004,8 @@ var opcodeTable = [...]opInfo{
|
||||||
call: true,
|
call: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{1, 2048}, // R11
|
{0, 4096}, // R12
|
||||||
{0, 1073733626}, // SP R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
{1, 2048}, // R11
|
||||||
},
|
},
|
||||||
clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
|
clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
|
||||||
},
|
},
|
||||||
|
|
@ -18018,7 +18018,7 @@ var opcodeTable = [...]opInfo{
|
||||||
call: true,
|
call: true,
|
||||||
reg: regInfo{
|
reg: regInfo{
|
||||||
inputs: []inputInfo{
|
inputs: []inputInfo{
|
||||||
{0, 1073733624}, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
|
{0, 4096}, // R12
|
||||||
},
|
},
|
||||||
clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
|
clobbers: 576460745860964344, // R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29 g F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 F11 F12 F13 F14 F15 F16 F17 F18 F19 F20 F21 F22 F23 F24 F25 F26
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -562,12 +562,6 @@ func (s *regAllocState) init(f *Func) {
|
||||||
if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
|
if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
|
||||||
s.allocatable &^= 1 << uint(s.f.Config.FPReg)
|
s.allocatable &^= 1 << uint(s.f.Config.FPReg)
|
||||||
}
|
}
|
||||||
if s.f.Config.ctxt.Flag_shared {
|
|
||||||
switch s.f.Config.arch {
|
|
||||||
case "ppc64le": // R2 already reserved.
|
|
||||||
s.allocatable &^= 1 << 12 // R12
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if s.f.Config.LinkReg != -1 {
|
if s.f.Config.LinkReg != -1 {
|
||||||
if isLeaf(f) {
|
if isLeaf(f) {
|
||||||
// Leaf functions don't save/restore the link register.
|
// Leaf functions don't save/restore the link register.
|
||||||
|
|
@ -587,7 +581,7 @@ func (s *regAllocState) init(f *Func) {
|
||||||
case "arm":
|
case "arm":
|
||||||
s.allocatable &^= 1 << 9 // R9
|
s.allocatable &^= 1 << 9 // R9
|
||||||
case "ppc64le": // R2 already reserved.
|
case "ppc64le": // R2 already reserved.
|
||||||
s.allocatable &^= 1 << 12 // R12
|
// nothing to do
|
||||||
case "arm64":
|
case "arm64":
|
||||||
// nothing to do?
|
// nothing to do?
|
||||||
case "386":
|
case "386":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue