Commit 9c4ffc38 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[Liftoff] Implement i32 shift with immediate

In fact, shifts are used most often with a fixed shift amount. This CL
adds special handling for this in Liftoff, to generate shorter and
faster code.

R=jkummerow@chromium.org

Bug: v8:9919

Change-Id: I9629872b628e0d617af00143ea27f9fbe95cb21e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1897539Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64758}
parent 7a7ec9a0
......@@ -693,6 +693,14 @@ void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) {
Register scratch = temps.Acquire(); \
and_(scratch, amount, Operand(0x1f)); \
instruction(dst, src, Operand(scratch)); \
} \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
int32_t amount) { \
if (V8_LIKELY((amount & 31) != 0)) { \
instruction(dst, src, Operand(amount & 31)); \
} else if (dst != src) { \
mov(dst, src); \
} \
}
#define FP32_UNOP(name, instruction) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
......@@ -867,11 +875,6 @@ void LiftoffAssembler::emit_i32_remu(Register dst, Register lhs, Register rhs,
mls(dst, scratch, rhs, lhs);
}
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
DCHECK(is_uint5(amount));
lsr(dst, src, Operand(amount));
}
void LiftoffAssembler::emit_i64_add(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
liftoff::I64Binop<&Assembler::add, &Assembler::adc>(this, dst, lhs, rhs);
......
......@@ -486,12 +486,10 @@ void LiftoffAssembler::FillStackSlotsWithZero(uint32_t index, uint32_t count) {
void LiftoffAssembler::emit_##name(Register dst, Register src, \
Register amount, LiftoffRegList pinned) { \
instruction(dst.W(), src.W(), amount.W()); \
}
#define I32_SHIFTOP_I(name, instruction) \
I32_SHIFTOP(name, instruction) \
void LiftoffAssembler::emit_##name(Register dst, Register src, int amount) { \
DCHECK(is_uint5(amount)); \
instruction(dst.W(), src.W(), amount); \
} \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
int32_t amount) { \
instruction(dst.W(), src.W(), amount & 31); \
}
#define I64_SHIFTOP(name, instruction) \
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
......@@ -514,7 +512,7 @@ I32_BINOP_I(i32_or, Orr)
I32_BINOP_I(i32_xor, Eor)
I32_SHIFTOP(i32_shl, Lsl)
I32_SHIFTOP(i32_sar, Asr)
I32_SHIFTOP_I(i32_shr, Lsr)
I32_SHIFTOP(i32_shr, Lsr)
I64_BINOP_I(i64_add, Add)
I64_BINOP(i64_sub, Sub)
I64_BINOP(i64_mul, Mul)
......@@ -559,7 +557,6 @@ FP64_UNOP(f64_sqrt, Fsqrt)
#undef FP64_UNOP
#undef FP64_UNOP_RETURN_TRUE
#undef I32_SHIFTOP
#undef I32_SHIFTOP_I
#undef I64_SHIFTOP
#undef I64_SHIFTOP_I
......
......@@ -759,22 +759,34 @@ void LiftoffAssembler::emit_i32_shl(Register dst, Register src, Register amount,
pinned);
}
void LiftoffAssembler::emit_i32_shl(Register dst, Register src,
int32_t amount) {
if (dst != src) mov(dst, src);
shl(dst, amount & 31);
}
void LiftoffAssembler::emit_i32_sar(Register dst, Register src, Register amount,
LiftoffRegList pinned) {
liftoff::EmitShiftOperation(this, dst, src, amount, &Assembler::sar_cl,
pinned);
}
void LiftoffAssembler::emit_i32_sar(Register dst, Register src,
int32_t amount) {
if (dst != src) mov(dst, src);
sar(dst, amount & 31);
}
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, Register amount,
LiftoffRegList pinned) {
liftoff::EmitShiftOperation(this, dst, src, amount, &Assembler::shr_cl,
pinned);
}
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
void LiftoffAssembler::emit_i32_shr(Register dst, Register src,
int32_t amount) {
if (dst != src) mov(dst, src);
DCHECK(is_uint5(amount));
shr(dst, amount);
shr(dst, amount & 31);
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
......
......@@ -410,11 +410,13 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_i32_xor(Register dst, Register lhs, int32_t imm);
inline void emit_i32_shl(Register dst, Register src, Register amount,
LiftoffRegList pinned = {});
inline void emit_i32_shl(Register dst, Register src, int32_t amount);
inline void emit_i32_sar(Register dst, Register src, Register amount,
LiftoffRegList pinned = {});
inline void emit_i32_sar(Register dst, Register src, int32_t amount);
inline void emit_i32_shr(Register dst, Register src, Register amount,
LiftoffRegList pinned = {});
inline void emit_i32_shr(Register dst, Register src, int amount);
inline void emit_i32_shr(Register dst, Register src, int32_t amount);
// i32 unops.
inline void emit_i32_clz(Register dst, Register src);
......
......@@ -998,12 +998,6 @@ class LiftoffCompiler {
[=](LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
__ emit_f64_set_cond(cond, dst.gp(), lhs.fp(), rhs.fp()); \
});
#define CASE_I32_SHIFTOP(opcode, fn) \
case kExpr##opcode: \
return EmitBinOp<kWasmI32, kWasmI32>( \
[=](LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
__ emit_##fn(dst.gp(), lhs.gp(), rhs.gp(), {}); \
});
#define CASE_I64_SHIFTOP(opcode, fn) \
case kExpr##opcode: \
return EmitBinOp<kWasmI64, kWasmI64>([=](LiftoffRegister dst, \
......@@ -1067,9 +1061,9 @@ class LiftoffCompiler {
CASE_F64_CMPOP(F64Gt, kUnsignedGreaterThan)
CASE_F64_CMPOP(F64Le, kUnsignedLessEqual)
CASE_F64_CMPOP(F64Ge, kUnsignedGreaterEqual)
CASE_I32_SHIFTOP(I32Shl, i32_shl)
CASE_I32_SHIFTOP(I32ShrS, i32_sar)
CASE_I32_SHIFTOP(I32ShrU, i32_shr)
CASE_I32_BINOPI(I32Shl, i32_shl)
CASE_I32_BINOPI(I32ShrS, i32_sar)
CASE_I32_BINOPI(I32ShrU, i32_shr)
CASE_I64_SHIFTOP(I64Shl, i64_shl)
CASE_I64_SHIFTOP(I64ShrS, i64_sar)
CASE_I64_SHIFTOP(I64ShrU, i64_shr)
......@@ -1204,7 +1198,6 @@ class LiftoffCompiler {
#undef CASE_I64_CMPOP
#undef CASE_F32_CMPOP
#undef CASE_F64_CMPOP
#undef CASE_I32_SHIFTOP
#undef CASE_I64_SHIFTOP
#undef CASE_CCALL_BINOP
}
......
......@@ -722,22 +722,34 @@ void LiftoffAssembler::emit_i32_shl(Register dst, Register src, Register amount,
&Assembler::shll_cl, pinned);
}
void LiftoffAssembler::emit_i32_shl(Register dst, Register src,
int32_t amount) {
if (dst != src) movl(dst, src);
shll(dst, Immediate(amount & 31));
}
void LiftoffAssembler::emit_i32_sar(Register dst, Register src, Register amount,
LiftoffRegList pinned) {
liftoff::EmitShiftOperation<kWasmI32>(this, dst, src, amount,
&Assembler::sarl_cl, pinned);
}
void LiftoffAssembler::emit_i32_sar(Register dst, Register src,
int32_t amount) {
if (dst != src) movl(dst, src);
sarl(dst, Immediate(amount & 31));
}
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, Register amount,
LiftoffRegList pinned) {
liftoff::EmitShiftOperation<kWasmI32>(this, dst, src, amount,
&Assembler::shrl_cl, pinned);
}
void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
void LiftoffAssembler::emit_i32_shr(Register dst, Register src,
int32_t amount) {
if (dst != src) movl(dst, src);
DCHECK(is_uint5(amount));
shrl(dst, Immediate(amount));
shrl(dst, Immediate(amount & 31));
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
......
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