1const std = @import("std");
2const expect = std.testing.expect;
3const builtin = @import("builtin");
4
5test "memory size and grow" {
6 var prev = @wasmMemorySize(0);
7 _ = &prev;
8 try expect(prev == @wasmMemoryGrow(0, 1));
9 try expect(prev + 1 == @wasmMemorySize(0));
10}
11
12test "asm .i32.add" {
13 const a: u32 = std.math.maxInt(u32);
14 const b: u32 = 3;
15 const result = asm (
16 \\ local.get %[a]
17 \\ local.get %[b]
18 \\ i32.add
19 \\ local.set %[ret]
20 : [ret] "=r" (-> u32),
21 : [a] "r" (a),
22 [b] "r" (b),
23 );
24
25 try expect(result == 2);
26}
27
28test "asm .i64.clz" {
29 const a: u64 = 1;
30 const result = asm (
31 \\ local.get %[a]
32 \\ i64.clz
33 \\ local.set %[ret]
34 : [ret] "=r" (-> u64),
35 : [a] "r" (a),
36 );
37
38 try expect(result == 63);
39}
40
41test "asm .i32.const" {
42 const result = asm (
43 \\ i32.const 12
44 \\ local.set %[ret]
45 : [ret] "=r" (-> u32),
46 );
47
48 try expect(result == 12);
49}
50
51test "asm .i64.const" {
52 const result = asm (
53 \\ i64.const 42
54 \\ local.set %[ret]
55 : [ret] "=r" (-> u64),
56 );
57
58 try expect(result == 42);
59}
60
61test "asm .f32.const" {
62 const result = asm (
63 \\ f32.const 1.5
64 \\ local.set %[ret]
65 : [ret] "=r" (-> f32),
66 );
67
68 try expect(result == 1.5);
69}
70
71test "asm .f64.const" {
72 const result = asm (
73 \\ f64.const 2.25
74 \\ local.set %[ret]
75 : [ret] "=r" (-> f64),
76 );
77
78 try expect(result == 2.25);
79}
80
81test "asm .local.get" {
82 const a: u32 = 77;
83 const result = asm (
84 \\ local.get %[a]
85 \\ local.set %[ret]
86 : [ret] "=r" (-> u32),
87 : [a] "r" (a),
88 );
89
90 try expect(result == 77);
91}
92
93test "asm .local.set" {
94 const result = asm (
95 \\ i32.const 55
96 \\ local.set %[ret]
97 : [ret] "=r" (-> u32),
98 );
99
100 try expect(result == 55);
101}
102
103test "asm .local.tee" {
104 const a: u32 = 3;
105 const result = asm (
106 \\ local.get %[a]
107 \\ local.tee %[ret]
108 \\ drop
109 : [ret] "=r" (-> u32),
110 : [a] "r" (a),
111 );
112
113 try expect(result == 3);
114}
115
116test "asm .memory.copy" {
117 var src: [8]u8 = .{ 1, 2, 3, 4, 5, 6, 7, 8 };
118 var dst: [8]u8 = .{ 0, 0, 0, 0, 0, 0, 0, 0 };
119
120 asm volatile (
121 \\ local.get %[dst]
122 \\ local.get %[src]
123 \\ i32.const 8
124 \\ memory.copy 0, 0
125 :
126 : [dst] "r" (@intFromPtr(&dst)),
127 [src] "r" (@intFromPtr(&src)),
128 );
129
130 try std.testing.expectEqualSlices(u8, &src, &dst);
131}
132
133test "asm .memory.fill" {
134 var buf: [8]u8 = .{ 0, 0, 0, 0, 0, 0, 0, 0 };
135
136 asm volatile (
137 \\ local.get %[dst]
138 \\ i32.const 2
139 \\ i32.const 8
140 \\ memory.fill 0
141 :
142 : [dst] "r" (@intFromPtr(&buf)),
143 );
144
145 try std.testing.expectEqualSlices(u8, &.{ 2, 2, 2, 2, 2, 2, 2, 2 }, &buf);
146}
147
148test "asm .i64.load and .i64.store" {
149 var slot: u64 = 0;
150 const value: u64 = 0x4444;
151
152 const result = asm (
153 \\ local.get %[ptr]
154 \\ local.get %[value]
155 \\ i64.store 0:p2align=0
156 \\ local.get %[ptr]
157 \\ i64.load 0
158 \\ local.set %[ret]
159 : [ret] "=r" (-> u64),
160 : [ptr] "r" (@intFromPtr(&slot)),
161 [value] "r" (value),
162 );
163
164 try expect(result == value);
165 try expect(slot == value);
166}