blob: e608df3342f2ea6a56428dc652a74e5615b83692 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2014 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// Flags: --harmony-sharedarraybuffer
6//
7
8function toRangeWrapped(value) {
9 var range = this.max - this.min + 1;
10 while (value < this.min) {
11 value += range;
12 }
13 while (value > this.max) {
14 value -= range;
15 }
16 return value;
17}
18
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000019function makeConstructorObject(constr, min, max, toRange) {
20 var o = {constr: constr, min: min, max: max};
Ben Murdochc5610432016-08-08 18:44:38 +010021 o.toRange = toRangeWrapped.bind(o);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000022 return o;
23}
24
25var IntegerTypedArrayConstructors = [
Ben Murdochc5610432016-08-08 18:44:38 +010026 makeConstructorObject(Int8Array, -128, 127),
27 makeConstructorObject(Int16Array, -32768, 32767),
28 makeConstructorObject(Int32Array, -0x80000000, 0x7fffffff),
29 makeConstructorObject(Uint8Array, 0, 255),
30 makeConstructorObject(Uint16Array, 0, 65535),
31 makeConstructorObject(Uint32Array, 0, 0xffffffff),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000032];
33
34(function TestBadArray() {
35 var ab = new ArrayBuffer(16);
36 var u32a = new Uint32Array(16);
37 var sab = new SharedArrayBuffer(128);
38 var sf32a = new Float32Array(sab);
39 var sf64a = new Float64Array(sab);
Ben Murdochc5610432016-08-08 18:44:38 +010040 var u8ca = new Uint8ClampedArray(sab);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041
42 // Atomic ops required integer shared typed arrays
Ben Murdochc5610432016-08-08 18:44:38 +010043 var badArrayTypes = [
44 undefined, 1, 'hi', 3.4, ab, u32a, sab, sf32a, sf64a, u8ca
45 ];
46 badArrayTypes.forEach(function(o) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000047 assertThrows(function() { Atomics.compareExchange(o, 0, 0, 0); },
48 TypeError);
49 assertThrows(function() { Atomics.load(o, 0); }, TypeError);
50 assertThrows(function() { Atomics.store(o, 0, 0); }, TypeError);
51 assertThrows(function() { Atomics.add(o, 0, 0); }, TypeError);
52 assertThrows(function() { Atomics.sub(o, 0, 0); }, TypeError);
53 assertThrows(function() { Atomics.and(o, 0, 0); }, TypeError);
54 assertThrows(function() { Atomics.or(o, 0, 0); }, TypeError);
55 assertThrows(function() { Atomics.xor(o, 0, 0); }, TypeError);
56 assertThrows(function() { Atomics.exchange(o, 0, 0); }, TypeError);
57 });
58})();
59
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000060(function TestBadIndex() {
61 var sab = new SharedArrayBuffer(8);
62 var si32a = new Int32Array(sab);
63 var si32a2 = new Int32Array(sab, 4);
64
Ben Murdochda12d292016-06-02 14:46:10 +010065 // Non-integer indexes should throw RangeError.
66 var nonInteger = [1.4, '1.4', NaN, -Infinity, Infinity, undefined, 'hi', {}];
67 nonInteger.forEach(function(i) {
68 assertThrows(function() { Atomics.compareExchange(si32a, i, 0); },
69 RangeError);
70 assertThrows(function() { Atomics.load(si32a, i, 0); }, RangeError);
71 assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError);
72 assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError);
73 assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError);
74 assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError);
75 assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError);
76 assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError);
77 assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError);
78 }, RangeError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079
Ben Murdochda12d292016-06-02 14:46:10 +010080 // Out-of-bounds indexes should throw RangeError.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000081 [-1, 2, 100].forEach(function(i) {
Ben Murdochda12d292016-06-02 14:46:10 +010082 assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); },
83 RangeError);
84 assertThrows(function() { Atomics.load(si32a, i); }, RangeError);
85 assertThrows(function() { Atomics.store(si32a, i, 0); }, RangeError);
86 assertThrows(function() { Atomics.add(si32a, i, 0); }, RangeError);
87 assertThrows(function() { Atomics.sub(si32a, i, 0); }, RangeError);
88 assertThrows(function() { Atomics.and(si32a, i, 0); }, RangeError);
89 assertThrows(function() { Atomics.or(si32a, i, 0); }, RangeError);
90 assertThrows(function() { Atomics.xor(si32a, i, 0); }, RangeError);
91 assertThrows(function() { Atomics.exchange(si32a, i, 0); }, RangeError);
92 }, RangeError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093
Ben Murdochda12d292016-06-02 14:46:10 +010094 // Out-of-bounds indexes for array with offset should throw RangeError.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095 [-1, 1, 100].forEach(function(i) {
Ben Murdochda12d292016-06-02 14:46:10 +010096 assertThrows(function() { Atomics.compareExchange(si32a2, i, 0, 0); });
97 assertThrows(function() { Atomics.load(si32a2, i); }, RangeError);
98 assertThrows(function() { Atomics.store(si32a2, i, 0); }, RangeError);
99 assertThrows(function() { Atomics.add(si32a2, i, 0); }, RangeError);
100 assertThrows(function() { Atomics.sub(si32a2, i, 0); }, RangeError);
101 assertThrows(function() { Atomics.and(si32a2, i, 0); }, RangeError);
102 assertThrows(function() { Atomics.or(si32a2, i, 0); }, RangeError);
103 assertThrows(function() { Atomics.xor(si32a2, i, 0); }, RangeError);
104 assertThrows(function() { Atomics.exchange(si32a2, i, 0); }, RangeError);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 });
106
Ben Murdochda12d292016-06-02 14:46:10 +0100107 // Monkey-patch length and make sure these functions still throw.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000108 Object.defineProperty(si32a, 'length', {get: function() { return 1000; }});
109 [2, 100].forEach(function(i) {
Ben Murdochda12d292016-06-02 14:46:10 +0100110 assertThrows(function() { Atomics.compareExchange(si32a, i, 0, 0); });
111 assertThrows(function() { Atomics.load(si32a, i); });
112 assertThrows(function() { Atomics.store(si32a, i, 0); });
113 assertThrows(function() { Atomics.add(si32a, i, 0); });
114 assertThrows(function() { Atomics.sub(si32a, i, 0); });
115 assertThrows(function() { Atomics.and(si32a, i, 0); });
116 assertThrows(function() { Atomics.or(si32a, i, 0); });
117 assertThrows(function() { Atomics.xor(si32a, i, 0); });
118 assertThrows(function() { Atomics.exchange(si32a, i, 0); });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119 });
120})();
121
122(function TestGoodIndex() {
123 var sab = new SharedArrayBuffer(64);
124 var si32a = new Int32Array(sab);
125 var si32a2 = new Int32Array(sab, 32);
126
Ben Murdochda12d292016-06-02 14:46:10 +0100127 var testOp = function(op, ia, index, expectedIndex, name) {
128 for (var i = 0; i < ia.length; ++i)
Ben Murdochc5610432016-08-08 18:44:38 +0100129 ia[i] = i * 2;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000130
Ben Murdochda12d292016-06-02 14:46:10 +0100131 ia[expectedIndex] = 0;
Ben Murdochc5610432016-08-08 18:44:38 +0100132 var result = op(ia, index, 0, 0);
133 assertEquals(0, result, name);
Ben Murdochda12d292016-06-02 14:46:10 +0100134 assertEquals(0, ia[expectedIndex], name);
135
136 for (var i = 0; i < ia.length; ++i) {
137 if (i == expectedIndex) continue;
Ben Murdochc5610432016-08-08 18:44:38 +0100138 assertEquals(i * 2, ia[i], name);
Ben Murdochda12d292016-06-02 14:46:10 +0100139 }
140 };
141
142 // These values all map to index 0
143 [-0, 0, 0.0, null, false].forEach(function(i) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000144 var name = String(i);
145 [si32a, si32a2].forEach(function(array) {
Ben Murdochda12d292016-06-02 14:46:10 +0100146 testOp(Atomics.compareExchange, array, i, 0, name);
147 testOp(Atomics.load, array, i, 0, name);
148 testOp(Atomics.store, array, i, 0, name);
149 testOp(Atomics.add, array, i, 0, name);
150 testOp(Atomics.sub, array, i, 0, name);
151 testOp(Atomics.and, array, i, 0, name);
152 testOp(Atomics.or, array, i, 0, name);
153 testOp(Atomics.xor, array, i, 0, name);
154 testOp(Atomics.exchange, array, i, 0, name);
155 });
156 });
157
158 // These values all map to index 3
159 var valueOf = {valueOf: function(){ return 3;}};
160 var toString = {toString: function(){ return '3';}};
161 [3, 3.0, '3', '3.0', valueOf, toString].forEach(function(i) {
162 var name = String(i);
163 [si32a, si32a2].forEach(function(array) {
164 testOp(Atomics.compareExchange, array, i, 3, name);
165 testOp(Atomics.load, array, i, 3, name);
166 testOp(Atomics.store, array, i, 3, name);
167 testOp(Atomics.add, array, i, 3, name);
168 testOp(Atomics.sub, array, i, 3, name);
169 testOp(Atomics.and, array, i, 3, name);
170 testOp(Atomics.or, array, i, 3, name);
171 testOp(Atomics.xor, array, i, 3, name);
172 testOp(Atomics.exchange, array, i, 3, name);
173 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174 });
175})();
176
177function clearArray(sab) {
178 var ui8 = new Uint8Array(sab);
179 for (var i = 0; i < sab.byteLength; ++i) {
180 ui8[i] = 0;
181 }
182}
183
184(function TestCompareExchange() {
185 IntegerTypedArrayConstructors.forEach(function(t) {
186 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
187 var sta = new t.constr(sab);
188 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
189
190 [sta, sta2].forEach(function(array) {
191 clearArray(array.buffer);
192 var name = Object.prototype.toString.call(array);
193 for (var i = 0; i < array.length; ++i) {
194 // array[i] == 0, CAS will store
195 assertEquals(0, Atomics.compareExchange(array, i, 0, 50), name);
196 assertEquals(50, array[i], name);
197
198 // array[i] == 50, CAS will not store
199 assertEquals(50, Atomics.compareExchange(array, i, 0, 100), name);
200 assertEquals(50, array[i], name);
201 }
202 })
203 });
204})();
205
206(function TestLoad() {
207 IntegerTypedArrayConstructors.forEach(function(t) {
208 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
209 var sta = new t.constr(sab);
210 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
211
212 [sta, sta2].forEach(function(array) {
213 clearArray(array.buffer);
214 var name = Object.prototype.toString.call(array);
215 for (var i = 0; i < array.length; ++i) {
216 array[i] = 0;
217 assertEquals(0, Atomics.load(array, i), name);
218 array[i] = 50;
219 assertEquals(50, Atomics.load(array, i), name);
220 }
221 })
222 });
Ben Murdochc5610432016-08-08 18:44:38 +0100223
224 // Test Smi range
225 (function () {
226 var sab = new SharedArrayBuffer(4);
227 var i32 = new Int32Array(sab);
228 var u32 = new Uint32Array(sab);
229
230 function testLoad(signedValue, unsignedValue) {
231 u32[0] = unsignedValue;
232 assertEquals(unsignedValue, Atomics.load(u32, 0));
233 assertEquals(signedValue, Atomics.load(i32, 0));
234 }
235
236 testLoad(0x3fffffff, 0x3fffffff); // 2**30-1 (always smi)
237 testLoad(0x40000000, 0x40000000); // 2**30 (smi if signed and 32-bits)
238 testLoad(0x80000000, -0x80000000); // 2**31 (smi if signed and 32-bits)
239 testLoad(0xffffffff, -1); // 2**31 (smi if signed)
240 });
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000241})();
242
243(function TestStore() {
244 IntegerTypedArrayConstructors.forEach(function(t) {
245 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
246 var sta = new t.constr(sab);
247 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
248
249 [sta, sta2].forEach(function(array) {
250 clearArray(array.buffer);
251 var name = Object.prototype.toString.call(array);
252 for (var i = 0; i < array.length; ++i) {
253 assertEquals(50, Atomics.store(array, i, 50), name);
254 assertEquals(50, array[i], name);
255
256 assertEquals(100, Atomics.store(array, i, 100), name);
257 assertEquals(100, array[i], name);
258 }
259 })
260 });
261})();
262
263(function TestAdd() {
264 IntegerTypedArrayConstructors.forEach(function(t) {
265 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
266 var sta = new t.constr(sab);
267 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
268
269 [sta, sta2].forEach(function(array) {
270 clearArray(array.buffer);
271 var name = Object.prototype.toString.call(array);
272 for (var i = 0; i < array.length; ++i) {
273 assertEquals(0, Atomics.add(array, i, 50), name);
274 assertEquals(50, array[i], name);
275
276 assertEquals(50, Atomics.add(array, i, 70), name);
277 assertEquals(120, array[i], name);
278 }
279 })
280 });
281})();
282
283(function TestSub() {
284 IntegerTypedArrayConstructors.forEach(function(t) {
285 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
286 var sta = new t.constr(sab);
287 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
288
289 [sta, sta2].forEach(function(array) {
290 clearArray(array.buffer);
291 var name = Object.prototype.toString.call(array);
292 for (var i = 0; i < array.length; ++i) {
293 array[i] = 120;
294 assertEquals(120, Atomics.sub(array, i, 50), name);
295 assertEquals(70, array[i], name);
296
297 assertEquals(70, Atomics.sub(array, i, 70), name);
298 assertEquals(0, array[i], name);
299 }
300 })
301 });
302})();
303
304(function TestAnd() {
305 IntegerTypedArrayConstructors.forEach(function(t) {
306 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
307 var sta = new t.constr(sab);
308 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
309
310 [sta, sta2].forEach(function(array) {
311 clearArray(array.buffer);
312 var name = Object.prototype.toString.call(sta);
313 for (var i = 0; i < array.length; ++i) {
314 array[i] = 0x3f;
315 assertEquals(0x3f, Atomics.and(array, i, 0x30), name);
316 assertEquals(0x30, array[i], name);
317
318 assertEquals(0x30, Atomics.and(array, i, 0x20), name);
319 assertEquals(0x20, array[i], name);
320 }
321 })
322 });
323})();
324
325(function TestOr() {
326 IntegerTypedArrayConstructors.forEach(function(t) {
327 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
328 var sta = new t.constr(sab);
329 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
330
331 [sta, sta2].forEach(function(array) {
332 clearArray(array.buffer);
333 var name = Object.prototype.toString.call(array);
334 for (var i = 0; i < array.length; ++i) {
335 array[i] = 0x30;
336 assertEquals(0x30, Atomics.or(array, i, 0x1c), name);
337 assertEquals(0x3c, array[i], name);
338
339 assertEquals(0x3c, Atomics.or(array, i, 0x09), name);
340 assertEquals(0x3d, array[i], name);
341 }
342 })
343 });
344})();
345
346(function TestXor() {
347 IntegerTypedArrayConstructors.forEach(function(t) {
348 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
349 var sta = new t.constr(sab);
350 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
351
352 [sta, sta2].forEach(function(array) {
353 clearArray(array.buffer);
354 var name = Object.prototype.toString.call(array);
355 for (var i = 0; i < array.length; ++i) {
356 array[i] = 0x30;
357 assertEquals(0x30, Atomics.xor(array, i, 0x1c), name);
358 assertEquals(0x2c, array[i], name);
359
360 assertEquals(0x2c, Atomics.xor(array, i, 0x09), name);
361 assertEquals(0x25, array[i], name);
362 }
363 })
364 });
365})();
366
367(function TestExchange() {
368 IntegerTypedArrayConstructors.forEach(function(t) {
369 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
370 var sta = new t.constr(sab);
371 var sta2 = new t.constr(sab, 5 * t.constr.BYTES_PER_ELEMENT);
372
373 [sta, sta2].forEach(function(array) {
374 clearArray(array.buffer);
375 var name = Object.prototype.toString.call(array);
376 for (var i = 0; i < array.length; ++i) {
377 array[i] = 0x30;
378 assertEquals(0x30, Atomics.exchange(array, i, 0x1c), name);
379 assertEquals(0x1c, array[i], name);
380
381 assertEquals(0x1c, Atomics.exchange(array, i, 0x09), name);
382 assertEquals(0x09, array[i], name);
383 }
384 })
385 });
386})();
387
388(function TestIsLockFree() {
389 // For all platforms we support, 1, 2 and 4 bytes should be lock-free.
390 assertEquals(true, Atomics.isLockFree(1));
391 assertEquals(true, Atomics.isLockFree(2));
392 assertEquals(true, Atomics.isLockFree(4));
393
394 // Sizes that aren't equal to a typedarray BYTES_PER_ELEMENT always return
395 // false.
396 var validSizes = {};
397 IntegerTypedArrayConstructors.forEach(function(t) {
398 validSizes[t.constr.BYTES_PER_ELEMENT] = true;
399 });
400
401 for (var i = 0; i < 1000; ++i) {
402 if (!validSizes[i]) {
403 assertEquals(false, Atomics.isLockFree(i));
404 }
405 }
406})();
407
408(function TestToNumber() {
409 IntegerTypedArrayConstructors.forEach(function(t) {
410 var sab = new SharedArrayBuffer(1 * t.constr.BYTES_PER_ELEMENT);
411 var sta = new t.constr(sab);
412
413 var valueOf = {valueOf: function(){ return 3;}};
414 var toString = {toString: function(){ return '3';}};
415
416 [false, true, undefined, valueOf, toString].forEach(function(v) {
417 var name = Object.prototype.toString.call(sta) + ' - ' + v;
418
419 // CompareExchange
420 sta[0] = 50;
421 assertEquals(50, Atomics.compareExchange(sta, 0, v, v), name);
422
423 // Store
Ben Murdochc5610432016-08-08 18:44:38 +0100424 assertEquals(v|0, Atomics.store(sta, 0, v), name);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000425 assertEquals(v|0, sta[0], name);
426
427 // Add
428 sta[0] = 120;
429 assertEquals(120, Atomics.add(sta, 0, v), name);
430 assertEquals(120 + (v|0), sta[0], name);
431
432 // Sub
433 sta[0] = 70;
434 assertEquals(70, Atomics.sub(sta, 0, v), name);
435 assertEquals(70 - (v|0), sta[0]);
436
437 // And
438 sta[0] = 0x20;
439 assertEquals(0x20, Atomics.and(sta, 0, v), name);
440 assertEquals(0x20 & (v|0), sta[0]);
441
442 // Or
443 sta[0] = 0x3d;
444 assertEquals(0x3d, Atomics.or(sta, 0, v), name);
445 assertEquals(0x3d | (v|0), sta[0]);
446
447 // Xor
448 sta[0] = 0x25;
449 assertEquals(0x25, Atomics.xor(sta, 0, v), name);
450 assertEquals(0x25 ^ (v|0), sta[0]);
451
452 // Exchange
453 sta[0] = 0x09;
454 assertEquals(0x09, Atomics.exchange(sta, 0, v), name);
455 assertEquals(v|0, sta[0]);
456 });
457 });
458})();
459
460(function TestWrapping() {
461 IntegerTypedArrayConstructors.forEach(function(t) {
462 var sab = new SharedArrayBuffer(10 * t.constr.BYTES_PER_ELEMENT);
463 var sta = new t.constr(sab);
464 var name = Object.prototype.toString.call(sta);
465 var range = t.max - t.min + 1;
466 var offset;
467 var operand;
468 var val, newVal;
469 var valWrapped, newValWrapped;
470
471 for (offset = -range; offset <= range; offset += range) {
472 // CompareExchange
473 sta[0] = val = 0;
474 newVal = val + offset + 1;
475 newValWrapped = t.toRange(newVal);
476 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name);
477 assertEquals(newValWrapped, sta[0], name);
478
479 sta[0] = val = t.min;
480 newVal = val + offset - 1;
481 newValWrapped = t.toRange(newVal);
482 assertEquals(val, Atomics.compareExchange(sta, 0, val, newVal), name);
483 assertEquals(newValWrapped, sta[0], name);
484
485 // Store
486 sta[0] = 0;
487 val = t.max + offset + 1;
488 valWrapped = t.toRange(val);
489 assertEquals(val, Atomics.store(sta, 0, val), name);
490 assertEquals(valWrapped, sta[0], name);
491
492 sta[0] = val = t.min + offset - 1;
493 valWrapped = t.toRange(val);
494 assertEquals(val, Atomics.store(sta, 0, val), name);
495 assertEquals(valWrapped, sta[0], name);
496
497 // Add
498 sta[0] = val = t.max;
499 operand = offset + 1;
500 valWrapped = t.toRange(val + operand);
501 assertEquals(val, Atomics.add(sta, 0, operand), name);
502 assertEquals(valWrapped, sta[0], name);
503
504 sta[0] = val = t.min;
505 operand = offset - 1;
506 valWrapped = t.toRange(val + operand);
507 assertEquals(val, Atomics.add(sta, 0, operand), name);
508 assertEquals(valWrapped, sta[0], name);
509
510 // Sub
511 sta[0] = val = t.max;
512 operand = offset - 1;
513 valWrapped = t.toRange(val - operand);
514 assertEquals(val, Atomics.sub(sta, 0, operand), name);
515 assertEquals(valWrapped, sta[0], name);
516
517 sta[0] = val = t.min;
518 operand = offset + 1;
519 valWrapped = t.toRange(val - operand);
520 assertEquals(val, Atomics.sub(sta, 0, operand), name);
521 assertEquals(valWrapped, sta[0], name);
522
523 // There's no way to wrap results with logical operators, just test that
524 // using an out-of-range value is properly wrapped/clamped when written
525 // to memory.
526
527 // And
528 sta[0] = val = 0xf;
529 operand = 0x3 + offset;
530 valWrapped = t.toRange(val & operand);
531 assertEquals(val, Atomics.and(sta, 0, operand), name);
532 assertEquals(valWrapped, sta[0], name);
533
534 // Or
535 sta[0] = val = 0x12;
536 operand = 0x22 + offset;
537 valWrapped = t.toRange(val | operand);
538 assertEquals(val, Atomics.or(sta, 0, operand), name);
539 assertEquals(valWrapped, sta[0], name);
540
541 // Xor
542 sta[0] = val = 0x12;
543 operand = 0x22 + offset;
544 valWrapped = t.toRange(val ^ operand);
545 assertEquals(val, Atomics.xor(sta, 0, operand), name);
546 assertEquals(valWrapped, sta[0], name);
547
548 // Exchange
549 sta[0] = val = 0x12;
550 operand = 0x22 + offset;
551 valWrapped = t.toRange(operand);
552 assertEquals(val, Atomics.exchange(sta, 0, operand), name);
553 assertEquals(valWrapped, sta[0], name);
554 }
555
556 });
557})();