diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 1 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 42 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86MCInstLower.cpp | 1 | 
4 files changed, 35 insertions, 16 deletions
| diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h index 82ec6fb20f6..0c7f14d01cc 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h +++ b/llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h @@ -128,6 +128,13 @@ namespace X86II {      ///    SYMBOL_LABEL @NTPOFF      MO_NTPOFF, +    /// MO_GOTNTPOFF - 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 @GOTNTPOFF +    MO_GOTNTPOFF, +      /// MO_DLLIMPORT - On a symbol operand "FOO", this indicates that the      /// reference is actually to the "__imp_FOO" symbol.  This is used for      /// dllimport linkage on windows. diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 7db7ccbedcf..6d97f46e9aa 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -190,6 +190,7 @@ void X86AsmPrinter::printSymbolOperand(const MachineOperand &MO,    case X86II::MO_INDNTPOFF: O << "@INDNTPOFF"; break;    case X86II::MO_TPOFF:     O << "@TPOFF";     break;    case X86II::MO_NTPOFF:    O << "@NTPOFF";    break; +  case X86II::MO_GOTNTPOFF: O << "@GOTNTPOFF"; break;    case X86II::MO_GOTPCREL:  O << "@GOTPCREL";  break;    case X86II::MO_GOT:       O << "@GOT";       break;    case X86II::MO_GOTOFF:    O << "@GOTOFF";    break; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 688c25c6a25..75e05883b6b 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7286,11 +7286,10 @@ LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,                      X86::RAX, X86II::MO_TLSGD);  } -// Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or -// "local exec" model. +// Lower ISD::GlobalTLSAddress using the "initial exec" or "local exec" model.  static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,                                     const EVT PtrVT, TLSModel::Model model, -                                   bool is64Bit) { +                                   bool is64Bit, bool isPIC) {    DebugLoc dl = GA->getDebugLoc();    // Get the Thread Pointer, which is %gs:0 (32-bit) or %fs:0 (64-bit). @@ -7308,25 +7307,36 @@ static SDValue LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,    unsigned WrapperKind = X86ISD::Wrapper;    if (model == TLSModel::LocalExec) {      OperandFlags = is64Bit ? X86II::MO_TPOFF : X86II::MO_NTPOFF; -  } else if (is64Bit) { -    assert(model == TLSModel::InitialExec); -    OperandFlags = X86II::MO_GOTTPOFF; -    WrapperKind = X86ISD::WrapperRIP; +  } else if (model == TLSModel::InitialExec) { +    if (is64Bit) { +      OperandFlags = X86II::MO_GOTTPOFF; +      WrapperKind = X86ISD::WrapperRIP; +    } else { +      OperandFlags = isPIC ? X86II::MO_GOTNTPOFF : X86II::MO_INDNTPOFF; +    }    } else { -    assert(model == TLSModel::InitialExec); -    OperandFlags = X86II::MO_INDNTPOFF; +    llvm_unreachable("Unexpected model");    } -  // emit "addl x@ntpoff,%eax" (local exec) or "addl x@indntpoff,%eax" (initial -  // exec) +  // emit "addl x@ntpoff,%eax" (local exec) +  // or "addl x@indntpoff,%eax" (initial exec) +  // or "addl x@gotntpoff(%ebx) ,%eax" (initial exec, 32-bit pic)    SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,                                             GA->getValueType(0),                                             GA->getOffset(), OperandFlags);    SDValue Offset = DAG.getNode(WrapperKind, dl, PtrVT, TGA); -  if (model == TLSModel::InitialExec) -    Offset = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Offset, -                         MachinePointerInfo::getGOT(), false, false, false, 0); +  if (model == TLSModel::InitialExec) { +    if (isPIC && !is64Bit) { +      Offset = DAG.getNode(ISD::ADD, dl, PtrVT, +                          DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc(), PtrVT), +                           Offset); +    } else { +      Offset = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Offset, +                           MachinePointerInfo::getGOT(), false, false, false, +                           0); +    } +  }    // The address of the thread local variable is the add of the thread    // pointer with the offset of the variable. @@ -7341,7 +7351,6 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {    if (Subtarget->isTargetELF()) {      // TODO: implement the "local dynamic" model -    // TODO: implement the "initial exec"model for pic executables      // If GV is an alias then use the aliasee for determining      // thread-localness. @@ -7360,7 +7369,8 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {        case TLSModel::InitialExec:        case TLSModel::LocalExec:          return LowerToTLSExecModel(GA, DAG, getPointerTy(), model, -                                   Subtarget->is64Bit()); +                                   Subtarget->is64Bit(), +                         getTargetMachine().getRelocationModel() == Reloc::PIC_);      }      llvm_unreachable("Unknown TLS model.");    } diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index b578e8d9285..54bfce1298c 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -160,6 +160,7 @@ MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,    case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;    case X86II::MO_TPOFF:     RefKind = MCSymbolRefExpr::VK_TPOFF; break;    case X86II::MO_NTPOFF:    RefKind = MCSymbolRefExpr::VK_NTPOFF; break; +  case X86II::MO_GOTNTPOFF: RefKind = MCSymbolRefExpr::VK_GOTNTPOFF; break;    case X86II::MO_GOTPCREL:  RefKind = MCSymbolRefExpr::VK_GOTPCREL; break;    case X86II::MO_GOT:       RefKind = MCSymbolRefExpr::VK_GOT; break;    case X86II::MO_GOTOFF:    RefKind = MCSymbolRefExpr::VK_GOTOFF; break; | 

