Changeset 189499 in webkit
- Timestamp:
- Sep 8, 2015 11:34:22 AM (9 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r189496 r189499 1 2015-09-08 Sukolsak Sakshuwong <sukolsak@gmail.com> 2 3 Implement all the arithmetic and logical instructions in WebAssembly 4 https://bugs.webkit.org/show_bug.cgi?id=148882 5 6 Reviewed by Mark Lam. 7 8 This patch implements all the arithmetic and logical instructions for 9 32-bit integers in WebAssembly. 10 11 * tests/stress/wasm-arithmetic.js: 12 * tests/stress/wasm/arithmetic.wasm: 13 * wasm/WASMFunctionCompiler.h: 14 (JSC::WASMFunctionCompiler::buildUnaryI32): 15 (JSC::WASMFunctionCompiler::buildBinaryI32): 16 * wasm/WASMFunctionParser.cpp: 17 (JSC::WASMFunctionParser::parseExpressionI32): 18 (JSC::WASMFunctionParser::parseUnaryExpressionI32): 19 * wasm/WASMFunctionParser.h: 20 * wasm/WASMFunctionSyntaxChecker.h: 21 (JSC::WASMFunctionSyntaxChecker::buildUnaryI32): 22 1 23 2015-09-08 Filip Pizlo <fpizlo@apple.com> 2 24 -
trunk/Source/JavaScriptCore/tests/stress/wasm-arithmetic.js
r189458 r189499 25 25 "use asm"; 26 26 27 var clz32 = global.Math.clz32; 28 var abs = global.Math.abs; 29 30 function negate() { 31 var x = 0; 32 x = 42; 33 return -x; 34 } 35 27 36 function addSubtract() { 28 37 return ((10 + 40) - 8) | 0; … … 33 42 } 34 43 44 function multiply() { 45 return (6 * 7) | 0; 46 } 47 48 function multiplyOverflow() { 49 return (-2147483648 * -1) | 0; 50 } 51 35 52 function divide() { 36 53 return (42 / 5) | 0; … … 77 94 } 78 95 96 function bitNot() { 97 return ~1; 98 } 99 100 function bitOr() { 101 return 3 | 5; 102 } 103 104 function bitAnd() { 105 return 3 & 5; 106 } 107 108 function bitXor() { 109 return 3 ^ 5; 110 } 111 112 function leftShift() { 113 return 1 << 16; 114 } 115 116 function arithmeticRightShift() { 117 return (-1) >> 16; 118 } 119 120 function logicalRightShift() { 121 return (-1) >>> 16; 122 } 123 124 function countLeadingZeros() { 125 return clz32(42); 126 } 127 128 function countLeadingZerosOfZero() { 129 return clz32(0); 130 } 131 132 function logicalNotNonZero() { 133 return (!42) | 0; 134 } 135 136 function logicalNotZero() { 137 return (!0) | 0; 138 } 139 140 function absoluteNegative() { 141 return abs(-42); 142 } 143 144 function absolutePositive() { 145 return abs(42); 146 } 147 79 148 return { 149 negate: negate, 80 150 addSubtract: addSubtract, 81 151 addOverflow: addOverflow, 152 multiply: multiply, 153 multiplyOverflow: multiplyOverflow, 82 154 divide: divide, 83 155 divideByZero: divideByZero, … … 91 163 unsignedModulo: unsignedModulo, 92 164 unsignedModuloZero: unsignedModuloZero, 165 bitNot: bitNot, 166 bitOr: bitOr, 167 bitAnd: bitAnd, 168 bitXor: bitXor, 169 leftShift: leftShift, 170 arithmeticRightShift: arithmeticRightShift, 171 logicalRightShift: logicalRightShift, 172 countLeadingZeros: countLeadingZeros, 173 countLeadingZerosOfZero: countLeadingZerosOfZero, 174 logicalNotNonZero: logicalNotNonZero, 175 logicalNotZero: logicalNotZero, 176 absoluteNegative: absoluteNegative, 177 absolutePositive: absolutePositive, 93 178 }; 94 179 } … … 97 182 var module = loadWebAssembly("wasm/arithmetic.wasm"); 98 183 184 shouldBe(module.negate(), -42); 185 99 186 shouldBe(module.addSubtract(), 42); 100 187 101 188 shouldBe(module.addOverflow(), -2147483648); 102 189 190 shouldBe(module.multiply(), 42); 191 192 shouldBe(module.multiplyOverflow(), -2147483648); 193 103 194 shouldBe(module.divide(), 8); 104 195 … … 134 225 module.unsignedModuloZero(); 135 226 }, "Error: Division by zero or division overflow."); 227 228 shouldBe(module.bitNot(), -2); 229 230 shouldBe(module.bitOr(), 7); 231 232 shouldBe(module.bitAnd(), 1); 233 234 shouldBe(module.bitXor(), 6); 235 236 shouldBe(module.leftShift(), 65536); 237 238 shouldBe(module.arithmeticRightShift(), -1); 239 240 shouldBe(module.logicalRightShift(), 65535); 241 242 shouldBe(module.countLeadingZeros(), 26); 243 244 shouldBe(module.countLeadingZerosOfZero(), 32); 245 246 shouldBe(module.logicalNotNonZero(), 0); 247 248 shouldBe(module.logicalNotZero(), 1); 249 250 shouldBe(module.absoluteNegative(), 42); 251 252 shouldBe(module.absolutePositive(), 42); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h
r189494 r189499 264 264 } 265 265 266 int buildUnaryI32(int, WASMOpExpressionI32 op) 267 { 268 load32(temporaryAddress(m_tempStackTop - 1), GPRInfo::regT0); 269 switch (op) { 270 case WASMOpExpressionI32::Negate: 271 neg32(GPRInfo::regT0); 272 break; 273 case WASMOpExpressionI32::BitNot: 274 xor32(TrustedImm32(-1), GPRInfo::regT0); 275 break; 276 case WASMOpExpressionI32::CountLeadingZeros: 277 countLeadingZeros32(GPRInfo::regT0, GPRInfo::regT0); 278 break; 279 case WASMOpExpressionI32::LogicalNot: { 280 // FIXME: Don't use branches. 281 Jump zero = branchTest32(Zero, GPRInfo::regT0); 282 move(TrustedImm32(0), GPRInfo::regT0); 283 Jump end = jump(); 284 zero.link(this); 285 move(TrustedImm32(1), GPRInfo::regT0); 286 end.link(this); 287 break; 288 } 289 case WASMOpExpressionI32::Abs: { 290 // FIXME: Don't use branches. 291 Jump end = branchTest32(PositiveOrZero, GPRInfo::regT0); 292 neg32(GPRInfo::regT0); 293 end.link(this); 294 break; 295 } 296 default: 297 ASSERT_NOT_REACHED(); 298 } 299 store32(GPRInfo::regT0, temporaryAddress(m_tempStackTop - 1)); 300 return UNUSED; 301 } 302 266 303 int buildBinaryI32(int, int, WASMOpExpressionI32 op) 267 304 { … … 274 311 case WASMOpExpressionI32::Sub: 275 312 sub32(GPRInfo::regT1, GPRInfo::regT0); 313 break; 314 case WASMOpExpressionI32::Mul: 315 mul32(GPRInfo::regT1, GPRInfo::regT0); 276 316 break; 277 317 case WASMOpExpressionI32::SDiv: … … 323 363 break; 324 364 } 365 case WASMOpExpressionI32::BitOr: 366 or32(GPRInfo::regT1, GPRInfo::regT0); 367 break; 368 case WASMOpExpressionI32::BitAnd: 369 and32(GPRInfo::regT1, GPRInfo::regT0); 370 break; 371 case WASMOpExpressionI32::BitXor: 372 xor32(GPRInfo::regT1, GPRInfo::regT0); 373 break; 374 case WASMOpExpressionI32::LeftShift: 375 lshift32(GPRInfo::regT1, GPRInfo::regT0); 376 break; 377 case WASMOpExpressionI32::ArithmeticRightShift: 378 rshift32(GPRInfo::regT1, GPRInfo::regT0); 379 break; 380 case WASMOpExpressionI32::LogicalRightShift: 381 urshift32(GPRInfo::regT1, GPRInfo::regT0); 382 break; 325 383 default: 326 384 ASSERT_NOT_REACHED(); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp
r189494 r189499 434 434 case WASMOpExpressionI32::GetLocal: 435 435 return parseGetLocalExpressionI32(context); 436 case WASMOpExpressionI32::Negate: 437 case WASMOpExpressionI32::BitNot: 438 case WASMOpExpressionI32::CountLeadingZeros: 439 case WASMOpExpressionI32::LogicalNot: 440 case WASMOpExpressionI32::Abs: 441 return parseUnaryExpressionI32(context, op); 436 442 case WASMOpExpressionI32::Add: 437 443 case WASMOpExpressionI32::Sub: 444 case WASMOpExpressionI32::Mul: 438 445 case WASMOpExpressionI32::SDiv: 439 446 case WASMOpExpressionI32::UDiv: 440 447 case WASMOpExpressionI32::SMod: 441 448 case WASMOpExpressionI32::UMod: 449 case WASMOpExpressionI32::BitOr: 450 case WASMOpExpressionI32::BitAnd: 451 case WASMOpExpressionI32::BitXor: 452 case WASMOpExpressionI32::LeftShift: 453 case WASMOpExpressionI32::ArithmeticRightShift: 454 case WASMOpExpressionI32::LogicalRightShift: 442 455 return parseBinaryExpressionI32(context, op); 443 456 case WASMOpExpressionI32::EqualI32: … … 478 491 case WASMOpExpressionI32::FromF32: 479 492 case WASMOpExpressionI32::FromF64: 480 case WASMOpExpressionI32::Negate:481 case WASMOpExpressionI32::Mul:482 case WASMOpExpressionI32::BitNot:483 case WASMOpExpressionI32::BitOr:484 case WASMOpExpressionI32::BitAnd:485 case WASMOpExpressionI32::BitXor:486 case WASMOpExpressionI32::LeftShift:487 case WASMOpExpressionI32::ArithmeticRightShift:488 case WASMOpExpressionI32::LogicalRightShift:489 case WASMOpExpressionI32::CountLeadingZeros:490 case WASMOpExpressionI32::LogicalNot:491 493 case WASMOpExpressionI32::EqualF32: 492 494 case WASMOpExpressionI32::EqualF64: … … 505 507 case WASMOpExpressionI32::SMax: 506 508 case WASMOpExpressionI32::UMax: 507 case WASMOpExpressionI32::Abs:508 509 // FIXME: Implement these instructions. 509 510 FAIL_WITH_MESSAGE("Unsupported instruction."); … … 569 570 READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index."); 570 571 return parseGetLocalExpressionI32(context, localIndex); 572 } 573 574 template <class Context> 575 ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op) 576 { 577 ContextExpression expression = parseExpressionI32(context); 578 PROPAGATE_ERROR(); 579 return context.buildUnaryI32(expression, op); 571 580 } 572 581 -
trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h
r189494 r189499 85 85 template <class Context> ContextExpression parseGetLocalExpressionI32(Context&, uint32_t localIndex); 86 86 template <class Context> ContextExpression parseGetLocalExpressionI32(Context&); 87 template <class Context> ContextExpression parseUnaryExpressionI32(Context&, WASMOpExpressionI32); 87 88 template <class Context> ContextExpression parseBinaryExpressionI32(Context&, WASMOpExpressionI32); 88 89 template <class Context> ContextExpression parseRelationalI32ExpressionI32(Context&, WASMOpExpressionI32); -
trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h
r189494 r189499 80 80 } 81 81 82 int buildUnaryI32(int, WASMOpExpressionI32) 83 { 84 return UNUSED; 85 } 86 82 87 int buildBinaryI32(int, int, WASMOpExpressionI32) 83 88 {
Note: See TracChangeset
for help on using the changeset viewer.