xref: /llvm-project/lld/test/wasm/tls.s (revision a0495e6b008c7b1f5af2d0756bf62aefdc6a43ea)
1# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown -o %t.o %s
2
3.globaltype __tls_base, i32
4.globaltype __tls_align, i32, immutable
5
6.globl tls1_addr
7tls1_addr:
8  .functype tls1_addr () -> (i32)
9  global.get __tls_base
10  i32.const tls1@TLSREL
11  i32.add
12  end_function
13
14.globl tls2_addr
15tls2_addr:
16  .functype tls2_addr () -> (i32)
17  global.get __tls_base
18  i32.const tls2@TLSREL
19  i32.add
20  end_function
21
22.globl tls3_addr
23tls3_addr:
24  .functype tls3_addr () -> (i32)
25  global.get __tls_base
26  i32.const tls3
27  i32.add
28  end_function
29
30.globl tls_align
31tls_align:
32  .functype tls_align () -> (i32)
33  global.get __tls_align
34  end_function
35
36# TLS symbols can also be accessed by `global.get tls1@GOT@TLS`
37# which is the pattern emitted for non-DSO-local symbols.
38# In this case the global that holds that address must be
39# initialized by `__wasm_apply_global_tls_relocs` which is
40# called by `__wasm_init_tls`.
41.globl tls1_got_addr
42tls1_got_addr:
43  .functype tls1_got_addr () -> (i32)
44  global.get tls1@GOT@TLS
45  end_function
46
47.section  .bss.no_tls,"",@
48.globl  no_tls
49.p2align  2
50no_tls:
51  .int32  0
52  .size no_tls, 4
53
54// Older versions of LLVM did not use the "T" flag so we need to support
55// infering TLS from the name alone.
56.section  .tdata.tls1,"",@
57.globl  tls1
58.p2align  2
59tls1:
60  .int32  1
61  .size tls1, 4
62
63.section  sec_tls2,"T",@
64.globl  tls2
65.p2align  2
66tls2:
67  .int32  1
68  .size tls2, 4
69
70.section  sec_tls3,"T",@
71.globl  tls3
72.p2align  2
73tls3:
74  .int32  0
75  .size tls3, 4
76
77.section  .custom_section.target_features,"",@
78  .int8 2
79  .int8 43
80  .int8 7
81  .ascii  "atomics"
82  .int8 43
83  .int8 11
84  .ascii  "bulk-memory"
85
86# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-entry -o %t.wasm %t.o
87# RUN: obj2yaml %t.wasm | FileCheck %s
88# RUN: llvm-objdump -d --no-show-raw-insn --no-leading-addr %t.wasm | FileCheck --check-prefix=ASM %s --
89
90# RUN: wasm-ld -no-gc-sections --shared-memory --max-memory=131072 --no-merge-data-segments --no-entry -o %t2.wasm %t.o
91# RUN: obj2yaml %t2.wasm | FileCheck %s
92
93# CHECK:      - Type:            GLOBAL
94# __stack_pointer
95# CHECK-NEXT:   Globals:
96# CHECK-NEXT:     - Index:           0
97# CHECK-NEXT:       Type:            I32
98# CHECK-NEXT:       Mutable:         true
99# CHECK-NEXT:       InitExpr:
100# CHECK-NEXT:         Opcode:          I32_CONST
101# CHECK-NEXT:         Value:           66592
102
103# __tls_base
104# CHECK-NEXT:     - Index:           1
105# CHECK-NEXT:       Type:            I32
106# CHECK-NEXT:       Mutable:         true
107# CHECK-NEXT:       InitExpr:
108# CHECK-NEXT:         Opcode:          I32_CONST
109# CHECK-NEXT:         Value:           0
110
111# __tls_size
112# CHECK-NEXT:     - Index:           2
113# CHECK-NEXT:       Type:            I32
114# CHECK-NEXT:       Mutable:         false
115# CHECK-NEXT:       InitExpr:
116# CHECK-NEXT:         Opcode:          I32_CONST
117# CHECK-NEXT:         Value:           12
118
119# __tls_align
120# CHECK-NEXT:     - Index:           3
121# CHECK-NEXT:       Type:            I32
122# CHECK-NEXT:       Mutable:         false
123# CHECK-NEXT:       InitExpr:
124# CHECK-NEXT:         Opcode:          I32_CONST
125# CHECK-NEXT:         Value:           4
126
127
128# ASM-LABEL: <__wasm_init_tls>:
129# ASM-EMPTY:
130# ASM-NEXT:   local.get 0
131# ASM-NEXT:   global.set 1
132# ASM-NEXT:   local.get 0
133# ASM-NEXT:   i32.const 0
134# ASM-NEXT:   i32.const 12
135# ASM-NEXT:   memory.init 0, 0
136# call to __wasm_apply_global_tls_relocs
137# ASM-NEXT:   call 3
138# ASM-NEXT:   end
139
140# ASM-LABEL: <__wasm_apply_global_tls_relocs>:
141# ASM-EMPTY:
142# ASM-NEXT:   global.get      1
143# ASM-NEXT:   i32.const       0
144# ASM-NEXT:   i32.add
145# ASM-NEXT:   global.set      4
146# ASM-NEXT:   end
147
148# ASM-LABEL: <tls1_addr>:
149# ASM-EMPTY:
150# ASM-NEXT:   global.get 1
151# ASM-NEXT:   i32.const 0
152# ASM-NEXT:   i32.add
153# ASM-NEXT:   end
154
155# ASM-LABEL: <tls2_addr>:
156# ASM-EMPTY:
157# ASM-NEXT:   global.get 1
158# ASM-NEXT:   i32.const 4
159# ASM-NEXT:   i32.add
160# ASM-NEXT:   end
161
162# ASM-LABEL: <tls3_addr>:
163# ASM-EMPTY:
164# ASM-NEXT:   global.get 1
165# ASM-NEXT:   i32.const 8
166# ASM-NEXT:   i32.add
167# ASM-NEXT:   end
168
169# ASM-LABEL: <tls_align>:
170# ASM-EMPTY:
171# ASM-NEXT:   global.get 3
172# ASM-NEXT:   end
173
174# Also verify TLS usage with --relocatable
175# RUN: wasm-ld --relocatable -o %t3.wasm %t.o
176# RUN: obj2yaml %t3.wasm | FileCheck %s --check-prefix=RELOC
177
178# RELOC:       - Type:            IMPORT
179# RELOC-NEXT:    Imports:
180# RELOC-NEXT:      - Module:          env
181# RELOC-NEXT:        Field:           __tls_base
182# RELOC-NEXT:        Kind:            GLOBAL
183# RELOC-NEXT:        GlobalType:      I32
184# RELOC-NEXT:        GlobalMutable:   true
185# RELOC-NEXT:      - Module:          env
186# RELOC-NEXT:        Field:           __tls_align
187# RELOC-NEXT:        Kind:            GLOBAL
188# RELOC-NEXT:        GlobalType:      I32
189# RELOC-NEXT:        GlobalMutable:   false
190
191# RELOC:         GlobalNames:
192# RELOC-NEXT:      - Index:           0
193# RELOC-NEXT:        Name:            __tls_base
194# RELOC-NEXT:      - Index:           1
195# RELOC-NEXT:        Name:            __tls_align
196# RELOC-NEXT:      - Index:           2
197# RELOC-NEXT:        Name:            GOT.data.internal.tls1
198# RELOC-NEXT:    DataSegmentNames:
199# RELOC-NEXT:      - Index:           0
200# RELOC-NEXT:        Name:            .tdata
201# RELOC-NEXT:      - Index:           1
202# RELOC-NEXT:        Name:            .bss.no_tls
203