xref: /llvm-project/llvm/test/MC/WebAssembly/basic-assembly.s (revision 4f7ff6bb38c8952a24b5cbae07031d78e359e573)
1# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+tail-call,+reference-types,atomics,+simd128,+nontrapping-fptoint < %s | FileCheck %s
2# Check that it converts to .o without errors, but don't check any output:
3# RUN: llvm-mc -triple=wasm32-unknown-unknown -filetype=obj -mattr=+tail-call,+reference-types,+atomics,+simd128,+nontrapping-fptoint -o %t.o < %s
4
5.functype   something1 () -> ()
6.functype   something2 (i64) -> (i32, f64)
7.functype   something3 () -> (i32)
8.globaltype __stack_pointer, i32
9
10empty_func:
11    .functype empty_func () -> ()
12    end_function
13
14test0:
15# local labels can appear between label and its .functype.
16.Ltest0begin:
17    # Test all types:
18    .functype   test0 (i32, i64) -> (i32)
19    .tagtype  __cpp_exception i32
20    .local      f32, f64, v128, v128
21    # Explicit getlocal/setlocal:
22    local.get   2
23    local.set   2
24    # Immediates:
25    f32.const   -1.0
26    drop
27    f32.const   -infinity
28    drop
29    v128.const  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
30    drop
31    v128.const  0, 1, 2, 3, 4, 5, 6, 7
32    drop
33    local.get   0
34    f64.const   0x1.999999999999ap1
35    # Indirect addressing:
36    f64.store   1234:p2align=4
37    i32.const   -1
38    f64.const   nan
39    f64.store   1234     # Natural alignment (3)
40    # Loops, conditionals, binary ops, calls etc:
41    block       f32
42    f32.const   2.0
43    i32.const   1
44    local.get   0
45    i32.ge_s
46    br_if       0        # 0: down to label0
47.LBB0_1:
48    loop        void      # label1:
49    call        something1
50    i64.const   1234
51    call        something2
52    i32.const   0
53    call_indirect (i32, f64) -> ()
54    i32.const   1
55    i32.const   2
56    i32.add
57    local.tee   0
58    local.get   0
59    i32.lt_s
60    br_if       0        # 0: up to label1
61.LBB0_2:
62    end_loop
63    end_block            # label0:
64    drop
65    block       i32
66    block       void
67    block       void
68    block       void
69    block       () -> (i32, i32)
70    i32.const   1
71    i32.const   2
72    end_block
73    drop
74    br_table {0, 1, 2}   # 2 entries, default
75    end_block            # first entry jumps here.
76    i32.const   1
77    br          2
78    end_block            # second entry jumps here.
79    i32.const   2
80    br          1
81    end_block            # default jumps here.
82    i32.const   3
83    end_block            # "switch" exit.
84    if                   # void
85    i32.const   0
86    if          i32
87    i32.const   0
88    end_if
89    drop
90    else
91    end_if
92    block       void
93    i32.const   2
94    return
95    end_block
96    block       void
97    return_call something3
98    end_block
99    block       void
100    i32.const   3
101    return_call_indirect () -> (i32)
102    end_block
103    local.get   4
104    local.get   5
105    f32x4.add
106    drop
107    # Test correct parsing of instructions with / and : in them:
108    # TODO: enable once instruction has been added.
109    #i32x4.trunc_sat_f32x4_s
110    f32.const   1.0
111    i32.trunc_f32_s
112    i32.atomic.load 0
113    i32.const   0
114    memory.atomic.notify 0
115    drop
116.LBB0_3:
117    i32.const   .L.str
118    i32.load8_u .L.str+2
119    i32.load16_u .L.str:p2align=0
120.LBB0_4:
121    #i32.trunc_sat_f32_s
122    global.get  __stack_pointer
123    global.set  __stack_pointer
124    end_function
125
126    .section    .rodata..L.str,"",@
127    .hidden     .L.str
128    .type       .L.str,@object
129.L.str:
130    .int8       'H'
131    .asciz      "ello, World!"
132    .int16      1234
133    .int64      5000000000
134    .int32      2000000000
135    .size       .L.str, 28
136
137    .data
138    .int8       73
139
140    .section    .init_array.42,"",@
141    .p2align    2
142    .int32      test0
143
144    .ident      "clang version 9.0.0 (trunk 364502) (llvm/trunk 364571)"
145
146.tabletype empty_externref_table, externref
147empty_externref_table:
148
149.tabletype empty_funcref_table, funcref
150empty_funcref_table:
151
152.tabletype empty_exnref_table, exnref
153empty_exnref_table:
154
155# CHECK:           .globaltype __stack_pointer, i32
156
157# CHECK-LABEL: empty_func:
158# CHECK-NEXT:      .functype	empty_func () -> ()
159# CHECK-NEXT:      end_function
160# CHECK-LABEL: test0:
161# CHECK-NEXT:  .Ltest0begin:
162# CHECK-NEXT:      .functype   test0 (i32, i64) -> (i32)
163# CHECK-NEXT:      .tagtype  __cpp_exception i32
164# CHECK-NEXT:      .local      f32, f64
165# CHECK-NEXT:      local.get   2
166# CHECK-NEXT:      local.set   2
167# CHECK-NEXT:      f32.const   -0x1p0
168# CHECK-NEXT:      drop
169# CHECK-NEXT:      f32.const   -infinity
170# CHECK-NEXT:      drop
171# CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
172# CHECK-NEXT:      drop
173# CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7
174# CHECK-NEXT:      drop
175# CHECK-NEXT:      local.get   0
176# CHECK-NEXT:      f64.const   0x1.999999999999ap1
177# CHECK-NEXT:      f64.store   1234:p2align=4
178# CHECK-NEXT:      i32.const   -1
179# CHECK-NEXT:      f64.const   nan
180# CHECK-NEXT:      f64.store   1234
181# CHECK-NEXT:      block       f32
182# CHECK-NEXT:      f32.const   0x1p1
183# CHECK-NEXT:      i32.const   1
184# CHECK-NEXT:      local.get   0
185# CHECK-NEXT:      i32.ge_s
186# CHECK-NEXT:      br_if       0       # 0: down to label0
187# CHECK-NEXT:  .LBB0_1:
188# CHECK-NEXT:      loop                # label1:
189# CHECK-NEXT:      call        something1
190# CHECK-NEXT:      i64.const   1234
191# CHECK-NEXT:      call        something2
192# CHECK-NEXT:      i32.const   0
193# CHECK-NEXT:      call_indirect __indirect_function_table, (i32, f64) -> ()
194# CHECK-NEXT:      i32.const   1
195# CHECK-NEXT:      i32.const   2
196# CHECK-NEXT:      i32.add
197# CHECK-NEXT:      local.tee   0
198# CHECK-NEXT:      local.get   0
199# CHECK-NEXT:      i32.lt_s
200# CHECK-NEXT:      br_if       0       # 0: up to label1
201# CHECK-NEXT:  .LBB0_2:
202# CHECK-NEXT:      end_loop
203# CHECK-NEXT:      end_block           # label0:
204# CHECK-NEXT:      drop
205# CHECK-NEXT:      block       i32
206# CHECK-NEXT:      block
207# CHECK-NEXT:      block
208# CHECK-NEXT:      block
209# CHECK-NEXT:      block       () -> (i32, i32)
210# CHECK-NEXT:      i32.const   1
211# CHECK-NEXT:      i32.const   2
212# CHECK-NEXT:      end_block
213# CHECK-NEXT:      drop
214# CHECK-NEXT:      br_table {0, 1, 2}  # 1: down to label4
215# CHECK-NEXT:                          # 2: down to label3
216# CHECK-NEXT:      end_block           # label5:
217# CHECK-NEXT:      i32.const   1
218# CHECK-NEXT:      br          2       # 2: down to label2
219# CHECK-NEXT:      end_block           # label4:
220# CHECK-NEXT:      i32.const   2
221# CHECK-NEXT:      br          1       # 1: down to label2
222# CHECK-NEXT:      end_block           # label3:
223# CHECK-NEXT:      i32.const   3
224# CHECK-NEXT:      end_block           # label2:
225# CHECK-NEXT:      if
226# CHECK-NEXT:      i32.const   0
227# CHECK-NEXT:      if          i32
228# CHECK-NEXT:      i32.const   0
229# CHECK-NEXT:      end_if
230# CHECK-NEXT:      drop
231# CHECK-NEXT:      else
232# CHECK-NEXT:      end_if
233# CHECK-NEXT:      block
234# CHECK-NEXT:      i32.const   2
235# CHECK-NEXT:      return
236# CHECK-NEXT:      end_block
237# CHECK-NEXT:      block
238# CHECK-NEXT:      return_call something3
239# CHECK-NEXT:      end_block
240# CHECK-NEXT:      block
241# CHECK-NEXT:      i32.const   3
242# CHECK-NEXT:      return_call_indirect __indirect_function_table, () -> (i32)
243# CHECK-NEXT:      end_block
244# CHECK-NEXT:      local.get   4
245# CHECK-NEXT:      local.get   5
246# CHECK-NEXT:      f32x4.add
247# CHECK-NEXT:      drop
248# CHECK-NEXT:      f32.const   0x1p0
249# CHECK-NEXT:      i32.trunc_f32_s
250# CHECK-NEXT:      i32.atomic.load 0
251# CHECK-NEXT:      i32.const   0
252# CHECK-NEXT:      memory.atomic.notify 0
253# CHECK-NEXT:      drop
254# CHECK-NEXT:  .LBB0_3:
255# CHECK-NEXT:      i32.const   .L.str
256# CHECK-NEXT:      i32.load8_u .L.str+2
257# CHECK-NEXT:      i32.load16_u .L.str:p2align=0
258# CHECK-NEXT:  .LBB0_4:
259# CHECK-NEXT:      global.get  __stack_pointer
260# CHECK-NEXT:      global.set  __stack_pointer
261# CHECK-NEXT:      end_function
262
263# CHECK:           .section    .rodata..L.str,"",@
264# CHECK-NEXT:      .hidden     .L.str
265# CHECK-NEXT:  .L.str:
266# CHECK-NEXT:      .int8       72
267# CHECK-NEXT:      .asciz      "ello, World!"
268# CHECK-NEXT:      .int16      1234
269# CHECK-NEXT:      .int64      5000000000
270# CHECK-NEXT:      .int32      2000000000
271# CHECK-NEXT:      .size       .L.str, 28
272
273# CHECK:           .data
274# CHECK-EMPTY:
275# CHECK-NEXT:      .int8       73
276
277# CHECK:           .section    .init_array.42,"",@
278# CHECK-NEXT:      .p2align    2
279# CHECK-NEXT:      .int32      test0
280
281# CHECK:           .tabletype empty_externref_table, externref
282# CHECK-NEXT: empty_externref_table:
283
284# CHECK:           .tabletype empty_funcref_table, funcref
285# CHECK-NEXT: empty_funcref_table:
286
287# CHECK:           .tabletype empty_exnref_table, exnref
288# CHECK-NEXT: empty_exnref_table:
289