i64.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. /* global assert,testRunner,yargsParse,i64ToString */ // eslint rule
  6. WScript.Flag("-wasmI64");
  7. WScript.LoadScriptFile("../UnitTestFramework/UnitTestFramework.js");
  8. WScript.LoadScriptFile("wasmutils.js");
  9. WScript.LoadScriptFile("../WasmSpec/testsuite/harness/wasm-constants.js");
  10. WScript.LoadScriptFile("../WasmSpec/testsuite/harness/wasm-module-builder.js");
  11. WScript.LoadScriptFile("../UnitTestFramework/yargs.js");
  12. const argv = yargsParse(WScript.Arguments, {
  13. number: ["start", "end", "verbose"],
  14. default: {
  15. verbose: 1,
  16. start: 0
  17. }
  18. }).argv;
  19. const comparisonOperators = [
  20. {name: "i64.eq", op: kExprI64Eq, check(a, b) {return a.high === b.high && a.low === b.low;}},
  21. {name: "i64.ne", op: kExprI64Ne, check(a, b) {return a.high !== b.high || a.low !== b.low;}},
  22. {name: "i64.lt_s", op: kExprI64LtS, check(a, b) {
  23. if (a.high !== b.high) {
  24. return a.high < b.high;
  25. }
  26. return (a.low>>>0) < (b.low>>>0);
  27. }},
  28. {name: "i64.lt_u", op: kExprI64LtU, check(a, b) {
  29. if (a.high !== b.high) {
  30. return (a.high>>>0) < (b.high>>>0);
  31. }
  32. return (a.low>>>0) < (b.low>>>0);
  33. }},
  34. {name: "i64.gt_s", op: kExprI64GtS, check(a, b) {
  35. if (a.high !== b.high) {
  36. return a.high > b.high;
  37. }
  38. return (a.low>>>0) > (b.low>>>0);
  39. }},
  40. {name: "i64.gt_u", op: kExprI64GtU, check(a, b) {
  41. if (a.high !== b.high) {
  42. return (a.high>>>0) > (b.high>>>0);
  43. }
  44. return (a.low>>>0) > (b.low>>>0);
  45. }},
  46. {name: "i64.le_s", op: kExprI64LeS, check(a, b) {
  47. if (a.high !== b.high) {
  48. return a.high < b.high;
  49. }
  50. return (a.low>>>0) <= (b.low>>>0);
  51. }},
  52. {name: "i64.le_u", op: kExprI64LeU, check(a, b) {
  53. if (a.high !== b.high) {
  54. return (a.high>>>0) < (b.high>>>0);
  55. }
  56. return (a.low>>>0) <= (b.low>>>0);
  57. }},
  58. {name: "i64.ge_s", op: kExprI64GeS, check(a, b) {
  59. if (a.high !== b.high) {
  60. return a.high > b.high;
  61. }
  62. return (a.low>>>0) >= (b.low>>>0);
  63. }},
  64. {name: "i64.ge_u", op: kExprI64GeU, check(a, b) {
  65. if (a.high !== b.high) {
  66. return (a.high>>>0) > (b.high>>>0);
  67. }
  68. return (a.low>>>0) >= (b.low>>>0);
  69. }},
  70. ];
  71. const I32values = [0, 1, -1, -5, 5, 1<<32, -(1<<32), (1<<32)-1, 1<<31, -(1<<31), 1<<25, -1<<25];
  72. const allPairs = [];
  73. const tested = {};
  74. for (let i = 0; i < I32values.length; ++i) {
  75. for (let j = i; j < I32values.length; ++j) {
  76. const v0 = I32values[i];
  77. const v1 = I32values[j];
  78. // Try all possible combinations
  79. for (let iShuffle = 0; iShuffle < (1 << 4); ++iShuffle) {
  80. const a = (iShuffle & 1) ? v1 : v0;
  81. const b = (iShuffle & 2) ? v1 : v0;
  82. const c = (iShuffle & 4) ? v1 : v0;
  83. const d = (iShuffle & 8) ? v1 : v0;
  84. const left = {high: a, low: b};
  85. const right = {high: c, low: d};
  86. const key = i64ToString(left) + i64ToString(right);
  87. if (!tested[key]) {
  88. tested[key] = true;
  89. allPairs.push([left, right]);
  90. }
  91. }
  92. }
  93. }
  94. function runTest(name, fn, expectedFn) {
  95. for (const pair of allPairs) {
  96. const [left, right] = pair;
  97. const i64Res = fn(left, right);
  98. const checkRes = expectedFn(left, right);
  99. const msg = `${name}(${i64ToString(left)}, ${i64ToString(right)})`;
  100. if (argv.verbose > 1) {
  101. console.log(`${msg} = ${i64Res}`);
  102. }
  103. assert.areEqual(checkRes, i64Res, msg);
  104. }
  105. }
  106. const comparisonTests = comparisonOperators.map(({name, op, check}) => ({
  107. name: `test ${name}`,
  108. body() {
  109. const builder = new WasmModuleBuilder();
  110. const body = [kExprGetLocal, 0, kExprGetLocal, 1, op];
  111. builder
  112. .addFunction("i64", makeSig([kWasmI64, kWasmI64], [kWasmI32]))
  113. .addBody(body)
  114. .exportFunc();
  115. const {exports: {i64}} = builder.instantiate();
  116. runTest(name, i64, (left, right) => (check(left, right) ? 1 : 0));
  117. }
  118. }));
  119. const branchingTests = comparisonOperators.map(({name, op, check}) => ({
  120. name: `test ${name} branching`,
  121. body() {
  122. const falseValue = 15;
  123. const trueValue = 24;
  124. const builder = new WasmModuleBuilder();
  125. const body = [
  126. kExprI32Const, falseValue,
  127. kExprSetLocal, 2, // tmp
  128. kExprGetLocal, 0, kExprGetLocal, 1, op,
  129. kExprIf, kWasmStmt,
  130. kExprI32Const, trueValue,
  131. kExprSetLocal, 2, // tmp
  132. kExprEnd,
  133. kExprGetLocal, 2, // return tmp
  134. ];
  135. builder
  136. .addFunction("i64", makeSig([kWasmI64, kWasmI64], [kWasmI32]))
  137. .addLocals({i32_count: 1})
  138. .addBody(body)
  139. .exportFunc();
  140. const {exports: {i64}} = builder.instantiate();
  141. runTest(name, i64, (left, right) => (check(left, right) ? trueValue : falseValue));
  142. }
  143. }));
  144. const tests = [
  145. ...comparisonTests,
  146. ...branchingTests,
  147. ];
  148. const todoTests = tests.slice(argv.start, argv.end === undefined ? tests.length : argv.end);
  149. testRunner.run(todoTests, {verbose: argv.verbose > 0});