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