Line data Source code
1 : // Copyright 2017 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "test/cctest/wasm/wasm-atomics-utils.h"
6 : #include "test/common/wasm/wasm-macro-gen.h"
7 :
8 : namespace v8 {
9 : namespace internal {
10 : namespace wasm {
11 : namespace test_run_wasm_atomics {
12 :
13 72 : void RunU32BinOp(ExecutionTier execution_tier, WasmOpcode wasm_op,
14 : Uint32BinOp expected_op) {
15 : EXPERIMENTAL_FLAG_SCOPE(threads);
16 144 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
17 : uint32_t* memory =
18 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
19 : r.builder().SetHasSharedMemory();
20 :
21 72 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
22 : MachineRepresentation::kWord32));
23 :
24 8424 : FOR_UINT32_INPUTS(i) {
25 : uint32_t initial = i;
26 488592 : FOR_UINT32_INPUTS(j) {
27 : r.builder().WriteMemory(&memory[0], initial);
28 242208 : CHECK_EQ(initial, r.Call(j));
29 242208 : uint32_t expected = expected_op(i, j);
30 242208 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
31 : }
32 : }
33 72 : }
34 :
35 : #define TEST_OPERATION(Name) \
36 : WASM_EXEC_TEST(I32Atomic##Name) { \
37 : RunU32BinOp(execution_tier, kExprI32Atomic##Name, Name); \
38 : }
39 26711 : OPERATION_LIST(TEST_OPERATION)
40 : #undef TEST_OPERATION
41 :
42 72 : void RunU16BinOp(ExecutionTier tier, WasmOpcode wasm_op,
43 : Uint16BinOp expected_op) {
44 : EXPERIMENTAL_FLAG_SCOPE(threads);
45 144 : WasmRunner<uint32_t, uint32_t> r(tier);
46 : r.builder().SetHasSharedMemory();
47 : uint16_t* memory =
48 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
49 :
50 72 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
51 : MachineRepresentation::kWord16));
52 :
53 1368 : FOR_UINT16_INPUTS(i) {
54 : uint16_t initial = i;
55 12312 : FOR_UINT16_INPUTS(j) {
56 : r.builder().WriteMemory(&memory[0], initial);
57 11664 : CHECK_EQ(initial, r.Call(j));
58 5832 : uint16_t expected = expected_op(i, j);
59 5832 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
60 : }
61 : }
62 72 : }
63 :
64 : #define TEST_OPERATION(Name) \
65 : WASM_EXEC_TEST(I32Atomic##Name##16U) { \
66 : RunU16BinOp(execution_tier, kExprI32Atomic##Name##16U, Name); \
67 : }
68 26711 : OPERATION_LIST(TEST_OPERATION)
69 : #undef TEST_OPERATION
70 :
71 72 : void RunU8BinOp(ExecutionTier execution_tier, WasmOpcode wasm_op,
72 : Uint8BinOp expected_op) {
73 : EXPERIMENTAL_FLAG_SCOPE(threads);
74 144 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
75 : r.builder().SetHasSharedMemory();
76 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
77 :
78 72 : BUILD(r, WASM_ATOMICS_BINOP(wasm_op, WASM_I32V_1(0), WASM_GET_LOCAL(0),
79 : MachineRepresentation::kWord8));
80 :
81 1368 : FOR_UINT8_INPUTS(i) {
82 : uint8_t initial = i;
83 12312 : FOR_UINT8_INPUTS(j) {
84 : r.builder().WriteMemory(&memory[0], initial);
85 11664 : CHECK_EQ(initial, r.Call(j));
86 5832 : uint8_t expected = expected_op(i, j);
87 5832 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
88 : }
89 : }
90 72 : }
91 :
92 : #define TEST_OPERATION(Name) \
93 : WASM_EXEC_TEST(I32Atomic##Name##8U) { \
94 : RunU8BinOp(execution_tier, kExprI32Atomic##Name##8U, Name); \
95 : }
96 26711 : OPERATION_LIST(TEST_OPERATION)
97 : #undef TEST_OPERATION
98 :
99 26663 : WASM_EXEC_TEST(I32AtomicCompareExchange) {
100 : EXPERIMENTAL_FLAG_SCOPE(threads);
101 24 : WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_tier);
102 : r.builder().SetHasSharedMemory();
103 : uint32_t* memory =
104 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
105 12 : BUILD(r, WASM_ATOMICS_TERNARY_OP(
106 : kExprI32AtomicCompareExchange, WASM_I32V_1(0), WASM_GET_LOCAL(0),
107 : WASM_GET_LOCAL(1), MachineRepresentation::kWord32));
108 :
109 1404 : FOR_UINT32_INPUTS(i) {
110 : uint32_t initial = i;
111 81432 : FOR_UINT32_INPUTS(j) {
112 : r.builder().WriteMemory(&memory[0], initial);
113 40368 : CHECK_EQ(initial, r.Call(i, j));
114 : uint32_t expected = CompareExchange(initial, i, j);
115 40368 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
116 : }
117 : }
118 12 : }
119 :
120 26663 : WASM_EXEC_TEST(I32AtomicCompareExchange16U) {
121 : EXPERIMENTAL_FLAG_SCOPE(threads);
122 24 : WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_tier);
123 : r.builder().SetHasSharedMemory();
124 : uint16_t* memory =
125 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
126 12 : BUILD(r, WASM_ATOMICS_TERNARY_OP(kExprI32AtomicCompareExchange16U,
127 : WASM_I32V_1(0), WASM_GET_LOCAL(0),
128 : WASM_GET_LOCAL(1),
129 : MachineRepresentation::kWord16));
130 :
131 228 : FOR_UINT16_INPUTS(i) {
132 : uint16_t initial = i;
133 2052 : FOR_UINT16_INPUTS(j) {
134 : r.builder().WriteMemory(&memory[0], initial);
135 972 : CHECK_EQ(initial, r.Call(i, j));
136 : uint16_t expected = CompareExchange(initial, i, j);
137 972 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
138 : }
139 : }
140 12 : }
141 :
142 26663 : WASM_EXEC_TEST(I32AtomicCompareExchange8U) {
143 : EXPERIMENTAL_FLAG_SCOPE(threads);
144 24 : WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_tier);
145 : r.builder().SetHasSharedMemory();
146 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
147 12 : BUILD(r,
148 : WASM_ATOMICS_TERNARY_OP(kExprI32AtomicCompareExchange8U, WASM_I32V_1(0),
149 : WASM_GET_LOCAL(0), WASM_GET_LOCAL(1),
150 : MachineRepresentation::kWord8));
151 :
152 228 : FOR_UINT8_INPUTS(i) {
153 : uint8_t initial = i;
154 2052 : FOR_UINT8_INPUTS(j) {
155 : r.builder().WriteMemory(&memory[0], initial);
156 972 : CHECK_EQ(initial, r.Call(i, j));
157 : uint8_t expected = CompareExchange(initial, i, j);
158 972 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
159 : }
160 : }
161 12 : }
162 :
163 26663 : WASM_EXEC_TEST(I32AtomicCompareExchange_fail) {
164 : EXPERIMENTAL_FLAG_SCOPE(threads);
165 24 : WasmRunner<uint32_t, uint32_t, uint32_t> r(execution_tier);
166 : r.builder().SetHasSharedMemory();
167 : uint32_t* memory =
168 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
169 12 : BUILD(r, WASM_ATOMICS_TERNARY_OP(
170 : kExprI32AtomicCompareExchange, WASM_I32V_1(0), WASM_GET_LOCAL(0),
171 : WASM_GET_LOCAL(1), MachineRepresentation::kWord32));
172 :
173 : // The original value at the memory location.
174 : uint32_t old_val = 4;
175 : // The value we use as the expected value for the compare-exchange so that it
176 : // fails.
177 : uint32_t expected = 6;
178 : // The new value for the compare-exchange.
179 : uint32_t new_val = 5;
180 :
181 : r.builder().WriteMemory(&memory[0], old_val);
182 12 : CHECK_EQ(old_val, r.Call(expected, new_val));
183 12 : }
184 :
185 26663 : WASM_EXEC_TEST(I32AtomicLoad) {
186 : EXPERIMENTAL_FLAG_SCOPE(threads);
187 24 : WasmRunner<uint32_t> r(execution_tier);
188 : r.builder().SetHasSharedMemory();
189 : uint32_t* memory =
190 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
191 12 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad, WASM_ZERO,
192 : MachineRepresentation::kWord32));
193 :
194 1404 : FOR_UINT32_INPUTS(i) {
195 : uint32_t expected = i;
196 : r.builder().WriteMemory(&memory[0], expected);
197 696 : CHECK_EQ(expected, r.Call());
198 : }
199 12 : }
200 :
201 26663 : WASM_EXEC_TEST(I32AtomicLoad16U) {
202 : EXPERIMENTAL_FLAG_SCOPE(threads);
203 24 : WasmRunner<uint32_t> r(execution_tier);
204 : r.builder().SetHasSharedMemory();
205 : uint16_t* memory =
206 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
207 12 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad16U, WASM_ZERO,
208 : MachineRepresentation::kWord16));
209 :
210 228 : FOR_UINT16_INPUTS(i) {
211 : uint16_t expected = i;
212 : r.builder().WriteMemory(&memory[0], expected);
213 216 : CHECK_EQ(expected, r.Call());
214 : }
215 12 : }
216 :
217 26663 : WASM_EXEC_TEST(I32AtomicLoad8U) {
218 : EXPERIMENTAL_FLAG_SCOPE(threads);
219 24 : WasmRunner<uint32_t> r(execution_tier);
220 : r.builder().SetHasSharedMemory();
221 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
222 12 : BUILD(r, WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad8U, WASM_ZERO,
223 : MachineRepresentation::kWord8));
224 :
225 228 : FOR_UINT8_INPUTS(i) {
226 : uint8_t expected = i;
227 : r.builder().WriteMemory(&memory[0], expected);
228 216 : CHECK_EQ(expected, r.Call());
229 : }
230 12 : }
231 :
232 26663 : WASM_EXEC_TEST(I32AtomicStoreLoad) {
233 : EXPERIMENTAL_FLAG_SCOPE(threads);
234 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
235 : r.builder().SetHasSharedMemory();
236 : uint32_t* memory =
237 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
238 :
239 12 : BUILD(r,
240 : WASM_ATOMICS_STORE_OP(kExprI32AtomicStore, WASM_ZERO, WASM_GET_LOCAL(0),
241 : MachineRepresentation::kWord32),
242 : WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad, WASM_ZERO,
243 : MachineRepresentation::kWord32));
244 :
245 1404 : FOR_UINT32_INPUTS(i) {
246 : uint32_t expected = i;
247 696 : CHECK_EQ(expected, r.Call(i));
248 696 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
249 : }
250 12 : }
251 :
252 26663 : WASM_EXEC_TEST(I32AtomicStoreLoad16U) {
253 : EXPERIMENTAL_FLAG_SCOPE(threads);
254 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
255 : r.builder().SetHasSharedMemory();
256 : uint16_t* memory =
257 : r.builder().AddMemoryElems<uint16_t>(kWasmPageSize / sizeof(uint16_t));
258 :
259 12 : BUILD(
260 : r,
261 : WASM_ATOMICS_STORE_OP(kExprI32AtomicStore16U, WASM_ZERO,
262 : WASM_GET_LOCAL(0), MachineRepresentation::kWord16),
263 : WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad16U, WASM_ZERO,
264 : MachineRepresentation::kWord16));
265 :
266 228 : FOR_UINT16_INPUTS(i) {
267 : uint16_t expected = i;
268 108 : CHECK_EQ(expected, r.Call(i));
269 108 : CHECK_EQ(expected, r.builder().ReadMemory(&memory[0]));
270 : }
271 12 : }
272 :
273 26663 : WASM_EXEC_TEST(I32AtomicStoreLoad8U) {
274 : EXPERIMENTAL_FLAG_SCOPE(threads);
275 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
276 : r.builder().SetHasSharedMemory();
277 : uint8_t* memory = r.builder().AddMemoryElems<uint8_t>(kWasmPageSize);
278 :
279 12 : BUILD(r,
280 : WASM_ATOMICS_STORE_OP(kExprI32AtomicStore8U, WASM_ZERO,
281 : WASM_GET_LOCAL(0), MachineRepresentation::kWord8),
282 : WASM_ATOMICS_LOAD_OP(kExprI32AtomicLoad8U, WASM_ZERO,
283 : MachineRepresentation::kWord8));
284 :
285 228 : FOR_UINT8_INPUTS(i) {
286 : uint8_t expected = i;
287 108 : CHECK_EQ(expected, r.Call(i));
288 108 : CHECK_EQ(i, r.builder().ReadMemory(&memory[0]));
289 : }
290 12 : }
291 :
292 26663 : WASM_EXEC_TEST(I32AtomicStoreParameter) {
293 : EXPERIMENTAL_FLAG_SCOPE(threads);
294 24 : WasmRunner<uint32_t, uint32_t> r(execution_tier);
295 : uint32_t* memory =
296 : r.builder().AddMemoryElems<uint32_t>(kWasmPageSize / sizeof(uint32_t));
297 : r.builder().SetHasSharedMemory();
298 :
299 12 : BUILD(r,
300 : WASM_ATOMICS_STORE_OP(kExprI32AtomicStore, WASM_ZERO, WASM_GET_LOCAL(0),
301 : MachineRepresentation::kWord8),
302 : WASM_ATOMICS_BINOP(kExprI32AtomicAdd, WASM_I32V_1(0), WASM_GET_LOCAL(0),
303 : MachineRepresentation::kWord32));
304 12 : CHECK_EQ(10, r.Call(10));
305 12 : CHECK_EQ(20, r.builder().ReadMemory(&memory[0]));
306 12 : }
307 : } // namespace test_run_wasm_atomics
308 : } // namespace wasm
309 : } // namespace internal
310 79917 : } // namespace v8
|