From 437c789a26960e6902fe7f905c6b7dc5784c8c9b Mon Sep 17 00:00:00 2001 From: "akos.palfi" Date: Thu, 30 Jul 2015 02:16:18 -0700 Subject: [PATCH] MIPS64: Fix the integer division in crankshaft. Replaces the 64-bit div instruction with 32-bit division in DivI. Also fixes the Ddiv implementation in the simulator. TEST=mjsunit/asm/int32div BUG= Review URL: https://codereview.chromium.org/1265603002 Cr-Commit-Position: refs/heads/master@{#29920} --- src/mips64/lithium-codegen-mips64.cc | 2 +- src/mips64/simulator-mips64.cc | 15 +++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc index 999db36c87..364a961b93 100644 --- a/src/mips64/lithium-codegen-mips64.cc +++ b/src/mips64/lithium-codegen-mips64.cc @@ -1215,7 +1215,7 @@ void LCodeGen::DoDivI(LDivI* instr) { // On MIPS div is asynchronous - it will run in the background while we // check for special cases. - __ Ddiv(result, dividend, divisor); + __ Div(result, dividend, divisor); // Check for x / 0. if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) { diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc index 16bc212813..a634f781f7 100644 --- a/src/mips64/simulator-mips64.cc +++ b/src/mips64/simulator-mips64.cc @@ -3794,15 +3794,17 @@ void Simulator::DecodeTypeRegisterSPECIAL( TraceRegWr(alu_out); break; case DIV: - case DDIV: + case DDIV: { + const int64_t int_min_value = + instr->FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN; switch (kArchVariant) { case kMips64r2: // Divide by zero and overflow was not checked in the // configuration step - div and divu do not raise exceptions. On // division by 0 the result will be UNPREDICTABLE. On overflow // (INT_MIN/-1), return INT_MIN which is what the hardware does. - if (rs == INT_MIN && rt == -1) { - set_register(LO, INT_MIN); + if (rs == int_min_value && rt == -1) { + set_register(LO, int_min_value); set_register(HI, 0); } else if (rt != 0) { set_register(LO, rs / rt); @@ -3812,14 +3814,14 @@ void Simulator::DecodeTypeRegisterSPECIAL( case kMips64r6: switch (instr->SaValue()) { case DIV_OP: - if (rs == INT_MIN && rt == -1) { - set_register(rd_reg, INT_MIN); + if (rs == int_min_value && rt == -1) { + set_register(rd_reg, int_min_value); } else if (rt != 0) { set_register(rd_reg, rs / rt); } break; case MOD_OP: - if (rs == INT_MIN && rt == -1) { + if (rs == int_min_value && rt == -1) { set_register(rd_reg, 0); } else if (rt != 0) { set_register(rd_reg, rs % rt); @@ -3834,6 +3836,7 @@ void Simulator::DecodeTypeRegisterSPECIAL( break; } break; + } case DIVU: if (rt_u != 0) { set_register(LO, rs_u / rt_u);