1# RUN: llvm-mc -triple=wasm32-unknown-unknown -mattr=+tail-call,+reference-types,atomics,+simd128,+nontrapping-fptoint,+exception-handling < %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,+exception-handling -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    if          i32
86    end_if
87    else
88    end_if
89    drop
90    block       void
91    i32.const   2
92    return
93    end_block
94    block       void
95    return_call something3
96    end_block
97    block       void
98    i32.const   3
99    return_call_indirect () -> (i32)
100    end_block
101    local.get   4
102    local.get   5
103    f32x4.add
104    drop
105    # Test correct parsing of instructions with / and : in them:
106    # TODO: enable once instruction has been added.
107    #i32x4.trunc_sat_f32x4_s
108    f32.const   1.0
109    i32.trunc_f32_s
110    try
111    i32.atomic.load 0
112    i32.const   0
113    memory.atomic.notify 0
114    drop
115.LBB0_3:
116    catch       __cpp_exception
117    local.set   0
118    end_try
119    i32.const   .L.str
120    i32.load8_u .L.str+2
121    i32.load16_u .L.str:p2align=0
122    throw 0
123.LBB0_4:
124    #i32.trunc_sat_f32_s
125    global.get  __stack_pointer
126    global.set  __stack_pointer
127    end_function
128
129    .section    .rodata..L.str,"",@
130    .hidden     .L.str
131    .type       .L.str,@object
132.L.str:
133    .int8       'H'
134    .asciz      "ello, World!"
135    .int16      1234
136    .int64      5000000000
137    .int32      2000000000
138    .size       .L.str, 28
139
140    .data
141    .int8       73
142
143    .section    .init_array.42,"",@
144    .p2align    2
145    .int32      test0
146
147    .ident      "clang version 9.0.0 (trunk 364502) (llvm/trunk 364571)"
148
149.tabletype empty_eref_table, externref
150empty_eref_table:
151
152.tabletype empty_fref_table, funcref
153empty_fref_table:
154
155
156# CHECK:           .text
157# CHECK:           .globaltype __stack_pointer, i32
158
159# CHECK-LABEL: empty_func:
160# CHECK-NEXT:      .functype	empty_func () -> ()
161# CHECK-NEXT:      end_function
162# CHECK-LABEL: test0:
163# CHECK-NEXT:  .Ltest0begin:
164# CHECK-NEXT:      .functype   test0 (i32, i64) -> (i32)
165# CHECK-NEXT:      .tagtype  __cpp_exception i32
166# CHECK-NEXT:      .local      f32, f64
167# CHECK-NEXT:      local.get   2
168# CHECK-NEXT:      local.set   2
169# CHECK-NEXT:      f32.const   -0x1p0
170# CHECK-NEXT:      drop
171# CHECK-NEXT:      f32.const   -infinity
172# CHECK-NEXT:      drop
173# CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
174# CHECK-NEXT:      drop
175# CHECK-NEXT:      v128.const  0, 1, 2, 3, 4, 5, 6, 7
176# CHECK-NEXT:      drop
177# CHECK-NEXT:      local.get   0
178# CHECK-NEXT:      f64.const   0x1.999999999999ap1
179# CHECK-NEXT:      f64.store   1234:p2align=4
180# CHECK-NEXT:      i32.const   -1
181# CHECK-NEXT:      f64.const   nan
182# CHECK-NEXT:      f64.store   1234
183# CHECK-NEXT:      block       f32
184# CHECK-NEXT:      f32.const   0x1p1
185# CHECK-NEXT:      i32.const   1
186# CHECK-NEXT:      local.get   0
187# CHECK-NEXT:      i32.ge_s
188# CHECK-NEXT:      br_if       0       # 0: down to label0
189# CHECK-NEXT:  .LBB0_1:
190# CHECK-NEXT:      loop                # label1:
191# CHECK-NEXT:      call        something1
192# CHECK-NEXT:      i64.const   1234
193# CHECK-NEXT:      call        something2
194# CHECK-NEXT:      i32.const   0
195# CHECK-NEXT:      call_indirect __indirect_function_table, (i32, f64) -> ()
196# CHECK-NEXT:      i32.const   1
197# CHECK-NEXT:      i32.const   2
198# CHECK-NEXT:      i32.add
199# CHECK-NEXT:      local.tee   0
200# CHECK-NEXT:      local.get   0
201# CHECK-NEXT:      i32.lt_s
202# CHECK-NEXT:      br_if       0       # 0: up to label1
203# CHECK-NEXT:  .LBB0_2:
204# CHECK-NEXT:      end_loop
205# CHECK-NEXT:      end_block           # label0:
206# CHECK-NEXT:      drop
207# CHECK-NEXT:      block       i32
208# CHECK-NEXT:      block
209# CHECK-NEXT:      block
210# CHECK-NEXT:      block
211# CHECK-NEXT:      block       () -> (i32, i32)
212# CHECK-NEXT:      i32.const   1
213# CHECK-NEXT:      i32.const   2
214# CHECK-NEXT:      end_block
215# CHECK-NEXT:      drop
216# CHECK-NEXT:      br_table {0, 1, 2}  # 1: down to label4
217# CHECK-NEXT:                          # 2: down to label3
218# CHECK-NEXT:      end_block           # label5:
219# CHECK-NEXT:      i32.const   1
220# CHECK-NEXT:      br          2       # 2: down to label2
221# CHECK-NEXT:      end_block           # label4:
222# CHECK-NEXT:      i32.const   2
223# CHECK-NEXT:      br          1       # 1: down to label2
224# CHECK-NEXT:      end_block           # label3:
225# CHECK-NEXT:      i32.const   3
226# CHECK-NEXT:      end_block           # label2:
227# CHECK-NEXT:      if
228# CHECK-NEXT:      if          i32
229# CHECK-NEXT:      end_if
230# CHECK-NEXT:      else
231# CHECK-NEXT:      end_if
232# CHECK-NEXT:      drop
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:      try
251# CHECK-NEXT:      i32.atomic.load 0
252# CHECK-NEXT:      i32.const   0
253# CHECK-NEXT:      memory.atomic.notify 0
254# CHECK-NEXT:      drop
255# CHECK-NEXT:  .LBB0_3:
256# CHECK-NEXT:      catch       __cpp_exception
257# CHECK-NEXT:      local.set   0
258# CHECK-NEXT:      end_try
259# CHECK-NEXT:      i32.const   .L.str
260# CHECK-NEXT:      i32.load8_u .L.str+2
261# CHECK-NEXT:      i32.load16_u .L.str:p2align=0
262# CHECK-NEXT:      throw       0
263# CHECK-NEXT:  .LBB0_4:
264# CHECK-NEXT:      global.get  __stack_pointer
265# CHECK-NEXT:      global.set  __stack_pointer
266# CHECK-NEXT:      end_function
267
268# CHECK:           .section    .rodata..L.str,"",@
269# CHECK-NEXT:      .hidden     .L.str
270# CHECK-NEXT:  .L.str:
271# CHECK-NEXT:      .int8       72
272# CHECK-NEXT:      .asciz      "ello, World!"
273# CHECK-NEXT:      .int16      1234
274# CHECK-NEXT:      .int64      5000000000
275# CHECK-NEXT:      .int32      2000000000
276# CHECK-NEXT:      .size       .L.str, 28
277
278# CHECK:           .data
279# CHECK-EMPTY:
280# CHECK-NEXT:      .int8       73
281
282# CHECK:           .section    .init_array.42,"",@
283# CHECK-NEXT:      .p2align    2
284# CHECK-NEXT:      .int32      test0
285
286# CHECK:           .tabletype empty_eref_table, externref
287# CHECK-NEXT: empty_eref_table:
288
289# CHECK:           .tabletype empty_fref_table, funcref
290# CHECK-NEXT: empty_fref_table:
291