[Liftoff] Add i32.eq and i32.ne
Also refactor the implementation of i32.eqz such that the same platform-specific code can be reused. As a next step, it should be straight-forward to add other i32 comparison operations. R=titzer@chromium.org Bug: v8:6600 Change-Id: I4e8768d4ceb7294ba35777b7777ddd69d1a58cf1 Reviewed-on: https://chromium-review.googlesource.com/877889 Commit-Queue: Clemens Hammacher <clemensh@chromium.org> Reviewed-by: Ben Titzer <titzer@chromium.org> Cr-Commit-Position: refs/heads/master@{#50868}
This commit is contained in:
parent
55efb6cc5d
commit
664dc868b9
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -358,20 +358,6 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register lhs, Register rhs,
|
||||
liftoff::EmitShiftOperation(this, dst, lhs, rhs, &Assembler::shr_cl, pinned);
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
|
||||
Register tmp_byte_reg = dst;
|
||||
// Only the lower 4 registers can be addressed as 8-bit registers.
|
||||
if (!dst.is_byte_register()) {
|
||||
LiftoffRegList pinned = LiftoffRegList::ForRegs(src);
|
||||
tmp_byte_reg = GetUnusedRegister(liftoff::kByteRegs, pinned).gp();
|
||||
}
|
||||
|
||||
test(src, src);
|
||||
setcc(zero, tmp_byte_reg);
|
||||
movzx_b(dst, tmp_byte_reg);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
|
||||
Label nonzero_input;
|
||||
Label continuation;
|
||||
@ -475,6 +461,20 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
Register tmp_byte_reg = dst;
|
||||
// Only the lower 4 registers can be addressed as 8-bit registers.
|
||||
if (!dst.is_byte_register()) {
|
||||
LiftoffRegList pinned = LiftoffRegList::ForRegs(dst);
|
||||
// {mov} does not change the status flags, so calling {GetUnusedRegister}
|
||||
// should be fine here.
|
||||
tmp_byte_reg = GetUnusedRegister(liftoff::kByteRegs, pinned).gp();
|
||||
}
|
||||
|
||||
setcc(cond, tmp_byte_reg);
|
||||
movzx_b(dst, tmp_byte_reg);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) {
|
||||
Register limit = GetUnusedRegister(kGpReg).gp();
|
||||
mov(limit, Immediate(ExternalReference::address_of_stack_limit(isolate())));
|
||||
|
@ -321,7 +321,6 @@ class LiftoffAssembler : public TurboAssembler {
|
||||
LiftoffRegList pinned = {});
|
||||
|
||||
// i32 unops.
|
||||
inline bool emit_i32_eqz(Register dst, Register src);
|
||||
inline bool emit_i32_clz(Register dst, Register src);
|
||||
inline bool emit_i32_ctz(Register dst, Register src);
|
||||
inline bool emit_i32_popcnt(Register dst, Register src);
|
||||
@ -340,6 +339,8 @@ class LiftoffAssembler : public TurboAssembler {
|
||||
inline void emit_ptrsize_compare(Register, Register);
|
||||
inline void emit_jump(Label*);
|
||||
inline void emit_cond_jump(Condition, Label*);
|
||||
// Set {dst} to 1 if condition holds, 0 otherwise.
|
||||
inline void emit_i32_set_cond(Condition, Register dst);
|
||||
|
||||
inline void StackCheck(Label* ool_code);
|
||||
|
||||
|
@ -481,6 +481,15 @@ class LiftoffCompiler {
|
||||
__ PushRegister(kWasmI32, dst_reg);
|
||||
}
|
||||
|
||||
void I32Eqz() {
|
||||
LiftoffRegList pinned;
|
||||
LiftoffRegister dst = pinned.set(__ GetUnaryOpTargetRegister(kGpReg));
|
||||
LiftoffRegister src = pinned.set(__ PopToRegister(kGpReg, pinned));
|
||||
asm_->emit_i32_test(src.gp());
|
||||
asm_->emit_i32_set_cond(kEqual, dst.gp());
|
||||
__ PushRegister(kWasmI32, dst);
|
||||
}
|
||||
|
||||
void UnOp(Decoder* decoder, WasmOpcode opcode, FunctionSig*,
|
||||
const Value& value, Value* result) {
|
||||
#define CASE_UNOP(opcode, type, fn, ext_ref_fn) \
|
||||
@ -488,11 +497,13 @@ class LiftoffCompiler {
|
||||
type##UnOp(&LiftoffAssembler::emit_##fn, ext_ref_fn); \
|
||||
break;
|
||||
switch (opcode) {
|
||||
CASE_UNOP(I32Eqz, I32, i32_eqz, nullptr)
|
||||
CASE_UNOP(I32Clz, I32, i32_clz, nullptr)
|
||||
CASE_UNOP(I32Ctz, I32, i32_ctz, nullptr)
|
||||
CASE_UNOP(I32Popcnt, I32, i32_popcnt,
|
||||
&ExternalReference::wasm_word32_popcnt)
|
||||
case WasmOpcode::kExprI32Eqz:
|
||||
I32Eqz();
|
||||
break;
|
||||
default:
|
||||
return unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
|
||||
}
|
||||
@ -509,6 +520,16 @@ class LiftoffCompiler {
|
||||
__ PushRegister(kWasmI32, dst_reg);
|
||||
}
|
||||
|
||||
void I32CmpOp(Condition cond) {
|
||||
LiftoffRegList pinned;
|
||||
LiftoffRegister dst = pinned.set(__ GetBinaryOpTargetRegister(kGpReg));
|
||||
LiftoffRegister rhs = pinned.set(__ PopToRegister(kGpReg, pinned));
|
||||
LiftoffRegister lhs = __ PopToRegister(kGpReg, pinned);
|
||||
__ emit_i32_compare(lhs.gp(), rhs.gp());
|
||||
__ emit_i32_set_cond(cond, dst.gp());
|
||||
__ PushRegister(kWasmI32, dst);
|
||||
}
|
||||
|
||||
void I32ShiftOp(void (LiftoffAssembler::*emit_fn)(Register, Register,
|
||||
Register, LiftoffRegList)) {
|
||||
LiftoffRegList pinned;
|
||||
@ -546,6 +567,9 @@ class LiftoffCompiler {
|
||||
#define CASE_BINOP(opcode, type, fn) \
|
||||
case WasmOpcode::kExpr##opcode: \
|
||||
return type##BinOp(&LiftoffAssembler::emit_##fn);
|
||||
#define CASE_CMPOP(opcode, cond) \
|
||||
case WasmOpcode::kExpr##opcode: \
|
||||
return I32CmpOp(cond);
|
||||
#define CASE_SHIFTOP(opcode, fn) \
|
||||
case WasmOpcode::kExpr##opcode: \
|
||||
return I32ShiftOp(&LiftoffAssembler::emit_##fn);
|
||||
@ -560,6 +584,8 @@ class LiftoffCompiler {
|
||||
CASE_BINOP(I32And, I32, i32_and)
|
||||
CASE_BINOP(I32Ior, I32, i32_or)
|
||||
CASE_BINOP(I32Xor, I32, i32_xor)
|
||||
CASE_CMPOP(I32Eq, kEqual)
|
||||
CASE_CMPOP(I32Ne, kUnequal)
|
||||
CASE_SHIFTOP(I32Shl, i32_shl)
|
||||
CASE_SHIFTOP(I32ShrS, i32_sar)
|
||||
CASE_SHIFTOP(I32ShrU, i32_shr)
|
||||
@ -573,6 +599,7 @@ class LiftoffCompiler {
|
||||
}
|
||||
#undef CASE_BINOP
|
||||
#undef CASE_SHIFTOP
|
||||
#undef CASE_CMPOP
|
||||
#undef CASE_CCALL_BINOP
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -104,7 +104,6 @@ UNIMPLEMENTED_GP_BINOP(i32_xor)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shl)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_sar)
|
||||
UNIMPLEMENTED_SHIFTOP(i32_shr)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_eqz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_clz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_ctz)
|
||||
UNIMPLEMENTED_GP_UNOP(i32_popcnt)
|
||||
@ -134,6 +133,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) { UNIMPLEMENTED(); }
|
||||
|
||||
void LiftoffAssembler::CallTrapCallbackForTesting() { UNIMPLEMENTED(); }
|
||||
|
@ -361,13 +361,6 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register lhs, Register rhs,
|
||||
liftoff::EmitShiftOperation(this, dst, lhs, rhs, &Assembler::shrl_cl, pinned);
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
|
||||
testl(src, src);
|
||||
setcc(zero, dst);
|
||||
movzxbl(dst, dst);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
|
||||
Label nonzero_input;
|
||||
Label continuation;
|
||||
@ -475,6 +468,11 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
|
||||
setcc(cond, dst);
|
||||
movzxbl(dst, dst);
|
||||
}
|
||||
|
||||
void LiftoffAssembler::StackCheck(Label* ool_code) {
|
||||
Register limit = GetUnusedRegister(kGpReg).gp();
|
||||
LoadAddress(limit, ExternalReference::address_of_stack_limit(isolate()));
|
||||
|
Loading…
Reference in New Issue
Block a user