Commit 0c795b64 authored by Ng Zhi An's avatar Ng Zhi An Committed by Commit Bot

[wasm-simd][liftoff][arm][arm64] Implement shl

Bug: v8:9909
Change-Id: Ia87c46a45804dc0a3b5e7275a92c263fbcd4b145
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2197547
Commit-Queue: Zhi An Ng <zhin@chromium.org>
Reviewed-by: 's avatarClemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67806}
parent dbf9ff61
......@@ -327,6 +327,36 @@ inline void Load(LiftoffAssembler* assm, LiftoffRegister dst, MemOperand src,
}
}
constexpr int MaskFromNeonDataType(NeonDataType dt) {
switch (dt) {
case NeonS8:
case NeonU8:
return 7;
case NeonS16:
case NeonU16:
return 15;
case NeonS32:
case NeonU32:
return 31;
case NeonS64:
case NeonU64:
return 63;
}
}
template <NeonDataType dt, NeonSize sz>
inline void EmitSimdShl(LiftoffAssembler* assm, LiftoffRegister dst,
LiftoffRegister lhs, LiftoffRegister rhs) {
constexpr int mask = MaskFromNeonDataType(dt);
UseScratchRegisterScope temps(assm);
QwNeonRegister tmp = temps.AcquireQ();
Register shift = temps.Acquire();
assm->and_(shift, rhs.gp(), Operand(mask));
assm->vdup(sz, tmp, shift);
assm->vshl(dt, liftoff::GetSimd128Register(dst),
liftoff::GetSimd128Register(lhs), tmp);
}
} // namespace liftoff
int LiftoffAssembler::PrepareStackFrame() {
......@@ -2268,12 +2298,13 @@ void LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i64x2_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shl");
liftoff::EmitSimdShl<NeonS64, Neon32>(this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i64x2_shli");
vshl(NeonS64, liftoff::GetSimd128Register(dst),
liftoff::GetSimd128Register(lhs), rhs & 63);
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -2360,12 +2391,13 @@ void LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i32x4_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i32x4_shl");
liftoff::EmitSimdShl<NeonS32, Neon32>(this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i32x4_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i32x4_shli");
vshl(NeonS32, liftoff::GetSimd128Register(dst),
liftoff::GetSimd128Register(lhs), rhs & 31);
}
void LiftoffAssembler::emit_i32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -2427,12 +2459,13 @@ void LiftoffAssembler::emit_i16x8_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i16x8_shl");
liftoff::EmitSimdShl<NeonS16, Neon16>(this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i16x8_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i16x8_shli");
vshl(NeonS16, liftoff::GetSimd128Register(dst),
liftoff::GetSimd128Register(lhs), rhs & 15);
}
void LiftoffAssembler::emit_i16x8_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -2566,12 +2599,13 @@ void LiftoffAssembler::emit_i8x16_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i8x16_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i8x16_shl");
liftoff::EmitSimdShl<NeonS8, Neon8>(this, dst, lhs, rhs);
}
void LiftoffAssembler::emit_i8x16_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i8x16_shli");
vshl(NeonS8, liftoff::GetSimd128Register(dst),
liftoff::GetSimd128Register(lhs), rhs & 7);
}
void LiftoffAssembler::emit_i8x16_add(LiftoffRegister dst, LiftoffRegister lhs,
......
......@@ -104,6 +104,21 @@ inline MemOperand GetMemOp(LiftoffAssembler* assm,
return MemOperand(addr.X(), offset_imm);
}
inline void EmitSimdShiftLeft(LiftoffAssembler* assm, VRegister dst,
VRegister lhs, Register rhs,
VectorFormat format) {
DCHECK(dst.IsSameFormat(lhs));
DCHECK_EQ(dst.LaneCount(), LaneCountFromFormat(format));
UseScratchRegisterScope temps(assm);
VRegister tmp = temps.AcquireV(format);
Register shift = dst.Is2D() ? temps.AcquireX() : temps.AcquireW();
int mask = LaneSizeInBitsFromFormat(format) - 1;
assm->And(shift, rhs, mask);
assm->Dup(tmp, shift);
assm->Sshl(dst, lhs, tmp);
}
} // namespace liftoff
int LiftoffAssembler::PrepareStackFrame() {
......@@ -439,7 +454,7 @@ void LiftoffAssembler::Move(DoubleRegister dst, DoubleRegister src,
Fmov(dst.D(), src.D());
} else {
DCHECK_EQ(kWasmS128, type);
Fmov(dst.Q(), src.Q());
Mov(dst.Q(), src.Q());
}
}
......@@ -1254,12 +1269,13 @@ void LiftoffAssembler::emit_i64x2_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i64x2_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i64x2_shl");
liftoff::EmitSimdShiftLeft(this, dst.fp().V2D(), lhs.fp().V2D(), rhs.gp(),
kFormat2D);
}
void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i64x2_shli");
Shl(dst.fp().V2D(), lhs.fp().V2D(), rhs & 63);
}
void LiftoffAssembler::emit_i64x2_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -1321,12 +1337,13 @@ void LiftoffAssembler::emit_i32x4_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i32x4_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i32x4_shl");
liftoff::EmitSimdShiftLeft(this, dst.fp().V4S(), lhs.fp().V4S(), rhs.gp(),
kFormat4S);
}
void LiftoffAssembler::emit_i32x4_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i32x4_shli");
Shl(dst.fp().V4S(), lhs.fp().V4S(), rhs & 31);
}
void LiftoffAssembler::emit_i32x4_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -1402,12 +1419,13 @@ void LiftoffAssembler::emit_i16x8_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i16x8_shl");
liftoff::EmitSimdShiftLeft(this, dst.fp().V8H(), lhs.fp().V8H(), rhs.gp(),
kFormat8H);
}
void LiftoffAssembler::emit_i16x8_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i16x8_shli");
Shl(dst.fp().V8H(), lhs.fp().V8H(), rhs & 15);
}
void LiftoffAssembler::emit_i16x8_add(LiftoffRegister dst, LiftoffRegister lhs,
......@@ -1507,12 +1525,13 @@ void LiftoffAssembler::emit_i8x16_neg(LiftoffRegister dst,
void LiftoffAssembler::emit_i8x16_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
bailout(kSimd, "i8x16_shl");
liftoff::EmitSimdShiftLeft(this, dst.fp().V16B(), lhs.fp().V16B(), rhs.gp(),
kFormat16B);
}
void LiftoffAssembler::emit_i8x16_shli(LiftoffRegister dst, LiftoffRegister lhs,
int32_t rhs) {
bailout(kSimd, "i8x16_shli");
Shl(dst.fp().V16B(), lhs.fp().V16B(), rhs & 7);
}
void LiftoffAssembler::emit_i8x16_add(LiftoffRegister dst, LiftoffRegister lhs,
......
......@@ -861,6 +861,10 @@ void LiftoffAssembler::Move(LiftoffRegister dst, LiftoffRegister src,
// Use the {StackTransferRecipe} to move pairs, as the registers in the
// pairs might overlap.
StackTransferRecipe(this).MoveRegister(dst, src, type);
} else if (kNeedS128RegPair && dst.is_fp_pair()) {
// Calling low_fp is fine, Move will automatically check the type and
// convert this FP to its SIMD register, and use a SIMD move.
Move(dst.low_fp(), src.low_fp(), type);
} else if (dst.is_gp()) {
Move(dst.gp(), src.gp(), type);
} else {
......
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