Commit 3e08654d authored by sreten.kovacevic's avatar sreten.kovacevic Committed by Commit Bot

[mips] Add FPURegister Move with uint argument

Refactor existing and add new Move instructions that get uint32_t
and uint64_t to prevent compiler to set quiet-nan on passing
float and double by value.

Change-Id: I544e98e1bb288666140a3b1d2437b31d9e36ca55
Reviewed-on: https://chromium-review.googlesource.com/928722
Commit-Queue: Sreten Kovacevic <sreten.kovacevic@mips.com>
Reviewed-by: 's avatarClemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarIvica Bogosavljevic <ivica.bogosavljevic@mips.com>
Cr-Commit-Position: refs/heads/master@{#51439}
parent 0d872514
......@@ -2498,15 +2498,6 @@ void Assembler::cfc1(Register rt, FPUControlRegister fs) {
}
void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
uint64_t i;
memcpy(&i, &d, 8);
*lo = i & 0xFFFFFFFF;
*hi = i >> 32;
}
void Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) {
DCHECK(!IsMipsArchVariant(kMips32r6));
GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C);
......
......@@ -1891,8 +1891,6 @@ class Assembler : public AssemblerBase {
return internal_trampoline_exception_;
}
void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
bool is_trampoline_emitted() const {
return trampoline_emitted_;
}
......
......@@ -2173,23 +2173,22 @@ void TurboAssembler::FmoveLow(FPURegister dst, Register src_low) {
}
}
void TurboAssembler::Move(FPURegister dst, float imm) {
void TurboAssembler::Move(FPURegister dst, uint32_t src) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
li(scratch, Operand(bit_cast<int32_t>(imm)));
li(scratch, Operand(static_cast<int32_t>(src)));
mtc1(scratch, dst);
}
void TurboAssembler::Move(FPURegister dst, double imm) {
int64_t imm_bits = bit_cast<int64_t>(imm);
void TurboAssembler::Move(FPURegister dst, uint64_t src) {
// Handle special values first.
if (imm_bits == bit_cast<int64_t>(0.0) && has_double_zero_reg_set_) {
if (src == bit_cast<uint64_t>(0.0) && has_double_zero_reg_set_) {
mov_d(dst, kDoubleRegZero);
} else if (imm_bits == bit_cast<int64_t>(-0.0) && has_double_zero_reg_set_) {
} else if (src == bit_cast<uint64_t>(-0.0) && has_double_zero_reg_set_) {
Neg_d(dst, kDoubleRegZero);
} else {
uint32_t lo, hi;
DoubleAsTwoUInt32(imm, &lo, &hi);
uint32_t lo = src & 0xFFFFFFFF;
uint32_t hi = src >> 32;
// Move the low part of the double into the lower of the corresponding FPU
// register of FPU register pair.
if (lo != 0) {
......
......@@ -736,8 +736,10 @@ class TurboAssembler : public Assembler {
Mthc1(src_high, dst);
}
void Move(FPURegister dst, float imm);
void Move(FPURegister dst, double imm);
void Move(FPURegister dst, float imm) { Move(dst, bit_cast<uint32_t>(imm)); }
void Move(FPURegister dst, double imm) { Move(dst, bit_cast<uint64_t>(imm)); }
void Move(FPURegister dst, uint32_t src);
void Move(FPURegister dst, uint64_t src);
// -------------------------------------------------------------------------
// Overflow handling functions.
......
......@@ -2899,15 +2899,6 @@ void Assembler::cfc1(Register rt, FPUControlRegister fs) {
}
void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
uint64_t i;
memcpy(&i, &d, 8);
*lo = i & 0xFFFFFFFF;
*hi = i >> 32;
}
void Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
FPURegister ft) {
DCHECK_EQ(kArchVariant, kMips64r6);
......
......@@ -1960,8 +1960,6 @@ class Assembler : public AssemblerBase {
return internal_trampoline_exception_;
}
void DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi);
bool is_trampoline_emitted() const {
return trampoline_emitted_;
}
......
......@@ -2704,39 +2704,38 @@ void TurboAssembler::FmoveLow(FPURegister dst, Register src_low) {
mthc1(scratch, dst);
}
void TurboAssembler::Move(FPURegister dst, float imm) {
void TurboAssembler::Move(FPURegister dst, uint32_t src) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
li(scratch, Operand(bit_cast<int32_t>(imm)));
li(scratch, Operand(static_cast<int32_t>(src)));
mtc1(scratch, dst);
}
void TurboAssembler::Move(FPURegister dst, double imm) {
int64_t imm_bits = bit_cast<int64_t>(imm);
void TurboAssembler::Move(FPURegister dst, uint64_t src) {
// Handle special values first.
if (imm_bits == bit_cast<int64_t>(0.0) && has_double_zero_reg_set_) {
if (src == bit_cast<uint64_t>(0.0) && has_double_zero_reg_set_) {
mov_d(dst, kDoubleRegZero);
} else if (imm_bits == bit_cast<int64_t>(-0.0) && has_double_zero_reg_set_) {
} else if (src == bit_cast<uint64_t>(-0.0) && has_double_zero_reg_set_) {
Neg_d(dst, kDoubleRegZero);
} else {
uint32_t lo, hi;
DoubleAsTwoUInt32(imm, &lo, &hi);
// Move the low part of the double into the lower bits of the corresponding
// FPU register.
uint32_t lo = src & 0xFFFFFFFF;
uint32_t hi = src >> 32;
// Move the low part of the double into the lower of the corresponding FPU
// register of FPU register pair.
if (lo != 0) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
li(scratch, lo);
li(scratch, Operand(lo));
mtc1(scratch, dst);
} else {
mtc1(zero_reg, dst);
}
// Move the high part of the double into the high bits of the corresponding
// FPU register.
// Move the high part of the double into the higher of the corresponding FPU
// register of FPU register pair.
if (hi != 0) {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
li(scratch, hi);
li(scratch, Operand(hi));
mthc1(scratch, dst);
} else {
mthc1(zero_reg, dst);
......
......@@ -751,8 +751,10 @@ class TurboAssembler : public Assembler {
}
}
void Move(FPURegister dst, float imm);
void Move(FPURegister dst, double imm);
void Move(FPURegister dst, float imm) { Move(dst, bit_cast<uint32_t>(imm)); }
void Move(FPURegister dst, double imm) { Move(dst, bit_cast<uint64_t>(imm)); }
void Move(FPURegister dst, uint32_t src);
void Move(FPURegister dst, uint64_t src);
inline void MulBranchOvf(Register dst, Register left, const Operand& right,
Label* overflow_label, Register scratch = at) {
......
......@@ -55,10 +55,10 @@ void LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value,
break;
}
case kWasmF32:
TurboAssembler::Move(reg.fp(), value.to_f32_boxed().get_scalar());
TurboAssembler::Move(reg.fp(), value.to_f32_boxed().get_bits());
break;
case kWasmF64:
TurboAssembler::Move(reg.fp(), value.to_f64_boxed().get_scalar());
TurboAssembler::Move(reg.fp(), value.to_f64_boxed().get_bits());
break;
default:
UNREACHABLE();
......
......@@ -50,10 +50,10 @@ void LiftoffAssembler::LoadConstant(LiftoffRegister reg, WasmValue value,
TurboAssembler::li(reg.gp(), Operand(value.to_i64(), rmode));
break;
case kWasmF32:
TurboAssembler::Move(reg.fp(), value.to_f32_boxed().get_scalar());
TurboAssembler::Move(reg.fp(), value.to_f32_boxed().get_bits());
break;
case kWasmF64:
TurboAssembler::Move(reg.fp(), value.to_f64_boxed().get_scalar());
TurboAssembler::Move(reg.fp(), value.to_f64_boxed().get_bits());
break;
default:
UNREACHABLE();
......
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