MIPS64: Fix the integer division in crankshaft.
authorakos.palfi <akos.palfi@imgtec.com>
Thu, 30 Jul 2015 09:16:18 +0000 (02:16 -0700)
committerCommit bot <commit-bot@chromium.org>
Thu, 30 Jul 2015 09:16:29 +0000 (09:16 +0000)
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
src/mips64/simulator-mips64.cc

index 999db36c879039c765f49124a8f3a81622d2f453..364a961b93905466e1ba0be92b102421afe5f38c 100644 (file)
@@ -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)) {
index 16bc2128131f3eeb6ac5f70c839b360d3a928b7f..a634f781f72601e6512021e87f6a46c9c48676ba 100644 (file)
@@ -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);