[llvm-commits] CVS: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp X86ATTAsmPrinter.h X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86ISelLowering.h X86InstrInfo.td X86IntelAsmPrinter.cpp X86IntelAsmPrinter.h X86Subtarget.cpp X86Subtarget.h
Evan Cheng
evan.cheng at apple.com
Fri Feb 17 16:15:17 PST 2006
Changes in directory llvm/lib/Target/X86:
X86ATTAsmPrinter.cpp updated: 1.22 -> 1.23
X86ATTAsmPrinter.h updated: 1.6 -> 1.7
X86ISelDAGToDAG.cpp updated: 1.49 -> 1.50
X86ISelLowering.cpp updated: 1.88 -> 1.89
X86ISelLowering.h updated: 1.27 -> 1.28
X86InstrInfo.td updated: 1.237 -> 1.238
X86IntelAsmPrinter.cpp updated: 1.16 -> 1.17
X86IntelAsmPrinter.h updated: 1.7 -> 1.8
X86Subtarget.cpp updated: 1.25 -> 1.26
X86Subtarget.h updated: 1.11 -> 1.12
---
Log message:
x86 / Darwin PIC support.
---
Diffs of the changes: (+143 -36)
X86ATTAsmPrinter.cpp | 23 +++++++++++++----------
X86ATTAsmPrinter.h | 1 +
X86ISelDAGToDAG.cpp | 39 +++++++++++++++++++++++++++++++++++++++
X86ISelLowering.cpp | 40 ++++++++++++++++++++++++++++++++--------
X86ISelLowering.h | 4 ++++
X86InstrInfo.td | 7 +++++++
X86IntelAsmPrinter.cpp | 47 +++++++++++++++++++++++++++++++++++++++++++----
X86IntelAsmPrinter.h | 1 +
X86Subtarget.cpp | 5 +----
X86Subtarget.h | 12 ++----------
10 files changed, 143 insertions(+), 36 deletions(-)
Index: llvm/lib/Target/X86/X86ATTAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.22 llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.23
--- llvm/lib/Target/X86/X86ATTAsmPrinter.cpp:1.22 Tue Feb 7 02:38:37 2006
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.cpp Fri Feb 17 18:15:05 2006
@@ -18,6 +18,7 @@
#include "X86TargetMachine.h"
#include "llvm/Module.h"
#include "llvm/Support/Mangler.h"
+#include "llvm/Target/TargetOptions.h"
#include <iostream>
using namespace llvm;
using namespace x86;
@@ -116,9 +117,9 @@
case MachineOperand::MO_GlobalAddress: {
bool isCallOp = Modifier && !strcmp(Modifier, "call");
bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ if (!isMemOp && !isCallOp) O << '$';
// Darwin block shameless ripped from PPCAsmPrinter.cpp
if (forDarwin) {
- if (!isMemOp && !isCallOp) O << '$';
GlobalValue *GV = MO.getGlobal();
std::string Name = Mang->getValueName(GV);
// Link-once, External, or Weakly-linked global variables need
@@ -132,19 +133,14 @@
} else {
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
+ if (PICEnabled)
+ O << "-\"L" << getFunctionNumber() << "$pb\"";
}
} else {
O << Mang->getValueName(GV);
}
- int Offset = MO.getOffset();
- if (Offset > 0)
- O << "+" << Offset;
- else if (Offset < 0)
- O << Offset;
- return;
- }
- if (!isMemOp && !isCallOp) O << '$';
- O << Mang->getValueName(MO.getGlobal());
+ } else
+ O << Mang->getValueName(MO.getGlobal());
int Offset = MO.getOffset();
if (Offset > 0)
O << "+" << Offset;
@@ -202,6 +198,8 @@
} else if (BaseReg.isConstantPoolIndex()) {
O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
<< BaseReg.getConstantPoolIndex();
+ if (forDarwin && PICEnabled)
+ O << "-\"L" << getFunctionNumber() << "$pb\"";
if (DispSpec.getImmedValue())
O << "+" << DispSpec.getImmedValue();
if (IndexReg.getReg()) {
@@ -238,6 +236,11 @@
}
}
+void X86ATTAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
+ O << "\"L" << getFunctionNumber() << "$pb\"\n";
+ O << "\"L" << getFunctionNumber() << "$pb\":";
+}
+
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
///
Index: llvm/lib/Target/X86/X86ATTAsmPrinter.h
diff -u llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.6 llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.7
--- llvm/lib/Target/X86/X86ATTAsmPrinter.h:1.6 Mon Feb 6 17:41:19 2006
+++ llvm/lib/Target/X86/X86ATTAsmPrinter.h Fri Feb 17 18:15:05 2006
@@ -62,6 +62,7 @@
void printMachineInstruction(const MachineInstr *MI);
void printSSECC(const MachineInstr *MI, unsigned Op);
void printMemReference(const MachineInstr *MI, unsigned Op);
+ void printPICLabel(const MachineInstr *MI, unsigned Op);
bool runOnMachineFunction(MachineFunction &F);
};
Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.49 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.50
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.49 Fri Feb 10 20:05:36 2006
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp Fri Feb 17 18:15:05 2006
@@ -85,12 +85,20 @@
/// Subtarget - Keep a pointer to the X86Subtarget around so that we can
/// make the right decision when generating code for different targets.
const X86Subtarget *Subtarget;
+
+ unsigned GlobalBaseReg;
public:
X86DAGToDAGISel(TargetMachine &TM)
: SelectionDAGISel(X86Lowering), X86Lowering(TM) {
Subtarget = &TM.getSubtarget<X86Subtarget>();
}
+ virtual bool runOnFunction(Function &Fn) {
+ // Make sure we re-emit a set of the global base reg if necessary
+ GlobalBaseReg = 0;
+ return SelectionDAGISel::runOnFunction(Fn);
+ }
+
virtual const char *getPassName() const {
return "X86 DAG->DAG Instruction Selection";
}
@@ -145,6 +153,10 @@
return CurDAG->getTargetConstant(Imm, MVT::i32);
}
+ /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
+ /// base register. Return the virtual register that holds this value.
+ SDOperand getGlobalBaseReg();
+
#ifndef NDEBUG
unsigned Indent;
#endif
@@ -283,6 +295,7 @@
break;
case ISD::ConstantPool:
+ case ISD::TargetConstantPool:
if (AM.BaseType == X86ISelAddressMode::RegBase && AM.Base.Reg.Val == 0) {
if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(N)) {
AM.BaseType = X86ISelAddressMode::ConstantPoolBase;
@@ -377,6 +390,10 @@
// Is the base register already occupied?
if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) {
+ // TargetConstantPool cannot be anything but the base.
+ if (N.getOpcode() == ISD::TargetConstantPool)
+ return true;
+
// If so, check to see if the scale index register is set.
if (AM.IndexReg.Val == 0) {
AM.IndexReg = N;
@@ -478,6 +495,24 @@
return false;
}
+/// getGlobalBaseReg - Output the instructions required to put the
+/// base address to use for accessing globals into a register.
+///
+SDOperand X86DAGToDAGISel::getGlobalBaseReg() {
+ if (!GlobalBaseReg) {
+ // Insert the set of GlobalBaseReg into the first MBB of the function
+ MachineBasicBlock &FirstMBB = BB->getParent()->front();
+ MachineBasicBlock::iterator MBBI = FirstMBB.begin();
+ SSARegMap *RegMap = BB->getParent()->getSSARegMap();
+ // FIXME: when we get to LP64, we will need to create the appropriate
+ // type of register here.
+ GlobalBaseReg = RegMap->createVirtualRegister(X86::R32RegisterClass);
+ BuildMI(FirstMBB, MBBI, X86::MovePCtoStack, 0);
+ BuildMI(FirstMBB, MBBI, X86::POP32r, 1, GlobalBaseReg);
+ }
+ return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
+}
+
void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
SDNode *Node = N.Val;
MVT::ValueType NVT = Node->getValueType(0);
@@ -603,6 +638,10 @@
#endif
return;
}
+
+ case X86ISD::GlobalBaseReg:
+ Result = getGlobalBaseReg();
+ return;
case ISD::SDIV:
case ISD::UDIV:
Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.88 llvm/lib/Target/X86/X86ISelLowering.cpp:1.89
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.88 Fri Feb 17 01:09:27 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp Fri Feb 17 18:15:05 2006
@@ -162,6 +162,7 @@
// X86 ret instruction may pop stack.
setOperationAction(ISD::RET , MVT::Other, Custom);
// Darwin ABI issue.
+ setOperationAction(ISD::ConstantPool , MVT::i32 , Custom);
setOperationAction(ISD::GlobalAddress , MVT::i32 , Custom);
// 64-bit addm sub, shl, sra, srl (iff 32-bit x86)
setOperationAction(ISD::SHL_PARTS , MVT::i32 , Custom);
@@ -1788,21 +1789,43 @@
return DAG.getNode(X86ISD::REP_MOVS, MVT::Other, Chain,
DAG.getValueType(AVT), InFlag);
}
+ case ISD::ConstantPool: {
+ ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
+ SDOperand Result =
+ DAG.getTargetConstantPool(CP->get(), getPointerTy(), CP->getAlignment());
+ // Only lower ConstantPool on Darwin.
+ if (getTargetMachine().
+ getSubtarget<X86Subtarget>().isTargetDarwin()) {
+ // With PIC, the address is actually $g + Offset.
+ if (PICEnabled)
+ Result = DAG.getNode(ISD::ADD, getPointerTy(),
+ DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result);
+ }
+
+ return Result;
+ }
case ISD::GlobalAddress: {
SDOperand Result;
- GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
- // For Darwin, external and weak symbols are indirect, so we want to load
- // the value at address GV, not the value of GV itself. This means that
- // the GlobalAddress must be in the base or index register of the address,
- // not the GV offset field.
+ // Only lower GlobalAddress on Darwin.
if (getTargetMachine().
- getSubtarget<X86Subtarget>().getIndirectExternAndWeakGlobals()) {
+ getSubtarget<X86Subtarget>().isTargetDarwin()) {
+ GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+ SDOperand Addr = DAG.getTargetGlobalAddress(GV, getPointerTy());
+ // With PIC, the address is actually $g + Offset.
+ if (PICEnabled)
+ Addr = DAG.getNode(ISD::ADD, getPointerTy(),
+ DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Addr);
+
+ // For Darwin, external and weak symbols are indirect, so we want to load
+ // the value at address GV, not the value of GV itself. This means that
+ // the GlobalAddress must be in the base or index register of the address,
+ // not the GV offset field.
if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
(GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))
Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(),
- DAG.getTargetGlobalAddress(GV, getPointerTy()),
- DAG.getSrcValue(NULL));
+ Addr, DAG.getSrcValue(NULL));
}
+
return Result;
}
case ISD::VASTART: {
@@ -1913,6 +1936,7 @@
case X86ISD::REP_STOS: return "X86ISD::RET_STOS";
case X86ISD::REP_MOVS: return "X86ISD::RET_MOVS";
case X86ISD::LOAD_PACK: return "X86ISD::LOAD_PACK";
+ case X86ISD::GlobalBaseReg: return "X86ISD::GlobalBaseReg";
}
}
Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.27 llvm/lib/Target/X86/X86ISelLowering.h:1.28
--- llvm/lib/Target/X86/X86ISelLowering.h:1.27 Thu Feb 16 23:43:56 2006
+++ llvm/lib/Target/X86/X86ISelLowering.h Fri Feb 17 18:15:05 2006
@@ -137,6 +137,10 @@
/// LOAD_PACK Load a 128-bit packed float / double value. It has the same
/// operands as a normal load.
LOAD_PACK,
+
+ /// GlobalBaseReg - On Darwin, this node represents the result of the popl
+ /// at function entry, used for PIC code.
+ GlobalBaseReg,
};
// X86 specific condition code. These correspond to X86_*_COND in
Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.237 llvm/lib/Target/X86/X86InstrInfo.td:1.238
--- llvm/lib/Target/X86/X86InstrInfo.td:1.237 Thu Feb 16 23:43:56 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td Fri Feb 17 18:15:05 2006
@@ -144,6 +144,10 @@
let PrintMethod = "printSSECC";
}
+def piclabel: Operand<i32> {
+ let PrintMethod = "printPICLabel";
+}
+
// A couple of more descriptive operand definitions.
// 16-bits but only 8 bits are significant.
def i16i8imm : Operand<i16>;
@@ -537,6 +541,9 @@
def POP32r : I<0x58, AddRegFrm,
(ops R32:$reg), "pop{l} $reg", []>, Imp<[ESP],[ESP]>;
+def MovePCtoStack : I<0, Pseudo, (ops piclabel:$label),
+ "call $label", []>;
+
let isTwoAddress = 1 in // R32 = bswap R32
def BSWAP32r : I<0xC8, AddRegFrm,
(ops R32:$dst, R32:$src),
Index: llvm/lib/Target/X86/X86IntelAsmPrinter.cpp
diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.16 llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.17
--- llvm/lib/Target/X86/X86IntelAsmPrinter.cpp:1.16 Tue Feb 7 02:38:37 2006
+++ llvm/lib/Target/X86/X86IntelAsmPrinter.cpp Fri Feb 17 18:15:05 2006
@@ -18,6 +18,7 @@
#include "llvm/Module.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/Support/Mangler.h"
+#include "llvm/Target/TargetOptions.h"
using namespace llvm;
using namespace x86;
@@ -109,9 +110,32 @@
abort ();
return;
case MachineOperand::MO_GlobalAddress: {
- if (!Modifier || strcmp(Modifier, "call") || strcmp(Modifier, "mem"))
- O << "OFFSET ";
- O << Mang->getValueName(MO.getGlobal());
+ bool isCallOp = Modifier && !strcmp(Modifier, "call");
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ if (!isMemOp && !isCallOp) O << "OFFSET ";
+ if (forDarwin) {
+ GlobalValue *GV = MO.getGlobal();
+ std::string Name = Mang->getValueName(GV);
+ if (!isMemOp && !isCallOp) O << '$';
+ // Link-once, External, or Weakly-linked global variables need
+ // non-lazily-resolved stubs
+ if (GV->isExternal() || GV->hasWeakLinkage() ||
+ GV->hasLinkOnceLinkage()) {
+ // Dynamically-resolved functions need a stub for the function.
+ if (isCallOp && isa<Function>(GV) && cast<Function>(GV)->isExternal()) {
+ FnStubs.insert(Name);
+ O << "L" << Name << "$stub";
+ } else {
+ GVStubs.insert(Name);
+ O << "L" << Name << "$non_lazy_ptr";
+ if (PICEnabled)
+ O << "-\"L" << getFunctionNumber() << "$pb\"";
+ }
+ } else {
+ O << Mang->getValueName(GV);
+ }
+ } else
+ O << Mang->getValueName(MO.getGlobal());
int Offset = MO.getOffset();
if (Offset > 0)
O << " + " << Offset;
@@ -119,9 +143,18 @@
O << Offset;
return;
}
- case MachineOperand::MO_ExternalSymbol:
+ case MachineOperand::MO_ExternalSymbol: {
+ bool isCallOp = Modifier && !strcmp(Modifier, "call");
+ bool isMemOp = Modifier && !strcmp(Modifier, "mem");
+ if (isCallOp && forDarwin) {
+ std::string Name(GlobalPrefix); Name += MO.getSymbolName();
+ FnStubs.insert(Name);
+ O << "L" << Name << "$stub";
+ return;
+ }
O << GlobalPrefix << MO.getSymbolName();
return;
+ }
default:
O << "<unknown operand type>"; return;
}
@@ -144,6 +177,8 @@
} else if (BaseReg.isConstantPoolIndex()) {
O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
<< BaseReg.getConstantPoolIndex();
+ if (forDarwin && PICEnabled)
+ O << "-\"L" << getFunctionNumber() << "$pb\"";
if (IndexReg.getReg()) {
O << " + ";
@@ -193,6 +228,10 @@
O << "]";
}
+void X86IntelAsmPrinter::printPICLabel(const MachineInstr *MI, unsigned Op) {
+ O << "\"L" << getFunctionNumber() << "$pb\"\n";
+ O << "\"L" << getFunctionNumber() << "$pb\":";
+}
/// printMachineInstruction -- Print out a single X86 LLVM instruction
/// MI in Intel syntax to the current output stream.
Index: llvm/lib/Target/X86/X86IntelAsmPrinter.h
diff -u llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.7 llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.8
--- llvm/lib/Target/X86/X86IntelAsmPrinter.h:1.7 Mon Feb 6 17:41:19 2006
+++ llvm/lib/Target/X86/X86IntelAsmPrinter.h Fri Feb 17 18:15:05 2006
@@ -82,6 +82,7 @@
void printOp(const MachineOperand &MO, const char *Modifier = 0);
void printSSECC(const MachineInstr *MI, unsigned Op);
void printMemReference(const MachineInstr *MI, unsigned Op);
+ void printPICLabel(const MachineInstr *MI, unsigned Op);
bool runOnMachineFunction(MachineFunction &F);
bool doInitialization(Module &M);
};
Index: llvm/lib/Target/X86/X86Subtarget.cpp
diff -u llvm/lib/Target/X86/X86Subtarget.cpp:1.25 llvm/lib/Target/X86/X86Subtarget.cpp:1.26
--- llvm/lib/Target/X86/X86Subtarget.cpp:1.25 Wed Feb 15 18:21:07 2006
+++ llvm/lib/Target/X86/X86Subtarget.cpp Fri Feb 17 18:15:05 2006
@@ -148,7 +148,6 @@
stackAlignment = 8;
// FIXME: this is a known good value for Yonah. Not sure about others.
MinRepStrSizeThreshold = 128;
- indirectExternAndWeakGlobals = false;
X86SSELevel = NoMMXSSE;
X863DNowLevel = NoThreeDNow;
Is64Bit = false;
@@ -183,8 +182,6 @@
#endif
}
- if (TargetType == isDarwin) {
+ if (TargetType == isDarwin)
stackAlignment = 16;
- indirectExternAndWeakGlobals = true;
- }
}
Index: llvm/lib/Target/X86/X86Subtarget.h
diff -u llvm/lib/Target/X86/X86Subtarget.h:1.11 llvm/lib/Target/X86/X86Subtarget.h:1.12
--- llvm/lib/Target/X86/X86Subtarget.h:1.11 Wed Feb 15 18:21:07 2006
+++ llvm/lib/Target/X86/X86Subtarget.h Fri Feb 17 18:15:05 2006
@@ -47,9 +47,6 @@
/// Min. memset / memcpy size that is turned into rep/movs, rep/stos ops.
unsigned MinRepStrSizeThreshold;
- /// Used by instruction selector
- bool indirectExternAndWeakGlobals;
-
public:
enum {
isELF, isCygwin, isDarwin, isWindows
@@ -71,13 +68,6 @@
/// aligned.
unsigned getMinRepStrSizeThreshold() const { return MinRepStrSizeThreshold; }
- /// Returns true if the instruction selector should treat global values
- /// referencing external or weak symbols as indirect rather than direct
- /// references.
- bool getIndirectExternAndWeakGlobals() const {
- return indirectExternAndWeakGlobals;
- }
-
/// ParseSubtargetFeatures - Parses features string setting specified
/// subtarget options. Definition of function is auto generated by tblgen.
void ParseSubtargetFeatures(const std::string &FS, const std::string &CPU);
@@ -90,6 +80,8 @@
bool hasSSE3() const { return X86SSELevel >= SSE3; }
bool has3DNow() const { return X863DNowLevel >= ThreeDNow; }
bool has3DNowA() const { return X863DNowLevel >= ThreeDNowA; }
+
+ bool isTargetDarwin() const { return TargetType == isDarwin; }
};
} // End llvm namespace
More information about the llvm-commits
mailing list