Index: src/mips64/simulator-mips64.cc |
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc |
index 16bc2128131f3eeb6ac5f70c839b360d3a928b7f..a634f781f72601e6512021e87f6a46c9c48676ba 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); |