Commit eb15bca2 authored by George Wort's avatar George Wort Committed by Commit Bot

[liftoff][arm] Implement Copy Sign

This implements copy sign for both the arm32 and arm64 port of Liftoff.

Bug: v8:6600
Change-Id: Ic822e75417c6b911a03e8e9a2d6d59a98fbc3d18
Reviewed-on: https://chromium-review.googlesource.com/c/1348430
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#57843}
parent 5ee0f009
......@@ -626,7 +626,6 @@ UNIMPLEMENTED_FP_UNOP(f32_floor)
UNIMPLEMENTED_FP_UNOP(f32_trunc)
UNIMPLEMENTED_FP_UNOP(f32_nearest_int)
UNIMPLEMENTED_FP_UNOP(f32_sqrt)
UNIMPLEMENTED_FP_BINOP(f64_copysign)
FP64_BINOP(f64_add, vadd)
FP64_BINOP(f64_sub, vsub)
FP64_BINOP(f64_mul, vmul)
......@@ -847,6 +846,26 @@ void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
// This is a nop on arm.
}
void LiftoffAssembler::emit_f64_copysign(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
constexpr uint32_t kF64SignBitHighWord = uint32_t{1} << 31;
// On arm, we cannot hold the whole f64 value in a gp register, so we just
// operate on the upper half (UH).
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
Register scratch2 = GetUnusedRegister(kGpReg).gp();
VmovHigh(scratch, lhs);
// Clear sign bit in {scratch}.
bic(scratch, scratch, Operand(kF64SignBitHighWord));
VmovHigh(scratch2, rhs);
// Isolate sign bit in {scratch2}.
and_(scratch2, scratch2, Operand(kF64SignBitHighWord));
// Combine {scratch2} into {scratch}.
orr(scratch, scratch, scratch2);
vmov(dst, lhs);
VmovHigh(dst, scratch);
}
bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode,
LiftoffRegister dst,
LiftoffRegister src, Label* trap) {
......
......@@ -628,12 +628,24 @@ void LiftoffAssembler::emit_i32_to_intptr(Register dst, Register src) {
void LiftoffAssembler::emit_f32_copysign(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
BAILOUT("f32_copysign");
UseScratchRegisterScope temps(this);
DoubleRegister scratch = temps.AcquireD();
Ushr(scratch.V2S(), rhs.V2S(), 31);
if (dst != lhs) {
Fmov(dst.S(), lhs.S());
}
Sli(dst.V2S(), scratch.V2S(), 31);
}
void LiftoffAssembler::emit_f64_copysign(DoubleRegister dst, DoubleRegister lhs,
DoubleRegister rhs) {
BAILOUT("f64_copysign");
UseScratchRegisterScope temps(this);
DoubleRegister scratch = temps.AcquireD();
Ushr(scratch.V1D(), rhs.V1D(), 63);
if (dst != lhs) {
Fmov(dst.D(), lhs.D());
}
Sli(dst.V1D(), scratch.V1D(), 63);
}
bool LiftoffAssembler::emit_type_conversion(WasmOpcode opcode,
......
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