aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp31
-rw-r--r--lib/Target/X86/X86ISelLowering.h9
-rw-r--r--lib/Target/X86/X86InstrCompiler.td10
-rw-r--r--lib/Target/X86/X86InstrInfo.td7
-rw-r--r--test/NaCl/ARM/nacl-read-tp-intrinsic.ll11
-rw-r--r--test/NaCl/X86/nacl-read-tp-intrinsic.ll44
6 files changed, 81 insertions, 31 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index c359d37885..fd0a8a27d6 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -10155,13 +10155,7 @@ SDValue X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op,
return CallResult.first;
} else {
// Get %gs:0, which contains the thread pointer on x86-32.
- unsigned GSAddrSpace = 256;
- Value *Ptr = Constant::getNullValue(
- Type::getInt8PtrTy(*DAG.getContext(), GSAddrSpace));
- return DAG.getLoad(PtrVT, dl, DAG.getEntryNode(),
- DAG.getIntPtrConstant(0),
- MachinePointerInfo(Ptr),
- false, false, false, 0);
+ return DAG.getNode(X86ISD::THREAD_POINTER_FROM_GS, dl, PtrVT);
}
}
// @LOCALMOD-END
@@ -13723,6 +13717,25 @@ X86TargetLowering::EmitLoweredWinAlloca(MachineInstr *MI,
return BB;
}
+// @LOCALMOD-BEGIN
+MachineBasicBlock *
+X86TargetLowering::EmitLoweredThreadPointerFromGs(MachineInstr *MI,
+ MachineBasicBlock *BB) const {
+ const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+ DebugLoc DL = MI->getDebugLoc();
+ // This generates "movl %gs:0, %DEST", which fetches the thread
+ // pointer on x86-32.
+ BuildMI(*BB, MI, DL, TII->get(X86::MOV32rm), MI->getOperand(0).getReg())
+ .addReg(/*Base=*/0)
+ .addImm(/*Scale=*/1)
+ .addReg(/*IndexReg=*/0)
+ .addImm(/*Disp=*/0)
+ .addReg(/*Segment=*/X86::GS);
+ MI->eraseFromParent();
+ return BB;
+}
+// @LOCALMOD-END
+
MachineBasicBlock *
X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
MachineBasicBlock *BB) const {
@@ -13998,6 +14011,10 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return EmitLoweredSegAlloca(MI, BB, false);
case X86::SEG_ALLOCA_64:
return EmitLoweredSegAlloca(MI, BB, true);
+ // @LOCALMOD-BEGIN
+ case X86::THREAD_POINTER_FROM_GS:
+ return EmitLoweredThreadPointerFromGs(MI, BB);
+ // @LOCALMOD-END
case X86::TLSCall_32:
case X86::TLSCall_64:
return EmitLoweredTLSCall(MI, BB);
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
index 872ef887c5..09f175db53 100644
--- a/lib/Target/X86/X86ISelLowering.h
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -220,6 +220,9 @@ namespace llvm {
// TLSADDR_IE - Thread Local Storage. (Initial Exec Model)
TLSADDR_IE,
+
+ // THREAD_POINTER_FROM_GS - Read thread pointer from %gs:0 on x86-32.
+ THREAD_POINTER_FROM_GS,
// @LOCALMOD-END
// TLSCALL - Thread Local Storage. When calling to an OS provided
@@ -941,6 +944,12 @@ namespace llvm {
MachineBasicBlock *BB,
bool Is64Bit) const;
+ // @LOCALMOD-BEGIN
+ MachineBasicBlock *EmitLoweredThreadPointerFromGs(
+ MachineInstr *MI,
+ MachineBasicBlock *BB) const;
+ // @LOCALMOD-END
+
MachineBasicBlock *EmitLoweredTLSCall(MachineInstr *MI,
MachineBasicBlock *BB) const;
diff --git a/lib/Target/X86/X86InstrCompiler.td b/lib/Target/X86/X86InstrCompiler.td
index 1430863055..a24ddf6f99 100644
--- a/lib/Target/X86/X86InstrCompiler.td
+++ b/lib/Target/X86/X86InstrCompiler.td
@@ -425,6 +425,16 @@ def TLS_base_addr64 : I<0, Pseudo, (outs), (ins i64mem:$sym),
Requires<[In64BitMode]>;
}
+// @LOCALMOD-BEGIN
+// NaCl TLS support
+let usesCustomInserter = 1 in {
+ def THREAD_POINTER_FROM_GS :
+ I<0, Pseudo, (outs GR32:$dst), (ins),
+ "# get thread pointer from %gs:0",
+ [(set GR32:$dst, (X86thread_pointer_from_gs))]>;
+}
+// @LOCALMOD-END
+
// Darwin TLS Support
// For i386, the address of the thunk is passed on the stack, on return the
// address of the variable is in %eax. %ecx is trashed during the function
diff --git a/lib/Target/X86/X86InstrInfo.td b/lib/Target/X86/X86InstrInfo.td
index 73de7ce0d3..cec4625135 100644
--- a/lib/Target/X86/X86InstrInfo.td
+++ b/lib/Target/X86/X86InstrInfo.td
@@ -103,6 +103,10 @@ def SDT_X86TLSBASEADDR : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
def SDT_X86TLSCALL : SDTypeProfile<0, 1, [SDTCisInt<0>]>;
+// @LOCALMOD-BEGIN
+def SDT_X86ThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
+// @LOCALMOD-END
+
def SDT_X86SEG_ALLOCA : SDTypeProfile<1, 1, [SDTCisVT<0, iPTR>, SDTCisVT<1, iPTR>]>;
def SDT_X86WIN_FTOL : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
@@ -219,6 +223,9 @@ def X86tlsaddr_le : SDNode<"X86ISD::TLSADDR_LE", SDT_X86TLSADDR,
def X86tlsaddr_ie : SDNode<"X86ISD::TLSADDR_IE", SDT_X86TLSADDR,
[SDNPHasChain, SDNPOptInGlue, SDNPOutGlue]>;
+
+def X86thread_pointer_from_gs :
+ SDNode<"X86ISD::THREAD_POINTER_FROM_GS", SDT_X86ThreadPointer>;
// @LOCALMOD-END
def X86ehret : SDNode<"X86ISD::EH_RETURN", SDT_X86EHRET,
diff --git a/test/NaCl/ARM/nacl-read-tp-intrinsic.ll b/test/NaCl/ARM/nacl-read-tp-intrinsic.ll
index 3ad5181149..1050b902ed 100644
--- a/test/NaCl/ARM/nacl-read-tp-intrinsic.ll
+++ b/test/NaCl/ARM/nacl-read-tp-intrinsic.ll
@@ -1,10 +1,8 @@
-; RUN: llc -mtriple=armv7-unknown-nacl -sfi-store -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble -r -triple armv7 - \
+; RUN: llc -mtriple=armv7-unknown-nacl -sfi-store -filetype=asm %s -o - \
; RUN: | FileCheck -check-prefix=ARM %s
-; RUN: llc -mtriple=armv7-unknown-nacl -sfi-store -filetype=obj -mtls-use-call %s -o - \
-; RUN: | llvm-objdump -disassemble -r -triple armv7 - \
+; RUN: llc -mtriple=armv7-unknown-nacl -sfi-store -filetype=asm -mtls-use-call %s -o - \
; RUN: | FileCheck -check-prefix=ARM_IRT %s
@@ -15,7 +13,8 @@ define i8* @get_thread_pointer() {
ret i8* %tp
}
+; ARM: get_thread_pointer:
; ARM: ldr r0, [r9]
-; ARM_IRT: bl #
-; ARM_IRT-NEXT: __aeabi_read_tp
+; ARM_IRT: get_thread_pointer:
+; ARM_IRT: bl __aeabi_read_tp
diff --git a/test/NaCl/X86/nacl-read-tp-intrinsic.ll b/test/NaCl/X86/nacl-read-tp-intrinsic.ll
index 2ad27fb6a4..2779f1b1e1 100644
--- a/test/NaCl/X86/nacl-read-tp-intrinsic.ll
+++ b/test/NaCl/X86/nacl-read-tp-intrinsic.ll
@@ -1,20 +1,16 @@
-; RUN: llc -mtriple=i386-unknown-nacl -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble r -triple i386 - \
+; RUN: llc -mtriple=i386-unknown-nacl -filetype=asm %s -o - \
; RUN: | FileCheck -check-prefix=X32 %s
-; RUN: llc -mtriple=i386-unknown-nacl -filetype=obj -mtls-use-call %s -o - \
-; RUN: | llvm-objdump -disassemble -r -triple i386 - \
-; RUN: | FileCheck -check-prefix=X32_IRT %s
+; RUN: llc -mtriple=i386-unknown-nacl -filetype=asm -mtls-use-call %s -o - \
+; RUN: | FileCheck -check-prefix=USE_CALL %s
-; RUN: llc -mtriple=x86_64-unknown-nacl -filetype=obj %s -o - \
-; RUN: | llvm-objdump -disassemble -r -triple x86_64 - \
-; RUN: | FileCheck -check-prefix=X64 %s
+; RUN: llc -mtriple=x86_64-unknown-nacl -filetype=asm %s -o - \
+; RUN: | FileCheck -check-prefix=USE_CALL %s
; "-mtls-use-call" should not make any difference on x86-64.
-; RUN: llc -mtriple=x86_64-unknown-nacl -filetype=obj -mtls-use-call %s -o - \
-; RUN: | llvm-objdump -disassemble -r -triple x86_64 - \
-; RUN: | FileCheck -check-prefix=X64 %s
+; RUN: llc -mtriple=x86_64-unknown-nacl -filetype=asm -mtls-use-call %s -o - \
+; RUN: | FileCheck -check-prefix=USE_CALL %s
declare i8* @llvm.nacl.read.tp()
@@ -24,13 +20,25 @@ define i8* @get_thread_pointer() {
ret i8* %tp
}
+; X32: get_thread_pointer:
; X32: movl %gs:0, %eax
-; There appears to be a bug in llvm-objdump which stops it from
-; showing the symbol name "__nacl_read_tp" in the relocation output on
-; x86-32.
-; X32_IRT: call
-; X32_IRT-NEXT: R_386_PC32 Unknown
+; USE_CALL: get_thread_pointer:
+; USE_CALL: naclcall __nacl_read_tp
-; X64: call
-; X64-NEXT: __nacl_read_tp
+
+; Make sure that we do not generate:
+; movl $1000, %eax
+; addl %gs:0, %eax
+; The x86-32 NaCl validator only accepts %gs with "mov", not with
+; "add". Note that we had to use a large immediate to trigger the bug
+; and generate the code above.
+define i8* @get_thread_pointer_add() {
+ %tp = call i8* @llvm.nacl.read.tp()
+ %result = getelementptr i8* %tp, i32 1000
+ ret i8* %result
+}
+
+; X32: get_thread_pointer_add:
+; X32: movl %gs:0, %eax
+; X32: addl $1000, %eax