Various bugfixes
divide by zero check for longs, off-by-one error on fill-array-data,
register management hygene, mvn encoding, iget/iput <= 32bits are
done as 32-bit (code was using type size for ld/st).
Change-Id: Ia09323e7d92f4ad21890af4c10f2f8c8f05f3b0e
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index 5ef7687..3f7a7ae 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -460,7 +460,7 @@
rlObj = loadValue(cUnit, rlObj, kCoreReg);
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */
- loadBaseIndexed(cUnit, rlObj.lowReg, r0, rlResult.lowReg, 0, size);
+ loadBaseIndexed(cUnit, rlObj.lowReg, r0, rlResult.lowReg, 0, kWord);
oatGenMemBarrier(cUnit, kSY);
storeValue(cUnit, rlDest, rlResult);
} else {
@@ -474,7 +474,7 @@
rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */
loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
- size, rlObj.sRegLow);
+ kWord, rlObj.sRegLow);
if (isVolatile) {
oatGenMemBarrier(cUnit, kSY);
}
@@ -495,7 +495,7 @@
rlSrc = loadValue(cUnit, rlSrc, regClass);
genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */
oatGenMemBarrier(cUnit, kSY);
- storeBaseIndexed(cUnit, rlObj.lowReg, r0, rlSrc.lowReg, 0, size);
+ storeBaseIndexed(cUnit, rlObj.lowReg, r0, rlSrc.lowReg, 0, kWord);
} else {
#if ANDROID_SMP != 0
bool isVolatile = fieldPtr->IsVolatile();
@@ -510,7 +510,7 @@
if (isVolatile) {
oatGenMemBarrier(cUnit, kST);
}
- storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, size);
+ storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, kWord);
if (isVolatile) {
oatGenMemBarrier(cUnit, kSY);
}
@@ -1498,6 +1498,7 @@
OpKind firstOp = kOpBkpt;
OpKind secondOp = kOpBkpt;
bool callOut = false;
+ bool checkZero = false;
int funcOffset;
int retReg = r0;
@@ -1538,6 +1539,7 @@
case OP_DIV_LONG:
case OP_DIV_LONG_2ADDR:
callOut = true;
+ checkZero = true;
retReg = r0;
funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
break;
@@ -1545,6 +1547,7 @@
case OP_REM_LONG:
case OP_REM_LONG_2ADDR:
callOut = true;
+ checkZero = true;
funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
retReg = r2;
break;
@@ -1592,12 +1595,22 @@
if (!callOut) {
genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
} else {
- // Adjust return regs in to handle case of rem returning r2/r3
oatFlushAllRegs(cUnit); /* Send everything to home location */
- loadWordDisp(cUnit, rSELF, funcOffset, rLR);
- loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
- loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+ if (checkZero) {
+ loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+ loadWordDisp(cUnit, rSELF, funcOffset, rLR);
+ loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+ int tReg = oatAllocTemp(cUnit);
+ newLIR4(cUnit, kThumb2OrrRRRs, tReg, r2, r3, 0);
+ oatFreeTemp(cUnit, tReg);
+ genCheck(cUnit, kArmCondEq, mir, kArmThrowDivZero);
+ } else {
+ loadWordDisp(cUnit, rSELF, funcOffset, rLR);
+ loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+ loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+ }
callRuntimeHelper(cUnit, rLR);
+ // Adjust return regs in to handle case of rem returning r2/r3
if (retReg == r0)
rlResult = oatGetReturnWide(cUnit);
else