diff options
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 31 | ||||
-rw-r--r-- | lib/Target/X86/X86ISelLowering.h | 9 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrCompiler.td | 10 | ||||
-rw-r--r-- | lib/Target/X86/X86InstrInfo.td | 7 | ||||
-rw-r--r-- | test/NaCl/ARM/nacl-read-tp-intrinsic.ll | 11 | ||||
-rw-r--r-- | test/NaCl/X86/nacl-read-tp-intrinsic.ll | 44 |
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 |