Browse Source

refactor & cleanup for bitselect & shuffle

Nikolay Korovaiko 8 năm trước cách đây
mục cha
commit
4a7149b032

+ 8 - 41
lib/Backend/IRBuilderAsmJs.cpp

@@ -5829,60 +5829,27 @@ template <typename SizePolicy>
 void
 IRBuilderAsmJs::BuildAsmShuffle(Js::OpCodeAsmJs newOpcode, uint32 offset)
 {
-    //TODO @nikolayk BuildAsmShuffle is very similar to BuildUint8x16_3Int16
-    //Unfortunately, the latter expects the shuffle indices to come from a constant table
-    //which we don't use for WebAssembly modules.
-    //See if there are opportunities for refactoring
     Assert(OpCodeAttrAsmJs::HasMultiSizeLayout(newOpcode) && newOpcode == Js::OpCodeAsmJs::Simd128_Shuffle_V8X16);
     auto layout = m_jnReader.GetLayout<Js::OpLayoutT_AsmShuffle<SizePolicy>>();
 
     IR::RegOpnd * dstOpnd = BuildDstOpnd(GetRegSlotFromSimd128Reg(layout->R0), TySimd128U16);
     IR::RegOpnd * src1Opnd = BuildSrcOpnd(GetRegSlotFromSimd128Reg(layout->R1), TySimd128U16);
     IR::RegOpnd * src2Opnd = BuildSrcOpnd(GetRegSlotFromSimd128Reg(layout->R2), TySimd128U16);
-
-    IR::RegOpnd * src3Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[0], TyInt32, this->m_func);
-    IR::RegOpnd * src4Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[1], TyInt32, this->m_func);
-    IR::RegOpnd * src5Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[2], TyInt32, this->m_func);
-    IR::RegOpnd * src6Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[3], TyInt32, this->m_func);
-    IR::RegOpnd * src7Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[4], TyInt32, this->m_func);
-    IR::RegOpnd * src8Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[5], TyInt32, this->m_func);
-    IR::RegOpnd * src9Opnd =  (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[6], TyInt32, this->m_func);
-    IR::RegOpnd * src10Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[7], TyInt32, this->m_func);
-    IR::RegOpnd * src11Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[8], TyInt32, this->m_func);
-    IR::RegOpnd * src12Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[9], TyInt32, this->m_func);
-    IR::RegOpnd * src13Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[10], TyInt32, this->m_func);
-    IR::RegOpnd * src14Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[11], TyInt32, this->m_func);
-    IR::RegOpnd * src15Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[12], TyInt32, this->m_func);
-    IR::RegOpnd * src16Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[13], TyInt32, this->m_func);
-    IR::RegOpnd * src17Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[14], TyInt32, this->m_func);
-    IR::RegOpnd * src18Opnd = (IR::RegOpnd*) IR::IntConstOpnd::New(layout->INDICES[15], TyInt32, this->m_func);
-
-    IR::Instr * instr = nullptr;
     dstOpnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
     src1Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
     src2Opnd->SetValueType(ValueType::GetSimd128(ObjectType::Simd128Uint8x16));
 
+    uint const LANES = 16;
+    IR::Instr * instr = nullptr;
+
     instr = AddExtendedArg(src1Opnd, nullptr, offset);
     instr = AddExtendedArg(src2Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src3Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src4Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src5Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src6Opnd, instr->GetDst()->AsRegOpnd(), offset);
-
-    instr = AddExtendedArg(src7Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src8Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src9Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src10Opnd, instr->GetDst()->AsRegOpnd(), offset);
-
-    instr = AddExtendedArg(src11Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src12Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src13Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src14Opnd, instr->GetDst()->AsRegOpnd(), offset);
 
-    instr = AddExtendedArg(src15Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src16Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src17Opnd, instr->GetDst()->AsRegOpnd(), offset);
-    instr = AddExtendedArg(src18Opnd, instr->GetDst()->AsRegOpnd(), offset);
+    for (uint i = 0; i < LANES; i++)
+    {
+        IR::RegOpnd* shuffleOpnd = (IR::RegOpnd*)IR::IntConstOpnd::New(layout->INDICES[i], TyInt32, this->m_func);
+        instr = AddExtendedArg(shuffleOpnd, instr->GetDst()->AsRegOpnd(), offset);
+    }
     AddInstr(IR::Instr::New(Js::OpCode::Simd128_Shuffle_U16, dstOpnd, instr->GetDst(), m_func), offset);
 }
 

+ 2 - 2
lib/Runtime/ByteCode/AsmJsByteCodeWriter.cpp

@@ -4,6 +4,7 @@
 //-------------------------------------------------------------------------------------------------------
 
 #include "RuntimeByteCodePch.h"
+#include "../../WasmReader/WasmParseTree.h"
 
 #if defined(ASMJS_PLAT) || defined(ENABLE_WASM)
 
@@ -253,11 +254,10 @@ namespace Js
     template <typename SizePolicy>
     bool AsmJsByteCodeWriter::TryWriteAsmShuffle(OpCodeAsmJs op, RegSlot R0, RegSlot R1, RegSlot R2, uint8 indices[])
     {
-        const uint32 MAX_LANES = 16;
         OpLayoutT_AsmShuffle<SizePolicy> layout;
         if (SizePolicy::Assign(layout.R0, R0) && SizePolicy::Assign(layout.R1, R1) && SizePolicy::Assign(layout.R2, R2))
         {
-            memcpy_s(layout.INDICES, MAX_LANES, indices, MAX_LANES);
+            memcpy_s(layout.INDICES, Wasm::Simd::MAX_LANES, indices, Wasm::Simd::MAX_LANES);
             m_byteCodeData.EncodeT<SizePolicy::LayoutEnum>(op, &layout, sizeof(layout), this);
             return true;
         }

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

@@ -695,8 +695,7 @@ EXDEF2_WMS( SIMD_U16_2toB16_1 , Simd128_Gt_U16              , Js::SIMDUint8x16Op
 EXDEF2_WMS( SIMD_U4_1toU4_1     , Simd128_Neg_U4              , SIMDInt32x4Operation::OpNeg                     )
 EXDEF2_WMS( SIMD_U8_1toU8_1     , Simd128_Neg_U8              , SIMDInt16x8Operation::OpNeg                     )
 EXDEF2_WMS( SIMD_U16_1toU16_1   , Simd128_Neg_U16             , SIMDInt8x16Operation::OpNeg                     )
-
-EXDEF2_WMS( SIMD_V8X16_2I16toV8X16_1, Simd128_Shuffle_V8X16 , SIMDUtils::SIMD128InnerShuffle                    )
+EXDEF3_WMS( CUSTOM_ASMJS        , Simd128_Shuffle_V8X16       , OP_SimdShuffleV8X16           ,       AsmShuffle)
 
 #if 0
 EXDEF2_WMS(SIMD_D2toD2_1, Simd128_DoublesToD2, SIMDFloat64x2Operation::OpFloat64x2)

+ 0 - 17
lib/Runtime/Language/InterpreterProcessOpCodeAsmJs.h

@@ -2183,23 +2183,6 @@ if (switchProfileMode) \
     }
 #define PROCESS_SIMD_U16_1I16toU16_1(name, func) PROCESS_SIMD_U16_1I16toU16_1_COMMON(name, func,)
 
-// v8x16shuffle
-#define PROCESS_SIMD_V8X16_2I16toV8X16_1_COMMON(name, func, suffix) \
-   case OpCodeAsmJs::name: \
-   { \
-   PROCESS_READ_LAYOUT_ASMJS(name, AsmShuffle, suffix); \
-   const uint32 max_lanes = 16; \
-   uint32 lanes[max_lanes]; \
-   for (uint32 i = 0; i < max_lanes; i++) \
-   { \
-       Assert(playout->INDICES[i] < max_lanes * 2); \
-       lanes[i] = playout->INDICES[i]; \
-   } \
-   SetRegRawSimd(playout->R0, func(GetRegRawSimd(playout->R1), GetRegRawSimd(playout->R2), max_lanes, lanes));  \
-   break; \
-   }
-#define PROCESS_SIMD_V8X16_2I16toV8X16_1(name, func) PROCESS_SIMD_V8X16_2I16toV8X16_1_COMMON(name, func,)
-
 // u16shuffle
 #define PROCESS_SIMD_U16_2I16toU16_1_COMMON(name, func, suffix) \
     case OpCodeAsmJs::name: \

+ 13 - 0
lib/Runtime/Language/InterpreterStackFrame.cpp

@@ -8246,6 +8246,19 @@ const byte * InterpreterStackFrame::OP_ProfiledLoopBodyStart(const byte * ip)
         SetRegRawSimd(playout->F4_0, result);
     }
     
+    template <class T>
+    void InterpreterStackFrame::OP_SimdShuffleV8X16(const unaligned T* playout)
+    {
+        const uint32 max_lanes = 16;
+        uint32 lanes[max_lanes];
+        for (uint32 i = 0; i < max_lanes; i++)
+        {
+            Assert(playout->INDICES[i] < max_lanes * 2);
+            lanes[i] = playout->INDICES[i];
+        }
+        SetRegRawSimd(playout->R0, SIMDUtils::SIMD128InnerShuffle(GetRegRawSimd(playout->R1), GetRegRawSimd(playout->R2), max_lanes, lanes));
+    }
+
     template <class T>
     void InterpreterStackFrame::OP_SimdInt16x8(const unaligned T* playout)
     {

+ 1 - 0
lib/Runtime/Language/InterpreterStackFrame.h

@@ -261,6 +261,7 @@ namespace Js
         template <class T> void OP_SimdInt32x4FromFloat32x4(const unaligned T* playout);
         template <class T> void OP_SimdUint32x4FromFloat32x4(const unaligned T* playout);
         template <class T> void OP_WasmSimdConst(const unaligned T* playout);
+        template <class T> inline void OP_SimdShuffleV8X16(const unaligned T* playout);
 
         template <class T> void OP_SimdInt16x8(const unaligned T* playout);
         template <class T> void OP_SimdInt8x16(const unaligned T* playout);

+ 1 - 0
lib/WasmReader/WasmBinaryReader.cpp

@@ -606,6 +606,7 @@ void WasmBinaryReader::ShuffleNode()
     {
         m_currentNode.shuffle.indices[i] = ReadConst<uint8>();
     }
+    CheckBytesLeft(Simd::MAX_LANES);
     m_funcState.count += Simd::MAX_LANES;
 }
 

+ 7 - 13
lib/WasmReader/WasmByteCodeGenerator.cpp

@@ -1450,14 +1450,8 @@ void WasmBytecodeGenerator::CheckLaneIndex(Js::OpCodeAsmJs op)
 EmitInfo WasmBytecodeGenerator::EmitLaneIndex(Js::OpCodeAsmJs op)
 {
     CheckLaneIndex(op);
-    const uint offset = GetReader()->m_currentNode.lane.index;
-    return EnregisterIntConst(offset);
-}
-
-EmitInfo WasmBytecodeGenerator::EnregisterIntConst(uint constVal)
-{
     WasmConstLitNode dummy;
-    dummy.i32 = constVal;
+    dummy.i32 = GetReader()->m_currentNode.lane.index;
     return EmitConst(WasmTypes::I32, dummy);
 }
 
@@ -1481,9 +1475,9 @@ EmitInfo WasmBytecodeGenerator::EmitReplaceLaneExpr(Js::OpCodeAsmJs op, const Wa
 
 EmitInfo WasmBytecodeGenerator::EmitM128BitSelect()
 {
-    EmitInfo mask = PopEvalStack(WasmTypes::M128, _u("Argument should be of type M128"));
-    EmitInfo arg2Info = PopEvalStack(WasmTypes::M128, _u("Argument should be of type M128"));
-    EmitInfo arg1Info = PopEvalStack(WasmTypes::M128, _u("Argument should be of type M128"));
+    EmitInfo mask = PopEvalStack(WasmTypes::M128);
+    EmitInfo arg2Info = PopEvalStack(WasmTypes::M128);
+    EmitInfo arg1Info = PopEvalStack(WasmTypes::M128);
     Js::RegSlot resultReg = GetRegisterSpace(WasmTypes::M128)->AcquireTmpRegister();
     EmitInfo resultInfo(resultReg, WasmTypes::M128);
     m_writer->AsmReg4(Js::OpCodeAsmJs::Simd128_BitSelect_I4, resultReg, arg1Info.location, arg2Info.location, mask.location);
@@ -1492,8 +1486,8 @@ EmitInfo WasmBytecodeGenerator::EmitM128BitSelect()
 
 EmitInfo WasmBytecodeGenerator::EmitV8X16Shuffle()
 {
-    EmitInfo arg2Info = PopEvalStack(WasmTypes::M128, _u("Argument should be of type M128"));
-    EmitInfo arg1Info = PopEvalStack(WasmTypes::M128, _u("Argument should be of type M128"));
+    EmitInfo arg2Info = PopEvalStack(WasmTypes::M128);
+    EmitInfo arg1Info = PopEvalStack(WasmTypes::M128);
 
     Js::RegSlot resultReg = GetRegisterSpace(WasmTypes::M128)->AcquireTmpRegister();
     EmitInfo resultInfo(resultReg, WasmTypes::M128);
@@ -1507,7 +1501,7 @@ EmitInfo WasmBytecodeGenerator::EmitV8X16Shuffle()
         }
     }
 
-    m_writer->AsmShuffle(Js::OpCodeAsmJs::Simd128_Shuffle_V8X16, resultReg, arg1Info.location, arg2Info.location, GetReader()->m_currentNode.shuffle.indices);
+    m_writer->AsmShuffle(Js::OpCodeAsmJs::Simd128_Shuffle_V8X16, resultReg, arg1Info.location, arg2Info.location, indices);
     return resultInfo;
 }
 

+ 0 - 1
lib/WasmReader/WasmByteCodeGenerator.h

@@ -228,7 +228,6 @@ namespace Wasm
         EmitInfo EmitReplaceLaneExpr(Js::OpCodeAsmJs op, const WasmTypes::WasmType* signature);
         void CheckLaneIndex(Js::OpCodeAsmJs op);
         EmitInfo EmitLaneIndex(Js::OpCodeAsmJs op);
-        EmitInfo EnregisterIntConst(uint index);
 
         EmitInfo EmitConst(WasmTypes::WasmType type, WasmConstLitNode cnst);
         void EmitLoadConst(EmitInfo dst, WasmConstLitNode cnst);