diff --git a/src/compiler/backend/ppc/code-generator-ppc.cc b/src/compiler/backend/ppc/code-generator-ppc.cc index a6350e96fb..b065060704 100644 --- a/src/compiler/backend/ppc/code-generator-ppc.cc +++ b/src/compiler/backend/ppc/code-generator-ppc.cc @@ -1851,6 +1851,20 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( i.OutputDoubleRegister()); DCHECK_EQ(LeaveRC, i.OutputRCBit()); break; + case kPPC_Float32ToInt32: { + __ mtfsb0(VXCVI); // clear FPSCR:VXCVI bit + __ fctiwz(kScratchDoubleReg, i.InputDoubleRegister(0)); + __ MovDoubleLowToInt(i.OutputRegister(), kScratchDoubleReg); + // Use INT32_MIN s an overflow indicator because it allows for easier + // out-of-bounds detection. + CRegister cr = cr7; + int crbit = v8::internal::Assembler::encode_crbit( + cr, static_cast(VXCVI % CRWIDTH)); + __ mcrfs(cr, VXCVI); // extract FPSCR field containing VXCVI into cr7 + __ lis(kScratchReg, Operand(static_cast(0x8000))); + __ isel(i.OutputRegister(0), kScratchReg, i.OutputRegister(0), crbit); + break; + } case kPPC_DoubleToInt32: case kPPC_DoubleToUint32: case kPPC_DoubleToInt64: { diff --git a/src/compiler/backend/ppc/instruction-codes-ppc.h b/src/compiler/backend/ppc/instruction-codes-ppc.h index 184d7f88f1..4d1fed2758 100644 --- a/src/compiler/backend/ppc/instruction-codes-ppc.h +++ b/src/compiler/backend/ppc/instruction-codes-ppc.h @@ -95,6 +95,7 @@ namespace compiler { V(PPC_Int32ToFloat32) \ V(PPC_Int32ToDouble) \ V(PPC_Uint32ToFloat32) \ + V(PPC_Float32ToInt32) \ V(PPC_Uint32ToDouble) \ V(PPC_Float32ToDouble) \ V(PPC_Float64SilenceNaN) \ diff --git a/src/compiler/backend/ppc/instruction-scheduler-ppc.cc b/src/compiler/backend/ppc/instruction-scheduler-ppc.cc index b1fe8cc575..bd10b36e5d 100644 --- a/src/compiler/backend/ppc/instruction-scheduler-ppc.cc +++ b/src/compiler/backend/ppc/instruction-scheduler-ppc.cc @@ -92,6 +92,7 @@ int InstructionScheduler::GetTargetInstructionFlags( case kPPC_Int32ToDouble: case kPPC_Uint32ToFloat32: case kPPC_Uint32ToDouble: + case kPPC_Float32ToInt32: case kPPC_Float32ToDouble: case kPPC_Float64SilenceNaN: case kPPC_DoubleToInt32: diff --git a/src/compiler/backend/ppc/instruction-selector-ppc.cc b/src/compiler/backend/ppc/instruction-selector-ppc.cc index f19b633dd0..fd73b27208 100644 --- a/src/compiler/backend/ppc/instruction-selector-ppc.cc +++ b/src/compiler/backend/ppc/instruction-selector-ppc.cc @@ -1227,7 +1227,7 @@ void InstructionSelector::VisitRoundFloat64ToInt32(Node* node) { } void InstructionSelector::VisitTruncateFloat32ToInt32(Node* node) { - VisitRR(this, kPPC_DoubleToInt32, node); + VisitRR(this, kPPC_Float32ToInt32, node); } void InstructionSelector::VisitTruncateFloat32ToUint32(Node* node) { diff --git a/src/compiler/backend/s390/code-generator-s390.cc b/src/compiler/backend/s390/code-generator-s390.cc index 24591b89b8..690eac56c5 100644 --- a/src/compiler/backend/s390/code-generator-s390.cc +++ b/src/compiler/backend/s390/code-generator-s390.cc @@ -2421,7 +2421,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( __ ConvertFloat32ToInt32(i.OutputRegister(0), i.InputDoubleRegister(0), kRoundToZero); __ b(Condition(0xE), &done, Label::kNear); // normal case - __ lghi(i.OutputRegister(0), Operand::Zero()); + // Use INT32_MIN s an overflow indicator because it allows for easier + // out-of-bounds detection. + __ llilh(i.OutputRegister(0), Operand(0x8000)); __ bind(&done); break; } diff --git a/src/execution/ppc/simulator-ppc.cc b/src/execution/ppc/simulator-ppc.cc index a0da6dd634..1134469134 100644 --- a/src/execution/ppc/simulator-ppc.cc +++ b/src/execution/ppc/simulator-ppc.cc @@ -3331,6 +3331,7 @@ void Simulator::ExecuteGeneric(Instruction* instr) { int64_t frt_val; int64_t kMinVal = kMinInt; int64_t kMaxVal = kMaxInt; + bool invalid_convert = false; if (std::isnan(frb_val)) { frt_val = kMinVal; @@ -3360,13 +3361,16 @@ void Simulator::ExecuteGeneric(Instruction* instr) { } if (frb_val < kMinVal) { frt_val = kMinVal; + invalid_convert = true; } else if (frb_val > kMaxVal) { frt_val = kMaxVal; + invalid_convert = true; } else { frt_val = (int64_t)frb_val; } } set_d_register(frt, frt_val); + if (invalid_convert) SetFPSCR(VXCVI); return; } case FNEG: { diff --git a/src/execution/s390/simulator-s390.cc b/src/execution/s390/simulator-s390.cc index 455f325f36..9ace63a009 100644 --- a/src/execution/s390/simulator-s390.cc +++ b/src/execution/s390/simulator-s390.cc @@ -5956,9 +5956,11 @@ EVALUATE(LLIHL) { } EVALUATE(LLILH) { - UNIMPLEMENTED(); - USE(instr); - return 0; + DCHECK_OPCODE(LLILH); + DECODE_RI_A_INSTRUCTION(instr, r1, i2); + uint64_t imm = static_cast(i2); + set_register(r1, (imm << 48) >> 32); + return length; } EVALUATE(LLILL) {