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