diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h index 077913d7fa5..999f4a25781 100644 --- a/include/llvm/BinaryFormat/Wasm.h +++ b/include/llvm/BinaryFormat/Wasm.h @@ -359,6 +359,7 @@ enum WasmSymbolType : unsigned { enum WasmSegmentFlag : unsigned { WASM_SEG_FLAG_STRINGS = 0x1, + WASM_SEG_FLAG_TLS = 0x2, }; // Kinds of event attributes. diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 54d65ccac50..31122295fa3 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -2009,11 +2009,14 @@ static const Comdat *getWasmComdat(const GlobalValue *GV) { static unsigned getWasmSectionFlags(SectionKind K) { unsigned Flags = 0; - // TODO(sbc): Add suport for K.isMergeableConst() + if (K.isThreadLocal()) + Flags |= wasm::WASM_SEG_FLAG_TLS; if (K.isMergeableCString()) Flags |= wasm::WASM_SEG_FLAG_STRINGS; + // TODO(sbc): Add suport for K.isMergeableConst() + return Flags; } diff --git a/lib/MC/MCParser/WasmAsmParser.cpp b/lib/MC/MCParser/WasmAsmParser.cpp index fdf8c45ba5c..833530bef3b 100644 --- a/lib/MC/MCParser/WasmAsmParser.cpp +++ b/lib/MC/MCParser/WasmAsmParser.cpp @@ -100,6 +100,9 @@ public: case 'G': Group = true; break; + case 'T': + flags |= wasm::WASM_SEG_FLAG_TLS; + break; case 'S': flags |= wasm::WASM_SEG_FLAG_STRINGS; break; diff --git a/lib/MC/MCSectionWasm.cpp b/lib/MC/MCSectionWasm.cpp index 9faa4caad64..45991326326 100644 --- a/lib/MC/MCSectionWasm.cpp +++ b/lib/MC/MCSectionWasm.cpp @@ -69,6 +69,8 @@ void MCSectionWasm::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, OS << 'G'; if (SegmentFlags & wasm::WASM_SEG_FLAG_STRINGS) OS << 'S'; + if (SegmentFlags & wasm::WASM_SEG_FLAG_TLS) + OS << 'T'; OS << '"'; diff --git a/lib/ObjectYAML/WasmYAML.cpp b/lib/ObjectYAML/WasmYAML.cpp index 0017e7e609a..6b7357c4d1d 100644 --- a/lib/ObjectYAML/WasmYAML.cpp +++ b/lib/ObjectYAML/WasmYAML.cpp @@ -544,6 +544,7 @@ void ScalarBitSetTraits::bitset( IO &IO, WasmYAML::SegmentFlags &Value) { #define BCase(X) IO.bitSetCase(Value, #X, wasm::WASM_SEG_FLAG_##X) BCase(STRINGS); + BCase(TLS); #undef BCase } diff --git a/test/CodeGen/WebAssembly/target-features-tls.ll b/test/CodeGen/WebAssembly/target-features-tls.ll index e146bdae5f5..f5ec6842de7 100644 --- a/test/CodeGen/WebAssembly/target-features-tls.ll +++ b/test/CodeGen/WebAssembly/target-features-tls.ll @@ -23,4 +23,4 @@ target triple = "wasm32-unknown-unknown" ; BULK-MEM-NEXT: .int8 43 ; BULK-MEM-NEXT: .int8 11 ; BULK-MEM-NEXT: .ascii "bulk-memory" -; BULK-MEM-NEXT: .tbss.foo,"",@ +; BULK-MEM-NEXT: .tbss.foo,"T",@ diff --git a/test/CodeGen/WebAssembly/tls-general-dynamic.ll b/test/CodeGen/WebAssembly/tls-general-dynamic.ll index 16a312bd6ba..cb20066e14c 100644 --- a/test/CodeGen/WebAssembly/tls-general-dynamic.ll +++ b/test/CodeGen/WebAssembly/tls-general-dynamic.ll @@ -105,7 +105,7 @@ define void @tls_base_write(i8** %output) { } ; CHECK: .type tls,@object -; TLS-NEXT: .section .tbss.tls,"",@ +; TLS-NEXT: .section .tbss.tls,"T",@ ; NO-TLS-NEXT: .section .bss.tls,"",@ ; CHECK-NEXT: .p2align 2 ; CHECK-NEXT: tls: diff --git a/test/CodeGen/WebAssembly/tls-local-exec.ll b/test/CodeGen/WebAssembly/tls-local-exec.ll index 7cc043a13ac..c6ae34b7fc8 100644 --- a/test/CodeGen/WebAssembly/tls-local-exec.ll +++ b/test/CodeGen/WebAssembly/tls-local-exec.ll @@ -72,7 +72,7 @@ define i32 @tls_size() { } ; CHECK: .type tls,@object -; TLS-NEXT: .section .tbss.tls,"",@ +; TLS-NEXT: .section .tbss.tls,"T",@ ; NO-TLS-NEXT: .section .bss.tls,"",@ ; CHECK-NEXT: .p2align 2 ; CHECK-NEXT: tls: diff --git a/test/MC/WebAssembly/tls.s b/test/MC/WebAssembly/tls.s index f1dba829944..2df245ff938 100644 --- a/test/MC/WebAssembly/tls.s +++ b/test/MC/WebAssembly/tls.s @@ -5,15 +5,26 @@ tls_store: .functype tls_store (i32) -> () # CHECK: global.get __tls_base - # CHECK-NEXT: i32.const tls@TLSREL + # CHECK-NEXT: i32.const tls1@TLSREL # CHECK-NEXT: i32.add # CHECK-NEXT: i32.store 0 global.get __tls_base - i32.const tls@TLSREL + i32.const tls1@TLSREL i32.add i32.store 0 end_function +.section .tls.foo,"T",@ +# CHECK: .tls.foo,"T",@ +tls1: + .int32 42 + .size tls1, 4 + +.section custom_tls,"T",@ +# CHECK: custom_tls,"T",@ +tls2: + .int32 43 + .size tls2, 4 # CHECK-OBJ: - Type: CODE # CHECK-OBJ-NEXT: Relocations: @@ -39,5 +50,22 @@ tls_store: # CHECK-OBJ-NEXT: Flags: [ UNDEFINED ] # CHECK-OBJ-NEXT: - Index: 2 # CHECK-OBJ-NEXT: Kind: DATA -# CHECK-OBJ-NEXT: Name: tls -# CHECK-OBJ-NEXT: Flags: [ UNDEFINED ] +# CHECK-OBJ-NEXT: Name: tls1 +# CHECK-OBJ-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-OBJ-NEXT: Segment: 0 +# CHECK-OBJ-NEXT: Size: 4 +# CHECK-OBJ-NEXT: - Index: 3 +# CHECK-OBJ-NEXT: Kind: DATA +# CHECK-OBJ-NEXT: Name: tls2 +# CHECK-OBJ-NEXT: Flags: [ BINDING_LOCAL ] +# CHECK-OBJ-NEXT: Segment: 1 +# CHECK-OBJ-NEXT: Size: 4 +# CHECK-OBJ-NEXT: SegmentInfo: +# CHECK-OBJ-NEXT: - Index: 0 +# CHECK-OBJ-NEXT: Name: .tls.foo +# CHECK-OBJ-NEXT: Alignment: 0 +# CHECK-OBJ-NEXT: Flags: [ TLS ] +# CHECK-OBJ-NEXT: - Index: 1 +# CHECK-OBJ-NEXT: Name: custom_tls +# CHECK-OBJ-NEXT: Alignment: 0 +# CHECK-OBJ-NEXT: Flags: [ TLS ]