mirror of
https://github.com/RPCS3/llvm.git
synced 2025-04-03 05:41:42 +00:00
Rework PPC64 calls. Now we have a LR8/CTR8 register which the PPC64 calls
clobber. This allows LR8 to be save/restored correctly as a 64-bit quantity, instead of handling it as a 32-bit quantity. This unbreaks ppc64 codegen when the code is actually located above the 4G boundary. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@31734 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d10434215d
commit
6a5339ba65
@ -102,6 +102,7 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
|
|||||||
case PPC::IMPLICIT_DEF_VRRC:
|
case PPC::IMPLICIT_DEF_VRRC:
|
||||||
break; // pseudo opcode, no side effects
|
break; // pseudo opcode, no side effects
|
||||||
case PPC::MovePCtoLR:
|
case PPC::MovePCtoLR:
|
||||||
|
case PPC::MovePCtoLR8:
|
||||||
assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
|
assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -60,11 +60,52 @@ def HI48_64 : SDNodeXForm<imm, [{
|
|||||||
def IMPLICIT_DEF_G8RC : Pseudo<(ops G8RC:$rD), "; IMPLICIT_DEF_G8RC $rD",
|
def IMPLICIT_DEF_G8RC : Pseudo<(ops G8RC:$rD), "; IMPLICIT_DEF_G8RC $rD",
|
||||||
[(set G8RC:$rD, (undef))]>;
|
[(set G8RC:$rD, (undef))]>;
|
||||||
|
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// Calls.
|
||||||
|
//
|
||||||
|
|
||||||
|
let Defs = [LR8] in
|
||||||
|
def MovePCtoLR8 : Pseudo<(ops piclabel:$label), "bl $label", []>,
|
||||||
|
PPC970_Unit_BRU;
|
||||||
|
|
||||||
|
let isCall = 1, noResults = 1, PPC970_Unit = 7,
|
||||||
|
// All calls clobber the PPC64 non-callee saved registers.
|
||||||
|
Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,
|
||||||
|
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
|
||||||
|
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
|
||||||
|
LR8,CTR8,
|
||||||
|
CR0,CR1,CR5,CR6,CR7] in {
|
||||||
|
// Convenient aliases for call instructions
|
||||||
|
def BL8 : IForm<18, 0, 1, (ops calltarget:$func, variable_ops),
|
||||||
|
"bl $func", BrB, []>; // See Pat patterns below.
|
||||||
|
|
||||||
|
def BLA8 : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
|
||||||
|
"bla $func", BrB, [(PPCcall (i64 imm:$func))]>;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calls
|
||||||
|
def : Pat<(PPCcall (i64 tglobaladdr:$dst)),
|
||||||
|
(BL8 tglobaladdr:$dst)>;
|
||||||
|
def : Pat<(PPCcall (i64 texternalsym:$dst)),
|
||||||
|
(BL8 texternalsym:$dst)>;
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// 64-bit SPR manipulation instrs.
|
||||||
|
|
||||||
|
def MFCTR8 : XFXForm_1_ext<31, 339, 9, (ops G8RC:$rT), "mfctr $rT", SprMFSPR>,
|
||||||
|
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||||
let Pattern = [(PPCmtctr G8RC:$rS)] in {
|
let Pattern = [(PPCmtctr G8RC:$rS)] in {
|
||||||
def MTCTR8 : XFXForm_7_ext<31, 467, 9, (ops G8RC:$rS), "mtctr $rS", SprMTSPR>,
|
def MTCTR8 : XFXForm_7_ext<31, 467, 9, (ops G8RC:$rS), "mtctr $rS", SprMTSPR>,
|
||||||
PPC970_DGroup_First, PPC970_Unit_FXU;
|
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def MTLR8 : XFXForm_7_ext<31, 467, 8, (ops G8RC:$rS), "mtlr $rS", SprMTSPR>,
|
||||||
|
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||||
|
def MFLR8 : XFXForm_1_ext<31, 339, 8, (ops G8RC:$rT), "mflr $rT", SprMFSPR>,
|
||||||
|
PPC970_DGroup_First, PPC970_Unit_FXU;
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Fixed point instructions.
|
// Fixed point instructions.
|
||||||
//
|
//
|
||||||
|
@ -274,6 +274,7 @@ def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std"
|
|||||||
// PowerPC Instruction Predicate Definitions.
|
// PowerPC Instruction Predicate Definitions.
|
||||||
def FPContractions : Predicate<"!NoExcessFPPrecision">;
|
def FPContractions : Predicate<"!NoExcessFPPrecision">;
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PowerPC Instruction Definitions.
|
// PowerPC Instruction Definitions.
|
||||||
|
|
||||||
@ -328,6 +329,7 @@ let isTerminator = 1, isBarrier = 1, noResults = 1, PPC970_Unit = 7 in {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
let Defs = [LR] in
|
let Defs = [LR] in
|
||||||
def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
|
def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
|
||||||
PPC970_Unit_BRU;
|
PPC970_Unit_BRU;
|
||||||
@ -1014,9 +1016,9 @@ def : Pat<(and (rotl GPRC:$in, GPRC:$sh), maskimm32:$imm),
|
|||||||
(RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
|
(RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
def : Pat<(PPCcall tglobaladdr:$dst),
|
def : Pat<(PPCcall (i32 tglobaladdr:$dst)),
|
||||||
(BL tglobaladdr:$dst)>;
|
(BL tglobaladdr:$dst)>;
|
||||||
def : Pat<(PPCcall texternalsym:$dst),
|
def : Pat<(PPCcall (i32 texternalsym:$dst)),
|
||||||
(BL texternalsym:$dst)>;
|
(BL texternalsym:$dst)>;
|
||||||
|
|
||||||
// Hi and Lo for Darwin Global Addresses.
|
// Hi and Lo for Darwin Global Addresses.
|
||||||
|
@ -99,12 +99,32 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
unsigned SrcReg, int FrameIdx,
|
unsigned SrcReg, int FrameIdx,
|
||||||
const TargetRegisterClass *RC) const {
|
const TargetRegisterClass *RC) const {
|
||||||
if (SrcReg == PPC::LR) {
|
if (RC == PPC::GPRCRegisterClass) {
|
||||||
// FIXME: this spills LR immediately to memory in one step. To do this, we
|
if (SrcReg != PPC::LR) {
|
||||||
// use R11, which we know cannot be used in the prolog/epilog. This is a
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
|
||||||
// hack.
|
} else {
|
||||||
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
|
// FIXME: this spills LR immediately to memory in one step. To do this,
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
|
// we use R11, which we know cannot be used in the prolog/epilog. This is
|
||||||
|
// a hack.
|
||||||
|
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11),
|
||||||
|
FrameIdx);
|
||||||
|
}
|
||||||
|
} else if (RC == PPC::G8RCRegisterClass) {
|
||||||
|
if (SrcReg != PPC::LR8) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg), FrameIdx);
|
||||||
|
} else {
|
||||||
|
// FIXME: this spills LR immediately to memory in one step. To do this,
|
||||||
|
// we use R11, which we know cannot be used in the prolog/epilog. This is
|
||||||
|
// a hack.
|
||||||
|
BuildMI(MBB, MI, PPC::MFLR8, 1, PPC::X11);
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(PPC::X11),
|
||||||
|
FrameIdx);
|
||||||
|
}
|
||||||
|
} else if (RC == PPC::F8RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
|
||||||
|
} else if (RC == PPC::F4RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
|
||||||
} else if (RC == PPC::CRRCRegisterClass) {
|
} else if (RC == PPC::CRRCRegisterClass) {
|
||||||
// FIXME: We use R0 here, because it isn't available for RA.
|
// FIXME: We use R0 here, because it isn't available for RA.
|
||||||
// We need to store the CR in the low 4-bits of the saved value. First,
|
// We need to store the CR in the low 4-bits of the saved value. First,
|
||||||
@ -121,14 +141,6 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R0), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R0), FrameIdx);
|
||||||
} else if (RC == PPC::GPRCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
|
|
||||||
} else if (RC == PPC::G8RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg),FrameIdx);
|
|
||||||
} else if (RC == PPC::F8RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
|
|
||||||
} else if (RC == PPC::F4RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
|
|
||||||
} else if (RC == PPC::VRRCRegisterClass) {
|
} else if (RC == PPC::VRRCRegisterClass) {
|
||||||
// We don't have indexed addressing for vector loads. Emit:
|
// We don't have indexed addressing for vector loads. Emit:
|
||||||
// R11 = ADDI FI#
|
// R11 = ADDI FI#
|
||||||
@ -146,12 +158,27 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|||||||
|
|
||||||
void
|
void
|
||||||
PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator MI,
|
MachineBasicBlock::iterator MI,
|
||||||
unsigned DestReg, int FrameIdx,
|
unsigned DestReg, int FrameIdx,
|
||||||
const TargetRegisterClass *RC) const {
|
const TargetRegisterClass *RC) const {
|
||||||
if (DestReg == PPC::LR) {
|
if (RC == PPC::GPRCRegisterClass) {
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
if (DestReg != PPC::LR) {
|
||||||
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
|
||||||
|
} else {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
|
||||||
|
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
|
||||||
|
}
|
||||||
|
} else if (RC == PPC::G8RCRegisterClass) {
|
||||||
|
if (DestReg != PPC::LR8) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
|
||||||
|
} else {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, PPC::R11), FrameIdx);
|
||||||
|
BuildMI(MBB, MI, PPC::MTLR8, 1).addReg(PPC::R11);
|
||||||
|
}
|
||||||
|
} else if (RC == PPC::F8RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
|
||||||
|
} else if (RC == PPC::F4RCRegisterClass) {
|
||||||
|
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
|
||||||
} else if (RC == PPC::CRRCRegisterClass) {
|
} else if (RC == PPC::CRRCRegisterClass) {
|
||||||
// FIXME: We use R0 here, because it isn't available for RA.
|
// FIXME: We use R0 here, because it isn't available for RA.
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R0), FrameIdx);
|
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R0), FrameIdx);
|
||||||
@ -166,14 +193,6 @@ PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|||||||
}
|
}
|
||||||
|
|
||||||
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R0);
|
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R0);
|
||||||
} else if (RC == PPC::GPRCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
|
|
||||||
} else if (RC == PPC::G8RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
|
|
||||||
} else if (RC == PPC::F8RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
|
|
||||||
} else if (RC == PPC::F4RCRegisterClass) {
|
|
||||||
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
|
|
||||||
} else if (RC == PPC::VRRCRegisterClass) {
|
} else if (RC == PPC::VRRCRegisterClass) {
|
||||||
// We don't have indexed addressing for vector loads. Emit:
|
// We don't have indexed addressing for vector loads. Emit:
|
||||||
// R11 = ADDI FI#
|
// R11 = ADDI FI#
|
||||||
@ -251,7 +270,7 @@ const unsigned* PPCRegisterInfo::getCalleeSaveRegs() const {
|
|||||||
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
|
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
|
||||||
PPC::V28, PPC::V29, PPC::V30, PPC::V31,
|
PPC::V28, PPC::V29, PPC::V30, PPC::V31,
|
||||||
|
|
||||||
PPC::LR, 0
|
PPC::LR8, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegs :
|
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegs :
|
||||||
@ -303,7 +322,7 @@ PPCRegisterInfo::getCalleeSaveRegClasses() const {
|
|||||||
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
|
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
|
||||||
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
|
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
|
||||||
|
|
||||||
&PPC::GPRCRegClass, 0
|
&PPC::G8RCRegClass, 0
|
||||||
};
|
};
|
||||||
|
|
||||||
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegClasses :
|
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegClasses :
|
||||||
@ -780,7 +799,8 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned PPCRegisterInfo::getRARegister() const {
|
unsigned PPCRegisterInfo::getRARegister() const {
|
||||||
return PPC::LR;
|
return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {
|
||||||
|
@ -195,8 +195,13 @@ def CR7 : CR<7, "cr7">, DwarfRegNum<75>;
|
|||||||
|
|
||||||
// Link register
|
// Link register
|
||||||
def LR : SPR<8, "lr">, DwarfRegNum<65>;
|
def LR : SPR<8, "lr">, DwarfRegNum<65>;
|
||||||
|
//let Aliases = [LR] in
|
||||||
|
def LR8 : SPR<8, "lr">, DwarfRegNum<65>;
|
||||||
|
|
||||||
// Count register
|
// Count register
|
||||||
def CTR : SPR<9, "ctr">, DwarfRegNum<66>;
|
def CTR : SPR<9, "ctr">, DwarfRegNum<66>;
|
||||||
|
def CTR8 : SPR<9, "ctr">, DwarfRegNum<66>;
|
||||||
|
|
||||||
// VRsave register
|
// VRsave register
|
||||||
def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<107>;
|
def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<107>;
|
||||||
|
|
||||||
@ -229,7 +234,7 @@ def GPRC : RegisterClass<"PPC", [i32], 32,
|
|||||||
def G8RC : RegisterClass<"PPC", [i64], 64,
|
def G8RC : RegisterClass<"PPC", [i64], 64,
|
||||||
[X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
|
[X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
|
||||||
X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
|
X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
|
||||||
X16, X15, X14, X13, X31, X0, X1]>
|
X16, X15, X14, X13, X31, X0, X1, LR8]>
|
||||||
{
|
{
|
||||||
let MethodProtos = [{
|
let MethodProtos = [{
|
||||||
iterator allocation_order_begin(const MachineFunction &MF) const;
|
iterator allocation_order_begin(const MachineFunction &MF) const;
|
||||||
@ -243,9 +248,9 @@ def G8RC : RegisterClass<"PPC", [i64], 64,
|
|||||||
G8RCClass::iterator
|
G8RCClass::iterator
|
||||||
G8RCClass::allocation_order_end(const MachineFunction &MF) const {
|
G8RCClass::allocation_order_end(const MachineFunction &MF) const {
|
||||||
if (hasFP(MF))
|
if (hasFP(MF))
|
||||||
return end()-3;
|
return end()-4;
|
||||||
else
|
else
|
||||||
return end()-2;
|
return end()-3;
|
||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user