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}
This commit is contained in:
parent
efab0b74dd
commit
437c789a26
@ -1215,7 +1215,7 @@ void LCodeGen::DoDivI(LDivI* instr) {
|
|||||||
|
|
||||||
// On MIPS div is asynchronous - it will run in the background while we
|
// On MIPS div is asynchronous - it will run in the background while we
|
||||||
// check for special cases.
|
// check for special cases.
|
||||||
__ Ddiv(result, dividend, divisor);
|
__ Div(result, dividend, divisor);
|
||||||
|
|
||||||
// Check for x / 0.
|
// Check for x / 0.
|
||||||
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
|
if (hdiv->CheckFlag(HValue::kCanBeDivByZero)) {
|
||||||
|
@ -3794,15 +3794,17 @@ void Simulator::DecodeTypeRegisterSPECIAL(
|
|||||||
TraceRegWr(alu_out);
|
TraceRegWr(alu_out);
|
||||||
break;
|
break;
|
||||||
case DIV:
|
case DIV:
|
||||||
case DDIV:
|
case DDIV: {
|
||||||
|
const int64_t int_min_value =
|
||||||
|
instr->FunctionFieldRaw() == DIV ? INT_MIN : LONG_MIN;
|
||||||
switch (kArchVariant) {
|
switch (kArchVariant) {
|
||||||
case kMips64r2:
|
case kMips64r2:
|
||||||
// Divide by zero and overflow was not checked in the
|
// Divide by zero and overflow was not checked in the
|
||||||
// configuration step - div and divu do not raise exceptions. On
|
// configuration step - div and divu do not raise exceptions. On
|
||||||
// division by 0 the result will be UNPREDICTABLE. On overflow
|
// division by 0 the result will be UNPREDICTABLE. On overflow
|
||||||
// (INT_MIN/-1), return INT_MIN which is what the hardware does.
|
// (INT_MIN/-1), return INT_MIN which is what the hardware does.
|
||||||
if (rs == INT_MIN && rt == -1) {
|
if (rs == int_min_value && rt == -1) {
|
||||||
set_register(LO, INT_MIN);
|
set_register(LO, int_min_value);
|
||||||
set_register(HI, 0);
|
set_register(HI, 0);
|
||||||
} else if (rt != 0) {
|
} else if (rt != 0) {
|
||||||
set_register(LO, rs / rt);
|
set_register(LO, rs / rt);
|
||||||
@ -3812,14 +3814,14 @@ void Simulator::DecodeTypeRegisterSPECIAL(
|
|||||||
case kMips64r6:
|
case kMips64r6:
|
||||||
switch (instr->SaValue()) {
|
switch (instr->SaValue()) {
|
||||||
case DIV_OP:
|
case DIV_OP:
|
||||||
if (rs == INT_MIN && rt == -1) {
|
if (rs == int_min_value && rt == -1) {
|
||||||
set_register(rd_reg, INT_MIN);
|
set_register(rd_reg, int_min_value);
|
||||||
} else if (rt != 0) {
|
} else if (rt != 0) {
|
||||||
set_register(rd_reg, rs / rt);
|
set_register(rd_reg, rs / rt);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MOD_OP:
|
case MOD_OP:
|
||||||
if (rs == INT_MIN && rt == -1) {
|
if (rs == int_min_value && rt == -1) {
|
||||||
set_register(rd_reg, 0);
|
set_register(rd_reg, 0);
|
||||||
} else if (rt != 0) {
|
} else if (rt != 0) {
|
||||||
set_register(rd_reg, rs % rt);
|
set_register(rd_reg, rs % rt);
|
||||||
@ -3834,6 +3836,7 @@ void Simulator::DecodeTypeRegisterSPECIAL(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case DIVU:
|
case DIVU:
|
||||||
if (rt_u != 0) {
|
if (rt_u != 0) {
|
||||||
set_register(LO, rs_u / rt_u);
|
set_register(LO, rs_u / rt_u);
|
||||||
|
Loading…
Reference in New Issue
Block a user