Commit 994d2390 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Implement i64 comparisons

This adds support for i64.eqz, and all binary comparisons (i64.eq,
i64.ne, i64.lt_s, i64.le_s, i64.lt_u, i64.le_u, i64.gt_s, i64.ge_s,
i64.gt_u, i64.and i64.ge_u).

R=titzer@chromium.org

Bug: v8:6600
Change-Id: Ic6c59529b007220698e09d5959394bcfb6590173
Reviewed-on: https://chromium-review.googlesource.com/969125
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#52063}
parent 9f08fd92
......@@ -101,31 +101,31 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
#define UNIMPLEMENTED_GP_BINOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, \
Register rhs) { \
BAILOUT("gp binop"); \
BAILOUT("gp binop: " #name); \
}
#define UNIMPLEMENTED_GP_UNOP(name) \
bool LiftoffAssembler::emit_##name(Register dst, Register src) { \
BAILOUT("gp unop"); \
BAILOUT("gp unop: " #name); \
return true; \
}
#define UNIMPLEMENTED_FP_BINOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
BAILOUT("fp binop: " #name); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
BAILOUT("fp unop: " #name); \
}
#define UNIMPLEMENTED_I32_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i32 shiftop"); \
BAILOUT("i32 shiftop: " #name); \
}
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
BAILOUT("i64 shiftop: " #name); \
}
UNIMPLEMENTED_GP_BINOP(i32_add)
......@@ -181,11 +181,25 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
BAILOUT("emit_i32_eqz");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -101,31 +101,31 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
#define UNIMPLEMENTED_GP_BINOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, \
Register rhs) { \
BAILOUT("gp binop"); \
BAILOUT("gp binop: " #name); \
}
#define UNIMPLEMENTED_GP_UNOP(name) \
bool LiftoffAssembler::emit_##name(Register dst, Register src) { \
BAILOUT("gp unop"); \
BAILOUT("gp unop: " #name); \
return true; \
}
#define UNIMPLEMENTED_FP_BINOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
BAILOUT("fp binop: " #name); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
BAILOUT("fp unop: " #name); \
}
#define UNIMPLEMENTED_I32_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i32 shiftop"); \
BAILOUT("i32 shiftop: " #name); \
}
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
BAILOUT("i64 shiftop: " #name); \
}
UNIMPLEMENTED_GP_BINOP(i32_add)
......@@ -181,11 +181,25 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
BAILOUT("emit_i32_eqz");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -888,14 +888,69 @@ inline void setcc_32(LiftoffAssembler* assm, Condition cond, Register dst) {
}
} // namespace liftoff
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
test(src, src);
liftoff::setcc_32(this, equal, dst);
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
if (rhs != no_reg) {
cmp(lhs, rhs);
cmp(lhs, rhs);
liftoff::setcc_32(this, cond, dst);
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
// Compute the OR of both registers in the src pair, using dst as scratch
// register. Then check whether the result is equal to zero.
if (src.low_gp() == dst) {
or_(dst, src.high_gp());
} else {
test(lhs, lhs);
if (src.high_gp() != dst) mov(dst, src.high_gp());
or_(dst, src.low_gp());
}
liftoff::setcc_32(this, equal, dst);
}
namespace liftoff {
inline Condition cond_make_unsigned(Condition cond) {
switch (cond) {
case kSignedLessThan:
return kUnsignedLessThan;
case kSignedLessEqual:
return kUnsignedLessEqual;
case kSignedGreaterThan:
return kUnsignedGreaterThan;
case kSignedGreaterEqual:
return kUnsignedGreaterEqual;
default:
return cond;
}
}
} // namespace liftoff
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
// For signed i64 comparisons, we still need to use unsigned comparison for
// the low word (the only bit carrying signedness information is the MSB in
// the high word).
Condition unsigned_cond = liftoff::cond_make_unsigned(cond);
Label setcc;
Label cont;
// Compare high word first. If it differs, use if for the setcc. If it's
// equal, compare the low word and use that for setcc.
cmp(lhs.high_gp(), rhs.high_gp());
j(not_equal, &setcc, Label::kNear);
cmp(lhs.low_gp(), rhs.low_gp());
if (unsigned_cond != cond) {
// If the condition predicate for the low differs from that for the high
// word, emit a separete setcc sequence for the low word.
liftoff::setcc_32(this, unsigned_cond, dst);
jmp(&cont);
}
bind(&setcc);
liftoff::setcc_32(this, cond, dst);
bind(&cont);
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
......
......@@ -429,10 +429,14 @@ class LiftoffAssembler : public TurboAssembler {
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_eqz(Register dst, Register src);
inline void emit_i32_set_cond(Condition, Register dst, Register lhs,
Register rhs = no_reg);
inline void emit_f32_set_cond(Condition, Register dst, DoubleRegister lhs,
DoubleRegister rhs);
Register rhs);
inline void emit_i64_eqz(Register dst, LiftoffRegister src);
inline void emit_i64_set_cond(Condition condition, Register dst,
LiftoffRegister lhs, LiftoffRegister rhs);
inline void emit_f32_set_cond(Condition condition, Register dst,
DoubleRegister lhs, DoubleRegister rhs);
inline void StackCheck(Label* ool_code);
......
......@@ -548,14 +548,17 @@ class LiftoffCompiler {
}
}
template <ValueType type, class EmitFn>
template <ValueType src_type, ValueType result_type, class EmitFn>
void EmitUnOp(EmitFn fn) {
static RegClass rc = reg_class_for(type);
static RegClass src_rc = reg_class_for(src_type);
static RegClass result_rc = reg_class_for(result_type);
LiftoffRegList pinned;
LiftoffRegister src = pinned.set(__ PopToRegister(pinned));
LiftoffRegister dst = __ GetUnusedRegister(rc, {src}, pinned);
LiftoffRegister dst = src_rc == result_rc
? __ GetUnusedRegister(result_rc, {src}, pinned)
: __ GetUnusedRegister(result_rc, pinned);
fn(dst, src);
__ PushRegister(type, dst);
__ PushRegister(result_type, dst);
}
void EmitI32UnOpWithCFallback(bool (LiftoffAssembler::*emit_fn)(Register,
......@@ -568,7 +571,7 @@ class LiftoffCompiler {
FunctionSig sig_i_i(1, 1, sig_i_i_reps);
GenerateCCall(&dst, &sig_i_i, kWasmStmt, &src, ext_ref);
};
EmitUnOp<kWasmI32>(emit_with_c_fallback);
EmitUnOp<kWasmI32, kWasmI32>(emit_with_c_fallback);
}
void EmitTypeConversion(WasmOpcode opcode, ValueType dst_type,
......@@ -593,17 +596,19 @@ class LiftoffCompiler {
void UnOp(Decoder* decoder, WasmOpcode opcode, FunctionSig*,
const Value& value, Value* result) {
#define CASE_I32_UNOP(opcode, fn) \
case WasmOpcode::kExpr##opcode: \
EmitUnOp<kWasmI32>([=](LiftoffRegister dst, LiftoffRegister src) { \
__ emit_##fn(dst.gp(), src.gp()); \
}); \
#define CASE_I32_UNOP(opcode, fn) \
case WasmOpcode::kExpr##opcode: \
EmitUnOp<kWasmI32, kWasmI32>( \
[=](LiftoffRegister dst, LiftoffRegister src) { \
__ emit_##fn(dst.gp(), src.gp()); \
}); \
break;
#define CASE_FLOAT_UNOP(opcode, type, fn) \
case WasmOpcode::kExpr##opcode: \
EmitUnOp<kWasm##type>([=](LiftoffRegister dst, LiftoffRegister src) { \
__ emit_##fn(dst.fp(), src.fp()); \
}); \
#define CASE_FLOAT_UNOP(opcode, type, fn) \
case WasmOpcode::kExpr##opcode: \
EmitUnOp<kWasm##type, kWasm##type>( \
[=](LiftoffRegister dst, LiftoffRegister src) { \
__ emit_##fn(dst.fp(), src.fp()); \
}); \
break;
#define CASE_TYPE_CONVERSION(opcode, dst_type, src_type, ext_ref) \
case WasmOpcode::kExpr##opcode: \
......@@ -611,44 +616,46 @@ class LiftoffCompiler {
ext_ref); \
break;
switch (opcode) {
CASE_I32_UNOP(I32Eqz, i32_eqz)
CASE_I32_UNOP(I32Clz, i32_clz)
CASE_I32_UNOP(I32Ctz, i32_ctz)
CASE_FLOAT_UNOP(F32Abs, F32, f32_abs)
CASE_FLOAT_UNOP(F32Neg, F32, f32_neg)
CASE_FLOAT_UNOP(F32Sqrt, F32, f32_sqrt)
CASE_FLOAT_UNOP(F64Abs, F64, f64_abs)
CASE_FLOAT_UNOP(F64Neg, F64, f64_neg)
CASE_FLOAT_UNOP(F64Sqrt, F64, f64_sqrt)
CASE_TYPE_CONVERSION(I32ConvertI64, I32, I64, nullptr)
CASE_TYPE_CONVERSION(I32ReinterpretF32, I32, F32, nullptr)
CASE_TYPE_CONVERSION(I64SConvertI32, I64, I32, nullptr)
CASE_TYPE_CONVERSION(I64UConvertI32, I64, I32, nullptr)
CASE_TYPE_CONVERSION(I64ReinterpretF64, I64, F64, nullptr)
CASE_TYPE_CONVERSION(F32SConvertI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F32UConvertI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F32SConvertI64, F32, I64,
&ExternalReference::wasm_int64_to_float32)
CASE_TYPE_CONVERSION(F32UConvertI64, F32, I64,
&ExternalReference::wasm_uint64_to_float32)
CASE_TYPE_CONVERSION(F32ConvertF64, F32, F64, nullptr)
CASE_TYPE_CONVERSION(F32ReinterpretI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F64SConvertI32, F64, I32, nullptr)
CASE_TYPE_CONVERSION(F64UConvertI32, F64, I32, nullptr)
CASE_TYPE_CONVERSION(F64SConvertI64, F64, I64,
&ExternalReference::wasm_int64_to_float64)
CASE_TYPE_CONVERSION(F64UConvertI64, F64, I64,
&ExternalReference::wasm_uint64_to_float64)
CASE_TYPE_CONVERSION(F64ConvertF32, F64, F32, nullptr)
CASE_TYPE_CONVERSION(F64ReinterpretI64, F64, I64, nullptr)
case kExprI32Popcnt:
EmitI32UnOpWithCFallback(&LiftoffAssembler::emit_i32_popcnt,
&ExternalReference::wasm_word32_popcnt);
break;
case kExprI32Eqz:
EmitUnOp<kWasmI32>([=](LiftoffRegister dst, LiftoffRegister src) {
__ emit_i32_set_cond(kEqual, dst.gp(), src.gp());
});
case WasmOpcode::kExprI64Eqz:
EmitUnOp<kWasmI64, kWasmI32>(
[=](LiftoffRegister dst, LiftoffRegister src) {
__ emit_i64_eqz(dst.gp(), src);
});
break;
CASE_FLOAT_UNOP(F32Abs, F32, f32_abs)
CASE_FLOAT_UNOP(F32Neg, F32, f32_neg)
CASE_FLOAT_UNOP(F32Sqrt, F32, f32_sqrt)
CASE_FLOAT_UNOP(F64Abs, F64, f64_abs)
CASE_FLOAT_UNOP(F64Neg, F64, f64_neg)
CASE_FLOAT_UNOP(F64Sqrt, F64, f64_sqrt)
CASE_TYPE_CONVERSION(I32ConvertI64, I32, I64, nullptr)
CASE_TYPE_CONVERSION(I32ReinterpretF32, I32, F32, nullptr)
CASE_TYPE_CONVERSION(I64SConvertI32, I64, I32, nullptr)
CASE_TYPE_CONVERSION(I64UConvertI32, I64, I32, nullptr)
CASE_TYPE_CONVERSION(I64ReinterpretF64, I64, F64, nullptr)
CASE_TYPE_CONVERSION(F32SConvertI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F32UConvertI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F32SConvertI64, F32, I64,
&ExternalReference::wasm_int64_to_float32)
CASE_TYPE_CONVERSION(F32UConvertI64, F32, I64,
&ExternalReference::wasm_uint64_to_float32)
CASE_TYPE_CONVERSION(F32ConvertF64, F32, F64, nullptr)
CASE_TYPE_CONVERSION(F32ReinterpretI32, F32, I32, nullptr)
CASE_TYPE_CONVERSION(F64SConvertI32, F64, I32, nullptr)
CASE_TYPE_CONVERSION(F64UConvertI32, F64, I32, nullptr)
CASE_TYPE_CONVERSION(F64SConvertI64, F64, I64,
&ExternalReference::wasm_int64_to_float64)
CASE_TYPE_CONVERSION(F64UConvertI64, F64, I64,
&ExternalReference::wasm_uint64_to_float64)
CASE_TYPE_CONVERSION(F64ConvertF32, F64, F32, nullptr)
CASE_TYPE_CONVERSION(F64ReinterpretI64, F64, I64, nullptr)
default:
return unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
}
......@@ -692,6 +699,12 @@ class LiftoffCompiler {
[=](LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
__ emit_i32_set_cond(cond, dst.gp(), lhs.gp(), rhs.gp()); \
});
#define CASE_I64_CMPOP(opcode, cond) \
case WasmOpcode::kExpr##opcode: \
return EmitBinOp<kWasmI64, kWasmI32>( \
[=](LiftoffRegister dst, LiftoffRegister lhs, LiftoffRegister rhs) { \
__ emit_i64_set_cond(cond, dst.gp(), lhs, rhs); \
});
#define CASE_F32_CMPOP(opcode, cond) \
case WasmOpcode::kExpr##opcode: \
return EmitBinOp<kWasmF32, kWasmI32>( \
......@@ -739,6 +752,16 @@ class LiftoffCompiler {
CASE_I32_CMPOP(I32LeU, kUnsignedLessEqual)
CASE_I32_CMPOP(I32GeS, kSignedGreaterEqual)
CASE_I32_CMPOP(I32GeU, kUnsignedGreaterEqual)
CASE_I64_CMPOP(I64Eq, kEqual)
CASE_I64_CMPOP(I64Ne, kUnequal)
CASE_I64_CMPOP(I64LtS, kSignedLessThan)
CASE_I64_CMPOP(I64LtU, kUnsignedLessThan)
CASE_I64_CMPOP(I64GtS, kSignedGreaterThan)
CASE_I64_CMPOP(I64GtU, kUnsignedGreaterThan)
CASE_I64_CMPOP(I64LeS, kSignedLessEqual)
CASE_I64_CMPOP(I64LeU, kUnsignedLessEqual)
CASE_I64_CMPOP(I64GeS, kSignedGreaterEqual)
CASE_I64_CMPOP(I64GeU, kUnsignedGreaterEqual)
CASE_F32_CMPOP(F32Eq, kEqual)
CASE_F32_CMPOP(F32Ne, kUnequal)
CASE_F32_CMPOP(F32Lt, kUnsignedLessThan)
......@@ -767,6 +790,7 @@ class LiftoffCompiler {
#undef CASE_I32_BINOP
#undef CASE_FLOAT_BINOP
#undef CASE_I32_CMPOP
#undef CASE_I64_CMPOP
#undef CASE_F32_CMPOP
#undef CASE_I32_SHIFTOP
#undef CASE_I64_SHIFTOP
......
......@@ -502,6 +502,28 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
}
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
Label true_label;
if (dst != src) {
ori(dst, zero_reg, 0x1);
}
TurboAssembler::Branch(&true_label, eq, src, Operand(zero_reg));
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
if (dst != src) {
bind(&true_label);
} else {
Label end_label;
TurboAssembler::Branch(&end_label);
bind(&true_label);
ori(dst, zero_reg, 0x1);
bind(&end_label);
}
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
Label true_label;
......@@ -509,11 +531,7 @@ void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
ori(dst, zero_reg, 0x1);
}
if (rhs != no_reg) {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(zero_reg));
}
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
......@@ -529,6 +547,16 @@ void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
}
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -449,6 +449,28 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
}
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
Label true_label;
if (dst != src) {
ori(dst, zero_reg, 0x1);
}
TurboAssembler::Branch(&true_label, eq, src, Operand(zero_reg));
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
if (dst != src) {
bind(&true_label);
} else {
Label end_label;
TurboAssembler::Branch(&end_label);
bind(&true_label);
ori(dst, zero_reg, 0x1);
bind(&end_label);
}
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
Label true_label;
......@@ -456,11 +478,7 @@ void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
ori(dst, zero_reg, 0x1);
}
if (rhs != no_reg) {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
} else {
TurboAssembler::Branch(&true_label, cond, lhs, Operand(zero_reg));
}
TurboAssembler::Branch(&true_label, cond, lhs, Operand(rhs));
// If not true, set on 0.
TurboAssembler::mov(dst, zero_reg);
......@@ -476,6 +494,16 @@ void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
}
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -101,31 +101,31 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
#define UNIMPLEMENTED_GP_BINOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, \
Register rhs) { \
BAILOUT("gp binop"); \
BAILOUT("gp binop: " #name); \
}
#define UNIMPLEMENTED_GP_UNOP(name) \
bool LiftoffAssembler::emit_##name(Register dst, Register src) { \
BAILOUT("gp unop"); \
BAILOUT("gp unop: " #name); \
return true; \
}
#define UNIMPLEMENTED_FP_BINOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
BAILOUT("fp binop: " #name); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
BAILOUT("fp unop: " #name); \
}
#define UNIMPLEMENTED_I32_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i32 shiftop"); \
BAILOUT("i32 shiftop: " #name); \
}
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
BAILOUT("i64 shiftop: " #name); \
}
UNIMPLEMENTED_GP_BINOP(i32_add)
......@@ -181,11 +181,25 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
BAILOUT("emit_i32_eqz");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -101,31 +101,31 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
#define UNIMPLEMENTED_GP_BINOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, \
Register rhs) { \
BAILOUT("gp binop"); \
BAILOUT("gp binop: " #name); \
}
#define UNIMPLEMENTED_GP_UNOP(name) \
bool LiftoffAssembler::emit_##name(Register dst, Register src) { \
BAILOUT("gp unop"); \
BAILOUT("gp unop: " #name); \
return true; \
}
#define UNIMPLEMENTED_FP_BINOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister lhs, \
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
BAILOUT("fp binop: " #name); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
BAILOUT("fp unop: " #name); \
}
#define UNIMPLEMENTED_I32_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i32 shiftop"); \
BAILOUT("i32 shiftop: " #name); \
}
#define UNIMPLEMENTED_I64_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(LiftoffRegister dst, LiftoffRegister src, \
Register amount, LiftoffRegList pinned) { \
BAILOUT("i64 shiftop"); \
BAILOUT("i64 shiftop: " #name); \
}
UNIMPLEMENTED_GP_BINOP(i32_add)
......@@ -181,11 +181,25 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
BAILOUT("emit_cond_jump");
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
BAILOUT("emit_i32_eqz");
}
void LiftoffAssembler::emit_i32_set_cond(Condition cond, Register dst,
Register lhs, Register rhs) {
BAILOUT("emit_i32_set_cond");
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
BAILOUT("emit_i64_eqz");
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
BAILOUT("emit_i64_set_cond");
}
void LiftoffAssembler::emit_f32_set_cond(Condition cond, Register dst,
DoubleRegister lhs,
DoubleRegister rhs) {
......
......@@ -775,14 +775,29 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
j(cond, label);
}
void LiftoffAssembler::emit_i32_eqz(Register dst, Register src) {
testl(src, src);
setcc(equal, dst);
movzxbl(dst, 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);
}
cmpl(lhs, rhs);
setcc(cond, dst);
movzxbl(dst, dst);
}
void LiftoffAssembler::emit_i64_eqz(Register dst, LiftoffRegister src) {
testq(src.gp(), src.gp());
setcc(equal, dst);
movzxbl(dst, dst);
}
void LiftoffAssembler::emit_i64_set_cond(Condition cond, Register dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
cmpq(lhs.gp(), rhs.gp());
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