Move all the TLS processing logic into isel, don't do it in asmprinter at all.

llvm-svn: 74327
This commit is contained in:
Chris Lattner 2009-06-26 21:20:29 +00:00
parent 899abc4655
commit 49ed726e46
3 changed files with 124 additions and 60 deletions

View File

@ -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))

View File

@ -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<GlobalAddressSDNode>(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<GlobalAlias>(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();
}

View File

@ -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