Commit dd79031d authored by Milad Fa's avatar Milad Fa Committed by Commit Bot

s390: [wasm-simd] Saturate swizzle indices to 5 bits

`vperm` indices are taken from the five least significant bits
of the input byte. We need to make sure bigger values
are saturated to 31 to make vperm select 0 as the output.

Change-Id: I74715e909e4a50dec23f5423e53254836fe0ff8e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2446553Reviewed-by: 's avatarJunliang Yan <junyan@redhat.com>
Commit-Queue: Milad Fa <mfarazma@redhat.com>
Cr-Commit-Position: refs/heads/master@{#70292}
parent 1ff33c41
...@@ -4200,20 +4200,29 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -4200,20 +4200,29 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Simd128Register dst = i.OutputSimd128Register(), Simd128Register dst = i.OutputSimd128Register(),
src0 = i.InputSimd128Register(0), src0 = i.InputSimd128Register(0),
src1 = i.InputSimd128Register(1); src1 = i.InputSimd128Register(1);
Simd128Register tempFPReg1 = i.ToSimd128Register(instr->TempAt(0));
// Saturate the indices to 5 bits. Input indices more than 31 should
// return 0.
__ vrepi(kScratchDoubleReg, Operand(31), Condition(0));
__ vmnl(tempFPReg1, src1, kScratchDoubleReg, Condition(0), Condition(0),
Condition(0));
#ifdef V8_TARGET_BIG_ENDIAN #ifdef V8_TARGET_BIG_ENDIAN
// input needs to be reversed // input needs to be reversed
__ vlgv(r0, src0, MemOperand(r0, 0), Condition(3)); __ vlgv(r0, src0, MemOperand(r0, 0), Condition(3));
__ vlgv(r1, src0, MemOperand(r0, 1), Condition(3)); __ vlgv(r1, src0, MemOperand(r0, 1), Condition(3));
__ lrvgr(r0, r0); __ lrvgr(r0, r0);
__ lrvgr(r1, r1); __ lrvgr(r1, r1);
__ vlvgp(kScratchDoubleReg, r1, r0); __ vlvgp(dst, r1, r0);
// clear scr0 // clear scratch
__ vx(src0, src0, src0, Condition(0), Condition(0), Condition(0)); __ vx(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg,
__ vperm(dst, kScratchDoubleReg, src0, src1, Condition(0), Condition(0)); Condition(0), Condition(0), Condition(0));
__ vperm(dst, dst, kScratchDoubleReg, tempFPReg1, Condition(0),
Condition(0));
#else #else
__ vx(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg, __ vx(kScratchDoubleReg, kScratchDoubleReg, kScratchDoubleReg,
Condition(0), Condition(0), Condition(0)); Condition(0), Condition(0), Condition(0));
__ vperm(dst, src0, kScratchDoubleReg, src1, Condition(0), Condition(0)); __ vperm(dst, src0, kScratchDoubleReg, tempFPReg1, Condition(0),
Condition(0));
#endif #endif
break; break;
} }
......
...@@ -2855,9 +2855,10 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) { ...@@ -2855,9 +2855,10 @@ void InstructionSelector::VisitI8x16Shuffle(Node* node) {
void InstructionSelector::VisitI8x16Swizzle(Node* node) { void InstructionSelector::VisitI8x16Swizzle(Node* node) {
S390OperandGenerator g(this); S390OperandGenerator g(this);
InstructionOperand temps[] = {g.TempSimd128Register()};
Emit(kS390_I8x16Swizzle, g.DefineAsRegister(node), Emit(kS390_I8x16Swizzle, g.DefineAsRegister(node),
g.UseUniqueRegister(node->InputAt(0)), g.UseUniqueRegister(node->InputAt(0)),
g.UseUniqueRegister(node->InputAt(1))); g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps);
} }
void InstructionSelector::VisitS128Const(Node* node) { void InstructionSelector::VisitS128Const(Node* node) {
......
...@@ -3742,15 +3742,14 @@ EVALUATE(VPERM) { ...@@ -3742,15 +3742,14 @@ EVALUATE(VPERM) {
USE(m6); USE(m6);
for (int i = 0; i < kSimd128Size; i++) { for (int i = 0; i < kSimd128Size; i++) {
int8_t lane_num = get_simd_register_by_lane<int8_t>(r4, i); int8_t lane_num = get_simd_register_by_lane<int8_t>(r4, i);
// Get the five least significant bits.
lane_num = (lane_num << 3) >> 3;
int reg = r2; int reg = r2;
if (lane_num >= kSimd128Size) { if (lane_num >= kSimd128Size) {
lane_num = lane_num - kSimd128Size; lane_num = lane_num - kSimd128Size;
reg = r3; reg = r3;
} }
int8_t result = 0; int8_t result = get_simd_register_by_lane<int8_t>(reg, lane_num);
if (lane_num >= 0 && lane_num < kSimd128Size * 2) {
result = get_simd_register_by_lane<int8_t>(reg, lane_num);
}
set_simd_register_by_lane<int8_t>(r1, i, result); set_simd_register_by_lane<int8_t>(r1, i, result);
} }
return length; return length;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment