diff --git a/src/interpreter/ByteCode.h b/src/interpreter/ByteCode.h index 4579865bb..38cb8fac6 100644 --- a/src/interpreter/ByteCode.h +++ b/src/interpreter/ByteCode.h @@ -52,9 +52,11 @@ class FunctionType; F(TableSize) \ F(TableFill) \ F(RefFunc) \ - F(Move32) \ - F(Move64) \ - F(Move128) \ + F(MoveI32) \ + F(MoveF32) \ + F(MoveI64) \ + F(MoveF64) \ + F(MoveV128) \ F(Jump) \ F(JumpIfTrue) \ F(JumpIfFalse) \ @@ -863,10 +865,10 @@ class CallIndirect : public ByteCode { uint16_t m_resultOffsetsSize; }; -class Move32 : public ByteCode { +class Move : public ByteCode { public: - Move32(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) - : ByteCode(Opcode::Move32Opcode) + Move(Opcode opcode, ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : ByteCode(opcode) , m_srcOffset(srcOffset) , m_dstOffset(dstOffset) { @@ -875,70 +877,94 @@ class Move32 : public ByteCode { ByteCodeStackOffset srcOffset() const { return m_srcOffset; } ByteCodeStackOffset dstOffset() const { return m_dstOffset; } +protected: + ByteCodeStackOffset m_srcOffset; + ByteCodeStackOffset m_dstOffset; +}; + +class MoveI32 : public Move { +public: + MoveI32(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : Move(Opcode::MoveI32Opcode, srcOffset, dstOffset) + { + } + #if !defined(NDEBUG) void dump(size_t pos) { - printf("move32 "); + printf("movei32 "); DUMP_BYTECODE_OFFSET(srcOffset); DUMP_BYTECODE_OFFSET(dstOffset); } #endif - -protected: - ByteCodeStackOffset m_srcOffset; - ByteCodeStackOffset m_dstOffset; }; -class Move64 : public ByteCode { +class MoveF32 : public Move { public: - Move64(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) - : ByteCode(Opcode::Move64Opcode) - , m_srcOffset(srcOffset) - , m_dstOffset(dstOffset) + MoveF32(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : Move(Opcode::MoveF32Opcode, srcOffset, dstOffset) { } - ByteCodeStackOffset srcOffset() const { return m_srcOffset; } - ByteCodeStackOffset dstOffset() const { return m_dstOffset; } - #if !defined(NDEBUG) void dump(size_t pos) { - printf("move64 "); + printf("movef32 "); DUMP_BYTECODE_OFFSET(srcOffset); DUMP_BYTECODE_OFFSET(dstOffset); } #endif - -protected: - ByteCodeStackOffset m_srcOffset; - ByteCodeStackOffset m_dstOffset; }; -class Move128 : public ByteCode { +class MoveI64 : public Move { public: - Move128(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) - : ByteCode(Opcode::Move128Opcode) - , m_srcOffset(srcOffset) - , m_dstOffset(dstOffset) + MoveI64(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : Move(Opcode::MoveI64Opcode, srcOffset, dstOffset) { } - ByteCodeStackOffset srcOffset() const { return m_srcOffset; } - ByteCodeStackOffset dstOffset() const { return m_dstOffset; } +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("movei64 "); + DUMP_BYTECODE_OFFSET(srcOffset); + DUMP_BYTECODE_OFFSET(dstOffset); + } +#endif +}; + +class MoveF64 : public Move { +public: + MoveF64(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : Move(Opcode::MoveF64Opcode, srcOffset, dstOffset) + { + } #if !defined(NDEBUG) void dump(size_t pos) { - printf("move128 "); + printf("movef64 "); DUMP_BYTECODE_OFFSET(srcOffset); DUMP_BYTECODE_OFFSET(dstOffset); } #endif +}; -protected: - ByteCodeStackOffset m_srcOffset; - ByteCodeStackOffset m_dstOffset; +class MoveV128 : public Move { +public: + MoveV128(ByteCodeStackOffset srcOffset, ByteCodeStackOffset dstOffset) + : Move(Opcode::MoveV128Opcode, srcOffset, dstOffset) + { + } + +#if !defined(NDEBUG) + void dump(size_t pos) + { + printf("movev128 "); + DUMP_BYTECODE_OFFSET(srcOffset); + DUMP_BYTECODE_OFFSET(dstOffset); + } +#endif }; class Load32 : public ByteCode { diff --git a/src/interpreter/Interpreter.cpp b/src/interpreter/Interpreter.cpp index d36b64a89..8fd9eceab 100644 --- a/src/interpreter/Interpreter.cpp +++ b/src/interpreter/Interpreter.cpp @@ -743,30 +743,48 @@ ByteCodeStackOffset* Interpreter::interpret(ExecutionState& state, NEXT_INSTRUCTION(); } - DEFINE_OPCODE(Move32) + DEFINE_OPCODE(MoveI32) : { - Move32* code = (Move32*)programCounter; + MoveI32* code = (MoveI32*)programCounter; *reinterpret_cast(bp + code->dstOffset()) = *reinterpret_cast(bp + code->srcOffset()); - ADD_PROGRAM_COUNTER(Move32); + ADD_PROGRAM_COUNTER(MoveI32); NEXT_INSTRUCTION(); } - DEFINE_OPCODE(Move64) + DEFINE_OPCODE(MoveF32) : { - Move64* code = (Move64*)programCounter; + MoveF32* code = (MoveF32*)programCounter; + *reinterpret_cast(bp + code->dstOffset()) = *reinterpret_cast(bp + code->srcOffset()); + ADD_PROGRAM_COUNTER(MoveF32); + NEXT_INSTRUCTION(); + } + + DEFINE_OPCODE(MoveI64) + : + { + MoveI64* code = (MoveI64*)programCounter; *reinterpret_cast(bp + code->dstOffset()) = *reinterpret_cast(bp + code->srcOffset()); - ADD_PROGRAM_COUNTER(Move64); + ADD_PROGRAM_COUNTER(MoveI64); + NEXT_INSTRUCTION(); + } + + DEFINE_OPCODE(MoveF64) + : + { + MoveF64* code = (MoveF64*)programCounter; + *reinterpret_cast(bp + code->dstOffset()) = *reinterpret_cast(bp + code->srcOffset()); + ADD_PROGRAM_COUNTER(MoveF64); NEXT_INSTRUCTION(); } - DEFINE_OPCODE(Move128) + DEFINE_OPCODE(MoveV128) : { - Move128* code = (Move128*)programCounter; + MoveV128* code = (MoveV128*)programCounter; memcpy(bp + code->dstOffset(), bp + code->srcOffset(), 16); - ADD_PROGRAM_COUNTER(Move128); + ADD_PROGRAM_COUNTER(MoveV128); NEXT_INSTRUCTION(); } diff --git a/src/jit/Backend.cpp b/src/jit/Backend.cpp index be719f83c..f6331a3ff 100644 --- a/src/jit/Backend.cpp +++ b/src/jit/Backend.cpp @@ -530,7 +530,7 @@ static void emitBrTable(sljit_compiler* compiler, BrTableInstruction* instr) context->branchTableOffset = reinterpret_cast(target); } -static void emitMove32(sljit_compiler* compiler, Instruction* instr) +static void emitMoveI32(sljit_compiler* compiler, Instruction* instr) { Operand* operands = instr->operands(); JITArg src(operands); @@ -788,18 +788,21 @@ void JITCompiler::compileFunction(JITFunction* jitFunc, bool isExternal) } case Instruction::Move: { switch (item->asInstruction()->opcode()) { - case ByteCode::Move32Opcode: - emitMove32(m_compiler, item->asInstruction()); + case ByteCode::MoveI32Opcode: + emitMoveI32(m_compiler, item->asInstruction()); + break; + case ByteCode::MoveI64Opcode: + emitMoveI64(m_compiler, item->asInstruction()); break; #ifdef HAS_SIMD - case ByteCode::Move128Opcode: - emitMove128(m_compiler, item->asInstruction()); + case ByteCode::MoveV128Opcode: + emitMoveV128(m_compiler, item->asInstruction()); break; #endif /* HAS_SIMD */ default: - ASSERT(item->asInstruction()->opcode() == ByteCode::Move64Opcode); - emitMove64(m_compiler, item->asInstruction()); - break; + ASSERT(item->asInstruction()->opcode() == ByteCode::MoveF32Opcode + || item->asInstruction()->opcode() == ByteCode::MoveF64Opcode); + emitMoveFloat(m_compiler, item->asInstruction()); } break; } diff --git a/src/jit/ByteCodeParser.cpp b/src/jit/ByteCodeParser.cpp index d7563372c..d2fda45d2 100644 --- a/src/jit/ByteCodeParser.cpp +++ b/src/jit/ByteCodeParser.cpp @@ -151,7 +151,9 @@ static bool isFloatGlobal(uint32_t globalIndex, Module* module) OL1(OTPutV128, /* D */ V128) \ OL1(OTPutPTR, /* D */ PTR) \ OL2(OTMoveI32, /* SD */ I32, I32 | S0) \ + OL2(OTMoveF32, /* SD */ F32 | NOTMP, F32 | S0) \ OL2(OTMoveI64, /* SD */ I64, I64 | S0) \ + OL2(OTMoveF64, /* SD */ F64 | NOTMP, F64 | S0) \ OL2(OTMoveV128, /* SD */ V128, V128 | S0) \ OL3(OTCompareI64, /* SSD */ I64, I64, I32 | S0 | S1) \ OL3(OTCompareF32, /* SSD */ F32, F32, I32) \ @@ -1507,43 +1509,40 @@ static void compileFunction(JITCompiler* compiler, ModuleFunction* function, Mod operands[0].offset = STACK_OFFSET(const64->dstOffset()); break; } - case ByteCode::Move32Opcode: { - Instruction* instr = compiler->append(byteCode, Instruction::Move, ByteCode::Move32Opcode, 1, 1); - instr->setRequiredRegsDescriptor(OTMoveI32); - - Move32* move32 = reinterpret_cast(byteCode); - Operand* operands = instr->operands(); - - operands[0].item = nullptr; - operands[0].offset = STACK_OFFSET(move32->srcOffset()); - operands[1].item = nullptr; - operands[1].offset = STACK_OFFSET(move32->dstOffset()); - break; - } - case ByteCode::Move64Opcode: { - Instruction* instr = compiler->append(byteCode, Instruction::Move, ByteCode::Move64Opcode, 1, 1); - instr->setRequiredRegsDescriptor(OTMoveI64); - - Move64* move64 = reinterpret_cast(byteCode); - Operand* operands = instr->operands(); + case ByteCode::MoveI32Opcode: + case ByteCode::MoveF32Opcode: + case ByteCode::MoveI64Opcode: + case ByteCode::MoveF64Opcode: + case ByteCode::MoveV128Opcode: { + Instruction* instr = compiler->append(byteCode, Instruction::Move, opcode, 1, 1); + + switch (opcode) { + case ByteCode::MoveI32Opcode: + requiredInit = OTMoveI32; + break; + case ByteCode::MoveF32Opcode: + requiredInit = OTMoveF32; + break; + case ByteCode::MoveI64Opcode: + requiredInit = OTMoveI64; + break; + case ByteCode::MoveF64Opcode: + requiredInit = OTMoveF64; + break; + default: + requiredInit = OTMoveV128; + break; + } - operands[0].item = nullptr; - operands[0].offset = STACK_OFFSET(move64->srcOffset()); - operands[1].item = nullptr; - operands[1].offset = STACK_OFFSET(move64->dstOffset()); - break; - } - case ByteCode::Move128Opcode: { - Instruction* instr = compiler->append(byteCode, Instruction::Move, ByteCode::Move128Opcode, 1, 1); - instr->setRequiredRegsDescriptor(OTMoveV128); + instr->setRequiredRegsDescriptor(requiredInit); - Move128* move128 = reinterpret_cast(byteCode); + Move* move = reinterpret_cast(byteCode); Operand* operands = instr->operands(); operands[0].item = nullptr; - operands[0].offset = STACK_OFFSET(move128->srcOffset()); + operands[0].offset = STACK_OFFSET(move->srcOffset()); operands[1].item = nullptr; - operands[1].offset = STACK_OFFSET(move128->dstOffset()); + operands[1].offset = STACK_OFFSET(move->dstOffset()); break; } case ByteCode::GlobalGet32Opcode: { diff --git a/src/jit/FloatMathInl.h b/src/jit/FloatMathInl.h index b80adbd5c..2da5e7bf6 100644 --- a/src/jit/FloatMathInl.h +++ b/src/jit/FloatMathInl.h @@ -65,6 +65,24 @@ static void floatOperandToArg(sljit_compiler* compiler, Operand* operand, JITArg sljit_emit_fset64(compiler, srcReg, u.number); } +static void emitMoveFloat(sljit_compiler* compiler, Instruction* instr) +{ + Operand* operands = instr->operands(); + + JITArg src; + JITArg dst(operands + 1); + sljit_s32 tmpReg = GET_TARGET_REG(dst.arg, SLJIT_TMP_DEST_FREG); + + floatOperandToArg(compiler, operands + 0, src, tmpReg); + + sljit_s32 op = (instr->opcode() == ByteCode::MoveF32Opcode) ? SLJIT_MOV_F32 : SLJIT_MOV_F64; + + // Immediate to register case has already been handled. + if (dst.arg != src.arg || dst.argw != src.argw) { + sljit_emit_fop1(compiler, op, dst.arg, dst.argw, src.arg, src.argw); + } +} + // Float operations. // TODO Canonical NaN static sljit_f32 floatFloor(sljit_f32 operand) diff --git a/src/jit/IntMath32Inl.h b/src/jit/IntMath32Inl.h index 0ac61ba1d..88f97b2a4 100644 --- a/src/jit/IntMath32Inl.h +++ b/src/jit/IntMath32Inl.h @@ -1180,7 +1180,7 @@ static void emitConvert(sljit_compiler* compiler, Instruction* instr) } } -static void emitMove64(sljit_compiler* compiler, Instruction* instr) +static void emitMoveI64(sljit_compiler* compiler, Instruction* instr) { Operand* operands = instr->operands(); JITArgPair src(operands); diff --git a/src/jit/IntMath64Inl.h b/src/jit/IntMath64Inl.h index 8a6363a7c..0bbd5fd68 100644 --- a/src/jit/IntMath64Inl.h +++ b/src/jit/IntMath64Inl.h @@ -561,7 +561,7 @@ static void emitConvert(sljit_compiler* compiler, Instruction* instr) } } -static void emitMove64(sljit_compiler* compiler, Instruction* instr) +static void emitMoveI64(sljit_compiler* compiler, Instruction* instr) { Operand* operands = instr->operands(); JITArg src(operands); diff --git a/src/jit/SimdInl.h b/src/jit/SimdInl.h index 101d09cf7..97ff2b178 100644 --- a/src/jit/SimdInl.h +++ b/src/jit/SimdInl.h @@ -16,7 +16,7 @@ /* Only included by jit-backend.cc */ -static void emitMove128(sljit_compiler* compiler, Instruction* instr) +static void emitMoveV128(sljit_compiler* compiler, Instruction* instr) { Operand* operands = instr->operands(); JITArg dst(operands + 1); diff --git a/src/parser/WASMParser.cpp b/src/parser/WASMParser.cpp index 45a90e9dc..69a9b0ac4 100644 --- a/src/parser/WASMParser.cpp +++ b/src/parser/WASMParser.cpp @@ -1592,15 +1592,32 @@ class WASMBinaryReader : public wabt::WASMBinaryReaderDelegate { void generateMoveCodeIfNeeds(size_t srcPosition, size_t dstPosition, Walrus::Value::Type type) { - size_t size = Walrus::valueSize(type); if (srcPosition != dstPosition) { - if (size == 4) { - pushByteCode(Walrus::Move32(srcPosition, dstPosition), WASMOpcode::Move32Opcode); - } else if (size == 8) { - pushByteCode(Walrus::Move64(srcPosition, dstPosition), WASMOpcode::Move64Opcode); - } else { - ASSERT(size == 16); - pushByteCode(Walrus::Move128(srcPosition, dstPosition), WASMOpcode::Move128Opcode); + switch (type) { + case Walrus::Value::I32: + pushByteCode(Walrus::MoveI32(srcPosition, dstPosition), WASMOpcode::MoveI32Opcode); + break; + case Walrus::Value::F32: + pushByteCode(Walrus::MoveF32(srcPosition, dstPosition), WASMOpcode::MoveF32Opcode); + break; + case Walrus::Value::I64: + pushByteCode(Walrus::MoveI64(srcPosition, dstPosition), WASMOpcode::MoveI64Opcode); + break; + case Walrus::Value::F64: + pushByteCode(Walrus::MoveF64(srcPosition, dstPosition), WASMOpcode::MoveF64Opcode); + break; + case Walrus::Value::V128: + pushByteCode(Walrus::MoveV128(srcPosition, dstPosition), WASMOpcode::MoveV128Opcode); + break; + default: + ASSERT(type == Walrus::Value::FuncRef || type == Walrus::Value::ExternRef); + + if (sizeof(size_t) == 4) { + pushByteCode(Walrus::MoveI32(srcPosition, dstPosition), WASMOpcode::MoveI32Opcode); + } else { + pushByteCode(Walrus::MoveI64(srcPosition, dstPosition), WASMOpcode::MoveI64Opcode); + } + break; } } } diff --git a/src/parser/opcode.def b/src/parser/opcode.def index 752d25689..4a7369323 100644 --- a/src/parser/opcode.def +++ b/src/parser/opcode.def @@ -567,8 +567,10 @@ WABT_OPCODE(I64, I32, I64, I64, 2, 0xfe, 0x4d, I64AtomicRmw16CmpxchgU, "i64.atom WABT_OPCODE(I64, I32, I64, I64, 4, 0xfe, 0x4e, I64AtomicRmw32CmpxchgU, "i64.atomic.rmw32.cmpxchg_u", "") /* Walrus interpreter only opcodes */ -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe7, Move32, "move_32", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe8, Move64, "move_64", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe9, Move128, "move_128", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xea, Const32, "const_32", "") -WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xeb, Const64, "const_64", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe7, MoveI32, "move_i32", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe8, MoveF32, "move_f32", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xe9, MoveI64, "move_i64", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xea, MoveF64, "move_f64", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xeb, MoveV128, "move_v128", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xec, Const32, "const_32", "") +WABT_OPCODE(___, ___, ___, ___, 0, 0, 0xed, Const64, "const_64", "")