p.To.Type = obj.TYPE_REG
p.To.Reg = ppc64.REG_CTR
- if gc.Ctxt.Flag_shared && p.From.Reg != ppc64.REG_R12 {
- // Make sure function pointer is in R12 as well when
- // 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
+ if v.Args[0].Reg() != ppc64.REG_R12 {
+ v.Fatalf("Function address for %v should be in R12 %d but is in %d", v.LongString(), ppc64.REG_R12, p.From.Reg)
}
pp := s.Call(v)
// cr = buildReg("CR")
// ctr = buildReg("CTR")
// lr = buildReg("LR")
- tmp = buildReg("R31")
- ctxt = buildReg("R11")
+ tmp = buildReg("R31")
+ ctxt = buildReg("R11")
+ callptr = buildReg("R12")
// tls = buildReg("R13")
gp01 = regInfo{inputs: nil, outputs: []regMask{gp}}
gp11 = regInfo{inputs: []regMask{gp | sp | sb}, outputs: []regMask{gp}}
{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: "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: "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: "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{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
// arg0 = address of memory to zero (in R3, changed as side effect)
call: true,
reg: regInfo{
inputs: []inputInfo{
- {1, 2048}, // R11
- {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
+ {0, 4096}, // R12
+ {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
},
call: true,
reg: regInfo{
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
},
if s.f.Config.ctxt.Framepointer_enabled && s.f.Config.FPReg >= 0 {
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 isLeaf(f) {
// Leaf functions don't save/restore the link register.
case "arm":
s.allocatable &^= 1 << 9 // R9
case "ppc64le": // R2 already reserved.
- s.allocatable &^= 1 << 12 // R12
+ // nothing to do
case "arm64":
// nothing to do?
case "386":