Skip to content

Commit 44dbdbe

Browse files
committed
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. llvm-svn: 31734
1 parent b542925 commit 44dbdbe

File tree

5 files changed

+107
-38
lines changed

5 files changed

+107
-38
lines changed

llvm/lib/Target/PowerPC/PPCCodeEmitter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
102102
case PPC::IMPLICIT_DEF_VRRC:
103103
break; // pseudo opcode, no side effects
104104
case PPC::MovePCtoLR:
105+
case PPC::MovePCtoLR8:
105106
assert(0 && "CodeEmitter does not support MovePCtoLR instruction");
106107
break;
107108
}

llvm/lib/Target/PowerPC/PPCInstr64Bit.td

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,52 @@ def HI48_64 : SDNodeXForm<imm, [{
6060
def IMPLICIT_DEF_G8RC : Pseudo<(ops G8RC:$rD), "; IMPLICIT_DEF_G8RC $rD",
6161
[(set G8RC:$rD, (undef))]>;
6262

63+
64+
//===----------------------------------------------------------------------===//
65+
// Calls.
66+
//
67+
68+
let Defs = [LR8] in
69+
def MovePCtoLR8 : Pseudo<(ops piclabel:$label), "bl $label", []>,
70+
PPC970_Unit_BRU;
71+
72+
let isCall = 1, noResults = 1, PPC970_Unit = 7,
73+
// All calls clobber the PPC64 non-callee saved registers.
74+
Defs = [X0,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,
75+
F0,F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,F13,
76+
V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,V10,V11,V12,V13,V14,V15,V16,V17,V18,V19,
77+
LR8,CTR8,
78+
CR0,CR1,CR5,CR6,CR7] in {
79+
// Convenient aliases for call instructions
80+
def BL8 : IForm<18, 0, 1, (ops calltarget:$func, variable_ops),
81+
"bl $func", BrB, []>; // See Pat patterns below.
82+
83+
def BLA8 : IForm<18, 1, 1, (ops aaddr:$func, variable_ops),
84+
"bla $func", BrB, [(PPCcall (i64 imm:$func))]>;
85+
}
86+
87+
// Calls
88+
def : Pat<(PPCcall (i64 tglobaladdr:$dst)),
89+
(BL8 tglobaladdr:$dst)>;
90+
def : Pat<(PPCcall (i64 texternalsym:$dst)),
91+
(BL8 texternalsym:$dst)>;
92+
93+
//===----------------------------------------------------------------------===//
94+
// 64-bit SPR manipulation instrs.
95+
96+
def MFCTR8 : XFXForm_1_ext<31, 339, 9, (ops G8RC:$rT), "mfctr $rT", SprMFSPR>,
97+
PPC970_DGroup_First, PPC970_Unit_FXU;
6398
let Pattern = [(PPCmtctr G8RC:$rS)] in {
6499
def MTCTR8 : XFXForm_7_ext<31, 467, 9, (ops G8RC:$rS), "mtctr $rS", SprMTSPR>,
65-
PPC970_DGroup_First, PPC970_Unit_FXU;
100+
PPC970_DGroup_First, PPC970_Unit_FXU;
66101
}
67102

103+
def MTLR8 : XFXForm_7_ext<31, 467, 8, (ops G8RC:$rS), "mtlr $rS", SprMTSPR>,
104+
PPC970_DGroup_First, PPC970_Unit_FXU;
105+
def MFLR8 : XFXForm_1_ext<31, 339, 8, (ops G8RC:$rT), "mflr $rT", SprMFSPR>,
106+
PPC970_DGroup_First, PPC970_Unit_FXU;
107+
108+
68109
//===----------------------------------------------------------------------===//
69110
// Fixed point instructions.
70111
//

llvm/lib/Target/PowerPC/PPCInstrInfo.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ def ixaddr : ComplexPattern<iPTR, 2, "SelectAddrImmShift", [], []>; // "std"
274274
// PowerPC Instruction Predicate Definitions.
275275
def FPContractions : Predicate<"!NoExcessFPPrecision">;
276276

277+
277278
//===----------------------------------------------------------------------===//
278279
// PowerPC Instruction Definitions.
279280

@@ -328,6 +329,7 @@ let isTerminator = 1, isBarrier = 1, noResults = 1, PPC970_Unit = 7 in {
328329
}
329330

330331

332+
331333
let Defs = [LR] in
332334
def MovePCtoLR : Pseudo<(ops piclabel:$label), "bl $label", []>,
333335
PPC970_Unit_BRU;
@@ -1014,9 +1016,9 @@ def : Pat<(and (rotl GPRC:$in, GPRC:$sh), maskimm32:$imm),
10141016
(RLWNM GPRC:$in, GPRC:$sh, (MB maskimm32:$imm), (ME maskimm32:$imm))>;
10151017

10161018
// Calls
1017-
def : Pat<(PPCcall tglobaladdr:$dst),
1019+
def : Pat<(PPCcall (i32 tglobaladdr:$dst)),
10181020
(BL tglobaladdr:$dst)>;
1019-
def : Pat<(PPCcall texternalsym:$dst),
1021+
def : Pat<(PPCcall (i32 texternalsym:$dst)),
10201022
(BL texternalsym:$dst)>;
10211023

10221024
// Hi and Lo for Darwin Global Addresses.

llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp

Lines changed: 51 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,32 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
9999
MachineBasicBlock::iterator MI,
100100
unsigned SrcReg, int FrameIdx,
101101
const TargetRegisterClass *RC) const {
102-
if (SrcReg == PPC::LR) {
103-
// FIXME: this spills LR immediately to memory in one step. To do this, we
104-
// use R11, which we know cannot be used in the prolog/epilog. This is a
105-
// hack.
106-
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
107-
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11), FrameIdx);
102+
if (RC == PPC::GPRCRegisterClass) {
103+
if (SrcReg != PPC::LR) {
104+
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
105+
} else {
106+
// FIXME: this spills LR immediately to memory in one step. To do this,
107+
// we use R11, which we know cannot be used in the prolog/epilog. This is
108+
// a hack.
109+
BuildMI(MBB, MI, PPC::MFLR, 1, PPC::R11);
110+
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R11),
111+
FrameIdx);
112+
}
113+
} else if (RC == PPC::G8RCRegisterClass) {
114+
if (SrcReg != PPC::LR8) {
115+
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg), FrameIdx);
116+
} else {
117+
// FIXME: this spills LR immediately to memory in one step. To do this,
118+
// we use R11, which we know cannot be used in the prolog/epilog. This is
119+
// a hack.
120+
BuildMI(MBB, MI, PPC::MFLR8, 1, PPC::X11);
121+
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(PPC::X11),
122+
FrameIdx);
123+
}
124+
} else if (RC == PPC::F8RCRegisterClass) {
125+
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
126+
} else if (RC == PPC::F4RCRegisterClass) {
127+
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
108128
} else if (RC == PPC::CRRCRegisterClass) {
109129
// FIXME: We use R0 here, because it isn't available for RA.
110130
// We need to store the CR in the low 4-bits of the saved value. First,
@@ -121,14 +141,6 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
121141
}
122142

123143
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(PPC::R0), FrameIdx);
124-
} else if (RC == PPC::GPRCRegisterClass) {
125-
addFrameReference(BuildMI(MBB, MI, PPC::STW, 3).addReg(SrcReg),FrameIdx);
126-
} else if (RC == PPC::G8RCRegisterClass) {
127-
addFrameReference(BuildMI(MBB, MI, PPC::STD, 3).addReg(SrcReg),FrameIdx);
128-
} else if (RC == PPC::F8RCRegisterClass) {
129-
addFrameReference(BuildMI(MBB, MI, PPC::STFD, 3).addReg(SrcReg),FrameIdx);
130-
} else if (RC == PPC::F4RCRegisterClass) {
131-
addFrameReference(BuildMI(MBB, MI, PPC::STFS, 3).addReg(SrcReg),FrameIdx);
132144
} else if (RC == PPC::VRRCRegisterClass) {
133145
// We don't have indexed addressing for vector loads. Emit:
134146
// R11 = ADDI FI#
@@ -146,12 +158,27 @@ PPCRegisterInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
146158

147159
void
148160
PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
149-
MachineBasicBlock::iterator MI,
150-
unsigned DestReg, int FrameIdx,
151-
const TargetRegisterClass *RC) const {
152-
if (DestReg == PPC::LR) {
153-
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
154-
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
161+
MachineBasicBlock::iterator MI,
162+
unsigned DestReg, int FrameIdx,
163+
const TargetRegisterClass *RC) const {
164+
if (RC == PPC::GPRCRegisterClass) {
165+
if (DestReg != PPC::LR) {
166+
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
167+
} else {
168+
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R11), FrameIdx);
169+
BuildMI(MBB, MI, PPC::MTLR, 1).addReg(PPC::R11);
170+
}
171+
} else if (RC == PPC::G8RCRegisterClass) {
172+
if (DestReg != PPC::LR8) {
173+
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
174+
} else {
175+
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, PPC::R11), FrameIdx);
176+
BuildMI(MBB, MI, PPC::MTLR8, 1).addReg(PPC::R11);
177+
}
178+
} else if (RC == PPC::F8RCRegisterClass) {
179+
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
180+
} else if (RC == PPC::F4RCRegisterClass) {
181+
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
155182
} else if (RC == PPC::CRRCRegisterClass) {
156183
// FIXME: We use R0 here, because it isn't available for RA.
157184
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, PPC::R0), FrameIdx);
@@ -166,14 +193,6 @@ PPCRegisterInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
166193
}
167194

168195
BuildMI(MBB, MI, PPC::MTCRF, 1, DestReg).addReg(PPC::R0);
169-
} else if (RC == PPC::GPRCRegisterClass) {
170-
addFrameReference(BuildMI(MBB, MI, PPC::LWZ, 2, DestReg), FrameIdx);
171-
} else if (RC == PPC::G8RCRegisterClass) {
172-
addFrameReference(BuildMI(MBB, MI, PPC::LD, 2, DestReg), FrameIdx);
173-
} else if (RC == PPC::F8RCRegisterClass) {
174-
addFrameReference(BuildMI(MBB, MI, PPC::LFD, 2, DestReg), FrameIdx);
175-
} else if (RC == PPC::F4RCRegisterClass) {
176-
addFrameReference(BuildMI(MBB, MI, PPC::LFS, 2, DestReg), FrameIdx);
177196
} else if (RC == PPC::VRRCRegisterClass) {
178197
// We don't have indexed addressing for vector loads. Emit:
179198
// R11 = ADDI FI#
@@ -251,7 +270,7 @@ const unsigned* PPCRegisterInfo::getCalleeSaveRegs() const {
251270
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
252271
PPC::V28, PPC::V29, PPC::V30, PPC::V31,
253272

254-
PPC::LR, 0
273+
PPC::LR8, 0
255274
};
256275

257276
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegs :
@@ -303,7 +322,7 @@ PPCRegisterInfo::getCalleeSaveRegClasses() const {
303322
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
304323
&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,&PPC::VRRCRegClass,
305324

306-
&PPC::GPRCRegClass, 0
325+
&PPC::G8RCRegClass, 0
307326
};
308327

309328
return Subtarget.isPPC64() ? Darwin64_CalleeSaveRegClasses :
@@ -780,7 +799,8 @@ void PPCRegisterInfo::emitEpilogue(MachineFunction &MF,
780799
}
781800

782801
unsigned PPCRegisterInfo::getRARegister() const {
783-
return PPC::LR;
802+
return !Subtarget.isPPC64() ? PPC::LR : PPC::LR8;
803+
784804
}
785805

786806
unsigned PPCRegisterInfo::getFrameRegister(MachineFunction &MF) const {

llvm/lib/Target/PowerPC/PPCRegisterInfo.td

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,13 @@ def CR7 : CR<7, "cr7">, DwarfRegNum<75>;
195195

196196
// Link register
197197
def LR : SPR<8, "lr">, DwarfRegNum<65>;
198+
//let Aliases = [LR] in
199+
def LR8 : SPR<8, "lr">, DwarfRegNum<65>;
200+
198201
// Count register
199-
def CTR : SPR<9, "ctr">, DwarfRegNum<66>;
202+
def CTR : SPR<9, "ctr">, DwarfRegNum<66>;
203+
def CTR8 : SPR<9, "ctr">, DwarfRegNum<66>;
204+
200205
// VRsave register
201206
def VRSAVE: SPR<256, "VRsave">, DwarfRegNum<107>;
202207

@@ -229,7 +234,7 @@ def GPRC : RegisterClass<"PPC", [i32], 32,
229234
def G8RC : RegisterClass<"PPC", [i64], 64,
230235
[X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12,
231236
X30, X29, X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, X18, X17,
232-
X16, X15, X14, X13, X31, X0, X1]>
237+
X16, X15, X14, X13, X31, X0, X1, LR8]>
233238
{
234239
let MethodProtos = [{
235240
iterator allocation_order_begin(const MachineFunction &MF) const;
@@ -243,9 +248,9 @@ def G8RC : RegisterClass<"PPC", [i64], 64,
243248
G8RCClass::iterator
244249
G8RCClass::allocation_order_end(const MachineFunction &MF) const {
245250
if (hasFP(MF))
246-
return end()-3;
251+
return end()-4;
247252
else
248-
return end()-2;
253+
return end()-3;
249254
}
250255
}];
251256
}

0 commit comments

Comments
 (0)