Another step towards a Mips target

Updating the MIPS target to use the now common codegen routines.
Still much to do, but the general structure is sufficient to allow
work to begin on the other target.

Change-Id: I0d288fdfb59c8e76fad73185fdd56b345e87b604
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index 4eccf04..96a9b21 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -154,6 +154,7 @@
         lir->defMask |= ENCODE_REG_LIST(lir->operands[1]);
     }
 
+#if defined(TARGET_ARM)
     if (flags & REG_DEF_FPCS_LIST0) {
         lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
     }
@@ -163,6 +164,7 @@
             setupRegMask(&lir->defMask, lir->operands[1] + i);
         }
     }
+#endif
 
     if (flags & SETS_CCODES) {
         lir->defMask |= ENCODE_CCODE;
@@ -201,6 +203,7 @@
         lir->useMask |= ENCODE_REG_LIST(lir->operands[1]);
     }
 
+#if defined(TARGET_ARM)
     if (flags & REG_USE_FPCS_LIST0) {
         lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
     }
@@ -210,6 +213,7 @@
             setupRegMask(&lir->useMask, lir->operands[1] + i);
         }
     }
+#endif
 
     if (flags & USES_CCODES) {
         lir->useMask |= ENCODE_CCODE;
@@ -231,10 +235,186 @@
 }
 
 /*
+ * Debugging macros
+ */
+#define DUMP_RESOURCE_MASK(X)
+#define DUMP_SSA_REP(X)
+
+/* Pretty-print a LIR instruction */
+void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
+{
+    LIR* lir = (LIR*) arg;
+    int offset = lir->offset;
+    int dest = lir->operands[0];
+    const bool dumpNop = false;
+
+    /* Handle pseudo-ops individually, and all regular insns as a group */
+    switch(lir->opcode) {
+        case kPseudoMethodEntry:
+            LOG(INFO) << "-------- method entry " <<
+                PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
+            break;
+        case kPseudoMethodExit:
+            LOG(INFO) << "-------- Method_Exit";
+            break;
+        case kPseudoBarrier:
+            LOG(INFO) << "-------- BARRIER";
+            break;
+        case kPseudoExtended:
+            LOG(INFO) << "-------- " << (char* ) dest;
+            break;
+        case kPseudoSSARep:
+            DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
+            break;
+        case kPseudoEntryBlock:
+            LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
+            break;
+        case kPseudoDalvikByteCodeBoundary:
+            LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
+                 lir->dalvikOffset << " @ " << (char* )lir->operands[0];
+            break;
+        case kPseudoExitBlock:
+            LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
+            break;
+        case kPseudoPseudoAlign4:
+            LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
+                offset << "): .align4";
+            break;
+        case kPseudoEHBlockLabel:
+            LOG(INFO) << "Exception_Handling:";
+            break;
+        case kPseudoTargetLabel:
+        case kPseudoNormalBlockLabel:
+            LOG(INFO) << "L" << (intptr_t)lir << ":";
+            break;
+        case kPseudoThrowTarget:
+            LOG(INFO) << "LT" << (intptr_t)lir << ":";
+            break;
+        case kPseudoSuspendTarget:
+            LOG(INFO) << "LS" << (intptr_t)lir << ":";
+            break;
+        case kPseudoCaseLabel:
+            LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" <<
+                std::hex << lir->operands[0] << "|" << std::dec <<
+                lir->operands[0];
+            break;
+        default:
+            if (lir->flags.isNop && !dumpNop) {
+                break;
+            } else {
+                std::string op_name(buildInsnString(EncodingMap[lir->opcode].name, lir, baseAddr));
+                std::string op_operands(buildInsnString(EncodingMap[lir->opcode].fmt, lir, baseAddr));
+                LOG(INFO) << StringPrintf("%p (%04x): %-9s%s%s", baseAddr + offset, offset,
+                    op_name.c_str(), op_operands.c_str(), lir->flags.isNop ? "(nop)" : "");
+            }
+            break;
+    }
+
+    if (lir->useMask && (!lir->flags.isNop || dumpNop)) {
+        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
+                                               lir->useMask, "use"));
+    }
+    if (lir->defMask && (!lir->flags.isNop || dumpNop)) {
+        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
+                                               lir->defMask, "def"));
+    }
+}
+
+void oatDumpPromotionMap(CompilationUnit *cUnit)
+{
+    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
+        PromotionMap vRegMap = cUnit->promotionMap[i];
+        char buf[100];
+        if (vRegMap.fpLocation == kLocPhysReg) {
+            snprintf(buf, 100, " : s%d", vRegMap.fpReg & FP_REG_MASK);
+        } else {
+            buf[0] = 0;
+        }
+        char buf2[100];
+        snprintf(buf2, 100, "V[%02d] -> %s%d%s", i,
+                 vRegMap.coreLocation == kLocPhysReg ?
+                 "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ?
+                 vRegMap.coreReg : oatSRegOffset(cUnit, i), buf);
+        LOG(INFO) << buf2;
+    }
+}
+
+void oatDumpFullPromotionMap(CompilationUnit *cUnit)
+{
+    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
+        PromotionMap vRegMap = cUnit->promotionMap[i];
+        LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation <<
+            ", CR:" << (int)vRegMap.coreReg << ", FL:" <<
+            (int)vRegMap.fpLocation << ", FR:" << (int)vRegMap.fpReg <<
+            ", - " << (int)vRegMap.firstInPair;
+    }
+}
+
+/* Dump instructions and constant pool contents */
+void oatCodegenDump(CompilationUnit* cUnit)
+{
+    LOG(INFO) << "/*";
+    LOG(INFO) << "Dumping LIR insns for "
+        << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
+    LIR* lirInsn;
+    LIR* thisLIR;
+    int insnsSize = cUnit->insnsSize;
+
+    LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs;
+    LOG(INFO) << "Ins                  : " << cUnit->numIns;
+    LOG(INFO) << "Outs                 : " << cUnit->numOuts;
+    LOG(INFO) << "CoreSpills           : " << cUnit->numCoreSpills;
+    LOG(INFO) << "FPSpills             : " << cUnit->numFPSpills;
+    LOG(INFO) << "Padding              : " << cUnit->numPadding;
+    LOG(INFO) << "Frame size           : " << cUnit->frameSize;
+    LOG(INFO) << "Start of ins         : " << cUnit->insOffset;
+    LOG(INFO) << "Start of regs        : " << cUnit->regsOffset;
+    LOG(INFO) << "code size is " << cUnit->totalSize <<
+        " bytes, Dalvik size is " << insnsSize * 2;
+    LOG(INFO) << "expansion factor: " <<
+         (float)cUnit->totalSize / (float)(insnsSize * 2);
+    oatDumpPromotionMap(cUnit);
+    for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) {
+        oatDumpLIRInsn(cUnit, lirInsn, 0);
+    }
+    for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) {
+        thisLIR = (LIR*) lirInsn;
+        LOG(INFO) << StringPrintf("%x (%04x): .class (%s)",
+            thisLIR->offset, thisLIR->offset,
+            ((CallsiteInfo *) thisLIR->operands[0])->classDescriptor);
+    }
+    for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) {
+        thisLIR = (LIR*) lirInsn;
+        LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)",
+            thisLIR->offset, thisLIR->offset, thisLIR->operands[0]);
+    }
+
+    const DexFile::MethodId& method_id =
+        cUnit->dex_file->GetMethodId(cUnit->method_idx);
+    std::string signature(cUnit->dex_file->GetMethodSignature(method_id));
+    std::string name(cUnit->dex_file->GetMethodName(method_id));
+    std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id));
+
+    // Dump mapping table
+    if (cUnit->mappingTable.size() > 0) {
+        std::string line(StringPrintf("\n    MappingTable %s%s_%s_mappingTable[%zu] = {",
+            descriptor.c_str(), name.c_str(), signature.c_str(), cUnit->mappingTable.size()));
+        std::replace(line.begin(), line.end(), ';', '_');
+        LOG(INFO) << line;
+        for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
+            line = StringPrintf("        {0x%08x, 0x%04x},",
+                cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
+            LOG(INFO) << line;
+        }
+        LOG(INFO) <<"    };\n\n";
+    }
+}
+
+/*
  * The following are building blocks to construct low-level IRs with 0 - 4
  * operands.
  */
-LIR* newLIR0(CompilationUnit* cUnit, ArmOpcode opcode)
+LIR* newLIR0(CompilationUnit* cUnit, int opcode)
 {
     LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
     DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND));
@@ -245,7 +425,7 @@
     return insn;
 }
 
-LIR* newLIR1(CompilationUnit* cUnit, ArmOpcode opcode,
+LIR* newLIR1(CompilationUnit* cUnit, int opcode,
                            int dest)
 {
     LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
@@ -258,7 +438,7 @@
     return insn;
 }
 
-LIR* newLIR2(CompilationUnit* cUnit, ArmOpcode opcode,
+LIR* newLIR2(CompilationUnit* cUnit, int opcode,
                            int dest, int src1)
 {
     LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
@@ -273,7 +453,7 @@
     return insn;
 }
 
-LIR* newLIR3(CompilationUnit* cUnit, ArmOpcode opcode,
+LIR* newLIR3(CompilationUnit* cUnit, int opcode,
                            int dest, int src1, int src2)
 {
     LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
@@ -293,7 +473,7 @@
 }
 
 #if defined(TARGET_ARM)
-LIR* newLIR4(CompilationUnit* cUnit, ArmOpcode opcode,
+LIR* newLIR4(CompilationUnit* cUnit, int opcode,
                            int dest, int src1, int src2, int info)
 {
     LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
@@ -350,7 +530,7 @@
  * instruction streams.
  */
 
-/* Add a 32-bit constant either in the constant pool or mixed with code */
+/* Add a 32-bit constant either in the constant pool */
 LIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP,
                            int value)
 {
@@ -362,10 +542,6 @@
         newValue->next = *constantListP;
         *constantListP = (LIR*) newValue;
         return newValue;
-    } else {
-        /* Add the constant in the middle of code stream */
-        newLIR1(cUnit, kArm16BitData, (value & 0xffff));
-        newLIR1(cUnit, kArm16BitData, (value >> 16));
     }
     return NULL;
 }
@@ -374,17 +550,10 @@
 LIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP,
                            int valLo, int valHi)
 {
-    LIR* res;
     //FIXME: hard-coded little endian, need BE variant
-    if (constantListP == NULL) {
-        res = addWordData(cUnit, NULL, valLo);
-        addWordData(cUnit, NULL, valHi);
-    } else {
-        // Insert high word into list first
-        addWordData(cUnit, constantListP, valHi);
-        res = addWordData(cUnit, constantListP, valLo);
-    }
-    return res;
+    // Insert high word into list first
+    addWordData(cUnit, constantListP, valHi);
+    return addWordData(cUnit, constantListP, valLo);
 }
 
 void pushWord(std::vector<uint16_t>&buf, int data) {
diff --git a/src/compiler/codegen/CompilerCodegen.h b/src/compiler/codegen/CompilerCodegen.h
index ae85bb3..26dad82 100644
--- a/src/compiler/codegen/CompilerCodegen.h
+++ b/src/compiler/codegen/CompilerCodegen.h
@@ -35,6 +35,9 @@
 void oatCodegenDump(CompilationUnit* cUnit);
 void oatDumpPromotionMap(CompilationUnit* cUnit);
 void oatDumpFullPromotionMap(CompilationUnit* cUnit);
+std::string buildInsnString(const char* fmt, LIR* lir,
+                            unsigned char* baseAddr);
+
 
 /* Implemented in codegen/<target>/Ralloc.c */
 void oatSimpleRegAlloc(CompilationUnit* cUnit);
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
index 7af1aa0..511c47b 100644
--- a/src/compiler/codegen/GenCommon.cc
+++ b/src/compiler/codegen/GenCommon.cc
@@ -43,14 +43,6 @@
     barrier->defMask = -1;
 }
 
-/* Generate conditional branch instructions */
-LIR* genConditionalBranch(CompilationUnit* cUnit, ConditionCode cond,
-                          LIR* target)
-{
-    LIR* branch = opCondBranch(cUnit, cond);
-    branch->target = (LIR*) target;
-    return branch;
-}
 
 /* Generate unconditional branch instructions */
 LIR* genUnconditionalBranch(CompilationUnit* cUnit, LIR* target)
@@ -60,6 +52,18 @@
     return branch;
 }
 
+// FIXME: need to do some work to split out targets with
+// condition codes and those without
+#if defined(TARGET_ARM) || defined(TARGET_X86)
+/* Generate conditional branch instructions */
+LIR* genConditionalBranch(CompilationUnit* cUnit, ConditionCode cond,
+                          LIR* target)
+{
+    LIR* branch = opCondBranch(cUnit, cond);
+    branch->target = (LIR*) target;
+    return branch;
+}
+
 LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir,
               ThrowKind kind)
 {
@@ -72,6 +76,7 @@
     oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
     return branch;
 }
+#endif
 
 LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode,
                    int reg, int immVal, MIR* mir, ThrowKind kind)
@@ -112,8 +117,12 @@
     tgt->operands[1] = mir ? mir->offset : 0;
     tgt->operands[2] = reg1;
     tgt->operands[3] = reg2;
+#if defined(TARGET_MIPS)
+    LIR* branch = genCompareBranch(cUnit, cCode, reg1, reg2);
+#else
     opRegReg(cUnit, kOpCmp, reg1, reg2);
     LIR* branch = genConditionalBranch(cUnit, cCode, tgt);
+#endif
     // Remember branch target - will process later
     oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
     return branch;
@@ -125,7 +134,6 @@
     ConditionCode cond;
     rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
     rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
-    opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
     Opcode opcode = mir->dalvikInsn.opcode;
     switch(opcode) {
         case OP_IF_EQ:
@@ -150,7 +158,13 @@
             cond = (ConditionCode)0;
             LOG(FATAL) << "Unexpected opcode " << (int)opcode;
     }
+#if defined(TARGET_MIPS)
+    LIR* branch = genCompareBranch(cUnit, cond, rlSrc1.lowReg, rlSrc2.lowReg);
+    branch->target = &labelList[bb->taken->id];
+#else
+    opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
     genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+#endif
     genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
 }
 
@@ -159,7 +173,6 @@
 {
     ConditionCode cond;
     rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
     Opcode opcode = mir->dalvikInsn.opcode;
     switch(opcode) {
         case OP_IF_EQZ:
@@ -184,7 +197,13 @@
             cond = (ConditionCode)0;
             LOG(FATAL) << "Unexpected opcode " << (int)opcode;
     }
+#if defined(TARGET_MIPS)
+    LIR* branch = genCmpImmBranch(cUnit, cond, rlSrc.lowReg, 0);
+    branch->target = &labelList[bb->taken->id];
+#else
+    opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
     genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+#endif
     genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
 }
 
@@ -319,7 +338,11 @@
         int rSrc = oatAllocTemp(cUnit);
         int rDst = oatAllocTemp(cUnit);
         int rIdx = oatAllocTemp(cUnit);
+#if defined(TARGET_ARM)
         int rVal = rLR;  // Using a lot of temps, rLR is known free here
+#else
+        int rVal = oatAllocTemp(cUnit);
+#endif
         // Set up source pointer
         RegLocation rlFirst = oatGetSrc(cUnit, mir, 0);
         opRegRegImm(cUnit, kOpAdd, rSrc, rSP,
@@ -340,8 +363,9 @@
         newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
         LIR* branch = opCondBranch(cUnit, kCondGe);
 #else
+        oatFreeTemp(cUnit, rVal);
         opRegImm(cUnit, kOpSub, rIdx, 1);
-        LIR* branch = opCompareBranchImm(cUnit, kCondGe, rIdx, 0);
+        LIR* branch = genCmpImmBranch(cUnit, kCondGe, rIdx, 0);
 #endif
         branch->target = (LIR*)target;
     } else if (!isRange) {
@@ -637,11 +661,11 @@
                 funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
                 break;
             case kThrowArrayBounds:
-                if (v2 != r0) {
+                if (v2 != rARG0) {
                     genRegCopy(cUnit, rARG0, v1);
                     genRegCopy(cUnit, rARG1, v2);
                 } else {
-                    if (v1 == r1) {
+                    if (v1 == rARG1) {
 #if defined(TARGET_ARM)
                         int rTmp = r12;
 #else
@@ -860,7 +884,7 @@
             // TUNING: move slow path to end & remove unconditional branch
             LIR* target1 = newLIR0(cUnit, kPseudoTargetLabel);
             target1->defMask = ENCODE_ALL;
-            // Call out to helper, which will return resolved type in r0
+            // Call out to helper, which will return resolved type in rARG0
             int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
                                   pInitializeTypeFromCode));
             genRegCopy(cUnit, rARG1, mReg);
@@ -909,7 +933,7 @@
         genRegCopy(cUnit, rARG0, rARG2);   // .eq
         opReg(cUnit, kOpBlx, rTgt);        // .eq, helper(Method*, string_idx)
 #else
-        LIR* branch = genCmpImmBranch(cUnit, kCondNe, 0);
+        LIR* branch = genCmpImmBranch(cUnit, kCondNe, rRET0, 0);
         genRegCopy(cUnit, rARG0, rARG2);   // .eq
         opReg(cUnit, kOpBlx, rTgt);
         LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
@@ -961,22 +985,22 @@
     // May generate a call - use explicit registers
     oatLockCallTemps(cUnit);
     uint32_t type_idx = mir->dalvikInsn.vC;
-    loadCurrMethodDirect(cUnit, rARG1);  // r1 <= current Method*
+    loadCurrMethodDirect(cUnit, rARG1);  // rARG1 <= current Method*
     int classReg = rARG2;  // rARG2 will hold the Class*
     if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
                                                      cUnit->dex_cache,
                                                      *cUnit->dex_file,
                                                      type_idx)) {
         // Check we have access to type_idx and if not throw IllegalAccessError,
-        // returns Class* in r0
+        // returns Class* in rARG0
         int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
                               pInitializeTypeAndVerifyAccessFromCode));
         loadConstant(cUnit, rARG0, type_idx);
         callRuntimeHelper(cUnit, rTgt);  // InitializeTypeAndVerifyAccess(idx, method)
         genRegCopy(cUnit, classReg, rRET0);  // Align usage with fast path
-        loadValueDirectFixed(cUnit, rlSrc, rARG0);  // r0 <= ref
+        loadValueDirectFixed(cUnit, rlSrc, rARG0);  // rARG0 <= ref
     } else {
-        // Load dex cache entry into classReg (r2)
+        // Load dex cache entry into classReg (rARG2)
         loadValueDirectFixed(cUnit, rlSrc, rARG0);  // rARG0 <= ref
         loadWordDisp(cUnit, rARG1,
                      Method::DexCacheResolvedTypesOffset().Int32Value(),
@@ -995,7 +1019,7 @@
                                   pInitializeTypeFromCode));
             loadConstant(cUnit, rARG0, type_idx);
             callRuntimeHelper(cUnit, rTgt);  // InitializeTypeFromCode(idx, method)
-            genRegCopy(cUnit, r2, rRET0); // Align usage with fast path
+            genRegCopy(cUnit, rARG2, rRET0); // Align usage with fast path
             loadValueDirectFixed(cUnit, rlSrc, rARG0);  /* reload Ref */
             // Rejoin code paths
             LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
@@ -1021,6 +1045,7 @@
     genBarrier(cUnit);
     oatClobberCalleeSave(cUnit);
 #else
+    (void)rTgt;
     // Perhaps a general-purpose kOpSelect operator?
     UNIMPLEMENTED(FATAL) << "Need non IT implementation";
 #endif
@@ -1065,18 +1090,18 @@
             // Need to test presence of type in dex cache at runtime
             LIR* hopBranch = genCmpImmBranch(cUnit, kCondNe, classReg, 0);
             // Not resolved
-            // Call out to helper, which will return resolved type in r0
-            loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
-            loadConstant(cUnit, r0, type_idx);
-            callRuntimeHelper(cUnit, rLR);  // InitializeTypeFromCode(idx, method)
-            genRegCopy(cUnit, classReg, r0); // Align usage with fast path
+            // Call out to helper, which will return resolved type in rARG0
+            int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode));
+            loadConstant(cUnit, rARG0, type_idx);
+            callRuntimeHelper(cUnit, rTgt);  // InitializeTypeFromCode(idx, method)
+            genRegCopy(cUnit, classReg, rARG0); // Align usage with fast path
             // Rejoin code paths
             LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
             hopTarget->defMask = ENCODE_ALL;
             hopBranch->target = (LIR*)hopTarget;
         }
     }
-    // At this point, classReg (r2) has class
+    // At this point, classReg (rARG2) has class
     loadValueDirectFixed(cUnit, rlSrc, rARG0);  // rARG0 <= ref
     /* Null is OK - continue */
     LIR* branch1 = genCmpImmBranch(cUnit, kCondEq, rARG0, 0);
@@ -1086,8 +1111,12 @@
     /* rARG1 now contains object->clazz */
     int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
                           pCheckCastFromCode));
+#if defined(TARGET_MIPS)
+    LIR* branch2 = genCompareBranch(cUnit, kCondEq, rARG1, classReg);
+#else
     opRegReg(cUnit, kOpCmp, rARG1, classReg);
     LIR* branch2 = opCondBranch(cUnit, kCondEq); /* If equal, trivial yes */
+#endif
     genRegCopy(cUnit, rARG0, rARG1);
     genRegCopy(cUnit, rARG1, rARG2);
     callRuntimeHelper(cUnit, rTgt);
@@ -1430,7 +1459,7 @@
             funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
             retReg = rRET0;
             break;
-        /* NOTE: returns in r1 */
+        /* NOTE: returns in rARG1 */
         case OP_REM_INT:
         case OP_REM_INT_2ADDR:
             callOut = true;
@@ -1598,8 +1627,12 @@
                                    RegLocation rlResult, int lit,
                                    int firstBit, int secondBit)
 {
+#if defined(TARGET_MIPS)
+    UNIMPLEMENTED(FATAL) << "Need shift & add primative";
+#else
     opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
                      encodeShift(kArmLsl, secondBit - firstBit));
+#endif
     if (firstBit != 0) {
         opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
     }
@@ -1882,7 +1915,7 @@
             genCheck(cUnit, kCondEq, mir, kThrowDivZero);
 #else
             opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3);
-            genImmedCheck(cUnit, kCondEq, mir, tReg, 0, mir, kThrowDivZero);
+            genImmedCheck(cUnit, kCondEq, tReg, 0, mir, kThrowDivZero);
             oatFreeTemp(cUnit, tReg);
 #endif
         } else {
@@ -2116,7 +2149,7 @@
         branch = opCondBranch(cUnit, kCondEq);
 #else
         opRegImm(cUnit, kOpSub, rSUSPEND, 1);
-        branch = opCompareBranchImm(cUnit, kCondEq, rSUSPEND, 0);
+        branch = genCmpImmBranch(cUnit, kCondEq, rSUSPEND, 0);
 #endif
     }
     LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel);
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index 6de3a9c..38c2117 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -102,7 +102,11 @@
     if (DISPLAY_MISSING_TARGETS) {
         genShowTarget(cUnit);
     }
+#if defined(TARGET_MIPS)
+    UNIMPLEMENTED(FATAL) << "Need to handle common target register";
+#else
     opReg(cUnit, kOpBlx, rLR);
+#endif
     oatClobberCalleeSave(cUnit);
 }
 
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index e1eba44..be6b44d 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -321,180 +321,5 @@
     }
 }
 
-/*
- * Debugging macros
- */
-#define DUMP_RESOURCE_MASK(X)
-#define DUMP_SSA_REP(X)
-
-/* Pretty-print a LIR instruction */
-void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
-{
-    LIR* lir = (LIR*) arg;
-    int offset = lir->offset;
-    int dest = lir->operands[0];
-    const bool dumpNop = false;
-
-    /* Handle pseudo-ops individually, and all regular insns as a group */
-    switch(lir->opcode) {
-        case kPseudoMethodEntry:
-            LOG(INFO) << "-------- method entry " <<
-                PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
-            break;
-        case kPseudoMethodExit:
-            LOG(INFO) << "-------- Method_Exit";
-            break;
-        case kPseudoBarrier:
-            LOG(INFO) << "-------- BARRIER";
-            break;
-        case kPseudoExtended:
-            LOG(INFO) << "-------- " << (char* ) dest;
-            break;
-        case kPseudoSSARep:
-            DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
-            break;
-        case kPseudoEntryBlock:
-            LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
-            break;
-        case kPseudoDalvikByteCodeBoundary:
-            LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
-                 lir->dalvikOffset << " @ " << (char* )lir->operands[0];
-            break;
-        case kPseudoExitBlock:
-            LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
-            break;
-        case kPseudoPseudoAlign4:
-            LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
-                offset << "): .align4";
-            break;
-        case kPseudoEHBlockLabel:
-            LOG(INFO) << "Exception_Handling:";
-            break;
-        case kPseudoTargetLabel:
-        case kPseudoNormalBlockLabel:
-            LOG(INFO) << "L" << (intptr_t)lir << ":";
-            break;
-        case kPseudoThrowTarget:
-            LOG(INFO) << "LT" << (intptr_t)lir << ":";
-            break;
-        case kPseudoSuspendTarget:
-            LOG(INFO) << "LS" << (intptr_t)lir << ":";
-            break;
-        case kPseudoCaseLabel:
-            LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" <<
-                std::hex << lir->operands[0] << "|" << std::dec <<
-                lir->operands[0];
-            break;
-        default:
-            if (lir->flags.isNop && !dumpNop) {
-                break;
-            } else {
-                std::string op_name(buildInsnString(EncodingMap[lir->opcode].name, lir, baseAddr));
-                std::string op_operands(buildInsnString(EncodingMap[lir->opcode].fmt, lir, baseAddr));
-                LOG(INFO) << StringPrintf("%p (%04x): %-9s%s%s", baseAddr + offset, offset,
-                    op_name.c_str(), op_operands.c_str(), lir->flags.isNop ? "(nop)" : "");
-            }
-            break;
-    }
-
-    if (lir->useMask && (!lir->flags.isNop || dumpNop)) {
-        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
-                                               lir->useMask, "use"));
-    }
-    if (lir->defMask && (!lir->flags.isNop || dumpNop)) {
-        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
-                                               lir->defMask, "def"));
-    }
-}
-
-void oatDumpPromotionMap(CompilationUnit *cUnit)
-{
-    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
-        PromotionMap vRegMap = cUnit->promotionMap[i];
-        char buf[100];
-        if (vRegMap.fpLocation == kLocPhysReg) {
-            snprintf(buf, 100, " : s%d", vRegMap.fpReg & FP_REG_MASK);
-        } else {
-            buf[0] = 0;
-        }
-        char buf2[100];
-        snprintf(buf2, 100, "V[%02d] -> %s%d%s", i,
-                 vRegMap.coreLocation == kLocPhysReg ?
-                 "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ?
-                 vRegMap.coreReg : oatSRegOffset(cUnit, i), buf);
-        LOG(INFO) << buf2;
-    }
-}
-
-void oatDumpFullPromotionMap(CompilationUnit *cUnit)
-{
-    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
-        PromotionMap vRegMap = cUnit->promotionMap[i];
-        LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation <<
-            ", CR:" << (int)vRegMap.coreReg << ", FL:" <<
-            (int)vRegMap.fpLocation << ", FR:" << (int)vRegMap.fpReg <<
-            ", - " << (int)vRegMap.firstInPair;
-    }
-}
-
-/* Dump instructions and constant pool contents */
-void oatCodegenDump(CompilationUnit* cUnit)
-{
-    LOG(INFO) << "/*";
-    LOG(INFO) << "Dumping LIR insns for "
-        << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
-    LIR* lirInsn;
-    LIR* armLIR;
-    int insnsSize = cUnit->insnsSize;
-
-    LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs;
-    LOG(INFO) << "Ins                  : " << cUnit->numIns;
-    LOG(INFO) << "Outs                 : " << cUnit->numOuts;
-    LOG(INFO) << "CoreSpills           : " << cUnit->numCoreSpills;
-    LOG(INFO) << "FPSpills             : " << cUnit->numFPSpills;
-    LOG(INFO) << "Padding              : " << cUnit->numPadding;
-    LOG(INFO) << "Frame size           : " << cUnit->frameSize;
-    LOG(INFO) << "Start of ins         : " << cUnit->insOffset;
-    LOG(INFO) << "Start of regs        : " << cUnit->regsOffset;
-    LOG(INFO) << "code size is " << cUnit->totalSize <<
-        " bytes, Dalvik size is " << insnsSize * 2;
-    LOG(INFO) << "expansion factor: " <<
-         (float)cUnit->totalSize / (float)(insnsSize * 2);
-    oatDumpPromotionMap(cUnit);
-    for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) {
-        oatDumpLIRInsn(cUnit, lirInsn, 0);
-    }
-    for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) {
-        armLIR = (LIR*) lirInsn;
-        LOG(INFO) << StringPrintf("%x (%04x): .class (%s)",
-            armLIR->offset, armLIR->offset,
-            ((CallsiteInfo *) armLIR->operands[0])->classDescriptor);
-    }
-    for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) {
-        armLIR = (LIR*) lirInsn;
-        LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)",
-            armLIR->offset, armLIR->offset, armLIR->operands[0]);
-    }
-
-    const DexFile::MethodId& method_id =
-        cUnit->dex_file->GetMethodId(cUnit->method_idx);
-    std::string signature(cUnit->dex_file->GetMethodSignature(method_id));
-    std::string name(cUnit->dex_file->GetMethodName(method_id));
-    std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id));
-
-    // Dump mapping table
-    if (cUnit->mappingTable.size() > 0) {
-        std::string line(StringPrintf("\n    MappingTable %s%s_%s_mappingTable[%zu] = {",
-            descriptor.c_str(), name.c_str(), signature.c_str(), cUnit->mappingTable.size()));
-        std::replace(line.begin(), line.end(), ';', '_');
-        LOG(INFO) << line;
-        for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
-            line = StringPrintf("        {0x%08x, 0x%04x},",
-                cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
-            LOG(INFO) << line;
-        }
-        LOG(INFO) <<"    };\n\n";
-    }
-}
 
 }  // namespace art
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index 196bddb..e4e9eb8 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -745,22 +745,6 @@
 
 extern const ArmEncodingMap EncodingMap[kArmLast];
 
-typedef struct SwitchTable {
-    int offset;
-    const u2* table;            // Original dex table
-    int vaddr;                  // Dalvik offset of switch opcode
-    LIR* bxInst;                // Switch indirect branch instruction
-    LIR** targets;              // Array of case targets
-} SwitchTable;
-
-typedef struct FillArrayData {
-    int offset;
-    const u2* table;           // Original dex table
-    int size;
-    int vaddr;                 // Dalvik offset of OP_FILL_ARRAY_DATA opcode
-} FillArrayData;
-
-
 }  // namespace art
 
 #endif  // ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index a020687..d44d7cf 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -116,6 +116,22 @@
     oatClobber(cUnit, r3);
     oatClobber(cUnit, r12);
     oatClobber(cUnit, r14lr);
+    oatClobber(cUnit, fr0);
+    oatClobber(cUnit, fr1);
+    oatClobber(cUnit, fr2);
+    oatClobber(cUnit, fr3);
+    oatClobber(cUnit, fr4);
+    oatClobber(cUnit, fr5);
+    oatClobber(cUnit, fr6);
+    oatClobber(cUnit, fr7);
+    oatClobber(cUnit, fr8);
+    oatClobber(cUnit, fr9);
+    oatClobber(cUnit, fr10);
+    oatClobber(cUnit, fr11);
+    oatClobber(cUnit, fr12);
+    oatClobber(cUnit, fr13);
+    oatClobber(cUnit, fr14);
+    oatClobber(cUnit, fr15);
 }
 
 extern RegLocation oatGetReturnWide(CompilationUnit* cUnit)
diff --git a/src/compiler/codegen/arm/Codegen.h b/src/compiler/codegen/arm/Codegen.h
index a565cb1..49e39db 100644
--- a/src/compiler/codegen/arm/Codegen.h
+++ b/src/compiler/codegen/arm/Codegen.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 The Android Open Source Project
+ * Copyright (C) 2012 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index cb9645d..2cb0731 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -22,1096 +22,68 @@
  *
  */
 
-#define SLOW_FIELD_PATH (cUnit->enableDebug & (1 << kDebugSlowFieldPath))
-#define SLOW_INVOKE_PATH (cUnit->enableDebug & (1 << kDebugSlowInvokePath))
-#define SLOW_STRING_PATH (cUnit->enableDebug & (1 << kDebugSlowStringPath))
-#define SLOW_TYPE_PATH (cUnit->enableDebug & (1 << kDebugSlowTypePath))
-#define EXERCISE_SLOWEST_FIELD_PATH (cUnit->enableDebug & \
-    (1 << kDebugSlowestFieldPath))
-#define EXERCISE_SLOWEST_STRING_PATH (cUnit->enableDebug & \
-    (1 << kDebugSlowestStringPath))
-#define EXERCISE_RESOLVE_METHOD (cUnit->enableDebug & \
-    (1 << kDebugExerciseResolveMethod))
-
-// FIXME - this is the Mips version, change to MIPS
-
 namespace art {
 
-STATIC void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
-
-/* Generate unconditional branch instructions */
-STATIC MipsLIR* genUnconditionalBranch(CompilationUnit* cUnit, MipsLIR* target)
-{
-    MipsLIR* branch = opNone(cUnit, kOpUncondBr);
-    branch->generic.target = (LIR*) target;
-    return branch;
-}
-
-STATIC MipsLIR* callRuntimeHelper(CompilationUnit* cUnit, int reg)
-{
-    oatClobberCalleeSave(cUnit);
-    return opReg(cUnit, kOpBlx, reg);
-}
+void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
 
 /*
- * Mark garbage collection card. Skip if the value we're storing is null.
+ * In the Arm code a it is typical to use the link register
+ * to hold the target address.  However, for Mips we must
+ * ensure that all branch instructions can be restarted if
+ * there is a trap in the shadow.  Allocate a temp register.
  */
-STATIC void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
+int loadHelper(CompilationUnit* cUnit, int offset)
 {
-    int regCardBase = oatAllocTemp(cUnit);
-    int regCardNo = oatAllocTemp(cUnit);
-    MipsLIR* branchOver = opCompareBranchCC(cUnit, kMipsCondEq, valReg, r_ZERO);
-    loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(),
-                 regCardBase);
-    opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
-    storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
-                     kUnsignedByte);
-    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-    target->defMask = ENCODE_ALL;
-    branchOver->generic.target = (LIR*)target;
-    oatFreeTemp(cUnit, regCardBase);
-    oatFreeTemp(cUnit, regCardNo);
+    int tReg = oatAllocTemp(cUnit);
+    loadWordDisp(cUnit, rSELF, offset, tReg);
+    return tReg;
 }
 
-/*
- * Utiltiy to load the current Method*.  Broken out
- * to allow easy change between placing the current Method* in a
- * dedicated register or its home location in the frame.
- */
-STATIC void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
+void spillCoreRegs(CompilationUnit* cUnit)
 {
-#if defined(METHOD_IN_REG)
-    genRegCopy(cUnit, rTgt, rMETHOD);
-#else
-    loadWordDisp(cUnit, rSP, 0, rTgt);
-#endif
-}
-
-STATIC int loadCurrMethod(CompilationUnit *cUnit)
-{
-#if defined(METHOD_IN_REG)
-    return rMETHOD;
-#else
-    int mReg = oatAllocTemp(cUnit);
-    loadCurrMethodDirect(cUnit, mReg);
-    return mReg;
-#endif
-}
-
-STATIC MipsLIR* genImmedCheck(CompilationUnit* cUnit, MipsConditionCode cCode,
-                             int reg, int immVal, MIR* mir, MipsThrowKind kind)
-{
-    MipsLIR* tgt = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    tgt->opcode = kPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir->offset;
-    MipsLIR* branch;
-    if (cCode == kMipsCondAl) {
-        branch = genUnconditionalBranch(cUnit, tgt);
-    } else {
-        int tReg;
-        if (immVal == 0) {
-            tReg = r_ZERO;
-        } else {
-            tReg = oatAllocTemp(cUnit);
-            loadConstant(cUnit, tReg, immVal);
-        }
-        branch = opCompareBranchCC(cUnit, cCode, reg, tReg);
-        branch->generic.target = (LIR*)tgt;
-    }
-    // Remember branch target - will process later
-    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-    return branch;
-}
-
-/* Perform null-check on a register.  */
-STATIC MipsLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
-                             MIR* mir)
-{
-    if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
-        mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
-        return NULL;
-    }
-    return genImmedCheck(cUnit, kMipsCondEq, mReg, 0, mir, kMipsThrowNullPointer);
-}
-
-/* Perform check on two registers */
-STATIC TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, MipsConditionCode cCode,
-                               int reg1, int reg2, MIR* mir, MipsThrowKind kind)
-{
-    MipsLIR* tgt = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    tgt->opcode = kPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir ? mir->offset : 0;
-    tgt->operands[2] = reg1;
-    tgt->operands[3] = reg2;
-    opRegReg(cUnit, kOpCmp, reg1, reg2);
-    MipsLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
-    // Remember branch target - will process later
-    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-    return branch;
-}
-
-/*
- * Let helper function take care of everything.  Will call
- * Array::AllocFromCode(type_idx, method, count);
- * Note: AllocFromCode will handle checks for errNegativeArraySize.
- */
-STATIC void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                        RegLocation rlSrc)
-{
-    oatFlushAllRegs(cUnit);    /* Everything to home location */
-    oatLockCallTemps(cUnit);
-    int addrReg = oatAllocTemp(cUnit);
-    uint32_t type_idx = mir->dalvikInsn.vC;
-    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
-                                                    cUnit->dex_cache,
-                                                    *cUnit->dex_file,
-                                                    type_idx)) {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCode), addrReg);
-    } else {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCodeWithAccessCheck), addrReg);
-    }
-    loadCurrMethodDirect(cUnit, r_ARG1);              // arg1 <- Method*
-    loadConstant(cUnit, r_ARG0, type_idx);            // arg0 <- type_id
-    loadValueDirectFixed(cUnit, rlSrc, r_ARG2);       // arg2 <- count
-    callRuntimeHelper(cUnit, addrReg);
-    RegLocation rlResult = oatGetReturn(cUnit);
-    storeValue(cUnit, rlDest, rlResult);
-}
-
-/*
- * Similar to genNewArray, but with post-allocation initialization.
- * Verifier guarantees we're dealing with an array class.  Current
- * code throws runtime exception "bad Filled array req" for 'D' and 'J'.
- * Current code also throws internal unimp if not 'L', '[' or 'I'.
- */
-STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
-{
-    DecodedInstruction* dInsn = &mir->dalvikInsn;
-    int elems = dInsn->vA;
-    int typeId = dInsn->vB;
-    oatFlushAllRegs(cUnit);    /* Everything to home location */
-    oatLockCallTemps(cUnit);
-    int addrReg = oatAllocTemp(cUnit);
-    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
-                                                    cUnit->dex_cache,
-                                                    *cUnit->dex_file,
-                                                    typeId)) {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCode),
-                                     addrReg);
-    } else {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread,
-                     pCheckAndAllocArrayFromCodeWithAccessCheck), addrReg);
-    }
-    loadCurrMethodDirect(cUnit, r_ARG1);              // arg1 <- Method*
-    loadConstant(cUnit, r_ARG0, typeId);              // arg0 <- type_id
-    loadConstant(cUnit, r_ARG2, elems);               // arg2 <- count
-    callRuntimeHelper(cUnit, addrReg);
-    /*
-     * NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
-     * return region.  Because AllocFromCode placed the new array
-     * in r_V0, we'll just lock it into place.  When debugger support is
-     * added, it may be necessary to additionally copy all return
-     * values to a home location in thread-local storage
-     */
-    oatLockTemp(cUnit, r_V0);
-
-    // Having a range of 0 is legal
-    if (isRange && (dInsn->vA > 0)) {
-        /*
-         * Bit of ugliness here.  We're going generate a mem copy loop
-         * on the register range, but it is possible that some regs
-         * in the range have been promoted.  This is unlikely, but
-         * before generating the copy, we'll just force a flush
-         * of any regs in the source range that have been promoted to
-         * home location.
-         */
-        for (unsigned int i = 0; i < dInsn->vA; i++) {
-            RegLocation loc = oatUpdateLoc(cUnit,
-                oatGetSrc(cUnit, mir, i));
-            if (loc.location == kLocPhysReg) {
-                storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
-                              loc.lowReg, kWord);
-            }
-        }
-        /*
-         * TUNING note: generated code here could be much improved, but
-         * this is an uncommon operation and isn't especially performance
-         * critical.
-         */
-        int rSrc = oatAllocTemp(cUnit);
-        int rDst = oatAllocTemp(cUnit);
-        int rIdx = oatAllocTemp(cUnit);
-        int rVal = oatAllocTemp(cUnit);
-        // Set up source pointer
-        RegLocation rlFirst = oatGetSrc(cUnit, mir, 0);
-        opRegRegImm(cUnit, kOpAdd, rSrc, rSP,
-                    oatSRegOffset(cUnit, rlFirst.sRegLow));
-        // Set up the target pointer
-        opRegRegImm(cUnit, kOpAdd, rDst, r_V0,
-                    Array::DataOffset().Int32Value());
-        // Set up the loop counter (known to be > 0)
-        loadConstant(cUnit, rIdx, dInsn->vA - 1);
-        // Generate the copy loop.  Going backwards for convenience
-        MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-        target->defMask = ENCODE_ALL;
-        // Copy next element
-        loadBaseIndexed(cUnit, rSrc, rIdx, rVal, 2, kWord);
-        storeBaseIndexed(cUnit, rDst, rIdx, rVal, 2, kWord);
-        opRegImm(cUnit, kOpSub, rIdx, 1);
-        MipsLIR* branch = opCompareBranchCC(cUnit, kMipsCondGe, rIdx, r_ZERO);
-        branch->generic.target = (LIR*)target;
-    } else if (!isRange) {
-        // TUNING: interleave
-        for (unsigned int i = 0; i < dInsn->vA; i++) {
-            RegLocation rlArg = loadValue(cUnit,
-                oatGetSrc(cUnit, mir, i), kCoreReg);
-            storeBaseDisp(cUnit, r_V0,
-                          Array::DataOffset().Int32Value() +
-                          i * 4, rlArg.lowReg, kWord);
-            // If the loadValue caused a temp to be allocated, free it
-            if (oatIsTemp(cUnit, rlArg.lowReg)) {
-                oatFreeTemp(cUnit, rlArg.lowReg);
-            }
-        }
-    }
-}
-
-STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
-                    bool isLongOrDouble, bool isObject)
-{
-    int fieldOffset;
-    int ssbIndex;
-    bool isVolatile;
-    bool isReferrersClass;
-    uint32_t fieldIdx = mir->dalvikInsn.vB;
-    bool fastPath =
-        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, cUnit,
-                                                fieldOffset, ssbIndex,
-                                                isReferrersClass, isVolatile, true);
-    if (fastPath && !SLOW_FIELD_PATH) {
-        DCHECK_GE(fieldOffset, 0);
-        int rBase;
-        int rMethod;
-        if (isReferrersClass) {
-            // Fast path, static storage base is this method's class
-            rMethod  = loadCurrMethod(cUnit);
-            rBase = oatAllocTemp(cUnit);
-            loadWordDisp(cUnit, rMethod,
-                         Method::DeclaringClassOffset().Int32Value(), rBase);
-        } else {
-            // Medium path, static storage base in a different class which
-            // requires checks that the other class is initialized.
-            DCHECK_GE(ssbIndex, 0);
-            // May do runtime call so everything to home locations.
-            oatFlushAllRegs(cUnit);
-            // Using fixed register to sync with possible call to runtime
-            // support.
-            oatLockCallTemps(cUnit);
-            rMethod = r1;
-            oatLockTemp(cUnit, rMethod);
-            loadCurrMethodDirect(cUnit, rMethod);
-            rBase = r0;
-            oatLockTemp(cUnit, rBase);
-            loadWordDisp(cUnit, rMethod,
-                Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
-                rBase);
-            loadWordDisp(cUnit, rBase,
-                         Array::DataOffset().Int32Value() + sizeof(int32_t*) *
-                         ssbIndex, rBase);
-            // rBase now points at appropriate static storage base (Class*)
-            // or NULL if not initialized. Check for NULL and call helper if NULL.
-            // TUNING: fast path should fall through
-            MipsLIR* branchOver = opCmpImmBranchCC(cUnit, kMipsCondNe,
-                                                   rBase, 0);
-            loadWordDisp(cUnit, rSELF,
-                         OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
-            loadConstant(cUnit, r0, ssbIndex);
-            callRuntimeHelper(cUnit, rLR);
-            MipsLIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
-            skipTarget->defMask = ENCODE_ALL;
-            branchOver->generic.target = (LIR*)skipTarget;
-        }
-        // rBase now holds static storage base
-        oatFreeTemp(cUnit, rMethod);
-        if (isLongOrDouble) {
-            rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
-            rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
-        } else {
-            rlSrc = oatGetSrc(cUnit, mir, 0);
-            rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
-        }
-        if (isVolatile) {
-            oatGenMemBarrier(cUnit, kST);
-        }
-        if (isLongOrDouble) {
-            storeBaseDispWide(cUnit, rBase, fieldOffset, rlSrc.lowReg,
-                              rlSrc.highReg);
-        } else {
-            storeWordDisp(cUnit, rBase, fieldOffset, rlSrc.lowReg);
-        }
-        if (isVolatile) {
-            oatGenMemBarrier(cUnit, kSY);
-        }
-        if (isObject) {
-            markGCCard(cUnit, rlSrc.lowReg, rBase);
-        }
-        oatFreeTemp(cUnit, rBase);
-    } else {
-        oatFlushAllRegs(cUnit);  // Everything to home locations
-        int setterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pSet64Static) :
-                           (isObject ? OFFSETOF_MEMBER(Thread, pSetObjStatic)
-                                     : OFFSETOF_MEMBER(Thread, pSet32Static));
-        loadWordDisp(cUnit, rSELF, setterOffset, rLR);
-        loadConstant(cUnit, r0, fieldIdx);
-        if (isLongOrDouble) {
-            loadValueDirectWideFixed(cUnit, rlSrc, r2, r3);
-        } else {
-            loadValueDirect(cUnit, rlSrc, r1);
-        }
-        callRuntimeHelper(cUnit, rLR);
-    }
-}
-
-STATIC void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                    bool isLongOrDouble, bool isObject)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    int fieldOffset;
-    int ssbIndex;
-    bool isVolatile;
-    bool isReferrersClass;
-    uint32_t fieldIdx = mir->dalvikInsn.vB;
-    bool fastPath =
-        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, cUnit,
-                                                fieldOffset, ssbIndex,
-                                                isReferrersClass, isVolatile, false);
-    if (fastPath && !SLOW_FIELD_PATH) {
-        DCHECK_GE(fieldOffset, 0);
-        int rBase;
-        int rMethod;
-        if (isReferrersClass) {
-            // Fast path, static storage base is this method's class
-            rMethod  = loadCurrMethod(cUnit);
-            rBase = oatAllocTemp(cUnit);
-            loadWordDisp(cUnit, rMethod,
-                         Method::DeclaringClassOffset().Int32Value(), rBase);
-        } else {
-            // Medium path, static storage base in a different class which
-            // requires checks that the other class is initialized
-            DCHECK_GE(ssbIndex, 0);
-            // May do runtime call so everything to home locations.
-            oatFlushAllRegs(cUnit);
-            // Using fixed register to sync with possible call to runtime
-            // support
-            rMethod = r1;
-            oatLockTemp(cUnit, rMethod);
-            loadCurrMethodDirect(cUnit, rMethod);
-            rBase = r0;
-            oatLockTemp(cUnit, rBase);
-            loadWordDisp(cUnit, rMethod,
-                Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
-                rBase);
-            loadWordDisp(cUnit, rBase,
-                         Array::DataOffset().Int32Value() + sizeof(int32_t*) * ssbIndex,
-                         rBase);
-            // rBase now points at appropriate static storage base (Class*)
-            // or NULL if not initialized. Check for NULL and call helper if NULL.
-            // TUNING: fast path should fall through
-            MipsLIR* branchOver = opCmpImmBranchCC(cUnit, kMipsCondNe, rBase, 0);
-            loadWordDisp(cUnit, rSELF,
-                         OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
-            loadConstant(cUnit, r0, ssbIndex);
-            callRuntimeHelper(cUnit, rLR);
-            MipsLIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
-            skipTarget->defMask = ENCODE_ALL;
-            branchOver->generic.target = (LIR*)skipTarget;
-        }
-        // rBase now holds static storage base
-        oatFreeTemp(cUnit, rMethod);
-        rlDest = isLongOrDouble ? oatGetDestWide(cUnit, mir, 0, 1)
-                                : oatGetDest(cUnit, mir, 0);
-        RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kAnyReg, true);
-        if (isVolatile) {
-            oatGenMemBarrier(cUnit, kSY);
-        }
-        if (isLongOrDouble) {
-            loadBaseDispWide(cUnit, NULL, rBase, fieldOffset, rlResult.lowReg,
-                             rlResult.highReg, INVALID_SREG);
-        } else {
-            loadWordDisp(cUnit, rBase, fieldOffset, rlResult.lowReg);
-        }
-        oatFreeTemp(cUnit, rBase);
-        if (isLongOrDouble) {
-            storeValueWide(cUnit, rlDest, rlResult);
-        } else {
-            storeValue(cUnit, rlDest, rlResult);
-        }
-    } else {
-        oatFlushAllRegs(cUnit);  // Everything to home locations
-        int getterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pGet64Static) :
-                           (isObject ? OFFSETOF_MEMBER(Thread, pGetObjStatic)
-                                     : OFFSETOF_MEMBER(Thread, pGet32Static));
-        loadWordDisp(cUnit, rSELF, getterOffset, rLR);
-        loadConstant(cUnit, r0, fieldIdx);
-        callRuntimeHelper(cUnit, rLR);
-        if (isLongOrDouble) {
-            RegLocation rlResult = oatGetReturnWide(cUnit);
-            storeValueWide(cUnit, rlDest, rlResult);
-        } else {
-            RegLocation rlResult = oatGetReturn(cUnit);
-            storeValue(cUnit, rlDest, rlResult);
-        }
-    }
-#endif
-}
-
-typedef int (*NextCallInsn)(CompilationUnit*, MIR*, int, uint32_t dexIdx,
-                            uint32_t methodIdx);
-
-/*
- * Bit of a hack here - in leiu of a real scheduling pass,
- * emit the next instruction in static & direct invoke sequences.
- */
-STATIC int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
-                          int state, uint32_t dexIdx, uint32_t unused)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    switch(state) {
-        case 0:  // Get the current Method* [sets r0]
-            loadCurrMethodDirect(cUnit, r0);
-            break;
-        case 1:  // Get method->code_and_direct_methods_
-            loadWordDisp(cUnit, r0,
-                Method::GetDexCacheCodeAndDirectMethodsOffset().Int32Value(),
-                r0);
-            break;
-        case 2:  // Grab target method* and target code_
-            loadWordDisp(cUnit, r0,
-                CodeAndDirectMethods::CodeOffsetInBytes(dexIdx), rLR);
-            loadWordDisp(cUnit, r0,
-                CodeAndDirectMethods::MethodOffsetInBytes(dexIdx), r0);
-            break;
-        default:
-            return -1;
-    }
-#endif
-    return state + 1;
-}
-
-/*
- * Bit of a hack here - in leiu of a real scheduling pass,
- * emit the next instruction in a virtual invoke sequence.
- * We can use rLR as a temp prior to target address loading
- * Note also that we'll load the first argument ("this") into
- * r1 here rather than the standard loadArgRegs.
- */
-STATIC int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
-                         int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    RegLocation rlArg;
-    /*
-     * This is the fast path in which the target virtual method is
-     * fully resolved at compile time.
-     */
-    switch(state) {
-        case 0:  // Get "this" [set r1]
-            rlArg = oatGetSrc(cUnit, mir, 0);
-            loadValueDirectFixed(cUnit, rlArg, r1);
-            break;
-        case 1: // Is "this" null? [use r1]
-            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
-            // get this->klass_ [use r1, set rLR]
-            loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), rLR);
-            break;
-        case 2: // Get this->klass_->vtable [usr rLR, set rLR]
-            loadWordDisp(cUnit, rLR, Class::VTableOffset().Int32Value(), rLR);
-            break;
-        case 3: // Get target method [use rLR, set r0]
-            loadWordDisp(cUnit, rLR, (methodIdx * 4) +
-                         Array::DataOffset().Int32Value(), r0);
-            break;
-        case 4: // Get the target compiled code address [uses r0, sets rLR]
-            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
-            break;
-        default:
-            return -1;
-    }
-#endif
-    return state + 1;
-}
-
-/*
- * Interleave launch code for INVOKE_SUPER.  See comments
- * for nextVCallIns.
- */
-STATIC int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir,
-                             int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    /*
-     * This is the fast path in which the target virtual method is
-     * fully resolved at compile time.  Note also that this path assumes
-     * that the check to verify that the target method index falls
-     * within the size of the super's vtable has been done at compile-time.
-     */
-    RegLocation rlArg;
-    switch(state) {
-        case 0: // Get current Method* [set r0]
-            loadCurrMethodDirect(cUnit, r0);
-            // Load "this" [set r1]
-            rlArg = oatGetSrc(cUnit, mir, 0);
-            loadValueDirectFixed(cUnit, rlArg, r1);
-            // Get method->declaring_class_ [use r0, set rLR]
-            loadWordDisp(cUnit, r0, Method::DeclaringClassOffset().Int32Value(),
-                         rLR);
-            // Is "this" null? [use r1]
-            genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
-            break;
-        case 1: // Get method->declaring_class_->super_class [usr rLR, set rLR]
-            loadWordDisp(cUnit, rLR, Class::SuperClassOffset().Int32Value(),
-                         rLR);
-            break;
-        case 2: // Get ...->super_class_->vtable [u/s rLR]
-            loadWordDisp(cUnit, rLR, Class::VTableOffset().Int32Value(), rLR);
-            break;
-        case 3: // Get target method [use rLR, set r0]
-            loadWordDisp(cUnit, rLR, (methodIdx * 4) +
-                         Array::DataOffset().Int32Value(), r0);
-            break;
-        case 4: // Get the target compiled code address [uses r0, sets rLR]
-            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
-            break;
-        default:
-            return -1;
-    }
-#endif
-    return state + 1;
-}
-
-STATIC int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
-                            int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    /*
-     * This handles the case in which the base method is not fully
-     * resolved at compile time, we bail to a runtime helper.
-     */
-    if (state == 0) {
-        // Load trampoline target
-        loadWordDisp(cUnit, rSELF, trampoline, rLR);
-        // Load r0 with method index
-        loadConstant(cUnit, r0, dexIdx);
-        return 1;
-    }
-#endif
-    return -1;
-}
-
-STATIC int nextStaticCallInsnSP(CompilationUnit* cUnit, MIR* mir,
-                                int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeStaticTrampolineWithAccessCheck);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-STATIC int nextDirectCallInsnSP(CompilationUnit* cUnit, MIR* mir,
-                                int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeDirectTrampolineWithAccessCheck);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-STATIC int nextSuperCallInsnSP(CompilationUnit* cUnit, MIR* mir,
-                               int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeSuperTrampolineWithAccessCheck);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-STATIC int nextVCallInsnSP(CompilationUnit* cUnit, MIR* mir,
-                           int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeVirtualTrampolineWithAccessCheck);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-/*
- * All invoke-interface calls bounce off of art_invoke_interface_trampoline,
- * which will locate the target and continue on via a tail call.
- */
-STATIC int nextInterfaceCallInsn(CompilationUnit* cUnit, MIR* mir,
-                                 int state, uint32_t dexIdx, uint32_t unused)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeInterfaceTrampoline);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-STATIC int nextInterfaceCallInsnWithAccessCheck(CompilationUnit* cUnit,
-                                                MIR* mir, int state,
-                                                uint32_t dexIdx,
-                                                uint32_t unused)
-{
-  int trampoline = OFFSETOF_MEMBER(Thread, pInvokeInterfaceTrampolineWithAccessCheck);
-  return nextInvokeInsnSP(cUnit, mir, trampoline, state, dexIdx, 0);
-}
-
-STATIC int loadArgRegs(CompilationUnit* cUnit, MIR* mir,
-                          DecodedInstruction* dInsn, int callState,
-                          NextCallInsn nextCallInsn, uint32_t dexIdx,
-                          uint32_t methodIdx, bool skipThis)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    int nextReg = r1;
-    int nextArg = 0;
-    if (skipThis) {
-        nextReg++;
-        nextArg++;
-    }
-    for (; (nextReg <= r3) && (nextArg < mir->ssaRep->numUses); nextReg++) {
-        RegLocation rlArg = oatGetRawSrc(cUnit, mir, nextArg++);
-        rlArg = oatUpdateRawLoc(cUnit, rlArg);
-        if (rlArg.wide && (nextReg <= r2)) {
-            loadValueDirectWideFixed(cUnit, rlArg, nextReg, nextReg + 1);
-            nextReg++;
-            nextArg++;
-        } else {
-            rlArg.wide = false;
-            loadValueDirectFixed(cUnit, rlArg, nextReg);
-        }
-        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-    }
-#endif
-    return callState;
-}
-
-/*
- * Load up to 5 arguments, the first three of which will be in
- * r1 .. r3.  On entry r0 contains the current method pointer,
- * and as part of the load sequence, it must be replaced with
- * the target method pointer.  Note, this may also be called
- * for "range" variants if the number of arguments is 5 or fewer.
- */
-STATIC int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
-                                DecodedInstruction* dInsn, int callState,
-                                MipsLIR** pcrLabel, NextCallInsn nextCallInsn,
-                                uint32_t dexIdx, uint32_t methodIdx,
-                                bool skipThis)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    RegLocation rlArg;
-
-    /* If no arguments, just return */
-    if (dInsn->vA == 0)
-        return callState;
-
-    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-
-    DCHECK_LE(dInsn->vA, 5U);
-    if (dInsn->vA > 3) {
-        uint32_t nextUse = 3;
-        //Detect special case of wide arg spanning arg3/arg4
-        RegLocation rlUse0 = oatGetRawSrc(cUnit, mir, 0);
-        RegLocation rlUse1 = oatGetRawSrc(cUnit, mir, 1);
-        RegLocation rlUse2 = oatGetRawSrc(cUnit, mir, 2);
-        if (((!rlUse0.wide && !rlUse1.wide) || rlUse0.wide) &&
-            rlUse2.wide) {
-            int reg;
-            // Wide spans, we need the 2nd half of uses[2].
-            rlArg = oatUpdateLocWide(cUnit, rlUse2);
-            if (rlArg.location == kLocPhysReg) {
-                reg = rlArg.highReg;
-            } else {
-                // r2 & r3 can safely be used here
-                reg = r3;
-                loadWordDisp(cUnit, rSP,
-                             oatSRegOffset(cUnit, rlArg.sRegLow) + 4, reg);
-                callState = nextCallInsn(cUnit, mir, callState, dexIdx,
-                                         methodIdx);
-            }
-            storeBaseDisp(cUnit, rSP, (nextUse + 1) * 4, reg, kWord);
-            storeBaseDisp(cUnit, rSP, 16 /* (3+1)*4 */, reg, kWord);
-            callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-            nextUse++;
-        }
-        // Loop through the rest
-        while (nextUse < dInsn->vA) {
-            int lowReg;
-            int highReg;
-            rlArg = oatGetRawSrc(cUnit, mir, nextUse);
-            rlArg = oatUpdateRawLoc(cUnit, rlArg);
-            if (rlArg.location == kLocPhysReg) {
-                lowReg = rlArg.lowReg;
-                highReg = rlArg.highReg;
-            } else {
-                lowReg = r2;
-                highReg = r3;
-                if (rlArg.wide) {
-                    loadValueDirectWideFixed(cUnit, rlArg, lowReg, highReg);
-                } else {
-                    loadValueDirectFixed(cUnit, rlArg, lowReg);
-                }
-                callState = nextCallInsn(cUnit, mir, callState, dexIdx,
-                                         methodIdx);
-            }
-            int outsOffset = (nextUse + 1) * 4;
-            if (rlArg.wide) {
-                storeBaseDispWide(cUnit, rSP, outsOffset, lowReg, highReg);
-                nextUse += 2;
-            } else {
-                storeWordDisp(cUnit, rSP, outsOffset, lowReg);
-                nextUse++;
-            }
-            callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-        }
-    }
-
-    callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
-                            dexIdx, methodIdx, skipThis);
-
-    if (pcrLabel) {
-        *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
-    }
-#endif
-    return callState;
-}
-
-/*
- * May have 0+ arguments (also used for jumbo).  Note that
- * source virtual registers may be in physical registers, so may
- * need to be flushed to home location before copying.  This
- * applies to arg3 and above (see below).
- *
- * Two general strategies:
- *    If < 20 arguments
- *       Pass args 3-18 using vldm/vstm block copy
- *       Pass arg0, arg1 & arg2 in r1-r3
- *    If 20+ arguments
- *       Pass args arg19+ using memcpy block copy
- *       Pass arg0, arg1 & arg2 in r1-r3
- *
- */
-STATIC int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
-                              DecodedInstruction* dInsn, int callState,
-                              MipsLIR** pcrLabel, NextCallInsn nextCallInsn,
-                              uint32_t dexIdx, uint32_t methodIdx,
-                              bool skipThis)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    int firstArg = dInsn->vC;
-    int numArgs = dInsn->vA;
-
-    // If we can treat it as non-range (Jumbo ops will use range form)
-    if (numArgs <= 5)
-        return genDalvikArgsNoRange(cUnit, mir, dInsn, callState, pcrLabel,
-                                    nextCallInsn, dexIdx, methodIdx,
-                                    skipThis);
-    /*
-     * Make sure range list doesn't span the break between in normal
-     * Dalvik vRegs and the ins.
-     */
-    int highestArg = oatGetSrc(cUnit, mir, numArgs-1).sRegLow;
-    int boundaryReg = cUnit->numDalvikRegisters - cUnit->numIns;
-    if ((firstArg < boundaryReg) && (highestArg >= boundaryReg)) {
-        LOG(FATAL) << "Argument list spanned locals & args";
-    }
-
-    /*
-     * First load the non-register arguments.  Both forms expect all
-     * of the source arguments to be in their home frame location, so
-     * scan the sReg names and flush any that have been promoted to
-     * frame backing storage.
-     */
-    // Scan the rest of the args - if in physReg flush to memory
-    for (int nextArg = 0; nextArg < numArgs;) {
-        RegLocation loc = oatGetRawSrc(cUnit, mir, nextArg);
-        if (loc.wide) {
-            loc = oatUpdateLocWide(cUnit, loc);
-            if ((nextArg >= 2) && (loc.location == kLocPhysReg)) {
-                storeBaseDispWide(cUnit, rSP,
-                                  oatSRegOffset(cUnit, loc.sRegLow),
-                                  loc.lowReg, loc.highReg);
-            }
-            nextArg += 2;
-        } else {
-            loc = oatUpdateLoc(cUnit, loc);
-            if ((nextArg >= 3) && (loc.location == kLocPhysReg)) {
-                storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, loc.sRegLow),
-                              loc.lowReg, kWord);
-            }
-            nextArg++;
-        }
-    }
-
-    int startOffset = oatSRegOffset(cUnit,
-        cUnit->regLocation[mir->ssaRep->uses[3]].sRegLow);
-    int outsOffset = 4 /* Method* */ + (3 * 4);
-    if (numArgs >= 20) {
-        // Generate memcpy
-        opRegRegImm(cUnit, kOpAdd, r0, rSP, outsOffset);
-        opRegRegImm(cUnit, kOpAdd, r1, rSP, startOffset);
-        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pMemcpy), rLR);
-        loadConstant(cUnit, r2, (numArgs - 3) * 4);
-        callRuntimeHelper(cUnit, rLR);
-        // Restore Method*
-        loadCurrMethodDirect(cUnit, r0);
-    } else {
-        // Use vldm/vstm pair using r3 as a temp
-        int regsLeft = std::min(numArgs - 3, 16);
-        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-        opRegRegImm(cUnit, kOpAdd, r3, rSP, startOffset);
-        MipsLIR* ld = newLIR3(cUnit, kThumb2Vldms, r3, fr0, regsLeft);
-        //TUNING: loosen barrier
-        ld->defMask = ENCODE_ALL;
-        setMemRefType(ld, true /* isLoad */, kDalvikReg);
-        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-        opRegRegImm(cUnit, kOpAdd, r3, rSP, 4 /* Method* */ + (3 * 4));
-        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-        MipsLIR* st = newLIR3(cUnit, kThumb2Vstms, r3, fr0, regsLeft);
-        setMemRefType(st, false /* isLoad */, kDalvikReg);
-        st->defMask = ENCODE_ALL;
-        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-    }
-
-    callState = loadArgRegs(cUnit, mir, dInsn, callState, nextCallInsn,
-                            dexIdx, methodIdx, skipThis);
-
-    callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
-    if (pcrLabel) {
-        *pcrLabel = genNullCheck(cUnit, oatSSASrc(mir,0), r1, mir);
-    }
-#endif
-    return callState;
-}
-
-// Debugging routine - if null target, branch to DebugMe
-STATIC void genShowTarget(CompilationUnit* cUnit)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsLIR* branchOver = opCmpImmBranch(cUnit, kMipsCondNe, rLR, 0);
-    loadWordDisp(cUnit, rSELF,
-                 OFFSETOF_MEMBER(Thread, pDebugMe), rLR);
-    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-    target->defMask = -1;
-    branchOver->generic.target = (LIR*)target;
-#endif
-}
-
-STATIC void genThrowVerificationError(CompilationUnit* cUnit, MIR* mir)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    loadWordDisp(cUnit, rSELF,
-                 OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode), rLR);
-    loadConstant(cUnit, r0, mir->dalvikInsn.vA);
-    loadConstant(cUnit, r1, mir->dalvikInsn.vB);
-    callRuntimeHelper(cUnit, rLR);
-#endif
-}
-
-STATIC void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
-                                MIR* mir, RegLocation rlSrc1,
-                                RegLocation rlSrc2, MipsLIR* labelList)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsConditionCode cond;
-    rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
-    rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
-    opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
-    Opcode opcode = mir->dalvikInsn.opcode;
-    switch(opcode) {
-        case OP_IF_EQ:
-            cond = kMipsCondEq;
-            break;
-        case OP_IF_NE:
-            cond = kMipsCondNe;
-            break;
-        case OP_IF_LT:
-            cond = kMipsCondLt;
-            break;
-        case OP_IF_GE:
-            cond = kMipsCondGe;
-            break;
-        case OP_IF_GT:
-            cond = kMipsCondGt;
-            break;
-        case OP_IF_LE:
-            cond = kMipsCondLe;
-            break;
-        default:
-            cond = (MipsConditionCode)0;
-            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
-    }
-    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
-    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
-#endif
-}
-
-STATIC void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
-                                   MIR* mir, RegLocation rlSrc,
-                                   MipsLIR* labelList)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsConditionCode cond;
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
-    Opcode opcode = mir->dalvikInsn.opcode;
-    switch(opcode) {
-        case OP_IF_EQZ:
-            cond = kMipsCondEq;
-            break;
-        case OP_IF_NEZ:
-            cond = kMipsCondNe;
-            break;
-        case OP_IF_LTZ:
-            cond = kMipsCondLt;
-            break;
-        case OP_IF_GEZ:
-            cond = kMipsCondGe;
-            break;
-        case OP_IF_GTZ:
-            cond = kMipsCondGt;
-            break;
-        case OP_IF_LEZ:
-            cond = kMipsCondLe;
-            break;
-        default:
-            cond = (MipsConditionCode)0;
-            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
-    }
-    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
-    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
-#endif
-}
-
-STATIC void genIntToLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                         RegLocation rlSrc)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    if (rlSrc.location == kLocPhysReg) {
-        genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
-    } else {
-        loadValueDirect(cUnit, rlSrc, rlResult.lowReg);
-    }
-    opRegRegImm(cUnit, kOpAsr, rlResult.highReg,
-                rlResult.lowReg, 31);
-    storeValueWide(cUnit, rlDest, rlResult);
-#endif
-}
-
-STATIC void genIntNarrowing(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlDest, RegLocation rlSrc)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-     rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-     RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-     OpKind op = kOpInvalid;
-     switch(mir->dalvikInsn.opcode) {
-         case OP_INT_TO_BYTE:
-             op = kOp2Byte;
-             break;
-         case OP_INT_TO_SHORT:
-              op = kOp2Short;
-              break;
-         case OP_INT_TO_CHAR:
-              op = kOp2Char;
-              break;
-         default:
-             LOG(ERROR) << "Bad int conversion type";
-     }
-     opRegReg(cUnit, op, rlResult.lowReg, rlSrc.lowReg);
-     storeValue(cUnit, rlDest, rlResult);
-#endif
-}
-
-/*
- * If there are any ins passed in registers that have not been promoted
- * to a callee-save register, flush them to the frame.  Perform intial
- * assignment of promoted arguments.
- */
-STATIC void flushIns(CompilationUnit* cUnit)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    if (cUnit->numIns == 0)
+    if (cUnit->numCoreSpills == 0) {
         return;
-    int firstArgReg = r1;
-    int lastArgReg = r3;
-    int startVReg = cUnit->numDalvikRegisters - cUnit->numIns;
-    /*
-     * Arguments passed in registers should be flushed
-     * to their backing locations in the frame for now.
-     * Also, we need to do initial assignment for promoted
-     * arguments.  NOTE: an older version of dx had an issue
-     * in which it would reuse static method argument registers.
-     * This could result in the same Dalvik virtual register
-     * being promoted to both core and fp regs.  In those
-     * cases, copy argument to both.  This will be uncommon
-     * enough that it isn't worth attempting to optimize.
-     */
-    for (int i = 0; i < cUnit->numIns; i++) {
-        PromotionMap vMap = cUnit->promotionMap[startVReg + i];
-        if (i <= (lastArgReg - firstArgReg)) {
-            // If arriving in register
-            if (vMap.coreLocation == kLocPhysReg) {
-                genRegCopy(cUnit, vMap.coreReg, firstArgReg + i);
-            }
-            if (vMap.fpLocation == kLocPhysReg) {
-                genRegCopy(cUnit, vMap.fpReg, firstArgReg + i);
-            }
-            // Also put a copy in memory in case we're partially promoted
-            storeBaseDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
-                          firstArgReg + i, kWord);
-        } else {
-            // If arriving in frame & promoted
-            if (vMap.coreLocation == kLocPhysReg) {
-                loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
-                             vMap.coreReg);
-            }
-            if (vMap.fpLocation == kLocPhysReg) {
-                loadWordDisp(cUnit, rSP, oatSRegOffset(cUnit, startVReg + i),
-                             vMap.fpReg);
-            }
+    }
+    uint32_t mask = cUnit->coreSpillMask;
+    int offset = cUnit->numCoreSpills * 4;
+    opRegImm(cUnit, kOpSub, rSP, offset);
+    for (int reg = 0; mask; mask >>= 1, reg++) {
+        if (mask & 0x1) {
+            offset -= 4;
+            storeWordDisp(cUnit, rSP, offset, reg);
         }
     }
-#endif
 }
 
-STATIC void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
+void unSpillCoreRegs(CompilationUnit* cUnit)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
+    if (cUnit->numCoreSpills == 0) {
+        return;
+    }
+    uint32_t mask = cUnit->coreSpillMask;
+    int offset = cUnit->frameSize;
+    for (int reg = 0; mask; mask >>= 1, reg++) {
+        if (mask & 0x1) {
+            offset -= 4;
+            loadWordDisp(cUnit, rSP, offset, reg);
+        }
+    }
+    opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize);
+}
+
+void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
+{
     int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
     /*
-     * On entry, r0, r1, r2 & r3 are live.  Let the register allocation
-     * mechanism know so it doesn't try to use any of them when
+     * On entry, rARG0, rARG1, rARG2 & rARG3 are live.  Let the register
+     * allocation mechanism know so it doesn't try to use any of them when
      * expanding the frame or flushing.  This leaves the utility
      * code with a single temp: r12.  This should be enough.
      */
-    oatLockTemp(cUnit, r0);
-    oatLockTemp(cUnit, r1);
-    oatLockTemp(cUnit, r2);
-    oatLockTemp(cUnit, r3);
+    oatLockTemp(cUnit, rARG0);
+    oatLockTemp(cUnit, rARG1);
+    oatLockTemp(cUnit, rARG2);
+    oatLockTemp(cUnit, rARG3);
 
     /*
      * We can safely skip the stack overflow check if we're
@@ -1121,33 +93,28 @@
                               ((size_t)cUnit->frameSize <
                               Thread::kStackOverflowReservedBytes));
     newLIR0(cUnit, kPseudoMethodEntry);
+    int checkReg = oatAllocTemp(cUnit);
+    int newSP = oatAllocTemp(cUnit);
     if (!skipOverflowCheck) {
         /* Load stack limit */
         loadWordDisp(cUnit, rSELF,
-                     Thread::StackEndOffset().Int32Value(), r12);
+                     Thread::StackEndOffset().Int32Value(), checkReg);
     }
     /* Spill core callee saves */
-    newLIR1(cUnit, kThumb2Push, cUnit->coreSpillMask);
-    /* Need to spill any FP regs? */
-    if (cUnit->numFPSpills) {
-        /*
-         * NOTE: fp spills are a little different from core spills in that
-         * they are pushed as a contiguous block.  When promoting from
-         * the fp set, we must allocate all singles from s16..highest-promoted
-         */
-        newLIR1(cUnit, kThumb2VPushCS, cUnit->numFPSpills);
-    }
+    spillCoreRegs(cUnit);
+    /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
+    DCHECK_EQ(cUnit->numFPSpills, 0);
     if (!skipOverflowCheck) {
-        opRegRegImm(cUnit, kOpSub, rLR, rSP,
+        opRegRegImm(cUnit, kOpSub, newSP, rSP,
                     cUnit->frameSize - (spillCount * 4));
-        genRegRegCheck(cUnit, kMipsCondCc, rLR, r12, NULL,
-                       kMipsThrowStackOverflow);
-        genRegCopy(cUnit, rSP, rLR);         // Establish stack
+        genRegRegCheck(cUnit, kCondCc, newSP, checkReg, NULL,
+                       kThrowStackOverflow);
+        genRegCopy(cUnit, rSP, newSP);         // Establish stack
     } else {
         opRegImm(cUnit, kOpSub, rSP,
                  cUnit->frameSize - (spillCount * 4));
     }
-    storeBaseDisp(cUnit, rSP, 0, r0, kWord);
+    storeBaseDisp(cUnit, rSP, 0, rARG0, kWord);
     flushIns(cUnit);
 
     if (cUnit->genDebugger) {
@@ -1157,46 +124,28 @@
         genDebuggerUpdate(cUnit, DEBUGGER_METHOD_ENTRY);
     }
 
-    oatFreeTemp(cUnit, r0);
-    oatFreeTemp(cUnit, r1);
-    oatFreeTemp(cUnit, r2);
-    oatFreeTemp(cUnit, r3);
-#endif
+    oatFreeTemp(cUnit, rARG0);
+    oatFreeTemp(cUnit, rARG1);
+    oatFreeTemp(cUnit, rARG2);
+    oatFreeTemp(cUnit, rARG3);
 }
 
-STATIC void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb)
+void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
     /*
-     * In the exit path, r0/r1 are live - make sure they aren't
+     * In the exit path, rRET0/rRET1 are live - make sure they aren't
      * allocated by the register utilities as temps.
      */
-    oatLockTemp(cUnit, r0);
-    oatLockTemp(cUnit, r1);
+    oatLockTemp(cUnit, rRET0);
+    oatLockTemp(cUnit, rRET1);
 
     newLIR0(cUnit, kPseudoMethodExit);
     /* If we're compiling for the debugger, generate an update callout */
     if (cUnit->genDebugger) {
         genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT);
     }
-    opRegImm(cUnit, kOpAdd, rSP, cUnit->frameSize - (spillCount * 4));
-    /* Need to restore any FP callee saves? */
-    if (cUnit->numFPSpills) {
-        newLIR1(cUnit, kThumb2VPopCS, cUnit->numFPSpills);
-    }
-    if (cUnit->coreSpillMask & (1 << rLR)) {
-        /* Unspill rLR to rPC */
-        cUnit->coreSpillMask &= ~(1 << rLR);
-        cUnit->coreSpillMask |= (1 << rPC);
-    }
-    newLIR1(cUnit, kThumb2Pop, cUnit->coreSpillMask);
-    if (!(cUnit->coreSpillMask & (1 << rPC))) {
-        /* We didn't pop to rPC, so must do a bv rLR */
-        newLIR1(cUnit, kThumbBx, rLR);
-    }
-#endif
+    unSpillCoreRegs(cUnit);
+    opReg(cUnit, kOpBx, rLINK);
 }
 
 /*
@@ -1206,18 +155,15 @@
  */
 void removeRedundantBranches(CompilationUnit* cUnit)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsLIR* thisLIR;
+    LIR* thisLIR;
 
-    for (thisLIR = (MipsLIR*) cUnit->firstLIRInsn;
-         thisLIR != (MipsLIR*) cUnit->lastLIRInsn;
+    for (thisLIR = (LIR*) cUnit->firstLIRInsn;
+         thisLIR != (LIR*) cUnit->lastLIRInsn;
          thisLIR = NEXT_LIR(thisLIR)) {
 
         /* Branch to the next instruction */
-        if ((thisLIR->opcode == kThumbBUncond) ||
-            (thisLIR->opcode == kThumb2BUncond)) {
-            MipsLIR* nextLIR = thisLIR;
+        if (thisLIR->opcode == kMipsB) {
+            LIR* nextLIR = thisLIR;
 
             while (true) {
                 nextLIR = NEXT_LIR(nextLIR);
@@ -1225,7 +171,7 @@
                 /*
                  * Is the branch target the next instruction?
                  */
-                if (nextLIR == (MipsLIR*) thisLIR->generic.target) {
+                if (nextLIR == (LIR*) thisLIR->target) {
                     thisLIR->flags.isNop = true;
                     break;
                 }
@@ -1236,116 +182,13 @@
                  * might be the last real instruction.
                  */
                 if (!isPseudoOpcode(nextLIR->opcode) ||
-                    (nextLIR = (MipsLIR*) cUnit->lastLIRInsn))
+                    (nextLIR = (LIR*) cUnit->lastLIRInsn))
                     break;
             }
         }
     }
-#endif
 }
 
-STATIC void handleSuspendLaunchpads(CompilationUnit *cUnit)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsLIR** suspendLabel =
-        (MipsLIR **) cUnit->suspendLaunchpads.elemList;
-    int numElems = cUnit->suspendLaunchpads.numUsed;
-
-    for (int i = 0; i < numElems; i++) {
-        /* TUNING: move suspend count load into helper */
-        MipsLIR* lab = suspendLabel[i];
-        MipsLIR* resumeLab = (MipsLIR*)lab->operands[0];
-        cUnit->currentDalvikOffset = lab->operands[1];
-        oatAppendLIR(cUnit, (LIR *)lab);
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pTestSuspendFromCode), rLR);
-        if (!cUnit->genDebugger) {
-            // use rSUSPEND for suspend count
-            loadWordDisp(cUnit, rSELF,
-                         Thread::SuspendCountOffset().Int32Value(), rSUSPEND);
-        }
-        opReg(cUnit, kOpBlx, rLR);
-        if ( cUnit->genDebugger) {
-            // use rSUSPEND for update debugger
-            loadWordDisp(cUnit, rSELF,
-                         OFFSETOF_MEMBER(Thread, pUpdateDebuggerFromCode), rSUSPEND);
-        }
-        genUnconditionalBranch(cUnit, resumeLab);
-    }
-#endif
-}
-
-STATIC void handleThrowLaunchpads(CompilationUnit *cUnit)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
-    MipsLIR** throwLabel =
-        (MipsLIR **) cUnit->throwLaunchpads.elemList;
-    int numElems = cUnit->throwLaunchpads.numUsed;
-    int i;
-
-    for (i = 0; i < numElems; i++) {
-        MipsLIR* lab = throwLabel[i];
-        cUnit->currentDalvikOffset = lab->operands[1];
-        oatAppendLIR(cUnit, (LIR *)lab);
-        int funcOffset = 0;
-        int v1 = lab->operands[2];
-        int v2 = lab->operands[3];
-        switch(lab->operands[0]) {
-            case kMipsThrowNullPointer:
-                funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
-                break;
-            case kMipsThrowArrayBounds:
-                if (v2 != r0) {
-                    genRegCopy(cUnit, r0, v1);
-                    genRegCopy(cUnit, r1, v2);
-                } else {
-                    if (v1 == r1) {
-                        genRegCopy(cUnit, r12, v1);
-                        genRegCopy(cUnit, r1, v2);
-                        genRegCopy(cUnit, r0, r12);
-                    } else {
-                        genRegCopy(cUnit, r1, v2);
-                        genRegCopy(cUnit, r0, v1);
-                    }
-                }
-                funcOffset = OFFSETOF_MEMBER(Thread, pThrowArrayBoundsFromCode);
-                break;
-            case kMipsThrowDivZero:
-                funcOffset = OFFSETOF_MEMBER(Thread, pThrowDivZeroFromCode);
-                break;
-            case kMipsThrowVerificationError:
-                loadConstant(cUnit, r0, v1);
-                loadConstant(cUnit, r1, v2);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode);
-                break;
-            case kMipsThrowNegArraySize:
-                genRegCopy(cUnit, r0, v1);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
-                break;
-            case kMipsThrowNoSuchMethod:
-                genRegCopy(cUnit, r0, v1);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
-                break;
-            case kMipsThrowStackOverflow:
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowStackOverflowFromCode);
-                // Restore stack alignment
-                opRegImm(cUnit, kOpAdd, rSP,
-                         (cUnit->numCoreSpills + cUnit->numFPSpills) * 4);
-                break;
-            default:
-                LOG(FATAL) << "Unexpected throw kind: " << lab->operands[0];
-        }
-        loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-        callRuntimeHelper(cUnit, rLR);
-    }
-#endif
-}
 
 /* Common initialization routine for an architecture family */
 bool oatArchInit()
@@ -1363,10 +206,4 @@
     return oatArchVariantInit();
 }
 
-/* Needed by the Assembler */
-void oatSetupResourceMasks(MipsLIR* lir)
-{
-    setupResourceMasks(lir);
-}
-
 }  // namespace art
diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc
index 2e8d417..7f7aeb3 100644
--- a/src/compiler/codegen/mips/ArchUtility.cc
+++ b/src/compiler/codegen/mips/ArchUtility.cc
@@ -22,6 +22,33 @@
 
 namespace art {
 
+MipsConditionCode oatMipsConditionEncoding(ConditionCode code)
+{
+    MipsConditionCode res;
+    switch(code) {
+        case kCondEq: res = kMipsCondEq; break;
+        case kCondNe: res = kMipsCondNe; break;
+        case kCondCs: res = kMipsCondCs; break;
+        case kCondCc: res = kMipsCondCc; break;
+        case kCondMi: res = kMipsCondMi; break;
+        case kCondPl: res = kMipsCondPl; break;
+        case kCondVs: res = kMipsCondVs; break;
+        case kCondVc: res = kMipsCondVc; break;
+        case kCondHi: res = kMipsCondHi; break;
+        case kCondLs: res = kMipsCondLs; break;
+        case kCondGe: res = kMipsCondGe; break;
+        case kCondLt: res = kMipsCondLt; break;
+        case kCondGt: res = kMipsCondGt; break;
+        case kCondLe: res = kMipsCondLe; break;
+        case kCondAl: res = kMipsCondAl; break;
+        case kCondNv: res = kMipsCondNv; break;
+        default:
+            LOG(FATAL) << "Bad condition code" << (int)code;
+            res = (MipsConditionCode)0;  // Quiet gcc
+    }
+    return res;
+}
+
 /* For dumping instructions */
 #define MIPS_REG_COUNT 32
 static const char *mipsRegName[MIPS_REG_COUNT] = {
@@ -35,7 +62,7 @@
  * Interpret a format string and build a string no longer than size
  * See format key in Assemble.c.
  */
-STATIC std::string buildInsnString(const char *fmt, MipsLIR *lir, unsigned char* baseAddr)
+std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr)
 {
     std::string buf;
     int i;
@@ -118,9 +145,9 @@
                        break;
                    case 't':
                        sprintf(tbuf,"0x%08x (L%p)",
-                               (int) baseAddr + lir->generic.offset + 4 +
+                               (int) baseAddr + lir->offset + 4 +
                                (operand << 2),
-                               lir->generic.target);
+                               lir->target);
                        break;
                    case 'T':
                        sprintf(tbuf,"0x%08x",
@@ -130,7 +157,7 @@
                        int offset_1 = lir->operands[0];
                        int offset_2 = NEXT_LIR(lir)->operands[0];
                        intptr_t target =
-                           ((((intptr_t) baseAddr + lir->generic.offset + 4) &
+                           ((((intptr_t) baseAddr + lir->offset + 4) &
                             ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
                            0xfffffffc;
                        sprintf(tbuf, "%p", (void *) target);
@@ -163,7 +190,7 @@
 {
     char buf[256];
     buf[0] = 0;
-    MipsLIR *mipsLIR = (MipsLIR *) lir;
+    LIR *mipsLIR = (LIR *) lir;
 
     if (mask == ENCODE_ALL) {
         strcpy(buf, "all");
@@ -205,180 +232,4 @@
     }
 }
 
-/*
- * Debugging macros
- */
-#define DUMP_RESOURCE_MASK(X)
-#define DUMP_SSA_REP(X)
-
-/* Pretty-print a LIR instruction */
-void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
-{
-    MipsLIR* lir = (MipsLIR*) arg;
-    int offset = lir->generic.offset;
-    int dest = lir->operands[0];
-    const bool dumpNop = false;
-
-    /* Handle pseudo-ops individually, and all regular insns as a group */
-    switch(lir->opcode) {
-        case kPseudoMethodEntry:
-            LOG(INFO) << "-------- method entry " <<
-                PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
-            break;
-        case kPseudoMethodExit:
-            LOG(INFO) << "-------- Method_Exit";
-            break;
-        case kPseudoBarrier:
-            LOG(INFO) << "-------- BARRIER";
-            break;
-        case kPseudoExtended:
-            LOG(INFO) << "-------- " << (char* ) dest;
-            break;
-        case kPseudoSSARep:
-            DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
-            break;
-        case kPseudoEntryBlock:
-            LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
-            break;
-        case kPseudoDalvikByteCodeBoundary:
-            LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
-                 lir->generic.dalvikOffset << " @ " << (char* )lir->operands[0];
-            break;
-        case kPseudoExitBlock:
-            LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
-            break;
-        case kPseudoPseudoAlign4:
-            LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
-                offset << "): .align4";
-            break;
-        case kPseudoEHBlockLabel:
-            LOG(INFO) << "Exception_Handling:";
-            break;
-        case kPseudoTargetLabel:
-        case kPseudoNormalBlockLabel:
-            LOG(INFO) << "L" << (intptr_t)lir << ":";
-            break;
-        case kPseudoThrowTarget:
-            LOG(INFO) << "LT" << (intptr_t)lir << ":";
-            break;
-        case kPseudoSuspendTarget:
-            LOG(INFO) << "LS" << (intptr_t)lir << ":";
-            break;
-        case kPseudoCaseLabel:
-            LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" <<
-                std::hex << lir->operands[0] << "|" << std::dec <<
-                lir->operands[0];
-            break;
-        default:
-            if (lir->flags.isNop && !dumpNop) {
-                break;
-            } else {
-                std::string op_name(buildInsnString(EncodingMap[lir->opcode].name, lir, baseAddr));
-                std::string op_operands(buildInsnString(EncodingMap[lir->opcode].fmt, lir, baseAddr));
-                LOG(INFO) << StringPrintf("%p (%04x): %-9s%s%s", baseAddr + offset, offset,
-                    op_name.c_str(), op_operands.c_str(), lir->flags.isNop ? "(nop)" : "");
-            }
-            break;
-    }
-
-    if (lir->useMask && (!lir->flags.isNop || dumpNop)) {
-        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
-                                               lir->useMask, "use"));
-    }
-    if (lir->defMask && (!lir->flags.isNop || dumpNop)) {
-        DUMP_RESOURCE_MASK(oatDumpResourceMask((LIR* ) lir,
-                                               lir->defMask, "def"));
-    }
-}
-
-void oatDumpPromotionMap(CompilationUnit *cUnit)
-{
-    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
-        PromotionMap vRegMap = cUnit->promotionMap[i];
-        char buf[100];
-        if (vRegMap.fpLocation == kLocPhysReg) {
-            snprintf(buf, 100, " : s%d", vRegMap.fpReg & FP_REG_MASK);
-        } else {
-            buf[0] = 0;
-        }
-        char buf2[100];
-        snprintf(buf2, 100, "V[%02d] -> %s%d%s", i,
-                 vRegMap.coreLocation == kLocPhysReg ?
-                 "r" : "SP+", vRegMap.coreLocation == kLocPhysReg ?
-                 vRegMap.coreReg : oatSRegOffset(cUnit, i), buf);
-        LOG(INFO) << buf2;
-    }
-}
-
-void oatDumpFullPromotionMap(CompilationUnit *cUnit)
-{
-    for (int i = 0; i < cUnit->numDalvikRegisters; i++) {
-        PromotionMap vRegMap = cUnit->promotionMap[i];
-        LOG(INFO) << i << " -> " << "CL:" << (int)vRegMap.coreLocation <<
-            ", CR:" << (int)vRegMap.coreReg << ", FL:" <<
-            (int)vRegMap.fpLocation << ", FR:" << (int)vRegMap.fpReg <<
-            ", - " << (int)vRegMap.firstInPair;
-    }
-}
-
-/* Dump instructions and constant pool contents */
-void oatCodegenDump(CompilationUnit* cUnit)
-{
-    LOG(INFO) << "/*";
-    LOG(INFO) << "Dumping LIR insns for "
-        << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
-    LIR* lirInsn;
-    MipsLIR* mipsLIR;
-    int insnsSize = cUnit->insnsSize;
-
-    LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs;
-    LOG(INFO) << "Ins                  : " << cUnit->numIns;
-    LOG(INFO) << "Outs                 : " << cUnit->numOuts;
-    LOG(INFO) << "CoreSpills           : " << cUnit->numCoreSpills;
-    LOG(INFO) << "FPSpills             : " << cUnit->numFPSpills;
-    LOG(INFO) << "Padding              : " << cUnit->numPadding;
-    LOG(INFO) << "Frame size           : " << cUnit->frameSize;
-    LOG(INFO) << "Start of ins         : " << cUnit->insOffset;
-    LOG(INFO) << "Start of regs        : " << cUnit->regsOffset;
-    LOG(INFO) << "code size is " << cUnit->totalSize <<
-        " bytes, Dalvik size is " << insnsSize * 2;
-    LOG(INFO) << "expansion factor: " <<
-         (float)cUnit->totalSize / (float)(insnsSize * 2);
-    oatDumpPromotionMap(cUnit);
-    for (lirInsn = cUnit->firstLIRInsn; lirInsn; lirInsn = lirInsn->next) {
-        oatDumpLIRInsn(cUnit, lirInsn, 0);
-    }
-    for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) {
-        mipsLIR = (MipsLIR*) lirInsn;
-        LOG(INFO) << StringPrintf("%x (%04x): .class (%s)",
-            mipsLIR->generic.offset, mipsLIR->generic.offset,
-            ((CallsiteInfo *) mipsLIR->operands[0])->classDescriptor);
-    }
-    for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) {
-        mipsLIR = (MipsLIR*) lirInsn;
-        LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)",
-            mipsLIR->generic.offset, mipsLIR->generic.offset, mipsLIR->operands[0]);
-    }
-
-    const DexFile::MethodId& method_id =
-        cUnit->dex_file->GetMethodId(cUnit->method_idx);
-    std::string signature(cUnit->dex_file->GetMethodSignature(method_id));
-    std::string name(cUnit->dex_file->GetMethodName(method_id));
-    std::string descriptor(cUnit->dex_file->GetMethodDeclaringClassDescriptor(method_id));
-
-    // Dump mapping table
-    if (cUnit->mappingTable.size() > 0) {
-        std::string line(StringPrintf("\n    MappingTable %s%s_%s_mappingTable[%zu] = {",
-            descriptor.c_str(), name.c_str(), signature.c_str(), cUnit->mappingTable.size()));
-        std::replace(line.begin(), line.end(), ';', '_');
-        LOG(INFO) << line;
-        for (uint32_t i = 0; i < cUnit->mappingTable.size(); i+=2) {
-            line = StringPrintf("        {0x%08x, 0x%04x},",
-                cUnit->mappingTable[i], cUnit->mappingTable[i+1]);
-            LOG(INFO) << line;
-        }
-        LOG(INFO) <<"    };\n\n";
-    }
-}
-
 } // namespace art
diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc
index 5b6e6ed..cb355c0 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/Assemble.cc
@@ -75,7 +75,7 @@
  *
  *  [!] escape.  To insert "!", use "!!"
  */
-/* NOTE: must be kept in sync with enum MipsOpcode from MipsLIR.h */
+/* NOTE: must be kept in sync with enum MipsOpcode from LIR.h */
 MipsEncodingMap EncodingMap[kMipsLast] = {
     ENCODING_MAP(kMips32BitData, 0x00000000,
                  kFmtBitBlt, 31, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
@@ -406,12 +406,10 @@
 AssemblerStatus oatAssembleInstructions(CompilationUnit *cUnit,
                                         intptr_t startAddr)
 {
-    UNIMPLEMENTED(FATAL) << "Rework for art code buffer";
-#if 0
-    int *bufferAddr = (int *) cUnit->codeBuffer;
-    MipsLIR *lir;
+    LIR *lir;
+    AssemblerStatus res = kSuccess;  // Assume success
 
-    for (lir = (MipsLIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) {
+    for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) {
         if (lir->opcode < 0) {
             continue;
         }
@@ -422,43 +420,43 @@
         }
 
         if (lir->opcode == kMipsB || lir->opcode == kMipsBal) {
-            MipsLIR *targetLIR = (MipsLIR *) lir->generic.target;
-            intptr_t pc = lir->generic.offset + 4;
-            intptr_t target = targetLIR->generic.offset;
+            LIR *targetLIR = (LIR *) lir->target;
+            intptr_t pc = lir->offset + 4;
+            intptr_t target = targetLIR->offset;
             int delta = target - pc;
             if (delta & 0x3) {
                 LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta;
             }
             if (delta > 131068 || delta < -131069) {
-                LOG(FATAL) << "Unconditional branch out of range: " << delta;
+                UNIMPLEMENTED(FATAL) << "B out of range, need long sequence: " << delta;
             }
             lir->operands[0] = delta >> 2;
         } else if (lir->opcode >= kMipsBeqz && lir->opcode <= kMipsBnez) {
-            MipsLIR *targetLIR = (MipsLIR *) lir->generic.target;
-            intptr_t pc = lir->generic.offset + 4;
-            intptr_t target = targetLIR->generic.offset;
+            LIR *targetLIR = (LIR *) lir->target;
+            intptr_t pc = lir->offset + 4;
+            intptr_t target = targetLIR->offset;
             int delta = target - pc;
             if (delta & 0x3) {
                 LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta;
             }
             if (delta > 131068 || delta < -131069) {
-                LOG(FATAL) << "Conditional branch out of range: " << delta;
+                UNIMPLEMENTED(FATAL) << "B[eq|ne]z needs long sequence: " << delta;
             }
             lir->operands[1] = delta >> 2;
         } else if (lir->opcode == kMipsBeq || lir->opcode == kMipsBne) {
-            MipsLIR *targetLIR = (MipsLIR *) lir->generic.target;
-            intptr_t pc = lir->generic.offset + 4;
-            intptr_t target = targetLIR->generic.offset;
+            LIR *targetLIR = (LIR *) lir->target;
+            intptr_t pc = lir->offset + 4;
+            intptr_t target = targetLIR->offset;
             int delta = target - pc;
             if (delta & 0x3) {
                 LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta;
             }
             if (delta > 131068 || delta < -131069) {
-                LOG(FATAL) << "Conditional branch out of range: " << delta;
+                UNIMPLEMENTED(FATAL) << "B[eq|ne] needs long sequence: " << delta;
             }
             lir->operands[2] = delta >> 2;
         } else if (lir->opcode == kMipsJal) {
-            intptr_t curPC = (startAddr + lir->generic.offset + 4) & ~3;
+            intptr_t curPC = (startAddr + lir->offset + 4) & ~3;
             intptr_t target = lir->operands[0];
             /* ensure PC-region branch can be used */
             DCHECK_EQ((curPC & 0xF0000000), (target & 0xF0000000));
@@ -467,16 +465,24 @@
             }
             lir->operands[0] =  target >> 2;
         } else if (lir->opcode == kMipsLahi) { /* load address hi (via lui) */
-            MipsLIR *targetLIR = (MipsLIR *) lir->generic.target;
-            intptr_t target = startAddr + targetLIR->generic.offset;
+            LIR *targetLIR = (LIR *) lir->target;
+            intptr_t target = startAddr + targetLIR->offset;
             lir->operands[1] = target >> 16;
         } else if (lir->opcode == kMipsLalo) { /* load address lo (via ori) */
-            MipsLIR *targetLIR = (MipsLIR *) lir->generic.target;
-            intptr_t target = startAddr + targetLIR->generic.offset;
+            LIR *targetLIR = (LIR *) lir->target;
+            intptr_t target = startAddr + targetLIR->offset;
             lir->operands[2] = lir->operands[2] + target;
         }
 
-        MipsEncodingMap *encoder = &EncodingMap[lir->opcode];
+        /*
+         * If one of the pc-relative instructions expanded we'll have
+         * to make another pass.  Don't bother to fully assemble the
+         * instruction.
+         */
+        if (res != kSuccess) {
+            continue;
+        }
+        const MipsEncodingMap *encoder = &EncodingMap[lir->opcode];
         u4 bits = encoder->skeleton;
         int i;
         for (i = 0; i < 4; i++) {
@@ -497,7 +503,7 @@
                     break;
                 case kFmtDfp: {
                     DCHECK(DOUBLEREG(operand));
-                    DCHECK_EQ((operand & 0x1), 0);
+                    DCHECK((operand & 0x1) == 0);
                     value = ((operand & FP_REG_MASK) << encoder->fieldLoc[i].start) &
                             ((1 << (encoder->fieldLoc[i].end + 1)) - 1);
                     bits |= value;
@@ -511,14 +517,15 @@
                     break;
                 default:
                     LOG(FATAL) << "Bad encoder format: "
-                               << encoder->fieldLoc[i].kind;
+                               << (int)encoder->fieldLoc[i].kind;
             }
         }
         DCHECK_EQ(encoder->size, 2);
-        *bufferAddr++ = bits;
+        // FIXME: need multi-endian handling here
+        cUnit->codeBuffer.push_back((bits >> 16) & 0xffff);
+        cUnit->codeBuffer.push_back(bits & 0xffff);
     }
-#endif
-    return kSuccess;
+    return res;
 }
 
 /*
@@ -528,13 +535,13 @@
  */
 int oatAssignInsnOffsets(CompilationUnit* cUnit)
 {
-    MipsLIR* mipsLIR;
+    LIR* mipsLIR;
     int offset = 0;
 
-    for (mipsLIR = (MipsLIR *) cUnit->firstLIRInsn;
-         mipsLIR;
-         mipsLIR = NEXT_LIR(mipsLIR)) {
-        mipsLIR->generic.offset = offset;
+    for (mipsLIR = (LIR *) cUnit->firstLIRInsn;
+        mipsLIR;
+        mipsLIR = NEXT_LIR(mipsLIR)) {
+        mipsLIR->offset = offset;
         if (mipsLIR->opcode >= 0) {
             if (!mipsLIR->flags.isNop) {
                 mipsLIR->flags.size = EncodingMap[mipsLIR->opcode].size * 2;
diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/Codegen.h
index b350dae..355693c 100644
--- a/src/compiler/codegen/mips/Codegen.h
+++ b/src/compiler/codegen/mips/Codegen.h
@@ -27,30 +27,72 @@
 namespace art {
 
 #if defined(_CODEGEN_C)
-/*
- * loadConstant() sometimes needs to add a small imm to a pre-existing constant
- */
-STATIC MipsLIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                        int value);
-STATIC MipsLIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                        int rSrc2);
+LIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value);
+LIR *opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2);
 
-/* Forward decalraton the portable versions due to circular dependency */
-STATIC bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+/* Forward declaraton the portable versions due to circular dependency */
+bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
                                     RegLocation rlDest, RegLocation rlSrc1,
                                     RegLocation rlSrc2);
 
-STATIC bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
                                      RegLocation rlDest, RegLocation rlSrc1,
                                      RegLocation rlSrc2);
 
-STATIC bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
+bool genConversionPortable(CompilationUnit* cUnit, MIR* mir);
+
+MipsConditionCode oatMipsConditionEncoding(ConditionCode code);
+
+int loadHelper(CompilationUnit* cUnit, int offset);
+LIR* callRuntimeHelper(CompilationUnit* cUnit, int reg);
+RegLocation getRetLoc(CompilationUnit* cUnit);
+LIR* loadConstant(CompilationUnit* cUnit, int reg, int immVal);
+void genRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
+                    int srcLo, int srcHi);
+LIR* genRegCopy(CompilationUnit* cUnit, int rDest, int rSrc);
+LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+                     int checkValue);
+void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
+                     RegLocation rlFree);
+
+
+/*
+ * Return most flexible allowed register class based on size.
+ * Bug: 2813841
+ * Must use a core register for data types narrower than word (due
+ * to possible unaligned load/store.
+ */
+inline RegisterClass oatRegClassBySize(OpSize size)
+{
+    return (size == kUnsignedHalf ||
+            size == kSignedHalf ||
+            size == kUnsignedByte ||
+            size == kSignedByte ) ? kCoreReg : kAnyReg;
+}
+
+/*
+ * Construct an s4 from two consecutive half-words of switch data.
+ * This needs to check endianness because the DEX optimizer only swaps
+ * half-words in instruction stream.
+ *
+ * "switchData" must be 32-bit aligned.
+ */
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+inline s4 s4FromSwitchData(const void* switchData) {
+    return *(s4*) switchData;
+}
+#else
+inline s4 s4FromSwitchData(const void* switchData) {
+    u2* data = switchData;
+    return data[0] | (((s4) data[1]) << 16);
+}
+#endif
 
 #endif
 
-extern void oatSetupResourceMasks(MipsLIR* lir);
+extern void oatSetupResourceMasks(LIR* lir);
 
-extern MipsLIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest,
+extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest,
                                           int rSrc);
 
 }  // namespace art
diff --git a/src/compiler/codegen/mips/CodegenCommon.cc b/src/compiler/codegen/mips/CodegenCommon.cc
deleted file mode 100644
index 8dbb9a3..0000000
--- a/src/compiler/codegen/mips/CodegenCommon.cc
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace art {
-
-/*
- * This file contains codegen and support common to all supported
- * Mips variants.  It is included by:
- *
- *        Codegen-$(TARGET_ARCH_VARIANT).c
- *
- * which combines this common code with specific support found in the
- * applicable directory below this one.
- */
-
-static void setMemRefType(MipsLIR *lir, bool isLoad, int memType)
-{
-    /* MIPSTODO simplify setMemRefType() */
-    u8 *maskPtr;
-    u8 mask = ENCODE_MEM;;
-    DCHECK(EncodingMap[lir->opcode].flags & (IS_LOAD | IS_STORE));
-
-    if (isLoad) {
-        maskPtr = &lir->useMask;
-    } else {
-        maskPtr = &lir->defMask;
-    }
-    /* Clear out the memref flags */
-    *maskPtr &= ~mask;
-    /* ..and then add back the one we need */
-    switch(memType) {
-        case kLiteral:
-            DCHECK(isLoad);
-            *maskPtr |= ENCODE_LITERAL;
-            break;
-        case kDalvikReg:
-            *maskPtr |= ENCODE_DALVIK_REG;
-            break;
-        case kHeapRef:
-            *maskPtr |= ENCODE_HEAP_REF;
-            break;
-        case kMustNotAlias:
-            /* Currently only loads can be marked as kMustNotAlias */
-            DCHECK(!(EncodingMap[lir->opcode].flags & IS_STORE));
-            *maskPtr |= ENCODE_MUST_NOT_ALIAS;
-            break;
-        default:
-            LOG(FATAL) << "Oat: invalid memref kind - " << memType;
-    }
-}
-
-/*
- * Mark load/store instructions that access Dalvik registers through rFP +
- * offset.
- */
-STATIC void annotateDalvikRegAccess(MipsLIR *lir, int regId, bool isLoad)
-{
-    /* MIPSTODO simplify annotateDalvikRegAccess() */
-    setMemRefType(lir, isLoad, kDalvikReg);
-
-    /*
-     * Store the Dalvik register id in aliasInfo. Mark he MSB if it is a 64-bit
-     * access.
-     */
-    lir->aliasInfo = regId;
-    if (DOUBLEREG(lir->operands[0])) {
-        lir->aliasInfo |= 0x80000000;
-    }
-}
-
-/*
- * Decode the register id
- */
-STATIC inline u8 getRegMaskCommon(int reg)
-{
-    u8 seed;
-    int shift;
-    int regId = reg & 0x1f;
-
-    /*
-     * Each double register is equal to a pair of single-precision FP registers
-     */
-    if (!DOUBLEREG(reg)) {
-        seed = 1;
-    } else {
-        DCHECK_EQ((regId & 1), 0); /* double registers must be even */
-        seed = 3;
-    }
-
-    if (FPREG(reg)) {
-       DCHECK_LT(regId, 16); /* only 16 fp regs */
-       shift = kFPReg0;
-    } else if (EXTRAREG(reg)) {
-       DCHECK_LT(regId, 3); /* only 3 extra regs */
-       shift = kFPRegEnd;
-    } else {
-       shift = 0;
-    }
-
-    /* Expand the double register id into single offset */
-    shift += regId;
-    return (seed << shift);
-}
-
-/*
- * Mark the corresponding bit(s).
- */
-STATIC inline void setupRegMask(u8 *mask, int reg)
-{
-    *mask |= getRegMaskCommon(reg);
-}
-
-/*
- * Set up the proper fields in the resource mask
- */
-STATIC void setupResourceMasks(MipsLIR *lir)
-{
-    /* MIPSTODO simplify setupResourceMasks() */
-    int opcode = lir->opcode;
-    int flags;
-
-    if (opcode <= 0) {
-        lir->useMask = lir->defMask = 0;
-        return;
-    }
-
-    flags = EncodingMap[lir->opcode].flags;
-
-    // TODO: do we need this for MIPS?  if so, add to inst table defs
-#if 0
-    if (flags & NEEDS_FIXUP) {
-        lir->flags.pcRelFixup = true;
-    }
-#endif
-
-    /* Set up the mask for resources that are updated */
-    if (flags & (IS_LOAD | IS_STORE)) {
-        /* Default to heap - will catch specialized classes later */
-        setMemRefType(lir, flags & IS_LOAD, kHeapRef);
-    }
-
-    /*
-     * Conservatively assume the branch here will call out a function that in
-     * turn will trash everything.
-     */
-    if (flags & IS_BRANCH) {
-        lir->defMask = lir->useMask = ENCODE_ALL;
-        return;
-    }
-
-    if (flags & REG_DEF0) {
-        setupRegMask(&lir->defMask, lir->operands[0]);
-    }
-
-    if (flags & REG_DEF1) {
-        setupRegMask(&lir->defMask, lir->operands[1]);
-    }
-
-    if (flags & REG_DEF_SP) {
-        lir->defMask |= ENCODE_REG_SP;
-    }
-
-    if (flags & REG_DEF_LR) {
-        lir->defMask |= ENCODE_REG_LR;
-    }
-
-    if (flags & REG_DEF_LIST0) {
-        lir->defMask |= ENCODE_REG_LIST(lir->operands[0]);
-    }
-
-    if (flags & REG_DEF_LIST1) {
-        lir->defMask |= ENCODE_REG_LIST(lir->operands[1]);
-    }
-
-    if (flags & SETS_CCODES) {
-        lir->defMask |= ENCODE_CCODE;
-    }
-
-    // TODO: needed for MIPS?
-    /* Conservatively treat the IT block */
-    if (flags & IS_IT) {
-        lir->defMask = ENCODE_ALL;
-    }
-
-    if (flags & (REG_USE0 | REG_USE1 | REG_USE2 | REG_USE3)) {
-        int i;
-
-        for (i = 0; i < 4; i++) {
-            if (flags & (1 << (kRegUse0 + i))) {
-                setupRegMask(&lir->useMask, lir->operands[i]);
-            }
-        }
-    }
-
-    if (flags & REG_USE_PC) {
-        lir->useMask |= ENCODE_REG_PC;
-    }
-
-    if (flags & REG_USE_SP) {
-        lir->useMask |= ENCODE_REG_SP;
-    }
-
-    if (flags & REG_USE_LIST0) {
-        lir->useMask |= ENCODE_REG_LIST(lir->operands[0]);
-    }
-
-    if (flags & REG_USE_LIST1) {
-        lir->useMask |= ENCODE_REG_LIST(lir->operands[1]);
-    }
-
-    if (flags & USES_CCODES) {
-        lir->useMask |= ENCODE_CCODE;
-    }
-}
-
-/*
- * The following are building blocks to construct low-level IRs with 0 - 4
- * operands.
- */
-MipsLIR *newLIR0(CompilationUnit *cUnit, MipsOpCode opcode)
-{
-    MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND));
-    insn->opcode = opcode;
-    setupResourceMasks(insn);
-    insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    oatAppendLIR(cUnit, (LIR *) insn);
-    return insn;
-}
-
-MipsLIR *newLIR1(CompilationUnit *cUnit, MipsOpCode opcode,
-                           int dest)
-{
-    MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP));
-    insn->opcode = opcode;
-    insn->operands[0] = dest;
-    setupResourceMasks(insn);
-    insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    oatAppendLIR(cUnit, (LIR *) insn);
-    return insn;
-}
-
-MipsLIR *newLIR2(CompilationUnit *cUnit, MipsOpCode opcode,
-                           int dest, int src1)
-{
-    MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpcode(opcode) ||
-           (EncodingMap[opcode].flags & IS_BINARY_OP));
-    insn->opcode = opcode;
-    insn->operands[0] = dest;
-    insn->operands[1] = src1;
-    setupResourceMasks(insn);
-    insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    oatAppendLIR(cUnit, (LIR *) insn);
-    return insn;
-}
-
-MipsLIR *newLIR3(CompilationUnit *cUnit, MipsOpCode opcode,
-                           int dest, int src1, int src2)
-{
-    MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    if (!(EncodingMap[opcode].flags & IS_TERTIARY_OP)) {
-        LOG(FATAL) << "Bad LIR3: " << EncodingMap[opcode].name;
-    }
-    DCHECK(isPseudoOpcode(opcode) ||
-           (EncodingMap[opcode].flags & IS_TERTIARY_OP));
-    insn->opcode = opcode;
-    insn->operands[0] = dest;
-    insn->operands[1] = src1;
-    insn->operands[2] = src2;
-    setupResourceMasks(insn);
-    insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    oatAppendLIR(cUnit, (LIR *) insn);
-    return insn;
-}
-
-MipsLIR *newLIR4(CompilationUnit *cUnit, MipsOpCode opcode,
-                           int dest, int src1, int src2, int info)
-{
-    MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpcode(opcode) ||
-           (EncodingMap[opcode].flags & IS_QUAD_OP));
-    insn->opcode = opcode;
-    insn->operands[0] = dest;
-    insn->operands[1] = src1;
-    insn->operands[2] = src2;
-    insn->operands[3] = info;
-    setupResourceMasks(insn);
-    insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    oatAppendLIR(cUnit, (LIR *) insn);
-    return insn;
-}
-
-/*
- * Generate an kPseudoBarrier marker to indicate the boundary of special
- * blocks.
- */
-static void genBarrier(CompilationUnit *cUnit)
-{
-    MipsLIR *barrier = newLIR0(cUnit, kPseudoBarrier);
-    /* Mark all resources as being clobbered */
-    barrier->defMask = -1;
-}
-
-} // namespace art
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index 7eb2a1a..acbac7f 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -16,42 +16,8 @@
 
 namespace art {
 
-extern void oatFlushRegWideForV5TEVFP(CompilationUnit *cUnit,
-                                              int reg1, int reg2);
-extern void oatFlushRegForV5TEVFP(CompilationUnit *cUnit, int reg);
-
-/* First, flush any registers associated with this value */
-void loadValueAddress(CompilationUnit *cUnit, RegLocation rlSrc,
-                             int rDest)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-     rlSrc = rlSrc.wide ? oatUpdateLocWide(cUnit, rlSrc) :
-                          oatUpdateLoc(cUnit, rlSrc);
-     if (rlSrc.location == kLocPhysReg) {
-         if (rlSrc.wide) {
-             oatFlushRegWideForV5TEVFP(cUnit, rlSrc.lowReg,
-                                               rlSrc.highReg);
-         } else {
-             oatFlushRegForV5TEVFP(cUnit, rlSrc.lowReg);
-         }
-     }
-     opRegRegImm(cUnit, kOpAdd, rDest, rFP,
-                 oatS2VReg(cUnit, rlSrc.sRegLow) << 2);
-#endif
-}
-
-/*
- * TUNING: On some implementations, it is quicker to pass addresses
- * to the handlers rather than load the operands into core registers
- * and then move the values to FP regs in the handlers.  Other implementations
- * may prefer passing data in registers (and the latter approach would
- * yeild cleaner register handling - avoiding the requirement that operands
- * be flushed to memory prior to the call).
- */
-static bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir,
-                            RegLocation rlDest, RegLocation rlSrc1,
-                            RegLocation rlSrc2)
+bool genArithOpFloat(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
+                     RegLocation rlSrc1, RegLocation rlSrc2)
 {
 #ifdef __mips_hard_float
     int op = kMipsNop;
@@ -89,60 +55,14 @@
     rlSrc1 = loadValue(cUnit, rlSrc1, kFPReg);
     rlSrc2 = loadValue(cUnit, rlSrc2, kFPReg);
     rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
-    newLIR3(cUnit, (MipsOpCode)op, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
+    newLIR3(cUnit, (MipsOpCode)op, rlResult.lowReg, rlSrc1.lowReg,
+                    rlSrc2.lowReg);
     storeValue(cUnit, rlDest, rlResult);
 
     return false;
 #else
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
     return false;
-#if 0
-    TemplateOpcode opcode;
-
-    /*
-     * Don't attempt to optimize register usage since these opcodes call out to
-     * the handlers.
-     */
-    switch (mir->dalvikInsn.opcode) {
-        case OP_ADD_FLOAT_2ADDR:
-        case OP_ADD_FLOAT:
-            opcode = TEMPLATE_ADD_FLOAT_VFP;
-            break;
-        case OP_SUB_FLOAT_2ADDR:
-        case OP_SUB_FLOAT:
-            opcode = TEMPLATE_SUB_FLOAT_VFP;
-            break;
-        case OP_DIV_FLOAT_2ADDR:
-        case OP_DIV_FLOAT:
-            opcode = TEMPLATE_DIV_FLOAT_VFP;
-            break;
-        case OP_MUL_FLOAT_2ADDR:
-        case OP_MUL_FLOAT:
-            opcode = TEMPLATE_MUL_FLOAT_VFP;
-            break;
-        case OP_REM_FLOAT_2ADDR:
-        case OP_REM_FLOAT:
-        case OP_NEG_FLOAT: {
-            return genArithOpFloatPortable(cUnit, mir, rlDest, rlSrc1, rlSrc2);
-        }
-        default:
-            return true;
-    }
-    loadValueAddress(cUnit, rlDest, r_A0);
-    oatClobber(cUnit, r_A0);
-    loadValueAddress(cUnit, rlSrc1, r_A1);
-    oatClobber(cUnit, r_A1);
-    loadValueAddress(cUnit, rlSrc2, r_A2);
-    UNIMP(FATAL) << "Need callout to handler";
-#if 0
-    genDispatchToHandler(cUnit, opcode);
-#endif
-    rlDest = oatUpdateLoc(cUnit, rlDest);
-    if (rlDest.location == kLocPhysReg) {
-        oatClobber(cUnit, rlDest.lowReg);
-    }
-    return false;
-#endif
 #endif
 }
 
@@ -192,64 +112,19 @@
     storeValueWide(cUnit, rlDest, rlResult);
     return false;
 #else
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
     return false;
-#if 0
-    TemplateOpcode opcode;
-
-    switch (mir->dalvikInsn.opcode) {
-        case OP_ADD_DOUBLE_2ADDR:
-        case OP_ADD_DOUBLE:
-            opcode = TEMPLATE_ADD_DOUBLE_VFP;
-            break;
-        case OP_SUB_DOUBLE_2ADDR:
-        case OP_SUB_DOUBLE:
-            opcode = TEMPLATE_SUB_DOUBLE_VFP;
-            break;
-        case OP_DIV_DOUBLE_2ADDR:
-        case OP_DIV_DOUBLE:
-            opcode = TEMPLATE_DIV_DOUBLE_VFP;
-            break;
-        case OP_MUL_DOUBLE_2ADDR:
-        case OP_MUL_DOUBLE:
-            opcode = TEMPLATE_MUL_DOUBLE_VFP;
-            break;
-        case OP_REM_DOUBLE_2ADDR:
-        case OP_REM_DOUBLE:
-        case OP_NEG_DOUBLE: {
-            return genArithOpDoublePortable(cUnit, mir, rlDest, rlSrc1,
-                                               rlSrc2);
-        }
-        default:
-            return true;
-    }
-    loadValueAddress(cUnit, rlDest, r_A0);
-    oatClobber(cUnit, r_A0);
-    loadValueAddress(cUnit, rlSrc1, r_A1);
-    oatClobber(cUnit, r_A1);
-    loadValueAddress(cUnit, rlSrc2, r_A2);
-    UNIMP(FATAL) << "Need callout to handler";
-#if 0
-    genDispatchToHandler(cUnit, opcode);
-#endif
-    rlDest = oatUpdateLocWide(cUnit, rlDest);
-    if (rlDest.location == kLocPhysReg) {
-        oatClobber(cUnit, rlDest.lowReg);
-        oatClobber(cUnit, rlDest.highReg);
-    }
-    return false;
-#endif
 #endif
 }
 
 static bool genConversion(CompilationUnit *cUnit, MIR *mir)
 {
+#ifdef __mips_hard_float
     Opcode opcode = mir->dalvikInsn.opcode;
     bool longSrc = false;
     bool longDest = false;
     RegLocation rlSrc;
     RegLocation rlDest;
-#ifdef __mips_hard_float
     int op = kMipsNop;
     int srcReg;
     RegLocation rlResult;
@@ -306,77 +181,8 @@
     }
     return false;
 #else
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Need Mips soft float implementation";
     return false;
-#if 0
-    TemplateOpcode templateOpcode;
-    switch (opcode) {
-        case OP_INT_TO_FLOAT:
-            longSrc = false;
-            longDest = false;
-            templateOpcode = TEMPLATE_INT_TO_FLOAT_VFP;
-            break;
-        case OP_FLOAT_TO_INT:
-            longSrc = false;
-            longDest = false;
-            templateOpcode = TEMPLATE_FLOAT_TO_INT_VFP;
-            break;
-        case OP_DOUBLE_TO_FLOAT:
-            longSrc = true;
-            longDest = false;
-            templateOpcode = TEMPLATE_DOUBLE_TO_FLOAT_VFP;
-            break;
-        case OP_FLOAT_TO_DOUBLE:
-            longSrc = false;
-            longDest = true;
-            templateOpcode = TEMPLATE_FLOAT_TO_DOUBLE_VFP;
-            break;
-        case OP_INT_TO_DOUBLE:
-            longSrc = false;
-            longDest = true;
-            templateOpcode = TEMPLATE_INT_TO_DOUBLE_VFP;
-            break;
-        case OP_DOUBLE_TO_INT:
-            longSrc = true;
-            longDest = false;
-            templateOpcode = TEMPLATE_DOUBLE_TO_INT_VFP;
-            break;
-        case OP_LONG_TO_DOUBLE:
-        case OP_FLOAT_TO_LONG:
-        case OP_LONG_TO_FLOAT:
-        case OP_DOUBLE_TO_LONG:
-            return genConversionPortable(cUnit, mir);
-        default:
-            return true;
-    }
-
-    if (longSrc) {
-        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
-    } else {
-        rlSrc = oatGetSrc(cUnit, mir, 0);
-    }
-
-    if (longDest) {
-        rlDest = oatGetDestWide(cUnit, mir, 0, 1);
-    } else {
-        rlDest = oatGetDest(cUnit, mir, 0);
-    }
-    loadValueAddress(cUnit, rlDest, r_A0);
-    oatClobber(cUnit, r_A0);
-    loadValueAddress(cUnit, rlSrc, r_A1);
-    UNIMP(FATAL) << "Need callout to handler";
-#if 0
-    genDispatchToHandler(cUnit, templateOpcode);
-#endif
-    if (rlDest.wide) {
-        rlDest = oatUpdateLocWide(cUnit, rlDest);
-        oatClobber(cUnit, rlDest.highReg);
-    } else {
-        rlDest = oatUpdateLoc(cUnit, rlDest);
-    }
-    oatClobber(cUnit, rlDest.lowReg);
-    return false;
-#endif
 #endif
 }
 
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index f76adff..71220c0 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -38,19 +38,24 @@
                         r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
 #endif
 
+void genBarrier(CompilationUnit *cUnit);
+LIR* genCompareBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+                      int src2);
+LIR* opCompareBranch(CompilationUnit* cUnit, MipsOpCode opc, int src1,
+                      int src2);
 void storePair(CompilationUnit *cUnit, int base, int lowReg,
                int highReg);
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
-MipsLIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
+LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
                       int rDest);
-MipsLIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
+LIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
                        int displacement, int rSrc);
-MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
+LIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
 
 #ifdef __mips_hard_float
-MipsLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+LIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
 {
-    MipsLIR* res = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
+    LIR* res = (LIR *) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
     res->operands[0] = rDest;
     res->operands[1] = rSrc;
     if (rDest == rSrc) {
@@ -90,10 +95,10 @@
  * 1) rDest is freshly returned from oatAllocTemp or
  * 2) The codegen is under fixed register usage
  */
-MipsLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
+LIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
                                int value)
 {
-    MipsLIR *res;
+    LIR *res;
 
 #ifdef __mips_hard_float
     int rDestSave = rDest;
@@ -127,22 +132,9 @@
     return res;
 }
 
-/*
- * Load an immediate value into a fixed or temp register.  Target
- * register is clobbered, and marked inUse.
- */
-MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
+LIR *opNone(CompilationUnit *cUnit, OpKind op)
 {
-    if (oatIsTemp(cUnit, rDest)) {
-        oatClobber(cUnit, rDest);
-        oatMarkInUse(cUnit, rDest);
-    }
-    return loadConstantNoClobber(cUnit, rDest, value);
-}
-
-MipsLIR *opNone(CompilationUnit *cUnit, OpKind op)
-{
-    MipsLIR *res;
+    LIR *res;
     MipsOpCode opcode = kMipsNop;
     switch (op) {
         case kOpUncondBr:
@@ -156,28 +148,28 @@
 }
 
 
-MipsLIR *opCmpBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
+LIR *opCmpBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
                            int rs, int rt)
 {
     UNIMPLEMENTED(FATAL);
     return 0;
 }
-MipsLIR *opCmpImmBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
+LIR *opCmpImmBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
                            int rs, int immVal)
 {
     UNIMPLEMENTED(FATAL);
     return 0;
 }
-MipsLIR *opCmpImmBranch(CompilationUnit *cUnit, MipsOpCode cc,
+LIR *opCmpImmBranch(CompilationUnit *cUnit, MipsOpCode cc,
                            int rs, int immVal)
 {
     UNIMPLEMENTED(FATAL);
     return 0;
 }
 
-MipsLIR *opCmpBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
+LIR *opCmpBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
 {
-    MipsLIR *res;
+    LIR *res;
     if (rt < 0) {
       DCHECK(opc >= kMipsBeqz && opc <= kMipsBnez);
       res = newLIR1(cUnit, opc, rs);
@@ -188,9 +180,9 @@
     return res;
 }
 
-MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
+LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
 
-MipsLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
+LIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
 {
     MipsOpCode opcode = kMipsNop;
     switch (op) {
@@ -203,12 +195,12 @@
     return newLIR2(cUnit, opcode, r_RA, rDestSrc);
 }
 
-MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
+LIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
                      int rSrc1, int value);
-MipsLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
+LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                   int value)
 {
-    MipsLIR *res;
+    LIR *res;
     bool neg = (value < 0);
     int absValue = (neg) ? -value : value;
     bool shortForm = (absValue & 0xff) == absValue;
@@ -237,7 +229,7 @@
     return res;
 }
 
-MipsLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
+LIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
                            int rSrc1, int rSrc2)
 {
     MipsOpCode opcode = kMipsNop;
@@ -276,10 +268,10 @@
     return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2);
 }
 
-MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
+LIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
                            int rSrc1, int value)
 {
-    MipsLIR *res;
+    LIR *res;
     MipsOpCode opcode = kMipsNop;
     bool shortForm = true;
 
@@ -366,11 +358,11 @@
     return res;
 }
 
-MipsLIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
+LIR *opRegReg(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                   int rSrc2)
 {
     MipsOpCode opcode = kMipsNop;
-    MipsLIR *res;
+    LIR *res;
     switch (op) {
         case kOpMov:
             opcode = kMipsMove;
@@ -411,21 +403,21 @@
     return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
 }
 
-MipsLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
+LIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
                                      int rDestHi, int valLo, int valHi)
 {
-    MipsLIR *res;
+    LIR *res;
     res = loadConstantNoClobber(cUnit, rDestLo, valLo);
     loadConstantNoClobber(cUnit, rDestHi, valHi);
     return res;
 }
 
 /* Load value from base + scaled index. */
-MipsLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
+LIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
                                int rIndex, int rDest, int scale, OpSize size)
 {
-    MipsLIR *first = NULL;
-    MipsLIR *res;
+    LIR *first = NULL;
+    LIR *res;
     MipsOpCode opcode = kMipsNop;
     int tReg = oatAllocTemp(cUnit);
 
@@ -478,11 +470,11 @@
 }
 
 /* store value base base + scaled index. */
-MipsLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
+LIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
                                 int rIndex, int rSrc, int scale, OpSize size)
 {
-    MipsLIR *first = NULL;
-    MipsLIR *res;
+    LIR *first = NULL;
+    LIR *res;
     MipsOpCode opcode = kMipsNop;
     int rNewIndex = rIndex;
     int tReg = oatAllocTemp(cUnit);
@@ -530,11 +522,11 @@
     return first;
 }
 
-MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
+LIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
 {
     int i;
     int loadCnt = 0;
-    MipsLIR *res = NULL ;
+    LIR *res = NULL ;
     genBarrier(cUnit);
 
     for (i = 0; i < 8; i++, rMask >>= 1) {
@@ -552,11 +544,11 @@
     return res; /* NULL always returned which should be ok since no callers use it */
 }
 
-MipsLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
+LIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
 {
     int i;
     int storeCnt = 0;
-    MipsLIR *res = NULL ;
+    LIR *res = NULL ;
     genBarrier(cUnit);
 
     for (i = 0; i < 8; i++, rMask >>= 1) {
@@ -574,7 +566,7 @@
     return res; /* NULL always returned which should be ok since no callers use it */
 }
 
-MipsLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
                                 int displacement, int rDest, int rDestHi,
                                 OpSize size, int sReg)
 /*
@@ -586,9 +578,9 @@
  * rlp and then restore.
  */
 {
-    MipsLIR *res;
-    MipsLIR *load = NULL;
-    MipsLIR *load2 = NULL;
+    LIR *res;
+    LIR *load = NULL;
+    LIR *load2 = NULL;
     MipsOpCode opcode = kMipsNop;
     bool shortForm = IS_SIMM16(displacement);
     bool pair = false;
@@ -680,7 +672,7 @@
     return load;
 }
 
-MipsLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
                             int displacement, int rDest, OpSize size,
                             int sReg)
 {
@@ -688,7 +680,7 @@
                             size, sReg);
 }
 
-MipsLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
+LIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
                           int displacement, int rDestLo, int rDestHi,
                                 int sReg)
 {
@@ -696,13 +688,13 @@
                             kLong, sReg);
 }
 
-MipsLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
+LIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
                                  int displacement, int rSrc, int rSrcHi,
                                  OpSize size)
 {
-    MipsLIR *res;
-    MipsLIR *store = NULL;
-    MipsLIR *store2 = NULL;
+    LIR *res;
+    LIR *store = NULL;
+    LIR *store2 = NULL;
     MipsOpCode opcode = kMipsNop;
     bool shortForm = IS_SIMM16(displacement);
     bool pair = false;
@@ -785,13 +777,13 @@
     return res;
 }
 
-MipsLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
+LIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
                        int displacement, int rSrc, OpSize size)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
 }
 
-MipsLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
+LIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
                            int displacement, int rSrcLo, int rSrcHi)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
@@ -803,83 +795,12 @@
     loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg);
 }
 
-MipsLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
-{
-    MipsLIR* res;
-    MipsOpCode opcode;
-#ifdef __mips_hard_float
-    if (FPREG(rDest) || FPREG(rSrc))
-        return fpRegCopy(cUnit, rDest, rSrc);
-#endif
-    res = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    opcode = kMipsMove;
-    DCHECK(LOWREG(rDest) && LOWREG(rSrc));
-    res->operands[0] = rDest;
-    res->operands[1] = rSrc;
-    res->opcode = opcode;
-    setupResourceMasks(res);
-    if (rDest == rSrc) {
-        res->flags.isNop = true;
-    }
-    return res;
-}
-
-MipsLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
-{
-    MipsLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
-    oatAppendLIR(cUnit, (LIR*)res);
-    return res;
-}
-
-void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
-                           int srcLo, int srcHi)
-{
-#ifdef __mips_hard_float
-    bool destFP = FPREG(destLo) && FPREG(destHi);
-    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
-    DCHECK_EQ(FPREG(srcLo), FPREG(srcHi));
-    DCHECK_EQ(FPREG(destLo), FPREG(destHi));
-    if (destFP) {
-        if (srcFP) {
-            genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
-        } else {
-           /* note the operands are swapped for the mtc1 instr */
-            newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
-            newLIR2(cUnit, kMipsMtc1, srcHi, destHi);
-        }
-    } else {
-        if (srcFP) {
-            newLIR2(cUnit, kMipsMfc1, destLo, srcLo);
-            newLIR2(cUnit, kMipsMfc1, destHi, srcHi);
-        } else {
-            // Handle overlap
-            if (srcHi == destLo) {
-                genRegCopy(cUnit, destHi, srcHi);
-                genRegCopy(cUnit, destLo, srcLo);
-            } else {
-                genRegCopy(cUnit, destLo, srcLo);
-                genRegCopy(cUnit, destHi, srcHi);
-            }
-        }
-    }
-#else
-    // Handle overlap
-    if (srcHi == destLo) {
-        genRegCopy(cUnit, destHi, srcHi);
-        genRegCopy(cUnit, destLo, srcLo);
-    } else {
-        genRegCopy(cUnit, destLo, srcLo);
-        genRegCopy(cUnit, destHi, srcHi);
-    }
-#endif
-}
-
-inline MipsLIR *genRegImmCheck(CompilationUnit *cUnit,
+LIR *genRegImmCheck(CompilationUnit *cUnit,
                                MipsConditionCode cond, int reg,
                                int checkValue, int dOffset,
-                               MipsLIR *pcrLabel)
+                               LIR *pcrLabel)
 {
-    MipsLIR *branch = NULL;
+    LIR *branch = NULL;
 
     if (checkValue == 0) {
         MipsOpCode opc = kMipsNop;
@@ -918,9 +839,9 @@
     if (cUnit->jitMode == kJitMethod) {
         BasicBlock *bb = cUnit->curBlock;
         if (bb->taken) {
-            MipsLIR  *exceptionLabel = (MipsLIR *) cUnit->blockLabelList;
+            LIR  *exceptionLabel = (LIR *) cUnit->blockLabelList;
             exceptionLabel += bb->taken->id;
-            branch->generic.target = (LIR *) exceptionLabel;
+            branch->target = (LIR *) exceptionLabel;
             return exceptionLabel;
         } else {
             LOG(FATAL) <<  "Catch blocks not handled yet";
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index 8801692..0b2b15a 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -24,377 +24,6 @@
 
 namespace art {
 
-// FIXME: need the following:
-void genSuspendTest(CompilationUnit* cUnit, MIR* mir) {}
-void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) {}
-void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) {}
-void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) {}
-void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                   RegLocation rlSrc) {}
-void genNewInstance(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest) {}
-void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc) {}
-void genConstString(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc) {}
-void genConstClass(CompilationUnit* cUnit, MIR* mir,
-                          RegLocation rlDest, RegLocation rlSrc) {}
-void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                        RegLocation rlArray, RegLocation rlIndex,
-                        RegLocation rlDest, int scale) {}
-void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                        RegLocation rlArray, RegLocation rlIndex,
-                        RegLocation rlSrc, int scale) {}
-void genArrayObjPut(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlArray, RegLocation rlIndex,
-                           RegLocation rlSrc, int scale) {}
-void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                    RegLocation rlSrc, RegLocation rlObj,
-                    bool isLongOrDouble, bool isObject) {}
-bool genArithOpInt(CompilationUnit* cUnit, MIR* mir,
-                          RegLocation rlDest, RegLocation rlSrc1,
-                          RegLocation rlSrc2) { return 0; }
-bool genArithOpLong(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc1,
-                           RegLocation rlSrc2) { return 0; }
-bool genShiftOpLong(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc1,
-                           RegLocation rlShift) { return 0; }
-bool genArithOpIntLit(CompilationUnit* cUnit, MIR* mir,
-                             RegLocation rlDest, RegLocation rlSrc,
-                             int lit) { return 0; }
-void oatArchDump(void) {};
-void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset) {};
-
-
-
-
-STATIC bool genConversionCall(CompilationUnit* cUnit, MIR* mir, int funcOffset,
-                                     int srcSize, int tgtSize)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-    return 0;
-#if 0
-    /*
-     * Don't optimize the register usage since it calls out to support
-     * functions
-     */
-    RegLocation rlSrc;
-    RegLocation rlDest;
-    oatFlushAllRegs(cUnit);   /* Send everything to home location */
-    loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-    if (srcSize == 1) {
-        rlSrc = oatGetSrc(cUnit, mir, 0);
-        loadValueDirectFixed(cUnit, rlSrc, r0);
-    } else {
-        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
-        loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
-    }
-    callRuntimeHelper(cUnit, rLR);
-    if (tgtSize == 1) {
-        RegLocation rlResult;
-        rlDest = oatGetDest(cUnit, mir, 0);
-        rlResult = oatGetReturn(cUnit);
-        storeValue(cUnit, rlDest, rlResult);
-    } else {
-        RegLocation rlResult;
-        rlDest = oatGetDestWide(cUnit, mir, 0, 1);
-        rlResult = oatGetReturnWide(cUnit);
-        storeValueWide(cUnit, rlDest, rlResult);
-    }
-    return false;
-#endif
-}
-
-bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
-                                    RegLocation rlDest, RegLocation rlSrc1,
-                                    RegLocation rlSrc2)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-    return 0;
-#if 0
-    RegLocation rlResult;
-    int funcOffset;
-
-    switch (mir->dalvikInsn.opcode) {
-        case OP_ADD_FLOAT_2ADDR:
-        case OP_ADD_FLOAT:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFadd);
-            break;
-        case OP_SUB_FLOAT_2ADDR:
-        case OP_SUB_FLOAT:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFsub);
-            break;
-        case OP_DIV_FLOAT_2ADDR:
-        case OP_DIV_FLOAT:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFdiv);
-            break;
-        case OP_MUL_FLOAT_2ADDR:
-        case OP_MUL_FLOAT:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFmul);
-            break;
-        case OP_REM_FLOAT_2ADDR:
-        case OP_REM_FLOAT:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFmodf);
-            break;
-        case OP_NEG_FLOAT: {
-            genNegFloat(cUnit, rlDest, rlSrc1);
-            return false;
-        }
-        default:
-            return true;
-    }
-    oatFlushAllRegs(cUnit);   /* Send everything to home location */
-    loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-    loadValueDirectFixed(cUnit, rlSrc1, r0);
-    loadValueDirectFixed(cUnit, rlSrc2, r1);
-    callRuntimeHelper(cUnit, rLR);
-    rlResult = oatGetReturn(cUnit);
-    storeValue(cUnit, rlDest, rlResult);
-    return false;
-#endif
-}
-
-bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
-                                     RegLocation rlDest, RegLocation rlSrc1,
-                                     RegLocation rlSrc2)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-    return 0;
-#if 0
-    RegLocation rlResult;
-    int funcOffset;
-
-    switch (mir->dalvikInsn.opcode) {
-        case OP_ADD_DOUBLE_2ADDR:
-        case OP_ADD_DOUBLE:
-            funcOffset = OFFSETOF_MEMBER(Thread, pDadd);
-            break;
-        case OP_SUB_DOUBLE_2ADDR:
-        case OP_SUB_DOUBLE:
-            funcOffset = OFFSETOF_MEMBER(Thread, pDsub);
-            break;
-        case OP_DIV_DOUBLE_2ADDR:
-        case OP_DIV_DOUBLE:
-            funcOffset = OFFSETOF_MEMBER(Thread, pDdiv);
-            break;
-        case OP_MUL_DOUBLE_2ADDR:
-        case OP_MUL_DOUBLE:
-            funcOffset = OFFSETOF_MEMBER(Thread, pDmul);
-            break;
-        case OP_REM_DOUBLE_2ADDR:
-        case OP_REM_DOUBLE:
-            funcOffset = OFFSETOF_MEMBER(Thread, pFmod);
-            break;
-        case OP_NEG_DOUBLE: {
-            genNegDouble(cUnit, rlDest, rlSrc1);
-            return false;
-        }
-        default:
-            return true;
-    }
-    oatFlushAllRegs(cUnit);   /* Send everything to home location */
-    loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-    loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-    loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-    callRuntimeHelper(cUnit, rLR);
-    rlResult = oatGetReturnWide(cUnit);
-    storeValueWide(cUnit, rlDest, rlResult);
-    return false;
-#endif
-}
-
-bool genConversionPortable(CompilationUnit* cUnit, MIR* mir)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-    return 0;
-#if 0
-    Opcode opcode = mir->dalvikInsn.opcode;
-
-    switch (opcode) {
-        case OP_INT_TO_FLOAT:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pI2f),
-                                     1, 1);
-        case OP_FLOAT_TO_INT:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pF2iz),
-                                     1, 1);
-        case OP_DOUBLE_TO_FLOAT:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pD2f),
-                                     2, 1);
-        case OP_FLOAT_TO_DOUBLE:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pF2d),
-                                     1, 2);
-        case OP_INT_TO_DOUBLE:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pI2d),
-                                     1, 2);
-        case OP_DOUBLE_TO_INT:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pD2iz),
-                                     2, 1);
-        case OP_FLOAT_TO_LONG:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread,
-                                     pF2l), 1, 2);
-        case OP_LONG_TO_FLOAT:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pL2f),
-                                     2, 1);
-        case OP_DOUBLE_TO_LONG:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread,
-                                     pD2l), 2, 2);
-        case OP_LONG_TO_DOUBLE:
-            return genConversionCall(cUnit, mir, OFFSETOF_MEMBER(Thread, pL2d),
-                                     2, 2);
-        default:
-            return true;
-    }
-    return false;
-#endif
-}
-
-
-
-
-
-STATIC RegLocation getRetLoc(CompilationUnit* cUnit);
-
-void warnIfUnresolved(CompilationUnit* cUnit, int fieldIdx, Field* field) {
-  if (field == NULL) {
-    const DexFile::FieldId& field_id = cUnit->dex_file->GetFieldId(fieldIdx);
-    std::string class_name(cUnit->dex_file->GetFieldDeclaringClassDescriptor(field_id));
-    std::string field_name(cUnit->dex_file->GetFieldName(field_id));
-    LOG(INFO) << "Field " << PrettyDescriptor(class_name) << "." << field_name
-              << " unresolved at compile time";
-  } else {
-    // We also use the slow path for wide volatile fields.
-  }
-}
-
-/*
- * Construct an s4 from two consecutive half-words of switch data.
- * This needs to check endianness because the DEX optimizer only swaps
- * half-words in instruction stream.
- *
- * "switchData" must be 32-bit aligned.
- */
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-STATIC inline s4 s4FromSwitchData(const void* switchData) {
-    return *(s4*) switchData;
-}
-#else
-STATIC inline s4 s4FromSwitchData(const void* switchData) {
-    u2* data = switchData;
-    return data[0] | (((s4) data[1]) << 16);
-}
-#endif
-/*
- * Insert a kPseudoCaseLabel at the beginning of the Dalvik
- * offset vaddr.  This label will be used to fix up the case
- * branch table during the assembly phase.  Be sure to set
- * all resource flags on this to prevent code motion across
- * target boundaries.  KeyVal is just there for debugging.
- */
-STATIC MipsLIR* insertCaseLabel(CompilationUnit* cUnit, int vaddr, int keyVal)
-{
-    std::map<unsigned int, LIR*>::iterator it;
-    it = cUnit->boundaryMap.find(vaddr);
-    if (it == cUnit->boundaryMap.end()) {
-        LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr;
-    }
-    MipsLIR* newLabel = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    newLabel->generic.dalvikOffset = vaddr;
-    newLabel->opcode = kPseudoCaseLabel;
-    newLabel->operands[0] = keyVal;
-    oatInsertLIRAfter(it->second, (LIR*)newLabel);
-    return newLabel;
-}
-
-STATIC void markPackedCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec)
-{
-    const u2* table = tabRec->table;
-    int baseVaddr = tabRec->vaddr;
-    int *targets = (int*)&table[4];
-    int entries = table[1];
-    int lowKey = s4FromSwitchData(&table[2]);
-    for (int i = 0; i < entries; i++) {
-        tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i],
-                                             i + lowKey);
-    }
-}
-
-STATIC void markSparseCaseLabels(CompilationUnit* cUnit, SwitchTable *tabRec)
-{
-    const u2* table = tabRec->table;
-    int baseVaddr = tabRec->vaddr;
-    int entries = table[1];
-    int* keys = (int*)&table[2];
-    int* targets = &keys[entries];
-    for (int i = 0; i < entries; i++) {
-        tabRec->targets[i] = insertCaseLabel(cUnit, baseVaddr + targets[i],
-                                             keys[i]);
-    }
-}
-
-void oatProcessSwitchTables(CompilationUnit* cUnit)
-{
-    GrowableListIterator iterator;
-    oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
-    while (true) {
-        SwitchTable *tabRec = (SwitchTable *) oatGrowableListIteratorNext(
-             &iterator);
-        if (tabRec == NULL) break;
-        if (tabRec->table[0] == kPackedSwitchSignature)
-            markPackedCaseLabels(cUnit, tabRec);
-        else if (tabRec->table[0] == kSparseSwitchSignature)
-            markSparseCaseLabels(cUnit, tabRec);
-        else {
-            LOG(FATAL) << "Invalid switch table";
-        }
-    }
-}
-
-STATIC void dumpSparseSwitchTable(const u2* table)
-    /*
-     * Sparse switch data format:
-     *  ushort ident = 0x0200   magic value
-     *  ushort size             number of entries in the table; > 0
-     *  int keys[size]          keys, sorted low-to-high; 32-bit aligned
-     *  int targets[size]       branch targets, relative to switch opcode
-     *
-     * Total size is (2+size*4) 16-bit code units.
-     */
-{
-    u2 ident = table[0];
-    int entries = table[1];
-    int* keys = (int*)&table[2];
-    int* targets = &keys[entries];
-    LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident <<
-       ", entries: " << std::dec << entries;
-    for (int i = 0; i < entries; i++) {
-        LOG(INFO) << "    Key[" << keys[i] << "] -> 0x" << std::hex <<
-        targets[i];
-    }
-}
-
-STATIC void dumpPackedSwitchTable(const u2* table)
-    /*
-     * Packed switch data format:
-     *  ushort ident = 0x0100   magic value
-     *  ushort size             number of entries in the table
-     *  int first_key           first (and lowest) switch case value
-     *  int targets[size]       branch targets, relative to switch opcode
-     *
-     * Total size is (4+size*2) 16-bit code units.
-     */
-{
-    u2 ident = table[0];
-    int* targets = (int*)&table[4];
-    int entries = table[1];
-    int lowKey = s4FromSwitchData(&table[2]);
-    LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident <<
-        ", entries: " << std::dec << entries << ", lowKey: " << lowKey;
-    for (int i = 0; i < entries; i++) {
-        LOG(INFO) << "    Key[" << (i + lowKey) << "] -> 0x" << std::hex <<
-            targets[i];
-    }
-}
-
 /*
  * The sparse table in the literal pool is an array of <key,displacement>
  * pairs.  For each set, we'll load them as a pair using ldmia.
@@ -414,10 +43,9 @@
  *   add   rPC, rDisp   ; This is the branch from which we compute displacement
  *   cbnz  rIdx, lp
  */
-STATIC void genSparseSwitch(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlSrc)
+void genSparseSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Needs Mips sparse switch";
 #if 0
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     if (cUnit->printMe) {
@@ -429,8 +57,8 @@
     tabRec->table = table;
     tabRec->vaddr = mir->offset;
     int size = table[1];
-    tabRec->targets = (MipsLIR* *)oatNew(cUnit, size * sizeof(MipsLIR*), true,
-                                        kAllocLIR);
+    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
+                                     kAllocLIR);
     oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
 
     // Get the switch value
@@ -451,26 +79,26 @@
     int rIdx = oatAllocTemp(cUnit);
     loadConstant(cUnit, rIdx, size);
     // Establish loop branch target
-    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     // Load next key/disp
     newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
     opRegReg(cUnit, kOpCmp, rKey, rlSrc.lowReg);
     // Go if match. NOTE: No instruction set switch here - must stay Thumb2
-    genIT(cUnit, kMipsCondEq, "");
-    MipsLIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
+    genIT(cUnit, kArmCondEq, "");
+    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
     tabRec->bxInst = switchBranch;
     // Needs to use setflags encoding here
     newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
-    MipsLIR* branch = opCondBranch(cUnit, kMipsCondNe);
-    branch->generic.target = (LIR*)target;
+    LIR* branch = opCondBranch(cUnit, kCondNe);
+    branch->target = (LIR*)target;
 #endif
 }
 
-STATIC void genPackedSwitch(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlSrc)
+
+void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Need Mips packed switch";
 #if 0
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     if (cUnit->printMe) {
@@ -482,7 +110,7 @@
     tabRec->table = table;
     tabRec->vaddr = mir->offset;
     int size = table[1];
-    tabRec->targets = (MipsLIR* *)oatNew(cUnit, size * sizeof(MipsLIR*), true,
+    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                                         kAllocLIR);
     oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
 
@@ -502,20 +130,20 @@
     }
     // Bounds check - if < 0 or >= size continue following switch
     opRegImm(cUnit, kOpCmp, keyReg, size-1);
-    MipsLIR* branchOver = opCondBranch(cUnit, kMipsCondHi);
+    LIR* branchOver = opCondBranch(cUnit, kCondHi);
 
     // Load the displacement from the switch table
     int dispReg = oatAllocTemp(cUnit);
     loadBaseIndexed(cUnit, tableBase, keyReg, dispReg, 2, kWord);
 
     // ..and go! NOTE: No instruction set switch here - must stay Thumb2
-    MipsLIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
+    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
     tabRec->bxInst = switchBranch;
 
     /* branchOver target here */
-    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
-    branchOver->generic.target = (LIR*)target;
+    branchOver->target = (LIR*)target;
 #endif
 }
 
@@ -529,10 +157,9 @@
  *
  * Total size is 4+(width * size + 1)/2 16-bit code units.
  */
-STATIC void genFillArrayData(CompilationUnit* cUnit, MIR* mir,
-                              RegLocation rlSrc)
+void genFillArrayData(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
+    UNIMPLEMENTED(FATAL) << "Needs Mips FillArrayData";
 #if 0
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     // Add the table to the list - we'll process it later
@@ -548,7 +175,7 @@
 
     // Making a call - use explicit registers
     oatFlushAllRegs(cUnit);   /* Everything to home location */
-    loadValueDirectFixed(cUnit, rlSrc, r0);
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);
     loadWordDisp(cUnit, rSELF,
                  OFFSETOF_MEMBER(Thread, pHandleFillArrayDataFromCode), rLR);
     // Materialize a pointer to the fill data image
@@ -557,275 +184,186 @@
 #endif
 }
 
-STATIC void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                    RegLocation rlDest, RegLocation rlObj,
-                    bool isLongOrDouble, bool isObject)
+/*
+ * TODO: implement fast path to short-circuit thin-lock case
+ */
+void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-    int fieldOffset;
-    bool isVolatile;
-    uint32_t fieldIdx = mir->dalvikInsn.vC;
-    bool fastPath =
-        cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, cUnit,
-                                                  fieldOffset, isVolatile, false);
-    if (fastPath && !SLOW_FIELD_PATH) {
-        RegLocation rlResult;
-        RegisterClass regClass = oatRegClassBySize(size);
-        DCHECK_GE(fieldOffset, 0);
-        rlObj = loadValue(cUnit, rlObj, kCoreReg);
-        if (isLongOrDouble) {
-            DCHECK(rlDest.wide);
-            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null obj? */
-            int regPtr = oatAllocTemp(cUnit);
-            opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
-            rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-            loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kSY);
-            }
-            oatFreeTemp(cUnit, regPtr);
-            storeValueWide(cUnit, rlDest, rlResult);
-        } else {
-            rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null object? */
-            loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
-                         kWord, rlObj.sRegLow);
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kSY);
-            }
-            storeValue(cUnit, rlDest, rlResult);
-        }
-    } else {
-        int getterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pGet64Instance) :
-                           (isObject ? OFFSETOF_MEMBER(Thread, pGetObjInstance)
-                                     : OFFSETOF_MEMBER(Thread, pGet32Instance));
-        loadWordDisp(cUnit, rSELF, getterOffset, rLR);
-        loadValueDirect(cUnit, rlObj, r1);
-        loadConstant(cUnit, r0, fieldIdx);
-        callRuntimeHelper(cUnit, rLR);
-        if (isLongOrDouble) {
-            RegLocation rlResult = oatGetReturnWide(cUnit);
-            storeValueWide(cUnit, rlDest, rlResult);
-        } else {
-            RegLocation rlResult = oatGetReturn(cUnit);
-            storeValue(cUnit, rlDest, rlResult);
-        }
-    }
-#endif
+    oatFlushAllRegs(cUnit);
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
+    oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+    genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+    // Go expensive route - artLockObjectFromCode(self, obj);
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pLockObjectFromCode));
+    callRuntimeHelper(cUnit, rTgt);
 }
 
 /*
- * Perform a "reg cmp imm" operation and jump to the PCR region if condition
- * satisfies.
+ * TODO: implement fast path to short-circuit thin-lock case
  */
-STATIC void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest,
-                        RegLocation rlSrc)
+void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    RegLocation rlResult;
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    opRegRegImm(cUnit, kOpAdd, rlResult.lowReg,
-                rlSrc.lowReg, 0x80000000);
+    oatFlushAllRegs(cUnit);
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get obj
+    oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+    genNullCheck(cUnit, rlSrc.sRegLow, rARG0, mir);
+    // Go expensive route - UnlockObjectFromCode(obj);
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode));
+    callRuntimeHelper(cUnit, rTgt);
+}
+
+/*
+ * Compare two 64-bit values
+ *    x = y     return  0
+ *    x < y     return -1
+ *    x > y     return  1
+ *
+ *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
+ *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
+ *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
+ *    bnez  res, finish
+ *    sltu  t0, x.lo, y.lo
+ *    sgtu  r1, x.lo, y.lo
+ *    subu  res, t0, t1
+ * finish:
+ *
+ */
+void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+    int t0 = oatAllocTemp(cUnit);
+    int t1 = oatAllocTemp(cUnit);
+    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    newLIR3(cUnit, kMipsSlt, t0, rlSrc1.highReg, rlSrc2.highReg);
+    newLIR3(cUnit, kMipsSlt, t1, rlSrc2.highReg, rlSrc1.highReg);
+    newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
+    LIR* branch = genCmpImmBranch(cUnit, kCondNe, rlResult.lowReg, 0);
+    newLIR3(cUnit, kMipsSltu, t0, rlSrc1.lowReg, rlSrc2.lowReg);
+    newLIR3(cUnit, kMipsSltu, t1, rlSrc2.lowReg, rlSrc1.lowReg);
+    newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
+    oatFreeTemp(cUnit, t0);
+    oatFreeTemp(cUnit, t1);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = ENCODE_ALL;
+    branch->target = (LIR*)target;
     storeValue(cUnit, rlDest, rlResult);
 }
 
-STATIC void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest,
-                         RegLocation rlSrc)
+LIR* genCompareBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+                      int src2)
 {
-    RegLocation rlResult;
-    rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg,
-                        0x80000000);
-    genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
-    storeValueWide(cUnit, rlDest, rlResult);
+    if (cond == kCondEq) {
+        return newLIR2(cUnit, kMipsBeq, src1, src2);
+    } else if (cond == kCondNe) {
+        return newLIR2(cUnit, kMipsBne, src1, src2);
+    }
+    //int rRes = oatAllocTemp(cUnit);
+    switch(cond) {
+        case kCondEq: return newLIR2(cUnit, kMipsBeq, src1, src2);
+        case kCondNe: return newLIR2(cUnit, kMipsBne, src1, src2);
+        default:
+            UNIMPLEMENTED(FATAL) << "Need to flesh out genCompareBranch";
+            return NULL;
+    }
 }
 
-STATIC void genMulLong(CompilationUnit *cUnit, RegLocation rlDest,
-                       RegLocation rlSrc1, RegLocation rlSrc2)
+LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+                     int checkValue)
 {
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-    RegLocation rlResult;
-    loadValueDirectWideFixed(cUnit, rlSrc1, r_ARG0, r_ARG1);
-    loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
-    genDispatchToHandler(cUnit, TEMPLATE_MUL_LONG);
-    rlResult = oatGetReturnWide(cUnit);
-    storeValueWide(cUnit, rlDest, rlResult);
-#endif
-}
-
-STATIC bool partialOverlap(int sreg1, int sreg2)
-{
-    return abs(sreg1 - sreg2) == 1;
-}
-
-STATIC void withCarryHelper(CompilationUnit *cUnit, MipsOpCode opc,
-                            RegLocation rlDest, RegLocation rlSrc1,
-                            RegLocation rlSrc2, int sltuSrc1, int sltuSrc2)
-{
-    int tReg = oatAllocTemp(cUnit);
-    newLIR3(cUnit, opc, rlDest.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
-    newLIR3(cUnit, kMipsSltu, tReg, sltuSrc1, sltuSrc2);
-    newLIR3(cUnit, opc, rlDest.highReg, rlSrc1.highReg, rlSrc2.highReg);
-    newLIR3(cUnit, opc, rlDest.highReg, rlDest.highReg, tReg);
-    oatFreeTemp(cUnit, tReg);
-}
-
-STATIC void genLong3Addr(CompilationUnit *cUnit, MIR *mir, OpKind firstOp,
-                         OpKind secondOp, RegLocation rlDest,
-                         RegLocation rlSrc1, RegLocation rlSrc2)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-    RegLocation rlResult;
-    int carryOp = (secondOp == kOpAdc || secondOp == kOpSbc);
-
-    if (partialOverlap(rlSrc1.sRegLow,rlSrc2.sRegLow) ||
-        partialOverlap(rlSrc1.sRegLow,rlDest.sRegLow) ||
-        partialOverlap(rlSrc2.sRegLow,rlDest.sRegLow)) {
-        // Rare case - not enough registers to properly handle
-        genInterpSingleStep(cUnit, mir);
-    } else if (rlDest.sRegLow == rlSrc1.sRegLow) {
-        rlResult = loadValueWide(cUnit, rlDest, kCoreReg);
-        rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-        if (!carryOp) {
-            opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlResult.lowReg, rlSrc2.lowReg);
-            opRegRegReg(cUnit, secondOp, rlResult.highReg, rlResult.highReg, rlSrc2.highReg);
-        } else if (secondOp == kOpAdc) {
-            withCarryHelper(cUnit, kMipsAddu, rlResult, rlResult, rlSrc2,
-                            rlResult.lowReg, rlSrc2.lowReg);
-        } else {
+    if (checkValue != 0) {
+        // TUNING: handle s16 & kCondLt/Mi case using slti
+        int tReg = oatAllocTemp(cUnit);
+        loadConstant(cUnit, tReg, checkValue);
+        return genCompareBranch(cUnit, cond, reg, tReg);
+    }
+    MipsOpCode opc;
+    switch(cond) {
+        case kCondEq: opc = kMipsBeqz; break;
+        case kCondGe: opc = kMipsBgez; break;
+        case kCondGt: opc = kMipsBgtz; break;
+        case kCondLe: opc = kMipsBlez; break;
+        //case KCondMi:
+        case kCondLt: opc = kMipsBltz; break;
+        case kCondNe: opc = kMipsBnez; break;
+        default:
             int tReg = oatAllocTemp(cUnit);
-            newLIR2(cUnit, kMipsMove, tReg, rlResult.lowReg);
-            withCarryHelper(cUnit, kMipsSubu, rlResult, rlResult, rlSrc2,
-                            tReg, rlResult.lowReg);
-            oatFreeTemp(cUnit, tReg);
-        }
-        storeValueWide(cUnit, rlDest, rlResult);
-    } else if (rlDest.sRegLow == rlSrc2.sRegLow) {
-        rlResult = loadValueWide(cUnit, rlDest, kCoreReg);
-        rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-        if (!carryOp) {
-            opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg, rlResult.lowReg);
-            opRegRegReg(cUnit, secondOp, rlResult.highReg, rlSrc1.highReg, rlResult.highReg);
-        } else if (secondOp == kOpAdc) {
-            withCarryHelper(cUnit, kMipsAddu, rlResult, rlSrc1, rlResult,
-                            rlResult.lowReg, rlSrc1.lowReg);
-        } else {
-            withCarryHelper(cUnit, kMipsSubu, rlResult, rlSrc1, rlResult,
-                            rlSrc1.lowReg, rlResult.lowReg);
-        }
-        storeValueWide(cUnit, rlDest, rlResult);
-    } else {
-        rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-        rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-        rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-        if (!carryOp) {
-            opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
-            opRegRegReg(cUnit, secondOp, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
-        } else if (secondOp == kOpAdc) {
-            withCarryHelper(cUnit, kMipsAddu, rlResult, rlSrc1, rlSrc2,
-                            rlResult.lowReg, rlSrc1.lowReg);
-        } else {
-            withCarryHelper(cUnit, kMipsSubu, rlResult, rlSrc1, rlSrc2,
-                            rlSrc1.lowReg, rlResult.lowReg);
-        }
-        storeValueWide(cUnit, rlDest, rlResult);
+            loadConstant(cUnit, tReg, checkValue);
+            return genCompareBranch(cUnit, cond, reg, tReg);
     }
-#endif
+    return newLIR1(cUnit, opc, reg);
 }
 
-void oatInitializeRegAlloc(CompilationUnit* cUnit)
+LIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
 {
-    int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
-    int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
-    int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
+    LIR* res;
+    MipsOpCode opcode;
 #ifdef __mips_hard_float
-    int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
-    int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+    if (FPREG(rDest) || FPREG(rSrc))
+        return fpRegCopy(cUnit, rDest, rSrc);
+#endif
+    res = (LIR *) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    opcode = kMipsMove;
+    assert(LOWREG(rDest) && LOWREG(rSrc));
+    res->operands[0] = rDest;
+    res->operands[1] = rSrc;
+    res->opcode = opcode;
+    setupResourceMasks(res);
+    if (rDest == rSrc) {
+        res->flags.isNop = true;
+    }
+    return res;
+}
+
+LIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+{
+    LIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
+    oatAppendLIR(cUnit, (LIR*)res);
+    return res;
+}
+
+void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
+                    int srcLo, int srcHi)
+{
+#ifdef __mips_hard_float
+    bool destFP = FPREG(destLo) && FPREG(destHi);
+    bool srcFP = FPREG(srcLo) && FPREG(srcHi);
+    assert(FPREG(srcLo) == FPREG(srcHi));
+    assert(FPREG(destLo) == FPREG(destHi));
+    if (destFP) {
+        if (srcFP) {
+            genRegCopy(cUnit, S2D(destLo, destHi), S2D(srcLo, srcHi));
+        } else {
+           /* note the operands are swapped for the mtc1 instr */
+            newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
+            newLIR2(cUnit, kMipsMtc1, srcHi, destHi);
+        }
+    } else {
+        if (srcFP) {
+            newLIR2(cUnit, kMipsMfc1, destLo, srcLo);
+            newLIR2(cUnit, kMipsMfc1, destHi, srcHi);
+        } else {
+            // Handle overlap
+            if (srcHi == destLo) {
+                genRegCopy(cUnit, destHi, srcHi);
+                genRegCopy(cUnit, destLo, srcLo);
+            } else {
+                genRegCopy(cUnit, destLo, srcLo);
+                genRegCopy(cUnit, destHi, srcHi);
+            }
+        }
+    }
 #else
-    int numFPRegs = 0;
-    int numFPTemps = 0;
+    // Handle overlap
+    if (srcHi == destLo) {
+        genRegCopy(cUnit, destHi, srcHi);
+        genRegCopy(cUnit, destLo, srcLo);
+    } else {
+        genRegCopy(cUnit, destLo, srcLo);
+        genRegCopy(cUnit, destHi, srcHi);
+    }
 #endif
-    RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
-                                                kAllocRegAlloc);
-    cUnit->regPool = pool;
-    pool->numCoreRegs = numRegs;
-    pool->coreRegs = (RegisterInfo *)
-            oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
-                   true, kAllocRegAlloc);
-    pool->numFPRegs = numFPRegs;
-    pool->FPRegs = numFPRegs == 0 ? NULL : (RegisterInfo *)
-            oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
-                   kAllocRegAlloc);
-    oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
-    oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
-    // Keep special registers from being allocated
-    for (int i = 0; i < numReserved; i++) {
-        if (NO_SUSPEND && !cUnit->genDebugger &&
-            (reservedRegs[i] == rSUSPEND)) {
-            //To measure cost of suspend check
-            continue;
-        }
-        oatMarkInUse(cUnit, reservedRegs[i]);
-    }
-    // Mark temp regs - all others not in use can be used for promotion
-    for (int i = 0; i < numTemps; i++) {
-        oatMarkTemp(cUnit, coreTemps[i]);
-    }
-    for (int i = 0; i < numFPTemps; i++) {
-        oatMarkTemp(cUnit, fpTemps[i]);
-    }
-    // Construct the alias map.
-    cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
-                                      sizeof(cUnit->phiAliasMap[0]), false,
-                                      kAllocDFInfo);
-    for (int i = 0; i < cUnit->numSSARegs; i++) {
-        cUnit->phiAliasMap[i] = i;
-    }
-    for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
-        int defReg = phi->ssaRep->defs[0];
-        for (int i = 0; i < phi->ssaRep->numUses; i++) {
-           for (int j = 0; j < cUnit->numSSARegs; j++) {
-               if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
-                   cUnit->phiAliasMap[j] = defReg;
-               }
-           }
-        }
-    }
-}
-
-STATIC void genMonitor(CompilationUnit *cUnit, MIR *mir)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-    genMonitorPortable(cUnit, mir);
-#endif
-}
-
-STATIC void genCmpLong(CompilationUnit *cUnit, MIR *mir, RegLocation rlDest,
-                       RegLocation rlSrc1, RegLocation rlSrc2)
-{
-    UNIMPLEMENTED(FATAL) << "Need Mips implementation";
-#if 0
-    RegLocation rlResult;
-    loadValueDirectWideFixed(cUnit, rlSrc1, r_ARG0, r_ARG1);
-    loadValueDirectWideFixed(cUnit, rlSrc2, r_ARG2, r_ARG3);
-    genDispatchToHandler(cUnit, TEMPLATE_CMP_LONG);
-    rlResult = oatGetReturn(cUnit);
-    storeValue(cUnit, rlDest, rlResult);
-#endif
-}
-
-STATIC void genMultiplyByTwoBitMultiplier(CompilationUnit *cUnit,
-        RegLocation rlSrc, RegLocation rlResult, int lit,
-        int firstBit, int secondBit)
-{
-    // We can't implement "add src, src, src, lsl#shift" on Thumb, so we have
-    // to do a regular multiply.
-    opRegRegImm(cUnit, kOpMul, rlResult.lowReg, rlSrc.lowReg, lit);
 }
 
 }  // namespace art
diff --git a/src/compiler/codegen/mips/Mips32/Ralloc.cc b/src/compiler/codegen/mips/Mips32/Ralloc.cc
index e0912d7..f8440a4 100644
--- a/src/compiler/codegen/mips/Mips32/Ralloc.cc
+++ b/src/compiler/codegen/mips/Mips32/Ralloc.cc
@@ -61,4 +61,76 @@
     return oatAllocTemp(cUnit);
 }
 
+void oatInitializeRegAlloc(CompilationUnit* cUnit)
+{
+    int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
+    int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
+    int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
+#ifdef __mips_hard_float
+    int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
+    int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+#else
+    int numFPRegs = 0;
+    int numFPTemps = 0;
+#endif
+    RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
+                                                kAllocRegAlloc);
+    cUnit->regPool = pool;
+    pool->numCoreRegs = numRegs;
+    pool->coreRegs = (RegisterInfo *)
+            oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
+                   true, kAllocRegAlloc);
+    pool->numFPRegs = numFPRegs;
+    pool->FPRegs = (RegisterInfo *)
+            oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
+                   kAllocRegAlloc);
+    oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
+    oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
+    // Keep special registers from being allocated
+    for (int i = 0; i < numReserved; i++) {
+        if (NO_SUSPEND && !cUnit->genDebugger &&
+            (reservedRegs[i] == rSUSPEND)) {
+            //To measure cost of suspend check
+            continue;
+        }
+        oatMarkInUse(cUnit, reservedRegs[i]);
+    }
+    // Mark temp regs - all others not in use can be used for promotion
+    for (int i = 0; i < numTemps; i++) {
+        oatMarkTemp(cUnit, coreTemps[i]);
+    }
+    for (int i = 0; i < numFPTemps; i++) {
+        oatMarkTemp(cUnit, fpTemps[i]);
+    }
+    // Construct the alias map.
+    cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
+                                      sizeof(cUnit->phiAliasMap[0]), false,
+                                      kAllocDFInfo);
+    for (int i = 0; i < cUnit->numSSARegs; i++) {
+        cUnit->phiAliasMap[i] = i;
+    }
+    for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
+        int defReg = phi->ssaRep->defs[0];
+        for (int i = 0; i < phi->ssaRep->numUses; i++) {
+           for (int j = 0; j < cUnit->numSSARegs; j++) {
+               if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
+                   cUnit->phiAliasMap[j] = defReg;
+               }
+           }
+        }
+    }
+}
+
+void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
+                     RegLocation rlFree)
+{
+    if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
+        (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
+        // No overlap, free both
+        oatFreeTemp(cUnit, rlFree.lowReg);
+        oatFreeTemp(cUnit, rlFree.highReg);
+    }
+}
+
+
 }  // namespace art
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index 44f0c5a..93956d5 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -149,10 +149,10 @@
                       INVALID_SREG}
 #define LOC_C_RETURN_ALT {kLocPhysReg, 0, 0, 0, 0, 0, 1, r_F0, INVALID_REG, \
                       INVALID_SREG}
-#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_V0, r_V1,\
+#define LOC_C_RETURN_WIDE {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_RESULT0, r_RESULT1,\
                            INVALID_SREG}
-#define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_F0, r_F1,\
-                           INVALID_SREG}
+#define LOC_C_RETURN_WIDE_ALT {kLocPhysReg, 1, 0, 0, 0, 0, 1, r_FRESULT0,\
+                               r_FRESULT1, INVALID_SREG}
 
 typedef enum ResourceEncodingPos {
     kGPReg0     = 0,
@@ -194,25 +194,6 @@
 #define DECODE_ALIAS_INFO_WIDE(X)       ((X & 0x80000000) ? 1 : 0)
 
 /*
- * FIXME:
- * Originally had r4PC as r_S0, rFP as r_S1, rSELF as r_S2, rINST as r_S4
- * Remap - don't need r4PC, rFP or rINST.  Might make sense to keep
- * Method* in one of these since we have so many registers to play with.
- */
-
-#define rSUSPEND r_S0
-#define rSELF r_S1
-#define rSP r_SP
-
-#define rARG0 r_ARG0
-#define rARG1 r_ARG1
-#define rARG2 r_ARG2
-#define rARG3 r_ARG3
-
-#define rRET0 r_V0
-#define rRET1 r_V1
-
-/*
  * Annotate special-purpose core registers:
  */
 
@@ -307,6 +288,21 @@
     r_PC,
 } NativeRegisterPool;
 
+/*
+ * Target-independent aliases
+ */
+
+#define rSUSPEND r_S0
+#define rSELF r_S1
+#define rSP r_SP
+#define rARG0 r_ARG0
+#define rARG1 r_ARG1
+#define rARG2 r_ARG2
+#define rARG3 r_ARG3
+#define rRET0 r_RESULT0
+#define rRET1 r_RESULT1
+#define rLINK r_RA
+
 /* Shift encodings */
 typedef enum MipsShiftEncodings {
     kMipsLsl = 0x0,
@@ -335,15 +331,9 @@
     kMipsCondNv = 0xf,    /* 1111 */
 } MipsConditionCode;
 
-typedef enum MipsThrowKind {
-    kMipsThrowNullPointer,
-    kMipsThrowDivZero,
-    kMipsThrowArrayBounds,
-    kMipsThrowVerificationError,
-    kMipsThrowNegArraySize,
-    kMipsThrowNoSuchMethod,
-    kMipsThrowStackOverflow,
-} MipsThrowKind;
+// FIXME: Need support for barriers.  Adding these defines to allow compile
+#define kST 0
+#define kSY 1
 
 #define isPseudoOpcode(opCode) ((int)(opCode) < 0)
 
@@ -487,6 +477,8 @@
     kUsesCCodes,
     kMemLoad,
     kMemStore,
+    kPCRelFixup,
+// FIXME: add NEEDS_FIXUP to instruction attributes
 } MipsOpFeatureFlags;
 
 #define IS_LOAD         (1 << kMemLoad)
@@ -514,6 +506,12 @@
 #define IS_IT           (1 << kIsIT)
 #define SETS_CCODES     (1 << kSetsCCodes)
 #define USES_CCODES     (1 << kUsesCCodes)
+#define NEEDS_FIXUP      (1 << kPCRelFixup)
+
+/*  attributes, included for compatibility */
+#define REG_DEF_FPCS_LIST0   (0)
+#define REG_DEF_FPCS_LIST2   (0)
+
 
 /* Common combo register usage patterns */
 #define REG_USE01       (REG_USE0 | REG_USE1)
@@ -559,63 +557,6 @@
 
 extern MipsEncodingMap EncodingMap[kMipsLast];
 
-/*
- * Each instance of this struct holds a pseudo or real LIR instruction:
- * - pseudo ones (eg labels and marks) and will be discarded by the assembler.
- * - real ones will be assembled
- *
- * FIXME: notes below are Arm-specific.  We have 32 core registers instead
- * of 16, and no IT blocks.  Must widen this or overload in order to
- * support all 32 FP regs.  Perhaps use r0 for ccodes, eliminate IT block
- * and overload gp with fp status word? (or just use a single bit for
- * both core and fp condition code/status word?
- *
- * Machine resources are encoded into a 64-bit vector, where the encodings are
- * as following:
- * - [ 0..15]: general purpose registers including PC, SP, and LR
- * - [16..47]: floating-point registers where d0 is expanded to s[01] and s0
- *   starts at bit 16
- * - [48]: IT block
- * - [49]: integer condition code
- * - [50]: floatint-point status word
- */
-typedef struct MipsLIR {
-    LIR generic;
-    MipsOpCode opcode;
-    int operands[4];            // [0..3] = [dest, src1, src2, extra]
-    struct {
-        bool isNop:1;           // LIR is optimized away
-        bool pcRelFixup:1;      // May need pc-relative fixup
-        unsigned int age:4;     // default is 0, set lazily by the optimizer
-        unsigned int size:3;    // in bytes
-        unsigned int unused:23;
-    } flags;
-    int aliasInfo;              // For Dalvik register access & litpool disambiguation
-    u8 useMask;                 // Resource mask for use
-    u8 defMask;                 // Resource mask for def
-} MipsLIR;
-
-typedef struct SwitchTable {
-    int offset;
-    const u2* table;            // Original dex table
-    int vaddr;                  // Dalvik offset of switch opcode
-    MipsLIR* bxInst;             // Switch indirect branch instruction
-    MipsLIR** targets;           // Array of case targets
-} SwitchTable;
-
-typedef struct FillArrayData {
-    int offset;
-    const u2* table;           // Original dex table
-    int size;
-    int vaddr;                 // Dalvik offset of OP_FILL_ARRAY_DATA opcode
-} FillArrayData;
-
-/* Utility macros to traverse the LIR/MipsLIR list */
-#define NEXT_LIR(lir) ((MipsLIR *) lir->generic.next)
-#define PREV_LIR(lir) ((MipsLIR *) lir->generic.prev)
-
-#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
-#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
 
 #define IS_UIMM16(v) ((0 <= (v)) && ((v) <= 65535))
 #define IS_SIMM16(v) ((-32768 <= (v)) && ((v) <= 32766))
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
index 0dfbfa5..504375b 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -48,20 +48,6 @@
 void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
 {
     UNIMPLEMENTED(FATAL) << "No support yet for promoted FP regs";
-#if 0
-    DCHECK_GE(reg, FP_REG_MASK + FP_CALLEE_SAVE_BASE);
-    reg = (reg & FP_REG_MASK) - FP_CALLEE_SAVE_BASE;
-    // Ensure fpVmapTable is large enough
-    int tableSize = cUnit->fpVmapTable.size();
-    for (int i = tableSize; i < (reg + 1); i++) {
-        cUnit->fpVmapTable.push_back(INVALID_VREG);
-    }
-    // Add the current mapping
-    cUnit->fpVmapTable[reg] = sReg;
-    // Size of fpVmapTable is high-water mark, use to set mask
-    cUnit->numFPSpills = cUnit->fpVmapTable.size();
-    cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << FP_CALLEE_SAVE_BASE;
-#endif
 }
 
 void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
@@ -159,10 +145,10 @@
 extern RegLocation oatGetReturnWide(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN_WIDE;
-    oatClobber(cUnit, r_V0);
-    oatClobber(cUnit, r_V1);
-    oatMarkInUse(cUnit, r_V0);
-    oatMarkInUse(cUnit, r_V1);
+    oatClobber(cUnit, res.lowReg);
+    oatClobber(cUnit, res.highReg);
+    oatMarkInUse(cUnit, res.lowReg);
+    oatMarkInUse(cUnit, res.highReg);
     oatMarkPair(cUnit, res.lowReg, res.highReg);
     return res;
 }
@@ -170,10 +156,10 @@
 extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN_WIDE_ALT;
-    oatClobber(cUnit, r_F0);
-    oatClobber(cUnit, r_F1);
-    oatMarkInUse(cUnit, r_F0);
-    oatMarkInUse(cUnit, r_F1);
+    oatClobber(cUnit, res.lowReg);
+    oatClobber(cUnit, res.highReg);
+    oatMarkInUse(cUnit, res.lowReg);
+    oatMarkInUse(cUnit, res.highReg);
     oatMarkPair(cUnit, res.lowReg, res.highReg);
     return res;
 }
@@ -181,16 +167,16 @@
 extern RegLocation oatGetReturn(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN;
-    oatClobber(cUnit, r_V0);
-    oatMarkInUse(cUnit, r_V0);
+    oatClobber(cUnit, res.lowReg);
+    oatMarkInUse(cUnit, res.lowReg);
     return res;
 }
 
 extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN_ALT;
-    oatClobber(cUnit, r_F0);
-    oatMarkInUse(cUnit, r_F0);
+    oatClobber(cUnit, res.lowReg);
+    oatMarkInUse(cUnit, res.lowReg);
     return res;
 }
 
@@ -203,25 +189,25 @@
 /* To be used when explicitly managing register use */
 extern void oatLockCallTemps(CompilationUnit* cUnit)
 {
-    oatLockTemp(cUnit, r_A0);
-    oatLockTemp(cUnit, r_A1);
-    oatLockTemp(cUnit, r_A2);
-    oatLockTemp(cUnit, r_A3);
+    oatLockTemp(cUnit, rARG0);
+    oatLockTemp(cUnit, rARG1);
+    oatLockTemp(cUnit, rARG2);
+    oatLockTemp(cUnit, rARG3);
 }
 
 /* To be used when explicitly managing register use */
 extern void oatFreeCallTemps(CompilationUnit* cUnit)
 {
-    oatFreeTemp(cUnit, r_A0);
-    oatFreeTemp(cUnit, r_A1);
-    oatFreeTemp(cUnit, r_A2);
-    oatFreeTemp(cUnit, r_A3);
+    oatFreeTemp(cUnit, rARG0);
+    oatFreeTemp(cUnit, rARG1);
+    oatFreeTemp(cUnit, rARG2);
+    oatFreeTemp(cUnit, rARG3);
 }
 
 /* Convert an instruction to a NOP */
-STATIC void oatNopLIR( LIR* lir)
+void oatNopLIR( LIR* lir)
 {
-    ((MipsLIR*)lir)->flags.isNop = true;
+    ((LIR*)lir)->flags.isNop = true;
 }
 
 }  // namespace art
diff --git a/src/compiler/codegen/mips/mips/Codegen.cc b/src/compiler/codegen/mips/mips/Codegen.cc
index 22a7c94..71f43e5 100644
--- a/src/compiler/codegen/mips/mips/Codegen.cc
+++ b/src/compiler/codegen/mips/mips/Codegen.cc
@@ -15,7 +15,7 @@
  */
 
 #define _CODEGEN_C
-#define TGT_LIR MipsLIR
+#define TARGET_MIPS
 
 #include "../../../Dalvik.h"
 #include "../../../CompilerInternals.h"
@@ -24,12 +24,16 @@
 #include "../Codegen.h"
 
 /* Mips codegen building blocks */
-#include "../CodegenCommon.cc"
+#include "../../CodegenUtil.cc"
 
 /* Mips-specific factory utilities */
 #include "../Mips32/Factory.cc"
-/* Target indepedent factory utilities */
+/* Target independent factory utilities */
 #include "../../CodegenFactory.cc"
+/* Target independent gen routines */
+#include "../../GenCommon.cc"
+/* Shared invoke gen routines */
+#include "../../GenInvoke.cc"
 /* Mips-specific factory utilities */
 #include "../ArchFactory.cc"
 
@@ -47,8 +51,5 @@
 /* Target-independent local optimizations */
 #include "../../LocalOptimizations.cc"
 
-/* Common codegen utility code */
-#include "../../CodegenUtil.cc"
-
 /* Architecture manifest */
 #include "ArchVariant.cc"