Commit 0e7d4ccd authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Implement i32 unops

This adds support for i32.eqz, i32.clz, and i32.ctz.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I0dd7c14cf98b68463edae7de3ced9a9d1f82de44
Reviewed-on: https://chromium-review.googlesource.com/852456
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50441}
parent 8d8f8756
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -244,11 +244,6 @@ void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {
}
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
emit_i32_add(dst, lhs, rhs);
}
void LiftoffAssembler::emit_i32_sub(Register dst, Register lhs, Register rhs) {
if (dst == rhs) {
neg(dst);
......@@ -279,6 +274,49 @@ COMMUTATIVE_I32_BINOP(xor, xor_)
#undef COMMUTATIVE_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
test(src, src);
setcc(zero, dst);
movzx_b(dst, dst);
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
test(src, src);
j(not_zero, &nonzero_input, Label::kNear);
mov(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get most significant bit set (MSBS).
bsr(dst, src);
// CLZ = 31 - MSBS = MSBS ^ 31.
xor_(dst, 31);
bind(&continuation);
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
test(src, src);
j(not_zero, &nonzero_input, Label::kNear);
mov(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get least significant bit set, which equals number of trailing zeros.
bsf(dst, src);
bind(&continuation);
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
emit_i32_add(dst, lhs, rhs);
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
if (CpuFeatures::IsSupported(AVX)) {
......
......@@ -284,6 +284,16 @@ LiftoffRegister LiftoffAssembler::GetBinaryOpTargetRegister(
return GetUnusedRegister(rc, pinned);
}
LiftoffRegister LiftoffAssembler::GetUnaryOpTargetRegister(
RegClass rc, LiftoffRegList pinned) {
auto& slot_src = cache_state_.stack_state.back();
if (slot_src.is_reg() && GetNumUses(slot_src.reg()) == 1) {
DCHECK_EQ(rc, slot_src.reg().reg_class());
return slot_src.reg();
}
return GetUnusedRegister(rc, pinned);
}
LiftoffRegister LiftoffAssembler::PopToRegister(RegClass rc,
LiftoffRegList pinned) {
DCHECK(!cache_state_.stack_state.empty());
......
......@@ -215,6 +215,8 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister GetBinaryOpTargetRegister(RegClass,
LiftoffRegList pinned = {});
LiftoffRegister GetUnaryOpTargetRegister(RegClass,
LiftoffRegList pinned = {});
LiftoffRegister PopToRegister(RegClass, LiftoffRegList pinned = {});
......@@ -294,6 +296,7 @@ class LiftoffAssembler : public TurboAssembler {
inline void Spill(uint32_t index, WasmValue);
inline void Fill(LiftoffRegister, uint32_t index);
// i32 binops.
inline void emit_i32_add(Register dst, Register lhs, Register rhs);
inline void emit_i32_sub(Register dst, Register lhs, Register rhs);
inline void emit_i32_mul(Register dst, Register lhs, Register rhs);
......@@ -301,6 +304,11 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_i32_or(Register dst, Register lhs, Register rhs);
inline void emit_i32_xor(Register dst, Register lhs, Register rhs);
// i32 unops.
inline void emit_i32_eqz(Register dst, Register src);
inline void emit_i32_clz(Register dst, Register src);
inline void emit_i32_ctz(Register dst, Register src);
inline void emit_ptrsize_add(Register dst, Register lhs, Register rhs);
inline void emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
......
......@@ -419,9 +419,31 @@ class LiftoffCompiler {
void EndControl(Decoder* decoder, Control* c) {}
void I32UnOp(void (LiftoffAssembler::*emit_fn)(Register, Register)) {
LiftoffRegList pinned_regs;
LiftoffRegister dst_reg =
pinned_regs.set(__ GetUnaryOpTargetRegister(kGpReg));
LiftoffRegister src_reg =
pinned_regs.set(__ PopToRegister(kGpReg, pinned_regs));
(asm_->*emit_fn)(dst_reg.gp(), src_reg.gp());
__ PushRegister(kWasmI32, dst_reg);
}
void UnOp(Decoder* decoder, WasmOpcode opcode, FunctionSig*,
const Value& value, Value* result) {
unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
TraceCacheState(decoder);
#define CASE_UNOP(opcode, type, fn) \
case WasmOpcode::kExpr##opcode: \
type##UnOp(&LiftoffAssembler::emit_##fn); \
break;
switch (opcode) {
CASE_UNOP(I32Eqz, I32, i32_eqz)
CASE_UNOP(I32Clz, I32, i32_clz)
CASE_UNOP(I32Ctz, I32, i32_ctz)
default:
return unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
}
#undef CASE_UNOP
}
void I32BinOp(void (LiftoffAssembler::*emit_fn)(Register, Register,
......
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -86,14 +86,33 @@ DEFAULT_I32_BINOP(xor, xor)
#undef DEFAULT_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
}
void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
UNIMPLEMENTED();
......
......@@ -236,15 +236,6 @@ void LiftoffAssembler::emit_i32_add(Register dst, Register lhs, Register rhs) {
}
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
if (lhs != dst) {
leap(dst, Operand(lhs, rhs, times_1, 0));
} else {
addp(dst, rhs);
}
}
void LiftoffAssembler::emit_i32_sub(Register dst, Register lhs, Register rhs) {
if (dst == rhs) {
negl(dst);
......@@ -275,6 +266,53 @@ COMMUTATIVE_I32_BINOP(xor, xor)
#undef COMMUTATIVE_I32_BINOP
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
testl(src, src);
setcc(zero, dst);
movzxbl(dst, dst);
}
void LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
testl(src, src);
j(not_zero, &nonzero_input, Label::kNear);
movl(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get most significant bit set (MSBS).
bsrl(dst, src);
// CLZ = 31 - MSBS = MSBS ^ 31.
xorl(dst, Immediate(31));
bind(&continuation);
}
void LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
testl(src, src);
j(not_zero, &nonzero_input, Label::kNear);
movl(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get least significant bit set, which equals number of trailing zeros.
bsfl(dst, src);
bind(&continuation);
}
void LiftoffAssembler::emit_ptrsize_add(Register dst, Register lhs,
Register rhs) {
if (lhs != dst) {
leap(dst, Operand(lhs, rhs, times_1, 0));
} else {
addp(dst, rhs);
}
}
void LiftoffAssembler::emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
if (CpuFeatures::IsSupported(AVX)) {
......
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