Index: src/compiler/ppc/code-generator-ppc.cc |
diff --git a/src/compiler/ppc/code-generator-ppc.cc b/src/compiler/ppc/code-generator-ppc.cc |
index 550cb230a947f17681484e2c53bd7ec347afdbe8..60b73aee8127bbc498ba0d74ba1e1df0c749c741 100644 |
--- a/src/compiler/ppc/code-generator-ppc.cc |
+++ b/src/compiler/ppc/code-generator-ppc.cc |
@@ -1191,18 +1191,27 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
#if V8_TARGET_ARCH_PPC64 |
case kPPC_DoubleToUint64: { |
bool check_conversion = (i.OutputCount() > 1); |
+ Label done; |
if (check_conversion) { |
+ // Set 2nd output to zero if conversion fails. |
+ // We must check explicitly for negative values here since the |
+ // conversion instruction rounds the input toward zero before |
+ // checking for validity (otherwise, values between -1 and 0 |
+ // would produce incorrect results). |
+ __ li(i.OutputRegister(1), Operand::Zero()); |
+ __ fcmpu(i.InputDoubleRegister(0), kDoubleRegZero); |
+ __ blt(&done); |
__ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit |
} |
__ ConvertDoubleToUnsignedInt64(i.InputDoubleRegister(0), |
i.OutputRegister(0), kScratchDoubleReg); |
if (check_conversion) { |
- // Set 2nd output to zero if conversion fails. |
CRBit crbit = static_cast<CRBit>(VXCVI % CRWIDTH); |
__ mcrfs(cr7, VXCVI); // extract FPSCR field containing VXCVI into cr7 |
__ li(i.OutputRegister(1), Operand(1)); |
__ isel(i.OutputRegister(1), r0, i.OutputRegister(1), |
v8::internal::Assembler::encode_crbit(cr7, crbit)); |
+ __ bind(&done); |
} |
DCHECK_EQ(LeaveRC, i.OutputRCBit()); |
break; |