Commit 1e89fed0 authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit Bot

[Liftoff] Refactor conditional instructions

Change prototypes of conditional jump and set instructions,
change their implementation accordingly and port these instructions
to MIPS.

Bug: v8:6600
Change-Id: I8e2c9c874f2fde9a1c1b5a34eaa9e72475e69bc5
Reviewed-on: https://chromium-review.googlesource.com/913252Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#51268}
parent 5bc39360
......@@ -138,23 +138,16 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
......
......@@ -138,23 +138,16 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
......
......@@ -609,23 +609,35 @@ void LiftoffAssembler::emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_i32_test(Register reg) { test(reg, reg); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
cmp(lhs, rhs);
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
emit_i32_compare(lhs, rhs);
}
void LiftoffAssembler::emit_jump(Label* label) { jmp(label); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
if (rhs != no_reg) {
switch (type) {
case kWasmI32:
cmp(lhs, rhs);
break;
default:
UNREACHABLE();
}
} else {
DCHECK_EQ(type, kWasmI32);
test(lhs, lhs);
}
j(cond, label);
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
if (rhs != no_reg) {
cmp(lhs, rhs);
} else {
test(lhs, lhs);
}
Register tmp_byte_reg = dst;
// Only the lower 4 registers can be addressed as 8-bit registers.
if (!dst.is_byte_register()) {
......
......@@ -77,7 +77,7 @@ constexpr Condition kUnsignedLessEqual = below_equal;
constexpr Condition kUnsignedGreaterThan = above;
constexpr Condition kUnsignedGreaterEqual = above_equal;
#elif V8_TARGET_ARCH_MIPS
#elif V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
constexpr Condition kEqual = eq;
constexpr Condition kUnequal = ne;
......
......@@ -380,13 +380,12 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
inline void emit_i32_test(Register);
inline void emit_i32_compare(Register, Register);
inline void emit_ptrsize_compare(Register, Register);
inline void emit_jump(Label*);
inline void emit_cond_jump(Condition, Label*);
inline void emit_cond_jump(Condition, Label*, ValueType value, Register lhs,
Register rhs = no_reg);
// Set {dst} to 1 if condition holds, 0 otherwise.
inline void emit_i32_set_cond(Condition, Register dst);
inline void emit_i32_set_cond(Condition, Register dst, Register lhs,
Register rhs = no_reg);
inline void StackCheck(Label* ool_code);
......
......@@ -431,8 +431,8 @@ class LiftoffCompiler {
// Test the condition, jump to else if zero.
Register value = __ PopToRegister(kGpReg).gp();
__ emit_i32_test(value);
__ emit_cond_jump(kEqual, if_block->else_state->label.get());
__ emit_cond_jump(kEqual, if_block->else_state->label.get(), kWasmI32,
value);
if_block->label_state.stack_base = __ cache_state()->stack_height();
// Store the state (after popping the value) for executing the else branch.
......@@ -534,8 +534,7 @@ class LiftoffCompiler {
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());
asm_->emit_i32_set_cond(kEqual, dst.gp(), src.gp());
__ PushRegister(kWasmI32, dst);
}
......@@ -574,8 +573,7 @@ class LiftoffCompiler {
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());
__ emit_i32_set_cond(cond, dst.gp(), lhs.gp(), rhs.gp());
__ PushRegister(kWasmI32, dst);
}
......@@ -853,8 +851,7 @@ class LiftoffCompiler {
void BrIf(Decoder* decoder, const Value& cond, Control* target) {
Label cont_false;
Register value = __ PopToRegister(kGpReg).gp();
__ emit_i32_test(value);
__ emit_cond_jump(kEqual, &cont_false);
__ emit_cond_jump(kEqual, &cont_false, kWasmI32, value);
Br(target);
__ bind(&cont_false);
......@@ -907,8 +904,8 @@ class LiftoffCompiler {
__ LoadFromContext(mem_size.gp(), offsetof(WasmContext, mem_size), 4);
__ LoadConstant(end_offset_reg, WasmValue(end_offset));
if (end_offset >= min_size_) {
__ emit_i32_compare(end_offset_reg.gp(), mem_size.gp());
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label);
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label, kWasmI32,
end_offset_reg.gp(), mem_size.gp());
}
// Just reuse the end_offset register for computing the effective size.
......@@ -916,8 +913,8 @@ class LiftoffCompiler {
__ emit_i32_sub(effective_size_reg.gp(), mem_size.gp(),
end_offset_reg.gp());
__ emit_i32_compare(index, effective_size_reg.gp());
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label);
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label, kWasmI32, index,
effective_size_reg.gp());
}
void TraceMemoryOperation(bool is_store, MachineRepresentation rep,
......@@ -1136,8 +1133,8 @@ class LiftoffCompiler {
__ LoadConstant(tmp_const, WasmValue(table_size),
RelocInfo::WASM_FUNCTION_TABLE_SIZE_REFERENCE);
__ emit_i32_compare(index.gp(), tmp_const.gp());
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label);
__ emit_cond_jump(kUnsignedGreaterEqual, trap_label, kWasmI32, index.gp(),
tmp_const.gp());
}
wasm::GlobalHandleAddress function_table_handle_address =
......@@ -1168,11 +1165,11 @@ class LiftoffCompiler {
DCHECK_GE(kMaxInt, canonical_sig_num);
__ LoadConstant(tmp_const, WasmPtrValue(Smi::FromInt(canonical_sig_num)));
__ emit_ptrsize_compare(scratch.gp(), tmp_const.gp());
Label* trap_label = AddOutOfLineTrap(
decoder->position(), Builtins::kThrowWasmTrapFuncSigMismatch);
__ emit_cond_jump(kUnequal, trap_label);
__ emit_cond_jump(kUnequal, trap_label, LiftoffAssembler::kWasmIntPtr,
scratch.gp(), tmp_const.gp());
// Load code object.
__ Load(scratch, table.gp(), index.gp(), kFixedArrayOffset + kPointerSize,
......
......@@ -178,24 +178,34 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
void LiftoffAssembler::emit_jump(Label* label) {
TurboAssembler::Branch(label);
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
if (rhs != no_reg) {
TurboAssembler::Branch(label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(label, cond, lhs, Operand(zero_reg));
}
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
Label true_label;
ori(dst, zero_reg, 0x1);
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
BAILOUT("emit_cond_jump");
}
if (rhs != no_reg) {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(zero_reg));
}
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
BAILOUT("emit_i32_set_cond");
bind(&true_label);
}
void LiftoffAssembler::StackCheck(Label* ool_code) { BAILOUT("StackCheck"); }
......
......@@ -173,24 +173,34 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
void LiftoffAssembler::emit_jump(Label* label) {
TurboAssembler::Branch(label);
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
if (rhs != no_reg) {
TurboAssembler::Branch(label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(label, cond, lhs, Operand(zero_reg));
}
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
Label true_label;
ori(dst, zero_reg, 0x1);
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
BAILOUT("emit_cond_jump");
}
if (rhs != no_reg) {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(zero_reg));
}
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
BAILOUT("emit_i32_set_cond");
bind(&true_label);
}
void LiftoffAssembler::StackCheck(Label* ool_code) { BAILOUT("StackCheck"); }
......
......@@ -138,23 +138,17 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
......
......@@ -138,23 +138,16 @@ UNIMPLEMENTED_FP_BINOP(f64_mul)
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_i32_test(Register reg) { BAILOUT("emit_i32_test"); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
BAILOUT("emit_i32_compare");
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
BAILOUT("emit_ptrsize_compare");
}
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
......
......@@ -549,23 +549,38 @@ void LiftoffAssembler::emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_i32_test(Register reg) { testl(reg, reg); }
void LiftoffAssembler::emit_i32_compare(Register lhs, Register rhs) {
cmpl(lhs, rhs);
}
void LiftoffAssembler::emit_ptrsize_compare(Register lhs, Register rhs) {
cmpp(lhs, rhs);
}
void LiftoffAssembler::emit_jump(Label* label) { jmp(label); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label) {
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
ValueType type, Register lhs,
Register rhs) {
if (rhs != no_reg) {
switch (type) {
case kWasmI32:
cmpl(lhs, rhs);
break;
case kWasmI64:
cmpq(lhs, rhs);
break;
default:
UNREACHABLE();
}
} else {
DCHECK_EQ(type, kWasmI32);
testl(lhs, lhs);
}
j(cond, label);
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst) {
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
if (rhs != no_reg) {
cmpl(lhs, rhs);
} else {
testl(lhs, lhs);
}
setcc(cond, dst);
movzxbl(dst, dst);
}
......
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