diff --git a/build/Android.common.mk b/build/Android.common.mk
index 3f6b84b..05228c7 100644
--- a/build/Android.common.mk
+++ b/build/Android.common.mk
@@ -21,6 +21,13 @@
 ART_USE_LLVM_COMPILER := false
 endif
 
+# Build for MIPS target (temporary)
+ifneq ($(wildcard art/MIPS_TARGET),)
+ART_MIPS_TARGET := true
+else
+ART_MIPS_TARGET := false
+endif
+
 ifeq ($(ART_USE_LLVM_COMPILER),true)
 LLVM_ROOT_PATH := external/llvm
 include $(LLVM_ROOT_PATH)/llvm.mk
@@ -60,6 +67,11 @@
 art_cflags += -DART_USE_LLVM_COMPILER=1
 endif
 
+# (temp) for testing
+ifeq ($(ART_MIPS_TARGET),true)
+art_cflags += -D__mips_hard_float
+endif
+
 ifeq ($(HOST_OS),linux)
   art_non_debug_cflags := \
 	-Wframe-larger-than=1728
@@ -224,12 +236,21 @@
 	src/compiler/SSATransformation.cc \
 	src/compiler/Utility.cc \
 	src/compiler/codegen/RallocUtil.cc \
+	src/jni_internal_arm.cc \
+	src/jni_internal_x86.cc
+ifeq ($(ART_MIPS_TARGET),true)
+LIBART_COMMON_SRC_FILES += \
+	src/compiler/codegen/mips/ArchUtility.cc \
+	src/compiler/codegen/mips/MipsRallocUtil.cc \
+	src/compiler/codegen/mips/Assemble.cc \
+	src/compiler/codegen/mips/mips/Codegen.cc
+else
+LIBART_COMMON_SRC_FILES += \
 	src/compiler/codegen/arm/ArchUtility.cc \
 	src/compiler/codegen/arm/ArmRallocUtil.cc \
 	src/compiler/codegen/arm/Assemble.cc \
-	src/compiler/codegen/arm/armv7-a/Codegen.cc \
-	src/jni_internal_arm.cc \
-	src/jni_internal_x86.cc
+	src/compiler/codegen/arm/armv7-a/Codegen.cc
+endif
 endif
 
 LIBART_TARGET_SRC_FILES := \
diff --git a/src/compiler/Compiler.h b/src/compiler/Compiler.h
index d07fe18..c7a1ac3 100644
--- a/src/compiler/Compiler.h
+++ b/src/compiler/Compiler.h
@@ -178,13 +178,11 @@
 
 void oatInit(CompilationUnit* cUnit, const Compiler& compiler);
 bool oatArchInit(void);
-void oatArchDump(void);
 bool oatStartup(void);
 void oatShutdown(void);
 CompiledMethod* oatCompileMethod(Compiler& compiler, bool is_direct,
                                  uint32_t method_idx, const ClassLoader* class_loader,
                                  const DexFile& dex_file, OatInstructionSetType);
-void oatDumpStats(void);
 void oatScanAllClassPointers(void (*callback)(void* ptr));
 void oatInitializeSSAConversion(struct CompilationUnit* cUnit);
 int oatConvertSSARegToDalvik(const struct CompilationUnit* cUnit, int ssaReg);
diff --git a/src/compiler/CompilerIR.h b/src/compiler/CompilerIR.h
index 66cc322..34ccfb4 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/CompilerIR.h
@@ -20,9 +20,21 @@
 #include "codegen/Optimizer.h"
 #include "CompilerUtility.h"
 #include <vector>
+#include "oat_compilation_unit.h"
 
 namespace art {
 
+#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))
+
 typedef enum RegisterClass {
     kCoreReg,
     kFPReg,
@@ -108,12 +120,31 @@
     kCatchEntry,
 } BBType;
 
+/* Utility macros to traverse the LIR list */
+#define NEXT_LIR(lir) (lir->next)
+#define PREV_LIR(lir) (lir->prev)
+
+#define NEXT_LIR_LVALUE(lir) (lir)->next
+#define PREV_LIR_LVALUE(lir) (lir)->prev
+
 typedef struct LIR {
     int offset;                        // Offset of this instruction
     int dalvikOffset;                  // Offset of Dalvik opcode
     struct LIR* next;
     struct LIR* prev;
     struct LIR* target;
+    int 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:4;    // in bytes
+        unsigned int unused:22;
+    } flags;
+    int aliasInfo;              // For Dalvik register & litpool disambiguation
+    u8 useMask;                 // Resource mask for use
+    u8 defMask;                 // Resource mask for def
 } LIR;
 
 enum ExtendedMIROpcode {
@@ -381,6 +412,71 @@
     kSignedByte,
 } OpSize;
 
+typedef enum OpKind {
+    kOpMov,
+    kOpMvn,
+    kOpCmp,
+    kOpLsl,
+    kOpLsr,
+    kOpAsr,
+    kOpRor,
+    kOpNot,
+    kOpAnd,
+    kOpOr,
+    kOpXor,
+    kOpNeg,
+    kOpAdd,
+    kOpAdc,
+    kOpSub,
+    kOpSbc,
+    kOpRsub,
+    kOpMul,
+    kOpDiv,
+    kOpRem,
+    kOpBic,
+    kOpCmn,
+    kOpTst,
+    kOpBkpt,
+    kOpBlx,
+    kOpPush,
+    kOpPop,
+    kOp2Char,
+    kOp2Short,
+    kOp2Byte,
+    kOpCondBr,
+    kOpUncondBr,
+    kOpInvalid,
+} OpKind;
+
+typedef enum ConditionCode {
+    kCondEq,
+    kCondNe,
+    kCondCs,
+    kCondCc,
+    kCondMi,
+    kCondPl,
+    kCondVs,
+    kCondVc,
+    kCondHi,
+    kCondLs,
+    kCondGe,
+    kCondLt,
+    kCondGt,
+    kCondLe,
+    kCondAl,
+    kCondNv,
+} ConditionCode;
+
+typedef enum ThrowKind {
+    kThrowNullPointer,
+    kThrowDivZero,
+    kThrowArrayBounds,
+    kThrowVerificationError,
+    kThrowNegArraySize,
+    kThrowNoSuchMethod,
+    kThrowStackOverflow,
+} ThrowKind;
+
 BasicBlock* oatNewBB(CompilationUnit* cUnit, BBType blockType, int blockId);
 
 void oatAppendMIR(BasicBlock* bb, MIR* mir);
diff --git a/src/compiler/Dalvik.h b/src/compiler/Dalvik.h
index 4753910..9af49aa 100644
--- a/src/compiler/Dalvik.h
+++ b/src/compiler/Dalvik.h
@@ -55,13 +55,6 @@
 #include "DexOpcodes.h"
 #include "InstrUtils.h"
 
-// use to switch visibility on DCHECK tracebacks
-#if 1
-#define STATIC
-#else
-#define STATIC static
-#endif
-
 #include "Compiler.h"
 
 #endif
diff --git a/src/compiler/Dataflow.cc b/src/compiler/Dataflow.cc
index 4572857..733552c 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/Dataflow.cc
@@ -917,8 +917,7 @@
 /*
  * Dalvik instruction disassembler with optional SSA printing.
  */
-char* oatFullDisassembler(CompilationUnit* cUnit,
-                          const MIR* mir)
+char* oatFullDisassembler(CompilationUnit* cUnit, const MIR* mir)
 {
     char buffer[256];
     char operand0[32], operand1[32];
@@ -1084,9 +1083,9 @@
 }
 
 /* Any register that is used before being defined is considered live-in */
-STATIC inline void handleLiveInUse(CompilationUnit* cUnit, ArenaBitVector* useV,
-                                   ArenaBitVector* defV,
-                                   ArenaBitVector* liveInV, int dalvikRegId)
+inline void handleLiveInUse(CompilationUnit* cUnit, ArenaBitVector* useV,
+                            ArenaBitVector* defV, ArenaBitVector* liveInV,
+                            int dalvikRegId)
 {
     oatSetBit(cUnit, useV, dalvikRegId);
     if (!oatIsBitSet(defV, dalvikRegId)) {
@@ -1095,8 +1094,8 @@
 }
 
 /* Mark a reg as being defined */
-STATIC inline void handleDef(CompilationUnit* cUnit, ArenaBitVector* defV,
-                             int dalvikRegId)
+inline void handleDef(CompilationUnit* cUnit, ArenaBitVector* defV,
+                      int dalvikRegId)
 {
     oatSetBit(cUnit, defV, dalvikRegId);
 }
@@ -1166,8 +1165,8 @@
 }
 
 /* Find out the latest SSA register for a given Dalvik register */
-STATIC void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
-                         int regIndex)
+void handleSSAUse(CompilationUnit* cUnit, int* uses, int dalvikReg,
+                  int regIndex)
 {
     int encodedValue = cUnit->dalvikToSSAMap[dalvikReg];
     int ssaReg = DECODE_REG(encodedValue);
@@ -1175,8 +1174,8 @@
 }
 
 /* Setup a new SSA register for a given Dalvik register */
-STATIC void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
-                         int regIndex)
+void handleSSADef(CompilationUnit* cUnit, int* defs, int dalvikReg,
+                  int regIndex)
 {
     int ssaReg = cUnit->numSSARegs++;
     /* Bump up the subscript */
@@ -1192,7 +1191,7 @@
 }
 
 /* Look up new SSA names for format_35c instructions */
-STATIC void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
+void dataFlowSSAFormat35C(CompilationUnit* cUnit, MIR* mir)
 {
     DecodedInstruction *dInsn = &mir->dalvikInsn;
     int numUses = dInsn->vA;
@@ -1211,7 +1210,7 @@
 }
 
 /* Look up new SSA names for format_3rc instructions */
-STATIC void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
+void dataFlowSSAFormat3RC(CompilationUnit* cUnit, MIR* mir)
 {
     DecodedInstruction *dInsn = &mir->dalvikInsn;
     int numUses = dInsn->vA;
@@ -1370,7 +1369,7 @@
 }
 
 /* Setup a constant value for opcodes thare have the DF_SETS_CONST attribute */
-STATIC void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
+void setConstant(CompilationUnit* cUnit, int ssaReg, int value)
 {
     oatSetBit(cUnit, cUnit->isConstantV, ssaReg);
     cUnit->constantValues[ssaReg] = value;
@@ -1515,8 +1514,7 @@
 }
 
 /* Clear the visited flag for each BB */
-bool oatClearVisitedFlag(struct CompilationUnit* cUnit,
-                                 struct BasicBlock* bb)
+bool oatClearVisitedFlag(struct CompilationUnit* cUnit, struct BasicBlock* bb)
 {
     bb->visited = false;
     return true;
@@ -1636,8 +1634,8 @@
     }
 }
 
-STATIC bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
-                                     struct BasicBlock* bb)
+bool nullCheckEliminationInit(struct CompilationUnit* cUnit,
+                              struct BasicBlock* bb)
 {
     if (bb->dataFlowInfo == NULL) return false;
     bb->dataFlowInfo->endingNullCheckV =
@@ -1647,8 +1645,7 @@
 }
 
 /* Eliminate unnecessary null checks for a basic block. */
-STATIC bool eliminateNullChecks( struct CompilationUnit* cUnit,
-                                 struct BasicBlock* bb)
+bool eliminateNullChecks( struct CompilationUnit* cUnit, struct BasicBlock* bb)
 {
     if (bb->dataFlowInfo == NULL) return false;
 
diff --git a/src/compiler/Frontend.cc b/src/compiler/Frontend.cc
index 701e245..92ffefc 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/Frontend.cc
@@ -49,7 +49,7 @@
      //(1 << kDebugShowMemoryUsage) |
      0;
 
-STATIC inline bool contentIsInsn(const u2* codePtr) {
+inline bool contentIsInsn(const u2* codePtr) {
     u2 instr = *codePtr;
     Opcode opcode = (Opcode)(instr & 0xff);
 
@@ -63,7 +63,7 @@
 /*
  * Parse an instruction, return the length of the instruction
  */
-STATIC inline int parseInsn(CompilationUnit* cUnit, const u2* codePtr,
+inline int parseInsn(CompilationUnit* cUnit, const u2* codePtr,
                             DecodedInstruction* decInsn, bool printMe)
 {
     // Don't parse instruction data
@@ -85,7 +85,7 @@
 
 #define UNKNOWN_TARGET 0xffffffff
 
-STATIC inline bool isGoto(MIR* insn)
+inline bool isGoto(MIR* insn)
 {
     switch (insn->dalvikInsn.opcode) {
         case OP_GOTO:
@@ -100,7 +100,7 @@
 /*
  * Identify unconditional branch instructions
  */
-STATIC inline bool isUnconditionalBranch(MIR* insn)
+inline bool isUnconditionalBranch(MIR* insn)
 {
     switch (insn->dalvikInsn.opcode) {
         case OP_RETURN_VOID:
@@ -114,10 +114,8 @@
 }
 
 /* Split an existing block from the specified code offset into two */
-STATIC BasicBlock *splitBlock(CompilationUnit* cUnit,
-                              unsigned int codeOffset,
-                              BasicBlock* origBlock,
-                              BasicBlock** immedPredBlockP)
+BasicBlock *splitBlock(CompilationUnit* cUnit, unsigned int codeOffset,
+                       BasicBlock* origBlock, BasicBlock** immedPredBlockP)
 {
     MIR* insn = origBlock->firstMIRInsn;
     while (insn) {
@@ -205,10 +203,8 @@
  * (by the caller)
  * Utilizes a map for fast lookup of the typical cases.
  */
-STATIC BasicBlock *findBlock(CompilationUnit* cUnit,
-                             unsigned int codeOffset,
-                             bool split, bool create,
-                             BasicBlock** immedPredBlockP)
+BasicBlock *findBlock(CompilationUnit* cUnit, unsigned int codeOffset,
+                      bool split, bool create, BasicBlock** immedPredBlockP)
 {
     GrowableList* blockList = &cUnit->blockList;
     BasicBlock* bb;
@@ -404,7 +400,7 @@
 }
 
 /* Verify if all the successor is connected with all the claimed predecessors */
-STATIC bool verifyPredInfo(CompilationUnit* cUnit, BasicBlock* bb)
+bool verifyPredInfo(CompilationUnit* cUnit, BasicBlock* bb)
 {
     GrowableListIterator iter;
 
@@ -446,7 +442,7 @@
 }
 
 /* Identify code range in try blocks and set up the empty catch blocks */
-STATIC void processTryCatchBlocks(CompilationUnit* cUnit)
+void processTryCatchBlocks(CompilationUnit* cUnit)
 {
     const DexFile::CodeItem* code_item = cUnit->code_item;
     int triesSize = code_item->tries_size_;
@@ -484,10 +480,9 @@
 }
 
 /* Process instructions with the kInstrCanBranch flag */
-STATIC BasicBlock* processCanBranch(CompilationUnit* cUnit,
-                                    BasicBlock* curBlock, MIR* insn,
-                                    int curOffset, int width, int flags,
-                                    const u2* codePtr, const u2* codeEnd)
+BasicBlock* processCanBranch(CompilationUnit* cUnit, BasicBlock* curBlock,
+                             MIR* insn, int curOffset, int width, int flags,
+                             const u2* codePtr, const u2* codeEnd)
 {
     int target = curOffset;
     switch (insn->dalvikInsn.opcode) {
@@ -566,8 +561,8 @@
 }
 
 /* Process instructions with the kInstrCanSwitch flag */
-STATIC void processCanSwitch(CompilationUnit* cUnit, BasicBlock* curBlock,
-                             MIR* insn, int curOffset, int width, int flags)
+void processCanSwitch(CompilationUnit* cUnit, BasicBlock* curBlock,
+                      MIR* insn, int curOffset, int width, int flags)
 {
     u2* switchData= (u2 *) (cUnit->insns + curOffset +
                             insn->dalvikInsn.vB);
@@ -654,10 +649,10 @@
 }
 
 /* Process instructions with the kInstrCanThrow flag */
-STATIC void processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock,
-                            MIR* insn, int curOffset, int width, int flags,
-                            ArenaBitVector* tryBlockAddr, const u2* codePtr,
-                            const u2* codeEnd)
+void processCanThrow(CompilationUnit* cUnit, BasicBlock* curBlock, MIR* insn,
+                     int curOffset, int width, int flags,
+                     ArenaBitVector* tryBlockAddr, const u2* codePtr,
+                     const u2* codeEnd)
 {
     const DexFile::CodeItem* code_item = cUnit->code_item;
 
@@ -735,10 +730,12 @@
 /*
  * Compile a method.
  */
-CompiledMethod* oatCompileMethod(Compiler& compiler, const DexFile::CodeItem* code_item,
+CompiledMethod* oatCompileMethod(Compiler& compiler,
+                                 const DexFile::CodeItem* code_item,
                                  uint32_t access_flags, uint32_t method_idx,
                                  const ClassLoader* class_loader,
-                                 const DexFile& dex_file, InstructionSet insnSet)
+                                 const DexFile& dex_file,
+                                 InstructionSet insnSet)
 {
     VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
 
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index bf9cb6a..09c2b7e 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -21,7 +21,7 @@
 
 namespace art {
 
-STATIC bool setFp(CompilationUnit* cUnit, int index, bool isFP) {
+bool setFp(CompilationUnit* cUnit, int index, bool isFP) {
     bool change = false;
     if (cUnit->regLocation[index].highWord) {
         return change;
@@ -34,7 +34,7 @@
     return change;
 }
 
-STATIC bool setCore(CompilationUnit* cUnit, int index, bool isCore) {
+bool setCore(CompilationUnit* cUnit, int index, bool isCore) {
     bool change = false;
     if (cUnit->regLocation[index].highWord) {
         return change;
@@ -47,7 +47,7 @@
     return change;
 }
 
-STATIC bool remapNames(CompilationUnit* cUnit, BasicBlock* bb)
+bool remapNames(CompilationUnit* cUnit, BasicBlock* bb)
 {
     if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock &&
         bb->blockType != kExitBlock)
@@ -68,7 +68,7 @@
 }
 
 // Try to find the next move result which might have an FP target
-STATIC SSARepresentation* findMoveResult(MIR* mir)
+SSARepresentation* findMoveResult(MIR* mir)
 {
     SSARepresentation* res = NULL;
     for (; mir; mir = mir->next) {
@@ -86,7 +86,7 @@
  * as it doesn't propagate.  We're guaranteed at least one pass through
  * the cfg.
  */
-STATIC bool inferTypeAndSize(CompilationUnit* cUnit, BasicBlock* bb)
+bool inferTypeAndSize(CompilationUnit* cUnit, BasicBlock* bb)
 {
     MIR *mir;
     bool changed = false;   // Did anything change?
diff --git a/src/compiler/SSATransformation.cc b/src/compiler/SSATransformation.cc
index 99de0a7..352828f 100644
--- a/src/compiler/SSATransformation.cc
+++ b/src/compiler/SSATransformation.cc
@@ -20,7 +20,7 @@
 namespace art {
 
 /* Enter the node to the dfsOrder list then visit its successors */
-STATIC void recordDFSOrders(CompilationUnit* cUnit, BasicBlock* block)
+void recordDFSOrders(CompilationUnit* cUnit, BasicBlock* block)
 {
 
     if (block->visited || block->hidden) return;
@@ -51,7 +51,7 @@
 }
 
 /* Sort the blocks by the Depth-First-Search */
-STATIC void computeDFSOrders(CompilationUnit* cUnit)
+void computeDFSOrders(CompilationUnit* cUnit)
 {
     /* Initialize or reset the DFS preOrder list */
     if (cUnit->dfsOrder.elemList == NULL) {
@@ -83,7 +83,7 @@
  * Mark block bit on the per-Dalvik register vector to denote that Dalvik
  * register idx is defined in BasicBlock bb.
  */
-STATIC bool fillDefBlockMatrix(CompilationUnit* cUnit, BasicBlock* bb)
+bool fillDefBlockMatrix(CompilationUnit* cUnit, BasicBlock* bb)
 {
     if (bb->dataFlowInfo == NULL) return false;
 
@@ -99,7 +99,7 @@
     return true;
 }
 
-STATIC void computeDefBlockMatrix(CompilationUnit* cUnit)
+void computeDefBlockMatrix(CompilationUnit* cUnit)
 {
     int numRegisters = cUnit->numDalvikRegisters;
     /* Allocate numDalvikRegisters bit vector pointers */
@@ -132,7 +132,7 @@
 }
 
 /* Compute the post-order traversal of the CFG */
-STATIC void computeDomPostOrderTraversal(CompilationUnit* cUnit, BasicBlock* bb)
+void computeDomPostOrderTraversal(CompilationUnit* cUnit, BasicBlock* bb)
 {
     ArenaBitVectorIterator bvIterator;
     oatBitVectorIteratorInit(bb->iDominated, &bvIterator);
@@ -157,8 +157,8 @@
     }
 }
 
-STATIC void checkForDominanceFrontier(CompilationUnit* cUnit, BasicBlock* domBB,
-                                      const BasicBlock* succBB)
+void checkForDominanceFrontier(CompilationUnit* cUnit, BasicBlock* domBB,
+                               const BasicBlock* succBB)
 {
     /*
      * TODO - evaluate whether phi will ever need to be inserted into exit
@@ -172,7 +172,7 @@
 }
 
 /* Worker function to compute the dominance frontier */
-STATIC bool computeDominanceFrontier(CompilationUnit* cUnit, BasicBlock* bb)
+bool computeDominanceFrontier(CompilationUnit* cUnit, BasicBlock* bb)
 {
     GrowableList* blockList = &cUnit->blockList;
 
@@ -221,7 +221,7 @@
 }
 
 /* Worker function for initializing domination-related data structures */
-STATIC bool initializeDominationInfo(CompilationUnit* cUnit, BasicBlock* bb)
+bool initializeDominationInfo(CompilationUnit* cUnit, BasicBlock* bb)
 {
     int numTotalBlocks = cUnit->blockList.numUsed;
 
@@ -251,7 +251,7 @@
  * is only used when kDebugVerifyDataflow is active and should compute
  * the same dominator sets as computeBlockDominators.
  */
-STATIC bool slowComputeBlockDominators(CompilationUnit* cUnit, BasicBlock* bb)
+bool slowComputeBlockDominators(CompilationUnit* cUnit, BasicBlock* bb)
 {
     GrowableList* blockList = &cUnit->blockList;
     int numTotalBlocks = blockList->numUsed;
@@ -289,7 +289,7 @@
  * used when kDebugVerifyDataflow is active and should compute the
  * same iDom as computeBlockIDom.
  */
-STATIC bool slowComputeBlockIDom(CompilationUnit* cUnit, BasicBlock* bb)
+bool slowComputeBlockIDom(CompilationUnit* cUnit, BasicBlock* bb)
 {
     GrowableList* blockList = &cUnit->blockList;
     ArenaBitVector* tempBlockV = cUnit->tempBlockV;
@@ -352,7 +352,7 @@
 }
 
 /* Worker function to compute each block's immediate dominator */
-STATIC bool computeBlockIDom(CompilationUnit* cUnit, BasicBlock* bb)
+bool computeBlockIDom(CompilationUnit* cUnit, BasicBlock* bb)
 {
     GrowableListIterator iter;
     int idom = -1;
@@ -397,7 +397,7 @@
 }
 
 /* Worker function to compute each block's domintors */
-STATIC bool computeBlockDominators(CompilationUnit* cUnit, BasicBlock* bb)
+bool computeBlockDominators(CompilationUnit* cUnit, BasicBlock* bb)
 {
     if (bb == cUnit->entryBlock) {
         oatClearAllBits(bb->dominators);
@@ -408,7 +408,7 @@
     return false;
 }
 
-STATIC bool setDominators(CompilationUnit* cUnit, BasicBlock* bb)
+bool setDominators(CompilationUnit* cUnit, BasicBlock* bb)
 {
     if (bb != cUnit->entryBlock) {
         int iDomDFSIdx = cUnit->iDomList[bb->dfsId];
@@ -427,7 +427,7 @@
 }
 
 /* Compute dominators, immediate dominator, and dominance fronter */
-STATIC void computeDominators(CompilationUnit* cUnit)
+void computeDominators(CompilationUnit* cUnit)
 {
     int numReachableBlocks = cUnit->numReachableBlocks;
     int numTotalBlocks = cUnit->blockList.numUsed;
@@ -513,7 +513,7 @@
  * Perform dest U= src1 ^ ~src2
  * This is probably not general enough to be placed in BitVector.[ch].
  */
-STATIC void computeSuccLiveIn(ArenaBitVector* dest,
+void computeSuccLiveIn(ArenaBitVector* dest,
                               const ArenaBitVector* src1,
                               const ArenaBitVector* src2)
 {
@@ -535,7 +535,7 @@
  * The calculated result is used for phi-node pruning - where we only need to
  * insert a phi node if the variable is live-in to the block.
  */
-STATIC bool computeBlockLiveIns(CompilationUnit* cUnit, BasicBlock* bb)
+bool computeBlockLiveIns(CompilationUnit* cUnit, BasicBlock* bb)
 {
     ArenaBitVector* tempDalvikRegisterV = cUnit->tempDalvikRegisterV;
 
@@ -572,7 +572,7 @@
 }
 
 /* Insert phi nodes to for each variable to the dominance frontiers */
-STATIC void insertPhiNodes(CompilationUnit* cUnit)
+void insertPhiNodes(CompilationUnit* cUnit)
 {
     int dalvikReg;
     const GrowableList* blockList = &cUnit->blockList;
@@ -658,7 +658,7 @@
  * Worker function to insert phi-operands with latest SSA names from
  * predecessor blocks
  */
-STATIC bool insertPhiNodeOperands(CompilationUnit* cUnit, BasicBlock* bb)
+bool insertPhiNodeOperands(CompilationUnit* cUnit, BasicBlock* bb)
 {
     ArenaBitVector* ssaRegV = cUnit->tempSSARegisterV;
     GrowableListIterator iter;
@@ -711,7 +711,7 @@
     return true;
 }
 
-STATIC void doDFSPreOrderSSARename(CompilationUnit* cUnit, BasicBlock* block)
+void doDFSPreOrderSSARename(CompilationUnit* cUnit, BasicBlock* block)
 {
 
     if (block->visited || block->hidden) return;
diff --git a/src/compiler/Utility.cc b/src/compiler/Utility.cc
index defd647..f86b72c 100644
--- a/src/compiler/Utility.cc
+++ b/src/compiler/Utility.cc
@@ -188,7 +188,7 @@
 }
 
 /* Expand the capacity of a growable list */
-STATIC void expandGrowableList(CompilationUnit* cUnit, GrowableList* gList)
+void expandGrowableList(CompilationUnit* cUnit, GrowableList* gList)
 {
     int newLength = gList->numAllocated;
     if (newLength < 128) {
@@ -341,14 +341,6 @@
     }
 }
 
-/*
- * Dump the current stats of the compiler.
- */
-void oatDumpStats(void)
-{
-    oatArchDump();
-}
-
 static uint32_t checkMasks[32] = {
     0x00000001, 0x00000002, 0x00000004, 0x00000008, 0x00000010,
     0x00000020, 0x00000040, 0x00000080, 0x00000100, 0x00000200,
@@ -518,7 +510,7 @@
 /*
  * If the vector sizes don't match, log an error and abort.
  */
-STATIC void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
+void checkSizes(const ArenaBitVector* bv1, const ArenaBitVector* bv2)
 {
     if (bv1->storageSize != bv2->storageSize) {
         LOG(FATAL) << "Mismatched vector sizes (" << bv1->storageSize <<
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/CodegenFactory.cc
index d141156..232cbf5 100644
--- a/src/compiler/codegen/CodegenFactory.cc
+++ b/src/compiler/codegen/CodegenFactory.cc
@@ -25,26 +25,31 @@
  * which combines this common code with specific support found in the
  * applicable directories below this one.
  *
- * Prior to including this file, TGT_LIR should be #defined.
- * For example, for arm:
- *    #define TGT_LIR ArmLIR
- * for MIPS:
- *    #define TGT_LIR MipsLIR
- * and for x86:
- *    #define TGT_LIR X86LIR
  */
 
+/*
+ * Load an immediate value into a fixed or temp register.  Target
+ * register is clobbered, and marked inUse.
+ */
+LIR* loadConstant(CompilationUnit* cUnit, int rDest, int value)
+{
+    if (oatIsTemp(cUnit, rDest)) {
+        oatClobber(cUnit, rDest);
+        oatMarkInUse(cUnit, rDest);
+    }
+    return loadConstantNoClobber(cUnit, rDest, value);
+}
 
 /* Load a word at base + displacement.  Displacement must be word multiple */
-STATIC TGT_LIR* loadWordDisp(CompilationUnit* cUnit, int rBase,
-                             int displacement, int rDest)
+LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement,
+                  int rDest)
 {
     return loadBaseDisp(cUnit, NULL, rBase, displacement, rDest, kWord,
                         INVALID_SREG);
 }
 
-STATIC TGT_LIR* storeWordDisp(CompilationUnit* cUnit, int rBase,
-                             int displacement, int rSrc)
+LIR* storeWordDisp(CompilationUnit* cUnit, int rBase, int displacement,
+                   int rSrc)
 {
     return storeBaseDisp(cUnit, rBase, displacement, rSrc, kWord);
 }
@@ -54,8 +59,7 @@
  * using this routine, as it doesn't perform any bookkeeping regarding
  * register liveness.  That is the responsibility of the caller.
  */
-STATIC void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc,
-                            int reg1)
+void loadValueDirect(CompilationUnit* cUnit, RegLocation rlSrc, int reg1)
 {
     rlSrc = oatUpdateLoc(cUnit, rlSrc);
     if (rlSrc.location == kLocPhysReg) {
@@ -71,8 +75,7 @@
  * register.  Should be used when loading to a fixed register (for example,
  * loading arguments to an out of line call.
  */
-STATIC void loadValueDirectFixed(CompilationUnit* cUnit, RegLocation rlSrc,
-                                 int reg1)
+void loadValueDirectFixed(CompilationUnit* cUnit, RegLocation rlSrc, int reg1)
 {
     oatClobber(cUnit, reg1);
     oatMarkInUse(cUnit, reg1);
@@ -84,8 +87,8 @@
  * using this routine, as it doesn't perform any bookkeeping regarding
  * register liveness.  That is the responsibility of the caller.
  */
-STATIC void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc,
-                                int regLo, int regHi)
+void loadValueDirectWide(CompilationUnit* cUnit, RegLocation rlSrc, int regLo,
+                         int regHi)
 {
     rlSrc = oatUpdateLocWide(cUnit, rlSrc);
     if (rlSrc.location == kLocPhysReg) {
@@ -103,8 +106,8 @@
  * registers.  Should be used when loading to a fixed registers (for example,
  * loading arguments to an out of line call.
  */
-STATIC void loadValueDirectWideFixed(CompilationUnit* cUnit, RegLocation rlSrc,
-                                     int regLo, int regHi)
+void loadValueDirectWideFixed(CompilationUnit* cUnit, RegLocation rlSrc,
+                              int regLo, int regHi)
 {
     oatClobber(cUnit, regLo);
     oatClobber(cUnit, regHi);
@@ -113,8 +116,8 @@
     loadValueDirectWide(cUnit, rlSrc, regLo, regHi);
 }
 
-STATIC RegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc,
-                             RegisterClass opKind)
+RegLocation loadValue(CompilationUnit* cUnit, RegLocation rlSrc,
+                      RegisterClass opKind)
 {
     rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
     if (rlSrc.location == kLocDalvikFrame) {
@@ -125,8 +128,7 @@
     return rlSrc;
 }
 
-STATIC void storeValue(CompilationUnit* cUnit, RegLocation rlDest,
-                       RegLocation rlSrc)
+void storeValue(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
 {
     LIR* defStart;
     LIR* defEnd;
@@ -169,8 +171,8 @@
     }
 }
 
-STATIC RegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc,
-                                 RegisterClass opKind)
+RegLocation loadValueWide(CompilationUnit* cUnit, RegLocation rlSrc,
+                          RegisterClass opKind)
 {
     DCHECK(rlSrc.wide);
     rlSrc = oatEvalLoc(cUnit, rlSrc, opKind, false);
@@ -184,8 +186,8 @@
     return rlSrc;
 }
 
-STATIC void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest,
-                           RegLocation rlSrc)
+void storeValueWide(CompilationUnit* cUnit, RegLocation rlDest,
+                    RegLocation rlSrc)
 {
     LIR* defStart;
     LIR* defEnd;
@@ -240,4 +242,50 @@
     }
 }
 
+/*
+ * Mark garbage collection card. Skip if the value we're storing is null.
+ */
+void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
+{
+    int regCardBase = oatAllocTemp(cUnit);
+    int regCardNo = oatAllocTemp(cUnit);
+    LIR* branchOver = genCmpImmBranch(cUnit, kCondEq, valReg, 0);
+    loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(),
+                 regCardBase);
+    opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
+    storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
+                     kUnsignedByte);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = ENCODE_ALL;
+    branchOver->target = (LIR*)target;
+    oatFreeTemp(cUnit, regCardBase);
+    oatFreeTemp(cUnit, regCardNo);
+}
+
+/*
+ * 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.
+ */
+void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
+{
+#if defined(METHOD_IN_REG)
+    genRegCopy(cUnit, rTgt, rMETHOD);
+#else
+    loadWordDisp(cUnit, rSP, 0, rTgt);
+#endif
+}
+
+int loadCurrMethod(CompilationUnit *cUnit)
+{
+#if defined(METHOD_IN_REG)
+    return rMETHOD;
+#else
+    int mReg = oatAllocTemp(cUnit);
+    loadCurrMethodDirect(cUnit, mReg);
+    return mReg;
+#endif
+}
+
+
 }  // namespace art
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/CodegenUtil.cc
index 1f05a17..4eccf04 100644
--- a/src/compiler/codegen/CodegenUtil.cc
+++ b/src/compiler/codegen/CodegenUtil.cc
@@ -16,7 +16,378 @@
 
 namespace art {
 
-STATIC void pushWord(std::vector<uint16_t>&buf, int data) {
+void setMemRefType(LIR* lir, bool isLoad, int memType)
+{
+    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 r5FP +
+ * offset.
+ */
+void annotateDalvikRegAccess(LIR* lir, int regId, bool isLoad)
+{
+    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.
+ */
+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
+     */
+    seed = DOUBLEREG(reg) ? 3 : 1;
+    /* FP register starts at bit position 16 */
+    shift = FPREG(reg) ? kFPReg0 : 0;
+    /* Expand the double register id into single offset */
+    shift += regId;
+    return (seed << shift);
+}
+
+/*
+ * Mark the corresponding bit(s).
+ */
+inline void setupRegMask(u8* mask, int reg)
+{
+    *mask |= getRegMaskCommon(reg);
+}
+
+/*
+ * Set up the proper fields in the resource mask
+ */
+void setupResourceMasks(LIR* lir)
+{
+    int opcode = lir->opcode;
+    int flags;
+
+    if (opcode <= 0) {
+        lir->useMask = lir->defMask = 0;
+        return;
+    }
+
+    flags = EncodingMap[lir->opcode].flags;
+
+    if (flags & NEEDS_FIXUP) {
+        lir->flags.pcRelFixup = true;
+    }
+
+    /* 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 & REG_DEF_FPCS_LIST0) {
+        lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
+    }
+
+    if (flags & REG_DEF_FPCS_LIST2) {
+        for (int i = 0; i < lir->operands[2]; i++) {
+            setupRegMask(&lir->defMask, lir->operands[1] + i);
+        }
+    }
+
+    if (flags & SETS_CCODES) {
+        lir->defMask |= ENCODE_CCODE;
+    }
+
+#if defined(TARGET_ARM)
+    /* Conservatively treat the IT block */
+    if (flags & IS_IT) {
+        lir->defMask = ENCODE_ALL;
+    }
+#endif
+
+    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 & REG_USE_FPCS_LIST0) {
+        lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
+    }
+
+    if (flags & REG_USE_FPCS_LIST2) {
+        for (int i = 0; i < lir->operands[2]; i++) {
+            setupRegMask(&lir->useMask, lir->operands[1] + i);
+        }
+    }
+
+    if (flags & USES_CCODES) {
+        lir->useMask |= ENCODE_CCODE;
+    }
+
+#if defined(TARGET_ARM)
+    /* Fixup for kThumbPush/lr and kThumbPop/pc */
+    if (opcode == kThumbPush || opcode == kThumbPop) {
+        u8 r8Mask = getRegMaskCommon(r8);
+        if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) {
+            lir->useMask &= ~r8Mask;
+            lir->useMask |= ENCODE_REG_LR;
+        } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) {
+            lir->defMask &= ~r8Mask;
+            lir->defMask |= ENCODE_REG_PC;
+        }
+    }
+#endif
+}
+
+/*
+ * The following are building blocks to construct low-level IRs with 0 - 4
+ * operands.
+ */
+LIR* newLIR0(CompilationUnit* cUnit, ArmOpcode opcode)
+{
+    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND));
+    insn->opcode = opcode;
+    setupResourceMasks(insn);
+    insn->dalvikOffset = cUnit->currentDalvikOffset;
+    oatAppendLIR(cUnit, (LIR*) insn);
+    return insn;
+}
+
+LIR* newLIR1(CompilationUnit* cUnit, ArmOpcode opcode,
+                           int dest)
+{
+    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP));
+    insn->opcode = opcode;
+    insn->operands[0] = dest;
+    setupResourceMasks(insn);
+    insn->dalvikOffset = cUnit->currentDalvikOffset;
+    oatAppendLIR(cUnit, (LIR*) insn);
+    return insn;
+}
+
+LIR* newLIR2(CompilationUnit* cUnit, ArmOpcode opcode,
+                           int dest, int src1)
+{
+    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), 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->dalvikOffset = cUnit->currentDalvikOffset;
+    oatAppendLIR(cUnit, (LIR*) insn);
+    return insn;
+}
+
+LIR* newLIR3(CompilationUnit* cUnit, ArmOpcode opcode,
+                           int dest, int src1, int src2)
+{
+    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    DCHECK(isPseudoOpcode(opcode) ||
+           (EncodingMap[opcode].flags & IS_TERTIARY_OP))
+            << (int)opcode << " "
+            << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
+            << cUnit->currentDalvikOffset;
+    insn->opcode = opcode;
+    insn->operands[0] = dest;
+    insn->operands[1] = src1;
+    insn->operands[2] = src2;
+    setupResourceMasks(insn);
+    insn->dalvikOffset = cUnit->currentDalvikOffset;
+    oatAppendLIR(cUnit, (LIR*) insn);
+    return insn;
+}
+
+#if defined(TARGET_ARM)
+LIR* newLIR4(CompilationUnit* cUnit, ArmOpcode opcode,
+                           int dest, int src1, int src2, int info)
+{
+    LIR* insn = (LIR* ) oatNew(cUnit, sizeof(LIR), 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->dalvikOffset = cUnit->currentDalvikOffset;
+    oatAppendLIR(cUnit, (LIR*) insn);
+    return insn;
+}
+#endif
+
+/*
+ * Search the existing constants in the literal pool for an exact or close match
+ * within specified delta (greater or equal to 0).
+ */
+LIR* scanLiteralPool(LIR* dataTarget, int value, unsigned int delta)
+{
+    while (dataTarget) {
+        if (((unsigned) (value - ((LIR* ) dataTarget)->operands[0])) <=
+            delta)
+            return (LIR* ) dataTarget;
+        dataTarget = dataTarget->next;
+    }
+    return NULL;
+}
+
+/* Search the existing constants in the literal pool for an exact wide match */
+LIR* scanLiteralPoolWide(LIR* dataTarget, int valLo, int valHi)
+{
+    bool loMatch = false;
+    LIR* loTarget = NULL;
+    while (dataTarget) {
+        if (loMatch && (((LIR*)dataTarget)->operands[0] == valHi)) {
+            return (LIR*)loTarget;
+        }
+        loMatch = false;
+        if (((LIR*)dataTarget)->operands[0] == valLo) {
+            loMatch = true;
+            loTarget = dataTarget;
+        }
+        dataTarget = dataTarget->next;
+    }
+    return NULL;
+}
+
+/*
+ * The following are building blocks to insert constants into the pool or
+ * instruction streams.
+ */
+
+/* Add a 32-bit constant either in the constant pool or mixed with code */
+LIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP,
+                           int value)
+{
+    /* Add the constant to the literal pool */
+    if (constantListP) {
+        LIR* newValue = (LIR* ) oatNew(cUnit, sizeof(LIR), true,
+                                             kAllocData);
+        newValue->operands[0] = value;
+        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;
+}
+
+/* Add a 64-bit constant to the constant pool or mixed with code */
+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;
+}
+
+void pushWord(std::vector<uint16_t>&buf, int data) {
     buf.push_back( data & 0xffff);
     buf.push_back( (data >> 16) & 0xffff);
 }
@@ -27,10 +398,10 @@
 }
 
 /* Write the literal pool to the output stream */
-STATIC void installLiteralPools(CompilationUnit* cUnit)
+void installLiteralPools(CompilationUnit* cUnit)
 {
     alignBuffer(cUnit->codeBuffer, cUnit->dataOffset);
-    TGT_LIR* dataLIR = (TGT_LIR*) cUnit->literalList;
+    LIR* dataLIR = (LIR*) cUnit->literalList;
     while (dataLIR != NULL) {
         pushWord(cUnit->codeBuffer, dataLIR->operands[0]);
         dataLIR = NEXT_LIR(dataLIR);
@@ -38,7 +409,7 @@
 }
 
 /* Write the switch tables to the output stream */
-STATIC void installSwitchTables(CompilationUnit* cUnit)
+void installSwitchTables(CompilationUnit* cUnit)
 {
     GrowableListIterator iterator;
     oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
@@ -47,14 +418,14 @@
              &iterator);
         if (tabRec == NULL) break;
         alignBuffer(cUnit->codeBuffer, tabRec->offset);
-        int bxOffset = tabRec->bxInst->generic.offset + 4;
+        int bxOffset = tabRec->bxInst->offset + 4;
         if (cUnit->printMe) {
             LOG(INFO) << "Switch table for offset 0x" << std::hex << bxOffset;
         }
         if (tabRec->table[0] == kSparseSwitchSignature) {
             int* keys = (int*)&(tabRec->table[2]);
             for (int elems = 0; elems < tabRec->table[1]; elems++) {
-                int disp = tabRec->targets[elems]->generic.offset - bxOffset;
+                int disp = tabRec->targets[elems]->offset - bxOffset;
                 if (cUnit->printMe) {
                     LOG(INFO) << "    Case[" << elems << "] key: 0x" <<
                         std::hex << keys[elems] << ", disp: 0x" <<
@@ -62,25 +433,25 @@
                 }
                 pushWord(cUnit->codeBuffer, keys[elems]);
                 pushWord(cUnit->codeBuffer,
-                    tabRec->targets[elems]->generic.offset - bxOffset);
+                    tabRec->targets[elems]->offset - bxOffset);
             }
         } else {
             DCHECK_EQ(tabRec->table[0], kPackedSwitchSignature);
             for (int elems = 0; elems < tabRec->table[1]; elems++) {
-                int disp = tabRec->targets[elems]->generic.offset - bxOffset;
+                int disp = tabRec->targets[elems]->offset - bxOffset;
                 if (cUnit->printMe) {
                     LOG(INFO) << "    Case[" << elems << "] disp: 0x" <<
                         std::hex << disp;
                 }
                 pushWord(cUnit->codeBuffer,
-                         tabRec->targets[elems]->generic.offset - bxOffset);
+                         tabRec->targets[elems]->offset - bxOffset);
             }
         }
     }
 }
 
 /* Write the fill array dta to the output stream */
-STATIC void installFillArrayData(CompilationUnit* cUnit)
+void installFillArrayData(CompilationUnit* cUnit)
 {
     GrowableListIterator iterator;
     oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
@@ -95,7 +466,7 @@
     }
 }
 
-STATIC int assignLiteralOffsetCommon(LIR* lir, int offset)
+int assignLiteralOffsetCommon(LIR* lir, int offset)
 {
     for (;lir != NULL; lir = lir->next) {
         lir->offset = offset;
@@ -104,32 +475,32 @@
     return offset;
 }
 
-STATIC void createMappingTable(CompilationUnit* cUnit)
+void createMappingTable(CompilationUnit* cUnit)
 {
-    TGT_LIR* tgtLIR;
+    LIR* tgtLIR;
     int currentDalvikOffset = -1;
 
-    for (tgtLIR = (TGT_LIR *) cUnit->firstLIRInsn;
+    for (tgtLIR = (LIR *) cUnit->firstLIRInsn;
          tgtLIR;
          tgtLIR = NEXT_LIR(tgtLIR)) {
         if ((tgtLIR->opcode >= 0) && !tgtLIR->flags.isNop &&
-            (currentDalvikOffset != tgtLIR->generic.dalvikOffset)) {
+            (currentDalvikOffset != tgtLIR->dalvikOffset)) {
             // Changed - need to emit a record
-            cUnit->mappingTable.push_back(tgtLIR->generic.offset);
-            cUnit->mappingTable.push_back(tgtLIR->generic.dalvikOffset);
-            currentDalvikOffset = tgtLIR->generic.dalvikOffset;
+            cUnit->mappingTable.push_back(tgtLIR->offset);
+            cUnit->mappingTable.push_back(tgtLIR->dalvikOffset);
+            currentDalvikOffset = tgtLIR->dalvikOffset;
         }
     }
 }
 
 /* Determine the offset of each literal field */
-STATIC int assignLiteralOffset(CompilationUnit* cUnit, int offset)
+int assignLiteralOffset(CompilationUnit* cUnit, int offset)
 {
     offset = assignLiteralOffsetCommon(cUnit->literalList, offset);
     return offset;
 }
 
-STATIC int assignSwitchTablesOffset(CompilationUnit* cUnit, int offset)
+int assignSwitchTablesOffset(CompilationUnit* cUnit, int offset)
 {
     GrowableListIterator iterator;
     oatGrowableListIteratorInit(&cUnit->switchTables, &iterator);
@@ -148,7 +519,7 @@
     return offset;
 }
 
-STATIC int assignFillArrayDataOffset(CompilationUnit* cUnit, int offset)
+int assignFillArrayDataOffset(CompilationUnit* cUnit, int offset)
 {
     GrowableListIterator iterator;
     oatGrowableListIteratorInit(&cUnit->fillArrayData, &iterator);
@@ -230,6 +601,119 @@
     createMappingTable(cUnit);
 }
 
+/*
+ * 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.
+ */
+LIR* 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;
+    }
+    LIR* newLabel = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    newLabel->dalvikOffset = vaddr;
+    newLabel->opcode = kPseudoCaseLabel;
+    newLabel->operands[0] = keyVal;
+    oatInsertLIRAfter(it->second, (LIR*)newLabel);
+    return newLabel;
+}
+
+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);
+    }
+}
+
+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";
+        }
+    }
+}
+
+//FIXME: Do we have endian issues here?
+
+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];
+    }
+}
+
+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];
+    }
+}
 
 
 }  // namespace art
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/GenCommon.cc
new file mode 100644
index 0000000..7af1aa0
--- /dev/null
+++ b/src/compiler/codegen/GenCommon.cc
@@ -0,0 +1,2133 @@
+/*
+ * 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 source files contains "gen" codegen routines that should
+ * be applicable to most targets.  Only mid-level support utilities
+ * and "op" calls may be used here.
+ */
+
+#if defined(TARGET_ARM)
+LIR* genIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide);
+#endif
+
+LIR* callRuntimeHelper(CompilationUnit* cUnit, int reg)
+{
+    oatClobberCalleeSave(cUnit);
+    return opReg(cUnit, kOpBlx, reg);
+}
+
+/*
+ * Generate an kPseudoBarrier marker to indicate the boundary of special
+ * blocks.
+ */
+void genBarrier(CompilationUnit* cUnit)
+{
+    LIR* barrier = newLIR0(cUnit, kPseudoBarrier);
+    /* Mark all resources as being clobbered */
+    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)
+{
+    LIR* branch = opNone(cUnit, kOpUncondBr);
+    branch->target = (LIR*) target;
+    return branch;
+}
+
+LIR* genCheck(CompilationUnit* cUnit, ConditionCode cCode, MIR* mir,
+              ThrowKind kind)
+{
+    LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    tgt->opcode = kPseudoThrowTarget;
+    tgt->operands[0] = kind;
+    tgt->operands[1] = mir ? mir->offset : 0;
+    LIR* branch = genConditionalBranch(cUnit, cCode, tgt);
+    // Remember branch target - will process later
+    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
+    return branch;
+}
+
+LIR* genImmedCheck(CompilationUnit* cUnit, ConditionCode cCode,
+                   int reg, int immVal, MIR* mir, ThrowKind kind)
+{
+    LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    tgt->opcode = kPseudoThrowTarget;
+    tgt->operands[0] = kind;
+    tgt->operands[1] = mir->offset;
+    LIR* branch;
+    if (cCode == kCondAl) {
+        branch = genUnconditionalBranch(cUnit, tgt);
+    } else {
+        branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
+        branch->target = (LIR*)tgt;
+    }
+    // Remember branch target - will process later
+    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
+    return branch;
+}
+
+/* Perform null-check on a register.  */
+LIR* 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, kCondEq, mReg, 0, mir, kThrowNullPointer);
+}
+
+/* Perform check on two registers */
+LIR* genRegRegCheck(CompilationUnit* cUnit, ConditionCode cCode,
+                        int reg1, int reg2, MIR* mir, ThrowKind kind)
+{
+    LIR* tgt = (LIR*)oatNew(cUnit, sizeof(LIR), 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);
+    LIR* branch = genConditionalBranch(cUnit, cCode, tgt);
+    // Remember branch target - will process later
+    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
+    return branch;
+}
+
+void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+                         RegLocation rlSrc1, RegLocation rlSrc2, LIR* labelList)
+{
+    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:
+            cond = kCondEq;
+            break;
+        case OP_IF_NE:
+            cond = kCondNe;
+            break;
+        case OP_IF_LT:
+            cond = kCondLt;
+            break;
+        case OP_IF_GE:
+            cond = kCondGe;
+            break;
+        case OP_IF_GT:
+            cond = kCondGt;
+            break;
+        case OP_IF_LE:
+            cond = kCondLe;
+            break;
+        default:
+            cond = (ConditionCode)0;
+            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
+    }
+    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
+}
+
+void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+                             RegLocation rlSrc, LIR* labelList)
+{
+    ConditionCode cond;
+    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+    opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
+    Opcode opcode = mir->dalvikInsn.opcode;
+    switch(opcode) {
+        case OP_IF_EQZ:
+            cond = kCondEq;
+            break;
+        case OP_IF_NEZ:
+            cond = kCondNe;
+            break;
+        case OP_IF_LTZ:
+            cond = kCondLt;
+            break;
+        case OP_IF_GEZ:
+            cond = kCondGe;
+            break;
+        case OP_IF_GTZ:
+            cond = kCondGt;
+            break;
+        case OP_IF_LEZ:
+            cond = kCondLe;
+            break;
+        default:
+            cond = (ConditionCode)0;
+            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
+    }
+    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
+    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
+}
+
+void genIntToLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                  RegLocation rlSrc)
+{
+    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);
+}
+
+void genIntNarrowing(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                     RegLocation rlSrc)
+{
+     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);
+}
+
+/*
+ * Let helper function take care of everything.  Will call
+ * Array::AllocFromCode(type_idx, method, count);
+ * Note: AllocFromCode will handle checks for errNegativeArraySize.
+ */
+void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                 RegLocation rlSrc)
+{
+    oatFlushAllRegs(cUnit);    /* Everything to home location */
+    uint32_t type_idx = mir->dalvikInsn.vC;
+    int rTgt;
+    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+                                                    cUnit->dex_cache,
+                                                    *cUnit->dex_file,
+                                                    type_idx)) {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pAllocArrayFromCode));
+    } else {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pAllocArrayFromCodeWithAccessCheck));
+    }
+    loadCurrMethodDirect(cUnit, rARG1);              // arg1 <- Method*
+    loadConstant(cUnit, rARG0, type_idx);            // arg0 <- type_id
+    loadValueDirectFixed(cUnit, rlSrc, rARG2);       // arg2 <- count
+    callRuntimeHelper(cUnit, rTgt);
+    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'.
+ */
+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 */
+    int rTgt;
+    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+                                                    cUnit->dex_cache,
+                                                    *cUnit->dex_file,
+                                                    typeId)) {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pCheckAndAllocArrayFromCode));
+    } else {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pCheckAndAllocArrayFromCodeWithAccessCheck));
+    }
+    loadCurrMethodDirect(cUnit, rARG1);              // arg1 <- Method*
+    loadConstant(cUnit, rARG0, typeId);              // arg0 <- type_id
+    loadConstant(cUnit, rARG2, elems);               // arg2 <- count
+    callRuntimeHelper(cUnit, rTgt);
+    /*
+     * NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
+     * return region.  Because AllocFromCode placed the new array
+     * in rRET0, 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, rRET0);
+
+    // TODO: use the correct component size, currently all supported types
+    // share array alignment with ints (see comment at head of function)
+    size_t component_size = sizeof(int32_t);
+
+    // 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 = rLR;  // Using a lot of temps, rLR is known free here
+        // 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, rRET0,
+                    Array::DataOffset(component_size).Int32Value());
+        // Set up the loop counter (known to be > 0)
+        loadConstant(cUnit, rIdx, dInsn->vA - 1);
+        // Generate the copy loop.  Going backwards for convenience
+        LIR* 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);
+#if defined(TARGET_ARM)
+        // Combine sub & test using sub setflags encoding here
+        newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
+        LIR* branch = opCondBranch(cUnit, kCondGe);
+#else
+        opRegImm(cUnit, kOpSub, rIdx, 1);
+        LIR* branch = opCompareBranchImm(cUnit, kCondGe, rIdx, 0);
+#endif
+        branch->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, rRET0,
+                          Array::DataOffset(component_size).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);
+            }
+        }
+    }
+}
+
+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;
+
+    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+                             *cUnit->dex_file, *cUnit->dex_cache,
+                             cUnit->code_item, cUnit->method_idx,
+                             cUnit->access_flags);
+
+    bool fastPath =
+        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
+                                                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.
+            rMethod = rARG1;
+            oatLockTemp(cUnit, rMethod);
+            loadCurrMethodDirect(cUnit, rMethod);
+            rBase = rARG0;
+            oatLockTemp(cUnit, rBase);
+            loadWordDisp(cUnit, rMethod,
+                Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
+                rBase);
+            loadWordDisp(cUnit, rBase,
+                         Array::DataOffset(sizeof(Object*)).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
+            LIR* branchOver = genCmpImmBranch(cUnit, kCondNe, rBase, 0);
+            int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                                  pInitializeStaticStorage));
+            loadConstant(cUnit, rARG0, ssbIndex);
+            callRuntimeHelper(cUnit, rTgt);
+#if defined(TARGET_MIPS)
+            // For Arm, rRET0 = rARG0 = rBASE, for Mips, we need to copy
+            genRegCopy(cUnit, rBase, rRET0);
+#endif
+            LIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
+            skipTarget->defMask = ENCODE_ALL;
+            branchOver->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);
+        }
+//FIXME: need to generalize the barrier call
+        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));
+        int rTgt = loadHelper(cUnit, setterOffset);
+        loadConstant(cUnit, rARG0, fieldIdx);
+        if (isLongOrDouble) {
+            loadValueDirectWideFixed(cUnit, rlSrc, rARG2, rARG3);
+        } else {
+            loadValueDirect(cUnit, rlSrc, rARG1);
+        }
+        callRuntimeHelper(cUnit, rTgt);
+    }
+}
+
+void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+             bool isLongOrDouble, bool isObject)
+{
+    int fieldOffset;
+    int ssbIndex;
+    bool isVolatile;
+    bool isReferrersClass;
+    uint32_t fieldIdx = mir->dalvikInsn.vB;
+
+    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+                             *cUnit->dex_file, *cUnit->dex_cache,
+                             cUnit->code_item, cUnit->method_idx,
+                             cUnit->access_flags);
+
+    bool fastPath =
+        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
+                                                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 = rARG1;
+            oatLockTemp(cUnit, rMethod);
+            loadCurrMethodDirect(cUnit, rMethod);
+            rBase = rARG0;
+            oatLockTemp(cUnit, rBase);
+            loadWordDisp(cUnit, rMethod,
+                Method::DexCacheInitializedStaticStorageOffset().Int32Value(),
+                rBase);
+            loadWordDisp(cUnit, rBase,
+                         Array::DataOffset(sizeof(Object*)).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
+            LIR* branchOver = genCmpImmBranch(cUnit, kCondNe, rBase, 0);
+            int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                                  pInitializeStaticStorage));
+            loadConstant(cUnit, rARG0, ssbIndex);
+            callRuntimeHelper(cUnit, rTgt);
+#if defined(TARGET_MIPS)
+            // For Arm, rRET0 = rARG0 = rBASE, for Mips, we need to copy
+            genRegCopy(cUnit, rBase, rRET0);
+#endif
+            LIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
+            skipTarget->defMask = ENCODE_ALL;
+            branchOver->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));
+        int rTgt = loadHelper(cUnit, getterOffset);
+        loadConstant(cUnit, rARG0, fieldIdx);
+        callRuntimeHelper(cUnit, rTgt);
+        if (isLongOrDouble) {
+            RegLocation rlResult = oatGetReturnWide(cUnit);
+            storeValueWide(cUnit, rlDest, rlResult);
+        } else {
+            RegLocation rlResult = oatGetReturn(cUnit);
+            storeValue(cUnit, rlDest, rlResult);
+        }
+    }
+}
+
+
+// Debugging routine - if null target, branch to DebugMe
+void genShowTarget(CompilationUnit* cUnit)
+{
+    LIR* branchOver = genCmpImmBranch(cUnit, kCondNe, rLINK, 0);
+    loadWordDisp(cUnit, rSELF,
+                 OFFSETOF_MEMBER(Thread, pDebugMe), rLINK);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = -1;
+    branchOver->target = (LIR*)target;
+}
+
+void genThrowVerificationError(CompilationUnit* cUnit, MIR* mir)
+{
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pThrowVerificationErrorFromCode));
+    loadConstant(cUnit, rARG0, mir->dalvikInsn.vA);
+    loadConstant(cUnit, rARG1, mir->dalvikInsn.vB);
+    callRuntimeHelper(cUnit, rTgt);
+}
+
+void handleSuspendLaunchpads(CompilationUnit *cUnit)
+{
+    LIR** suspendLabel =
+        (LIR **) cUnit->suspendLaunchpads.elemList;
+    int numElems = cUnit->suspendLaunchpads.numUsed;
+
+    for (int i = 0; i < numElems; i++) {
+        /* TUNING: move suspend count load into helper */
+        LIR* lab = suspendLabel[i];
+        LIR* resumeLab = (LIR*)lab->operands[0];
+        cUnit->currentDalvikOffset = lab->operands[1];
+        oatAppendLIR(cUnit, (LIR *)lab);
+        int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                              pTestSuspendFromCode));
+        if (!cUnit->genDebugger) {
+            // use rSUSPEND for suspend count
+            loadWordDisp(cUnit, rSELF,
+                         Thread::SuspendCountOffset().Int32Value(), rSUSPEND);
+        }
+        opReg(cUnit, kOpBlx, rTgt);
+        if ( cUnit->genDebugger) {
+            // use rSUSPEND for update debugger
+            loadWordDisp(cUnit, rSELF,
+                         OFFSETOF_MEMBER(Thread, pUpdateDebuggerFromCode),
+                         rSUSPEND);
+        }
+        genUnconditionalBranch(cUnit, resumeLab);
+    }
+}
+
+void handleThrowLaunchpads(CompilationUnit *cUnit)
+{
+    LIR** throwLabel = (LIR **) cUnit->throwLaunchpads.elemList;
+    int numElems = cUnit->throwLaunchpads.numUsed;
+    int i;
+
+    for (i = 0; i < numElems; i++) {
+        LIR* 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 kThrowNullPointer:
+                funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
+                break;
+            case kThrowArrayBounds:
+                if (v2 != r0) {
+                    genRegCopy(cUnit, rARG0, v1);
+                    genRegCopy(cUnit, rARG1, v2);
+                } else {
+                    if (v1 == r1) {
+#if defined(TARGET_ARM)
+                        int rTmp = r12;
+#else
+                        int rTmp = oatAllocTemp(cUnit);
+#endif
+                        genRegCopy(cUnit, rTmp, v1);
+                        genRegCopy(cUnit, rARG1, v2);
+                        genRegCopy(cUnit, rARG0, rTmp);
+#if !(defined(TARGET_ARM))
+                        oatFreeTemp(cUnit, rTmp);
+#endif
+                    } else {
+                        genRegCopy(cUnit, rARG1, v2);
+                        genRegCopy(cUnit, rARG0, v1);
+                    }
+                }
+                funcOffset = OFFSETOF_MEMBER(Thread, pThrowArrayBoundsFromCode);
+                break;
+            case kThrowDivZero:
+                funcOffset = OFFSETOF_MEMBER(Thread, pThrowDivZeroFromCode);
+                break;
+            case kThrowVerificationError:
+                loadConstant(cUnit, rARG0, v1);
+                loadConstant(cUnit, rARG1, v2);
+                funcOffset =
+                    OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode);
+                break;
+            case kThrowNegArraySize:
+                genRegCopy(cUnit, rARG0, v1);
+                funcOffset =
+                    OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
+                break;
+            case kThrowNoSuchMethod:
+                genRegCopy(cUnit, rARG0, v1);
+                funcOffset =
+                    OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
+                break;
+            case kThrowStackOverflow:
+                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];
+        }
+        int rTgt = loadHelper(cUnit, funcOffset);
+        callRuntimeHelper(cUnit, rTgt);
+    }
+}
+
+/* Needed by the Assembler */
+void oatSetupResourceMasks(LIR* lir)
+{
+    setupResourceMasks(lir);
+}
+
+void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+             RegLocation rlDest, RegLocation rlObj,
+                    bool isLongOrDouble, bool isObject)
+{
+    int fieldOffset;
+    bool isVolatile;
+    uint32_t fieldIdx = mir->dalvikInsn.vC;
+
+    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+                             *cUnit->dex_file, *cUnit->dex_cache,
+                             cUnit->code_item, cUnit->method_idx,
+                             cUnit->access_flags);
+
+    bool fastPath = cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
+                    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? */
+            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? */
+            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));
+        int rTgt = loadHelper(cUnit, getterOffset);
+        loadValueDirect(cUnit, rlObj, rARG1);
+        loadConstant(cUnit, rARG0, fieldIdx);
+        callRuntimeHelper(cUnit, rTgt);
+        if (isLongOrDouble) {
+            RegLocation rlResult = oatGetReturnWide(cUnit);
+            storeValueWide(cUnit, rlDest, rlResult);
+        } else {
+            RegLocation rlResult = oatGetReturn(cUnit);
+            storeValue(cUnit, rlDest, rlResult);
+        }
+    }
+}
+
+void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size, RegLocation rlSrc,
+             RegLocation rlObj, bool isLongOrDouble, bool isObject)
+{
+    int fieldOffset;
+    bool isVolatile;
+    uint32_t fieldIdx = mir->dalvikInsn.vC;
+
+    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
+                             *cUnit->dex_file, *cUnit->dex_cache,
+                             cUnit->code_item, cUnit->method_idx,
+                             cUnit->access_flags);
+
+    bool fastPath = cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
+                    fieldOffset, isVolatile, true);
+    if (fastPath && !SLOW_FIELD_PATH) {
+        RegisterClass regClass = oatRegClassBySize(size);
+        DCHECK_GE(fieldOffset, 0);
+        rlObj = loadValue(cUnit, rlObj, kCoreReg);
+        if (isLongOrDouble) {
+            int regPtr;
+            rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
+            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+            regPtr = oatAllocTemp(cUnit);
+            opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
+            if (isVolatile) {
+                oatGenMemBarrier(cUnit, kST);
+            }
+            storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
+            if (isVolatile) {
+                oatGenMemBarrier(cUnit, kSY);
+            }
+            oatFreeTemp(cUnit, regPtr);
+        } else {
+            rlSrc = loadValue(cUnit, rlSrc, regClass);
+            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null? */
+            if (isVolatile) {
+                oatGenMemBarrier(cUnit, kST);
+            }
+            storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, kWord);
+            if (isVolatile) {
+                oatGenMemBarrier(cUnit, kSY);
+            }
+        }
+    } else {
+        int setterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pSet64Instance) :
+                           (isObject ? OFFSETOF_MEMBER(Thread, pSetObjInstance)
+                                     : OFFSETOF_MEMBER(Thread, pSet32Instance));
+        int rTgt = loadHelper(cUnit, setterOffset);
+        loadValueDirect(cUnit, rlObj, rARG1);
+        if (isLongOrDouble) {
+            loadValueDirectWide(cUnit, rlSrc, rARG2, rARG3);
+        } else {
+            loadValueDirect(cUnit, rlSrc, rARG2);
+        }
+        loadConstant(cUnit, rARG0, fieldIdx);
+        callRuntimeHelper(cUnit, rTgt);
+    }
+}
+
+void genConstClass(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                   RegLocation rlSrc)
+{
+    uint32_t type_idx = mir->dalvikInsn.vB;
+    int mReg = loadCurrMethod(cUnit);
+    int resReg = oatAllocTemp(cUnit);
+    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
+                                                     cUnit->dex_cache,
+                                                     *cUnit->dex_file,
+                                                     type_idx)) {
+        // Call out to helper which resolves type and verifies access.
+        // Resolved type returned in rRET0.
+        int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                              pInitializeTypeAndVerifyAccessFromCode));
+        genRegCopy(cUnit, rARG1, mReg);
+        loadConstant(cUnit, rARG0, type_idx);
+        callRuntimeHelper(cUnit, rTgt);
+        RegLocation rlResult = oatGetReturn(cUnit);
+        storeValue(cUnit, rlDest, rlResult);
+    } else {
+        // We're don't need access checks, load type from dex cache
+        int32_t dex_cache_offset =
+            Method::DexCacheResolvedTypesOffset().Int32Value();
+        loadWordDisp(cUnit, mReg, dex_cache_offset, resReg);
+        int32_t offset_of_type =
+            Array::DataOffset(sizeof(Class*)).Int32Value() + (sizeof(Class*)
+                              * type_idx);
+        loadWordDisp(cUnit, resReg, offset_of_type, rlResult.lowReg);
+        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache,
+                type_idx) || SLOW_TYPE_PATH) {
+            // Slow path, at runtime test if type is null and if so initialize
+            oatFlushAllRegs(cUnit);
+            LIR* branch1 = genCmpImmBranch(cUnit, kCondEq, rlResult.lowReg, 0);
+            // Resolved, store and hop over following code
+            storeValue(cUnit, rlDest, rlResult);
+            LIR* branch2 = genUnconditionalBranch(cUnit,0);
+            // 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
+            int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                                  pInitializeTypeFromCode));
+            genRegCopy(cUnit, rARG1, mReg);
+            loadConstant(cUnit, rARG0, type_idx);
+            callRuntimeHelper(cUnit, rTgt);
+            RegLocation rlResult = oatGetReturn(cUnit);
+            storeValue(cUnit, rlDest, rlResult);
+            // Rejoin code paths
+            LIR* target2 = newLIR0(cUnit, kPseudoTargetLabel);
+            target2->defMask = ENCODE_ALL;
+            branch1->target = (LIR*)target1;
+            branch2->target = (LIR*)target2;
+        } else {
+            // Fast path, we're done - just store result
+            storeValue(cUnit, rlDest, rlResult);
+        }
+    }
+}
+void genConstString(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                    RegLocation rlSrc)
+{
+    /* NOTE: Most strings should be available at compile time */
+    uint32_t string_idx = mir->dalvikInsn.vB;
+    int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() +
+                               (sizeof(String*) * string_idx);
+    if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(
+            cUnit->dex_cache, string_idx) || SLOW_STRING_PATH) {
+        // slow path, resolve string if not in dex cache
+        oatFlushAllRegs(cUnit);
+        oatLockCallTemps(cUnit); // Using explicit registers
+        loadCurrMethodDirect(cUnit, rARG2);
+        loadWordDisp(cUnit, rARG2,
+                     Method::DexCacheStringsOffset().Int32Value(), rARG0);
+        // Might call out to helper, which will return resolved string in rRET0
+        int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                              pResolveStringFromCode));
+        loadWordDisp(cUnit, rRET0, offset_of_string, rARG0);
+        loadConstant(cUnit, rARG1, string_idx);
+#if defined(TARGET_ARM)
+        opRegImm(cUnit, kOpCmp, rRET0, 0);  // Is resolved?
+        genBarrier(cUnit);
+        // For testing, always force through helper
+        if (!EXERCISE_SLOWEST_STRING_PATH) {
+            genIT(cUnit, kArmCondEq, "T");
+        }
+        genRegCopy(cUnit, rARG0, rARG2);   // .eq
+        opReg(cUnit, kOpBlx, rTgt);        // .eq, helper(Method*, string_idx)
+#else
+        LIR* branch = genCmpImmBranch(cUnit, kCondNe, 0);
+        genRegCopy(cUnit, rARG0, rARG2);   // .eq
+        opReg(cUnit, kOpBlx, rTgt);
+        LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+        target->defMask = ENCODE_ALL;
+        branch->target = target;
+#endif
+        genBarrier(cUnit);
+        storeValue(cUnit, rlDest, getRetLoc(cUnit));
+    } else {
+        int mReg = loadCurrMethod(cUnit);
+        int resReg = oatAllocTemp(cUnit);
+        RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+        loadWordDisp(cUnit, mReg,
+                     Method::DexCacheStringsOffset().Int32Value(), resReg);
+        loadWordDisp(cUnit, resReg, offset_of_string, rlResult.lowReg);
+        storeValue(cUnit, rlDest, rlResult);
+    }
+}
+
+/*
+ * Let helper function take care of everything.  Will
+ * call Class::NewInstanceFromCode(type_idx, method);
+ */
+void genNewInstance(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest)
+{
+    oatFlushAllRegs(cUnit);    /* Everything to home location */
+    uint32_t type_idx = mir->dalvikInsn.vB;
+    // alloc will always check for resolution, do we also need to verify
+    // access because the verifier was unable to?
+    int rTgt;
+    if (cUnit->compiler->CanAccessInstantiableTypeWithoutChecks(
+            cUnit->method_idx, cUnit->dex_cache, *cUnit->dex_file, type_idx)) {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pAllocObjectFromCode));
+    } else {
+        rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pAllocObjectFromCodeWithAccessCheck));
+    }
+    loadCurrMethodDirect(cUnit, rARG1);    // arg1 <= Method*
+    loadConstant(cUnit, rARG0, type_idx);  // arg0 <- type_idx
+    callRuntimeHelper(cUnit, rTgt);
+    RegLocation rlResult = oatGetReturn(cUnit);
+    storeValue(cUnit, rlDest, rlResult);
+}
+
+void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                   RegLocation rlSrc)
+{
+    oatFlushAllRegs(cUnit);
+    // May generate a call - use explicit registers
+    oatLockCallTemps(cUnit);
+    uint32_t type_idx = mir->dalvikInsn.vC;
+    loadCurrMethodDirect(cUnit, rARG1);  // r1 <= 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
+        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
+    } else {
+        // Load dex cache entry into classReg (r2)
+        loadValueDirectFixed(cUnit, rlSrc, rARG0);  // rARG0 <= ref
+        loadWordDisp(cUnit, rARG1,
+                     Method::DexCacheResolvedTypesOffset().Int32Value(),
+                     classReg);
+        int32_t offset_of_type =
+            Array::DataOffset(sizeof(Class*)).Int32Value() + (sizeof(Class*)
+            * type_idx);
+        loadWordDisp(cUnit, classReg, offset_of_type, classReg);
+        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(
+                cUnit->dex_cache, type_idx)) {
+            // 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 rRET0
+            int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                                  pInitializeTypeFromCode));
+            loadConstant(cUnit, rARG0, type_idx);
+            callRuntimeHelper(cUnit, rTgt);  // InitializeTypeFromCode(idx, method)
+            genRegCopy(cUnit, r2, rRET0); // Align usage with fast path
+            loadValueDirectFixed(cUnit, rlSrc, rARG0);  /* reload Ref */
+            // Rejoin code paths
+            LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
+            hopTarget->defMask = ENCODE_ALL;
+            hopBranch->target = (LIR*)hopTarget;
+        }
+    }
+    /* rARG0 is ref, rARG2 is class. If ref==null, use directly as bool result */
+    LIR* branch1 = genCmpImmBranch(cUnit, kCondEq, rARG0, 0);
+    /* load object->clazz */
+    DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
+    loadWordDisp(cUnit, rARG0,  Object::ClassOffset().Int32Value(), rARG1);
+    /* rARG0 is ref, rARG1 is ref->clazz, rARG2 is class */
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pInstanceofNonTrivialFromCode));
+#if defined(TARGET_ARM)
+    opRegReg(cUnit, kOpCmp, rARG1, rARG2);  // Same?
+    genBarrier(cUnit);
+    genIT(cUnit, kArmCondEq, "EE");   // if-convert the test
+    loadConstant(cUnit, rARG0, 1);       // .eq case - load true
+    genRegCopy(cUnit, rARG0, rARG2);        // .ne case - arg0 <= class
+    opReg(cUnit, kOpBlx, rTgt);        // .ne case: helper(class, ref->class)
+    genBarrier(cUnit);
+    oatClobberCalleeSave(cUnit);
+#else
+    // Perhaps a general-purpose kOpSelect operator?
+    UNIMPLEMENTED(FATAL) << "Need non IT implementation";
+#endif
+    /* branch target here */
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = ENCODE_ALL;
+    RegLocation rlResult = oatGetReturn(cUnit);
+    storeValue(cUnit, rlDest, rlResult);
+    branch1->target = (LIR*)target;
+}
+
+void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+{
+    oatFlushAllRegs(cUnit);
+    // May generate a call - use explicit registers
+    oatLockCallTemps(cUnit);
+    uint32_t type_idx = mir->dalvikInsn.vB;
+    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 rRET0
+        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
+    } else {
+        // Load dex cache entry into classReg (rARG2)
+        loadWordDisp(cUnit, rARG1,
+                     Method::DexCacheResolvedTypesOffset().Int32Value(),
+                     classReg);
+        int32_t offset_of_type =
+                Array::DataOffset(sizeof(Class*)).Int32Value() +
+                (sizeof(Class*) * type_idx);
+        loadWordDisp(cUnit, classReg, offset_of_type, classReg);
+        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(
+                cUnit->dex_cache, type_idx)) {
+            // 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
+            // Rejoin code paths
+            LIR* hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
+            hopTarget->defMask = ENCODE_ALL;
+            hopBranch->target = (LIR*)hopTarget;
+        }
+    }
+    // At this point, classReg (r2) has class
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);  // rARG0 <= ref
+    /* Null is OK - continue */
+    LIR* branch1 = genCmpImmBranch(cUnit, kCondEq, rARG0, 0);
+    /* load object->clazz */
+    DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
+    loadWordDisp(cUnit, rARG0,  Object::ClassOffset().Int32Value(), rARG1);
+    /* rARG1 now contains object->clazz */
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pCheckCastFromCode));
+    opRegReg(cUnit, kOpCmp, rARG1, classReg);
+    LIR* branch2 = opCondBranch(cUnit, kCondEq); /* If equal, trivial yes */
+    genRegCopy(cUnit, rARG0, rARG1);
+    genRegCopy(cUnit, rARG1, rARG2);
+    callRuntimeHelper(cUnit, rTgt);
+    /* branch target here */
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = ENCODE_ALL;
+    branch1->target = (LIR*)target;
+    branch2->target = (LIR*)target;
+}
+
+
+void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
+{
+    oatFlushAllRegs(cUnit);
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pDeliverException));
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);  // Get exception object
+    callRuntimeHelper(cUnit, rTgt);  // art_deliver_exception(exception);
+}
+
+/*
+ * Generate array store
+ *
+ */
+void genArrayObjPut(CompilationUnit* cUnit, MIR* mir, RegLocation rlArray,
+                    RegLocation rlIndex, RegLocation rlSrc, int scale)
+{
+    RegisterClass regClass = oatRegClassBySize(kWord);
+    int lenOffset = Array::LengthOffset().Int32Value();
+    int dataOffset = Array::DataOffset(sizeof(Object*)).Int32Value();
+
+    oatFlushAllRegs(cUnit);
+    /* Make sure it's a legal object Put. Use direct regs at first */
+    loadValueDirectFixed(cUnit, rlArray, rARG1);
+    loadValueDirectFixed(cUnit, rlSrc, rARG0);
+
+    /* null array object? */
+    genNullCheck(cUnit, rlArray.sRegLow, rARG1, mir);
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread,
+                          pCanPutArrayElementFromCode));
+    /* Get the array's clazz */
+    loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(), rARG1);
+    callRuntimeHelper(cUnit, rTgt);
+    oatFreeTemp(cUnit, rARG0);
+    oatFreeTemp(cUnit, rARG1);
+
+    // Now, redo loadValues in case they didn't survive the call
+
+    int regPtr;
+    rlArray = loadValue(cUnit, rlArray, kCoreReg);
+    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
+
+    if (oatIsTemp(cUnit, rlArray.lowReg)) {
+        oatClobber(cUnit, rlArray.lowReg);
+        regPtr = rlArray.lowReg;
+    } else {
+        regPtr = oatAllocTemp(cUnit);
+        genRegCopy(cUnit, regPtr, rlArray.lowReg);
+    }
+
+    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        int regLen = oatAllocTemp(cUnit);
+        //NOTE: max live temps(4) here.
+        /* Get len */
+        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
+        /* regPtr -> array data */
+        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
+        genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
+                       kThrowArrayBounds);
+        oatFreeTemp(cUnit, regLen);
+    } else {
+        /* regPtr -> array data */
+        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
+    }
+    /* at this point, regPtr points to array, 2 live temps */
+    rlSrc = loadValue(cUnit, rlSrc, regClass);
+    storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
+                     scale, kWord);
+}
+
+/*
+ * Generate array load
+ */
+void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
+                 RegLocation rlArray, RegLocation rlIndex,
+                 RegLocation rlDest, int scale)
+{
+    RegisterClass regClass = oatRegClassBySize(size);
+    int lenOffset = Array::LengthOffset().Int32Value();
+    int dataOffset;
+    RegLocation rlResult;
+    rlArray = loadValue(cUnit, rlArray, kCoreReg);
+    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
+    int regPtr;
+
+    if (size == kLong || size == kDouble) {
+      dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+    } else {
+      dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+    }
+
+    /* null object? */
+    genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+
+    regPtr = oatAllocTemp(cUnit);
+
+    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        int regLen = oatAllocTemp(cUnit);
+        /* Get len */
+        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
+        /* regPtr -> array data */
+        opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
+        genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
+                       kThrowArrayBounds);
+        oatFreeTemp(cUnit, regLen);
+    } else {
+        /* regPtr -> array data */
+        opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
+    }
+    oatFreeTemp(cUnit, rlArray.lowReg);
+    if ((size == kLong) || (size == kDouble)) {
+        if (scale) {
+            int rNewIndex = oatAllocTemp(cUnit);
+            opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
+            opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
+            oatFreeTemp(cUnit, rNewIndex);
+        } else {
+            opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
+        }
+        oatFreeTemp(cUnit, rlIndex.lowReg);
+        rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
+
+        loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
+
+        oatFreeTemp(cUnit, regPtr);
+        storeValueWide(cUnit, rlDest, rlResult);
+    } else {
+        rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
+
+        loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
+                        scale, size);
+
+        oatFreeTemp(cUnit, regPtr);
+        storeValue(cUnit, rlDest, rlResult);
+    }
+}
+
+/*
+ * Generate array store
+ *
+ */
+void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
+                 RegLocation rlArray, RegLocation rlIndex,
+                 RegLocation rlSrc, int scale)
+{
+    RegisterClass regClass = oatRegClassBySize(size);
+    int lenOffset = Array::LengthOffset().Int32Value();
+    int dataOffset;
+
+    if (size == kLong || size == kDouble) {
+      dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value();
+    } else {
+      dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value();
+    }
+
+    int regPtr;
+    rlArray = loadValue(cUnit, rlArray, kCoreReg);
+    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
+
+    if (oatIsTemp(cUnit, rlArray.lowReg)) {
+        oatClobber(cUnit, rlArray.lowReg);
+        regPtr = rlArray.lowReg;
+    } else {
+        regPtr = oatAllocTemp(cUnit);
+        genRegCopy(cUnit, regPtr, rlArray.lowReg);
+    }
+
+    /* null object? */
+    genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
+
+    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
+        int regLen = oatAllocTemp(cUnit);
+        //NOTE: max live temps(4) here.
+        /* Get len */
+        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
+        /* regPtr -> array data */
+        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
+        genRegRegCheck(cUnit, kCondCs, rlIndex.lowReg, regLen, mir,
+                       kThrowArrayBounds);
+        oatFreeTemp(cUnit, regLen);
+    } else {
+        /* regPtr -> array data */
+        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
+    }
+    /* at this point, regPtr points to array, 2 live temps */
+    if ((size == kLong) || (size == kDouble)) {
+        //TUNING: specific wide routine that can handle fp regs
+        if (scale) {
+            int rNewIndex = oatAllocTemp(cUnit);
+            opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
+            opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
+            oatFreeTemp(cUnit, rNewIndex);
+        } else {
+            opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
+        }
+        rlSrc = loadValueWide(cUnit, rlSrc, regClass);
+
+        storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
+
+        oatFreeTemp(cUnit, regPtr);
+    } else {
+        rlSrc = loadValue(cUnit, rlSrc, regClass);
+
+        storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
+                         scale, size);
+    }
+}
+
+void genLong3Addr(CompilationUnit* cUnit, MIR* mir, OpKind firstOp,
+                  OpKind secondOp, RegLocation rlDest,
+                         RegLocation rlSrc1, RegLocation rlSrc2)
+{
+    RegLocation rlResult;
+#if defined(TARGET_ARM)
+    /*
+     * NOTE:  This is the one place in the code in which we might have
+     * as many as six live temporary registers.  There are 5 in the normal
+     * set for Arm.  Until we have spill capabilities, temporarily add
+     * lr to the temp set.  It is safe to do this locally, but note that
+     * lr is used explicitly elsewhere in the code generator and cannot
+     * normally be used as a general temp register.
+     */
+    oatMarkTemp(cUnit, rLR);   // Add lr to the temp pool
+    oatFreeTemp(cUnit, rLR);   // and make it available
+#endif
+    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    // The longs may overlap - use intermediate temp if so
+    if (rlResult.lowReg == rlSrc1.highReg) {
+        int tReg = oatAllocTemp(cUnit);
+        genRegCopy(cUnit, tReg, rlSrc1.highReg);
+        opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg,
+                    rlSrc2.lowReg);
+        opRegRegReg(cUnit, secondOp, rlResult.highReg, tReg,
+                    rlSrc2.highReg);
+        oatFreeTemp(cUnit, tReg);
+    } else {
+        opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg,
+                    rlSrc2.lowReg);
+        opRegRegReg(cUnit, secondOp, rlResult.highReg, rlSrc1.highReg,
+                    rlSrc2.highReg);
+    }
+    /*
+     * NOTE: If rlDest refers to a frame variable in a large frame, the
+     * following storeValueWide might need to allocate a temp register.
+     * To further work around the lack of a spill capability, explicitly
+     * free any temps from rlSrc1 & rlSrc2 that aren't still live in rlResult.
+     * Remove when spill is functional.
+     */
+    freeRegLocTemps(cUnit, rlResult, rlSrc1);
+    freeRegLocTemps(cUnit, rlResult, rlSrc2);
+    storeValueWide(cUnit, rlDest, rlResult);
+#if defined(TARGET_ARM)
+    oatClobber(cUnit, rLR);
+    oatUnmarkTemp(cUnit, rLR);  // Remove lr from the temp pool
+#endif
+}
+
+
+bool genShiftOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                    RegLocation rlSrc1, RegLocation rlShift)
+{
+    int funcOffset;
+
+    switch( mir->dalvikInsn.opcode) {
+        case OP_SHL_LONG:
+        case OP_SHL_LONG_2ADDR:
+            funcOffset = OFFSETOF_MEMBER(Thread, pShlLong);
+            break;
+        case OP_SHR_LONG:
+        case OP_SHR_LONG_2ADDR:
+            funcOffset = OFFSETOF_MEMBER(Thread, pShrLong);
+            break;
+        case OP_USHR_LONG:
+        case OP_USHR_LONG_2ADDR:
+            funcOffset = OFFSETOF_MEMBER(Thread, pUshrLong);
+            break;
+        default:
+            LOG(FATAL) << "Unexpected case";
+            return true;
+    }
+    oatFlushAllRegs(cUnit);   /* Send everything to home location */
+    int rTgt = loadHelper(cUnit, funcOffset);
+    loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
+    loadValueDirect(cUnit, rlShift, rARG2);
+    callRuntimeHelper(cUnit, rTgt);
+    RegLocation rlResult = oatGetReturnWide(cUnit);
+    storeValueWide(cUnit, rlDest, rlResult);
+    return false;
+}
+
+
+bool genArithOpInt(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                   RegLocation rlSrc1, RegLocation rlSrc2)
+{
+    OpKind op = kOpBkpt;
+    bool callOut = false;
+    bool checkZero = false;
+    bool unary = false;
+    int retReg = rRET0;
+    int funcOffset;
+    RegLocation rlResult;
+    bool shiftOp = false;
+
+    switch (mir->dalvikInsn.opcode) {
+        case OP_NEG_INT:
+            op = kOpNeg;
+            unary = true;
+            break;
+        case OP_NOT_INT:
+            op = kOpMvn;
+            unary = true;
+            break;
+        case OP_ADD_INT:
+        case OP_ADD_INT_2ADDR:
+            op = kOpAdd;
+            break;
+        case OP_SUB_INT:
+        case OP_SUB_INT_2ADDR:
+            op = kOpSub;
+            break;
+        case OP_MUL_INT:
+        case OP_MUL_INT_2ADDR:
+            op = kOpMul;
+            break;
+        case OP_DIV_INT:
+        case OP_DIV_INT_2ADDR:
+            callOut = true;
+            checkZero = true;
+            funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
+            retReg = rRET0;
+            break;
+        /* NOTE: returns in r1 */
+        case OP_REM_INT:
+        case OP_REM_INT_2ADDR:
+            callOut = true;
+            checkZero = true;
+            funcOffset = OFFSETOF_MEMBER(Thread, pIdivmod);
+            retReg = rRET1;
+            break;
+        case OP_AND_INT:
+        case OP_AND_INT_2ADDR:
+            op = kOpAnd;
+            break;
+        case OP_OR_INT:
+        case OP_OR_INT_2ADDR:
+            op = kOpOr;
+            break;
+        case OP_XOR_INT:
+        case OP_XOR_INT_2ADDR:
+            op = kOpXor;
+            break;
+        case OP_SHL_INT:
+        case OP_SHL_INT_2ADDR:
+            shiftOp = true;
+            op = kOpLsl;
+            break;
+        case OP_SHR_INT:
+        case OP_SHR_INT_2ADDR:
+            shiftOp = true;
+            op = kOpAsr;
+            break;
+        case OP_USHR_INT:
+        case OP_USHR_INT_2ADDR:
+            shiftOp = true;
+            op = kOpLsr;
+            break;
+        default:
+            LOG(FATAL) << "Invalid word arith op: " <<
+                (int)mir->dalvikInsn.opcode;
+    }
+    if (!callOut) {
+        rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
+        if (unary) {
+            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+            opRegReg(cUnit, op, rlResult.lowReg,
+                     rlSrc1.lowReg);
+        } else {
+            rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
+            if (shiftOp) {
+                int tReg = oatAllocTemp(cUnit);
+                opRegRegImm(cUnit, kOpAnd, tReg, rlSrc2.lowReg, 31);
+                rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+                opRegRegReg(cUnit, op, rlResult.lowReg,
+                            rlSrc1.lowReg, tReg);
+                oatFreeTemp(cUnit, tReg);
+            } else {
+                rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+                opRegRegReg(cUnit, op, rlResult.lowReg,
+                            rlSrc1.lowReg, rlSrc2.lowReg);
+            }
+        }
+        storeValue(cUnit, rlDest, rlResult);
+    } else {
+        RegLocation rlResult;
+        oatFlushAllRegs(cUnit);   /* Send everything to home location */
+        loadValueDirectFixed(cUnit, rlSrc2, rRET1);
+        int rTgt = loadHelper(cUnit, funcOffset);
+        loadValueDirectFixed(cUnit, rlSrc1, rARG0);
+        if (checkZero) {
+            genImmedCheck(cUnit, kCondEq, rARG1, 0, mir, kThrowDivZero);
+        }
+        callRuntimeHelper(cUnit, rTgt);
+        if (retReg == rRET0)
+            rlResult = oatGetReturn(cUnit);
+        else
+            rlResult = oatGetReturnAlt(cUnit);
+        storeValue(cUnit, rlDest, rlResult);
+    }
+    return false;
+}
+
+/*
+ * The following are the first-level codegen routines that analyze the format
+ * of each bytecode then either dispatch special purpose codegen routines
+ * or produce corresponding Thumb instructions directly.
+ */
+
+bool isPowerOfTwo(int x)
+{
+    return (x & (x - 1)) == 0;
+}
+
+// Returns true if no more than two bits are set in 'x'.
+bool isPopCountLE2(unsigned int x)
+{
+    x &= x - 1;
+    return (x & (x - 1)) == 0;
+}
+
+// Returns the index of the lowest set bit in 'x'.
+int lowestSetBit(unsigned int x) {
+    int bit_posn = 0;
+    while ((x & 0xf) == 0) {
+        bit_posn += 4;
+        x >>= 4;
+    }
+    while ((x & 1) == 0) {
+        bit_posn++;
+        x >>= 1;
+    }
+    return bit_posn;
+}
+
+// Returns true if it added instructions to 'cUnit' to divide 'rlSrc' by 'lit'
+// and store the result in 'rlDest'.
+bool handleEasyDivide(CompilationUnit* cUnit, Opcode dalvikOpcode,
+                      RegLocation rlSrc, RegLocation rlDest, int lit)
+{
+    if (lit < 2 || !isPowerOfTwo(lit)) {
+        return false;
+    }
+    int k = lowestSetBit(lit);
+    if (k >= 30) {
+        // Avoid special cases.
+        return false;
+    }
+    bool div = (dalvikOpcode == OP_DIV_INT_LIT8 ||
+                dalvikOpcode == OP_DIV_INT_LIT16);
+    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    if (div) {
+        int tReg = oatAllocTemp(cUnit);
+        if (lit == 2) {
+            // Division by 2 is by far the most common division by constant.
+            opRegRegImm(cUnit, kOpLsr, tReg, rlSrc.lowReg, 32 - k);
+            opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
+            opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
+        } else {
+            opRegRegImm(cUnit, kOpAsr, tReg, rlSrc.lowReg, 31);
+            opRegRegImm(cUnit, kOpLsr, tReg, tReg, 32 - k);
+            opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
+            opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
+        }
+    } else {
+        int cReg = oatAllocTemp(cUnit);
+        loadConstant(cUnit, cReg, lit - 1);
+        int tReg1 = oatAllocTemp(cUnit);
+        int tReg2 = oatAllocTemp(cUnit);
+        if (lit == 2) {
+            opRegRegImm(cUnit, kOpLsr, tReg1, rlSrc.lowReg, 32 - k);
+            opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
+            opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
+            opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
+        } else {
+            opRegRegImm(cUnit, kOpAsr, tReg1, rlSrc.lowReg, 31);
+            opRegRegImm(cUnit, kOpLsr, tReg1, tReg1, 32 - k);
+            opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
+            opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
+            opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
+        }
+    }
+    storeValue(cUnit, rlDest, rlResult);
+    return true;
+}
+
+void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
+                                   RegLocation rlResult, int lit,
+                                   int firstBit, int secondBit)
+{
+    opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
+                     encodeShift(kArmLsl, secondBit - firstBit));
+    if (firstBit != 0) {
+        opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
+    }
+}
+
+// Returns true if it added instructions to 'cUnit' to multiply 'rlSrc' by 'lit'
+// and store the result in 'rlDest'.
+bool handleEasyMultiply(CompilationUnit* cUnit, RegLocation rlSrc,
+                        RegLocation rlDest, int lit)
+{
+    // Can we simplify this multiplication?
+    bool powerOfTwo = false;
+    bool popCountLE2 = false;
+    bool powerOfTwoMinusOne = false;
+    if (lit < 2) {
+        // Avoid special cases.
+        return false;
+    } else if (isPowerOfTwo(lit)) {
+        powerOfTwo = true;
+    } else if (isPopCountLE2(lit)) {
+        popCountLE2 = true;
+    } else if (isPowerOfTwo(lit + 1)) {
+        powerOfTwoMinusOne = true;
+    } else {
+        return false;
+    }
+    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    if (powerOfTwo) {
+        // Shift.
+        opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlSrc.lowReg,
+                    lowestSetBit(lit));
+    } else if (popCountLE2) {
+        // Shift and add and shift.
+        int firstBit = lowestSetBit(lit);
+        int secondBit = lowestSetBit(lit ^ (1 << firstBit));
+        genMultiplyByTwoBitMultiplier(cUnit, rlSrc, rlResult, lit,
+                                      firstBit, secondBit);
+    } else {
+        // Reverse subtract: (src << (shift + 1)) - src.
+        DCHECK(powerOfTwoMinusOne);
+        // TUNING: rsb dst, src, src lsl#lowestSetBit(lit + 1)
+        int tReg = oatAllocTemp(cUnit);
+        opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lowestSetBit(lit + 1));
+        opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg);
+    }
+    storeValue(cUnit, rlDest, rlResult);
+    return true;
+}
+
+bool genArithOpIntLit(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                      RegLocation rlSrc, int lit)
+{
+    Opcode dalvikOpcode = mir->dalvikInsn.opcode;
+    RegLocation rlResult;
+    OpKind op = (OpKind)0;      /* Make gcc happy */
+    int shiftOp = false;
+    bool isDiv = false;
+    int funcOffset;
+    int rTgt;
+
+    switch (dalvikOpcode) {
+        case OP_RSUB_INT_LIT8:
+        case OP_RSUB_INT: {
+            int tReg;
+            //TUNING: add support for use of Arm rsub op
+            rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+            tReg = oatAllocTemp(cUnit);
+            loadConstant(cUnit, tReg, lit);
+            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+            opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
+                        tReg, rlSrc.lowReg);
+            storeValue(cUnit, rlDest, rlResult);
+            return false;
+            break;
+        }
+
+        case OP_ADD_INT_LIT8:
+        case OP_ADD_INT_LIT16:
+            op = kOpAdd;
+            break;
+        case OP_MUL_INT_LIT8:
+        case OP_MUL_INT_LIT16: {
+            if (handleEasyMultiply(cUnit, rlSrc, rlDest, lit)) {
+                return false;
+            }
+            op = kOpMul;
+            break;
+        }
+        case OP_AND_INT_LIT8:
+        case OP_AND_INT_LIT16:
+            op = kOpAnd;
+            break;
+        case OP_OR_INT_LIT8:
+        case OP_OR_INT_LIT16:
+            op = kOpOr;
+            break;
+        case OP_XOR_INT_LIT8:
+        case OP_XOR_INT_LIT16:
+            op = kOpXor;
+            break;
+        case OP_SHL_INT_LIT8:
+            lit &= 31;
+            shiftOp = true;
+            op = kOpLsl;
+            break;
+        case OP_SHR_INT_LIT8:
+            lit &= 31;
+            shiftOp = true;
+            op = kOpAsr;
+            break;
+        case OP_USHR_INT_LIT8:
+            lit &= 31;
+            shiftOp = true;
+            op = kOpLsr;
+            break;
+
+        case OP_DIV_INT_LIT8:
+        case OP_DIV_INT_LIT16:
+        case OP_REM_INT_LIT8:
+        case OP_REM_INT_LIT16:
+            if (lit == 0) {
+                genImmedCheck(cUnit, kCondAl, 0, 0, mir, kThrowDivZero);
+                return false;
+            }
+            if (handleEasyDivide(cUnit, dalvikOpcode, rlSrc, rlDest, lit)) {
+                return false;
+            }
+            oatFlushAllRegs(cUnit);   /* Everything to home location */
+            loadValueDirectFixed(cUnit, rlSrc, rARG0);
+            oatClobber(cUnit, rARG0);
+            if ((dalvikOpcode == OP_DIV_INT_LIT8) ||
+                (dalvikOpcode == OP_DIV_INT_LIT16)) {
+                funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
+                isDiv = true;
+            } else {
+                funcOffset = OFFSETOF_MEMBER(Thread, pIdivmod);
+                isDiv = false;
+            }
+            rTgt = loadHelper(cUnit, funcOffset);
+            loadConstant(cUnit, rARG1, lit);
+            callRuntimeHelper(cUnit, rTgt);
+            if (isDiv)
+                rlResult = oatGetReturn(cUnit);
+            else
+                rlResult = oatGetReturnAlt(cUnit);
+            storeValue(cUnit, rlDest, rlResult);
+            return false;
+            break;
+        default:
+            return true;
+    }
+    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+    // Avoid shifts by literal 0 - no support in Thumb.  Change to copy
+    if (shiftOp && (lit == 0)) {
+        genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
+    } else {
+        opRegRegImm(cUnit, op, rlResult.lowReg, rlSrc.lowReg, lit);
+    }
+    storeValue(cUnit, rlDest, rlResult);
+    return false;
+}
+
+bool genArithOpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                    RegLocation rlSrc1, RegLocation rlSrc2)
+{
+    RegLocation rlResult;
+    OpKind firstOp = kOpBkpt;
+    OpKind secondOp = kOpBkpt;
+    bool callOut = false;
+    bool checkZero = false;
+    int funcOffset;
+    int retReg = rRET0;
+
+    switch (mir->dalvikInsn.opcode) {
+        case OP_NOT_LONG:
+            rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+            // Check for destructive overlap
+            if (rlResult.lowReg == rlSrc2.highReg) {
+                int tReg = oatAllocTemp(cUnit);
+                genRegCopy(cUnit, tReg, rlSrc2.highReg);
+                opRegReg(cUnit, kOpMvn, rlResult.lowReg, rlSrc2.lowReg);
+                opRegReg(cUnit, kOpMvn, rlResult.highReg, tReg);
+                oatFreeTemp(cUnit, tReg);
+            } else {
+                opRegReg(cUnit, kOpMvn, rlResult.lowReg, rlSrc2.lowReg);
+                opRegReg(cUnit, kOpMvn, rlResult.highReg, rlSrc2.highReg);
+            }
+            storeValueWide(cUnit, rlDest, rlResult);
+            return false;
+            break;
+        case OP_ADD_LONG:
+        case OP_ADD_LONG_2ADDR:
+            firstOp = kOpAdd;
+            secondOp = kOpAdc;
+            break;
+        case OP_SUB_LONG:
+        case OP_SUB_LONG_2ADDR:
+            firstOp = kOpSub;
+            secondOp = kOpSbc;
+            break;
+        case OP_MUL_LONG:
+        case OP_MUL_LONG_2ADDR:
+            callOut = true;
+            retReg = rRET0;
+            funcOffset = OFFSETOF_MEMBER(Thread, pLmul);
+            break;
+        case OP_DIV_LONG:
+        case OP_DIV_LONG_2ADDR:
+            callOut = true;
+            checkZero = true;
+            retReg = rRET0;
+            funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
+            break;
+        /* NOTE - result is in rARG2/rARG3 instead of rRET0/rRET1 */
+        // FIXME: is true, or could be made true, or other targets?
+        case OP_REM_LONG:
+        case OP_REM_LONG_2ADDR:
+            callOut = true;
+            checkZero = true;
+            funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
+            retReg = rARG2;
+            break;
+        case OP_AND_LONG_2ADDR:
+        case OP_AND_LONG:
+            firstOp = kOpAnd;
+            secondOp = kOpAnd;
+            break;
+        case OP_OR_LONG:
+        case OP_OR_LONG_2ADDR:
+            firstOp = kOpOr;
+            secondOp = kOpOr;
+            break;
+        case OP_XOR_LONG:
+        case OP_XOR_LONG_2ADDR:
+            firstOp = kOpXor;
+            secondOp = kOpXor;
+            break;
+        case OP_NEG_LONG: {
+            rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+            int zReg = oatAllocTemp(cUnit);
+            loadConstantNoClobber(cUnit, zReg, 0);
+            // Check for destructive overlap
+            if (rlResult.lowReg == rlSrc2.highReg) {
+                int tReg = oatAllocTemp(cUnit);
+                opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
+                            zReg, rlSrc2.lowReg);
+                opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
+                            zReg, tReg);
+                oatFreeTemp(cUnit, tReg);
+            } else {
+                opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
+                            zReg, rlSrc2.lowReg);
+                opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
+                            zReg, rlSrc2.highReg);
+            }
+            oatFreeTemp(cUnit, zReg);
+            storeValueWide(cUnit, rlDest, rlResult);
+            return false;
+        }
+        default:
+            LOG(FATAL) << "Invalid long arith op";
+    }
+    if (!callOut) {
+        genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
+    } else {
+        int rTgt;
+        oatFlushAllRegs(cUnit);   /* Send everything to home location */
+        if (checkZero) {
+            loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
+            rTgt = loadHelper(cUnit, funcOffset);
+            loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
+            int tReg = oatAllocTemp(cUnit);
+#if defined(TARGET_ARM)
+            newLIR4(cUnit, kThumb2OrrRRRs, tReg, rARG2, rARG3, 0);
+            oatFreeTemp(cUnit, tReg);
+            genCheck(cUnit, kCondEq, mir, kThrowDivZero);
+#else
+            opRegRegReg(cUnit, kOpOr, tReg, rARG2, rARG3);
+            genImmedCheck(cUnit, kCondEq, mir, tReg, 0, mir, kThrowDivZero);
+            oatFreeTemp(cUnit, tReg);
+#endif
+        } else {
+            rTgt = loadHelper(cUnit, funcOffset);
+            loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
+            loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
+        }
+        callRuntimeHelper(cUnit, rTgt);
+        // Adjust return regs in to handle case of rem returning rARG2/rARG3
+        if (retReg == rRET0)
+            rlResult = oatGetReturnWide(cUnit);
+        else
+            rlResult = oatGetReturnWideAlt(cUnit);
+        storeValueWide(cUnit, rlDest, rlResult);
+    }
+    return false;
+}
+
+bool genConversionCall(CompilationUnit* cUnit, MIR* mir, int funcOffset,
+                       int srcSize, int tgtSize)
+{
+    /*
+     * Don't optimize the register usage since it calls out to support
+     * functions
+     */
+    RegLocation rlSrc;
+    RegLocation rlDest;
+    oatFlushAllRegs(cUnit);   /* Send everything to home location */
+    int rTgt = loadHelper(cUnit, funcOffset);
+    if (srcSize == 1) {
+        rlSrc = oatGetSrc(cUnit, mir, 0);
+        loadValueDirectFixed(cUnit, rlSrc, rARG0);
+    } else {
+        rlSrc = oatGetSrcWide(cUnit, mir, 0, 1);
+        loadValueDirectWideFixed(cUnit, rlSrc, rARG0, rARG1);
+    }
+    callRuntimeHelper(cUnit, rTgt);
+    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;
+}
+
+void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc);
+bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
+                             RegLocation rlDest, RegLocation rlSrc1,
+                             RegLocation rlSrc2)
+{
+    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 */
+    int rTgt = loadHelper(cUnit, funcOffset);
+    loadValueDirectFixed(cUnit, rlSrc1, rARG0);
+    loadValueDirectFixed(cUnit, rlSrc2, rARG1);
+    callRuntimeHelper(cUnit, rTgt);
+    rlResult = oatGetReturn(cUnit);
+    storeValue(cUnit, rlDest, rlResult);
+    return false;
+}
+
+void genNegDouble(CompilationUnit* cUnit, RegLocation rlDst, RegLocation rlSrc);
+bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
+                              RegLocation rlDest, RegLocation rlSrc1,
+                              RegLocation rlSrc2)
+{
+    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 */
+    int rTgt = loadHelper(cUnit, funcOffset);
+    loadValueDirectWideFixed(cUnit, rlSrc1, rARG0, rARG1);
+    loadValueDirectWideFixed(cUnit, rlSrc2, rARG2, rARG3);
+    callRuntimeHelper(cUnit, rTgt);
+    rlResult = oatGetReturnWide(cUnit);
+    storeValueWide(cUnit, rlDest, rlResult);
+    return false;
+}
+
+bool genConversionPortable(CompilationUnit* cUnit, MIR* mir)
+{
+    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;
+}
+
+/*
+ * Generate callout to updateDebugger. Note that we're overloading
+ * the use of rSUSPEND here.  When the debugger is active, this
+ * register holds the address of the update function.  So, if it's
+ * non-null, we call out to it.
+ *
+ * Note also that rRET0 and rRET1 must be preserved across this
+ * code.  This must be handled by the stub.
+ */
+void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset)
+{
+    // Following DCHECK verifies that dPC is in range of single load immediate
+    DCHECK((offset == DEBUGGER_METHOD_ENTRY) ||
+           (offset == DEBUGGER_METHOD_EXIT) || ((offset & 0xffff) == offset));
+    oatClobberCalleeSave(cUnit);
+#if defined(TARGET_ARM)
+    opRegImm(cUnit, kOpCmp, rSUSPEND, 0);
+    genIT(cUnit, kArmCondNe, "T");
+    loadConstant(cUnit, rARG2, offset);     // arg2 <- Entry code
+    opReg(cUnit, kOpBlx, rSUSPEND);
+#else
+    LIR* branch = genCmpImmBranch(cUnit, kCondEq, rSUSPEND, 0);
+    loadConstant(cUnit, rARG2, offset);
+    opReg(cUnit, kOpBlx, rSUSPEND);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+    target->defMask = ENCODE_ALL;
+    branch->target = (LIR*)target;
+#endif
+    oatFreeTemp(cUnit, rARG2);
+}
+
+/* Check if we need to check for pending suspend request */
+void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
+{
+    if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
+        return;
+    }
+    oatFlushAllRegs(cUnit);
+    LIR* branch;
+    if (cUnit->genDebugger) {
+        // If generating code for the debugger, always check for suspension
+        branch = genUnconditionalBranch(cUnit, NULL);
+    } else {
+#if defined(TARGET_ARM)
+        // In non-debug case, only check periodically
+        newLIR2(cUnit, kThumbSubRI8, rSUSPEND, 1);
+        branch = opCondBranch(cUnit, kCondEq);
+#else
+        opRegImm(cUnit, kOpSub, rSUSPEND, 1);
+        branch = opCompareBranchImm(cUnit, kCondEq, rSUSPEND, 0);
+#endif
+    }
+    LIR* retLab = newLIR0(cUnit, kPseudoTargetLabel);
+    retLab->defMask = ENCODE_ALL;
+    LIR* target = (LIR*)oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    target->dalvikOffset = cUnit->currentDalvikOffset;
+    target->opcode = kPseudoSuspendTarget;
+    target->operands[0] = (intptr_t)retLab;
+    target->operands[1] = mir->offset;
+    branch->target = (LIR*)target;
+    oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads, (intptr_t)target);
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/GenInvoke.cc
new file mode 100644
index 0000000..a201010
--- /dev/null
+++ b/src/compiler/codegen/GenInvoke.cc
@@ -0,0 +1,506 @@
+/*
+ * 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 source files contains "gen" codegen routines that should
+ * be applicable to most targets.  Only mid-level support utilities
+ * and "op" calls may be used here.
+ */
+
+
+/*
+ * x86 targets will likely be different enough to need their own
+ * invoke gen routies.
+ */
+#if defined(TARGET_ARM) || defined (TARGET_MIPS)
+typedef int (*NextCallInsn)(CompilationUnit*, MIR*, int, uint32_t dexIdx,
+                            uint32_t methodIdx);
+/*
+ * 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.
+ */
+void flushIns(CompilationUnit* cUnit)
+{
+    if (cUnit->numIns == 0)
+        return;
+    int firstArgReg = rARG1;
+    int lastArgReg = rARG3;
+    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);
+            }
+        }
+    }
+}
+
+/*
+ * Bit of a hack here - in leiu of a real scheduling pass,
+ * emit the next instruction in static & direct invoke sequences.
+ */
+int nextSDCallInsn(CompilationUnit* cUnit, MIR* mir,
+                   int state, uint32_t dexIdx, uint32_t unused)
+{
+    switch(state) {
+        case 0:  // Get the current Method* [sets rARG0]
+            loadCurrMethodDirect(cUnit, rARG0);
+            break;
+        case 1:  // Get method->dex_cache_resolved_methods_
+            loadWordDisp(cUnit, rARG0,
+                Method::DexCacheResolvedMethodsOffset().Int32Value(),
+                rARG0);
+            break;
+        case 2:  // Grab target method*
+            loadWordDisp(cUnit, rARG0,
+                Array::DataOffset(sizeof(Object*)).Int32Value() + dexIdx * 4,
+                rARG0);
+            break;
+        case 3:  // Grab the code from the method*
+            loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
+                         rLINK);
+            break;
+        default:
+            return -1;
+    }
+    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
+ * rARG1 here rather than the standard loadArgRegs.
+ */
+int nextVCallInsn(CompilationUnit* cUnit, MIR* mir,
+                  int state, uint32_t dexIdx, uint32_t methodIdx)
+{
+    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 rARG1]
+            rlArg = oatGetSrc(cUnit, mir, 0);
+            loadValueDirectFixed(cUnit, rlArg, rARG1);
+            break;
+        case 1: // Is "this" null? [use rARG1]
+            genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
+            // get this->klass_ [use rARG1, set rLINK]
+            loadWordDisp(cUnit, rARG1, Object::ClassOffset().Int32Value(),
+                         rLINK);
+            break;
+        case 2: // Get this->klass_->vtable [usr rLINK, set rLINK]
+            loadWordDisp(cUnit, rLINK, Class::VTableOffset().Int32Value(),
+                         rLINK);
+            break;
+        case 3: // Get target method [use rLINK, set rARG0]
+            loadWordDisp(cUnit, rLINK, (methodIdx * 4) +
+                         Array::DataOffset(sizeof(Object*)).Int32Value(),
+                         rARG0);
+            break;
+        case 4: // Get the target compiled code address [uses rARG0, sets rLINK]
+            loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
+                         rLINK);
+            break;
+        default:
+            return -1;
+    }
+    return state + 1;
+}
+
+/*
+ * Interleave launch code for INVOKE_SUPER.  See comments
+ * for nextVCallIns.
+ */
+int nextSuperCallInsn(CompilationUnit* cUnit, MIR* mir,
+                      int state, uint32_t dexIdx, uint32_t methodIdx)
+{
+    /*
+     * 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 rARG0]
+            loadCurrMethodDirect(cUnit, rARG0);
+            // Load "this" [set rARG1]
+            rlArg = oatGetSrc(cUnit, mir, 0);
+            loadValueDirectFixed(cUnit, rlArg, rARG1);
+            // Get method->declaring_class_ [use rARG0, set rLINK]
+            loadWordDisp(cUnit, rARG0,
+                         Method::DeclaringClassOffset().Int32Value(),
+                         rLINK);
+            // Is "this" null? [use rARG1]
+            genNullCheck(cUnit, oatSSASrc(mir,0), rARG1, mir);
+            break;
+        case 1: // Get method->declaring_class_->super_class [use/set rLINK]
+            loadWordDisp(cUnit, rLINK,
+                         Class::SuperClassOffset().Int32Value(), rLINK);
+            break;
+        case 2: // Get ...->super_class_->vtable [u/s rLINK]
+            loadWordDisp(cUnit, rLINK,
+                         Class::VTableOffset().Int32Value(), rLINK);
+            break;
+        case 3: // Get target method [use rLINK, set rARG0]
+            loadWordDisp(cUnit, rLINK, (methodIdx * 4) +
+                         Array::DataOffset(sizeof(Object*)).Int32Value(),
+                         rARG0);
+            break;
+        case 4: // Get the target compiled code address [uses rARG0, sets rLINK]
+            loadWordDisp(cUnit, rARG0, Method::GetCodeOffset().Int32Value(),
+                         rLINK);
+            break;
+        default:
+            return -1;
+    }
+    return state + 1;
+}
+
+int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
+                     int state, uint32_t dexIdx, uint32_t methodIdx)
+{
+    /*
+     * 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, rLINK);
+        // Load rARG0 with method index
+        loadConstant(cUnit, rARG0, dexIdx);
+        return 1;
+    }
+    return -1;
+}
+
+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);
+}
+
+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);
+}
+
+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);
+}
+
+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.
+ */
+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);
+}
+
+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);
+}
+
+int loadArgRegs(CompilationUnit* cUnit, MIR* mir, DecodedInstruction* dInsn,
+                int callState, NextCallInsn nextCallInsn, uint32_t dexIdx,
+                uint32_t methodIdx, bool skipThis)
+{
+    int nextReg = rARG1;
+    int nextArg = 0;
+    if (skipThis) {
+        nextReg++;
+        nextArg++;
+    }
+    for (; (nextReg <= rARG3) && (nextArg < mir->ssaRep->numUses); nextReg++) {
+        RegLocation rlArg = oatGetRawSrc(cUnit, mir, nextArg++);
+        rlArg = oatUpdateRawLoc(cUnit, rlArg);
+        if (rlArg.wide && (nextReg <= rARG2)) {
+            loadValueDirectWideFixed(cUnit, rlArg, nextReg, nextReg + 1);
+            nextReg++;
+            nextArg++;
+        } else {
+            rlArg.wide = false;
+            loadValueDirectFixed(cUnit, rlArg, nextReg);
+        }
+        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
+    }
+    return callState;
+}
+
+/*
+ * Load up to 5 arguments, the first three of which will be in
+ * rARG1 .. rARG3.  On entry rARG0 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.
+ */
+int genDalvikArgsNoRange(CompilationUnit* cUnit, MIR* mir,
+                         DecodedInstruction* dInsn, int callState,
+                         LIR** pcrLabel, NextCallInsn nextCallInsn,
+                         uint32_t dexIdx, uint32_t methodIdx, bool skipThis)
+{
+    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 {
+                // rARG2 & rARG3 can safely be used here
+                reg = rARG3;
+                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 = rARG2;
+                highReg = rARG3;
+                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), rARG1, mir);
+    }
+    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 rARG1-rARG3
+ *    If 20+ arguments
+ *       Pass args arg19+ using memcpy block copy
+ *       Pass arg0, arg1 & arg2 in rARG1-rARG3
+ *
+ */
+int genDalvikArgsRange(CompilationUnit* cUnit, MIR* mir,
+                       DecodedInstruction* dInsn, int callState,
+                       LIR** pcrLabel, NextCallInsn nextCallInsn,
+                       uint32_t dexIdx, uint32_t methodIdx, bool skipThis)
+{
+    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 defined(TARGET_MIPS)
+    // Generate memcpy
+    opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
+    opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
+    int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pMemcpy));
+    loadConstant(cUnit, rARG2, (numArgs - 3) * 4);
+    callRuntimeHelper(cUnit, rTgt);
+    // Restore Method*
+    loadCurrMethodDirect(cUnit, rARG0);
+#else
+    if (numArgs >= 20) {
+        // Generate memcpy
+        opRegRegImm(cUnit, kOpAdd, rARG0, rSP, outsOffset);
+        opRegRegImm(cUnit, kOpAdd, rARG1, rSP, startOffset);
+        int rTgt = loadHelper(cUnit, OFFSETOF_MEMBER(Thread, pMemcpy));
+        loadConstant(cUnit, rARG2, (numArgs - 3) * 4);
+        callRuntimeHelper(cUnit, rTgt);
+        // Restore Method*
+        loadCurrMethodDirect(cUnit, rARG0);
+    } else {
+        // Use vldm/vstm pair using rARG3 as a temp
+        int regsLeft = std::min(numArgs - 3, 16);
+        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
+        opRegRegImm(cUnit, kOpAdd, rARG3, rSP, startOffset);
+        LIR* ld = newLIR3(cUnit, kThumb2Vldms, rARG3, fr0, regsLeft);
+        //TUNING: loosen barrier
+        ld->defMask = ENCODE_ALL;
+        setMemRefType(ld, true /* isLoad */, kDalvikReg);
+        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
+        opRegRegImm(cUnit, kOpAdd, rARG3, rSP, 4 /* Method* */ + (3 * 4));
+        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
+        LIR* st = newLIR3(cUnit, kThumb2Vstms, rARG3, fr0, regsLeft);
+        setMemRefType(st, false /* isLoad */, kDalvikReg);
+        st->defMask = ENCODE_ALL;
+        callState = nextCallInsn(cUnit, mir, callState, dexIdx, methodIdx);
+    }
+#endif
+
+    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), rARG1, mir);
+    }
+    return callState;
+}
+
+#endif  // TARGET_ARM || TARGET_MIPS
+
+
+}  // namespace art
diff --git a/src/compiler/codegen/LocalOptimizations.cc b/src/compiler/codegen/LocalOptimizations.cc
index cc276f2..19b41e7 100644
--- a/src/compiler/codegen/LocalOptimizations.cc
+++ b/src/compiler/codegen/LocalOptimizations.cc
@@ -27,7 +27,7 @@
 #define LDLD_DISTANCE 4
 #define LD_LATENCY 2
 
-STATIC inline bool isDalvikRegisterClobbered(TGT_LIR* lir1, TGT_LIR* lir2)
+inline bool isDalvikRegisterClobbered(LIR* lir1, LIR* lir2)
 {
     int reg1Lo = DECODE_ALIAS_INFO_REG(lir1->aliasInfo);
     int reg1Hi = reg1Lo + DECODE_ALIAS_INFO_WIDE(lir1->aliasInfo);
@@ -38,11 +38,11 @@
 }
 
 /* Convert a more expensive instruction (ie load) into a move */
-STATIC void convertMemOpIntoMove(CompilationUnit* cUnit, TGT_LIR* origLIR,
-                                 int dest, int src)
+void convertMemOpIntoMove(CompilationUnit* cUnit, LIR* origLIR, int dest,
+                          int src)
 {
     /* Insert a move to replace the load */
-    TGT_LIR* moveLIR;
+    LIR* moveLIR;
     moveLIR = oatRegCopyNoInsert( cUnit, dest, src);
     /*
      * Insert the converted instruction after the original since the
@@ -71,11 +71,10 @@
  *   1) They are must-aliases
  *   2) The memory location is not written to in between
  */
-STATIC void applyLoadStoreElimination(CompilationUnit* cUnit,
-                                      TGT_LIR* headLIR,
-                                      TGT_LIR* tailLIR)
+void applyLoadStoreElimination(CompilationUnit* cUnit, LIR* headLIR,
+                               LIR* tailLIR)
 {
-    TGT_LIR* thisLIR;
+    LIR* thisLIR;
 
     if (headLIR == tailLIR) return;
 
@@ -93,7 +92,7 @@
 
         int nativeRegId = thisLIR->operands[0];
         bool isThisLIRLoad = EncodingMap[thisLIR->opcode].flags & IS_LOAD;
-        TGT_LIR* checkLIR;
+        LIR* checkLIR;
         /* Use the mem mask to determine the rough memory location */
         u8 thisMemMask = (thisLIR->useMask | thisLIR->defMask) & ENCODE_MEM;
 
@@ -230,9 +229,9 @@
                                                 "REG CLOBBERED"));
                 /* Only sink store instructions */
                 if (sinkDistance && !isThisLIRLoad) {
-                    TGT_LIR* newStoreLIR =
-                        (TGT_LIR* ) oatNew(cUnit, sizeof(TGT_LIR), true,
-                                          kAllocLIR);
+                    LIR* newStoreLIR =
+                        (LIR* ) oatNew(cUnit, sizeof(LIR), true,
+                                       kAllocLIR);
                     *newStoreLIR = *thisLIR;
                     /*
                      * Stop point found - insert *before* the checkLIR
@@ -255,16 +254,14 @@
  * Perform a pass of bottom-up walk, from the second instruction in the
  * superblock, to try to hoist loads to earlier slots.
  */
-STATIC void applyLoadHoisting(CompilationUnit* cUnit,
-                              TGT_LIR* headLIR,
-                              TGT_LIR* tailLIR)
+void applyLoadHoisting(CompilationUnit* cUnit, LIR* headLIR, LIR* tailLIR)
 {
-    TGT_LIR* thisLIR, *checkLIR;
+    LIR* thisLIR, *checkLIR;
     /*
      * Store the list of independent instructions that can be hoisted past.
      * Will decide the best place to insert later.
      */
-    TGT_LIR* prevInstList[MAX_HOIST_DISTANCE];
+    LIR* prevInstList[MAX_HOIST_DISTANCE];
 
     /* Empty block */
     if (headLIR == tailLIR) return;
@@ -373,7 +370,7 @@
         if (nextSlot >= 2) {
             int firstSlot = nextSlot - 2;
             int slot;
-            TGT_LIR* depLIR = prevInstList[nextSlot-1];
+            LIR* depLIR = prevInstList[nextSlot-1];
             /* If there is ld-ld dependency, wait LDLD_DISTANCE cycles */
             if (!isPseudoOpcode(depLIR->opcode) &&
                 (EncodingMap[depLIR->opcode].flags & IS_LOAD)) {
@@ -384,8 +381,8 @@
              * when the loop is first entered.
              */
             for (slot = firstSlot; slot >= 0; slot--) {
-                TGT_LIR* curLIR = prevInstList[slot];
-                TGT_LIR* prevLIR = prevInstList[slot+1];
+                LIR* curLIR = prevInstList[slot];
+                LIR* prevLIR = prevInstList[slot+1];
 
                 /* Check the highest instruction */
                 if (prevLIR->defMask == ENCODE_ALL) {
@@ -418,8 +415,8 @@
 
             /* Found a slot to hoist to */
             if (slot >= 0) {
-                TGT_LIR* curLIR = prevInstList[slot];
-                TGT_LIR* newLoadLIR = (TGT_LIR* ) oatNew(cUnit, sizeof(TGT_LIR),
+                LIR* curLIR = prevInstList[slot];
+                LIR* newLoadLIR = (LIR* ) oatNew(cUnit, sizeof(LIR),
                                                        true, kAllocLIR);
                 *newLoadLIR = *thisLIR;
                 /*
@@ -437,11 +434,11 @@
                                         LIR* tailLIR)
 {
     if (!(cUnit->disableOpt & (1 << kLoadStoreElimination))) {
-        applyLoadStoreElimination(cUnit, (TGT_LIR* ) headLIR,
-                                  (TGT_LIR* ) tailLIR);
+        applyLoadStoreElimination(cUnit, (LIR* ) headLIR,
+                                  (LIR* ) tailLIR);
     }
     if (!(cUnit->disableOpt & (1 << kLoadHoisting))) {
-        applyLoadHoisting(cUnit, (TGT_LIR* ) headLIR, (TGT_LIR* ) tailLIR);
+        applyLoadHoisting(cUnit, (LIR* ) headLIR, (LIR* ) tailLIR);
     }
 }
 
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/MethodCodegenDriver.cc
index ce8cfda..6de3a9c 100644
--- a/src/compiler/codegen/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/MethodCodegenDriver.cc
@@ -21,11 +21,11 @@
 #define DISPLAY_MISSING_TARGETS (cUnit->enableDebug & \
     (1 << kDebugDisplayMissingTargets))
 
-STATIC const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0,
-                                   INVALID_REG, INVALID_REG, INVALID_SREG};
+const RegLocation badLoc = {kLocDalvikFrame, 0, 0, 0, 0, 0, 0,
+                            INVALID_REG, INVALID_REG, INVALID_SREG};
 
 /* Mark register usage state and return long retloc */
-STATIC RegLocation getRetLocWide(CompilationUnit* cUnit)
+RegLocation getRetLocWide(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN_WIDE;
     oatLockTemp(cUnit, res.lowReg);
@@ -34,28 +34,28 @@
     return res;
 }
 
-STATIC RegLocation getRetLoc(CompilationUnit* cUnit)
+RegLocation getRetLoc(CompilationUnit* cUnit)
 {
     RegLocation res = LOC_C_RETURN;
     oatLockTemp(cUnit, res.lowReg);
     return res;
 }
 
-STATIC void genInvoke(CompilationUnit* cUnit, MIR* mir,
-                      InvokeType type, bool isRange)
+void genInvoke(CompilationUnit* cUnit, MIR* mir, InvokeType type, bool isRange)
 {
     DecodedInstruction* dInsn = &mir->dalvikInsn;
     int callState = 0;
-    TGT_LIR* nullCk;
-    TGT_LIR** pNullCk = NULL;
+    LIR* nullCk;
+    LIR** pNullCk = NULL;
     NextCallInsn nextCallInsn;
     oatFlushAllRegs(cUnit);    /* Everything to home location */
     // Explicit register usage
     oatLockCallTemps(cUnit);
 
     OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
-                             *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
-                             cUnit->method_idx, cUnit->access_flags);
+                             *cUnit->dex_file, *cUnit->dex_cache,
+                             cUnit->code_item, cUnit->method_idx,
+                             cUnit->access_flags);
 
     uint32_t dexMethodIdx = dInsn->vB;
     int vtableIdx;
@@ -111,8 +111,8 @@
  * load/store utilities here, or target-dependent genXX() handlers
  * when necessary.
  */
-STATIC bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
-                                     BasicBlock* bb, TGT_LIR* labelList)
+bool compileDalvikInstruction(CompilationUnit* cUnit, MIR* mir,
+                              BasicBlock* bb, LIR* labelList)
 {
     bool res = false;   // Assume success
     RegLocation rlSrc[3];
@@ -690,7 +690,7 @@
     return res;
 }
 
-STATIC const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
+const char* extendedMIROpNames[kMirOpLast - kMirOpFirst] = {
     "kMirOpPhi",
     "kMirOpNullNRangeUpCheck",
     "kMirOpNullNRangeDownCheck",
@@ -700,7 +700,7 @@
 };
 
 /* Extended MIR instructions like PHI */
-STATIC void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
+void handleExtendedMethodMIR(CompilationUnit* cUnit, MIR* mir)
 {
     int opOffset = mir->dalvikInsn.opcode - kMirOpFirst;
     char* msg = NULL;
@@ -709,7 +709,7 @@
                             false, kAllocDebugInfo);
         strcpy(msg, extendedMIROpNames[opOffset]);
     }
-    TGT_LIR* op = newLIR1(cUnit, kArmPseudoExtended, (int) msg);
+    LIR* op = newLIR1(cUnit, kPseudoExtended, (int) msg);
 
     switch ((ExtendedMIROpcode)mir->dalvikInsn.opcode) {
         case kMirOpPhi: {
@@ -718,7 +718,7 @@
                 ssaString = oatGetSSAString(cUnit, mir->ssaRep);
             }
             op->flags.isNop = true;
-            newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
+            newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
             break;
         }
         default:
@@ -727,17 +727,17 @@
 }
 
 /* Handle the content in each basic block */
-STATIC bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
+bool methodBlockCodeGen(CompilationUnit* cUnit, BasicBlock* bb)
 {
     MIR* mir;
-    TGT_LIR* labelList = (TGT_LIR*) cUnit->blockLabelList;
+    LIR* labelList = (LIR*) cUnit->blockLabelList;
     int blockId = bb->id;
 
     cUnit->curBlock = bb;
     labelList[blockId].operands[0] = bb->startOffset;
 
     /* Insert the block label */
-    labelList[blockId].opcode = kArmPseudoNormalBlockLabel;
+    labelList[blockId].opcode = kPseudoNormalBlockLabel;
     oatAppendLIR(cUnit, (LIR*) &labelList[blockId]);
 
     /* Reset local optimization data on block boundaries */
@@ -745,7 +745,7 @@
     oatClobberAllRegs(cUnit);
     oatResetDefTracking(cUnit);
 
-    TGT_LIR* headLIR = NULL;
+    LIR* headLIR = NULL;
 
     if (bb->blockType == kEntryBlock) {
         genEntrySequence(cUnit, bb);
@@ -775,12 +775,12 @@
         InstructionFormat dalvikFormat =
             dexGetFormatFromOpcode(dalvikOpcode);
 
-        TGT_LIR* boundaryLIR;
+        LIR* boundaryLIR;
 
         /* Mark the beginning of a Dalvik instruction for line tracking */
         char* instStr = cUnit->printMe ?
            oatGetDalvikDisassembly(cUnit, &mir->dalvikInsn, "") : NULL;
-        boundaryLIR = newLIR1(cUnit, kArmPseudoDalvikByteCodeBoundary,
+        boundaryLIR = newLIR1(cUnit, kPseudoDalvikByteCodeBoundary,
                               (intptr_t) instStr);
         cUnit->boundaryMap.insert(std::make_pair(mir->offset,
                                  (LIR*)boundaryLIR));
@@ -799,7 +799,7 @@
         /* Don't generate the SSA annotation unless verbose mode is on */
         if (cUnit->printMe && mir->ssaRep) {
             char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
-            newLIR1(cUnit, kArmPseudoSSARep, (int) ssaString);
+            newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
         }
 
         bool notHandled = compileDalvikInstruction(cUnit, mir, bb, labelList);
@@ -837,7 +837,7 @@
 {
     /* Used to hold the labels of each block */
     cUnit->blockLabelList =
-        (void *) oatNew(cUnit, sizeof(TGT_LIR) * cUnit->numBlocks, true,
+        (void *) oatNew(cUnit, sizeof(LIR) * cUnit->numBlocks, true,
                         kAllocLIR);
 
     oatDataFlowAnalysisDispatcher(cUnit, methodBlockCodeGen,
@@ -850,7 +850,7 @@
 }
 
 /* Needed by the ld/st optmizatons */
-TGT_LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
+LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
 {
     return genRegCopyNoInsert(cUnit, rDest, rSrc);
 }
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/RallocUtil.cc
index 77fb23b..bb2abba 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/RallocUtil.cc
@@ -76,7 +76,7 @@
     }
 }
 
-STATIC void dumpRegPool(RegisterInfo* p, int numRegs)
+void dumpRegPool(RegisterInfo* p, int numRegs)
 {
     int i;
     LOG(INFO) << "================================================";
@@ -124,7 +124,7 @@
     clobberBody(cUnit, oatGetRegInfo(cUnit, reg));
 }
 
-STATIC void clobberSRegBody(RegisterInfo* p, int numRegs, int sReg)
+void clobberSRegBody(RegisterInfo* p, int numRegs, int sReg)
 {
     int i;
     for (i=0; i< numRegs; i++) {
@@ -174,7 +174,7 @@
  * even/odd  allocation, but go ahead and allocate anything if not
  * available.  If nothing's available, return -1.
  */
-STATIC int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even)
+int allocPreservedSingle(CompilationUnit* cUnit, int sReg, bool even)
 {
     int res = -1;
     RegisterInfo* FPRegs = cUnit->regPool->FPRegs;
@@ -202,7 +202,7 @@
  * allocate if we can't meet the requirements for the pair of
  * sReg<=sX[even] & (sReg+1)<= sX+1.
  */
-STATIC int allocPreservedDouble(CompilationUnit* cUnit, int sReg)
+int allocPreservedDouble(CompilationUnit* cUnit, int sReg)
 {
     int res = -1; // Assume failure
     //  Should be promoting based on initial sReg set
@@ -274,8 +274,8 @@
     return res;
 }
 
-STATIC int allocTempBody(CompilationUnit* cUnit, RegisterInfo* p, int numRegs,
-                         int* nextTemp, bool required)
+int allocTempBody(CompilationUnit* cUnit, RegisterInfo* p, int numRegs,
+                  int* nextTemp, bool required)
 {
     int i;
     int next = *nextTemp;
@@ -389,7 +389,7 @@
                          &cUnit->regPool->nextFPReg, true);
 }
 
-STATIC RegisterInfo* allocLiveBody(RegisterInfo* p, int numRegs, int sReg)
+RegisterInfo* allocLiveBody(RegisterInfo* p, int numRegs, int sReg)
 {
     int i;
     if (sReg == -1)
@@ -404,8 +404,7 @@
     return NULL;
 }
 
-STATIC RegisterInfo* allocLive(CompilationUnit* cUnit, int sReg,
-                               int regClass)
+RegisterInfo* allocLive(CompilationUnit* cUnit, int sReg, int regClass)
 {
     RegisterInfo* res = NULL;
     switch(regClass) {
@@ -537,7 +536,7 @@
     resetDefBody(oatGetRegInfo(cUnit, reg));
 }
 
-STATIC void nullifyRange(CompilationUnit* cUnit, LIR *start, LIR *finish,
+void nullifyRange(CompilationUnit* cUnit, LIR *start, LIR *finish,
                          int sReg1, int sReg2)
 {
     if (start && finish) {
@@ -557,7 +556,7 @@
  * sequence.
  */
 extern void oatMarkDef(CompilationUnit* cUnit, RegLocation rl,
-                    LIR *start, LIR *finish)
+                       LIR *start, LIR *finish)
 {
     DCHECK(!rl.wide);
     DCHECK(start && start->next);
@@ -573,7 +572,7 @@
  * sequence.
  */
 extern void oatMarkDefWide(CompilationUnit* cUnit, RegLocation rl,
-                        LIR *start, LIR *finish)
+                           LIR *start, LIR *finish)
 {
     DCHECK(rl.wide);
     DCHECK(start && start->next);
@@ -584,8 +583,7 @@
     p->defEnd = finish;
 }
 
-extern RegLocation oatWideToNarrow(CompilationUnit* cUnit,
-                                           RegLocation rl)
+extern RegLocation oatWideToNarrow(CompilationUnit* cUnit, RegLocation rl)
 {
     DCHECK(rl.wide);
     if (rl.location == kLocPhysReg) {
@@ -658,7 +656,7 @@
 }
 
 // Make sure nothing is live and dirty
-STATIC void flushAllRegsBody(CompilationUnit* cUnit, RegisterInfo* info,
+void flushAllRegsBody(CompilationUnit* cUnit, RegisterInfo* info,
                              int numRegs)
 {
     int i;
@@ -684,7 +682,7 @@
 
 
 //TUNING: rewrite all of this reg stuff.  Probably use an attribute table
-STATIC bool regClassMatches(int regClass, int reg)
+bool regClassMatches(int regClass, int reg)
 {
     if (regClass == kAnyReg) {
         return true;
@@ -764,7 +762,7 @@
       info->inUse = true;
 }
 
-STATIC void copyRegInfo(CompilationUnit* cUnit, int newReg, int oldReg)
+void copyRegInfo(CompilationUnit* cUnit, int newReg, int oldReg)
 {
     RegisterInfo* newInfo = oatGetRegInfo(cUnit, newReg);
     RegisterInfo* oldInfo = oatGetRegInfo(cUnit, oldReg);
@@ -835,8 +833,7 @@
 }
 
 /* see comments for updateLoc */
-extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit,
-                                    RegLocation loc)
+extern RegLocation oatUpdateLocWide(CompilationUnit* cUnit, RegLocation loc)
 {
     DCHECK(loc.wide);
     DCHECK(oatCheckCorePoolSanity(cUnit));
@@ -889,8 +886,7 @@
 
 
 /* For use in cases we don't know (or care) width */
-extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit,
-                                   RegLocation loc)
+extern RegLocation oatUpdateRawLoc(CompilationUnit* cUnit, RegLocation loc)
 {
     if (loc.wide)
         return oatUpdateLocWide(cUnit, loc);
@@ -898,8 +894,8 @@
         return oatUpdateLoc(cUnit, loc);
 }
 
-STATIC RegLocation evalLocWide(CompilationUnit* cUnit, RegLocation loc,
-                               int regClass, bool update)
+RegLocation evalLocWide(CompilationUnit* cUnit, RegLocation loc,
+                        int regClass, bool update)
 {
     DCHECK(loc.wide);
     int newRegs;
@@ -1017,7 +1013,7 @@
 
 /* USE SSA names to count references of base Dalvik vRegs. */
 void oatCountRefs(CompilationUnit *cUnit, BasicBlock* bb,
-                      RefCounts* coreCounts, RefCounts* fpCounts)
+                  RefCounts* coreCounts, RefCounts* fpCounts)
 {
     MIR* mir;
     if (bb->blockType != kDalvikByteCode && bb->blockType != kEntryBlock &&
diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
index c3de5ff..5f75ef8 100644
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ b/src/compiler/codegen/arm/ArchFactory.cc
@@ -22,1063 +22,17 @@
  *
  */
 
-#include "oat_compilation_unit.h"
-
-#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))
-
 namespace art {
 
-STATIC void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
+void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
 
-/* Generate conditional branch instructions */
-STATIC ArmLIR* genConditionalBranch(CompilationUnit* cUnit,
-                                    ArmConditionCode cond,
-                                    ArmLIR* target)
+int loadHelper(CompilationUnit* cUnit, int offset)
 {
-    ArmLIR* branch = opCondBranch(cUnit, cond);
-    branch->generic.target = (LIR*) target;
-    return branch;
+    loadWordDisp(cUnit, rSELF, offset, rLR);
+    return rLR;
 }
 
-/* Generate unconditional branch instructions */
-STATIC ArmLIR* genUnconditionalBranch(CompilationUnit* cUnit, ArmLIR* target)
-{
-    ArmLIR* branch = opNone(cUnit, kOpUncondBr);
-    branch->generic.target = (LIR*) target;
-    return branch;
-}
-
-STATIC ArmLIR* callRuntimeHelper(CompilationUnit* cUnit, int reg)
-{
-    oatClobberCalleeSave(cUnit);
-    return opReg(cUnit, kOpBlx, reg);
-}
-
-/*
- * Mark garbage collection card. Skip if the value we're storing is null.
- */
-STATIC void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
-{
-    int regCardBase = oatAllocTemp(cUnit);
-    int regCardNo = oatAllocTemp(cUnit);
-    ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondEq, valReg, 0);
-    loadWordDisp(cUnit, rSELF, Thread::CardTableOffset().Int32Value(),
-                 regCardBase);
-    opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, GC_CARD_SHIFT);
-    storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
-                     kUnsignedByte);
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
-    target->defMask = ENCODE_ALL;
-    branchOver->generic.target = (LIR*)target;
-    oatFreeTemp(cUnit, regCardBase);
-    oatFreeTemp(cUnit, regCardNo);
-}
-
-/*
- * 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)
-{
-#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 ArmLIR* genCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
-                        MIR* mir, ArmThrowKind kind)
-{
-    ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    tgt->opcode = kArmPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir ? mir->offset : 0;
-    ArmLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
-    // Remember branch target - will process later
-    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-    return branch;
-}
-
-STATIC ArmLIR* genImmedCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
-                             int reg, int immVal, MIR* mir, ArmThrowKind kind)
-{
-    ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    tgt->opcode = kArmPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir->offset;
-    ArmLIR* branch;
-    if (cCode == kArmCondAl) {
-        branch = genUnconditionalBranch(cUnit, tgt);
-    } else {
-        branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
-        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 ArmLIR* 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, kArmCondEq, mReg, 0, mir, kArmThrowNullPointer);
-}
-
-/* Perform check on two registers */
-STATIC TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, ArmConditionCode cCode,
-                               int reg1, int reg2, MIR* mir, ArmThrowKind kind)
-{
-    ArmLIR* tgt = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    tgt->opcode = kArmPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir ? mir->offset : 0;
-    tgt->operands[2] = reg1;
-    tgt->operands[3] = reg2;
-    opRegReg(cUnit, kOpCmp, reg1, reg2);
-    ArmLIR* 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 */
-    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), rLR);
-    } else {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCodeWithAccessCheck), rLR);
-    }
-    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
-    loadConstant(cUnit, r0, type_idx);            // arg0 <- type_id
-    loadValueDirectFixed(cUnit, rlSrc, r2);       // arg2 <- count
-    callRuntimeHelper(cUnit, rLR);
-    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 */
-    if (cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
-                                                    cUnit->dex_cache,
-                                                    *cUnit->dex_file,
-                                                    typeId)) {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCode), rLR);
-    } else {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCodeWithAccessCheck), rLR);
-    }
-    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
-    loadConstant(cUnit, r0, typeId);              // arg0 <- type_id
-    loadConstant(cUnit, r2, elems);               // arg2 <- count
-    callRuntimeHelper(cUnit, rLR);
-    /*
-     * NOTE: the implicit target for OP_FILLED_NEW_ARRAY is the
-     * return region.  Because AllocFromCode placed the new array
-     * in r0, 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, r0);
-
-    // TODO: use the correct component size, currently all supported types share array alignment
-    // with ints (see comment at head of function)
-    size_t component_size = sizeof(int32_t);
-
-    // 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 = rLR;  // Using a lot of temps, rLR is known free here
-        // 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, r0,
-                    Array::DataOffset(component_size).Int32Value());
-        // Set up the loop counter (known to be > 0)
-        loadConstant(cUnit, rIdx, dInsn->vA - 1);
-        // Generate the copy loop.  Going backwards for convenience
-        ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
-        target->defMask = ENCODE_ALL;
-        // Copy next element
-        loadBaseIndexed(cUnit, rSrc, rIdx, rVal, 2, kWord);
-        storeBaseIndexed(cUnit, rDst, rIdx, rVal, 2, kWord);
-        // Use setflags encoding here
-        newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
-        ArmLIR* branch = opCondBranch(cUnit, kArmCondGe);
-        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, r0,
-                          Array::DataOffset(component_size).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;
-
-    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
-                             *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
-                             cUnit->method_idx, cUnit->access_flags);
-
-    bool fastPath =
-        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
-                                                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.
-            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(sizeof(Object*)).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
-            ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
-            loadWordDisp(cUnit, rSELF,
-                         OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
-            loadConstant(cUnit, r0, ssbIndex);
-            callRuntimeHelper(cUnit, rLR);
-            ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
-            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)
-{
-    int fieldOffset;
-    int ssbIndex;
-    bool isVolatile;
-    bool isReferrersClass;
-    uint32_t fieldIdx = mir->dalvikInsn.vB;
-
-    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
-                             *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
-                             cUnit->method_idx, cUnit->access_flags);
-
-    bool fastPath =
-        cUnit->compiler->ComputeStaticFieldInfo(fieldIdx, &mUnit,
-                                                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(sizeof(Object*)).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
-            ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rBase, 0);
-            loadWordDisp(cUnit, rSELF,
-                         OFFSETOF_MEMBER(Thread, pInitializeStaticStorage), rLR);
-            loadConstant(cUnit, r0, ssbIndex);
-            callRuntimeHelper(cUnit, rLR);
-            ArmLIR* skipTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
-            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);
-        }
-    }
-}
-
-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)
-{
-    switch(state) {
-        case 0:  // Get the current Method* [sets r0]
-            loadCurrMethodDirect(cUnit, r0);
-            break;
-        case 1:  // Get method->dex_cache_resolved_methods_
-            loadWordDisp(cUnit, r0,
-                Method::DexCacheResolvedMethodsOffset().Int32Value(),
-                r0);
-            break;
-        case 2:  // Grab target method*
-            loadWordDisp(cUnit, r0,
-                Array::DataOffset(sizeof(Object*)).Int32Value() + dexIdx * 4,
-                r0);
-            break;
-        case 3:  // Grab the code from the method*
-            loadWordDisp(cUnit, r0, Method::GetCodeOffset().Int32Value(), rLR);
-            break;
-        default:
-            return -1;
-    }
-    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)
-{
-    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(sizeof(Object*)).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;
-    }
-    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)
-{
-    /*
-     * 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(sizeof(Object*)).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;
-    }
-    return state + 1;
-}
-
-STATIC int nextInvokeInsnSP(CompilationUnit* cUnit, MIR* mir, int trampoline,
-                            int state, uint32_t dexIdx, uint32_t methodIdx)
-{
-    /*
-     * 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;
-    }
-    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)
-{
-    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);
-    }
-    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,
-                                ArmLIR** pcrLabel, NextCallInsn nextCallInsn,
-                                uint32_t dexIdx, uint32_t methodIdx,
-                                bool skipThis)
-{
-    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);
-    }
-    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,
-                              ArmLIR** pcrLabel, NextCallInsn nextCallInsn,
-                              uint32_t dexIdx, uint32_t methodIdx,
-                              bool skipThis)
-{
-    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);
-        ArmLIR* 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);
-        ArmLIR* 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);
-    }
-    return callState;
-}
-
-// Debugging routine - if null target, branch to DebugMe
-STATIC void genShowTarget(CompilationUnit* cUnit)
-{
-    ArmLIR* branchOver = genCmpImmBranch(cUnit, kArmCondNe, rLR, 0);
-    loadWordDisp(cUnit, rSELF,
-                 OFFSETOF_MEMBER(Thread, pDebugMe), rLR);
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
-    target->defMask = -1;
-    branchOver->generic.target = (LIR*)target;
-}
-
-STATIC void genThrowVerificationError(CompilationUnit* cUnit, MIR* mir)
-{
-    loadWordDisp(cUnit, rSELF,
-                 OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode), rLR);
-    loadConstant(cUnit, r0, mir->dalvikInsn.vA);
-    loadConstant(cUnit, r1, mir->dalvikInsn.vB);
-    callRuntimeHelper(cUnit, rLR);
-}
-
-STATIC void genCompareAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
-                                MIR* mir, RegLocation rlSrc1,
-                                RegLocation rlSrc2, ArmLIR* labelList)
-{
-    ArmConditionCode 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 = kArmCondEq;
-            break;
-        case OP_IF_NE:
-            cond = kArmCondNe;
-            break;
-        case OP_IF_LT:
-            cond = kArmCondLt;
-            break;
-        case OP_IF_GE:
-            cond = kArmCondGe;
-            break;
-        case OP_IF_GT:
-            cond = kArmCondGt;
-            break;
-        case OP_IF_LE:
-            cond = kArmCondLe;
-            break;
-        default:
-            cond = (ArmConditionCode)0;
-            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
-    }
-    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
-    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
-}
-
-STATIC void genCompareZeroAndBranch(CompilationUnit* cUnit, BasicBlock* bb,
-                                   MIR* mir, RegLocation rlSrc,
-                                   ArmLIR* labelList)
-{
-    ArmConditionCode cond;
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    opRegImm(cUnit, kOpCmp, rlSrc.lowReg, 0);
-    Opcode opcode = mir->dalvikInsn.opcode;
-    switch(opcode) {
-        case OP_IF_EQZ:
-            cond = kArmCondEq;
-            break;
-        case OP_IF_NEZ:
-            cond = kArmCondNe;
-            break;
-        case OP_IF_LTZ:
-            cond = kArmCondLt;
-            break;
-        case OP_IF_GEZ:
-            cond = kArmCondGe;
-            break;
-        case OP_IF_GTZ:
-            cond = kArmCondGt;
-            break;
-        case OP_IF_LEZ:
-            cond = kArmCondLe;
-            break;
-        default:
-            cond = (ArmConditionCode)0;
-            LOG(FATAL) << "Unexpected opcode " << (int)opcode;
-    }
-    genConditionalBranch(cUnit, cond, &labelList[bb->taken->id]);
-    genUnconditionalBranch(cUnit, &labelList[bb->fallThrough->id]);
-}
-
-STATIC void genIntToLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                         RegLocation rlSrc)
-{
-    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);
-}
-
-STATIC void genIntNarrowing(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlDest, RegLocation rlSrc)
-{
-     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);
-}
-
-/*
- * 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)
-{
-    if (cUnit->numIns == 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);
-            }
-        }
-    }
-}
-
-STATIC void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
+void genEntrySequence(CompilationUnit* cUnit, BasicBlock* bb)
 {
     int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
     /*
@@ -1099,7 +53,7 @@
     bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) &&
                               ((size_t)cUnit->frameSize <
                               Thread::kStackOverflowReservedBytes));
-    newLIR0(cUnit, kArmPseudoMethodEntry);
+    newLIR0(cUnit, kPseudoMethodEntry);
     if (!skipOverflowCheck) {
         /* Load stack limit */
         loadWordDisp(cUnit, rSELF,
@@ -1119,8 +73,8 @@
     if (!skipOverflowCheck) {
         opRegRegImm(cUnit, kOpSub, rLR, rSP,
                     cUnit->frameSize - (spillCount * 4));
-        genRegRegCheck(cUnit, kArmCondCc, rLR, r12, NULL,
-                       kArmThrowStackOverflow);
+        genRegRegCheck(cUnit, kCondCc, rLR, r12, NULL,
+                       kThrowStackOverflow);
         genRegCopy(cUnit, rSP, rLR);         // Establish stack
     } else {
         opRegImm(cUnit, kOpSub, rSP,
@@ -1142,7 +96,7 @@
     oatFreeTemp(cUnit, r3);
 }
 
-STATIC void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb)
+void genExitSequence(CompilationUnit* cUnit, BasicBlock* bb)
 {
     int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
     /*
@@ -1152,7 +106,7 @@
     oatLockTemp(cUnit, r0);
     oatLockTemp(cUnit, r1);
 
-    newLIR0(cUnit, kArmPseudoMethodExit);
+    newLIR0(cUnit, kPseudoMethodExit);
     /* If we're compiling for the debugger, generate an update callout */
     if (cUnit->genDebugger) {
         genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT);
@@ -1181,16 +135,16 @@
  */
 void removeRedundantBranches(CompilationUnit* cUnit)
 {
-    ArmLIR* thisLIR;
+    LIR* thisLIR;
 
-    for (thisLIR = (ArmLIR*) cUnit->firstLIRInsn;
-         thisLIR != (ArmLIR*) 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)) {
-            ArmLIR* nextLIR = thisLIR;
+            LIR* nextLIR = thisLIR;
 
             while (true) {
                 nextLIR = NEXT_LIR(nextLIR);
@@ -1198,7 +152,7 @@
                 /*
                  * Is the branch target the next instruction?
                  */
-                if (nextLIR == (ArmLIR*) thisLIR->generic.target) {
+                if (nextLIR == (LIR*) thisLIR->target) {
                     thisLIR->flags.isNop = true;
                     break;
                 }
@@ -1209,109 +163,13 @@
                  * might be the last real instruction.
                  */
                 if (!isPseudoOpcode(nextLIR->opcode) ||
-                    (nextLIR = (ArmLIR*) cUnit->lastLIRInsn))
+                    (nextLIR = (LIR*) cUnit->lastLIRInsn))
                     break;
             }
         }
     }
 }
 
-STATIC void handleSuspendLaunchpads(CompilationUnit *cUnit)
-{
-    ArmLIR** suspendLabel =
-        (ArmLIR **) cUnit->suspendLaunchpads.elemList;
-    int numElems = cUnit->suspendLaunchpads.numUsed;
-
-    for (int i = 0; i < numElems; i++) {
-        /* TUNING: move suspend count load into helper */
-        ArmLIR* lab = suspendLabel[i];
-        ArmLIR* resumeLab = (ArmLIR*)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);
-    }
-}
-
-STATIC void handleThrowLaunchpads(CompilationUnit *cUnit)
-{
-    ArmLIR** throwLabel =
-        (ArmLIR **) cUnit->throwLaunchpads.elemList;
-    int numElems = cUnit->throwLaunchpads.numUsed;
-    int i;
-
-    for (i = 0; i < numElems; i++) {
-        ArmLIR* 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 kArmThrowNullPointer:
-                funcOffset = OFFSETOF_MEMBER(Thread, pThrowNullPointerFromCode);
-                break;
-            case kArmThrowArrayBounds:
-                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 kArmThrowDivZero:
-                funcOffset = OFFSETOF_MEMBER(Thread, pThrowDivZeroFromCode);
-                break;
-            case kArmThrowVerificationError:
-                loadConstant(cUnit, r0, v1);
-                loadConstant(cUnit, r1, v2);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowVerificationErrorFromCode);
-                break;
-            case kArmThrowNegArraySize:
-                genRegCopy(cUnit, r0, v1);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
-                break;
-            case kArmThrowNoSuchMethod:
-                genRegCopy(cUnit, r0, v1);
-                funcOffset =
-                    OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
-                break;
-            case kArmThrowStackOverflow:
-                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);
-    }
-}
 
 /* Common initialization routine for an architecture family */
 bool oatArchInit()
@@ -1328,11 +186,4 @@
 
     return oatArchVariantInit();
 }
-
-/* Needed by the Assembler */
-void oatSetupResourceMasks(ArmLIR* lir)
-{
-    setupResourceMasks(lir);
-}
-
 }  // namespace art
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
index 75ae456..e1eba44 100644
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ b/src/compiler/codegen/arm/ArchUtility.cc
@@ -22,6 +22,33 @@
 
 namespace art {
 
+ArmConditionCode oatArmConditionEncoding(ConditionCode code)
+{
+    ArmConditionCode res;
+    switch(code) {
+        case kCondEq: res = kArmCondEq; break;
+        case kCondNe: res = kArmCondNe; break;
+        case kCondCs: res = kArmCondCs; break;
+        case kCondCc: res = kArmCondCc; break;
+        case kCondMi: res = kArmCondMi; break;
+        case kCondPl: res = kArmCondPl; break;
+        case kCondVs: res = kArmCondVs; break;
+        case kCondVc: res = kArmCondVc; break;
+        case kCondHi: res = kArmCondHi; break;
+        case kCondLs: res = kArmCondLs; break;
+        case kCondGe: res = kArmCondGe; break;
+        case kCondLt: res = kArmCondLt; break;
+        case kCondGt: res = kArmCondGt; break;
+        case kCondLe: res = kArmCondLe; break;
+        case kCondAl: res = kArmCondAl; break;
+        case kCondNv: res = kArmCondNv; break;
+        default:
+            LOG(FATAL) << "Bad condition code" << (int)code;
+            res = (ArmConditionCode)0;  // Quiet gcc
+    }
+    return res;
+}
+
 static const char* coreRegNames[16] = {
     "r0",
     "r1",
@@ -49,7 +76,7 @@
     "ror"};
 
 /* Decode and print a ARM register name */
-STATIC char* decodeRegList(ArmOpcode opcode, int vector, char* buf)
+char* decodeRegList(int opcode, int vector, char* buf)
 {
     int i;
     bool printed = false;
@@ -73,7 +100,7 @@
     return buf;
 }
 
-STATIC char*  decodeFPCSRegList(int count, int base, char* buf)
+char*  decodeFPCSRegList(int count, int base, char* buf)
 {
     sprintf(buf, "s%d", base);
     for (int i = 1; i < count; i++) {
@@ -82,7 +109,7 @@
     return buf;
 }
 
-STATIC int expandImmediate(int value)
+int expandImmediate(int value)
 {
     int mode = (value & 0xf00) >> 8;
     u4 bits = value & 0xff;
@@ -108,7 +135,8 @@
  * 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, ArmLIR* lir, unsigned char* baseAddr)
+std::string buildInsnString(const char* fmt, LIR* lir,
+                            unsigned char* baseAddr)
 {
     std::string buf;
     int i;
@@ -205,15 +233,15 @@
                        break;
                    case 't':
                        sprintf(tbuf,"0x%08x (L%p)",
-                               (int) baseAddr + lir->generic.offset + 4 +
+                               (int) baseAddr + lir->offset + 4 +
                                (operand << 1),
-                               lir->generic.target);
+                               lir->target);
                        break;
                    case 'u': {
                        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);
@@ -250,7 +278,7 @@
 {
     char buf[256];
     buf[0] = 0;
-    ArmLIR* armLIR = (ArmLIR*) lir;
+    LIR* armLIR = (LIR*) lir;
 
     if (mask == ENCODE_ALL) {
         strcpy(buf, "all");
@@ -302,57 +330,57 @@
 /* Pretty-print a LIR instruction */
 void oatDumpLIRInsn(CompilationUnit* cUnit, LIR* arg, unsigned char* baseAddr)
 {
-    ArmLIR* lir = (ArmLIR*) arg;
-    int offset = lir->generic.offset;
+    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 kArmPseudoMethodEntry:
+        case kPseudoMethodEntry:
             LOG(INFO) << "-------- method entry " <<
                 PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
             break;
-        case kArmPseudoMethodExit:
+        case kPseudoMethodExit:
             LOG(INFO) << "-------- Method_Exit";
             break;
-        case kArmPseudoBarrier:
+        case kPseudoBarrier:
             LOG(INFO) << "-------- BARRIER";
             break;
-        case kArmPseudoExtended:
+        case kPseudoExtended:
             LOG(INFO) << "-------- " << (char* ) dest;
             break;
-        case kArmPseudoSSARep:
+        case kPseudoSSARep:
             DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
             break;
-        case kArmPseudoEntryBlock:
+        case kPseudoEntryBlock:
             LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
             break;
-        case kArmPseudoDalvikByteCodeBoundary:
+        case kPseudoDalvikByteCodeBoundary:
             LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
-                 lir->generic.dalvikOffset << " @ " << (char* )lir->operands[0];
+                 lir->dalvikOffset << " @ " << (char* )lir->operands[0];
             break;
-        case kArmPseudoExitBlock:
+        case kPseudoExitBlock:
             LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
             break;
-        case kArmPseudoPseudoAlign4:
+        case kPseudoPseudoAlign4:
             LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
                 offset << "): .align4";
             break;
-        case kArmPseudoEHBlockLabel:
+        case kPseudoEHBlockLabel:
             LOG(INFO) << "Exception_Handling:";
             break;
-        case kArmPseudoTargetLabel:
-        case kArmPseudoNormalBlockLabel:
+        case kPseudoTargetLabel:
+        case kPseudoNormalBlockLabel:
             LOG(INFO) << "L" << (intptr_t)lir << ":";
             break;
-        case kArmPseudoThrowTarget:
+        case kPseudoThrowTarget:
             LOG(INFO) << "LT" << (intptr_t)lir << ":";
             break;
-        case kArmPseudoSuspendTarget:
+        case kPseudoSuspendTarget:
             LOG(INFO) << "LS" << (intptr_t)lir << ":";
             break;
-        case kArmPseudoCaseLabel:
+        case kPseudoCaseLabel:
             LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" <<
                 std::hex << lir->operands[0] << "|" << std::dec <<
                 lir->operands[0];
@@ -416,7 +444,7 @@
     LOG(INFO) << "Dumping LIR insns for "
         << PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
     LIR* lirInsn;
-    ArmLIR* armLIR;
+    LIR* armLIR;
     int insnsSize = cUnit->insnsSize;
 
     LOG(INFO) << "Regs (excluding ins) : " << cUnit->numRegs;
@@ -437,15 +465,15 @@
         oatDumpLIRInsn(cUnit, lirInsn, 0);
     }
     for (lirInsn = cUnit->classPointerList; lirInsn; lirInsn = lirInsn->next) {
-        armLIR = (ArmLIR*) lirInsn;
+        armLIR = (LIR*) lirInsn;
         LOG(INFO) << StringPrintf("%x (%04x): .class (%s)",
-            armLIR->generic.offset, armLIR->generic.offset,
+            armLIR->offset, armLIR->offset,
             ((CallsiteInfo *) armLIR->operands[0])->classDescriptor);
     }
     for (lirInsn = cUnit->literalList; lirInsn; lirInsn = lirInsn->next) {
-        armLIR = (ArmLIR*) lirInsn;
+        armLIR = (LIR*) lirInsn;
         LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)",
-            armLIR->generic.offset, armLIR->generic.offset, armLIR->operands[0]);
+            armLIR->offset, armLIR->offset, armLIR->operands[0]);
     }
 
     const DexFile::MethodId& method_id =
diff --git a/src/compiler/codegen/arm/ArmLIR.h b/src/compiler/codegen/arm/ArmLIR.h
index a9c8286..196bddb 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/ArmLIR.h
@@ -167,42 +167,6 @@
 #define DECODE_ALIAS_INFO_REG(X)        (X & 0xffff)
 #define DECODE_ALIAS_INFO_WIDE(X)       ((X & 0x80000000) ? 1 : 0)
 
-typedef enum OpKind {
-    kOpMov,
-    kOpMvn,
-    kOpCmp,
-    kOpLsl,
-    kOpLsr,
-    kOpAsr,
-    kOpRor,
-    kOpNot,
-    kOpAnd,
-    kOpOr,
-    kOpXor,
-    kOpNeg,
-    kOpAdd,
-    kOpAdc,
-    kOpSub,
-    kOpSbc,
-    kOpRsub,
-    kOpMul,
-    kOpDiv,
-    kOpRem,
-    kOpBic,
-    kOpCmn,
-    kOpTst,
-    kOpBkpt,
-    kOpBlx,
-    kOpPush,
-    kOpPop,
-    kOp2Char,
-    kOp2Short,
-    kOp2Byte,
-    kOpCondBr,
-    kOpUncondBr,
-    kOpInvalid,
-} OpKind;
-
 /*
  * Annotate special-purpose core registers:
  *   - VM: r6SELF
@@ -280,6 +244,15 @@
     dr15 = fr30 + FP_DOUBLE,
 } NativeRegisterPool;
 
+/* Target-independent aliases */
+#define rARG0 r0
+#define rARG1 r1
+#define rARG2 r2
+#define rARG3 r3
+#define rRET0 r0
+#define rRET1 r1
+#define rLINK rLR
+
 /* Shift encodings */
 typedef enum ArmShiftEncodings {
     kArmLsl = 0x0,
@@ -308,16 +281,6 @@
     kArmCondNv = 0xf,    /* 1111 */
 } ArmConditionCode;
 
-typedef enum ArmThrowKind {
-    kArmThrowNullPointer,
-    kArmThrowDivZero,
-    kArmThrowArrayBounds,
-    kArmThrowVerificationError,
-    kArmThrowNegArraySize,
-    kArmThrowNoSuchMethod,
-    kArmThrowStackOverflow,
-} ArmThrowKind;
-
 #define isPseudoOpcode(opcode) ((int)(opcode) < 0)
 
 /*
@@ -326,21 +289,21 @@
  * Assemble.c.
  */
 typedef enum ArmOpcode {
-    kArmPseudoSuspendTarget = -15,
-    kArmPseudoThrowTarget = -14,
-    kArmPseudoCaseLabel = -13,
-    kArmPseudoMethodEntry = -12,
-    kArmPseudoMethodExit = -11,
-    kArmPseudoBarrier = -10,
-    kArmPseudoExtended = -9,
-    kArmPseudoSSARep = -8,
-    kArmPseudoEntryBlock = -7,
-    kArmPseudoExitBlock = -6,
-    kArmPseudoTargetLabel = -5,
-    kArmPseudoDalvikByteCodeBoundary = -4,
-    kArmPseudoPseudoAlign4 = -3,
-    kArmPseudoEHBlockLabel = -2,
-    kArmPseudoNormalBlockLabel = -1,
+    kPseudoSuspendTarget = -15,
+    kPseudoThrowTarget = -14,
+    kPseudoCaseLabel = -13,
+    kPseudoMethodEntry = -12,
+    kPseudoMethodExit = -11,
+    kPseudoBarrier = -10,
+    kPseudoExtended = -9,
+    kPseudoSSARep = -8,
+    kPseudoEntryBlock = -7,
+    kPseudoExitBlock = -6,
+    kPseudoTargetLabel = -5,
+    kPseudoDalvikByteCodeBoundary = -4,
+    kPseudoPseudoAlign4 = -3,
+    kPseudoEHBlockLabel = -2,
+    kPseudoNormalBlockLabel = -1,
     /************************************************************************/
     kArm16BitData,       /* DATA   [0] rd[15..0] */
     kThumbAdcRR,         /* adc     [0100000101] rm[5..3] rd[2..0] */
@@ -782,42 +745,12 @@
 
 extern const ArmEncodingMap EncodingMap[kArmLast];
 
-/*
- * 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 into Thumb instructions.
- *
- * 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 ArmLIR {
-    LIR generic;
-    ArmOpcode 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;    // bytes (2 for thumb, 2/4 for thumb2)
-        unsigned int unused:23;
-    } flags;
-    int aliasInfo;              // For Dalvik register & litpool disambiguation
-    u8 useMask;                 // Resource mask for use
-    u8 defMask;                 // Resource mask for def
-} ArmLIR;
-
 typedef struct SwitchTable {
     int offset;
     const u2* table;            // Original dex table
     int vaddr;                  // Dalvik offset of switch opcode
-    ArmLIR* bxInst;             // Switch indirect branch instruction
-    ArmLIR** targets;           // Array of case targets
+    LIR* bxInst;                // Switch indirect branch instruction
+    LIR** targets;              // Array of case targets
 } SwitchTable;
 
 typedef struct FillArrayData {
@@ -827,12 +760,6 @@
     int vaddr;                 // Dalvik offset of OP_FILL_ARRAY_DATA opcode
 } FillArrayData;
 
-/* Utility macros to traverse the LIR/ArmLIR list */
-#define NEXT_LIR(lir) ((ArmLIR *) lir->generic.next)
-#define PREV_LIR(lir) ((ArmLIR *) lir->generic.prev)
-
-#define NEXT_LIR_LVALUE(lir) (lir)->generic.next
-#define PREV_LIR_LVALUE(lir) (lir)->generic.prev
 
 }  // namespace art
 
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
index 38f1b88..a020687 100644
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ b/src/compiler/codegen/arm/ArmRallocUtil.cc
@@ -184,9 +184,9 @@
 }
 
 /* Convert an instruction to a NOP */
-STATIC void oatNopLIR( LIR* lir)
+void oatNopLIR( LIR* lir)
 {
-    ((ArmLIR*)lir)->flags.isNop = true;
+    ((LIR*)lir)->flags.isNop = true;
 }
 
 }  // namespace art
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/Assemble.cc
index 0cd7605..53f9494 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/Assemble.cc
@@ -77,7 +77,7 @@
  *
  *  [!] escape.  To insert "!", use "!!"
  */
-/* NOTE: must be kept in sync with enum ArmOpcode from ArmLIR.h */
+/* NOTE: must be kept in sync with enum ArmOpcode from LIR.h */
 const ArmEncodingMap EncodingMap[kArmLast] = {
     ENCODING_MAP(kArm16BitData,    0x0000,
                  kFmtBitBlt, 15, 0, kFmtUnused, -1, -1, kFmtUnused, -1, -1,
@@ -983,13 +983,13 @@
 AssemblerStatus oatAssembleInstructions(CompilationUnit* cUnit,
                                         intptr_t startAddr)
 {
-    ArmLIR* lir;
+    LIR* lir;
     AssemblerStatus res = kSuccess;  // Assume success
 
-    for (lir = (ArmLIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) {
+    for (lir = (LIR *) cUnit->firstLIRInsn; lir; lir = NEXT_LIR(lir)) {
 
         if (lir->opcode < 0) {
-            if ((lir->opcode == kArmPseudoPseudoAlign4) &&
+            if ((lir->opcode == kPseudoPseudoAlign4) &&
                 /* 1 means padding is needed */
                 (lir->operands[0] == 1)) {
                 cUnit->codeBuffer.push_back(PADDING_MOV_R5_R5);
@@ -1024,9 +1024,9 @@
                  * However, if the load displacement exceeds the limit,
                  * we revert to a 2-instruction materialization sequence.
                  */
-                ArmLIR *lirTarget = (ArmLIR *) lir->generic.target;
-                intptr_t pc = (lir->generic.offset + 4) & ~3;
-                intptr_t target = lirTarget->generic.offset;
+                LIR *lirTarget = (LIR *) lir->target;
+                intptr_t pc = (lir->offset + 4) & ~3;
+                intptr_t target = lirTarget->offset;
                 int delta = target - pc;
                 if (delta & 0x3) {
                     LOG(FATAL) << "PC-rel offset not multiple of 4: " << delta;
@@ -1050,10 +1050,10 @@
                         lir->operands[0] : rLR;
 
                     // Add new Adr to generate the address
-                    ArmLIR *newAdr = (ArmLIR *)oatNew(cUnit, sizeof(ArmLIR),
+                    LIR *newAdr = (LIR *)oatNew(cUnit, sizeof(LIR),
                         true, kAllocLIR);
-                    newAdr->generic.dalvikOffset = lir->generic.dalvikOffset;
-                    newAdr->generic.target = lir->generic.target;
+                    newAdr->dalvikOffset = lir->dalvikOffset;
+                    newAdr->target = lir->target;
                     newAdr->opcode = kThumb2Adr;
                     newAdr->operands[0] = baseReg;
                     oatSetupResourceMasks(newAdr);
@@ -1078,28 +1078,28 @@
                     }
                 }
             } else if (lir->opcode == kThumb2Cbnz || lir->opcode == kThumb2Cbz) {
-                ArmLIR *targetLIR = (ArmLIR *) 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 > 126 || delta < 0) {
                     /* Convert to cmp rx,#0 / b[eq/ne] tgt pair */
-                    ArmLIR *newInst = (ArmLIR *)oatNew(cUnit, sizeof(ArmLIR),
+                    LIR *newInst = (LIR *)oatNew(cUnit, sizeof(LIR),
                         true, kAllocLIR);
                     /* Make new branch instruction and insert after */
-                    newInst->generic.dalvikOffset = lir->generic.dalvikOffset;
+                    newInst->dalvikOffset = lir->dalvikOffset;
                     newInst->opcode = kThumbBCond;
                     newInst->operands[0] = 0;
                     newInst->operands[1] = (lir->opcode == kThumb2Cbz) ?
                                             kArmCondEq : kArmCondNe;
-                    newInst->generic.target = lir->generic.target;
+                    newInst->target = lir->target;
                     oatSetupResourceMasks(newInst);
                     oatInsertLIRAfter((LIR *)lir, (LIR *)newInst);
                     /* Convert the cb[n]z to a cmp rx, #0 ] */
                     lir->opcode = kThumbCmpRI8;
                     /* operand[0] is src1 in both cb[n]z & CmpRI8 */
                     lir->operands[1] = 0;
-                    lir->generic.target = 0;
+                    lir->target = 0;
                     oatSetupResourceMasks(lir);
                     res = kRetryAll;
                 } else {
@@ -1131,11 +1131,11 @@
                 }
             } else if (lir->opcode == kThumbBCond ||
                        lir->opcode == kThumb2BCond) {
-                ArmLIR *targetLIR = (ArmLIR *) lir->generic.target;
+                LIR *targetLIR = (LIR *) lir->target;
                 int delta = 0;
                 DCHECK(targetLIR);
-                intptr_t pc = lir->generic.offset + 4;
-                intptr_t target = targetLIR->generic.offset;
+                intptr_t pc = lir->offset + 4;
+                intptr_t target = targetLIR->offset;
                 delta = target - pc;
                 if ((lir->opcode == kThumbBCond) &&
                     (delta > 254 || delta < -256)) {
@@ -1145,9 +1145,9 @@
                 }
                 lir->operands[0] = delta >> 1;
             } else if (lir->opcode == kThumb2BUncond) {
-                ArmLIR *targetLIR = (ArmLIR *) 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;
                 lir->operands[0] = delta >> 1;
                 if (lir->operands[0] == 0) {  // Useless branch?
@@ -1155,9 +1155,9 @@
                     res = kRetryAll;
                 }
             } else if (lir->opcode == kThumbBUncond) {
-                ArmLIR *targetLIR = (ArmLIR *) 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 > 2046 || delta < -2048) {
                     // Convert to Thumb2BCond w/ kArmCondAl
@@ -1175,7 +1175,7 @@
             } else if (lir->opcode == kThumbBlx1) {
                 DCHECK(NEXT_LIR(lir)->opcode == kThumbBlx2);
                 /* curPC is Thumb */
-                intptr_t curPC = (startAddr + lir->generic.offset + 4) & ~3;
+                intptr_t curPC = (startAddr + lir->offset + 4) & ~3;
                 intptr_t target = lir->operands[1];
 
                 /* Match bit[1] in target with base */
@@ -1190,7 +1190,7 @@
             } else if (lir->opcode == kThumbBl1) {
                 DCHECK(NEXT_LIR(lir)->opcode == kThumbBl2);
                 /* Both curPC and target are Thumb */
-                intptr_t curPC = startAddr + lir->generic.offset + 4;
+                intptr_t curPC = startAddr + lir->offset + 4;
                 intptr_t target = lir->operands[1];
 
                 int delta = target - curPC;
@@ -1200,30 +1200,30 @@
                 NEXT_LIR(lir)->operands[0] = (delta>> 1) & 0x7ff;
             } else if (lir->opcode == kThumb2Adr) {
                 SwitchTable *tabRec = (SwitchTable*)lir->operands[2];
-                ArmLIR* target = (ArmLIR*)lir->generic.target;
+                LIR* target = (LIR*)lir->target;
                 int targetDisp = tabRec ? tabRec->offset
-                                        : target->generic.offset;
-                int disp = targetDisp - ((lir->generic.offset + 4) & ~3);
+                                        : target->offset;
+                int disp = targetDisp - ((lir->offset + 4) & ~3);
                 if (disp < 4096) {
                     lir->operands[1] = disp;
                 } else {
                     // convert to ldimm16l, ldimm16h, add tgt, pc, operands[0]
-                    ArmLIR *newMov16L =
-                        (ArmLIR *)oatNew(cUnit, sizeof(ArmLIR), true,
+                    LIR *newMov16L =
+                        (LIR *)oatNew(cUnit, sizeof(LIR), true,
                         kAllocLIR);
-                    newMov16L->generic.dalvikOffset = lir->generic.dalvikOffset;
-                    newMov16L->generic.target = lir->generic.target;
+                    newMov16L->dalvikOffset = lir->dalvikOffset;
+                    newMov16L->target = lir->target;
                     newMov16L->opcode = kThumb2MovImm16LST;
                     newMov16L->operands[0] = lir->operands[0];
                     newMov16L->operands[2] = (intptr_t)lir;
                     newMov16L->operands[3] = (intptr_t)tabRec;
                     oatSetupResourceMasks(newMov16L);
                     oatInsertLIRBefore((LIR*)lir, (LIR*)newMov16L);
-                    ArmLIR *newMov16H =
-                        (ArmLIR *)oatNew(cUnit, sizeof(ArmLIR), true,
+                    LIR *newMov16H =
+                        (LIR *)oatNew(cUnit, sizeof(LIR), true,
                         kAllocLIR);
-                    newMov16H->generic.dalvikOffset = lir->generic.dalvikOffset;
-                    newMov16H->generic.target = lir->generic.target;
+                    newMov16H->dalvikOffset = lir->dalvikOffset;
+                    newMov16H->target = lir->target;
                     newMov16H->opcode = kThumb2MovImm16HST;
                     newMov16H->operands[0] = lir->operands[0];
                     newMov16H->operands[2] = (intptr_t)lir;
@@ -1238,24 +1238,24 @@
                 }
             } else if (lir->opcode == kThumb2MovImm16LST) {
                 // operands[1] should hold disp, [2] has add, [3] has tabRec
-                ArmLIR *addPCInst = (ArmLIR*)lir->operands[2];
+                LIR *addPCInst = (LIR*)lir->operands[2];
                 SwitchTable *tabRec = (SwitchTable*)lir->operands[3];
-                // If tabRec is null, this is a literal load. Use generic.target
-                ArmLIR* target = (ArmLIR*)lir->generic.target;
+                // If tabRec is null, this is a literal load. Use target
+                LIR* target = (LIR*)lir->target;
                 int targetDisp = tabRec ? tabRec->offset
-                                        : target->generic.offset;
+                                        : target->offset;
                 lir->operands[1] = (targetDisp -
-                    (addPCInst->generic.offset + 4)) & 0xffff;
+                    (addPCInst->offset + 4)) & 0xffff;
             } else if (lir->opcode == kThumb2MovImm16HST) {
                 // operands[1] should hold disp, [2] has add, [3] has tabRec
-                ArmLIR *addPCInst = (ArmLIR*)lir->operands[2];
+                LIR *addPCInst = (LIR*)lir->operands[2];
                 SwitchTable *tabRec = (SwitchTable*)lir->operands[3];
-                // If tabRec is null, this is a literal load. Use generic.target
-                ArmLIR* target = (ArmLIR*)lir->generic.target;
+                // If tabRec is null, this is a literal load. Use target
+                LIR* target = (LIR*)lir->target;
                 int targetDisp = tabRec ? tabRec->offset
-                                        : target->generic.offset;
+                                        : target->offset;
                 lir->operands[1] = ((targetDisp -
-                    (addPCInst->generic.offset + 4)) >> 16) & 0xffff;
+                    (addPCInst->offset + 4)) >> 16) & 0xffff;
             }
         }
         /*
@@ -1387,19 +1387,19 @@
  */
 int oatAssignInsnOffsets(CompilationUnit* cUnit)
 {
-    ArmLIR* armLIR;
+    LIR* armLIR;
     int offset = 0;
 
-    for (armLIR = (ArmLIR *) cUnit->firstLIRInsn;
+    for (armLIR = (LIR *) cUnit->firstLIRInsn;
          armLIR;
          armLIR = NEXT_LIR(armLIR)) {
-        armLIR->generic.offset = offset;
+        armLIR->offset = offset;
         if (armLIR->opcode >= 0) {
             if (!armLIR->flags.isNop) {
                 armLIR->flags.size = EncodingMap[armLIR->opcode].size * 2;
                 offset += armLIR->flags.size;
             }
-        } else if (armLIR->opcode == kArmPseudoPseudoAlign4) {
+        } else if (armLIR->opcode == kPseudoPseudoAlign4) {
             if (offset & 0x2) {
                 offset += 2;
                 armLIR->operands[0] = 1;
diff --git a/src/compiler/codegen/arm/Codegen.h b/src/compiler/codegen/arm/Codegen.h
index 8d3c425..a565cb1 100644
--- a/src/compiler/codegen/arm/Codegen.h
+++ b/src/compiler/codegen/arm/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 ArmLIR *opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                        int value);
-STATIC ArmLIR *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);
+
+ArmConditionCode oatArmConditionEncoding(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(ArmLIR* lir);
+extern void oatSetupResourceMasks(LIR* lir);
 
-extern ArmLIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest,
+extern LIR* oatRegCopyNoInsert(CompilationUnit* cUnit, int rDest,
                                           int rSrc);
 
 }  // namespace art
diff --git a/src/compiler/codegen/arm/CodegenCommon.cc b/src/compiler/codegen/arm/CodegenCommon.cc
deleted file mode 100644
index fb6ad30..0000000
--- a/src/compiler/codegen/arm/CodegenCommon.cc
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * Copyright (C) 2011 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
- * ARM 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.
- */
-
-/* Track exercised opcodes */
-static int opcodeCoverage[kNumPackedOpcodes];
-
-STATIC void setMemRefType(ArmLIR* lir, bool isLoad, int memType)
-{
-    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 r5FP +
- * offset.
- */
-STATIC void annotateDalvikRegAccess(ArmLIR* lir, int regId, bool isLoad)
-{
-    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
-     */
-    seed = DOUBLEREG(reg) ? 3 : 1;
-    /* FP register starts at bit position 16 */
-    shift = FPREG(reg) ? kFPReg0 : 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(ArmLIR* lir)
-{
-    int opcode = lir->opcode;
-    int flags;
-
-    if (opcode <= 0) {
-        lir->useMask = lir->defMask = 0;
-        return;
-    }
-
-    flags = EncodingMap[lir->opcode].flags;
-
-    if (flags & NEEDS_FIXUP) {
-        lir->flags.pcRelFixup = true;
-    }
-
-    /* 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 & REG_DEF_FPCS_LIST0) {
-        lir->defMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
-    }
-
-    if (flags & REG_DEF_FPCS_LIST2) {
-        for (int i = 0; i < lir->operands[2]; i++) {
-            setupRegMask(&lir->defMask, lir->operands[1] + i);
-        }
-    }
-
-    if (flags & SETS_CCODES) {
-        lir->defMask |= ENCODE_CCODE;
-    }
-
-    /* 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 & REG_USE_FPCS_LIST0) {
-        lir->useMask |= ENCODE_REG_FPCS_LIST(lir->operands[0]);
-    }
-
-    if (flags & REG_USE_FPCS_LIST2) {
-        for (int i = 0; i < lir->operands[2]; i++) {
-            setupRegMask(&lir->useMask, lir->operands[1] + i);
-        }
-    }
-
-    if (flags & USES_CCODES) {
-        lir->useMask |= ENCODE_CCODE;
-    }
-
-    /* Fixup for kThumbPush/lr and kThumbPop/pc */
-    if (opcode == kThumbPush || opcode == kThumbPop) {
-        u8 r8Mask = getRegMaskCommon(r8);
-        if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) {
-            lir->useMask &= ~r8Mask;
-            lir->useMask |= ENCODE_REG_LR;
-        } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) {
-            lir->defMask &= ~r8Mask;
-            lir->defMask |= ENCODE_REG_PC;
-        }
-    }
-}
-
-/*
- * The following are building blocks to construct low-level IRs with 0 - 4
- * operands.
- */
-STATIC ArmLIR* newLIR0(CompilationUnit* cUnit, ArmOpcode opcode)
-{
-    ArmLIR* insn = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), 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;
-}
-
-STATIC ArmLIR* newLIR1(CompilationUnit* cUnit, ArmOpcode opcode,
-                           int dest)
-{
-    ArmLIR* insn = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), 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;
-}
-
-STATIC ArmLIR* newLIR2(CompilationUnit* cUnit, ArmOpcode opcode,
-                           int dest, int src1)
-{
-    ArmLIR* insn = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), 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;
-}
-
-STATIC ArmLIR* newLIR3(CompilationUnit* cUnit, ArmOpcode opcode,
-                           int dest, int src1, int src2)
-{
-    ArmLIR* insn = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpcode(opcode) ||
-           (EncodingMap[opcode].flags & IS_TERTIARY_OP))
-            << (int)opcode << " "
-            << PrettyMethod(cUnit->method_idx, *cUnit->dex_file) << " "
-            << cUnit->currentDalvikOffset;
-    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;
-}
-
-#if defined(_ARMV7_A) || defined(_ARMV7_A_NEON)
-STATIC ArmLIR* newLIR4(CompilationUnit* cUnit, ArmOpcode opcode,
-                           int dest, int src1, int src2, int info)
-{
-    ArmLIR* insn = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), 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;
-}
-#endif
-
-/*
- * Search the existing constants in the literal pool for an exact or close match
- * within specified delta (greater or equal to 0).
- */
-STATIC ArmLIR* scanLiteralPool(LIR* dataTarget, int value, unsigned int delta)
-{
-    while (dataTarget) {
-        if (((unsigned) (value - ((ArmLIR* ) dataTarget)->operands[0])) <=
-            delta)
-            return (ArmLIR* ) dataTarget;
-        dataTarget = dataTarget->next;
-    }
-    return NULL;
-}
-
-/* Search the existing constants in the literal pool for an exact wide match */
-STATIC ArmLIR* scanLiteralPoolWide(LIR* dataTarget, int valLo, int valHi)
-{
-    bool loMatch = false;
-    LIR* loTarget = NULL;
-    while (dataTarget) {
-        if (loMatch && (((ArmLIR*)dataTarget)->operands[0] == valHi)) {
-            return (ArmLIR*)loTarget;
-        }
-        loMatch = false;
-        if (((ArmLIR*)dataTarget)->operands[0] == valLo) {
-            loMatch = true;
-            loTarget = dataTarget;
-        }
-        dataTarget = dataTarget->next;
-    }
-    return NULL;
-}
-
-/*
- * The following are building blocks to insert constants into the pool or
- * instruction streams.
- */
-
-/* Add a 32-bit constant either in the constant pool or mixed with code */
-STATIC ArmLIR* addWordData(CompilationUnit* cUnit, LIR* *constantListP,
-                           int value)
-{
-    /* Add the constant to the literal pool */
-    if (constantListP) {
-        ArmLIR* newValue = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true,
-                                             kAllocData);
-        newValue->operands[0] = value;
-        newValue->generic.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;
-}
-
-/* Add a 64-bit constant to the constant pool or mixed with code */
-STATIC ArmLIR* addWideData(CompilationUnit* cUnit, LIR* *constantListP,
-                           int valLo, int valHi)
-{
-    ArmLIR* res;
-    //NOTE: hard-coded little endian
-    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;
-}
-
-/*
- * Generate an kArmPseudoBarrier marker to indicate the boundary of special
- * blocks.
- */
-STATIC void genBarrier(CompilationUnit* cUnit)
-{
-    ArmLIR* barrier = newLIR0(cUnit, kArmPseudoBarrier);
-    /* Mark all resources as being clobbered */
-    barrier->defMask = -1;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/FP/Thumb2VFP.cc b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
index 494e09f..094b952 100644
--- a/src/compiler/codegen/arm/FP/Thumb2VFP.cc
+++ b/src/compiler/codegen/arm/FP/Thumb2VFP.cc
@@ -16,9 +16,8 @@
 
 namespace art {
 
-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)
 {
     int op = kThumbBkpt;
     RegLocation rlResult;
@@ -62,9 +61,8 @@
     return false;
 }
 
-STATIC bool genArithOpDouble(CompilationUnit* cUnit, MIR* mir,
-                             RegLocation rlDest, RegLocation rlSrc1,
-                             RegLocation rlSrc2)
+bool genArithOpDouble(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                      RegLocation rlSrc1, RegLocation rlSrc2)
 {
     int op = kThumbBkpt;
     RegLocation rlResult;
@@ -110,7 +108,7 @@
     return false;
 }
 
-STATIC bool genConversion(CompilationUnit* cUnit, MIR* mir)
+bool genConversion(CompilationUnit* cUnit, MIR* mir)
 {
     Opcode opcode = mir->dalvikInsn.opcode;
     int op = kThumbBkpt;
@@ -184,8 +182,8 @@
     return false;
 }
 
-STATIC bool genCmpFP(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                     RegLocation rlSrc1, RegLocation rlSrc2)
+bool genCmpFP(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+              RegLocation rlSrc1, RegLocation rlSrc2)
 {
     bool isDouble;
     int defaultResult;
diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/Thumb2/Factory.cc
index 0a43aae..77d6066 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/Thumb2/Factory.cc
@@ -35,7 +35,7 @@
 static int fpTemps[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
                         fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15};
 
-STATIC int encodeImmSingle(int value)
+int encodeImmSingle(int value)
 {
     int res;
     int bitA =    (value & 0x80000000) >> 31;
@@ -57,23 +57,22 @@
     return res;
 }
 
-STATIC ArmLIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest,
-                                   int value)
+LIR* loadFPConstantValue(CompilationUnit* cUnit, int rDest, int value)
 {
     int encodedImm = encodeImmSingle(value);
     DCHECK(SINGLEREG(rDest));
     if (encodedImm >= 0) {
         return newLIR2(cUnit, kThumb2Vmovs_IMM8, rDest, encodedImm);
     }
-    ArmLIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
+    LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
     if (dataTarget == NULL) {
         dataTarget = addWordData(cUnit, &cUnit->literalList, value);
     }
-    ArmLIR* loadPcRel = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true,
+    LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true,
                                           kAllocLIR);
-    loadPcRel->generic.dalvikOffset = cUnit->currentDalvikOffset;
+    loadPcRel->dalvikOffset = cUnit->currentDalvikOffset;
     loadPcRel->opcode = kThumb2Vldrs;
-    loadPcRel->generic.target = (LIR* ) dataTarget;
+    loadPcRel->target = (LIR* ) dataTarget;
     loadPcRel->operands[0] = rDest;
     loadPcRel->operands[1] = r15pc;
     setupResourceMasks(loadPcRel);
@@ -83,7 +82,7 @@
     return loadPcRel;
 }
 
-STATIC int leadingZeros(u4 val)
+int leadingZeros(u4 val)
 {
     u4 alt;
     int n;
@@ -106,7 +105,7 @@
  * Determine whether value can be encoded as a Thumb2 modified
  * immediate.  If not, return -1.  If so, return i:imm3:a:bcdefgh form.
  */
-STATIC int modifiedImmediate(u4 value)
+int modifiedImmediate(u4 value)
 {
    int zLeading;
    int zTrailing;
@@ -144,10 +143,9 @@
  * 1) rDest is freshly returned from oatAllocTemp or
  * 2) The codegen is under fixed register usage
  */
-STATIC ArmLIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest,
-                                     int value)
+LIR* loadConstantNoClobber(CompilationUnit* cUnit, int rDest, int value)
 {
-    ArmLIR* res;
+    LIR* res;
     int modImm;
 
     if (FPREG(rDest)) {
@@ -175,15 +173,15 @@
         return res;
     }
     /* No shortcut - go ahead and use literal pool */
-    ArmLIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
+    LIR* dataTarget = scanLiteralPool(cUnit->literalList, value, 0);
     if (dataTarget == NULL) {
         dataTarget = addWordData(cUnit, &cUnit->literalList, value);
     }
-    ArmLIR* loadPcRel = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true,
+    LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true,
                                           kAllocLIR);
     loadPcRel->opcode = kThumb2LdrPcRel12;
-    loadPcRel->generic.target = (LIR* ) dataTarget;
-    loadPcRel->generic.dalvikOffset = cUnit->currentDalvikOffset;
+    loadPcRel->target = (LIR* ) dataTarget;
+    loadPcRel->dalvikOffset = cUnit->currentDalvikOffset;
     loadPcRel->operands[0] = rDest;
     setupResourceMasks(loadPcRel);
     setMemRefType(loadPcRel, true, kLiteral);
@@ -201,20 +199,7 @@
     return res;
 }
 
-/*
- * Load an immediate value into a fixed or temp register.  Target
- * register is clobbered, and marked inUse.
- */
-STATIC ArmLIR* loadConstant(CompilationUnit* cUnit, int rDest, int value)
-{
-    if (oatIsTemp(cUnit, rDest)) {
-        oatClobber(cUnit, rDest);
-        oatMarkInUse(cUnit, rDest);
-    }
-    return loadConstantNoClobber(cUnit, rDest, value);
-}
-
-STATIC ArmLIR* opNone(CompilationUnit* cUnit, OpKind op)
+LIR* opNone(CompilationUnit* cUnit, OpKind op)
 {
     ArmOpcode opcode = kThumbBkpt;
     switch (op) {
@@ -227,12 +212,13 @@
     return newLIR0(cUnit, opcode);
 }
 
-STATIC ArmLIR* opCondBranch(CompilationUnit* cUnit, ArmConditionCode cc)
+LIR* opCondBranch(CompilationUnit* cUnit, ConditionCode cc)
 {
-    return newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */, cc);
+    return newLIR2(cUnit, kThumb2BCond, 0 /* offset to be patched */,
+                   oatArmConditionEncoding(cc));
 }
 
-STATIC ArmLIR* opReg(CompilationUnit* cUnit, OpKind op, int rDestSrc)
+LIR* opReg(CompilationUnit* cUnit, OpKind op, int rDestSrc)
 {
     ArmOpcode opcode = kThumbBkpt;
     switch (op) {
@@ -245,8 +231,8 @@
     return newLIR1(cUnit, opcode, rDestSrc);
 }
 
-STATIC ArmLIR* opRegRegShift(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                             int rSrc2, int shift)
+LIR* opRegRegShift(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
+                   int rSrc2, int shift)
 {
     bool thumbForm = ((shift == 0) && LOWREG(rDestSrc1) && LOWREG(rSrc2));
     ArmOpcode opcode = kThumbBkpt;
@@ -361,14 +347,13 @@
     }
 }
 
-STATIC ArmLIR* opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                        int rSrc2)
+LIR* opRegReg(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int rSrc2)
 {
     return opRegRegShift(cUnit, op, rDestSrc1, rSrc2, 0);
 }
 
-STATIC ArmLIR* opRegRegRegShift(CompilationUnit* cUnit, OpKind op,
-                                int rDest, int rSrc1, int rSrc2, int shift)
+LIR* opRegRegRegShift(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
+                      int rSrc2, int shift)
 {
     ArmOpcode opcode = kThumbBkpt;
     bool thumbForm = (shift == 0) && LOWREG(rDest) && LOWREG(rSrc1) &&
@@ -431,16 +416,16 @@
     }
 }
 
-STATIC ArmLIR* opRegRegReg(CompilationUnit* cUnit, OpKind op, int rDest,
-                           int rSrc1, int rSrc2)
+LIR* opRegRegReg(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
+                 int rSrc2)
 {
     return opRegRegRegShift(cUnit, op, rDest, rSrc1, rSrc2, 0);
 }
 
-STATIC ArmLIR* opRegRegImm(CompilationUnit* cUnit, OpKind op, int rDest,
-                           int rSrc1, int value)
+LIR* opRegRegImm(CompilationUnit* cUnit, OpKind op, int rDest, int rSrc1,
+                 int value)
 {
-    ArmLIR* res;
+    LIR* res;
     bool neg = (value < 0);
     int absValue = (neg) ? -value : value;
     ArmOpcode opcode = kThumbBkpt;
@@ -531,7 +516,7 @@
             break;
         case kOpCmp: {
             int modImm = modifiedImmediate(value);
-            ArmLIR* res;
+            LIR* res;
             if (modImm >= 0) {
                 res = newLIR2(cUnit, kThumb2CmpRI8, rSrc1, modImm);
             } else {
@@ -561,8 +546,7 @@
 }
 
 /* Handle Thumb-only variants here - otherwise punt to opRegRegImm */
-STATIC ArmLIR* opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1,
-                        int value)
+LIR* opRegImm(CompilationUnit* cUnit, OpKind op, int rDestSrc1, int value)
 {
     bool neg = (value < 0);
     int absValue = (neg) ? -value : value;
@@ -611,7 +595,7 @@
  * Determine whether value can be encoded as a Thumb2 floating point
  * immediate.  If not, return -1.  If so return encoded 8-bit value.
  */
-STATIC int encodeImmDoubleHigh(int value)
+int encodeImmDoubleHigh(int value)
 {
     int res;
     int bitA =    (value & 0x80000000) >> 31;
@@ -633,7 +617,7 @@
     return res;
 }
 
-STATIC int encodeImmDouble(int valLo, int valHi)
+int encodeImmDouble(int valLo, int valHi)
 {
     int res = -1;
     if (valLo == 0)
@@ -641,27 +625,27 @@
     return res;
 }
 
-STATIC ArmLIR* loadConstantValueWide(CompilationUnit* cUnit, int rDestLo,
-                                     int rDestHi, int valLo, int valHi)
+LIR* loadConstantValueWide(CompilationUnit* cUnit, int rDestLo, int rDestHi,
+                           int valLo, int valHi)
 {
     int encodedImm = encodeImmDouble(valLo, valHi);
-    ArmLIR* res;
+    LIR* res;
     if (FPREG(rDestLo)) {
         if (encodedImm >= 0) {
             res = newLIR2(cUnit, kThumb2Vmovd_IMM8, S2D(rDestLo, rDestHi),
                           encodedImm);
         } else {
-            ArmLIR* dataTarget = scanLiteralPoolWide(cUnit->literalList, valLo,
+            LIR* dataTarget = scanLiteralPoolWide(cUnit->literalList, valLo,
                valHi);
             if (dataTarget == NULL) {
                 dataTarget = addWideData(cUnit, &cUnit->literalList, valLo,
                                          valHi);
             }
-            ArmLIR* loadPcRel = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true,
+            LIR* loadPcRel = (LIR* ) oatNew(cUnit, sizeof(LIR), true,
                                                   kAllocLIR);
-            loadPcRel->generic.dalvikOffset = cUnit->currentDalvikOffset;
+            loadPcRel->dalvikOffset = cUnit->currentDalvikOffset;
             loadPcRel->opcode = kThumb2Vldrd;
-            loadPcRel->generic.target = (LIR* ) dataTarget;
+            loadPcRel->target = (LIR* ) dataTarget;
             loadPcRel->operands[0] = S2D(rDestLo, rDestHi);
             loadPcRel->operands[1] = r15pc;
             setupResourceMasks(loadPcRel);
@@ -677,15 +661,15 @@
     return res;
 }
 
-STATIC int encodeShift(int code, int amount) {
+int encodeShift(int code, int amount) {
     return ((amount & 0x1f) << 2) | code;
 }
 
-STATIC ArmLIR* loadBaseIndexed(CompilationUnit* cUnit, int rBase,
-                               int rIndex, int rDest, int scale, OpSize size)
+LIR* loadBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rDest,
+                     int scale, OpSize size)
 {
     bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rDest);
-    ArmLIR* load;
+    LIR* load;
     ArmOpcode opcode = kThumbBkpt;
     bool thumbForm = (allLowRegs && (scale == 0));
     int regPtr;
@@ -745,11 +729,11 @@
     return load;
 }
 
-STATIC ArmLIR* storeBaseIndexed(CompilationUnit* cUnit, int rBase,
-                                int rIndex, int rSrc, int scale, OpSize size)
+LIR* storeBaseIndexed(CompilationUnit* cUnit, int rBase, int rIndex, int rSrc,
+                      int scale, OpSize size)
 {
     bool allLowRegs = LOWREG(rBase) && LOWREG(rIndex) && LOWREG(rSrc);
-    ArmLIR* store;
+    LIR* store;
     ArmOpcode opcode = kThumbBkpt;
     bool thumbForm = (allLowRegs && (scale == 0));
     int regPtr;
@@ -810,12 +794,12 @@
  * on base (which must have an associated sReg and MIR).  If not
  * performing null check, incoming MIR can be null.
  */
-STATIC ArmLIR* loadBaseDispBody(CompilationUnit* cUnit, MIR* mir, int rBase,
-                                int displacement, int rDest, int rDestHi,
-                                OpSize size, int sReg)
+LIR* loadBaseDispBody(CompilationUnit* cUnit, MIR* mir, int rBase,
+                      int displacement, int rDest, int rDestHi, OpSize size,
+                      int sReg)
 {
-    ArmLIR* res;
-    ArmLIR* load;
+    LIR* res;
+    LIR* load;
     ArmOpcode opcode = kThumbBkpt;
     bool shortForm = false;
     bool thumb2Form = (displacement < 4092 && displacement >= 0);
@@ -925,28 +909,25 @@
     return load;
 }
 
-STATIC ArmLIR* loadBaseDisp(CompilationUnit* cUnit, MIR* mir, int rBase,
-                            int displacement, int rDest, OpSize size,
-                            int sReg)
+LIR* loadBaseDisp(CompilationUnit* cUnit, MIR* mir, int rBase,
+                  int displacement, int rDest, OpSize size, int sReg)
 {
     return loadBaseDispBody(cUnit, mir, rBase, displacement, rDest, -1,
                             size, sReg);
 }
 
-STATIC  ArmLIR* loadBaseDispWide(CompilationUnit* cUnit, MIR* mir, int rBase,
-                                 int displacement, int rDestLo, int rDestHi,
-                                 int sReg)
+ LIR* loadBaseDispWide(CompilationUnit* cUnit, MIR* mir, int rBase,
+                       int displacement, int rDestLo, int rDestHi, int sReg)
 {
     return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
                             kLong, sReg);
 }
 
 
-STATIC ArmLIR* storeBaseDispBody(CompilationUnit* cUnit, int rBase,
-                                 int displacement, int rSrc, int rSrcHi,
-                                 OpSize size)
+LIR* storeBaseDispBody(CompilationUnit* cUnit, int rBase, int displacement,
+                       int rSrc, int rSrcHi, OpSize size)
 {
-    ArmLIR* res, *store;
+    LIR* res, *store;
     ArmOpcode opcode = kThumbBkpt;
     bool shortForm = false;
     bool thumb2Form = (displacement < 4092 && displacement >= 0);
@@ -1035,63 +1016,32 @@
     return res;
 }
 
-STATIC ArmLIR* storeBaseDisp(CompilationUnit* cUnit, int rBase,
-                             int displacement, int rSrc, OpSize size)
+LIR* storeBaseDisp(CompilationUnit* cUnit, int rBase, int displacement,
+                   int rSrc, OpSize size)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
 }
 
-STATIC ArmLIR* storeBaseDispWide(CompilationUnit* cUnit, int rBase,
-                                 int displacement, int rSrcLo, int rSrcHi)
+LIR* storeBaseDispWide(CompilationUnit* cUnit, int rBase, int displacement,
+                       int rSrcLo, int rSrcHi)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
 }
 
-STATIC void storePair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
+void storePair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
 {
     storeBaseDispWide(cUnit, base, 0, lowReg, highReg);
 }
 
-STATIC void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
+void loadPair(CompilationUnit* cUnit, int base, int lowReg, int highReg)
 {
     loadBaseDispWide(cUnit, NULL, base, 0, lowReg, highReg, INVALID_SREG);
 }
 
-/*
- * Generate a register comparison to an immediate and branch.  Caller
- * is responsible for setting branch target field.
- */
-STATIC ArmLIR* genCmpImmBranch(CompilationUnit* cUnit,
-                              ArmConditionCode cond, int reg,
-                              int checkValue)
+LIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
 {
-    ArmLIR* branch;
-    int modImm;
-    if ((LOWREG(reg)) && (checkValue == 0) &&
-       ((cond == kArmCondEq) || (cond == kArmCondNe))) {
-        branch = newLIR2(cUnit,
-                         (cond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
-                         reg, 0);
-    } else {
-        modImm = modifiedImmediate(checkValue);
-        if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
-            newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
-        } else if (modImm >= 0) {
-            newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
-        } else {
-            int tReg = oatAllocTemp(cUnit);
-            loadConstant(cUnit, tReg, checkValue);
-            opRegReg(cUnit, kOpCmp, reg, tReg);
-        }
-        branch = newLIR2(cUnit, kThumbBCond, 0, cond);
-    }
-    return branch;
-}
-
-STATIC ArmLIR* fpRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
-{
-    ArmLIR* res = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    res->generic.dalvikOffset = cUnit->currentDalvikOffset;
+    LIR* res = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    res->dalvikOffset = cUnit->currentDalvikOffset;
     res->operands[0] = rDest;
     res->operands[1] = rSrc;
     if (rDest == rSrc) {
@@ -1115,67 +1065,6 @@
     return res;
 }
 
-STATIC ArmLIR* genRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
-{
-    ArmLIR* res;
-    ArmOpcode opcode;
-    if (FPREG(rDest) || FPREG(rSrc))
-        return fpRegCopy(cUnit, rDest, rSrc);
-    res = (ArmLIR* ) oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    res->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    if (LOWREG(rDest) && LOWREG(rSrc))
-        opcode = kThumbMovRR;
-    else if (!LOWREG(rDest) && !LOWREG(rSrc))
-         opcode = kThumbMovRR_H2H;
-    else if (LOWREG(rDest))
-         opcode = kThumbMovRR_H2L;
-    else
-         opcode = kThumbMovRR_L2H;
 
-    res->operands[0] = rDest;
-    res->operands[1] = rSrc;
-    res->opcode = opcode;
-    setupResourceMasks(res);
-    if (rDest == rSrc) {
-        res->flags.isNop = true;
-    }
-    return res;
-}
-
-STATIC ArmLIR* genRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
-{
-    ArmLIR* res = genRegCopyNoInsert(cUnit, rDest, rSrc);
-    oatAppendLIR(cUnit, (LIR*)res);
-    return res;
-}
-
-STATIC void genRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
-                           int srcLo, int srcHi)
-{
-    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 {
-            newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
-        }
-    } else {
-        if (srcFP) {
-            newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
-        } else {
-            // Handle overlap
-            if (srcHi == destLo) {
-                genRegCopy(cUnit, destHi, srcHi);
-                genRegCopy(cUnit, destLo, srcLo);
-            } else {
-                genRegCopy(cUnit, destLo, srcLo);
-                genRegCopy(cUnit, destHi, srcHi);
-            }
-        }
-    }
-}
 
 }  // namespace art
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
index e20e19b..1dfb90d 100644
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ b/src/compiler/codegen/arm/Thumb2/Gen.cc
@@ -26,51 +26,6 @@
 
 namespace art {
 
-/*
- * 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.
- */
-STATIC inline RegisterClass oatRegClassBySize(OpSize size)
-{
-    return (size == kUnsignedHalf ||
-            size == kSignedHalf ||
-            size == kUnsignedByte ||
-            size == kSignedByte ) ? kCoreReg : kAnyReg;
-}
-
-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
 
 /*
  * Generate a Thumb2 IT instruction, which can nullify up to
@@ -82,8 +37,7 @@
  * met, and an "E" means the instruction is executed if the condition
  * is not met.
  */
-STATIC ArmLIR* genIT(CompilationUnit* cUnit, ArmConditionCode code,
-                     const char* guide)
+LIR* genIT(CompilationUnit* cUnit, ArmConditionCode code, const char* guide)
 {
     int mask;
     int condBit = code & 1;
@@ -112,118 +66,6 @@
 }
 
 /*
- * Insert a kArmPseudoCaseLabel 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 ArmLIR* 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;
-    }
-    ArmLIR* newLabel = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    newLabel->generic.dalvikOffset = vaddr;
-    newLabel->opcode = kArmPseudoCaseLabel;
-    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.
  * This means that the register number of the temp we use for the key
@@ -242,8 +84,7 @@
  *   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)
 {
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     if (cUnit->printMe) {
@@ -255,8 +96,8 @@
     tabRec->table = table;
     tabRec->vaddr = mir->offset;
     int size = table[1];
-    tabRec->targets = (ArmLIR* *)oatNew(cUnit, size * sizeof(ArmLIR*), true,
-                                        kAllocLIR);
+    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
+                                     kAllocLIR);
     oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
 
     // Get the switch value
@@ -277,24 +118,23 @@
     int rIdx = oatAllocTemp(cUnit);
     loadConstant(cUnit, rIdx, size);
     // Establish loop branch target
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
+    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, kArmCondEq, "");
-    ArmLIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
+    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
     tabRec->bxInst = switchBranch;
     // Needs to use setflags encoding here
     newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
-    ArmLIR* branch = opCondBranch(cUnit, kArmCondNe);
-    branch->generic.target = (LIR*)target;
+    LIR* branch = opCondBranch(cUnit, kCondNe);
+    branch->target = (LIR*)target;
 }
 
 
-STATIC void genPackedSwitch(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlSrc)
+void genPackedSwitch(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     if (cUnit->printMe) {
@@ -306,7 +146,7 @@
     tabRec->table = table;
     tabRec->vaddr = mir->offset;
     int size = table[1];
-    tabRec->targets = (ArmLIR* *)oatNew(cUnit, size * sizeof(ArmLIR*), true,
+    tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true,
                                         kAllocLIR);
     oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
 
@@ -326,20 +166,20 @@
     }
     // Bounds check - if < 0 or >= size continue following switch
     opRegImm(cUnit, kOpCmp, keyReg, size-1);
-    ArmLIR* branchOver = opCondBranch(cUnit, kArmCondHi);
+    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
-    ArmLIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
+    LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
     tabRec->bxInst = switchBranch;
 
     /* branchOver target here */
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
+    LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
-    branchOver->generic.target = (LIR*)target;
+    branchOver->target = (LIR*)target;
 }
 
 /*
@@ -352,8 +192,7 @@
  *
  * 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)
 {
     const u2* table = cUnit->insns + mir->offset + mir->dalvikInsn.vB;
     // Add the table to the list - we'll process it later
@@ -377,413 +216,7 @@
     callRuntimeHelper(cUnit, rLR);
 }
 
-STATIC void genIGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                    RegLocation rlDest, RegLocation rlObj,
-                    bool isLongOrDouble, bool isObject)
-{
-    int fieldOffset;
-    bool isVolatile;
-    uint32_t fieldIdx = mir->dalvikInsn.vC;
-
-    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
-                             *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
-                             cUnit->method_idx, cUnit->access_flags);
-
-    bool fastPath =
-        cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
-                                                  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);
-        }
-    }
-}
-
-STATIC void genIPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                    RegLocation rlSrc, RegLocation rlObj,
-                    bool isLongOrDouble, bool isObject)
-{
-    int fieldOffset;
-    bool isVolatile;
-    uint32_t fieldIdx = mir->dalvikInsn.vC;
-
-    OatCompilationUnit mUnit(cUnit->class_loader, cUnit->class_linker,
-                             *cUnit->dex_file, *cUnit->dex_cache, cUnit->code_item,
-                             cUnit->method_idx, cUnit->access_flags);
-
-    bool fastPath =
-        cUnit->compiler->ComputeInstanceFieldInfo(fieldIdx, &mUnit,
-                                                  fieldOffset, isVolatile, true);
-    if (fastPath && !SLOW_FIELD_PATH) {
-        RegisterClass regClass = oatRegClassBySize(size);
-        DCHECK_GE(fieldOffset, 0);
-        rlObj = loadValue(cUnit, rlObj, kCoreReg);
-        if (isLongOrDouble) {
-            int regPtr;
-            rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
-            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null obj? */
-            regPtr = oatAllocTemp(cUnit);
-            opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kST);
-            }
-            storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kSY);
-            }
-            oatFreeTemp(cUnit, regPtr);
-        } else {
-            rlSrc = loadValue(cUnit, rlSrc, regClass);
-            genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir);/* null obj? */
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kST);
-            }
-            storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, kWord);
-            if (isVolatile) {
-                oatGenMemBarrier(cUnit, kSY);
-            }
-        }
-    } else {
-        int setterOffset = isLongOrDouble ? OFFSETOF_MEMBER(Thread, pSet64Instance) :
-                           (isObject ? OFFSETOF_MEMBER(Thread, pSetObjInstance)
-                                     : OFFSETOF_MEMBER(Thread, pSet32Instance));
-        loadWordDisp(cUnit, rSELF, setterOffset, rLR);
-        loadValueDirect(cUnit, rlObj, r1);
-        if (isLongOrDouble) {
-            loadValueDirectWide(cUnit, rlSrc, r2, r3);
-        } else {
-            loadValueDirect(cUnit, rlSrc, r2);
-        }
-        loadConstant(cUnit, r0, fieldIdx);
-        callRuntimeHelper(cUnit, rLR);
-    }
-}
-
-STATIC void genConstClass(CompilationUnit* cUnit, MIR* mir,
-                          RegLocation rlDest, RegLocation rlSrc)
-{
-    uint32_t type_idx = mir->dalvikInsn.vB;
-    int mReg = loadCurrMethod(cUnit);
-    int resReg = oatAllocTemp(cUnit);
-    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    if (!cUnit->compiler->CanAccessTypeWithoutChecks(cUnit->method_idx,
-                                                     cUnit->dex_cache,
-                                                     *cUnit->dex_file,
-                                                     type_idx)) {
-        // Call out to helper which resolves type and verifies access.
-        // Resolved type returned in r0.
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
-                     rLR);
-        genRegCopy(cUnit, r1, mReg);
-        loadConstant(cUnit, r0, type_idx);
-        callRuntimeHelper(cUnit, rLR);
-        RegLocation rlResult = oatGetReturn(cUnit);
-        storeValue(cUnit, rlDest, rlResult);
-    } else {
-        // We're don't need access checks, load type from dex cache
-        int32_t dex_cache_offset = Method::DexCacheResolvedTypesOffset().Int32Value();
-        loadWordDisp(cUnit, mReg, dex_cache_offset, resReg);
-        int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() +
-                                 (sizeof(Class*) * type_idx);
-        loadWordDisp(cUnit, resReg, offset_of_type, rlResult.lowReg);
-        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache,
-                                                               type_idx) ||
-            SLOW_TYPE_PATH) {
-            // Slow path, at runtime test if the type is null and if so initialize
-            oatFlushAllRegs(cUnit);
-            ArmLIR* branch1 = genCmpImmBranch(cUnit, kArmCondEq, rlResult.lowReg, 0);
-            // Resolved, store and hop over following code
-            storeValue(cUnit, rlDest, rlResult);
-            ArmLIR* branch2 = genUnconditionalBranch(cUnit,0);
-            // TUNING: move slow path to end & remove unconditional branch
-            ArmLIR* target1 = newLIR0(cUnit, kArmPseudoTargetLabel);
-            target1->defMask = ENCODE_ALL;
-            // Call out to helper, which will return resolved type in r0
-            loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInitializeTypeFromCode), rLR);
-            genRegCopy(cUnit, r1, mReg);
-            loadConstant(cUnit, r0, type_idx);
-            callRuntimeHelper(cUnit, rLR);
-            RegLocation rlResult = oatGetReturn(cUnit);
-            storeValue(cUnit, rlDest, rlResult);
-            // Rejoin code paths
-            ArmLIR* target2 = newLIR0(cUnit, kArmPseudoTargetLabel);
-            target2->defMask = ENCODE_ALL;
-            branch1->generic.target = (LIR*)target1;
-            branch2->generic.target = (LIR*)target2;
-        } else {
-            // Fast path, we're done - just store result
-            storeValue(cUnit, rlDest, rlResult);
-        }
-    }
-}
-
-/*
- * Generate callout to updateDebugger. Note: genIT will automatically
- * create a scheduling barrier, which we need to prevent code motion that
- * might confuse the debugger.  Note: Return registers r0/r1 are
- * handled specially during code generation following function calls.
- * Typically, temp registers are not live between opcodes, but we keep
- * r0/r1 live following invokes, where they are consumed by the immediately
- * following op_move_result_xxx.  Thus, we must preserve and restore r0/r1
- * when making a call to update the debugger.  This is handled by the stub.
- */
-STATIC void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset)
-{
-    // Following DCHECK verifies that dPC is in range of single load immediate
-    DCHECK((offset == DEBUGGER_METHOD_ENTRY) ||
-           (offset == DEBUGGER_METHOD_EXIT) || ((offset & 0xffff) == offset));
-    oatClobberCalleeSave(cUnit);
-    opRegImm(cUnit, kOpCmp, rSUSPEND, 0);
-    genIT(cUnit, kArmCondNe, "T");
-    loadConstant(cUnit, r2, offset);     // arg2 <- Entry code
-    opReg(cUnit, kOpBlx, rSUSPEND);
-    oatFreeTemp(cUnit, r2);
-}
-
-STATIC void genConstString(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc)
-{
-    /* NOTE: Most strings should be available at compile time */
-    uint32_t string_idx = mir->dalvikInsn.vB;
-    int32_t offset_of_string = Array::DataOffset(sizeof(String*)).Int32Value() +
-                               (sizeof(String*) * string_idx);
-    if (!cUnit->compiler->CanAssumeStringIsPresentInDexCache(cUnit->dex_cache, string_idx) ||
-        SLOW_STRING_PATH) {
-        // slow path, resolve string if not in dex cache
-        oatFlushAllRegs(cUnit);
-        oatLockCallTemps(cUnit); // Using explicit registers
-        loadCurrMethodDirect(cUnit, r2);
-        loadWordDisp(cUnit, r2, Method::DexCacheStringsOffset().Int32Value(), r0);
-        // Might call out to helper, which will return resolved string in r0
-        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pResolveStringFromCode), rLR);
-        loadWordDisp(cUnit, r0, offset_of_string, r0);
-        loadConstant(cUnit, r1, string_idx);
-        opRegImm(cUnit, kOpCmp, r0, 0);  // Is resolved?
-        genBarrier(cUnit);
-        // For testing, always force through helper
-        if (!EXERCISE_SLOWEST_STRING_PATH) {
-            genIT(cUnit, kArmCondEq, "T");
-        }
-        genRegCopy(cUnit, r0, r2);       // .eq
-        opReg(cUnit, kOpBlx, rLR);       // .eq, helper(Method*, string_idx)
-        genBarrier(cUnit);
-        storeValue(cUnit, rlDest, getRetLoc(cUnit));
-    } else {
-        int mReg = loadCurrMethod(cUnit);
-        int resReg = oatAllocTemp(cUnit);
-        RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-        loadWordDisp(cUnit, mReg, Method::DexCacheStringsOffset().Int32Value(), resReg);
-        loadWordDisp(cUnit, resReg, offset_of_string, rlResult.lowReg);
-        storeValue(cUnit, rlDest, rlResult);
-    }
-}
-
-/*
- * Let helper function take care of everything.  Will
- * call Class::NewInstanceFromCode(type_idx, method);
- */
-STATIC void genNewInstance(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest)
-{
-    oatFlushAllRegs(cUnit);    /* Everything to home location */
-    uint32_t type_idx = mir->dalvikInsn.vB;
-    // alloc will always check for resolution, do we also need to verify access because the
-    // verifier was unable to?
-    if (cUnit->compiler->CanAccessInstantiableTypeWithoutChecks(cUnit->method_idx,
-                                                                cUnit->dex_cache,
-                                                                *cUnit->dex_file,
-                                                                type_idx)) {
-        loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pAllocObjectFromCode), rLR);
-    } else {
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pAllocObjectFromCodeWithAccessCheck), rLR);
-    }
-    loadCurrMethodDirect(cUnit, r1);    // arg1 <= Method*
-    loadConstant(cUnit, r0, type_idx);  // arg0 <- type_idx
-    callRuntimeHelper(cUnit, rLR);
-    RegLocation rlResult = oatGetReturn(cUnit);
-    storeValue(cUnit, rlDest, rlResult);
-}
-
-void genThrow(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
-{
-    oatFlushAllRegs(cUnit);
-    loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pDeliverException), rLR);
-    loadValueDirectFixed(cUnit, rlSrc, r0);  // Get exception object
-    callRuntimeHelper(cUnit, rLR);  // art_deliver_exception(exception);
-}
-
-STATIC void genInstanceof(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
-                          RegLocation rlSrc)
-{
-    oatFlushAllRegs(cUnit);
-    // May generate a call - use explicit registers
-    oatLockCallTemps(cUnit);
-    uint32_t type_idx = mir->dalvikInsn.vC;
-    loadCurrMethodDirect(cUnit, r1);  // r1 <= current Method*
-    int classReg = r2;  // r2 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
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
-                     rLR);
-        loadConstant(cUnit, r0, type_idx);
-        callRuntimeHelper(cUnit, rLR);  // InitializeTypeAndVerifyAccess(idx, method)
-        genRegCopy(cUnit, classReg, r0);  // Align usage with fast path
-        loadValueDirectFixed(cUnit, rlSrc, r0);  // r0 <= ref
-    } else {
-        // Load dex cache entry into classReg (r2)
-        loadValueDirectFixed(cUnit, rlSrc, r0);  // r0 <= ref
-        loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
-        int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() +
-                                 (sizeof(Class*) * type_idx);
-        loadWordDisp(cUnit, classReg, offset_of_type, classReg);
-        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) {
-            // Need to test presence of type in dex cache at runtime
-            ArmLIR* hopBranch = genCmpImmBranch(cUnit, kArmCondNe, 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, r2, r0); // Align usage with fast path
-            loadValueDirectFixed(cUnit, rlSrc, r0);  /* reload Ref */
-            // Rejoin code paths
-            ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
-            hopTarget->defMask = ENCODE_ALL;
-            hopBranch->generic.target = (LIR*)hopTarget;
-        }
-    }
-    /* r0 is ref, r2 is class.  If ref==null, use directly as bool result */
-    ArmLIR* branch1 = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
-    /* load object->clazz */
-    DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
-    loadWordDisp(cUnit, r0,  Object::ClassOffset().Int32Value(), r1);
-    /* r0 is ref, r1 is ref->clazz, r2 is class */
-    loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pInstanceofNonTrivialFromCode), rLR);
-    opRegReg(cUnit, kOpCmp, r1, r2);  // Same?
-    genBarrier(cUnit);
-    genIT(cUnit, kArmCondEq, "EE");   // if-convert the test
-    loadConstant(cUnit, r0, 1);       // .eq case - load true
-    genRegCopy(cUnit, r0, r2);        // .ne case - arg0 <= class
-    opReg(cUnit, kOpBlx, rLR);        // .ne case: helper(class, ref->class)
-    genBarrier(cUnit);
-    oatClobberCalleeSave(cUnit);
-    /* branch target here */
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
-    target->defMask = ENCODE_ALL;
-    RegLocation rlResult = oatGetReturn(cUnit);
-    storeValue(cUnit, rlDest, rlResult);
-    branch1->generic.target = (LIR*)target;
-}
-
-STATIC void genCheckCast(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
-{
-    oatFlushAllRegs(cUnit);
-    // May generate a call - use explicit registers
-    oatLockCallTemps(cUnit);
-    uint32_t type_idx = mir->dalvikInsn.vB;
-    loadCurrMethodDirect(cUnit, r1);  // r1 <= current Method*
-    int classReg = r2;  // r2 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
-        loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pInitializeTypeAndVerifyAccessFromCode),
-                     rLR);
-        loadConstant(cUnit, r0, type_idx);
-        callRuntimeHelper(cUnit, rLR);  // InitializeTypeAndVerifyAccess(idx, method)
-        genRegCopy(cUnit, classReg, r0);  // Align usage with fast path
-    } else {
-        // Load dex cache entry into classReg (r2)
-        loadWordDisp(cUnit, r1, Method::DexCacheResolvedTypesOffset().Int32Value(), classReg);
-        int32_t offset_of_type = Array::DataOffset(sizeof(Class*)).Int32Value() +
-                                 (sizeof(Class*) * type_idx);
-        loadWordDisp(cUnit, classReg, offset_of_type, classReg);
-        if (!cUnit->compiler->CanAssumeTypeIsPresentInDexCache(cUnit->dex_cache, type_idx)) {
-            // Need to test presence of type in dex cache at runtime
-            ArmLIR* hopBranch = genCmpImmBranch(cUnit, kArmCondNe, 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
-            // Rejoin code paths
-            ArmLIR* hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
-            hopTarget->defMask = ENCODE_ALL;
-            hopBranch->generic.target = (LIR*)hopTarget;
-        }
-    }
-    // At this point, classReg (r2) has class
-    loadValueDirectFixed(cUnit, rlSrc, r0);  // r0 <= ref
-    /* Null is OK - continue */
-    ArmLIR* branch1 = genCmpImmBranch(cUnit, kArmCondEq, r0, 0);
-    /* load object->clazz */
-    DCHECK_EQ(Object::ClassOffset().Int32Value(), 0);
-    loadWordDisp(cUnit, r0,  Object::ClassOffset().Int32Value(), r1);
-    /* r1 now contains object->clazz */
-    loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pCheckCastFromCode), rLR);
-    opRegReg(cUnit, kOpCmp, r1, classReg);
-    ArmLIR* branch2 = opCondBranch(cUnit, kArmCondEq); /* If equal, trivial yes */
-    genRegCopy(cUnit, r0, r1);
-    genRegCopy(cUnit, r1, r2);
-    callRuntimeHelper(cUnit, rLR);
-    /* branch target here */
-    ArmLIR* target = newLIR0(cUnit, kArmPseudoTargetLabel);
-    target->defMask = ENCODE_ALL;
-    branch1->generic.target = (LIR*)target;
-    branch2->generic.target = (LIR*)target;
-}
-
-STATIC void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest,
-                        RegLocation rlSrc)
+void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
 {
     RegLocation rlResult;
     rlSrc = loadValue(cUnit, rlSrc, kFPReg);
@@ -792,8 +225,7 @@
     storeValue(cUnit, rlDest, rlResult);
 }
 
-STATIC void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest,
-                         RegLocation rlSrc)
+void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
 {
     RegLocation rlResult;
     rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
@@ -803,119 +235,6 @@
     storeValueWide(cUnit, rlDest, rlResult);
 }
 
-STATIC 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);
-    }
-}
-
-STATIC void genLong3Addr(CompilationUnit* cUnit, MIR* mir, OpKind firstOp,
-                         OpKind secondOp, RegLocation rlDest,
-                         RegLocation rlSrc1, RegLocation rlSrc2)
-{
-    /*
-     * NOTE:  This is the one place in the code in which we might have
-     * as many as six live temporary registers.  There are 5 in the normal
-     * set for Arm.  Until we have spill capabilities, temporarily add
-     * lr to the temp set.  It is safe to do this locally, but note that
-     * lr is used explicitly elsewhere in the code generator and cannot
-     * normally be used as a general temp register.
-     */
-    RegLocation rlResult;
-    oatMarkTemp(cUnit, rLR);   // Add lr to the temp pool
-    oatFreeTemp(cUnit, rLR);   // and make it available
-    rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-    rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    // The longs may overlap - use intermediate temp if so
-    if (rlResult.lowReg == rlSrc1.highReg) {
-        int tReg = oatAllocTemp(cUnit);
-        genRegCopy(cUnit, tReg, rlSrc1.highReg);
-        opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg,
-                    rlSrc2.lowReg);
-        opRegRegReg(cUnit, secondOp, rlResult.highReg, tReg,
-                    rlSrc2.highReg);
-        oatFreeTemp(cUnit, tReg);
-    } else {
-        opRegRegReg(cUnit, firstOp, rlResult.lowReg, rlSrc1.lowReg,
-                    rlSrc2.lowReg);
-        opRegRegReg(cUnit, secondOp, rlResult.highReg, rlSrc1.highReg,
-                    rlSrc2.highReg);
-    }
-    /*
-     * NOTE: If rlDest refers to a frame variable in a large frame, the
-     * following storeValueWide might need to allocate a temp register.
-     * To further work around the lack of a spill capability, explicitly
-     * free any temps from rlSrc1 & rlSrc2 that aren't still live in rlResult.
-     * Remove when spill is functional.
-     */
-    freeRegLocTemps(cUnit, rlResult, rlSrc1);
-    freeRegLocTemps(cUnit, rlResult, rlSrc2);
-    storeValueWide(cUnit, rlDest, rlResult);
-    oatClobber(cUnit, rLR);
-    oatUnmarkTemp(cUnit, rLR);  // Remove lr from the temp pool
-}
-
-void oatInitializeRegAlloc(CompilationUnit* cUnit)
-{
-    int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
-    int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
-    int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
-    int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
-    int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
-    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;
-               }
-           }
-        }
-    }
-}
-
 /*
  * Handle simple case (thin lock) inline.  If it's complicated, bail
  * out to the heavyweight lock/unlock routines.  We'll use dedicated
@@ -942,13 +261,12 @@
  * preserved.
  *
  */
-STATIC void genMonitorEnter(CompilationUnit* cUnit, MIR* mir,
-                            RegLocation rlSrc)
+void genMonitorEnter(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    ArmLIR* target;
-    ArmLIR* hopTarget;
-    ArmLIR* branch;
-    ArmLIR* hopBranch;
+    LIR* target;
+    LIR* hopTarget;
+    LIR* branch;
+    LIR* hopBranch;
 
     oatFlushAllRegs(cUnit);
     DCHECK_EQ(LW_SHAPE_THIN, 0);
@@ -969,9 +287,9 @@
     oatGenMemBarrier(cUnit, kSY);
     branch = newLIR2(cUnit, kThumb2Cbz, r1, 0);
 
-    hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
+    hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
     hopTarget->defMask = ENCODE_ALL;
-    hopBranch->generic.target = (LIR*)hopTarget;
+    hopBranch->target = (LIR*)hopTarget;
 
     // Go expensive route - artLockObjectFromCode(self, obj);
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pLockObjectFromCode),
@@ -979,9 +297,9 @@
     callRuntimeHelper(cUnit, rLR);
 
     // Resume here
-    target = newLIR0(cUnit, kArmPseudoTargetLabel);
+    target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
-    branch->generic.target = (LIR*)target;
+    branch->target = (LIR*)target;
 }
 
 /*
@@ -990,13 +308,12 @@
  * a zero recursion count, it's safe to punch it back to the
  * initial, unlock thin state with a store word.
  */
-STATIC void genMonitorExit(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlSrc)
+void genMonitorExit(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc)
 {
-    ArmLIR* target;
-    ArmLIR* branch;
-    ArmLIR* hopTarget;
-    ArmLIR* hopBranch;
+    LIR* target;
+    LIR* branch;
+    LIR* hopTarget;
+    LIR* hopBranch;
 
     DCHECK_EQ(LW_SHAPE_THIN, 0);
     oatFlushAllRegs(cUnit);
@@ -1011,14 +328,14 @@
     opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
     newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
     opRegReg(cUnit, kOpSub, r1, r2);
-    hopBranch = opCondBranch(cUnit, kArmCondNe);
+    hopBranch = opCondBranch(cUnit, kCondNe);
     oatGenMemBarrier(cUnit, kSY);
     storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
     branch = opNone(cUnit, kOpUncondBr);
 
-    hopTarget = newLIR0(cUnit, kArmPseudoTargetLabel);
+    hopTarget = newLIR0(cUnit, kPseudoTargetLabel);
     hopTarget->defMask = ENCODE_ALL;
-    hopBranch->generic.target = (LIR*)hopTarget;
+    hopBranch->target = (LIR*)hopTarget;
 
     // Go expensive route - UnlockObjectFromCode(obj);
     loadWordDisp(cUnit, rSELF, OFFSETOF_MEMBER(Thread, pUnlockObjectFromCode),
@@ -1026,9 +343,9 @@
     callRuntimeHelper(cUnit, rLR);
 
     // Resume here
-    target = newLIR0(cUnit, kArmPseudoTargetLabel);
+    target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
-    branch->generic.target = (LIR*)target;
+    branch->target = (LIR*)target;
 }
 
 /*
@@ -1046,32 +363,31 @@
  *     neg   rX
  * done:
  */
-STATIC void genCmpLong(CompilationUnit* cUnit, MIR* mir,
-                       RegLocation rlDest, RegLocation rlSrc1,
-                       RegLocation rlSrc2)
+void genCmpLong(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
 {
-    ArmLIR* target1;
-    ArmLIR* target2;
+    LIR* target1;
+    LIR* target2;
     rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
     rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
     int tReg = oatAllocTemp(cUnit);
     loadConstant(cUnit, tReg, -1);
     opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
-    ArmLIR* branch1 = opCondBranch(cUnit, kArmCondLt);
-    ArmLIR* branch2 = opCondBranch(cUnit, kArmCondGt);
+    LIR* branch1 = opCondBranch(cUnit, kCondLt);
+    LIR* branch2 = opCondBranch(cUnit, kCondGt);
     opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
-    ArmLIR* branch3 = opCondBranch(cUnit, kArmCondEq);
+    LIR* branch3 = opCondBranch(cUnit, kCondEq);
 
     genIT(cUnit, kArmCondHi, "E");
     newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
     loadConstant(cUnit, tReg, 1);
     genBarrier(cUnit);
 
-    target2 = newLIR0(cUnit, kArmPseudoTargetLabel);
+    target2 = newLIR0(cUnit, kPseudoTargetLabel);
     target2->defMask = -1;
     opRegReg(cUnit, kOpNeg, tReg, tReg);
 
-    target1 = newLIR0(cUnit, kArmPseudoTargetLabel);
+    target1 = newLIR0(cUnit, kPseudoTargetLabel);
     target1->defMask = -1;
 
     RegLocation rlTemp = LOC_C_RETURN; // Just using as template, will change
@@ -1079,982 +395,103 @@
     storeValue(cUnit, rlDest, rlTemp);
     oatFreeTemp(cUnit, tReg);
 
-    branch1->generic.target = (LIR*)target1;
-    branch2->generic.target = (LIR*)target2;
-    branch3->generic.target = branch1->generic.target;
-}
-
-STATIC void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit,
-        RegLocation rlSrc, RegLocation rlResult, int lit,
-        int firstBit, int secondBit)
-{
-    opRegRegRegShift(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, rlSrc.lowReg,
-                     encodeShift(kArmLsl, secondBit - firstBit));
-    if (firstBit != 0) {
-        opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
-    }
-}
-
-STATIC bool genConversionCall(CompilationUnit* cUnit, MIR* mir, int funcOffset,
-                                     int srcSize, int tgtSize)
-{
-    /*
-     * 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;
-}
-
-STATIC bool genArithOpFloatPortable(CompilationUnit* cUnit, MIR* mir,
-                                    RegLocation rlDest, RegLocation rlSrc1,
-                                    RegLocation rlSrc2)
-{
-    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;
-}
-
-STATIC bool genArithOpDoublePortable(CompilationUnit* cUnit, MIR* mir,
-                                     RegLocation rlDest, RegLocation rlSrc1,
-                                     RegLocation rlSrc2)
-{
-    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;
-}
-
-STATIC bool genConversionPortable(CompilationUnit* cUnit, MIR* mir)
-{
-    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;
+    branch1->target = (LIR*)target1;
+    branch2->target = (LIR*)target2;
+    branch3->target = branch1->target;
 }
 
 /*
- * Generate array store
- *
+ * Generate a register comparison to an immediate and branch.  Caller
+ * is responsible for setting branch target field.
  */
-STATIC void genArrayObjPut(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlArray, RegLocation rlIndex,
-                           RegLocation rlSrc, int scale)
+LIR* genCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+                        int checkValue)
 {
-    RegisterClass regClass = oatRegClassBySize(kWord);
-    int lenOffset = Array::LengthOffset().Int32Value();
-    int dataOffset = Array::DataOffset(sizeof(Object*)).Int32Value();
-
-    oatFlushAllRegs(cUnit);
-    /* Make sure it's a legal object Put. Use direct regs at first */
-    loadValueDirectFixed(cUnit, rlArray, r1);
-    loadValueDirectFixed(cUnit, rlSrc, r0);
-
-    /* null array object? */
-    genNullCheck(cUnit, rlArray.sRegLow, r1, mir);
-    loadWordDisp(cUnit, rSELF,
-                 OFFSETOF_MEMBER(Thread, pCanPutArrayElementFromCode), rLR);
-    /* Get the array's clazz */
-    loadWordDisp(cUnit, r1, Object::ClassOffset().Int32Value(), r1);
-    callRuntimeHelper(cUnit, rLR);
-    oatFreeTemp(cUnit, r0);
-    oatFreeTemp(cUnit, r1);
-
-    // Now, redo loadValues in case they didn't survive the call
-
-    int regPtr;
-    rlArray = loadValue(cUnit, rlArray, kCoreReg);
-    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
-
-    if (oatIsTemp(cUnit, rlArray.lowReg)) {
-        oatClobber(cUnit, rlArray.lowReg);
-        regPtr = rlArray.lowReg;
+    LIR* branch;
+    int modImm;
+    ArmConditionCode armCond = oatArmConditionEncoding(cond);
+    if ((LOWREG(reg)) && (checkValue == 0) &&
+       ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
+        branch = newLIR2(cUnit,
+                         (armCond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
+                         reg, 0);
     } else {
-        regPtr = oatAllocTemp(cUnit);
-        genRegCopy(cUnit, regPtr, rlArray.lowReg);
-    }
-
-    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
-        int regLen = oatAllocTemp(cUnit);
-        //NOTE: max live temps(4) here.
-        /* Get len */
-        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
-        /* regPtr -> array data */
-        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
-        genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
-                       kArmThrowArrayBounds);
-        oatFreeTemp(cUnit, regLen);
-    } else {
-        /* regPtr -> array data */
-        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
-    }
-    /* at this point, regPtr points to array, 2 live temps */
-    rlSrc = loadValue(cUnit, rlSrc, regClass);
-    storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
-                     scale, kWord);
-}
-
-/*
- * Generate array load
- */
-STATIC void genArrayGet(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                        RegLocation rlArray, RegLocation rlIndex,
-                        RegLocation rlDest, int scale)
-{
-    RegisterClass regClass = oatRegClassBySize(size);
-    int lenOffset = Array::LengthOffset().Int32Value();
-    int dataOffset;
-    RegLocation rlResult;
-    rlArray = loadValue(cUnit, rlArray, kCoreReg);
-    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
-    int regPtr;
-
-    if (size == kLong || size == kDouble) {
-      dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value();
-    } else {
-      dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value();
-    }
-
-    /* null object? */
-    genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
-
-    regPtr = oatAllocTemp(cUnit);
-
-    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
-        int regLen = oatAllocTemp(cUnit);
-        /* Get len */
-        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
-        /* regPtr -> array data */
-        opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
-        genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
-                       kArmThrowArrayBounds);
-        oatFreeTemp(cUnit, regLen);
-    } else {
-        /* regPtr -> array data */
-        opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
-    }
-    oatFreeTemp(cUnit, rlArray.lowReg);
-    if ((size == kLong) || (size == kDouble)) {
-        if (scale) {
-            int rNewIndex = oatAllocTemp(cUnit);
-            opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
-            opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
-            oatFreeTemp(cUnit, rNewIndex);
+        modImm = modifiedImmediate(checkValue);
+        if (LOWREG(reg) && ((checkValue & 0xff) == checkValue)) {
+            newLIR2(cUnit, kThumbCmpRI8, reg, checkValue);
+        } else if (modImm >= 0) {
+            newLIR2(cUnit, kThumb2CmpRI8, reg, modImm);
         } else {
-            opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
-        }
-        oatFreeTemp(cUnit, rlIndex.lowReg);
-        rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-
-        loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
-
-        oatFreeTemp(cUnit, regPtr);
-        storeValueWide(cUnit, rlDest, rlResult);
-    } else {
-        rlResult = oatEvalLoc(cUnit, rlDest, regClass, true);
-
-        loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
-                        scale, size);
-
-        oatFreeTemp(cUnit, regPtr);
-        storeValue(cUnit, rlDest, rlResult);
-    }
-}
-
-/*
- * Generate array store
- *
- */
-STATIC void genArrayPut(CompilationUnit* cUnit, MIR* mir, OpSize size,
-                        RegLocation rlArray, RegLocation rlIndex,
-                        RegLocation rlSrc, int scale)
-{
-    RegisterClass regClass = oatRegClassBySize(size);
-    int lenOffset = Array::LengthOffset().Int32Value();
-    int dataOffset;
-
-    if (size == kLong || size == kDouble) {
-      dataOffset = Array::DataOffset(sizeof(int64_t)).Int32Value();
-    } else {
-      dataOffset = Array::DataOffset(sizeof(int32_t)).Int32Value();
-    }
-
-    int regPtr;
-    rlArray = loadValue(cUnit, rlArray, kCoreReg);
-    rlIndex = loadValue(cUnit, rlIndex, kCoreReg);
-
-    if (oatIsTemp(cUnit, rlArray.lowReg)) {
-        oatClobber(cUnit, rlArray.lowReg);
-        regPtr = rlArray.lowReg;
-    } else {
-        regPtr = oatAllocTemp(cUnit);
-        genRegCopy(cUnit, regPtr, rlArray.lowReg);
-    }
-
-    /* null object? */
-    genNullCheck(cUnit, rlArray.sRegLow, rlArray.lowReg, mir);
-
-    if (!(mir->optimizationFlags & MIR_IGNORE_RANGE_CHECK)) {
-        int regLen = oatAllocTemp(cUnit);
-        //NOTE: max live temps(4) here.
-        /* Get len */
-        loadWordDisp(cUnit, rlArray.lowReg, lenOffset, regLen);
-        /* regPtr -> array data */
-        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
-        genRegRegCheck(cUnit, kArmCondCs, rlIndex.lowReg, regLen, mir,
-                       kArmThrowArrayBounds);
-        oatFreeTemp(cUnit, regLen);
-    } else {
-        /* regPtr -> array data */
-        opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
-    }
-    /* at this point, regPtr points to array, 2 live temps */
-    if ((size == kLong) || (size == kDouble)) {
-        //TUNING: specific wide routine that can handle fp regs
-        if (scale) {
-            int rNewIndex = oatAllocTemp(cUnit);
-            opRegRegImm(cUnit, kOpLsl, rNewIndex, rlIndex.lowReg, scale);
-            opRegReg(cUnit, kOpAdd, regPtr, rNewIndex);
-            oatFreeTemp(cUnit, rNewIndex);
-        } else {
-            opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
-        }
-        rlSrc = loadValueWide(cUnit, rlSrc, regClass);
-
-        storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
-
-        oatFreeTemp(cUnit, regPtr);
-    } else {
-        rlSrc = loadValue(cUnit, rlSrc, regClass);
-
-        storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
-                         scale, size);
-    }
-}
-
-STATIC bool genShiftOpLong(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc1,
-                           RegLocation rlShift)
-{
-    int funcOffset;
-
-    switch( mir->dalvikInsn.opcode) {
-        case OP_SHL_LONG:
-        case OP_SHL_LONG_2ADDR:
-            funcOffset = OFFSETOF_MEMBER(Thread, pShlLong);
-            break;
-        case OP_SHR_LONG:
-        case OP_SHR_LONG_2ADDR:
-            funcOffset = OFFSETOF_MEMBER(Thread, pShrLong);
-            break;
-        case OP_USHR_LONG:
-        case OP_USHR_LONG_2ADDR:
-            funcOffset = OFFSETOF_MEMBER(Thread, pUshrLong);
-            break;
-        default:
-            LOG(FATAL) << "Unexpected case";
-            return true;
-    }
-    oatFlushAllRegs(cUnit);   /* Send everything to home location */
-    loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-    loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-    loadValueDirect(cUnit, rlShift, r2);
-    callRuntimeHelper(cUnit, rLR);
-    RegLocation rlResult = oatGetReturnWide(cUnit);
-    storeValueWide(cUnit, rlDest, rlResult);
-    return false;
-}
-
-STATIC bool genArithOpLong(CompilationUnit* cUnit, MIR* mir,
-                           RegLocation rlDest, RegLocation rlSrc1,
-                           RegLocation rlSrc2)
-{
-    RegLocation rlResult;
-    OpKind firstOp = kOpBkpt;
-    OpKind secondOp = kOpBkpt;
-    bool callOut = false;
-    bool checkZero = false;
-    int funcOffset;
-    int retReg = r0;
-
-    switch (mir->dalvikInsn.opcode) {
-        case OP_NOT_LONG:
-            rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-            // Check for destructive overlap
-            if (rlResult.lowReg == rlSrc2.highReg) {
-                int tReg = oatAllocTemp(cUnit);
-                genRegCopy(cUnit, tReg, rlSrc2.highReg);
-                opRegReg(cUnit, kOpMvn, rlResult.lowReg, rlSrc2.lowReg);
-                opRegReg(cUnit, kOpMvn, rlResult.highReg, tReg);
-                oatFreeTemp(cUnit, tReg);
-            } else {
-                opRegReg(cUnit, kOpMvn, rlResult.lowReg, rlSrc2.lowReg);
-                opRegReg(cUnit, kOpMvn, rlResult.highReg, rlSrc2.highReg);
-            }
-            storeValueWide(cUnit, rlDest, rlResult);
-            return false;
-            break;
-        case OP_ADD_LONG:
-        case OP_ADD_LONG_2ADDR:
-            firstOp = kOpAdd;
-            secondOp = kOpAdc;
-            break;
-        case OP_SUB_LONG:
-        case OP_SUB_LONG_2ADDR:
-            firstOp = kOpSub;
-            secondOp = kOpSbc;
-            break;
-        case OP_MUL_LONG:
-        case OP_MUL_LONG_2ADDR:
-            callOut = true;
-            retReg = r0;
-            funcOffset = OFFSETOF_MEMBER(Thread, pLmul);
-            break;
-        case OP_DIV_LONG:
-        case OP_DIV_LONG_2ADDR:
-            callOut = true;
-            checkZero = true;
-            retReg = r0;
-            funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
-            break;
-        /* NOTE - result is in r2/r3 instead of r0/r1 */
-        case OP_REM_LONG:
-        case OP_REM_LONG_2ADDR:
-            callOut = true;
-            checkZero = true;
-            funcOffset = OFFSETOF_MEMBER(Thread, pLdivmod);
-            retReg = r2;
-            break;
-        case OP_AND_LONG_2ADDR:
-        case OP_AND_LONG:
-            firstOp = kOpAnd;
-            secondOp = kOpAnd;
-            break;
-        case OP_OR_LONG:
-        case OP_OR_LONG_2ADDR:
-            firstOp = kOpOr;
-            secondOp = kOpOr;
-            break;
-        case OP_XOR_LONG:
-        case OP_XOR_LONG_2ADDR:
-            firstOp = kOpXor;
-            secondOp = kOpXor;
-            break;
-        case OP_NEG_LONG: {
-            rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-            int zReg = oatAllocTemp(cUnit);
-            loadConstantNoClobber(cUnit, zReg, 0);
-            // Check for destructive overlap
-            if (rlResult.lowReg == rlSrc2.highReg) {
-                int tReg = oatAllocTemp(cUnit);
-                opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
-                            zReg, rlSrc2.lowReg);
-                opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
-                            zReg, tReg);
-                oatFreeTemp(cUnit, tReg);
-            } else {
-                opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
-                            zReg, rlSrc2.lowReg);
-                opRegRegReg(cUnit, kOpSbc, rlResult.highReg,
-                            zReg, rlSrc2.highReg);
-            }
-            oatFreeTemp(cUnit, zReg);
-            storeValueWide(cUnit, rlDest, rlResult);
-            return false;
-        }
-        default:
-            LOG(FATAL) << "Invalid long arith op";
-    }
-    if (!callOut) {
-        genLong3Addr(cUnit, mir, firstOp, secondOp, rlDest, rlSrc1, rlSrc2);
-    } else {
-        oatFlushAllRegs(cUnit);   /* Send everything to home location */
-        if (checkZero) {
-            loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-            loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-            loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
             int tReg = oatAllocTemp(cUnit);
-            newLIR4(cUnit, kThumb2OrrRRRs, tReg, r2, r3, 0);
-            oatFreeTemp(cUnit, tReg);
-            genCheck(cUnit, kArmCondEq, mir, kArmThrowDivZero);
-        } else {
-            loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-            loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-            loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+            loadConstant(cUnit, tReg, checkValue);
+            opRegReg(cUnit, kOpCmp, reg, tReg);
         }
-        callRuntimeHelper(cUnit, rLR);
-        // Adjust return regs in to handle case of rem returning r2/r3
-        if (retReg == r0)
-            rlResult = oatGetReturnWide(cUnit);
-        else
-            rlResult = oatGetReturnWideAlt(cUnit);
-        storeValueWide(cUnit, rlDest, rlResult);
+        branch = newLIR2(cUnit, kThumbBCond, 0, armCond);
     }
-    return false;
+    return branch;
+}
+LIR* genRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
+{
+    LIR* res;
+    ArmOpcode opcode;
+    if (FPREG(rDest) || FPREG(rSrc))
+        return fpRegCopy(cUnit, rDest, rSrc);
+    res = (LIR* ) oatNew(cUnit, sizeof(LIR), true, kAllocLIR);
+    res->dalvikOffset = cUnit->currentDalvikOffset;
+    if (LOWREG(rDest) && LOWREG(rSrc))
+        opcode = kThumbMovRR;
+    else if (!LOWREG(rDest) && !LOWREG(rSrc))
+         opcode = kThumbMovRR_H2H;
+    else if (LOWREG(rDest))
+         opcode = kThumbMovRR_H2L;
+    else
+         opcode = kThumbMovRR_L2H;
+
+    res->operands[0] = rDest;
+    res->operands[1] = rSrc;
+    res->opcode = opcode;
+    setupResourceMasks(res);
+    if (rDest == rSrc) {
+        res->flags.isNop = true;
+    }
+    return res;
 }
 
-STATIC bool genArithOpInt(CompilationUnit* cUnit, MIR* mir,
-                          RegLocation rlDest, RegLocation rlSrc1,
-                          RegLocation rlSrc2)
+LIR* genRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
 {
-    OpKind op = kOpBkpt;
-    bool callOut = false;
-    bool checkZero = false;
-    bool unary = false;
-    int retReg = r0;
-    int funcOffset;
-    RegLocation rlResult;
-    bool shiftOp = false;
+    LIR* res = genRegCopyNoInsert(cUnit, rDest, rSrc);
+    oatAppendLIR(cUnit, (LIR*)res);
+    return res;
+}
 
-    switch (mir->dalvikInsn.opcode) {
-        case OP_NEG_INT:
-            op = kOpNeg;
-            unary = true;
-            break;
-        case OP_NOT_INT:
-            op = kOpMvn;
-            unary = true;
-            break;
-        case OP_ADD_INT:
-        case OP_ADD_INT_2ADDR:
-            op = kOpAdd;
-            break;
-        case OP_SUB_INT:
-        case OP_SUB_INT_2ADDR:
-            op = kOpSub;
-            break;
-        case OP_MUL_INT:
-        case OP_MUL_INT_2ADDR:
-            op = kOpMul;
-            break;
-        case OP_DIV_INT:
-        case OP_DIV_INT_2ADDR:
-            callOut = true;
-            checkZero = true;
-            funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
-            retReg = r0;
-            break;
-        /* NOTE: returns in r1 */
-        case OP_REM_INT:
-        case OP_REM_INT_2ADDR:
-            callOut = true;
-            checkZero = true;
-            funcOffset = OFFSETOF_MEMBER(Thread, pIdivmod);
-            retReg = r1;
-            break;
-        case OP_AND_INT:
-        case OP_AND_INT_2ADDR:
-            op = kOpAnd;
-            break;
-        case OP_OR_INT:
-        case OP_OR_INT_2ADDR:
-            op = kOpOr;
-            break;
-        case OP_XOR_INT:
-        case OP_XOR_INT_2ADDR:
-            op = kOpXor;
-            break;
-        case OP_SHL_INT:
-        case OP_SHL_INT_2ADDR:
-            shiftOp = true;
-            op = kOpLsl;
-            break;
-        case OP_SHR_INT:
-        case OP_SHR_INT_2ADDR:
-            shiftOp = true;
-            op = kOpAsr;
-            break;
-        case OP_USHR_INT:
-        case OP_USHR_INT_2ADDR:
-            shiftOp = true;
-            op = kOpLsr;
-            break;
-        default:
-            LOG(FATAL) << "Invalid word arith op: " <<
-                (int)mir->dalvikInsn.opcode;
-    }
-    if (!callOut) {
-        rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
-        if (unary) {
-            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-            opRegReg(cUnit, op, rlResult.lowReg,
-                     rlSrc1.lowReg);
+void genRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
+                           int srcLo, int srcHi)
+{
+    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 {
-            rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
-            if (shiftOp) {
-                int tReg = oatAllocTemp(cUnit);
-                opRegRegImm(cUnit, kOpAnd, tReg, rlSrc2.lowReg, 31);
-                rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-                opRegRegReg(cUnit, op, rlResult.lowReg,
-                            rlSrc1.lowReg, tReg);
-                oatFreeTemp(cUnit, tReg);
+            newLIR3(cUnit, kThumb2Fmdrr, S2D(destLo, destHi), srcLo, srcHi);
+        }
+    } else {
+        if (srcFP) {
+            newLIR3(cUnit, kThumb2Fmrrd, destLo, destHi, S2D(srcLo, srcHi));
+        } else {
+            // Handle overlap
+            if (srcHi == destLo) {
+                genRegCopy(cUnit, destHi, srcHi);
+                genRegCopy(cUnit, destLo, srcLo);
             } else {
-                rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-                opRegRegReg(cUnit, op, rlResult.lowReg,
-                            rlSrc1.lowReg, rlSrc2.lowReg);
-            }
-        }
-        storeValue(cUnit, rlDest, rlResult);
-    } else {
-        RegLocation rlResult;
-        oatFlushAllRegs(cUnit);   /* Send everything to home location */
-        loadValueDirectFixed(cUnit, rlSrc2, r1);
-        loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-        loadValueDirectFixed(cUnit, rlSrc1, r0);
-        if (checkZero) {
-            genImmedCheck(cUnit, kArmCondEq, r1, 0, mir, kArmThrowDivZero);
-        }
-        callRuntimeHelper(cUnit, rLR);
-        if (retReg == r0)
-            rlResult = oatGetReturn(cUnit);
-        else
-            rlResult = oatGetReturnAlt(cUnit);
-        storeValue(cUnit, rlDest, rlResult);
-    }
-    return false;
-}
-
-/* Check if we need to check for pending suspend request */
-STATIC void genSuspendTest(CompilationUnit* cUnit, MIR* mir)
-{
-    if (NO_SUSPEND || (mir->optimizationFlags & MIR_IGNORE_SUSPEND_CHECK)) {
-        return;
-    }
-    oatFlushAllRegs(cUnit);
-    ArmLIR* branch;
-    if (cUnit->genDebugger) {
-        // If generating code for the debugger, always check for suspension
-        branch = genUnconditionalBranch(cUnit, NULL);
-    } else {
-        // In non-debug case, only check periodically
-        newLIR2(cUnit, kThumbSubRI8, rSUSPEND, 1);
-        branch = opCondBranch(cUnit, kArmCondEq);
-    }
-    ArmLIR* retLab = newLIR0(cUnit, kArmPseudoTargetLabel);
-    retLab->defMask = ENCODE_ALL;
-    ArmLIR* target = (ArmLIR*)oatNew(cUnit, sizeof(ArmLIR), true, kAllocLIR);
-    target->generic.dalvikOffset = cUnit->currentDalvikOffset;
-    target->opcode = kArmPseudoSuspendTarget;
-    target->operands[0] = (intptr_t)retLab;
-    target->operands[1] = mir->offset;
-    branch->generic.target = (LIR*)target;
-    oatInsertGrowableList(cUnit, &cUnit->suspendLaunchpads, (intptr_t)target);
-}
-
-/*
- * The following are the first-level codegen routines that analyze the format
- * of each bytecode then either dispatch special purpose codegen routines
- * or produce corresponding Thumb instructions directly.
- */
-
-STATIC bool isPowerOfTwo(int x)
-{
-    return (x & (x - 1)) == 0;
-}
-
-// Returns true if no more than two bits are set in 'x'.
-STATIC bool isPopCountLE2(unsigned int x)
-{
-    x &= x - 1;
-    return (x & (x - 1)) == 0;
-}
-
-// Returns the index of the lowest set bit in 'x'.
-STATIC int lowestSetBit(unsigned int x) {
-    int bit_posn = 0;
-    while ((x & 0xf) == 0) {
-        bit_posn += 4;
-        x >>= 4;
-    }
-    while ((x & 1) == 0) {
-        bit_posn++;
-        x >>= 1;
-    }
-    return bit_posn;
-}
-
-// Returns true if it added instructions to 'cUnit' to divide 'rlSrc' by 'lit'
-// and store the result in 'rlDest'.
-STATIC bool handleEasyDivide(CompilationUnit* cUnit, Opcode dalvikOpcode,
-                             RegLocation rlSrc, RegLocation rlDest, int lit)
-{
-    if (lit < 2 || !isPowerOfTwo(lit)) {
-        return false;
-    }
-    int k = lowestSetBit(lit);
-    if (k >= 30) {
-        // Avoid special cases.
-        return false;
-    }
-    bool div = (dalvikOpcode == OP_DIV_INT_LIT8 ||
-                dalvikOpcode == OP_DIV_INT_LIT16);
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    if (div) {
-        int tReg = oatAllocTemp(cUnit);
-        if (lit == 2) {
-            // Division by 2 is by far the most common division by constant.
-            opRegRegImm(cUnit, kOpLsr, tReg, rlSrc.lowReg, 32 - k);
-            opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
-            opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
-        } else {
-            opRegRegImm(cUnit, kOpAsr, tReg, rlSrc.lowReg, 31);
-            opRegRegImm(cUnit, kOpLsr, tReg, tReg, 32 - k);
-            opRegRegReg(cUnit, kOpAdd, tReg, tReg, rlSrc.lowReg);
-            opRegRegImm(cUnit, kOpAsr, rlResult.lowReg, tReg, k);
-        }
-    } else {
-        int cReg = oatAllocTemp(cUnit);
-        loadConstant(cUnit, cReg, lit - 1);
-        int tReg1 = oatAllocTemp(cUnit);
-        int tReg2 = oatAllocTemp(cUnit);
-        if (lit == 2) {
-            opRegRegImm(cUnit, kOpLsr, tReg1, rlSrc.lowReg, 32 - k);
-            opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
-            opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
-            opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
-        } else {
-            opRegRegImm(cUnit, kOpAsr, tReg1, rlSrc.lowReg, 31);
-            opRegRegImm(cUnit, kOpLsr, tReg1, tReg1, 32 - k);
-            opRegRegReg(cUnit, kOpAdd, tReg2, tReg1, rlSrc.lowReg);
-            opRegRegReg(cUnit, kOpAnd, tReg2, tReg2, cReg);
-            opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg2, tReg1);
-        }
-    }
-    storeValue(cUnit, rlDest, rlResult);
-    return true;
-}
-
-// Returns true if it added instructions to 'cUnit' to multiply 'rlSrc' by 'lit'
-// and store the result in 'rlDest'.
-STATIC bool handleEasyMultiply(CompilationUnit* cUnit,
-                               RegLocation rlSrc, RegLocation rlDest, int lit)
-{
-    // Can we simplify this multiplication?
-    bool powerOfTwo = false;
-    bool popCountLE2 = false;
-    bool powerOfTwoMinusOne = false;
-    if (lit < 2) {
-        // Avoid special cases.
-        return false;
-    } else if (isPowerOfTwo(lit)) {
-        powerOfTwo = true;
-    } else if (isPopCountLE2(lit)) {
-        popCountLE2 = true;
-    } else if (isPowerOfTwo(lit + 1)) {
-        powerOfTwoMinusOne = true;
-    } else {
-        return false;
-    }
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    if (powerOfTwo) {
-        // Shift.
-        opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlSrc.lowReg,
-                    lowestSetBit(lit));
-    } else if (popCountLE2) {
-        // Shift and add and shift.
-        int firstBit = lowestSetBit(lit);
-        int secondBit = lowestSetBit(lit ^ (1 << firstBit));
-        genMultiplyByTwoBitMultiplier(cUnit, rlSrc, rlResult, lit,
-                                      firstBit, secondBit);
-    } else {
-        // Reverse subtract: (src << (shift + 1)) - src.
-        DCHECK(powerOfTwoMinusOne);
-        // TUNING: rsb dst, src, src lsl#lowestSetBit(lit + 1)
-        int tReg = oatAllocTemp(cUnit);
-        opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, lowestSetBit(lit + 1));
-        opRegRegReg(cUnit, kOpSub, rlResult.lowReg, tReg, rlSrc.lowReg);
-    }
-    storeValue(cUnit, rlDest, rlResult);
-    return true;
-}
-
-STATIC bool genArithOpIntLit(CompilationUnit* cUnit, MIR* mir,
-                             RegLocation rlDest, RegLocation rlSrc,
-                             int lit)
-{
-    Opcode dalvikOpcode = mir->dalvikInsn.opcode;
-    RegLocation rlResult;
-    OpKind op = (OpKind)0;      /* Make gcc happy */
-    int shiftOp = false;
-    bool isDiv = false;
-    int funcOffset;
-
-    switch (dalvikOpcode) {
-        case OP_RSUB_INT_LIT8:
-        case OP_RSUB_INT: {
-            int tReg;
-            //TUNING: add support for use of Arm rsub op
-            rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-            tReg = oatAllocTemp(cUnit);
-            loadConstant(cUnit, tReg, lit);
-            rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-            opRegRegReg(cUnit, kOpSub, rlResult.lowReg,
-                        tReg, rlSrc.lowReg);
-            storeValue(cUnit, rlDest, rlResult);
-            return false;
-            break;
-        }
-
-        case OP_ADD_INT_LIT8:
-        case OP_ADD_INT_LIT16:
-            op = kOpAdd;
-            break;
-        case OP_MUL_INT_LIT8:
-        case OP_MUL_INT_LIT16: {
-            if (handleEasyMultiply(cUnit, rlSrc, rlDest, lit)) {
-                return false;
-            }
-            op = kOpMul;
-            break;
-        }
-        case OP_AND_INT_LIT8:
-        case OP_AND_INT_LIT16:
-            op = kOpAnd;
-            break;
-        case OP_OR_INT_LIT8:
-        case OP_OR_INT_LIT16:
-            op = kOpOr;
-            break;
-        case OP_XOR_INT_LIT8:
-        case OP_XOR_INT_LIT16:
-            op = kOpXor;
-            break;
-        case OP_SHL_INT_LIT8:
-            lit &= 31;
-            shiftOp = true;
-            op = kOpLsl;
-            break;
-        case OP_SHR_INT_LIT8:
-            lit &= 31;
-            shiftOp = true;
-            op = kOpAsr;
-            break;
-        case OP_USHR_INT_LIT8:
-            lit &= 31;
-            shiftOp = true;
-            op = kOpLsr;
-            break;
-
-        case OP_DIV_INT_LIT8:
-        case OP_DIV_INT_LIT16:
-        case OP_REM_INT_LIT8:
-        case OP_REM_INT_LIT16:
-            if (lit == 0) {
-                genImmedCheck(cUnit, kArmCondAl, 0, 0, mir, kArmThrowDivZero);
-                return false;
-            }
-            if (handleEasyDivide(cUnit, dalvikOpcode, rlSrc, rlDest, lit)) {
-                return false;
-            }
-            oatFlushAllRegs(cUnit);   /* Everything to home location */
-            loadValueDirectFixed(cUnit, rlSrc, r0);
-            oatClobber(cUnit, r0);
-            if ((dalvikOpcode == OP_DIV_INT_LIT8) ||
-                (dalvikOpcode == OP_DIV_INT_LIT16)) {
-                funcOffset = OFFSETOF_MEMBER(Thread, pIdiv);
-                isDiv = true;
-            } else {
-                funcOffset = OFFSETOF_MEMBER(Thread, pIdivmod);
-                isDiv = false;
-            }
-            loadWordDisp(cUnit, rSELF, funcOffset, rLR);
-            loadConstant(cUnit, r1, lit);
-            callRuntimeHelper(cUnit, rLR);
-            if (isDiv)
-                rlResult = oatGetReturn(cUnit);
-            else
-                rlResult = oatGetReturnAlt(cUnit);
-            storeValue(cUnit, rlDest, rlResult);
-            return false;
-            break;
-        default:
-            return true;
-    }
-    rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-    rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-    // Avoid shifts by literal 0 - no support in Thumb.  Change to copy
-    if (shiftOp && (lit == 0)) {
-        genRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
-    } else {
-        opRegRegImm(cUnit, op, rlResult.lowReg, rlSrc.lowReg, lit);
-    }
-    storeValue(cUnit, rlDest, rlResult);
-    return false;
-}
-
-/* Architectural-specific debugging helpers go here */
-void oatArchDump(void)
-{
-    /* Print compiled opcode in this VM instance */
-    int i, start, streak;
-    std::string buf;
-
-    streak = i = 0;
-    while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) {
-        i++;
-    }
-    if (i == kNumPackedOpcodes) {
-        return;
-    }
-    for (start = i++, streak = 1; i < kNumPackedOpcodes; i++) {
-        if (opcodeCoverage[i]) {
-            streak++;
-        } else {
-            if (streak == 1) {
-                StringAppendF(&buf, "%x,", start);
-            } else {
-                StringAppendF(&buf, "%x-%x,", start, start + streak - 1);
-            }
-            streak = 0;
-            while (opcodeCoverage[i] == 0 && i < kNumPackedOpcodes) {
-                i++;
-            }
-            if (i < kNumPackedOpcodes) {
-                streak = 1;
-                start = i;
+                genRegCopy(cUnit, destLo, srcLo);
+                genRegCopy(cUnit, destHi, srcHi);
             }
         }
     }
-    if (streak) {
-        if (streak == 1) {
-            StringAppendF(&buf, "%x", start);
-        } else {
-            StringAppendF(&buf, "%x-%x", start, start + streak - 1);
-        }
-    }
-    if (!buf.empty()) {
-        LOG(INFO) << "dalvik.vm.oat.op = " << buf;
-    }
 }
 
+
 }  // namespace art
diff --git a/src/compiler/codegen/arm/Thumb2/Ralloc.cc b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
index 59c1aa6..c0f2c77 100644
--- a/src/compiler/codegen/arm/Thumb2/Ralloc.cc
+++ b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
@@ -52,4 +52,71 @@
     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);
+    int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
+    int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+    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/arm/armv7-a-neon/ArchVariant.cc b/src/compiler/codegen/arm/armv7-a-neon/ArchVariant.cc
index eafe5ed..77844fc 100644
--- a/src/compiler/codegen/arm/armv7-a-neon/ArchVariant.cc
+++ b/src/compiler/codegen/arm/armv7-a-neon/ArchVariant.cc
@@ -47,7 +47,7 @@
 void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind)
 {
 #if ANDROID_SMP != 0
-    ArmLIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
+    LIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
     dmb->defMask = ENCODE_ALL;
 #endif
 }
diff --git a/src/compiler/codegen/arm/armv7-a-neon/Codegen.cc b/src/compiler/codegen/arm/armv7-a-neon/Codegen.cc
index f042d5d..f7132ab 100644
--- a/src/compiler/codegen/arm/armv7-a-neon/Codegen.cc
+++ b/src/compiler/codegen/arm/armv7-a-neon/Codegen.cc
@@ -15,7 +15,7 @@
  */
 #define _CODEGEN_C
 #define _ARMV7_A_NEON
-#define TGT_LIR ArmLIR
+#define TARGET_ARM
 
 #include "../../../Dalvik.h"
 #include "../../../CompilerInternals.h"
@@ -23,13 +23,17 @@
 #include "../../Ralloc.h"
 #include "../Codegen.h"
 
-/* Arm codegen building blocks */
-#include "../CodegenCommon.cc"
+/* Common codegen utility code */
+#include "../../CodegenUtil.cc"
 
 /* Thumb2-specific factory utilities */
 #include "../Thumb2/Factory.cc"
 /* Target indepedent factory utilities */
 #include "../../CodegenFactory.cc"
+/* Target independent gen routines */
+#include "../../GenCommon.cc"
+/* Shared invoke gen routines */
+#include "../../GenInvoke.cc"
 /* Arm-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"
diff --git a/src/compiler/codegen/arm/armv7-a/ArchVariant.cc b/src/compiler/codegen/arm/armv7-a/ArchVariant.cc
index eafe5ed..77844fc 100644
--- a/src/compiler/codegen/arm/armv7-a/ArchVariant.cc
+++ b/src/compiler/codegen/arm/armv7-a/ArchVariant.cc
@@ -47,7 +47,7 @@
 void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind)
 {
 #if ANDROID_SMP != 0
-    ArmLIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
+    LIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
     dmb->defMask = ENCODE_ALL;
 #endif
 }
diff --git a/src/compiler/codegen/arm/armv7-a/Codegen.cc b/src/compiler/codegen/arm/armv7-a/Codegen.cc
index 633ab1e..6f62ccf 100644
--- a/src/compiler/codegen/arm/armv7-a/Codegen.cc
+++ b/src/compiler/codegen/arm/armv7-a/Codegen.cc
@@ -15,7 +15,7 @@
  */
 #define _CODEGEN_C
 #define _ARMV7_A
-#define TGT_LIR ArmLIR
+#define TARGET_ARM
 
 #include "../../../Dalvik.h"
 #include "../../../CompilerInternals.h"
@@ -23,13 +23,17 @@
 #include "../../Ralloc.h"
 #include "../Codegen.h"
 
-/* Arm codegen building blocks */
-#include "../CodegenCommon.cc"
+/* Common codegen utility code */
+#include "../../CodegenUtil.cc"
 
 /* Thumb2-specific factory utilities */
 #include "../Thumb2/Factory.cc"
 /* Target independent factory utilities */
 #include "../../CodegenFactory.cc"
+/* Target independent gen routines */
+#include "../../GenCommon.cc"
+/* Shared invoke gen routines */
+#include "../../GenInvoke.cc"
 /* Arm-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"
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
index 6a3e667..cb9645d 100644
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ b/src/compiler/codegen/mips/ArchFactory.cc
@@ -39,20 +39,6 @@
 
 STATIC void genDebuggerUpdate(CompilationUnit* cUnit, int32_t offset);
 
-/* Generate conditional branch instructions */
-STATIC MipsLIR* genConditionalBranch(CompilationUnit* cUnit,
-                                    MipsConditionCode cond,
-                                    MipsLIR* target)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-    return NULL;
-#if 0
-    MipsLIR* branch = opCondBranch(cUnit, cond);
-    branch->generic.target = (LIR*) target;
-    return branch;
-#endif
-}
-
 /* Generate unconditional branch instructions */
 STATIC MipsLIR* genUnconditionalBranch(CompilationUnit* cUnit, MipsLIR* target)
 {
@@ -72,22 +58,19 @@
  */
 STATIC void markGCCard(CompilationUnit* cUnit, int valReg, int tgtAddrReg)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
     int regCardBase = oatAllocTemp(cUnit);
     int regCardNo = oatAllocTemp(cUnit);
-    MipsLIR* branchOver = genCmpImmBranch(cUnit, kMipsCondEq, valReg, 0);
+    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, kMipsPseudoTargetLabel);
+    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     branchOver->generic.target = (LIR*)target;
     oatFreeTemp(cUnit, regCardBase);
     oatFreeTemp(cUnit, regCardNo);
-#endif
 }
 
 /*
@@ -97,14 +80,11 @@
  */
 STATIC void loadCurrMethodDirect(CompilationUnit *cUnit, int rTgt)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
 #if defined(METHOD_IN_REG)
     genRegCopy(cUnit, rTgt, rMETHOD);
 #else
     loadWordDisp(cUnit, rSP, 0, rTgt);
 #endif
-#endif
 }
 
 STATIC int loadCurrMethod(CompilationUnit *cUnit)
@@ -118,70 +98,49 @@
 #endif
 }
 
-STATIC MipsLIR* genCheck(CompilationUnit* cUnit, MipsConditionCode cCode,
-                        MIR* mir, MipsThrowKind kind)
-{
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-    return 0;
-#if 0
-    MipsLIR* tgt = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    tgt->opcode = kMipsPseudoThrowTarget;
-    tgt->operands[0] = kind;
-    tgt->operands[1] = mir ? mir->offset : 0;
-    MipsLIR* branch = genConditionalBranch(cUnit, cCode, tgt);
-    // Remember branch target - will process later
-    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-    return branch;
-#endif
-}
-
 STATIC MipsLIR* genImmedCheck(CompilationUnit* cUnit, MipsConditionCode cCode,
                              int reg, int immVal, MIR* mir, MipsThrowKind kind)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-    return 0;
-#if 0
     MipsLIR* tgt = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    tgt->opcode = kMipsPseudoThrowTarget;
+    tgt->opcode = kPseudoThrowTarget;
     tgt->operands[0] = kind;
     tgt->operands[1] = mir->offset;
     MipsLIR* branch;
     if (cCode == kMipsCondAl) {
         branch = genUnconditionalBranch(cUnit, tgt);
     } else {
-        branch = genCmpImmBranch(cUnit, cCode, reg, immVal);
+        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;
-#endif
 }
 
 /* Perform null-check on a register.  */
 STATIC MipsLIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg,
                              MIR* mir)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-    return 0;
-#if 0
     if (!(cUnit->disableOpt & (1 << kNullCheckElimination)) &&
         mir->optimizationFlags & MIR_IGNORE_NULL_CHECK) {
         return NULL;
     }
     return genImmedCheck(cUnit, kMipsCondEq, mReg, 0, mir, kMipsThrowNullPointer);
-#endif
 }
 
 /* Perform check on two registers */
 STATIC TGT_LIR* genRegRegCheck(CompilationUnit* cUnit, MipsConditionCode cCode,
                                int reg1, int reg2, MIR* mir, MipsThrowKind kind)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-    return 0;
-#if 0
     MipsLIR* tgt = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    tgt->opcode = kMipsPseudoThrowTarget;
+    tgt->opcode = kPseudoThrowTarget;
     tgt->operands[0] = kind;
     tgt->operands[1] = mir ? mir->offset : 0;
     tgt->operands[2] = reg1;
@@ -191,7 +150,6 @@
     // Remember branch target - will process later
     oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
     return branch;
-#endif
 }
 
 /*
@@ -202,27 +160,26 @@
 STATIC void genNewArray(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
                         RegLocation rlSrc)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
     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), rLR);
+                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCode), addrReg);
     } else {
         loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCodeWithAccessCheck), rLR);
+                     OFFSETOF_MEMBER(Thread, pAllocArrayFromCodeWithAccessCheck), addrReg);
     }
-    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
-    loadConstant(cUnit, r0, type_idx);            // arg0 <- type_id
-    loadValueDirectFixed(cUnit, rlSrc, r2);       // arg2 <- count
-    callRuntimeHelper(cUnit, rLR);
+    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);
-#endif
 }
 
 /*
@@ -233,34 +190,36 @@
  */
 STATIC void genFilledNewArray(CompilationUnit* cUnit, MIR* mir, bool isRange)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
     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), rLR);
+                     OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCode),
+                                     addrReg);
     } else {
         loadWordDisp(cUnit, rSELF,
-                     OFFSETOF_MEMBER(Thread, pCheckAndAllocArrayFromCodeWithAccessCheck), rLR);
+                     OFFSETOF_MEMBER(Thread,
+                     pCheckAndAllocArrayFromCodeWithAccessCheck), addrReg);
     }
-    loadCurrMethodDirect(cUnit, r1);              // arg1 <- Method*
-    loadConstant(cUnit, r0, typeId);              // arg0 <- type_id
-    loadConstant(cUnit, r2, elems);               // arg2 <- count
-    callRuntimeHelper(cUnit, rLR);
+    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 r0, we'll just lock it into place.  When debugger support is
+     * 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, r0);
+    oatLockTemp(cUnit, r_V0);
 
     // Having a range of 0 is legal
     if (isRange && (dInsn->vA > 0)) {
@@ -288,32 +247,31 @@
         int rSrc = oatAllocTemp(cUnit);
         int rDst = oatAllocTemp(cUnit);
         int rIdx = oatAllocTemp(cUnit);
-        int rVal = rLR;  // Using a lot of temps, rLR is known free here
+        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, r0,
+        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, kMipsPseudoTargetLabel);
+        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);
-        // Use setflags encoding here
-        newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
-        MipsLIR* branch = opCondBranch(cUnit, kMipsCondGe);
+        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, r0,
+            storeBaseDisp(cUnit, r_V0,
                           Array::DataOffset().Int32Value() +
                           i * 4, rlArg.lowReg, kWord);
             // If the loadValue caused a temp to be allocated, free it
@@ -322,14 +280,11 @@
             }
         }
     }
-#endif
 }
 
 STATIC void genSput(CompilationUnit* cUnit, MIR* mir, RegLocation rlSrc,
                     bool isLongOrDouble, bool isObject)
 {
-    UNIMPLEMENTED(FATAL) << "Needs mips version";
-#if 0
     int fieldOffset;
     int ssbIndex;
     bool isVolatile;
@@ -357,6 +312,7 @@
             oatFlushAllRegs(cUnit);
             // Using fixed register to sync with possible call to runtime
             // support.
+            oatLockCallTemps(cUnit);
             rMethod = r1;
             oatLockTemp(cUnit, rMethod);
             loadCurrMethodDirect(cUnit, rMethod);
@@ -371,12 +327,13 @@
             // 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 = genCmpImmBranch(cUnit, kMipsCondNe, rBase, 0);
+            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, kMipsPseudoTargetLabel);
+            MipsLIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
             skipTarget->defMask = ENCODE_ALL;
             branchOver->generic.target = (LIR*)skipTarget;
         }
@@ -419,7 +376,6 @@
         }
         callRuntimeHelper(cUnit, rLR);
     }
-#endif
 }
 
 STATIC void genSget(CompilationUnit* cUnit, MIR* mir, RegLocation rlDest,
@@ -468,12 +424,12 @@
             // 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 = genCmpImmBranch(cUnit, kMipsCondNe, rBase, 0);
+            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, kMipsPseudoTargetLabel);
+            MipsLIR* skipTarget = newLIR0(cUnit, kPseudoTargetLabel);
             skipTarget->defMask = ENCODE_ALL;
             branchOver->generic.target = (LIR*)skipTarget;
         }
@@ -947,10 +903,10 @@
 {
     UNIMPLEMENTED(FATAL) << "Needs mips version";
 #if 0
-    MipsLIR* branchOver = genCmpImmBranch(cUnit, kMipsCondNe, rLR, 0);
+    MipsLIR* branchOver = opCmpImmBranch(cUnit, kMipsCondNe, rLR, 0);
     loadWordDisp(cUnit, rSELF,
                  OFFSETOF_MEMBER(Thread, pDebugMe), rLR);
-    MipsLIR* target = newLIR0(cUnit, kMipsPseudoTargetLabel);
+    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = -1;
     branchOver->generic.target = (LIR*)target;
 #endif
@@ -1164,7 +1120,7 @@
     bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) &&
                               ((size_t)cUnit->frameSize <
                               Thread::kStackOverflowReservedBytes));
-    newLIR0(cUnit, kMipsPseudoMethodEntry);
+    newLIR0(cUnit, kPseudoMethodEntry);
     if (!skipOverflowCheck) {
         /* Load stack limit */
         loadWordDisp(cUnit, rSELF,
@@ -1220,7 +1176,7 @@
     oatLockTemp(cUnit, r0);
     oatLockTemp(cUnit, r1);
 
-    newLIR0(cUnit, kMipsPseudoMethodExit);
+    newLIR0(cUnit, kPseudoMethodExit);
     /* If we're compiling for the debugger, generate an update callout */
     if (cUnit->genDebugger) {
         genDebuggerUpdate(cUnit, DEBUGGER_METHOD_EXIT);
diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc
index f218436..2e8d417 100644
--- a/src/compiler/codegen/mips/ArchUtility.cc
+++ b/src/compiler/codegen/mips/ArchUtility.cc
@@ -221,50 +221,50 @@
 
     /* Handle pseudo-ops individually, and all regular insns as a group */
     switch(lir->opcode) {
-        case kMipsPseudoMethodEntry:
+        case kPseudoMethodEntry:
             LOG(INFO) << "-------- method entry " <<
                 PrettyMethod(cUnit->method_idx, *cUnit->dex_file);
             break;
-        case kMipsPseudoMethodExit:
+        case kPseudoMethodExit:
             LOG(INFO) << "-------- Method_Exit";
             break;
-        case kMipsPseudoBarrier:
+        case kPseudoBarrier:
             LOG(INFO) << "-------- BARRIER";
             break;
-        case kMipsPseudoExtended:
+        case kPseudoExtended:
             LOG(INFO) << "-------- " << (char* ) dest;
             break;
-        case kMipsPseudoSSARep:
+        case kPseudoSSARep:
             DUMP_SSA_REP(LOG(INFO) << "-------- kMirOpPhi: " <<  (char* ) dest);
             break;
-        case kMipsPseudoEntryBlock:
+        case kPseudoEntryBlock:
             LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
             break;
-        case kMipsPseudoDalvikByteCodeBoundary:
+        case kPseudoDalvikByteCodeBoundary:
             LOG(INFO) << "-------- dalvik offset: 0x" << std::hex <<
                  lir->generic.dalvikOffset << " @ " << (char* )lir->operands[0];
             break;
-        case kMipsPseudoExitBlock:
+        case kPseudoExitBlock:
             LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
             break;
-        case kMipsPseudoPseudoAlign4:
+        case kPseudoPseudoAlign4:
             LOG(INFO) << (intptr_t)baseAddr + offset << " (0x" << std::hex <<
                 offset << "): .align4";
             break;
-        case kMipsPseudoEHBlockLabel:
+        case kPseudoEHBlockLabel:
             LOG(INFO) << "Exception_Handling:";
             break;
-        case kMipsPseudoTargetLabel:
-        case kMipsPseudoNormalBlockLabel:
+        case kPseudoTargetLabel:
+        case kPseudoNormalBlockLabel:
             LOG(INFO) << "L" << (intptr_t)lir << ":";
             break;
-        case kMipsPseudoThrowTarget:
+        case kPseudoThrowTarget:
             LOG(INFO) << "LT" << (intptr_t)lir << ":";
             break;
-        case kMipsPseudoSuspendTarget:
+        case kPseudoSuspendTarget:
             LOG(INFO) << "LS" << (intptr_t)lir << ":";
             break;
-        case kMipsPseudoCaseLabel:
+        case kPseudoCaseLabel:
             LOG(INFO) << "LC" << (intptr_t)lir << ": Case target 0x" <<
                 std::hex << lir->operands[0] << "|" << std::dec <<
                 lir->operands[0];
diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/Assemble.cc
index 9e8af2a..5b6e6ed 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/Assemble.cc
@@ -540,7 +540,7 @@
                 mipsLIR->flags.size = EncodingMap[mipsLIR->opcode].size * 2;
                 offset += mipsLIR->flags.size;
             }
-        } else if (mipsLIR->opcode == kMipsPseudoPseudoAlign4) {
+        } else if (mipsLIR->opcode == kPseudoPseudoAlign4) {
             if (offset & 0x2) {
                 offset += 2;
                 mipsLIR->operands[0] = 1;
diff --git a/src/compiler/codegen/mips/CodegenCommon.cc b/src/compiler/codegen/mips/CodegenCommon.cc
index 3645643..8dbb9a3 100644
--- a/src/compiler/codegen/mips/CodegenCommon.cc
+++ b/src/compiler/codegen/mips/CodegenCommon.cc
@@ -26,9 +26,6 @@
  * applicable directory below this one.
  */
 
-/* Track exercised opcodes */
-static int opcodeCoverage[kNumPackedOpcodes];
-
 static void setMemRefType(MipsLIR *lir, bool isLoad, int memType)
 {
     /* MIPSTODO simplify setMemRefType() */
@@ -230,46 +227,13 @@
 }
 
 /*
- * Set up the accurate resource mask for branch instructions
- */
-static void relaxBranchMasks(MipsLIR *lir)
-{
-    int flags = EncodingMap[lir->opcode].flags;
-
-    /* Make sure only branch instructions are passed here */
-    DCHECK(flags & IS_BRANCH);
-
-    lir->defMask |= ENCODE_REG_PC;
-    lir->useMask |= ENCODE_REG_PC;
-
-
-    if (flags & REG_DEF_LR) {
-        lir->defMask |= ENCODE_REG_LR;
-    }
-
-    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 & USES_CCODES) {
-        lir->useMask |= ENCODE_CCODE;
-    }
-}
-
-/*
  * The following are building blocks to construct low-level IRs with 0 - 4
  * operands.
  */
-static MipsLIR *newLIR0(CompilationUnit *cUnit, MipsOpCode opcode)
+MipsLIR *newLIR0(CompilationUnit *cUnit, MipsOpCode opcode)
 {
     MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpCode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND));
+    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & NO_OPERAND));
     insn->opcode = opcode;
     setupResourceMasks(insn);
     insn->generic.dalvikOffset = cUnit->currentDalvikOffset;
@@ -277,11 +241,11 @@
     return insn;
 }
 
-static MipsLIR *newLIR1(CompilationUnit *cUnit, MipsOpCode opcode,
+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));
+    DCHECK(isPseudoOpcode(opcode) || (EncodingMap[opcode].flags & IS_UNARY_OP));
     insn->opcode = opcode;
     insn->operands[0] = dest;
     setupResourceMasks(insn);
@@ -290,11 +254,11 @@
     return insn;
 }
 
-static MipsLIR *newLIR2(CompilationUnit *cUnit, MipsOpCode opcode,
+MipsLIR *newLIR2(CompilationUnit *cUnit, MipsOpCode opcode,
                            int dest, int src1)
 {
     MipsLIR *insn = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
-    DCHECK(isPseudoOpCode(opcode) ||
+    DCHECK(isPseudoOpcode(opcode) ||
            (EncodingMap[opcode].flags & IS_BINARY_OP));
     insn->opcode = opcode;
     insn->operands[0] = dest;
@@ -305,14 +269,14 @@
     return insn;
 }
 
-static MipsLIR *newLIR3(CompilationUnit *cUnit, MipsOpCode opcode,
+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) ||
+    DCHECK(isPseudoOpcode(opcode) ||
            (EncodingMap[opcode].flags & IS_TERTIARY_OP));
     insn->opcode = opcode;
     insn->operands[0] = dest;
@@ -324,11 +288,11 @@
     return insn;
 }
 
-static MipsLIR *newLIR4(CompilationUnit *cUnit, MipsOpCode opcode,
+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) ||
+    DCHECK(isPseudoOpcode(opcode) ||
            (EncodingMap[opcode].flags & IS_QUAD_OP));
     insn->opcode = opcode;
     insn->operands[0] = dest;
@@ -342,36 +306,12 @@
 }
 
 /*
- * The following are building blocks to insert constants into the pool or
- * instruction streams.
- */
-
-/* Add a 32-bit constant either in the constant pool or mixed with code */
-static MipsLIR *addWordData(CompilationUnit *cUnit, LIR **constantListP,
-                           int value)
-{
-    /* Add the constant to the literal pool */
-    if (constantListP) {
-        MipsLIR *newValue = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true,
-                                               kAllocData);
-        newValue->operands[0] = value;
-        newValue->generic.next = *constantListP;
-        *constantListP = (LIR *) newValue;
-        return newValue;
-    } else {
-        /* Add the constant in the middle of code stream */
-        newLIR1(cUnit, kMips32BitData, value);
-    }
-    return NULL;
-}
-
-/*
- * Generate an kMipsPseudoBarrier marker to indicate the boundary of special
+ * Generate an kPseudoBarrier marker to indicate the boundary of special
  * blocks.
  */
 static void genBarrier(CompilationUnit *cUnit)
 {
-    MipsLIR *barrier = newLIR0(cUnit, kMipsPseudoBarrier);
+    MipsLIR *barrier = newLIR0(cUnit, kPseudoBarrier);
     /* Mark all resources as being clobbered */
     barrier->defMask = -1;
 }
diff --git a/src/compiler/codegen/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/FP/MipsFP.cc
index fd07a34..7eb2a1a 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/FP/MipsFP.cc
@@ -21,7 +21,7 @@
 extern void oatFlushRegForV5TEVFP(CompilationUnit *cUnit, int reg);
 
 /* First, flush any registers associated with this value */
-static void loadValueAddress(CompilationUnit *cUnit, RegLocation rlSrc,
+void loadValueAddress(CompilationUnit *cUnit, RegLocation rlSrc,
                              int rDest)
 {
     UNIMPLEMENTED(FATAL) << "Need Mips implementation";
@@ -253,7 +253,6 @@
     int op = kMipsNop;
     int srcReg;
     RegLocation rlResult;
-
     switch (opcode) {
         case OP_INT_TO_FLOAT:
             longSrc = false;
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/Mips32/Factory.cc
index ffbb223..f76adff 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/Mips32/Factory.cc
@@ -38,21 +38,17 @@
                         r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
 #endif
 
-static void storePair(CompilationUnit *cUnit, int base, int lowReg,
-                      int highReg);
-static void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
-static MipsLIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
-                            int rDest);
-static MipsLIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
-                             int displacement, int rSrc);
-static MipsLIR *genRegRegCheck(CompilationUnit *cUnit,
-                              MipsConditionCode cond,
-                              int reg1, int reg2, int dOffset,
-                              MipsLIR *pcrLabel);
-static MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
+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,
+                      int rDest);
+MipsLIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
+                       int displacement, int rSrc);
+MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value);
 
 #ifdef __mips_hard_float
-static MipsLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+MipsLIR *fpRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
 {
     MipsLIR* res = (MipsLIR *) oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
     res->operands[0] = rDest;
@@ -94,8 +90,8 @@
  * 1) rDest is freshly returned from oatAllocTemp or
  * 2) The codegen is under fixed register usage
  */
-static MipsLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
-                                     int value)
+MipsLIR *loadConstantNoClobber(CompilationUnit *cUnit, int rDest,
+                               int value)
 {
     MipsLIR *res;
 
@@ -135,7 +131,7 @@
  * Load an immediate value into a fixed or temp register.  Target
  * register is clobbered, and marked inUse.
  */
-static MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
+MipsLIR *loadConstant(CompilationUnit *cUnit, int rDest, int value)
 {
     if (oatIsTemp(cUnit, rDest)) {
         oatClobber(cUnit, rDest);
@@ -144,24 +140,7 @@
     return loadConstantNoClobber(cUnit, rDest, value);
 }
 
-/*
- * Load a class pointer value into a fixed or temp register.  Target
- * register is clobbered, and marked inUse.
- */
-static MipsLIR *loadClassPointer(CompilationUnit *cUnit, int rDest, int value)
-{
-    MipsLIR *res;
-    if (oatIsTemp(cUnit, rDest)) {
-        oatClobber(cUnit, rDest);
-        oatMarkInUse(cUnit, rDest);
-    }
-    res = newLIR2(cUnit, kMipsLui, rDest, value>>16);
-    if (value & 0xffff)
-        newLIR3(cUnit, kMipsOri, rDest, rDest, value);
-    return res;
-}
-
-static MipsLIR *opNone(CompilationUnit *cUnit, OpKind op)
+MipsLIR *opNone(CompilationUnit *cUnit, OpKind op)
 {
     MipsLIR *res;
     MipsOpCode opcode = kMipsNop;
@@ -176,7 +155,27 @@
     return res;
 }
 
-static MipsLIR *opCompareBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
+
+MipsLIR *opCmpBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
+                           int rs, int rt)
+{
+    UNIMPLEMENTED(FATAL);
+    return 0;
+}
+MipsLIR *opCmpImmBranchCC(CompilationUnit *cUnit, MipsConditionCode cc,
+                           int rs, int immVal)
+{
+    UNIMPLEMENTED(FATAL);
+    return 0;
+}
+MipsLIR *opCmpImmBranch(CompilationUnit *cUnit, MipsOpCode cc,
+                           int rs, int immVal)
+{
+    UNIMPLEMENTED(FATAL);
+    return 0;
+}
+
+MipsLIR *opCmpBranch(CompilationUnit *cUnit, MipsOpCode opc, int rs, int rt)
 {
     MipsLIR *res;
     if (rt < 0) {
@@ -189,9 +188,9 @@
     return res;
 }
 
-static MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
+MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask);
 
-static MipsLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
+MipsLIR *opReg(CompilationUnit *cUnit, OpKind op, int rDestSrc)
 {
     MipsOpCode opcode = kMipsNop;
     switch (op) {
@@ -204,8 +203,8 @@
     return newLIR2(cUnit, opcode, r_RA, rDestSrc);
 }
 
-static MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
-                           int rSrc1, int value);
+MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
+                     int rSrc1, int value);
 MipsLIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1,
                   int value)
 {
@@ -238,7 +237,7 @@
     return res;
 }
 
-static MipsLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
+MipsLIR *opRegRegReg(CompilationUnit *cUnit, OpKind op, int rDest,
                            int rSrc1, int rSrc2)
 {
     MipsOpCode opcode = kMipsNop;
@@ -277,7 +276,7 @@
     return newLIR3(cUnit, opcode, rDest, rSrc1, rSrc2);
 }
 
-static MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
+MipsLIR *opRegRegImm(CompilationUnit *cUnit, OpKind op, int rDest,
                            int rSrc1, int value)
 {
     MipsLIR *res;
@@ -412,7 +411,7 @@
     return newLIR2(cUnit, opcode, rDestSrc1, rSrc2);
 }
 
-static MipsLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
+MipsLIR *loadConstantValueWide(CompilationUnit *cUnit, int rDestLo,
                                      int rDestHi, int valLo, int valHi)
 {
     MipsLIR *res;
@@ -422,7 +421,7 @@
 }
 
 /* Load value from base + scaled index. */
-static MipsLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
+MipsLIR *loadBaseIndexed(CompilationUnit *cUnit, int rBase,
                                int rIndex, int rDest, int scale, OpSize size)
 {
     MipsLIR *first = NULL;
@@ -479,7 +478,7 @@
 }
 
 /* store value base base + scaled index. */
-static MipsLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
+MipsLIR *storeBaseIndexed(CompilationUnit *cUnit, int rBase,
                                 int rIndex, int rSrc, int scale, OpSize size)
 {
     MipsLIR *first = NULL;
@@ -531,7 +530,7 @@
     return first;
 }
 
-static MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
+MipsLIR *loadMultiple(CompilationUnit *cUnit, int rBase, int rMask)
 {
     int i;
     int loadCnt = 0;
@@ -553,7 +552,7 @@
     return res; /* NULL always returned which should be ok since no callers use it */
 }
 
-static MipsLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
+MipsLIR *storeMultiple(CompilationUnit *cUnit, int rBase, int rMask)
 {
     int i;
     int storeCnt = 0;
@@ -575,7 +574,7 @@
     return res; /* NULL always returned which should be ok since no callers use it */
 }
 
-static MipsLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
+MipsLIR *loadBaseDispBody(CompilationUnit *cUnit, MIR *mir, int rBase,
                                 int displacement, int rDest, int rDestHi,
                                 OpSize size, int sReg)
 /*
@@ -681,7 +680,7 @@
     return load;
 }
 
-static MipsLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
+MipsLIR *loadBaseDisp(CompilationUnit *cUnit, MIR *mir, int rBase,
                             int displacement, int rDest, OpSize size,
                             int sReg)
 {
@@ -689,15 +688,15 @@
                             size, sReg);
 }
 
-static MipsLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
-                                int displacement, int rDestLo, int rDestHi,
+MipsLIR *loadBaseDispWide(CompilationUnit *cUnit, MIR *mir, int rBase,
+                          int displacement, int rDestLo, int rDestHi,
                                 int sReg)
 {
     return loadBaseDispBody(cUnit, mir, rBase, displacement, rDestLo, rDestHi,
                             kLong, sReg);
 }
 
-static MipsLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
+MipsLIR *storeBaseDispBody(CompilationUnit *cUnit, int rBase,
                                  int displacement, int rSrc, int rSrcHi,
                                  OpSize size)
 {
@@ -786,31 +785,25 @@
     return res;
 }
 
-static MipsLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
-                             int displacement, int rSrc, OpSize size)
+MipsLIR *storeBaseDisp(CompilationUnit *cUnit, int rBase,
+                       int displacement, int rSrc, OpSize size)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrc, -1, size);
 }
 
-static MipsLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
-                                 int displacement, int rSrcLo, int rSrcHi)
+MipsLIR *storeBaseDispWide(CompilationUnit *cUnit, int rBase,
+                           int displacement, int rSrcLo, int rSrcHi)
 {
     return storeBaseDispBody(cUnit, rBase, displacement, rSrcLo, rSrcHi, kLong);
 }
 
-static void storePair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
-{
-    storeWordDisp(cUnit, base, LOWORD_OFFSET, lowReg);
-    storeWordDisp(cUnit, base, HIWORD_OFFSET, highReg);
-}
-
-static void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
+void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg)
 {
     loadWordDisp(cUnit, base, LOWORD_OFFSET , lowReg);
     loadWordDisp(cUnit, base, HIWORD_OFFSET , highReg);
 }
 
-static MipsLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
+MipsLIR* genRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
 {
     MipsLIR* res;
     MipsOpCode opcode;
@@ -831,14 +824,14 @@
     return res;
 }
 
-static MipsLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+MipsLIR* genRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
 {
     MipsLIR *res = genRegCopyNoInsert(cUnit, rDest, rSrc);
     oatAppendLIR(cUnit, (LIR*)res);
     return res;
 }
 
-static void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
+void genRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
                            int srcLo, int srcHi)
 {
 #ifdef __mips_hard_float
@@ -881,10 +874,10 @@
 #endif
 }
 
-static inline MipsLIR *genRegImmCheck(CompilationUnit *cUnit,
-                                     MipsConditionCode cond, int reg,
-                                     int checkValue, int dOffset,
-                                     MipsLIR *pcrLabel)
+inline MipsLIR *genRegImmCheck(CompilationUnit *cUnit,
+                               MipsConditionCode cond, int reg,
+                               int checkValue, int dOffset,
+                               MipsLIR *pcrLabel)
 {
     MipsLIR *branch = NULL;
 
diff --git a/src/compiler/codegen/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
index f49cdab..8801692 100644
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ b/src/compiler/codegen/mips/Mips32/Gen.cc
@@ -62,10 +62,192 @@
 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
+}
+
 
 
 
@@ -102,7 +284,7 @@
 }
 #endif
 /*
- * Insert a kMipsPseudoCaseLabel at the beginning of the Dalvik
+ * 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
@@ -117,7 +299,7 @@
     }
     MipsLIR* newLabel = (MipsLIR*)oatNew(cUnit, sizeof(MipsLIR), true, kAllocLIR);
     newLabel->generic.dalvikOffset = vaddr;
-    newLabel->opcode = kMipsPseudoCaseLabel;
+    newLabel->opcode = kPseudoCaseLabel;
     newLabel->operands[0] = keyVal;
     oatInsertLIRAfter(it->second, (LIR*)newLabel);
     return newLabel;
@@ -269,7 +451,7 @@
     int rIdx = oatAllocTemp(cUnit);
     loadConstant(cUnit, rIdx, size);
     // Establish loop branch target
-    MipsLIR* target = newLIR0(cUnit, kMipsPseudoTargetLabel);
+    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     // Load next key/disp
     newLIR2(cUnit, kThumb2LdmiaWB, rBase, (1 << rKey) | (1 << rDisp));
@@ -331,7 +513,7 @@
     tabRec->bxInst = switchBranch;
 
     /* branchOver target here */
-    MipsLIR* target = newLIR0(cUnit, kMipsPseudoTargetLabel);
+    MipsLIR* target = newLIR0(cUnit, kPseudoTargetLabel);
     target->defMask = ENCODE_ALL;
     branchOver->generic.target = (LIR*)target;
 #endif
diff --git a/src/compiler/codegen/mips/MipsLIR.h b/src/compiler/codegen/mips/MipsLIR.h
index a6f426e..44f0c5a 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/MipsLIR.h
@@ -193,42 +193,6 @@
 #define DECODE_ALIAS_INFO_REG(X)        (X & 0xffff)
 #define DECODE_ALIAS_INFO_WIDE(X)       ((X & 0x80000000) ? 1 : 0)
 
-typedef enum OpKind {
-    kOpMov,
-    kOpMvn,
-    kOpCmp,
-    kOpLsl,
-    kOpLsr,
-    kOpAsr,
-    kOpRor,
-    kOpNot,
-    kOpAnd,
-    kOpOr,
-    kOpXor,
-    kOpNeg,
-    kOpAdd,
-    kOpAdc,
-    kOpSub,
-    kOpSbc,
-    kOpRsub,
-    kOpMul,
-    kOpDiv,
-    kOpRem,
-    kOpBic,
-    kOpCmn,
-    kOpTst,
-    kOpBkpt,
-    kOpBlx,
-    kOpPush,
-    kOpPop,
-    kOp2Char,
-    kOp2Short,
-    kOp2Byte,
-    kOpCondBr,
-    kOpUncondBr,
-    kOpInvalid,
-} OpKind;
-
 /*
  * FIXME:
  * Originally had r4PC as r_S0, rFP as r_S1, rSELF as r_S2, rINST as r_S4
@@ -240,8 +204,13 @@
 #define rSELF r_S1
 #define rSP r_SP
 
-/* FIXME: don't do this - find and fix all rLR's */
-#define rLR r_RA
+#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:
@@ -376,7 +345,7 @@
     kMipsThrowStackOverflow,
 } MipsThrowKind;
 
-#define isPseudoOpCode(opCode) ((int)(opCode) < 0)
+#define isPseudoOpcode(opCode) ((int)(opCode) < 0)
 
 /*
  * The following enum defines the list of supported Thumb instructions by the
@@ -384,21 +353,21 @@
  * Assemble.c.
  */
 typedef enum MipsOpCode {
-    kMipsPseudoSuspendTarget = -15,
-    kMipsPseudoThrowTarget = -14,
-    kMipsPseudoCaseLabel = -13,
-    kMipsPseudoMethodEntry = -12,
-    kMipsPseudoMethodExit = -11,
-    kMipsPseudoBarrier = -10,
-    kMipsPseudoExtended = -9,
-    kMipsPseudoSSARep = -8,
-    kMipsPseudoEntryBlock = -7,
-    kMipsPseudoExitBlock = -6,
-    kMipsPseudoTargetLabel = -5,
-    kMipsPseudoDalvikByteCodeBoundary = -4,
-    kMipsPseudoPseudoAlign4 = -3,
-    kMipsPseudoEHBlockLabel = -2,
-    kMipsPseudoNormalBlockLabel = -1,
+    kPseudoSuspendTarget = -15,
+    kPseudoThrowTarget = -14,
+    kPseudoCaseLabel = -13,
+    kPseudoMethodEntry = -12,
+    kPseudoMethodExit = -11,
+    kPseudoBarrier = -10,
+    kPseudoExtended = -9,
+    kPseudoSSARep = -8,
+    kPseudoEntryBlock = -7,
+    kPseudoExitBlock = -6,
+    kPseudoTargetLabel = -5,
+    kPseudoDalvikByteCodeBoundary = -4,
+    kPseudoPseudoAlign4 = -3,
+    kPseudoEHBlockLabel = -2,
+    kPseudoNormalBlockLabel = -1,
 
     kMipsFirst,
     kMips32BitData = kMipsFirst, /* data [31..0] */
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
index a243415..0dfbfa5 100644
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ b/src/compiler/codegen/mips/MipsRallocUtil.cc
@@ -28,12 +28,24 @@
 namespace art {
 
 /*
+ * TUNING: is leaf?  Can't just use "hasInvoke" to determine as some
+ * instructions might call out to C/assembly helper functions.  Until
+ * machinery is in place, always spill lr.
+ */
+
+void oatAdjustSpillMask(CompilationUnit* cUnit)
+{
+    cUnit->coreSpillMask |= (1 << r_RA);
+    cUnit->numCoreSpills++;
+}
+
+/*
  * Mark a callee-save fp register as promoted.  Note that
  * vpush/vpop uses contiguous register lists so we must
  * include any holes in the mask.  Associate holes with
  * Dalvik register INVALID_VREG (0xFFFFU).
  */
-STATIC void markPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
+void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
 {
     UNIMPLEMENTED(FATAL) << "No support yet for promoted FP regs";
 #if 0
@@ -206,4 +218,10 @@
     oatFreeTemp(cUnit, r_A3);
 }
 
+/* Convert an instruction to a NOP */
+STATIC void oatNopLIR( LIR* lir)
+{
+    ((MipsLIR*)lir)->flags.isNop = true;
+}
+
 }  // namespace art
diff --git a/src/compiler/codegen/mips/mips/ArchVariant.cc b/src/compiler/codegen/mips/mips/ArchVariant.cc
index 5eca74b..dd46f24 100644
--- a/src/compiler/codegen/mips/mips/ArchVariant.cc
+++ b/src/compiler/codegen/mips/mips/ArchVariant.cc
@@ -25,9 +25,9 @@
  * Determine the initial instruction set to be used for this trace.
  * Later components may decide to change this.
  */
-JitInstructionSetType oatInstructionSet(void)
+OatInstructionSetType oatInstructionSet(void)
 {
-    return DALVIK_OAT_MIPS;
+    return DALVIK_OAT_MIPS32;
 }
 
 /* Architecture-specific initializations and checks go here */
diff --git a/src/compiler/codegen/mips/mips/Codegen.cc b/src/compiler/codegen/mips/mips/Codegen.cc
index 2b71b04..22a7c94 100644
--- a/src/compiler/codegen/mips/mips/Codegen.cc
+++ b/src/compiler/codegen/mips/mips/Codegen.cc
@@ -17,9 +17,6 @@
 #define _CODEGEN_C
 #define TGT_LIR MipsLIR
 
-/* For testing */
-#define __mips_hard_float
-
 #include "../../../Dalvik.h"
 #include "../../../CompilerInternals.h"
 #include "../MipsLIR.h"
