diff options
| author | Douglas Leung <douglas@mips.com> | 2012-10-05 17:01:22 -0700 |
|---|---|---|
| committer | Douglas Leung <douglas@mips.com> | 2012-10-05 17:23:54 -0700 |
| commit | a5fbd70a962297d305988616a4ad7b3194cb1237 (patch) | |
| tree | 28ea7f8ad9fcd45b30504e37c532211fde506798 /vm/compiler/codegen/mips/CodegenDriver.cpp | |
| parent | f75aa0de3d243466f56d262de08da3808ad34cf3 (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.cpp | 10 |
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); |
