[llvm-commits] [llvm] r56608 - /llvm/trunk/lib/Target/X86/X86FastISel.cpp
Dan Gohman
gohman at apple.com
Thu Sep 25 08:24:29 PDT 2008
Author: djg
Date: Thu Sep 25 10:24:26 2008
New Revision: 56608
URL: http://llvm.org/viewvc/llvm-project?rev=56608&view=rev
Log:
PIC support in X86FastISel.
Modified:
llvm/trunk/lib/Target/X86/X86FastISel.cpp
Modified: llvm/trunk/lib/Target/X86/X86FastISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FastISel.cpp?rev=56608&r1=56607&r2=56608&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FastISel.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FastISel.cpp Thu Sep 25 10:24:26 2008
@@ -40,6 +40,10 @@
///
unsigned StackPtr;
+ /// GlobalBaseReg - keeps track of the virtual register mapped onto global
+ /// base register.
+ unsigned GlobalBaseReg;
+
/// X86ScalarSSEf32, X86ScalarSSEf64 - Select between SSE or x87
/// floating point ops.
/// When SSE is available, use it for f32 operations.
@@ -56,6 +60,7 @@
: FastISel(mf, mmi, vm, bm, am) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
+ GlobalBaseReg = 0;
X86ScalarSSEf64 = Subtarget->hasSSE2();
X86ScalarSSEf32 = Subtarget->hasSSE1();
}
@@ -98,6 +103,12 @@
CCAssignFn *CCAssignFnForCall(unsigned CC, bool isTailCall = false);
+ unsigned getGlobalBaseReg();
+
+ const X86InstrInfo *getInstrInfo() const {
+ return static_cast<const X86InstrInfo *>(TM.getInstrInfo());
+ }
+
unsigned TargetMaterializeConstant(Constant *C);
unsigned TargetMaterializeAlloca(AllocaInst *C);
@@ -127,6 +138,16 @@
return (AllowI1 && VT == MVT::i1) || TLI.isTypeLegal(VT);
}
+/// getGlobalBaseReg - Return the the global base register. Output
+/// instructions required to initialize the global base register, if necessary.
+///
+unsigned X86FastISel::getGlobalBaseReg() {
+ assert(!Subtarget->is64Bit() && "X86-64 PIC uses RIP relative addressing");
+ if (!GlobalBaseReg)
+ GlobalBaseReg = getInstrInfo()->initializeGlobalBaseReg(MBB->getParent());
+ return GlobalBaseReg;
+}
+
#include "X86GenCallingConv.inc"
/// CCAssignFnForCall - Selects the correct CCAssignFn for a given calling
@@ -375,11 +396,25 @@
// Handle constant address.
if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ // Can't handle alternate code models yet.
+ if (TM.getCodeModel() != CodeModel::Default &&
+ TM.getCodeModel() != CodeModel::Small)
+ return false;
+
+ // Set up the basic address.
+ AM.GV = GV;
+ if (!isCall &&
+ TM.getRelocationModel() == Reloc::PIC_ &&
+ !Subtarget->is64Bit())
+ AM.Base.Reg = getGlobalBaseReg();
+
+ // Emit an extra load if the ABI requires it.
if (Subtarget->GVRequiresExtraLoad(GV, TM, isCall)) {
// Check to see if we've already materialized this
// value in a register in this block.
if (unsigned Reg = LocalValueMap[V]) {
AM.Base.Reg = Reg;
+ AM.GV = 0;
return true;
}
// Issue load from stub if necessary.
@@ -392,14 +427,12 @@
Opc = X86::MOV64rm;
RC = X86::GR64RegisterClass;
}
- AM.Base.Reg = createResultReg(RC);
- X86AddressMode LocalAM;
- LocalAM.GV = GV;
- addFullAddress(BuildMI(MBB, TII.get(Opc), AM.Base.Reg), LocalAM);
+ unsigned ResultReg = createResultReg(RC);
+ addFullAddress(BuildMI(MBB, TII.get(Opc), ResultReg), AM);
+ AM.Base.Reg = ResultReg;
+ AM.GV = 0;
// Prevent loading GV stub multiple times in same MBB.
LocalValueMap[V] = AM.Base.Reg;
- } else {
- AM.GV = GV;
}
return true;
}
@@ -957,6 +990,17 @@
}
}
+ // ELF / PIC requires GOT in the EBX register before function calls via PLT
+ // GOT pointer.
+ if (!Subtarget->is64Bit() &&
+ TM.getRelocationModel() == Reloc::PIC_ &&
+ Subtarget->isPICStyleGOT()) {
+ TargetRegisterClass *RC = X86::GR32RegisterClass;
+ unsigned Base = getGlobalBaseReg();
+ bool Emitted = TII.copyRegToReg(*MBB, MBB->end(), X86::EBX, Base, RC, RC);
+ assert(Emitted && "Failed to emit a copy instruction!");
+ }
+
// Issue the call.
unsigned CallOpc = CalleeOp
? (Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r)
@@ -964,6 +1008,13 @@
MachineInstrBuilder MIB = CalleeOp
? BuildMI(MBB, TII.get(CallOpc)).addReg(CalleeOp)
: BuildMI(MBB, TII.get(CallOpc)).addGlobalAddress(GV);
+
+ // Add an implicit use GOT pointer in EBX.
+ if (!Subtarget->is64Bit() &&
+ TM.getRelocationModel() == Reloc::PIC_ &&
+ Subtarget->isPICStyleGOT())
+ MIB.addReg(X86::EBX);
+
// Add implicit physical register uses to the call.
while (!RegArgs.empty()) {
MIB.addReg(RegArgs.back());
@@ -1065,10 +1116,6 @@
}
unsigned X86FastISel::TargetMaterializeConstant(Constant *C) {
- // Can't handle PIC-mode yet.
- if (TM.getRelocationModel() == Reloc::PIC_)
- return 0;
-
MVT VT;
if (!isTypeLegal(C->getType(), TLI, VT))
return false;
More information about the llvm-commits
mailing list