Changeset 189499 in webkit


Ignore:
Timestamp:
Sep 8, 2015 11:34:22 AM (9 years ago)
Author:
commit-queue@webkit.org
Message:

Implement all the arithmetic and logical instructions in WebAssembly
https://bugs.webkit.org/show_bug.cgi?id=148882

Patch by Sukolsak Sakshuwong <Sukolsak Sakshuwong> on 2015-09-08
Reviewed by Mark Lam.

This patch implements all the arithmetic and logical instructions for
32-bit integers in WebAssembly.

  • tests/stress/wasm-arithmetic.js:
  • tests/stress/wasm/arithmetic.wasm:
  • wasm/WASMFunctionCompiler.h:

(JSC::WASMFunctionCompiler::buildUnaryI32):
(JSC::WASMFunctionCompiler::buildBinaryI32):

  • wasm/WASMFunctionParser.cpp:

(JSC::WASMFunctionParser::parseExpressionI32):
(JSC::WASMFunctionParser::parseUnaryExpressionI32):

  • wasm/WASMFunctionParser.h:
  • wasm/WASMFunctionSyntaxChecker.h:

(JSC::WASMFunctionSyntaxChecker::buildUnaryI32):

Location:
trunk/Source/JavaScriptCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r189496 r189499  
     12015-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
    1232015-09-08  Filip Pizlo  <fpizlo@apple.com>
    224
  • trunk/Source/JavaScriptCore/tests/stress/wasm-arithmetic.js

    r189458 r189499  
    2525    "use asm";
    2626
     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
    2736    function addSubtract() {
    2837        return ((10 + 40) - 8) | 0;
     
    3342    }
    3443
     44    function multiply() {
     45        return (6 * 7) | 0;
     46    }
     47
     48    function multiplyOverflow() {
     49        return (-2147483648 * -1) | 0;
     50    }
     51
    3552    function divide() {
    3653        return (42 / 5) | 0;
     
    7794    }
    7895
     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
    79148    return {
     149        negate: negate,
    80150        addSubtract: addSubtract,
    81151        addOverflow: addOverflow,
     152        multiply: multiply,
     153        multiplyOverflow: multiplyOverflow,
    82154        divide: divide,
    83155        divideByZero: divideByZero,
     
    91163        unsignedModulo: unsignedModulo,
    92164        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,
    93178    };
    94179}
     
    97182var module = loadWebAssembly("wasm/arithmetic.wasm");
    98183
     184shouldBe(module.negate(), -42);
     185
    99186shouldBe(module.addSubtract(), 42);
    100187
    101188shouldBe(module.addOverflow(), -2147483648);
    102189
     190shouldBe(module.multiply(), 42);
     191
     192shouldBe(module.multiplyOverflow(), -2147483648);
     193
    103194shouldBe(module.divide(), 8);
    104195
     
    134225    module.unsignedModuloZero();
    135226}, "Error: Division by zero or division overflow.");
     227
     228shouldBe(module.bitNot(), -2);
     229
     230shouldBe(module.bitOr(), 7);
     231
     232shouldBe(module.bitAnd(), 1);
     233
     234shouldBe(module.bitXor(), 6);
     235
     236shouldBe(module.leftShift(), 65536);
     237
     238shouldBe(module.arithmeticRightShift(), -1);
     239
     240shouldBe(module.logicalRightShift(), 65535);
     241
     242shouldBe(module.countLeadingZeros(), 26);
     243
     244shouldBe(module.countLeadingZerosOfZero(), 32);
     245
     246shouldBe(module.logicalNotNonZero(), 0);
     247
     248shouldBe(module.logicalNotZero(), 1);
     249
     250shouldBe(module.absoluteNegative(), 42);
     251
     252shouldBe(module.absolutePositive(), 42);
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionCompiler.h

    r189494 r189499  
    264264    }
    265265
     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
    266303    int buildBinaryI32(int, int, WASMOpExpressionI32 op)
    267304    {
     
    274311        case WASMOpExpressionI32::Sub:
    275312            sub32(GPRInfo::regT1, GPRInfo::regT0);
     313            break;
     314        case WASMOpExpressionI32::Mul:
     315            mul32(GPRInfo::regT1, GPRInfo::regT0);
    276316            break;
    277317        case WASMOpExpressionI32::SDiv:
     
    323363            break;
    324364        }
     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;
    325383        default:
    326384            ASSERT_NOT_REACHED();
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.cpp

    r189494 r189499  
    434434        case WASMOpExpressionI32::GetLocal:
    435435            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);
    436442        case WASMOpExpressionI32::Add:
    437443        case WASMOpExpressionI32::Sub:
     444        case WASMOpExpressionI32::Mul:
    438445        case WASMOpExpressionI32::SDiv:
    439446        case WASMOpExpressionI32::UDiv:
    440447        case WASMOpExpressionI32::SMod:
    441448        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:
    442455            return parseBinaryExpressionI32(context, op);
    443456        case WASMOpExpressionI32::EqualI32:
     
    478491        case WASMOpExpressionI32::FromF32:
    479492        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:
    491493        case WASMOpExpressionI32::EqualF32:
    492494        case WASMOpExpressionI32::EqualF64:
     
    505507        case WASMOpExpressionI32::SMax:
    506508        case WASMOpExpressionI32::UMax:
    507         case WASMOpExpressionI32::Abs:
    508509            // FIXME: Implement these instructions.
    509510            FAIL_WITH_MESSAGE("Unsupported instruction.");
     
    569570    READ_COMPACT_UINT32_OR_FAIL(localIndex, "Cannot read the local index.");
    570571    return parseGetLocalExpressionI32(context, localIndex);
     572}
     573
     574template <class Context>
     575ContextExpression WASMFunctionParser::parseUnaryExpressionI32(Context& context, WASMOpExpressionI32 op)
     576{
     577    ContextExpression expression = parseExpressionI32(context);
     578    PROPAGATE_ERROR();
     579    return context.buildUnaryI32(expression, op);
    571580}
    572581
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionParser.h

    r189494 r189499  
    8585    template <class Context> ContextExpression parseGetLocalExpressionI32(Context&, uint32_t localIndex);
    8686    template <class Context> ContextExpression parseGetLocalExpressionI32(Context&);
     87    template <class Context> ContextExpression parseUnaryExpressionI32(Context&, WASMOpExpressionI32);
    8788    template <class Context> ContextExpression parseBinaryExpressionI32(Context&, WASMOpExpressionI32);
    8889    template <class Context> ContextExpression parseRelationalI32ExpressionI32(Context&, WASMOpExpressionI32);
  • trunk/Source/JavaScriptCore/wasm/WASMFunctionSyntaxChecker.h

    r189494 r189499  
    8080    }
    8181
     82    int buildUnaryI32(int, WASMOpExpressionI32)
     83    {
     84        return UNUSED;
     85    }
     86
    8287    int buildBinaryI32(int, int, WASMOpExpressionI32)
    8388    {
Note: See TracChangeset for help on using the changeset viewer.