aboutsummaryrefslogtreecommitdiff
path: root/vm/compiler/codegen/mips/CodegenDriver.cpp
diff options
context:
space:
mode:
authorDouglas Leung <douglas@mips.com>2012-10-05 17:01:22 -0700
committerDouglas Leung <douglas@mips.com>2012-10-05 17:23:54 -0700
commita5fbd70a962297d305988616a4ad7b3194cb1237 (patch)
tree28ea7f8ad9fcd45b30504e37c532211fde506798 /vm/compiler/codegen/mips/CodegenDriver.cpp
parentf75aa0de3d243466f56d262de08da3808ad34cf3 (diff)
MIPS: Missing zero-checks in JIT compiler.
Zero-checks were not generated by the JIT compiler for some instructions. This caused crashes instead of the expected ArithmeticException. Change-Id: Ic7f20c78ef9ac22bb529b6ed9a38f0ffb2fab33c Signed-off-by: Douglas Leung <douglas@mips.com>
Diffstat (limited to 'vm/compiler/codegen/mips/CodegenDriver.cpp')
-rw-r--r--vm/compiler/codegen/mips/CodegenDriver.cpp10
1 files changed, 9 insertions, 1 deletions
diff --git a/vm/compiler/codegen/mips/CodegenDriver.cpp b/vm/compiler/codegen/mips/CodegenDriver.cpp
index fea1d1ec4..62a9a4fb9 100644
--- a/vm/compiler/codegen/mips/CodegenDriver.cpp
+++ b/vm/compiler/codegen/mips/CodegenDriver.cpp
@@ -731,6 +731,7 @@ static bool genArithOpLong(CompilationUnit *cUnit, MIR *mir,
OpKind firstOp = kOpBkpt;
OpKind secondOp = kOpBkpt;
bool callOut = false;
+ bool checkZero = false;
void *callTgt;
switch (mir->dalvikInsn.opcode) {
@@ -759,12 +760,14 @@ static bool genArithOpLong(CompilationUnit *cUnit, MIR *mir,
case OP_DIV_LONG:
case OP_DIV_LONG_2ADDR:
callOut = true;
+ checkZero = true;
callTgt = (void*)__divdi3;
break;
case OP_REM_LONG:
case OP_REM_LONG_2ADDR:
callOut = true;
callTgt = (void*)__moddi3;
+ checkZero = true;
break;
case OP_AND_LONG_2ADDR:
case OP_AND_LONG:
@@ -802,9 +805,14 @@ static bool genArithOpLong(CompilationUnit *cUnit, MIR *mir,
genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
} else {
dvmCompilerFlushAllRegs(cUnit); /* Send everything to home location */
+ loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
loadValueDirectWideFixed(cUnit, rlSrc1, r_ARG0, r_ARG1);
LOAD_FUNC_ADDR(cUnit, r_T9, (int) callTgt);
- loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
+ if (checkZero) {
+ int tReg = r_T1; // Using fixed registers during call sequence
+ opRegRegReg(cUnit, kOpOr, tReg, r_ARG2, r_ARG3);
+ genRegImmCheck(cUnit, kMipsCondEq, tReg, 0, mir->offset, NULL);
+ }
opReg(cUnit, kOpBlx, r_T9);
newLIR3(cUnit, kMipsLw, r_GP, STACK_OFFSET_GP, r_SP);
dvmCompilerClobberCallRegs(cUnit);