summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/ARM/ARMAsmPrinter.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMConstantPoolValue.cpp2
-rw-r--r--llvm/lib/Target/ARM/ARMConstantPoolValue.h1
-rw-r--r--llvm/lib/Target/ARM/ARMISelLowering.cpp14
-rw-r--r--llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h10
-rw-r--r--llvm/test/CodeGen/ARM/Windows/tls.ll44
6 files changed, 54 insertions, 19 deletions
diff --git a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
index 71fa0a51ac9..27bf01b5dff 100644
--- a/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/ARMAsmPrinter.cpp
@@ -902,6 +902,8 @@ getModifierVariantKind(ARMCP::ARMCPModifier Modifier) {
return MCSymbolRefExpr::VK_GOTTPOFF;
case ARMCP::GOT_PREL:
return MCSymbolRefExpr::VK_ARM_GOT_PREL;
+ case ARMCP::SECREL:
+ return MCSymbolRefExpr::VK_SECREL;
}
llvm_unreachable("Invalid ARMCPModifier!");
}
diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
index 2dbe236cc77..c0db001cb6f 100644
--- a/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
+++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
@@ -60,6 +60,8 @@ const char *ARMConstantPoolValue::getModifierText() const {
return "gottpoff";
case ARMCP::TPOFF:
return "tpoff";
+ case ARMCP::SECREL:
+ return "secrel32";
}
llvm_unreachable("Unknown modifier!");
}
diff --git a/llvm/lib/Target/ARM/ARMConstantPoolValue.h b/llvm/lib/Target/ARM/ARMConstantPoolValue.h
index f719df8fe04..c07331d71da 100644
--- a/llvm/lib/Target/ARM/ARMConstantPoolValue.h
+++ b/llvm/lib/Target/ARM/ARMConstantPoolValue.h
@@ -42,6 +42,7 @@ namespace ARMCP {
GOT_PREL, /// Global Offset Table, PC Relative
GOTTPOFF, /// Global Offset Table, Thread Pointer Offset
TPOFF, /// Thread Pointer Offset
+ SECREL, /// Section Relative (Windows TLS)
};
}
diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp
index 6a05e5473bb..a5c698bc4ed 100644
--- a/llvm/lib/Target/ARM/ARMISelLowering.cpp
+++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp
@@ -2622,6 +2622,7 @@ SDValue
ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
SelectionDAG &DAG) const {
assert(Subtarget->isTargetWindows() && "Windows specific TLS lowering");
+
SDValue Chain = DAG.getEntryNode();
EVT PtrVT = getPointerTy(DAG.getDataLayout());
SDLoc DL(Op);
@@ -2663,8 +2664,17 @@ ARMTargetLowering::LowerGlobalTLSAddressWindows(SDValue Op,
DAG.getNode(ISD::ADD, DL, PtrVT, TLSArray, Slot),
MachinePointerInfo(), false, false, false, 0);
- return DAG.getNode(ISD::ADD, DL, PtrVT, TLS,
- LowerGlobalAddressWindows(Op, DAG));
+ // Get the offset of the start of the .tls section (section base)
+ const auto *GA = cast<GlobalAddressSDNode>(Op);
+ auto *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMCP::SECREL);
+ SDValue Offset =
+ DAG.getLoad(PtrVT, DL, Chain,
+ DAG.getNode(ARMISD::Wrapper, DL, MVT::i32,
+ DAG.getTargetConstantPool(CPV, PtrVT, 4)),
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()),
+ false, false, false, 0);
+
+ return DAG.getNode(ISD::ADD, DL, PtrVT, TLS, Offset);
}
// Lower ISD::GlobalTLSAddress using the "general dynamic" model
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
index 4289a73e9d6..5bc10d613a3 100644
--- a/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
+++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMBaseInfo.h
@@ -295,12 +295,18 @@ namespace ARMII {
/// MO_OPTION_MASK - Most flags are mutually exclusive; this mask selects
/// just that part of the flag set.
- MO_OPTION_MASK = 0x3f,
+ MO_OPTION_MASK = 0x1f,
/// MO_DLLIMPORT - On a symbol operand, this represents that the reference
/// to the symbol is for an import stub. This is used for DLL import
/// storage class indication on Windows.
- MO_DLLIMPORT = 0x40,
+ MO_DLLIMPORT = 0x20,
+
+ /// 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 = 0x40,
/// MO_NONLAZY - This is an independent flag, on a symbol operand "FOO" it
/// represents a symbol which, if indirect, will get special Darwin mangling
diff --git a/llvm/test/CodeGen/ARM/Windows/tls.ll b/llvm/test/CodeGen/ARM/Windows/tls.ll
index 9022f8af9f5..689f4e29187 100644
--- a/llvm/test/CodeGen/ARM/Windows/tls.ll
+++ b/llvm/test/CodeGen/ARM/Windows/tls.ll
@@ -1,4 +1,4 @@
-; RUN: llc -mtriple thumbv7--windows %s -o - | FileCheck %s
+; RUN: llc -mtriple thumbv7--windows-itanium %s -o - | FileCheck %s
@i = thread_local global i32 0
@j = external thread_local global i32
@@ -22,11 +22,13 @@ define i32 @f() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:i
-; CHECK-NEXT: movt [[SLOT]], :upper16:i
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long i(SECREL32)
+
define i32 @e() {
%1 = load i32, i32* @j
ret i32 %1
@@ -41,11 +43,13 @@ define i32 @e() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:j
-; CHECK-NEXT: movt [[SLOT]], :upper16:j
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long j(SECREL32)
+
define i32 @d() {
%1 = load i32, i32* @k
ret i32 %1
@@ -60,11 +64,13 @@ define i32 @d() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:k
-; CHECK-NEXT: movt [[SLOT]], :upper16:k
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long k(SECREL32)
+
define i32 @c() {
%1 = load i32, i32* @l
ret i32 %1
@@ -79,11 +85,13 @@ define i32 @c() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:l
-; CHECK-NEXT: movt [[SLOT]], :upper16:l
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long l(SECREL32)
+
define i32 @b() {
%1 = load i32, i32* @m
ret i32 %1
@@ -98,11 +106,13 @@ define i32 @b() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:m
-; CHECK-NEXT: movt [[SLOT]], :upper16:m
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldr r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK: .long m(SECREL32)
+
define i16 @a() {
%1 = load i16, i16* @n
ret i16 %1
@@ -117,11 +127,13 @@ define i16 @a() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:n
-; CHECK-NEXT: movt [[SLOT]], :upper16:n
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldrh r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK: .long n(SECREL32)
+
define i8 @Z() {
%1 = load i8, i8* @o
ret i8 %1
@@ -136,8 +148,10 @@ define i8 @Z() {
; CHECK: ldr [[TLS_POINTER:r[0-9]]], {{\[}}[[TEB]], #44]
; CHECK-NEXT: ldr{{.w}} [[TLS:r[0-9]]], {{\[}}[[TLS_POINTER]], [[INDEX]], lsl #2]
-; CHECK-NEXT: movw [[SLOT:r[0-9]]], :lower16:o
-; CHECK-NEXT: movt [[SLOT]], :upper16:o
+; CHECK-NEXT: ldr [[SLOT:r[0-9]]], [[CPI:LCPI[0-9]+_[0-9]+]]
; CHECK-NEXT: ldrb r0, {{\[}}[[TLS]], [[SLOT]]]
+; CHECK: [[CPI]]:
+; CHECK-NEXT: .long o(SECREL32)
+
OpenPOWER on IntegriCloud