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 _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits