Commit b12f8d21 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Implement f32.neg and f64.neg

This adds support for f32.neg and f64.neg. Note that this cannot be
computed as "0 - src", as this would not turn 0 into -0. Instead, we
need to explicitly flip the sign bit.

R=ahaas@chromium.org

Bug: v8:6600
Change-Id: I3cbcfa156c5d2a727e0e2da279369bf055f0d657
Reviewed-on: https://chromium-review.googlesource.com/937202Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#51601}
parent c7430e8d
......@@ -113,6 +113,10 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
#define UNIMPLEMENTED_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, Register rhs, \
LiftoffRegList pinned) { \
......@@ -135,13 +139,16 @@ UNIMPLEMENTED_GP_BINOP(ptrsize_add)
UNIMPLEMENTED_FP_BINOP(f32_add)
UNIMPLEMENTED_FP_BINOP(f32_sub)
UNIMPLEMENTED_FP_BINOP(f32_mul)
UNIMPLEMENTED_FP_UNOP(f32_neg)
UNIMPLEMENTED_FP_BINOP(f64_add)
UNIMPLEMENTED_FP_BINOP(f64_sub)
UNIMPLEMENTED_FP_BINOP(f64_mul)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef UNIMPLEMENTED_GP_BINOP
#undef UNIMPLEMENTED_GP_UNOP
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_FP_UNOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
......
......@@ -113,6 +113,10 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
#define UNIMPLEMENTED_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, Register rhs, \
LiftoffRegList pinned) { \
......@@ -135,13 +139,16 @@ UNIMPLEMENTED_GP_BINOP(ptrsize_add)
UNIMPLEMENTED_FP_BINOP(f32_add)
UNIMPLEMENTED_FP_BINOP(f32_sub)
UNIMPLEMENTED_FP_BINOP(f32_mul)
UNIMPLEMENTED_FP_UNOP(f32_neg)
UNIMPLEMENTED_FP_BINOP(f64_add)
UNIMPLEMENTED_FP_BINOP(f64_sub)
UNIMPLEMENTED_FP_BINOP(f64_mul)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef UNIMPLEMENTED_GP_BINOP
#undef UNIMPLEMENTED_GP_UNOP
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_FP_UNOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
......
......@@ -587,6 +587,17 @@ void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_f32_neg(DoubleRegister dst, DoubleRegister src) {
static constexpr uint32_t kSignBit = uint32_t{1} << 31;
if (dst == src) {
TurboAssembler::Move(kScratchDoubleReg, kSignBit);
Xorps(dst, kScratchDoubleReg);
} else {
TurboAssembler::Move(dst, kSignBit);
Xorps(dst, src);
}
}
void LiftoffAssembler::emit_f64_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
if (CpuFeatures::IsSupported(AVX)) {
......@@ -628,6 +639,17 @@ void LiftoffAssembler::emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_f64_neg(DoubleRegister dst, DoubleRegister src) {
static constexpr uint64_t kSignBit = uint64_t{1} << 63;
if (dst == src) {
TurboAssembler::Move(kScratchDoubleReg, kSignBit);
Xorpd(dst, kScratchDoubleReg);
} else {
TurboAssembler::Move(dst, kSignBit);
Xorpd(dst, src);
}
}
void LiftoffAssembler::emit_jump(Label* label) { jmp(label); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
......
......@@ -373,12 +373,17 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_ptrsize_add(Register dst, Register lhs, Register rhs);
// f32 binops.
inline void emit_f32_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
inline void emit_f32_sub(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
inline void emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
// f32 unops.
inline void emit_f32_neg(DoubleRegister dst, DoubleRegister src);
// f64 binops.
inline void emit_f64_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
inline void emit_f64_sub(DoubleRegister dst, DoubleRegister lhs,
......@@ -386,6 +391,9 @@ class LiftoffAssembler : public TurboAssembler {
inline void emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs);
// f64 unops.
inline void emit_f64_neg(DoubleRegister dst, DoubleRegister src);
inline void emit_jump(Label*);
inline void emit_cond_jump(Condition, Label*, ValueType value, Register lhs,
Register rhs = no_reg);
......
......@@ -542,6 +542,12 @@ class LiftoffCompiler {
__ 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()); \
}); \
break;
switch (opcode) {
CASE_I32_UNOP(I32Clz, i32_clz)
CASE_I32_UNOP(I32Ctz, i32_ctz)
......@@ -554,10 +560,13 @@ class LiftoffCompiler {
__ emit_i32_set_cond(kEqual, dst.gp(), src.gp());
});
break;
CASE_FLOAT_UNOP(F32Neg, F32, f32_neg)
CASE_FLOAT_UNOP(F64Neg, F64, f64_neg)
default:
return unsupported(decoder, WasmOpcodes::OpcodeName(opcode));
}
#undef CASE_I32_UNOP
#undef CASE_FLOAT_UNOP
}
template <ValueType type, typename EmitFn>
......
......@@ -317,15 +317,22 @@ I32_SHIFTOP(shr, srlv)
DoubleRegister rhs) { \
instruction(dst, lhs, rhs); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
FP_BINOP(f32_add, add_s)
FP_BINOP(f32_sub, sub_s)
FP_BINOP(f32_mul, mul_s)
UNIMPLEMENTED_FP_UNOP(f32_neg)
FP_BINOP(f64_add, add_d)
FP_BINOP(f64_sub, sub_d)
FP_BINOP(f64_mul, mul_d)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef FP_BINOP
#undef UNIMPLEMENTED_FP_BINOP
void LiftoffAssembler::emit_jump(Label* label) {
TurboAssembler::Branch(label);
......
......@@ -276,15 +276,22 @@ I32_SHIFTOP(shr, srlv)
DoubleRegister rhs) { \
instruction(dst, lhs, rhs); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
FP_BINOP(f32_add, add_s)
FP_BINOP(f32_sub, sub_s)
FP_BINOP(f32_mul, mul_s)
UNIMPLEMENTED_FP_UNOP(f32_neg)
FP_BINOP(f64_add, add_d)
FP_BINOP(f64_sub, sub_d)
FP_BINOP(f64_mul, mul_d)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef FP_BINOP
#undef UNIMPLEMENTED_FP_BINOP
void LiftoffAssembler::emit_jump(Label* label) {
TurboAssembler::Branch(label);
......@@ -354,7 +361,7 @@ void LiftoffAssembler::PopRegisters(LiftoffRegList regs) {
}
void LiftoffAssembler::DropStackSlotsAndRet(uint32_t num_stack_slots) {
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize);
DCHECK_LT(num_stack_slots, (1 << 16) / kPointerSize); // 16 bit immediate
TurboAssembler::DropAndRet(static_cast<int>(num_stack_slots * kPointerSize));
}
......
......@@ -113,6 +113,10 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
#define UNIMPLEMENTED_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, Register rhs, \
LiftoffRegList pinned) { \
......@@ -135,13 +139,16 @@ UNIMPLEMENTED_GP_BINOP(ptrsize_add)
UNIMPLEMENTED_FP_BINOP(f32_add)
UNIMPLEMENTED_FP_BINOP(f32_sub)
UNIMPLEMENTED_FP_BINOP(f32_mul)
UNIMPLEMENTED_FP_UNOP(f32_neg)
UNIMPLEMENTED_FP_BINOP(f64_add)
UNIMPLEMENTED_FP_BINOP(f64_sub)
UNIMPLEMENTED_FP_BINOP(f64_mul)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef UNIMPLEMENTED_GP_BINOP
#undef UNIMPLEMENTED_GP_UNOP
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_FP_UNOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
......
......@@ -113,6 +113,10 @@ void LiftoffAssembler::FillI64Half(Register, uint32_t half_index) {
DoubleRegister rhs) { \
BAILOUT("fp binop"); \
}
#define UNIMPLEMENTED_FP_UNOP(name) \
void LiftoffAssembler::emit_##name(DoubleRegister dst, DoubleRegister src) { \
BAILOUT("fp unop"); \
}
#define UNIMPLEMENTED_SHIFTOP(name) \
void LiftoffAssembler::emit_##name(Register dst, Register lhs, Register rhs, \
LiftoffRegList pinned) { \
......@@ -135,13 +139,16 @@ UNIMPLEMENTED_GP_BINOP(ptrsize_add)
UNIMPLEMENTED_FP_BINOP(f32_add)
UNIMPLEMENTED_FP_BINOP(f32_sub)
UNIMPLEMENTED_FP_BINOP(f32_mul)
UNIMPLEMENTED_FP_UNOP(f32_neg)
UNIMPLEMENTED_FP_BINOP(f64_add)
UNIMPLEMENTED_FP_BINOP(f64_sub)
UNIMPLEMENTED_FP_BINOP(f64_mul)
UNIMPLEMENTED_FP_UNOP(f64_neg)
#undef UNIMPLEMENTED_GP_BINOP
#undef UNIMPLEMENTED_GP_UNOP
#undef UNIMPLEMENTED_FP_BINOP
#undef UNIMPLEMENTED_FP_UNOP
#undef UNIMPLEMENTED_SHIFTOP
void LiftoffAssembler::emit_jump(Label* label) { BAILOUT("emit_jump"); }
......
......@@ -520,6 +520,17 @@ void LiftoffAssembler::emit_f32_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_f32_neg(DoubleRegister dst, DoubleRegister src) {
static constexpr uint32_t kSignBit = uint32_t{1} << 31;
if (dst == src) {
TurboAssembler::Move(kScratchDoubleReg, kSignBit);
Xorps(dst, kScratchDoubleReg);
} else {
TurboAssembler::Move(dst, kSignBit);
Xorps(dst, src);
}
}
void LiftoffAssembler::emit_f64_add(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
if (CpuFeatures::IsSupported(AVX)) {
......@@ -561,6 +572,17 @@ void LiftoffAssembler::emit_f64_mul(DoubleRegister dst, DoubleRegister lhs,
}
}
void LiftoffAssembler::emit_f64_neg(DoubleRegister dst, DoubleRegister src) {
static constexpr uint64_t kSignBit = uint64_t{1} << 63;
if (dst == src) {
TurboAssembler::Move(kScratchDoubleReg, kSignBit);
Xorpd(dst, kScratchDoubleReg);
} else {
TurboAssembler::Move(dst, kSignBit);
Xorpd(dst, src);
}
}
void LiftoffAssembler::emit_jump(Label* label) { jmp(label); }
void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
......
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