mathTests.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft Corporation and contributors. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. let passed = true;
  6. function assertEquals(expected, actual) {
  7. if (expected != actual) {
  8. passed = false;
  9. throw `Expected ${expected}, received ${actual}`;
  10. }
  11. }
  12. const INITIAL_SIZE = 1;
  13. const memObj = new WebAssembly.Memory({initial:INITIAL_SIZE});
  14. const module = new WebAssembly.Module(readbuffer('math.wasm'));
  15. const instance = new WebAssembly.Instance(module, { "dummy" : { "memory" : memObj } }).exports;
  16. const arrays = {
  17. "i32x4" : new Int32Array (memObj.buffer),
  18. "i16x8" : new Int16Array (memObj.buffer),
  19. "i8x16" : new Int8Array (memObj.buffer),
  20. "f32x4" : new Float32Array (memObj.buffer),
  21. "f64x2" : new Float64Array (memObj.buffer),
  22. "i64x2" : new Int32Array (memObj.buffer)
  23. };
  24. function moveArgsIntoArray(args, offset, arr) {
  25. for (let i = 0; i < args.length; i++) {
  26. arr[offset + i] = args[i];
  27. }
  28. }
  29. let testCompOps = function (funcname, args1, args2, op, resultArr) {
  30. const len = args1.length;
  31. const arr = arrays[funcname.split('_')[1]];
  32. moveArgsIntoArray(args1, 0, arr);
  33. moveArgsIntoArray(args2, len, arr);
  34. instance[funcname](op);
  35. for (let i = 0; i < len; i++) {
  36. assertEquals(resultArr[i], Number.isNaN(arr[i]) || !!arr[i]);
  37. }
  38. }
  39. let testMathOps = function (funcname, args1, args2, resultArr) {
  40. const len = args1.length;
  41. const type = funcname.split('_')[1];
  42. const arr = arrays[type];
  43. moveArgsIntoArray(args1, 0, arr);
  44. if (Array.isArray(args2)) { //binary ops
  45. moveArgsIntoArray(args2, len, arr);
  46. instance[funcname]();
  47. }
  48. else if (Number.isInteger(args2)) {
  49. instance[funcname](args2); //shift amount for shl/shr
  50. }
  51. else {
  52. instance[funcname](); //unary ops
  53. }
  54. for (let i = 0; i < resultArr.length; i++) {
  55. if ((type === "f32x4" || type === "f64x2") && Number.isNaN(resultArr[i])) {
  56. assertEquals(true, Number.isNaN(arr[i]));
  57. } else {
  58. assertEquals(resultArr[i], arr[i]);
  59. }
  60. }
  61. }
  62. let reverse64x2Type = (type) => type === "f64x2" ? "i64x2" : "f64x2";
  63. let testTruncConvOps = function (funcname, args1, resultArr) {
  64. const len = args1.length;
  65. const type = funcname.split('_')[1];
  66. const resultType = reverse64x2Type(type);
  67. const arr = arrays[resultType];
  68. const resultArrView = arrays[type];
  69. moveArgsIntoArray(args1, 0, arr);
  70. instance[funcname]();
  71. for (let i = 0; i < resultArr.length; i++) {
  72. if (type === "f64x2" && Number.isNaN(resultArr[i])) {
  73. assertEquals(true, Number.isNaN(resultArrView[i]));
  74. } else {
  75. assertEquals(resultArr[i], resultArrView[i]);
  76. }
  77. }
  78. }
  79. //i32x4
  80. testMathOps("func_i32x4_add",
  81. [2147483645 , 0, -1, 65536],
  82. [3 , 0, 1 , 65536],
  83. [-2147483648, 0, 0 , 131072]
  84. );
  85. testMathOps("func_i32x4_sub",
  86. [-2147483648, 0 , 65536, 32768],
  87. [1 , -1, 65536, 65536],
  88. [2147483647 , 1 , 0 , -32768]
  89. );
  90. testMathOps("func_i32x4_mul",
  91. [65536, 65536 , 0 , 1],
  92. [65536, 65535 , 2147483647, -2147483648],
  93. [0 , -65536, 0 , -2147483648]
  94. );
  95. testMathOps("func_i32x4_shl", [1,2,1,0], 30, [1073741824, -2147483648, 1073741824, 0]);
  96. testMathOps("func_i32x4_shl", [1,2,8,16], 32, [1,2,8,16]);
  97. testMathOps("func_i32x4_shr_s", [-2147483648,0x80010000,0x10000,1], 16, [-32768,-32767,1,0]);
  98. testMathOps("func_i32x4_shr_u", [-2147483648,0x80010000,0x10000,1], 16, [32768,32769,1,0]);
  99. //i16x8
  100. testMathOps("func_i16x8_add",
  101. [32767 , -32768, -1, 16, 32767 , -32768, 0, 0],
  102. [1 , -1 , 1 , 16, 2 , -2 , 0, 32767],
  103. [-32768, 32767 , 0 , 32, -32767, 32766 , 0, 32767]
  104. );
  105. testMathOps("func_i16x8_addsaturate_s",
  106. [32767, 32767, -1 , -32768, 32767, -32768, 0 , 0],
  107. [1 , 32767, -32768, -32768, -2 , 0 , 32767, -1],
  108. [32767, 32767, -32768, -32768, 32765, -32768, 32767, -1]
  109. );
  110. testMathOps("func_i16x8_subsaturate_s",
  111. [32767, 32767 , -2 , -32768, 32767, -32768, 0 , 0],
  112. [-1 , -32767, 32767 , 32767, 2 , 0 , -32767, -1],
  113. [32767, 32767 , -32768, -32768, 32765, -32768, 32767 , 1]
  114. );
  115. testMathOps("func_i16x8_addsaturate_u",
  116. [65535, 65535, 65535, 32768, 32767 , 0, 0 , 32768],
  117. [1 , 2 , 0 , 32768, 2 , 0, 32768 , 1],
  118. [-1 , -1 , -1 , -1 , -32767, 0, -32768, -32767]
  119. );
  120. testMathOps("func_i16x8_subsaturate_u",
  121. [0 , 65535, 65535, 32768, 32767, 0, 65535, 65535],
  122. [65535, 2 , 0 , 32768, 32768, 0, 32768, 32767],
  123. [0 , -3 , -1 , 0 , 0, 0, 32767, -32768]
  124. );
  125. testMathOps("func_i16x8_sub",
  126. [-1 , 32767 , 1, 16, 32767 , -32768, 0, 0],
  127. [32768,-1 , 1, 16, -2 , 2 , 0, 32767],
  128. [32767,-32768 , 0, 0 , -32767, 32766 , 0, -32767]
  129. );
  130. testMathOps("func_i16x8_mul",
  131. [256, 128 , 1 , -32768, -32768, -32768, -128 , 0],
  132. [256, 256 , -32767, 0 , -32768, 2 , -128 , 0],
  133. [0 ,-32768, -32767, 0 , 0 , 0 , 16384, 0]
  134. );
  135. testMathOps("func_i16x8_shl", [1, 2, 3, 0, 4, 5, 6, 7], 15, [-32768, 0, -32768, 0, 0, -32768, 0, -32768]);
  136. testMathOps("func_i16x8_shl", [1, 2, 3, 0, 2048, 128, 256, 512], 4, [16, 32, 48, 0, -32768, 2048, 4096, 8192]);
  137. testMathOps("func_i16x8_shr_s", [0x8000, 0x8100, 256, 1, 0x8000, 0x8101, 257, 0], 8, [-128, -127, 1, 0, -128, -127, 1, 0]);
  138. testMathOps("func_i16x8_shr_u", [0x8000, 0x8100, 256, 1, 0x8000, 0x8101, 257, 0], 8, [128, 129, 1, 0, 128, 129, 1, 0]);
  139. //i8x16
  140. testMathOps("func_i8x16_add",
  141. [127 , -128, -1, 16, 127 , -128, 0, 0 , 127 , -128, -1, 16, 127 , -128, 0, 0],
  142. [1 , -1 , 1 , 16, 2 , -2 , 0, 127, 1 , -1 , 1 , 16, 2 , -2 , 0, 127],
  143. [-128, 127 , 0 , 32, -127, 126 , 0, 127, -128, 127 , 0 , 32, -127, 126 , 0, 127]
  144. );
  145. testMathOps("func_i8x16_addsaturate_s",
  146. [127, 127, -1 , -128, 127, -128, 0 , 0 , 127, 127, -1 , -128, 127, -128, 0 , 0 ],
  147. [1 , 127, -128, -128, -2 , 0 , 127, -1, 1 , 127, -128, -128, -2 , 0 , 127, -1],
  148. [127, 127, -128, -128, 125, -128, 127, -1, 127, 127, -128, -128, 125, -128, 127, -1]
  149. );
  150. testMathOps("func_i8x16_subsaturate_s",
  151. [127, 127 , -2 , -128, 127, -128, 0 , 0 , 127, 127 , -2 , -128, 127, -128, 0 , 0],
  152. [-1 , -127, 127 , 127, 2 , 0 , -127, -1, -1 , -127, 127 , 127, 2 , 0 , -127, -1],
  153. [127, 127 , -128, -128, 125, -128, 127 , 1 , 127, 127 , -128, -128, 125, -128, 127 , 1]
  154. );
  155. testMathOps("func_i8x16_addsaturate_u",
  156. [255, 255, 255, 128, 127 , 0, 0 , 128 , 255, 255, 255, 128, 127 , 0, 0 , 128 ],
  157. [1 , 2 , 0 , 128, 2 , 0, 128 , 1 , 1 , 2 , 0 , 128, 2 , 0, 128 , 1],
  158. [-1 , -1 , -1 , -1 , -127, 0, -128, -127, -1 , -1 , -1 , -1 , -127, 0, -128, -127]
  159. );
  160. testMathOps("func_i8x16_subsaturate_u",
  161. [0 , 255, 255, 128, 127, 0, 255, 255 , 0 , 255, 255, 128, 127, 0, 255, 255],
  162. [255, 2 , 0 , 128, 128, 0, 128, 127 , 255, 2 , 0 , 128, 128, 0, 128, 127],
  163. [0 , -3 , -1 , 0 , 0 , 0, 127, -128, 0 , -3 , -1 , 0 , 0 , 0, 127, -128]
  164. );
  165. testMathOps("func_i8x16_sub",
  166. [-1 , 127 , 1, 16, 127 , -128 , 0, 0 , -1 , 127 , 1, 16, 127 , -128 , 0, 0],
  167. [128 ,-1 , 1, 16, -2 , 2 , 0, 127 , 128 ,-1 , 1, 16, -2 , 2 , 0, 127],
  168. [127 ,-128 , 0, 0 , -127 , 126 , 0, -127, 127 ,-128 , 0, 0 , -127 , 126 , 0, -127]
  169. );
  170. testMathOps("func_i8x16_shl", [1, 2, 3, 0, 4, 5, 6, 7, 1, 2, 3, 0, 4, 5, 6, 16], 4, [16, 32, 48, 0, 64, 80, 96, 112, 16, 32, 48, 0, 64, 80, 96, 0]);
  171. testMathOps("func_i8x16_shr_s", [-128, -127, 16, 1, -128, -127, 16, -64, -128, -127, 16, 1, -128, -127, 16, 1], 4, [-8, -8, 1, 0, -8, -8, 1, -4, -8, -8, 1, 0, -8, -8, 1, 0]);
  172. testMathOps("func_i8x16_shr_u", [128, 192, 16, 1, 128, 193, 17, 0, 128, 192, 16, 1, 128, 193, 17, 0], 4, [8, 12, 1, 0, 8, 12, 1, 0, 8, 12, 1, 0, 8, 12, 1, 0]);
  173. //f32x4
  174. testMathOps("func_f32x4_add",
  175. [400000512, 400000256, 1.4E-45 , -1],
  176. [400000505, 400000100, 1.4E-45 , Number.NaN],
  177. [800001024, 800000384, 2.802596928649634e-45, Number.NaN]
  178. );
  179. testMathOps("func_f32x4_sub",
  180. [800001024, 800000256, 2.802596928649634e-45, 1],
  181. [400000512, 400000128, 1.4E-45 , Number.NaN],
  182. [400000512, 400000128, 1.401298464324817e-45, Number.NaN]
  183. );
  184. testMathOps("func_f32x4_mul",
  185. [400000512 , 800000256 , 2.802596928649634e-45, 1],
  186. [400000512 , 400000128 , 1.4E-45 , Number.NaN],
  187. [160000416677888000, 320000214880485400, 0 , Number.NaN]
  188. );
  189. testMathOps("func_f32x4_div",
  190. [400000512, 800000256, 2.802596928649634e-45, 1],
  191. [400000512, 400000128, 1.4E-45 , Number.NaN],
  192. [1 , 2 , 2 , Number.NaN]
  193. );
  194. testMathOps("func_f32x4_abs",
  195. [-800001024, 0, 2.802596928649634e-45, -1.401298464324817e-45],
  196. null,
  197. [800001024, 0 , 2.802596928649634e-45, 1.401298464324817e-45]
  198. );
  199. testMathOps("func_f32x4_sqrt",
  200. [1 << 20, 0, 6.25, -1],
  201. null,
  202. [1 << 10, 0, 2.5 , Number.NaN]
  203. );
  204. //f64x2
  205. testMathOps("func_f64x2_add",
  206. [1.34826985114673713038100984656E308, 2.7670146896890036224E19],
  207. [1.34826985114673693079697889309E308, 1.288491622400006103515625E10],
  208. [Number.POSITIVE_INFINITY , 27670146909774954000]
  209. );
  210. testMathOps("func_f64x2_add",
  211. [1.4E-45 , -1],
  212. [1.4E-45 , Number.NaN],
  213. [2.8e-45, Number.NaN]
  214. );
  215. testMathOps("func_f64x2_add",
  216. [400000512, 400000256],
  217. [400000505, 400000100],
  218. [800001017, 800000356]
  219. );
  220. testMathOps("func_f64x2_sub",
  221. [1.34826985114673713038100984656E308, 2.7670146896890036224E19],
  222. [1.34826985114673693079697889309E308, 1.288491622400006103515625E10],
  223. [1.99584030953472e+292 , 27670146884005120000]
  224. );
  225. testMathOps("func_f64x2_sub",
  226. [2.802596928649634e-45, 1],
  227. [1.4E-45 , Number.NaN],
  228. [1.402596928649634e-45, Number.NaN]
  229. );
  230. testMathOps("func_f64x2_sub",
  231. [800001024, 800000256],
  232. [400000512, 400000128],
  233. [400000512, 400000128]
  234. );
  235. testMathOps("func_f64x2_mul",
  236. [1.34826985114673713038100984656E308, 2.7670146896890036224E19],
  237. [1.34826985114673693079697889309E308, 1.288491622400006103515625E10],
  238. [Number.POSITIVE_INFINITY , 3.565275246722034e+29]
  239. );
  240. testMathOps("func_f64x2_mul",
  241. [400000512 , 800000256 ],
  242. [400000512 , 400000128 ],
  243. [160000409600262140, 320000204800032800]
  244. );
  245. testMathOps("func_f64x2_div",
  246. [-4.27214248753826131799357622933E-306, 1],
  247. [3 , Number.NaN],
  248. [-1.424047495846087e-306 , Number.NaN]
  249. );
  250. testMathOps("func_f64x2_div",
  251. [400000512, 800000256],
  252. [400000512, 400000128],
  253. [1 , 2 ]
  254. );
  255. testMathOps("func_f64x2_abs",
  256. [-800001024, -4.27214248753826131799357622933E-306],
  257. null,
  258. [800001024 , 4.27214248753826131799357622933E-306]
  259. );
  260. testMathOps("func_f64x2_abs",
  261. [-Math.pow(120), -0],
  262. null,
  263. [Math.pow(120) , 0]
  264. );
  265. testMathOps("func_f64x2_sqrt",
  266. [Math.pow(2, 40), 0],
  267. null,
  268. [Math.pow(2, 20), 0]
  269. );
  270. testMathOps("func_f64x2_sqrt",
  271. [6.25, -1],
  272. null,
  273. [2.5 , Number.NaN]
  274. );
  275. //bitselect
  276. testMathOps("func_i32x4_bitselect",
  277. [0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  278. 0, 0, 0, 0,
  279. 0xF0F0F0F0, 0xFFFFFFFF, 0xD6D6D6D6, 0xAAAAAAAA],
  280. null,
  281. [0xF0F0F0F0|0, 0xFFFFFFFF|0, 0xD6D6D6D6|0, 0xAAAAAAAA|0]
  282. );
  283. testMathOps("func_i32x4_bitselect",
  284. [0, 0, 0, 0,
  285. 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF,
  286. ~0xF0F0F0F0, ~0xFFFFFFFF, ~0xD6D6D6D6, ~0xAAAAAAAA],
  287. null,
  288. [0xF0F0F0F0|0, 0xFFFFFFFF|0, 0xD6D6D6D6|0, 0xAAAAAAAA|0]
  289. );
  290. testMathOps("func_i32x4_bitselect",
  291. [0xBEBEBEBE, 0xD7D7D7D7, 0xF3F3F3F3, 0xFFFFFFFF,
  292. 0x55555555, 0x29292929, 0x0F0F0F0F, 0,
  293. 0xAAAAAAAA, 0xD6D6D6D6,0xF0F0F0F0, 0],
  294. null,
  295. [-1,-1,-1,0]
  296. );
  297. //shuffle
  298. testMathOps("func_i8x16_shuffle_test1",
  299. [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15],
  300. [16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31],
  301. [16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7]
  302. );
  303. testMathOps("func_i8x16_shuffle_test0",
  304. [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15],
  305. [16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31],
  306. [31 , 30 , 29 , 28 , 1 , 17 , 2 , 19 , 3 , 4 , 5 , 6 , 21 , 20 , 11 , 10]
  307. );
  308. testMathOps("func_i8x16_shuffle_test2",
  309. [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15],
  310. [16 , 17 , 18 , 19 , 20 , 21 , 22 , 23 , 24 , 25 , 26 , 27 , 28 , 29 , 30 , 31],
  311. [0 , 17 , 1 , 18 , 2 , 19 , 3 , 20 , 4 , 21 , 5 , 22 , 6 , 23 , 7 , 24]
  312. );
  313. if (passed) {
  314. print("Passed");
  315. }