MIPS64: [turbofan] Changed TruncateFloat64ToInt64 to TryTruncateFloat64ToInt64

Port 95844d94f3

Original commit message:
The new operator provides a second output which indicates whether the
conversion from float64 to int64 was successful or not. The second
output returns 0 if the conversion fails. If the conversion succeeds,
then the second output is differs from 0.

The second output can be ignored, which means that the operator can be
used the same way as the original operator.

I implemented the new operator on x64 and arm64. @v8-mips-ports and
@v8-ppc-ports, can you please take care of the mips64 and ppc64
implementation of the second output?

BUG=
TEST=cctest/test-run-machops/RunTryTruncateFloat64ToInt64WithCheck

Review URL: https://codereview.chromium.org/1503173002

Cr-Commit-Position: refs/heads/master@{#32664}
This commit is contained in:
ivica.bogosavljevic 2015-12-07 12:29:50 -08:00 committed by Commit bot
parent a4634fd357
commit 80f2a6390c
2 changed files with 33 additions and 5 deletions

View File

@ -1046,9 +1046,30 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
}
case kMips64TruncLD: {
FPURegister scratch = kScratchDoubleReg;
Register tmp_fcsr = kScratchReg;
Register result = kScratchReg2;
bool load_status = instr->OutputCount() > 1;
if (load_status) {
// Save FCSR.
__ cfc1(tmp_fcsr, FCSR);
// Clear FPU flags.
__ ctc1(zero_reg, FCSR);
}
// Other arches use round to zero here, so we follow.
__ trunc_l_d(scratch, i.InputDoubleRegister(0));
__ dmfc1(i.OutputRegister(), scratch);
__ dmfc1(i.OutputRegister(0), scratch);
if (load_status) {
__ cfc1(result, FCSR);
// Check for overflow and NaNs.
__ andi(result, result,
(kFCSROverflowFlagMask | kFCSRInvalidOpFlagMask));
__ Slt(result, zero_reg, result);
__ xori(result, result, 1);
__ mov(i.OutputRegister(1), result);
// Restore FCSR
__ ctc1(tmp_fcsr, FCSR);
}
break;
}
case kMips64TruncUwD: {

View File

@ -829,11 +829,18 @@ void InstructionSelector::VisitTruncateFloat32ToInt64(Node* node) {
void InstructionSelector::VisitTryTruncateFloat64ToInt64(Node* node) {
if (NodeProperties::FindProjection(node, 1)) {
// TODO(mips): implement the second return value.
UNIMPLEMENTED();
Mips64OperandGenerator g(this);
InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0))};
InstructionOperand outputs[2];
size_t output_count = 0;
outputs[output_count++] = g.DefineAsRegister(node);
Node* success_output = NodeProperties::FindProjection(node, 1);
if (success_output) {
outputs[output_count++] = g.DefineAsRegister(success_output);
}
VisitRR(this, kMips64TruncLD, node);
Emit(kMips64TruncLD, output_count, outputs, 1, inputs);
}