Commit c0f255f0 authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC: Work-around to preserve sNan bit

On ia32/x64 when casting a sNan to double, the signalling
bit is flipped to qNan.

R=joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N

Review-Url: https://codereview.chromium.org/2660873003
Cr-Commit-Position: refs/heads/master@{#42786}
parent e42da75c
......@@ -2346,8 +2346,23 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
DoubleRegister dst = destination->IsFPRegister()
? g.ToDoubleRegister(destination)
: kScratchDoubleReg;
double value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
: src.ToFloat64();
double value;
// bit_cast of snan is converted to qnan on ia32/x64
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
intptr_t valueInt = (src.type() == Constant::kFloat32)
? src.ToFloat32AsInt()
: src.ToFloat64AsInt();
if (valueInt == ((src.type() == Constant::kFloat32)
? 0x7fa00000
: 0x7fa0000000000000)) {
value = bit_cast<double, int64_t>(0x7ff4000000000000L);
} else {
#endif
value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
: src.ToFloat64();
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
}
#endif
__ LoadDoubleLiteral(dst, value, kScratchReg);
if (destination->IsFPStackSlot()) {
__ StoreDouble(dst, g.ToMemOperand(destination), r0);
......
......@@ -3681,7 +3681,6 @@ void MacroAssembler::MovIntToFloat(DoubleRegister dst, Register src) {
void MacroAssembler::MovFloatToInt(Register dst, DoubleRegister src) {
subi(sp, sp, Operand(kFloatSize));
frsp(src, src);
stfs(src, MemOperand(sp, 0));
nop(GROUP_ENDING_NOP); // LHS/RAW optimization
lwz(dst, MemOperand(sp, 0));
......
......@@ -3800,7 +3800,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
int32_t val = ReadW(ra_val + offset, instr);
float* fptr = reinterpret_cast<float*>(&val);
set_d_register_from_double(frt, static_cast<double>(*fptr));
// Conversion using double changes sNan to qNan on ia32/x64
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
if (val == 0x7fa00000) {
set_d_register(frt, 0x7ff4000000000000);
} else {
#endif
set_d_register_from_double(frt, static_cast<double>(*fptr));
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
}
#endif
if (opcode == LFSU) {
DCHECK(ra != 0);
set_register(ra, ra_val + offset);
......@@ -3830,7 +3839,19 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
int32_t offset = SIGN_EXT_IMM16(instr->Bits(15, 0));
intptr_t ra_val = ra == 0 ? 0 : get_register(ra);
float frs_val = static_cast<float>(get_double_from_d_register(frs));
int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
int32_t* p;
// Conversion using double changes sNan to qNan on ia32/x64
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
int64_t frs_isnan = get_d_register(frs);
int32_t frs_nan_single = 0x7fa00000;
if (frs_isnan == 0x7ff4000000000000) {
p = &frs_nan_single;
} else {
#endif
p = reinterpret_cast<int32_t*>(&frs_val);
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
}
#endif
WriteW(ra_val + offset, *p, instr);
if (opcode == STFSU) {
DCHECK(ra != 0);
......
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