From b903bed0feaa35a2b5e404923db724a62b433787 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 26 Jun 2009 21:20:29 +0000 Subject: [PATCH] Move all the TLS processing logic into isel, don't do it in asmprinter at all. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@74327 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../X86/AsmPrinter/X86ATTAsmPrinter.cpp | 52 +++++++-------- lib/Target/X86/X86ISelLowering.cpp | 66 +++++++++++-------- lib/Target/X86/X86InstrInfo.h | 66 +++++++++++++++++-- 3 files changed, 124 insertions(+), 60 deletions(-) diff --git a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index beac1bdd917..b180beb9d69 100644 --- a/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -580,43 +580,37 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, if (needCloseParen) O << ')'; + bool isRIPRelative = false; + switch (MO.getTargetFlags()) { default: assert(0 && "Unknown target flag on GV operand"); case X86II::MO_NO_FLAG: + // FIXME: RIP THIS CHECKING CODE OUT EVENTUALLY. + if (isThreadLocal) + assert(0 && "Not lowered right"); + break; + case X86II::MO_TLSGD: + O << "@TLSGD"; + break; + case X86II::MO_GOTTPOFF: + O << "@GOTTPOFF"; + assert(!NotRIPRel); + isRIPRelative = true; + break; + case X86II::MO_INDNTPOFF: + O << "@INDNTPOFF"; + break; + case X86II::MO_TPOFF: + O << "@TPOFF"; + break; + case X86II::MO_NTPOFF: + O << "@NTPOFF"; break; } - - bool isRIPRelative = false; if (isThreadLocal) { - TLSModel::Model model = getTLSModel(GVar, TM.getRelocationModel()); - switch (model) { - case TLSModel::GeneralDynamic: - O << "@TLSGD"; - break; - case TLSModel::LocalDynamic: - // O << "@TLSLD"; // local dynamic not implemented - O << "@TLSGD"; - break; - case TLSModel::InitialExec: - if (Subtarget->is64Bit()) { - assert (!NotRIPRel); - O << "@GOTTPOFF"; - isRIPRelative = true; - } else { - O << "@INDNTPOFF"; - } - break; - case TLSModel::LocalExec: - if (Subtarget->is64Bit()) - O << "@TPOFF"; - else - O << "@NTPOFF"; - break; - default: - assert (0 && "Unknown TLS model"); - } + // DEAD } else if (isMemOp) { if (shouldPrintGOT(TM, Subtarget)) { if (Subtarget->GVRequiresExtraLoad(GV, TM, false)) diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 1c3dc156df1..01361f2998e 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -19,6 +19,7 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" +#include "llvm/GlobalAlias.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" #include "llvm/Intrinsics.h" @@ -4390,12 +4391,14 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) { static SDValue GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA, - SDValue *InFlag, const MVT PtrVT, unsigned ReturnReg) { + SDValue *InFlag, const MVT PtrVT, unsigned ReturnReg, + unsigned char OperandFlags) { SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Flag); DebugLoc dl = GA->getDebugLoc(); SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), - GA->getOffset()); + GA->getOffset(), + OperandFlags); if (InFlag) { SDValue Ops[] = { Chain, TGA, *InFlag }; Chain = DAG.getNode(X86ISD::TLSADDR, dl, NodeTys, Ops, 3); @@ -4419,14 +4422,15 @@ LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG, PtrVT), InFlag); InFlag = Chain.getValue(1); - return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX); + return GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX, X86II::MO_TLSGD); } // Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit static SDValue LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG, const MVT PtrVT) { - return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT, X86::RAX); + return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT, + X86::RAX, X86II::MO_TLSGD); } // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or @@ -4444,10 +4448,19 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG, SDValue ThreadPointer = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Base, NULL, 0); + unsigned char OperandFlags = 0; + if (model == TLSModel::InitialExec) { + OperandFlags = is64Bit ? X86II::MO_GOTTPOFF : X86II::MO_INDNTPOFF; + } else { + assert(model == TLSModel::LocalExec); + OperandFlags = is64Bit ? X86II::MO_TPOFF : X86II::MO_NTPOFF; + } + + // emit "addl x@ntpoff,%eax" (local exec) or "addl x@indntpoff,%eax" (initial // exec) SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0), - GA->getOffset()); + GA->getOffset(), OperandFlags); SDValue Offset = DAG.getNode(X86ISD::Wrapper, dl, PtrVT, TGA); if (model == TLSModel::InitialExec) @@ -4466,30 +4479,29 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) { assert(Subtarget->isTargetELF() && "TLS not implemented for non-ELF targets"); GlobalAddressSDNode *GA = cast(Op); - GlobalValue *GV = GA->getGlobal(); - TLSModel::Model model = - getTLSModel (GV, getTargetMachine().getRelocationModel()); - if (Subtarget->is64Bit()) { - switch (model) { - case TLSModel::GeneralDynamic: - case TLSModel::LocalDynamic: // not implemented + const GlobalValue *GV = GA->getGlobal(); + + // If GV is an alias then use the aliasee for determining + // thread-localness. + if (const GlobalAlias *GA = dyn_cast(GV)) + GV = GA->resolveAliasedGlobal(false); + + TLSModel::Model model = getTLSModel(GV, + getTargetMachine().getRelocationModel()); + + switch (model) { + case TLSModel::GeneralDynamic: + case TLSModel::LocalDynamic: // not implemented + if (Subtarget->is64Bit()) return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy()); - - case TLSModel::InitialExec: - case TLSModel::LocalExec: - return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, true); - } - } else { - switch (model) { - case TLSModel::GeneralDynamic: - case TLSModel::LocalDynamic: // not implemented - return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy()); - - case TLSModel::InitialExec: - case TLSModel::LocalExec: - return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, false); - } + return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy()); + + case TLSModel::InitialExec: + case TLSModel::LocalExec: + return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, + Subtarget->is64Bit()); } + assert(0 && "Unreachable"); return SDValue(); } diff --git a/lib/Target/X86/X86InstrInfo.h b/lib/Target/X86/X86InstrInfo.h index b4ba5f0dc00..83f01945ea2 100644 --- a/lib/Target/X86/X86InstrInfo.h +++ b/lib/Target/X86/X86InstrInfo.h @@ -85,11 +85,69 @@ namespace X86II { /// SYMBOL_LABEL - PICBASELABEL MO_PIC_BASE_OFFSET = 2, - /// MO_GOTOFF - On a symbol operand this indicates that the immediate should - /// the offset to the location of the symbol name from the base of the GOT. - /// SYMBOL_LABEL @GOTOFF - MO_GOTOFF = 3, + /// MO_GOT - On a symbol operand this indicates that the immediate is the + /// offset to the GOT entry for the symbol name from the base of the GOT. + /// + /// See the X86-64 ELF ABI supplement for more details. + /// SYMBOL_LABEL @GOT + MO_GOT = 3, + /// MO_GOTOFF - On a symbol operand this indicates that the immediate is + /// the offset to the location of the symbol name from the base of the GOT. + /// + /// See the X86-64 ELF ABI supplement for more details. + /// SYMBOL_LABEL @GOTOFF + MO_GOTOFF = 4, + + /// MO_GOTPCREL - On a symbol operand this indicates that the immediate is + /// offset to the GOT entry for the symbol name from the current code + /// location. + /// + /// See the X86-64 ELF ABI supplement for more details. + /// SYMBOL_LABEL @GOTPCREL + MO_GOTPCREL = 5, + + /// MO_PLT - On a symbol operand this indicates that the immediate is + /// offset to the PLT entry of symbol name from the current code location. + /// + /// See the X86-64 ELF ABI supplement for more details. + /// SYMBOL_LABEL @PLT + MO_PLT = 6, + + /// MO_TLSGD - On a symbol operand this indicates that the immediate is + /// some TLS offset. + /// + /// See 'ELF Handling for Thread-Local Storage' for more details. + /// SYMBOL_LABEL @TLSGD + MO_TLSGD = 7, + + /// MO_GOTTPOFF - On a symbol operand this indicates that the immediate is + /// some TLS offset. + /// + /// See 'ELF Handling for Thread-Local Storage' for more details. + /// SYMBOL_LABEL @GOTTPOFF + MO_GOTTPOFF = 8, + + /// MO_INDNTPOFF - On a symbol operand this indicates that the immediate is + /// some TLS offset. + /// + /// See 'ELF Handling for Thread-Local Storage' for more details. + /// SYMBOL_LABEL @INDNTPOFF + MO_INDNTPOFF = 9, + + /// MO_TPOFF - On a symbol operand this indicates that the immediate is + /// some TLS offset. + /// + /// See 'ELF Handling for Thread-Local Storage' for more details. + /// SYMBOL_LABEL @TPOFF + MO_TPOFF = 10, + + /// MO_NTPOFF - On a symbol operand this indicates that the immediate is + /// some TLS offset. + /// + /// See 'ELF Handling for Thread-Local Storage' for more details. + /// SYMBOL_LABEL @NTPOFF + MO_NTPOFF = 11, //===------------------------------------------------------------------===// // Instruction encodings. These are the standard/most common forms for X86