[wasm simd] Fix x64 and ia32 implementation of *.all_true

Bug: v8:9372
Change-Id: Ia25d6a5e1950a89e945cb4fdbdf166bdfb0d3c00
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1688429
Reviewed-by: Deepti Gandluri <gdeepti@chromium.org>
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62610}
This commit is contained in:
Ng Zhi An 2019-07-07 18:51:26 -07:00 committed by Commit Bot
parent d2b3eee50e
commit f0b9b77dd1
3 changed files with 51 additions and 21 deletions

View File

@ -464,6 +464,19 @@ class OutOfLineRecordWrite final : public OutOfLineCode {
__ opcode(i.OutputSimd128Register(), i.InputOperand(1), imm); \
}
#define ASSEMBLE_SIMD_ALL_TRUE(opcode) \
do { \
Register dst = i.OutputRegister(); \
Operand src = i.InputOperand(0); \
Register tmp = i.TempRegister(0); \
__ mov(tmp, Immediate(1)); \
__ xor_(dst, dst); \
__ Pxor(kScratchDoubleReg, kScratchDoubleReg); \
__ opcode(kScratchDoubleReg, src); \
__ Ptest(kScratchDoubleReg, kScratchDoubleReg); \
__ cmov(zero, dst, tmp); \
} while (false)
void CodeGenerator::AssembleDeconstructFrame() {
__ mov(esp, ebp);
__ pop(ebp);
@ -3665,18 +3678,18 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ cmov(zero, dst, tmp);
break;
}
// Need to split up all the different lane structures because the
// comparison instruction used matters, e.g. given 0xff00, pcmpeqb returns
// 0x0011, pcmpeqw returns 0x0000, ptest will set ZF to 0 and 1
// respectively.
case kIA32S1x4AllTrue:
ASSEMBLE_SIMD_ALL_TRUE(Pcmpeqd);
break;
case kIA32S1x8AllTrue:
ASSEMBLE_SIMD_ALL_TRUE(pcmpeqw);
break;
case kIA32S1x16AllTrue: {
Register dst = i.OutputRegister();
Operand src = i.InputOperand(0);
Register tmp = i.TempRegister(0);
__ mov(tmp, Immediate(1));
__ xor_(dst, dst);
__ Pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ Pxor(kScratchDoubleReg, src);
__ Ptest(kScratchDoubleReg, kScratchDoubleReg);
__ cmov(zero, dst, tmp);
ASSEMBLE_SIMD_ALL_TRUE(pcmpeqb);
break;
}
case kIA32StackCheck: {
@ -4636,6 +4649,7 @@ void CodeGenerator::AssembleJumpTable(Label** targets, size_t target_count) {
#undef ASSEMBLE_MOVX
#undef ASSEMBLE_SIMD_PUNPCK_SHUFFLE
#undef ASSEMBLE_SIMD_IMM_SHUFFLE
#undef ASSEMBLE_SIMD_ALL_TRUE
} // namespace compiler
} // namespace internal

View File

@ -576,6 +576,19 @@ void EmitWordLoadPoisoningIfNeeded(
__ opcode(i.OutputSimd128Register(), i.InputSimd128Register(1), imm); \
} while (false)
#define ASSEMBLE_SIMD_ALL_TRUE(opcode) \
do { \
CpuFeatureScope sse_scope(tasm(), SSE4_1); \
Register dst = i.OutputRegister(); \
Register tmp = i.TempRegister(0); \
__ movq(tmp, Immediate(1)); \
__ xorq(dst, dst); \
__ pxor(kScratchDoubleReg, kScratchDoubleReg); \
__ opcode(kScratchDoubleReg, i.InputSimd128Register(0)); \
__ ptest(kScratchDoubleReg, kScratchDoubleReg); \
__ cmovq(zero, dst, tmp); \
} while (false)
void CodeGenerator::AssembleDeconstructFrame() {
unwinding_info_writer_.MarkFrameDeconstructed(__ pc_offset());
__ movq(rsp, rbp);
@ -3463,19 +3476,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ cmovq(zero, dst, tmp);
break;
}
case kX64S1x4AllTrue:
case kX64S1x8AllTrue:
// Need to split up all the different lane structures because the
// comparison instruction used matters, e.g. given 0xff00, pcmpeqb returns
// 0x0011, pcmpeqw returns 0x0000, ptest will set ZF to 0 and 1
// respectively.
case kX64S1x4AllTrue: {
ASSEMBLE_SIMD_ALL_TRUE(pcmpeqd);
break;
}
case kX64S1x8AllTrue: {
ASSEMBLE_SIMD_ALL_TRUE(pcmpeqw);
break;
}
case kX64S1x16AllTrue: {
CpuFeatureScope sse_scope(tasm(), SSE4_1);
Register dst = i.OutputRegister();
XMMRegister src = i.InputSimd128Register(0);
Register tmp = i.TempRegister(0);
__ movq(tmp, Immediate(1));
__ xorq(dst, dst);
__ pcmpeqd(kScratchDoubleReg, kScratchDoubleReg);
__ pxor(kScratchDoubleReg, src);
__ ptest(kScratchDoubleReg, kScratchDoubleReg);
__ cmovq(zero, dst, tmp);
ASSEMBLE_SIMD_ALL_TRUE(pcmpeqb);
break;
}
case kX64StackCheck:
@ -3660,6 +3674,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
#undef ASSEMBLE_SIMD_IMM_INSTR
#undef ASSEMBLE_SIMD_PUNPCK_SHUFFLE
#undef ASSEMBLE_SIMD_IMM_SHUFFLE
#undef ASSEMBLE_SIMD_ALL_TRUE
namespace {

View File

@ -2555,6 +2555,7 @@ WASM_SIMD_ANYTRUE_TEST(8x16, 16, 0xff)
WASM_SET_LOCAL(simd, WASM_SIMD_I##format##_SPLAT(WASM_GET_LOCAL(0))), \
WASM_SIMD_UNOP(kExprS1x##lanes##AllTrue, WASM_GET_LOCAL(simd))); \
DCHECK_EQ(1, r.Call(max)); \
DCHECK_EQ(1, r.Call(0x1)); \
DCHECK_EQ(0, r.Call(0)); \
}
WASM_SIMD_ALLTRUE_TEST(32x4, 4, 0xffffffff)