Fix endianness of compiled code and stacks of stubs for MIPS.

The gtests now all work on MIPS.

Change-Id: I2883ce002f23d75e700366014517c863fb626d09
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 6868d0b..d948d2d 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -1784,13 +1784,11 @@
            RegLocation rlSrc1, RegLocation rlSrc2)
 {
   OpKind op = kOpBkpt;
-  bool callOut = false;
+  bool isDivRem = false;
   bool checkZero = false;
   bool unary = false;
   RegLocation rlResult;
   bool shiftOp = false;
-  int funcOffset;
-  int retReg = rRET0;
   switch (opcode) {
     case Instruction::NEG_INT:
       op = kOpNeg;
@@ -1816,18 +1814,14 @@
     case Instruction::DIV_INT_2ADDR:
       checkZero = true;
       op = kOpDiv;
-      callOut = true;
-      funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
-      retReg = rRET0;
+      isDivRem = true;
       break;
     /* NOTE: returns in rARG1 */
     case Instruction::REM_INT:
     case Instruction::REM_INT_2ADDR:
       checkZero = true;
       op = kOpRem;
-      callOut = true;
-      funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
-      retReg = rRET1;
+      isDivRem = true;
       break;
     case Instruction::AND_INT:
     case Instruction::AND_INT_2ADDR:
@@ -1860,7 +1854,7 @@
       LOG(FATAL) << "Invalid word arith op: " <<
         (int)opcode;
   }
-  if (!callOut) {
+  if (!isDivRem) {
     if (unary) {
       rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
       rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
@@ -1889,10 +1883,24 @@
     }
     storeValue(cUnit, rlDest, rlResult);
   } else {
+#if defined(TARGET_MIPS)
+    rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
+    if (checkZero) {
+        genNullCheck(cUnit, rlSrc2.sRegLow, rlSrc2.lowReg, 0);
+    }
+    newLIR4(cUnit, kMipsDiv, r_HI, r_LO, rlSrc1.lowReg, rlSrc2.lowReg);
+    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    if (op == kOpDiv) {
+      newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
+    } else {
+      newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
+    }
+#else
+    int funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
     RegLocation rlResult;
     oatFlushAllRegs(cUnit);   /* Send everything to home location */
     loadValueDirectFixed(cUnit, rlSrc2, rARG1);
-#if !defined(TARGET_X86)
+#if defined(TARGET_ARM)
     int rTgt = loadHelper(cUnit, funcOffset);
 #endif
     loadValueDirectFixed(cUnit, rlSrc1, rARG0);
@@ -1900,17 +1908,18 @@
       genImmedCheck(cUnit, kCondEq, rARG1, 0, kThrowDivZero);
     }
     // NOTE: callout here is not a safepoint
-#if !defined(TARGET_X86)
+#if defined(TARGET_ARM)
     opReg(cUnit, kOpBlx, rTgt);
     oatFreeTemp(cUnit, rTgt);
 #else
     opThreadMem(cUnit, kOpBlx, funcOffset);
 #endif
-    if (retReg == rRET0)
+    if (op == kOpDiv)
       rlResult = oatGetReturn(cUnit, false);
     else
       rlResult = oatGetReturnAlt(cUnit);
     storeValue(cUnit, rlDest, rlResult);
+#endif
   }
   return false;
 }
@@ -2077,7 +2086,6 @@
   OpKind op = (OpKind)0;    /* Make gcc happy */
   int shiftOp = false;
   bool isDiv = false;
-  int funcOffset;
 
   switch (opcode) {
     case Instruction::RSUB_INT_LIT8:
@@ -2140,7 +2148,7 @@
     case Instruction::DIV_INT_LIT8:
     case Instruction::DIV_INT_LIT16:
     case Instruction::REM_INT_LIT8:
-    case Instruction::REM_INT_LIT16:
+    case Instruction::REM_INT_LIT16: {
       if (lit == 0) {
         genImmedCheck(cUnit, kCondAl, 0, 0, kThrowDivZero);
         return false;
@@ -2148,24 +2156,39 @@
       if (handleEasyDivide(cUnit, opcode, rlSrc, rlDest, lit)) {
         return false;
       }
-      oatFlushAllRegs(cUnit);   /* Everything to home location */
-      loadValueDirectFixed(cUnit, rlSrc, rARG0);
-      oatClobber(cUnit, rARG0);
-      funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
       if ((opcode == Instruction::DIV_INT_LIT8) ||
           (opcode == Instruction::DIV_INT_LIT16)) {
         isDiv = true;
       } else {
         isDiv = false;
       }
+#if defined(TARGET_MIPS)
+      rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+      int tReg = oatAllocTemp(cUnit);
+      newLIR3(cUnit, kMipsAddiu, tReg, r_ZERO, lit);
+      newLIR4(cUnit, kMipsDiv, r_HI, r_LO, rlSrc.lowReg, tReg);
+      rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+      if (isDiv) {
+        newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
+      } else {
+        newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
+      }
+      oatFreeTemp(cUnit, tReg);
+#else
+      oatFlushAllRegs(cUnit);   /* Everything to home location */
+      loadValueDirectFixed(cUnit, rlSrc, rARG0);
+      oatClobber(cUnit, rARG0);
+      int funcOffset = ENTRYPOINT_OFFSET(pIdivmod);
       callRuntimeHelperRegImm(cUnit, funcOffset, rARG0, lit, false);
       if (isDiv)
         rlResult = oatGetReturn(cUnit, false);
       else
         rlResult = oatGetReturnAlt(cUnit);
+#endif
       storeValue(cUnit, rlDest, rlResult);
       return false;
       break;
+    }
     default:
       return true;
   }