diff --git a/src/jit/Backend.cpp b/src/jit/Backend.cpp index c9ec9b65b..a218e45a0 100644 --- a/src/jit/Backend.cpp +++ b/src/jit/Backend.cpp @@ -71,6 +71,11 @@ struct JITArg { void set(Operand* operand); + static bool isImm(Operand* operand) + { + return VARIABLE_TYPE(*operand) == Instruction::ConstPtr; + } + sljit_s32 arg; sljit_sw argw; }; diff --git a/src/jit/SimdInl.h b/src/jit/SimdInl.h index 88734e4d3..271c9773c 100644 --- a/src/jit/SimdInl.h +++ b/src/jit/SimdInl.h @@ -215,6 +215,11 @@ static void emitSplatSIMD(sljit_compiler* compiler, Instruction* instr) default: ASSERT(instr->opcode() == ByteCode::F64X2SplatOpcode); type = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64 | SLJIT_SIMD_FLOAT; +#if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) + if (JITArg::isImm(operands)) { + type = SLJIT_SIMD_REG_128 | SLJIT_SIMD_ELEM_64; + } +#endif /* SLJIT_32BIT_ARCHITECTURE */ break; } @@ -241,6 +246,11 @@ static void emitSplatSIMD(sljit_compiler* compiler, Instruction* instr) } else { #endif /* SLJIT_32BIT_ARCHITECTURE */ args[0].set(operands); + + if (SLJIT_IS_IMM(args[0].arg)) { + type &= ~SLJIT_SIMD_FLOAT; + } + sljit_emit_simd_replicate(compiler, type, dstReg, args[0].arg, args[0].argw); #if (defined SLJIT_32BIT_ARCHITECTURE && SLJIT_32BIT_ARCHITECTURE) } diff --git a/test/jit/splat.wast b/test/jit/splat.wast new file mode 100644 index 000000000..637478e93 --- /dev/null +++ b/test/jit/splat.wast @@ -0,0 +1,16 @@ +(module + (table $t 10 externref) + + (func (export "splat_f32") (result v128) + f32.const 1234.75 + f32x4.splat + ) + + (func (export "splat_f64") (result v128) + f64.const -123456.75 + f64x2.splat + ) +) + +(assert_return (invoke "splat_f32") (v128.const f32x4 1234.75 1234.75 1234.75 1234.75)) +(assert_return (invoke "splat_f64") (v128.const f64x2 -123456.75 -123456.75))