Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -164,8 +164,10 @@ addUInt(*Loc, dwarf::DW_FORM_udata, DD->getAddressPool().getIndex(Sym, /* TLS */ true)); } - // 3) followed by a custom OP to make the debugger do a TLS lookup. - addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address); + // 3) followed by an OP to make the debugger do a TLS lookup. + addUInt(*Loc, dwarf::DW_FORM_data1, + DD->useGNUTLSOpcode() ? dwarf::DW_OP_GNU_push_tls_address + : dwarf::DW_OP_form_tls_address); } else { DD->addArangeLabel(SymbolCU(this, Sym)); addOpAddress(*Loc, Sym); Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -290,6 +290,9 @@ // text. bool UsedNonDefaultText; + // Whether to use the GNU TLS opcode (instead of the standard opcode). + bool UseGNUTLSOpcode; + // Version of dwarf we're emitting. unsigned DwarfVersion; @@ -318,6 +321,7 @@ // True iff there are multiple CUs in this module. bool SingleCU; bool IsDarwin; + bool IsPS4; AddressPool AddrPool; @@ -540,6 +544,10 @@ SymSize[Sym] = Size; } + /// \brief Returns whether to use DW_OP_GNU_push_tls_address, instead of the + /// standard DW_OP_form_tls_address opcode + bool useGNUTLSOpcode() const { return UseGNUTLSOpcode; } + // Experimental DWARF5 features. /// \brief Returns whether or not to emit tables that dwarf consumers can Index: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -193,6 +193,7 @@ UsedNonDefaultText(false), SkeletonHolder(A, "skel_string", DIEValueAllocator), IsDarwin(Triple(A->getTargetTriple()).isOSDarwin()), + IsPS4(Triple(A->getTargetTriple()).isPS4()), AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4)), AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, @@ -231,6 +232,10 @@ DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber : MMI->getModule()->getDwarfVersion(); + // Darwin and PS4 use the standard TLS opcode (defined in DWARF 3). + // Everybody else uses GNU's. + UseGNUTLSOpcode = !(IsDarwin || IsPS4) || DwarfVersion < 3; + Asm->OutStreamer.getContext().setDwarfVersion(DwarfVersion); { Index: llvm/trunk/test/DebugInfo/X86/tls.ll =================================================================== --- llvm/trunk/test/DebugInfo/X86/tls.ll +++ llvm/trunk/test/DebugInfo/X86/tls.ll @@ -1,17 +1,20 @@ ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu \ -; RUN: | FileCheck --check-prefix=CHECK --check-prefix=SINGLE --check-prefix=SINGLE-64 %s +; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=GNUOP %s ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=i386-linux-gnu \ -; RUN: | FileCheck --check-prefix=CHECK --check-prefix=SINGLE --check-prefix=SINGLE-32 %s +; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-32 --check-prefix=GNUOP %s ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-linux-gnu -split-dwarf=Enable \ -; RUN: | FileCheck --check-prefix=CHECK --check-prefix=FISSION %s +; RUN: | FileCheck --check-prefix=FISSION --check-prefix=GNUOP %s ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-scei-ps4 \ -; RUN: | FileCheck --check-prefix=CHECK --check-prefix=SINGLE --check-prefix=SINGLE-64 %s +; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=STDOP %s + +; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-apple-darwin \ +; RUN: | FileCheck --check-prefix=DARWIN --check-prefix=STDOP %s ; RUN: llc %s -o - -filetype=asm -O0 -mtriple=x86_64-unknown-freebsd \ -; RUN: | FileCheck --check-prefix=CHECK --check-prefix=SINGLE --check-prefix=SINGLE-64 %s +; RUN: | FileCheck --check-prefix=SINGLE --check-prefix=SINGLE-64 --check-prefix=GNUOP %s ; FIXME: add relocation and DWARF expression support to llvm-dwarfdump & use ; that here instead of raw assembly printing @@ -25,19 +28,29 @@ ; FISSION-NEXT: .byte 0 ; SINGLE: .section .debug_info, +; DARWIN: .section {{.*}}debug_info, + ; 10 bytes of data in this DW_FORM_block1 representation of the location of 'tls' ; SINGLE-64: .byte 10 # DW_AT_location ; DW_OP_const8u (0x0e == 14) of address ; SINGLE-64-NEXT: .byte 14 ; SINGLE-64-NEXT: .quad tls@DTPOFF +; DARWIN: .byte 10 ## DW_AT_location +; DW_OP_const8u (0x0e == 14) of address +; DARWIN-NEXT: .byte 14 +; DARWIN-NEXT: .quad _tls + +; 6 bytes of data in 32-bit mode ; SINGLE-32: .byte 6 # DW_AT_location ; DW_OP_const4u (0x0e == 12) of address ; SINGLE-32-NEXT: .byte 12 ; SINGLE-32-NEXT: .long tls@DTPOFF ; DW_OP_GNU_push_tls_address -; CHECK-NEXT: .byte 224 +; GNUOP-NEXT: .byte 224 +; DW_OP_form_tls_address +; STDOP-NEXT: .byte 155 ; FISSION: DW_TAG_variable ; FISSION: .byte 2 # DW_AT_location