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