PPC: fix signaling nan issue in simulator and fix disassembler

R=joransiu@ca.ibm.com, jbarboza@ca.ibm.com

Bug: 
Change-Id: I5d81c14c658af7e8fb5054e147aada9999fbde0c
Reviewed-on: https://chromium-review.googlesource.com/737440
Reviewed-by: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: Joran Siu <joransiu@ca.ibm.com>
Commit-Queue: Joran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#48948}
This commit is contained in:
Junliang Yan 2017-10-25 17:56:23 -04:00 committed by Commit Bot
parent 82ee3bcad0
commit 9d59a32b36
2 changed files with 30 additions and 4 deletions

View File

@ -601,19 +601,19 @@ void Decoder::DecodeExt2(Instruction* instr) {
return;
}
case LFSX: {
Format(instr, "lfsx 'rt, 'ra, 'rb");
Format(instr, "lfsx 'Dt, 'ra, 'rb");
return;
}
case LFSUX: {
Format(instr, "lfsux 'rt, 'ra, 'rb");
Format(instr, "lfsux 'Dt, 'ra, 'rb");
return;
}
case LFDX: {
Format(instr, "lfdx 'rt, 'ra, 'rb");
Format(instr, "lfdx 'Dt, 'ra, 'rb");
return;
}
case LFDUX: {
Format(instr, "lfdux 'rt, 'ra, 'rb");
Format(instr, "lfdux 'Dt, 'ra, 'rb");
return;
}
case STFSX: {

View File

@ -2242,7 +2242,19 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
intptr_t rb_val = get_register(rb);
int32_t val = ReadW(ra_val + rb_val, instr);
float* fptr = reinterpret_cast<float*>(&val);
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
// Conversion using double changes sNan to qNan on ia32/x64
if ((val & 0x7f800000) == 0x7f800000) {
int64_t dval = static_cast<int64_t>(val);
dval = ((dval & 0xc0000000) << 32) | ((dval & 0x40000000) << 31) |
((dval & 0x40000000) << 30) | ((dval & 0x7fffffff) << 29) | 0x0;
set_d_register(frt, dval);
} else {
set_d_register_from_double(frt, static_cast<double>(*fptr));
}
#else
set_d_register_from_double(frt, static_cast<double>(*fptr));
#endif
if (opcode == LFSUX) {
DCHECK_NE(ra, 0);
set_register(ra, ra_val + rb_val);
@ -2273,6 +2285,20 @@ void Simulator::ExecuteGeneric(Instruction* instr) {
intptr_t rb_val = get_register(rb);
float frs_val = static_cast<float>(get_double_from_d_register(frs));
int32_t* p = reinterpret_cast<int32_t*>(&frs_val);
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
// Conversion using double changes sNan to qNan on ia32/x64
int32_t sval = 0;
int64_t dval = get_d_register(frs);
if ((dval & 0x7ff0000000000000) == 0x7ff0000000000000) {
sval = ((dval & 0xc000000000000000) >> 32) |
((dval & 0x07ffffffe0000000) >> 29);
p = &sval;
} else {
p = reinterpret_cast<int32_t*>(&frs_val);
}
#else
p = reinterpret_cast<int32_t*>(&frs_val);
#endif
WriteW(ra_val + rb_val, *p, instr);
if (opcode == STFSUX) {
DCHECK_NE(ra, 0);