Ver Fonte

wasm: Add rotate opcodes

- adding rol and ror to backend
- test cases including encoded wasm (for now until wast to wasm is
  scripted)
- formatting of unknown opcode message in hex
George Kuan há 10 anos atrás
pai
commit
3f3cbfc136

+ 6 - 1
lib/Backend/IRBuilderAsmJs.cpp

@@ -2674,7 +2674,12 @@ IRBuilderAsmJs::BuildInt3(Js::OpCodeAsmJs newOpcode, uint32 offset, Js::RegSlot
     case Js::OpCodeAsmJs::Imul_Int:
         instr = IR::Instr::New(Js::OpCode::InlineMathImul, dstOpnd, src1Opnd, src2Opnd, m_func);
         break;
-
+    case Js::OpCodeAsmJs::Rol_Int:
+        instr = IR::Instr::New(Js::OpCode::Rol_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
+        break;
+    case Js::OpCodeAsmJs::Ror_Int:
+        instr = IR::Instr::New(Js::OpCode::Ror_I4, dstOpnd, src1Opnd, src2Opnd, m_func);
+        break;
     default:
         Assume(UNREACHED);
     }

+ 3 - 1
lib/Backend/Lower.cpp

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 #include "Backend.h"
@@ -974,6 +974,8 @@ Lowerer::LowerRange(IR::Instr *instrStart, IR::Instr *instrEnd, bool defaultDoFa
         case Js::OpCode::Shl_I4:
         case Js::OpCode::Shr_I4:
         case Js::OpCode::ShrU_I4:
+        case Js::OpCode::Rol_I4:
+        case Js::OpCode::Ror_I4:
         case Js::OpCode::BrTrue_I4:
         case Js::OpCode::BrFalse_I4:
             if(instr->HasBailOutInfo())

+ 10 - 0
lib/Backend/LowerMDShared.cpp

@@ -1189,6 +1189,14 @@ void LowererMD::ChangeToShift(IR::Instr *const instr, const bool needFlags)
             instr->m_opcode = Js::OpCode::SHR;
             break;
 
+        case Js::OpCode::Rol_I4:
+            instr->m_opcode = Js::OpCode::ROL;
+            break;
+
+        case Js::OpCode::Ror_I4:
+            instr->m_opcode = Js::OpCode::ROR;
+            break;
+
         default:
             Assert(false);
             __assume(false);
@@ -1634,6 +1642,8 @@ LowererMD::Legalize(IR::Instr *const instr, bool fPostRegAlloc)
         case Js::OpCode::SHL:
         case Js::OpCode::SHR:
         case Js::OpCode::SAR:
+        case Js::OpCode::ROL:
+        case Js::OpCode::ROR:
             if (verify)
             {
                 Assert(instr->GetSrc2()->IsIntConstOpnd()

+ 2 - 0
lib/Backend/amd64/LowererMDArch.cpp

@@ -2020,6 +2020,8 @@ idiv_common:
     case Js::OpCode::Shl_I4:
     case Js::OpCode::ShrU_I4:
     case Js::OpCode::Shr_I4:
+    case Js::OpCode::Rol_I4:
+    case Js::OpCode::Ror_I4:
         LowererMD::ChangeToShift(instr, false /* needFlags */);
         legalize = true;
         break;

+ 2 - 0
lib/Backend/amd64/MdOpCodes.h

@@ -222,6 +222,8 @@ MACRO(PXOR,     Reg2,   None,           RNON,   f(MODRM),   o(PXOR),    DNO16|DO
 
 
 MACRO(RET,      Empty,  OpSideEffect,  RNON,   f(SPECIAL), o(RET),     DSETCC,                      OLB_NONE)
+MACRO(ROL,      Reg2,   None /* XXX */,R000,   f(SHIFT),   o(ROL),     DOPEQ | DSETCC,              OLB_NONE)
+MACRO(ROR,      Reg2,   None /* XXX */,R001,   f(SHIFT),   o(ROR),     DOPEQ | DSETCC,              OLB_NONE)
 MACRO(ROUNDSD,  Reg3,   None,          RNON,   f(MODRM),   o(ROUNDSD), DDST|DNO16|DSSE|D66,         OLB_0F3A)
 MACRO(ROUNDSS,  Reg3,   None,          RNON,   f(MODRM),   o(ROUNDSS), DDST|DNO16|DSSE|D66,         OLB_0F3A)
 MACRO(SAR,      Reg2,   OpSideEffect,  R111,   f(SHIFT),   o(SAR),     DOPEQ|DSETCC,                OLB_NONE)

+ 2 - 0
lib/Backend/amd64/X64Encode.h

@@ -315,6 +315,8 @@ enum Forms : BYTE
 #define OPBYTE_PXOR     {0xef}                  // modrm
 
 #define OPBYTE_RET      {0xc2}                   // special
+#define OPBYTE_ROL      {0xc0, 0xd2}             // shift, byte2=0
+#define OPBYTE_ROR      {0xc0, 0xd2}             // shift, byte2=1
 #define OPBYTE_ROUNDSD  {0x0B}                   // modrm
 #define OPBYTE_ROUNDSS  {0x0A}                   // modrm
 #define OPBYTE_SAR      {0xc0, 0xd2}             // shift, byte2=7

+ 2 - 0
lib/Backend/i386/LowererMDArch.cpp

@@ -2012,6 +2012,8 @@ idiv_common:
     case Js::OpCode::Shl_I4:
     case Js::OpCode::ShrU_I4:
     case Js::OpCode::Shr_I4:
+    case Js::OpCode::Rol_I4:
+    case Js::OpCode::Ror_I4:
         LowererMD::ChangeToShift(instr, false /* needFlags */);
         legalize = true;
         break;

+ 2 - 0
lib/Backend/i386/MdOpCodes.h

@@ -224,6 +224,8 @@ MACRO(SETB,     Reg1,       None,           RNON,   f(MODRM),   o(SETB),    DOPE
 MACRO(SETBE,    Reg1,       None,           RNON,   f(MODRM),   o(SETBE),   DOPEQ|DUSECC|DZEROF|DDST,   OLB_NONE)
 MACRO(SHL,      Reg2,       None,           R100,   f(SHIFT),   o(SHL),     DOPEQ|DSETCC,               OLB_NONE)
 MACRO(SHR,      Reg2,       None,           R101,   f(SHIFT),   o(SHR),     DOPEQ|DSETCC,               OLB_NONE)
+MACRO(ROL,      Reg2,       None /* XXX */, R000,   f(SHIFT),   o(ROL),     DOPEQ|DSETCC,               OLB_NONE)
+MACRO(ROR,      Reg2,       None /* XXX */, R001,   f(SHIFT),   o(ROR),     DOPEQ|DSETCC,               OLB_NONE)
 
 MACRO(SHUFPD,   Reg2,       None,           RNON,   f(MODRM),   o(SHUFPD),  DDST|DNO16|D66|DSSE,        OLB_NONE)
 MACRO(SHUFPS,   Reg2,       None,           RNON,   f(MODRM),   o(SHUFPS),  DDST|DNO16|DZEROF|DSSE,     OLB_NONE)

+ 2 - 0
lib/Backend/i386/X86Encode.h

@@ -301,6 +301,8 @@ enum Forms : BYTE
 #define OPBYTE_PXOR     {0xef}                  // modrm
 
 #define OPBYTE_RET      {0xc2}                  // special
+#define OPBYTE_ROL      {0xc0, 0xd2}            // shift, byte2=0
+#define OPBYTE_ROR      {0xc0, 0xd2}            // shift, byte2=1
 #define OPBYTE_ROUNDSD  {0x0B}                  // modrm
 #define OPBYTE_ROUNDSS  {0x0A}                  // modrm
 #define OPBYTE_SAR      {0xc0, 0xd2}            // shift, byte2=7

+ 3 - 1
lib/Runtime/ByteCode/OpCodes.h

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 // Default all macro to nothing
@@ -223,6 +223,8 @@ MACRO_BACKEND_ONLY(     Xor_I4,             Empty,          OpTempNumberSources|
 MACRO_BACKEND_ONLY(     Shl_I4,             Empty,          OpTempNumberSources|OpCanCSE)                                    // int32 Shift '<<' (signed, truncate)
 MACRO_BACKEND_ONLY(     Shr_I4,             Empty,          OpTempNumberSources|OpCanCSE)                                    // int32 Shift '>>' (signed, truncate)
 MACRO_BACKEND_ONLY(     ShrU_I4,            Empty,          OpTempNumberSources|OpCanCSE)                                    // int32 Shift '>>>'(unsigned, truncate)
+MACRO_BACKEND_ONLY(     Rol_I4,             Empty,          OpTempNumberSources|OpCanCSE)                                    // int32 rol (signed)
+MACRO_BACKEND_ONLY(     Ror_I4,             Empty,          OpTempNumberSources|OpCanCSE)                                    // int32 ror (signed)
 
 MACRO_BACKEND_ONLY(     Add_Ptr,            Empty,          OpTempNumberSources|OpCanCSE)                                    // ptr Arithmetic '+'
 

+ 3 - 1
lib/Runtime/ByteCode/OpCodesAsmJs.h

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 // Default all macro to nothing
@@ -126,6 +126,8 @@ MACRO_WMS   ( Xor_Int                   , Int3         , None            ) // in
 MACRO_WMS   ( Shl_Int                   , Int3         , None            ) // int32 Shift '<<' (signed, truncate)
 MACRO_WMS   ( Shr_Int                   , Int3         , None            ) // int32 Shift '>>' (signed, truncate)
 MACRO_WMS   ( ShrU_Int                  , Int3         , None            ) // int32 Shift '>>>'(unsigned, truncate)
+MACRO_WMS   ( Rol_Int                   , Int3         , None            ) // int32 Rotate left
+MACRO_WMS   ( Ror_Int                   , Int3         , None            ) // int32 Rotate right
 
 // Unsigned int math
 MACRO_WMS   ( Mul_UInt                  , Int3         , None            ) // unsigned int32 Arithmetic '*'

+ 2 - 0
lib/Runtime/Language/InterpreterHandlerAsmJs.inl

@@ -92,6 +92,8 @@ EXDEF2    (NOPASMJS          , NopEx        , Empty
   DEF2_WMS( I2toI1Mem        , Shl_Int      , AsmJsMath::Shl                                     )
   DEF2_WMS( I2toI1Mem        , Shr_Int      , AsmJsMath::Shr                                     )
   DEF2_WMS( I2toI1Mem        , ShrU_Int     , AsmJsMath::ShrU                                    )
+  DEF2_WMS( I2toI1Mem        , Rol_Int      , AsmJsMath::Rol                                     )
+  DEF2_WMS( I2toI1Mem        , Ror_Int      , AsmJsMath::Ror                                     )
 
   DEF2_WMS( I2toI1Mem   , Mul_UInt     , AsmJsMath::Mul<uint>                             )
   DEF2_WMS( I2toI1Mem   , Div_UInt     , AsmJsMath::Div<uint>                             )

+ 3 - 1
lib/Runtime/Math/AsmJsMath.h

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 #pragma once
@@ -23,6 +23,8 @@ namespace Js
         static int Shl( int aLeft, int aRight );
         static int Shr( int aLeft, int aRight );
         static int ShrU( int aLeft, int aRight );
+        static int Rol( int aLeft, int aRight );
+        static int Ror( int aLeft, int aRight );
         template<typename T> static T Neg( T aLeft);
         static int Not( int aLeft);
         static int LogNot( int aLeft);

+ 11 - 1
lib/Runtime/Math/AsmJsMath.inl

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 namespace Js
@@ -127,6 +127,16 @@ namespace Js
         return (unsigned int)aLeft >> (unsigned int)aRight;
     }
 
+    __inline int AsmJsMath::Rol( int aLeft, int aRight )
+    {
+        return _rotl(aLeft, aRight);
+    }
+
+    __inline int AsmJsMath::Ror( int aLeft, int aRight )
+    {
+        return _rotr(aLeft, aRight);
+    }
+
     template<typename T>
     __inline T AsmJsMath::Neg( T aLeft )
     {

+ 4 - 1
lib/WasmReader/WasmBinaryOpCodes.h

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 
@@ -238,6 +238,9 @@ WASM_SIMPLE_OPCODE(F64ConvertF32,       0xb2, PROMOTE_F32_F64,  D_F)
 WASM_SIMPLE_OPCODE(F64ReinterpretI64,   0xb3, LIMIT,            D_L)
 WASM_SIMPLE_OPCODE(I32ReinterpretF32,   0xb4, REINTERPRET_F32_I32, I_F)
 WASM_SIMPLE_OPCODE(I64ReinterpretF64,   0xb5, LIMIT,            L_D)
+WASM_SIMPLE_OPCODE(I32Ror,              0xb6, ROR_I32,          I_II)
+WASM_SIMPLE_OPCODE(I32Rol,              0xb7, ROL_I32,          I_II)
+
 
 #undef WASM_SIMPLE_OPCODE
 #undef WASM_MEM_OPCODE

+ 2 - 2
lib/WasmReader/WasmBinaryReader.cpp

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 
@@ -397,7 +397,7 @@ WasmBinaryReader::ASTNode()
 #include "WasmBinaryOpcodes.h"
 
     default:
-        ThrowDecodingError(_u("Unknown opcode %u"), op);
+        ThrowDecodingError(_u("Unknown opcode 0x%X"), op);
     }
 
 #if DBG_DUMP

+ 3 - 1
lib/WasmReader/WasmKeywords.h

@@ -1,5 +1,5 @@
 //-------------------------------------------------------------------------------------------------------
-// Copyright (C) Microsoft. All rights reserved.
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
 // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
 //-------------------------------------------------------------------------------------------------------
 
@@ -105,6 +105,8 @@ WASM_KEYWORD_BIN_MATH_I(SHRS, shr_s, Shr_Int)
 WASM_KEYWORD_BIN_MATH_I(SHRU, shr_u, ShrU_Int)
 WASM_KEYWORD_BIN_MATH_I(DIVU, divu, Div_UInt)
 WASM_KEYWORD_BIN_MATH_I(MODU, modu, Rem_UInt)
+WASM_KEYWORD_BIN_MATH_I(ROR, rotr, Ror_Int)
+WASM_KEYWORD_BIN_MATH_I(ROL, rotl, Rol_Int)
 
 WASM_KEYWORD_BIN_MATH_FD(DIV, div, Div)
 

+ 9 - 0
test/wasm/rlexe.xml

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<regress-exe>
+<test>
+    <default>
+      <files>rot.js</files>
+      <baseline>rot.baseline</baseline>
+    </default>
+  </test>
+</regress-exe>

+ 6 - 0
test/wasm/rot.baseline

@@ -0,0 +1,6 @@
+44
+262144
+16384
+255
+2
+-2147483648

+ 14 - 0
test/wasm/rot.js

@@ -0,0 +1,14 @@
+//-------------------------------------------------------------------------------------------------------
+// Copyright (C) Microsoft Corporation and contributors. All rights reserved.
+// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+//-------------------------------------------------------------------------------------------------------
+
+const blob = WScript.LoadBinaryFile('rot.wasm');
+const moduleBytesView = new Uint8Array(blob);
+var a = Wasm.instantiateModule(moduleBytesView, {}).exports;
+print(a.rotl(11,2)); // == 44
+print(a.rotl(65536,2)); // == 262144
+print(a.rotr(65536,2)); //  == 16384
+print(a.rotl(0xff00, 24)); // == 255
+print(a.rotl(0x80000000, 2)); // == 2
+print(a.rotr(0x00000001, 1)); // == -2147483648

BIN
test/wasm/rot.wasm


+ 15 - 0
test/wasm/rot.wast

@@ -0,0 +1,15 @@
+;;-------------------------------------------------------------------------------------------------------
+;; Copyright (C) Microsoft Corporation and contributors. All rights reserved.
+;; Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
+;;-------------------------------------------------------------------------------------------------------
+
+(module
+  (func (param i32) (param i32) (result i32)
+    (return (i32.rotl (get_local 0) (get_local 1)))
+  )
+  (func (param i32) (param i32) (result i32)
+    (return (i32.rotr (get_local 0) (get_local 1)))
+  )
+  (export "rotl" 0)
+  (export "rotr" 1)
+)