Index: lib/Target/X86/X86ISelLowering.cpp
===================================================================
--- lib/Target/X86/X86ISelLowering.cpp	(Revision 146152)
+++ lib/Target/X86/X86ISelLowering.cpp	(Arbeitskopie)
@@ -7394,6 +7394,54 @@
     unsigned Reg = Subtarget->is64Bit() ? X86::RAX : X86::EAX;
     return DAG.getCopyFromReg(Chain, DL, Reg, getPointerTy(),
                               Chain.getValue(1));
+  } else if (Subtarget->isTargetWindows()) {
+    // Just use the implicit TLS architecture
+    // Need to generate someting similar to:
+    //   mov     rdx, qword [gs:abs 58H]; Load pointer to ThreadLocalStorage from TEB
+    //   mov     ecx, dword [rel _tls_index]: Load index (from C runtime)
+    //   mov     rcx, qword [rdx+rcx*8]
+    //   mov     eax, .tls$:tlsvar
+    //   [rax+rcx] contains the address
+    // Windows 64bit: gs:0x58
+    // Windows 32bit: fs:0x2C
+	// Ignore 32bit for now.
+	assert(Subtarget->is64Bit() && "TLS not implemented for x86-pc-win32.");
+
+    // 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);
+    DebugLoc dl = GA->getDebugLoc();
+
+    // Get the Thread Pointer, which is %fs:0x2C (32-bit) or %gs:0x58 (64-bit).
+    Value *Ptr = Constant::getNullValue(Type::getInt8PtrTy(*DAG.getContext(),
+                                                         Subtarget->is64Bit() ? 256 : 257));
+
+    SDValue ThreadPointer = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
+                                        DAG.getIntPtrConstant(Subtarget->is64Bit() ? 0x58 : 0x2C),
+                                        MachinePointerInfo(Ptr),
+                                        false, false, false, 0);
+
+	// Load the _tls_index variable
+	SDValue IDX = DAG.getExternalSymbol("_tls_index", getPointerTy());
+	IDX = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
+                      IDX,
+                      MachinePointerInfo::getGOT(),
+                      false, false, false, 0);
+
+	SDValue Scale = DAG.getConstant(TD->getPointerSize(), Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
+	IDX = DAG.getNode(ISD::MUL, dl, getPointerTy(), IDX, Scale);
+
+	// Get the offset of start of .tls section
+    SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl,
+                                             GA->getValueType(0),
+                                             GA->getOffset(), X86II::MO_SECREL);
+    SDValue Offset = DAG.getNode(X86ISD::Wrapper, dl, getPointerTy(), TGA);
+
+    // The address of the thread local variable is the add of the thread
+    // pointer with the offset of the variable.
+    SDValue res = DAG.getNode(ISD::ADD, dl, getPointerTy(), ThreadPointer, IDX);
+    return DAG.getNode(ISD::ADD, dl, getPointerTy(), res, Offset);
   }
 
   assert(false &&
Index: lib/Target/X86/X86AsmPrinter.cpp
===================================================================
--- lib/Target/X86/X86AsmPrinter.cpp	(Revision 146152)
+++ lib/Target/X86/X86AsmPrinter.cpp	(Arbeitskopie)
@@ -199,6 +199,7 @@
   case X86II::MO_TLVP_PIC_BASE:
     O << "@TLVP" << '-' << *MF->getPICBaseSymbol();
     break;
+  case X86II::MO_SECREL:      O << "@SECREL";      break;
   }
 }
 
Index: lib/Target/X86/X86MCInstLower.cpp
===================================================================
--- lib/Target/X86/X86MCInstLower.cpp	(Revision 146152)
+++ lib/Target/X86/X86MCInstLower.cpp	(Arbeitskopie)
@@ -154,6 +154,7 @@
                                                            Ctx),
                                    Ctx);
     break;
+  case X86II::MO_SECREL:    RefKind = MCSymbolRefExpr::VK_SECREL; break;
   case X86II::MO_TLSGD:     RefKind = MCSymbolRefExpr::VK_TLSGD; break;
   case X86II::MO_GOTTPOFF:  RefKind = MCSymbolRefExpr::VK_GOTTPOFF; break;
   case X86II::MO_INDNTPOFF: RefKind = MCSymbolRefExpr::VK_INDNTPOFF; break;
Index: lib/Target/X86/MCTargetDesc/X86BaseInfo.h
===================================================================
--- lib/Target/X86/MCTargetDesc/X86BaseInfo.h	(Revision 146152)
+++ lib/Target/X86/MCTargetDesc/X86BaseInfo.h	(Arbeitskopie)
@@ -164,7 +164,13 @@
     /// is some TLS offset from the picbase.
     ///
     /// This is the 32-bit TLS offset for Darwin TLS in PIC mode.
-    MO_TLVP_PIC_BASE
+    MO_TLVP_PIC_BASE,
+
+    /// MO_SECREL - On a symbol operand this indicates that the immediate is
+    /// the offset from beginning of section.
+    ///
+    /// This is the TLS offset for the COFF/Windows TLS mechanism.
+    MO_SECREL
   };
 
   enum {
Index: lib/MC/MCExpr.cpp
===================================================================
--- lib/MC/MCExpr.cpp	(Revision 146152)
+++ lib/MC/MCExpr.cpp	(Arbeitskopie)
@@ -189,6 +189,7 @@
   case VK_TPOFF: return "TPOFF";
   case VK_DTPOFF: return "DTPOFF";
   case VK_TLVP: return "TLVP";
+  case VK_SECREL: return "SECREL";
   case VK_ARM_PLT: return "(PLT)";
   case VK_ARM_GOT: return "(GOT)";
   case VK_ARM_GOTOFF: return "(GOTOFF)";
Index: lib/MC/MCObjectFileInfo.cpp
===================================================================
--- lib/MC/MCObjectFileInfo.cpp	(Revision 146152)
+++ lib/MC/MCObjectFileInfo.cpp	(Arbeitskopie)
@@ -501,6 +501,12 @@
                         COFF::IMAGE_SCN_MEM_READ |
                         COFF::IMAGE_SCN_MEM_WRITE,
                         SectionKind::getDataRel());
+  TLSDataSection =
+    Ctx->getCOFFSection(".tls$",
+                        COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+                        COFF::IMAGE_SCN_MEM_READ |
+                        COFF::IMAGE_SCN_MEM_WRITE,
+                        SectionKind::getDataRel());
 }
 
 void MCObjectFileInfo::InitMCObjectFileInfo(StringRef TT, Reloc::Model relocm,
Index: lib/MC/WinCOFFObjectWriter.cpp
===================================================================
--- lib/MC/WinCOFFObjectWriter.cpp	(Revision 146152)
+++ lib/MC/WinCOFFObjectWriter.cpp	(Arbeitskopie)
@@ -711,7 +711,10 @@
                               : COFF::IMAGE_REL_I386_DIR32;
     break;
   case FK_Data_8:
-    if (Is64Bit)
+    if (SymA->getKind() == MCSymbolRefExpr::VK_SECREL)
+      Reloc.Data.Type = Is64Bit ? COFF::IMAGE_REL_AMD64_SECREL
+                                : COFF::IMAGE_REL_I386_SECREL;
+	else if (Is64Bit)
       Reloc.Data.Type = COFF::IMAGE_REL_AMD64_ADDR64;
     else
       llvm_unreachable("unsupported relocation type");
Index: lib/CodeGen/TargetLoweringObjectFileImpl.cpp
===================================================================
--- lib/CodeGen/TargetLoweringObjectFileImpl.cpp	(Revision 146152)
+++ lib/CodeGen/TargetLoweringObjectFileImpl.cpp	(Arbeitskopie)
@@ -566,6 +566,11 @@
       COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA |
       COFF::IMAGE_SCN_MEM_READ |
       COFF::IMAGE_SCN_MEM_WRITE;
+  else if (K.isThreadLocal())
+    Flags |=
+      COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
+      COFF::IMAGE_SCN_MEM_READ |
+      COFF::IMAGE_SCN_MEM_WRITE;
   else if (K.isReadOnly())
     Flags |=
       COFF::IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -592,6 +597,8 @@
     return ".text$";
   if (Kind.isBSS ())
     return ".bss$";
+  if (Kind.isThreadLocal())
+    return ".tls$";
   if (Kind.isWriteable())
     return ".data$";
   return ".rdata$";
@@ -601,7 +608,6 @@
 const MCSection *TargetLoweringObjectFileCOFF::
 SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind,
                        Mangler *Mang, const TargetMachine &TM) const {
-  assert(!Kind.isThreadLocal() && "Doesn't support TLS");
 
   // If this global is linkonce/weak and the target handles this by emitting it
   // into a 'uniqued' section name, create and return the section now.
@@ -622,6 +628,9 @@
   if (Kind.isText())
     return getTextSection();
 
+  if (Kind.isThreadLocal())
+    return getTLSDataSection();
+
   return getDataSection();
 }
 
Index: include/llvm/MC/MCObjectFileInfo.h
===================================================================
--- include/llvm/MC/MCObjectFileInfo.h	(Revision 146152)
+++ include/llvm/MC/MCObjectFileInfo.h	(Arbeitskopie)
@@ -113,7 +113,7 @@
   const MCSection *TLSExtraDataSection;
   
   /// TLSDataSection - Section directive for Thread Local data.
-  /// ELF and MachO only.
+  /// ELF, MachO and COFF.
   const MCSection *TLSDataSection;        // Defaults to ".tdata".
 
   /// TLSBSSSection - Section directive for Thread Local uninitialized data.
Index: include/llvm/MC/MCExpr.h
===================================================================
--- include/llvm/MC/MCExpr.h	(Revision 146152)
+++ include/llvm/MC/MCExpr.h	(Arbeitskopie)
@@ -162,6 +162,7 @@
     VK_TPOFF,
     VK_DTPOFF,
     VK_TLVP,      // Mach-O thread local variable relocation
+    VK_SECREL,
     // FIXME: We'd really like to use the generic Kinds listed above for these.
     VK_ARM_PLT,   // ARM-style PLT references. i.e., (PLT) instead of @PLT
     VK_ARM_TLSGD, //   ditto for TLSGD, GOT, GOTOFF, TPOFF and GOTTPOFF
