diff --git a/src/compiler/codegen/arm/ArchFactory.cc b/src/compiler/codegen/arm/ArchFactory.cc
deleted file mode 100644
index f75d8e3..0000000
--- a/src/compiler/codegen/arm/ArchFactory.cc
+++ /dev/null
@@ -1,227 +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.
- */
-
-/* This file contains arm-specific codegen factory support. */
-
-#include "oat/runtime/oat_support_entrypoints.h"
-
-namespace art {
-
-bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc)
-{
-  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  int zReg = oatAllocTemp(cUnit);
-  loadConstantNoClobber(cUnit, zReg, 0);
-  // Check for destructive overlap
-  if (rlResult.lowReg == rlSrc.highReg) {
-    int tReg = oatAllocTemp(cUnit);
-    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, zReg, rlSrc.lowReg);
-    opRegRegReg(cUnit, kOpSbc, rlResult.highReg, zReg, tReg);
-    oatFreeTemp(cUnit, tReg);
-  } else {
-    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, zReg, rlSrc.lowReg);
-    opRegRegReg(cUnit, kOpSbc, rlResult.highReg, zReg, rlSrc.highReg);
-  }
-  oatFreeTemp(cUnit, zReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-int loadHelper(CompilationUnit* cUnit, int offset)
-{
-  loadWordDisp(cUnit, rARM_SELF, offset, rARM_LR);
-  return rARM_LR;
-}
-
-void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
-                      RegLocation rlMethod)
-{
-  int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
-  /*
-   * On entry, r0, r1, r2 & r3 are live.  Let the register allocation
-   * mechanism know so it doesn't try to use any of them when
-   * expanding the frame or flushing.  This leaves the utility
-   * code with a single temp: r12.  This should be enough.
-   */
-  oatLockTemp(cUnit, r0);
-  oatLockTemp(cUnit, r1);
-  oatLockTemp(cUnit, r2);
-  oatLockTemp(cUnit, r3);
-
-  /*
-   * We can safely skip the stack overflow check if we're
-   * a leaf *and* our frame size < fudge factor.
-   */
-  bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) &&
-                            ((size_t)cUnit->frameSize <
-                            Thread::kStackOverflowReservedBytes));
-  newLIR0(cUnit, kPseudoMethodEntry);
-  if (!skipOverflowCheck) {
-    /* Load stack limit */
-    loadWordDisp(cUnit, rARM_SELF, Thread::StackEndOffset().Int32Value(), r12);
-  }
-  /* Spill core callee saves */
-  newLIR1(cUnit, kThumb2Push, cUnit->coreSpillMask);
-  /* Need to spill any FP regs? */
-  if (cUnit->numFPSpills) {
-    /*
-     * NOTE: fp spills are a little different from core spills in that
-     * they are pushed as a contiguous block.  When promoting from
-     * the fp set, we must allocate all singles from s16..highest-promoted
-     */
-    newLIR1(cUnit, kThumb2VPushCS, cUnit->numFPSpills);
-  }
-  if (!skipOverflowCheck) {
-    opRegRegImm(cUnit, kOpSub, rARM_LR, rARM_SP, cUnit->frameSize - (spillCount * 4));
-    genRegRegCheck(cUnit, kCondCc, rARM_LR, r12, kThrowStackOverflow);
-    opRegCopy(cUnit, rARM_SP, rARM_LR);     // Establish stack
-  } else {
-    opRegImm(cUnit, kOpSub, rARM_SP, cUnit->frameSize - (spillCount * 4));
-  }
-
-  flushIns(cUnit, argLocs, rlMethod);
-
-  oatFreeTemp(cUnit, r0);
-  oatFreeTemp(cUnit, r1);
-  oatFreeTemp(cUnit, r2);
-  oatFreeTemp(cUnit, r3);
-}
-
-void genExitSequence(CompilationUnit* cUnit)
-{
-  int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
-  /*
-   * In the exit path, r0/r1 are live - make sure they aren't
-   * allocated by the register utilities as temps.
-   */
-  oatLockTemp(cUnit, r0);
-  oatLockTemp(cUnit, r1);
-
-  newLIR0(cUnit, kPseudoMethodExit);
-  opRegImm(cUnit, kOpAdd, rARM_SP, cUnit->frameSize - (spillCount * 4));
-  /* Need to restore any FP callee saves? */
-  if (cUnit->numFPSpills) {
-    newLIR1(cUnit, kThumb2VPopCS, cUnit->numFPSpills);
-  }
-  if (cUnit->coreSpillMask & (1 << rARM_LR)) {
-    /* Unspill rARM_LR to rARM_PC */
-    cUnit->coreSpillMask &= ~(1 << rARM_LR);
-    cUnit->coreSpillMask |= (1 << rARM_PC);
-  }
-  newLIR1(cUnit, kThumb2Pop, cUnit->coreSpillMask);
-  if (!(cUnit->coreSpillMask & (1 << rARM_PC))) {
-    /* We didn't pop to rARM_PC, so must do a bv rARM_LR */
-    newLIR1(cUnit, kThumbBx, rARM_LR);
-  }
-}
-
-/*
- * Nop any unconditional branches that go to the next instruction.
- * Note: new redundant branches may be inserted later, and we'll
- * use a check in final instruction assembly to nop those out.
- */
-void removeRedundantBranches(CompilationUnit* cUnit)
-{
-  LIR* thisLIR;
-
-  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)) {
-      LIR* nextLIR = thisLIR;
-
-      while (true) {
-        nextLIR = NEXT_LIR(nextLIR);
-
-        /*
-         * Is the branch target the next instruction?
-         */
-        if (nextLIR == (LIR*) thisLIR->target) {
-          thisLIR->flags.isNop = true;
-          break;
-        }
-
-        /*
-         * Found real useful stuff between the branch and the target.
-         * Need to explicitly check the lastLIRInsn here because it
-         * might be the last real instruction.
-         */
-        if (!isPseudoOpcode(nextLIR->opcode) ||
-          (nextLIR = (LIR*) cUnit->lastLIRInsn))
-          break;
-      }
-    }
-  }
-}
-
-
-/* Common initialization routine for an architecture family */
-bool oatArchInit()
-{
-  int i;
-
-  for (i = 0; i < kArmLast; i++) {
-    if (EncodingMap[i].opcode != i) {
-      LOG(FATAL) << "Encoding order for " << EncodingMap[i].name
-                 << " is wrong: expecting " << i << ", seeing "
-                 << (int)EncodingMap[i].opcode;
-    }
-  }
-
-  return oatArchVariantInit();
-}
-
-bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genAddLong for Arm";
-  return false;
-}
-
-bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genSubLong for Arm";
-  return false;
-}
-
-bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genAndLong for Arm";
-  return false;
-}
-
-bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
-               RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genOrLong for Arm";
-  return false;
-}
-
-bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
-               RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genXoLong for Arm";
-  return false;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/ArchUtility.cc b/src/compiler/codegen/arm/ArchUtility.cc
deleted file mode 100644
index 2d4b314..0000000
--- a/src/compiler/codegen/arm/ArchUtility.cc
+++ /dev/null
@@ -1,512 +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.
- */
-
-#include "../../CompilerInternals.h"
-#include "ArmLIR.h"
-#include "../Ralloc.h"
-
-#include <string>
-
-namespace art {
-
-RegLocation locCReturn()
-{
-  RegLocation res = ARM_LOC_C_RETURN;
-  return res;
-}
-
-RegLocation locCReturnWide()
-{
-  RegLocation res = ARM_LOC_C_RETURN_WIDE;
-  return res;
-}
-
-RegLocation locCReturnFloat()
-{
-  RegLocation res = ARM_LOC_C_RETURN_FLOAT;
-  return res;
-}
-
-RegLocation locCReturnDouble()
-{
-  RegLocation res = ARM_LOC_C_RETURN_DOUBLE;
-  return res;
-}
-
-// Return a target-dependent special register.
-int targetReg(SpecialTargetRegister reg) {
-  int res = INVALID_REG;
-  switch (reg) {
-    case kSelf: res = rARM_SELF; break;
-    case kSuspend: res =  rARM_SUSPEND; break;
-    case kLr: res =  rARM_LR; break;
-    case kPc: res =  rARM_PC; break;
-    case kSp: res =  rARM_SP; break;
-    case kArg0: res = rARM_ARG0; break;
-    case kArg1: res = rARM_ARG1; break;
-    case kArg2: res = rARM_ARG2; break;
-    case kArg3: res = rARM_ARG3; break;
-    case kFArg0: res = rARM_FARG0; break;
-    case kFArg1: res = rARM_FARG1; break;
-    case kFArg2: res = rARM_FARG2; break;
-    case kFArg3: res = rARM_FARG3; break;
-    case kRet0: res = rARM_RET0; break;
-    case kRet1: res = rARM_RET1; break;
-    case kInvokeTgt: res = rARM_INVOKE_TGT; break;
-    case kCount: res = rARM_COUNT; break;
-  }
-  return res;
-}
-
-
-// Create a double from a pair of singles.
-int s2d(int lowReg, int highReg)
-{
-  return ARM_S2D(lowReg, highReg);
-}
-
-// Is reg a single or double?
-bool fpReg(int reg)
-{
-  return ARM_FPREG(reg);
-}
-
-// Is reg a single?
-bool singleReg(int reg)
-{
-  return ARM_SINGLEREG(reg);
-}
-
-// Is reg a double?
-bool doubleReg(int reg)
-{
-  return ARM_DOUBLEREG(reg);
-}
-
-// Return mask to strip off fp reg flags and bias.
-uint32_t fpRegMask()
-{
-  return ARM_FP_REG_MASK;
-}
-
-// True if both regs single, both core or both double.
-bool sameRegType(int reg1, int reg2)
-{
-  return (ARM_REGTYPE(reg1) == ARM_REGTYPE(reg2));
-}
-
-/*
- * Decode the register id.
- */
-u8 getRegMaskCommon(CompilationUnit* cUnit, int reg)
-{
-  u8 seed;
-  int shift;
-  int regId;
-
-
-  regId = reg & 0x1f;
-  /* Each double register is equal to a pair of single-precision FP registers */
-  seed = ARM_DOUBLEREG(reg) ? 3 : 1;
-  /* FP register starts at bit position 16 */
-  shift = ARM_FPREG(reg) ? kArmFPReg0 : 0;
-  /* Expand the double register id into single offset */
-  shift += regId;
-  return (seed << shift);
-}
-
-uint64_t getPCUseDefEncoding()
-{
-  return ENCODE_ARM_REG_PC;
-}
-
-void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
-{
-  DCHECK_EQ(cUnit->instructionSet, kThumb2);
-
-  // Thumb2 specific setup
-  uint64_t flags = EncodingMap[lir->opcode].flags;
-  int opcode = lir->opcode;
-
-  if (flags & REG_DEF_SP) {
-    lir->defMask |= ENCODE_ARM_REG_SP;
-  }
-
-  if (flags & REG_USE_SP) {
-    lir->useMask |= ENCODE_ARM_REG_SP;
-  }
-
-  if (flags & REG_DEF_LIST0) {
-    lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[0]);
-  }
-
-  if (flags & REG_DEF_LIST1) {
-    lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[1]);
-  }
-
-  if (flags & REG_DEF_FPCS_LIST0) {
-    lir->defMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]);
-  }
-
-  if (flags & REG_DEF_FPCS_LIST2) {
-    for (int i = 0; i < lir->operands[2]; i++) {
-      oatSetupRegMask(cUnit, &lir->defMask, lir->operands[1] + i);
-    }
-  }
-
-  if (flags & REG_USE_PC) {
-    lir->useMask |= ENCODE_ARM_REG_PC;
-  }
-
-  /* Conservatively treat the IT block */
-  if (flags & IS_IT) {
-    lir->defMask = ENCODE_ALL;
-  }
-
-  if (flags & REG_USE_LIST0) {
-    lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[0]);
-  }
-
-  if (flags & REG_USE_LIST1) {
-    lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[1]);
-  }
-
-  if (flags & REG_USE_FPCS_LIST0) {
-    lir->useMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]);
-  }
-
-  if (flags & REG_USE_FPCS_LIST2) {
-    for (int i = 0; i < lir->operands[2]; i++) {
-      oatSetupRegMask(cUnit, &lir->useMask, lir->operands[1] + i);
-    }
-  }
-  /* Fixup for kThumbPush/lr and kThumbPop/pc */
-  if (opcode == kThumbPush || opcode == kThumbPop) {
-    u8 r8Mask = oatGetRegMaskCommon(cUnit, r8);
-    if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) {
-      lir->useMask &= ~r8Mask;
-      lir->useMask |= ENCODE_ARM_REG_LR;
-    } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) {
-      lir->defMask &= ~r8Mask;
-      lir->defMask |= ENCODE_ARM_REG_PC;
-    }
-  }
-  if (flags & REG_DEF_LR) {
-    lir->defMask |= ENCODE_ARM_REG_LR;
-  }
-}
-
-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",
-  "r2",
-  "r3",
-  "r4",
-  "r5",
-  "r6",
-  "r7",
-  "r8",
-  "rSELF",
-  "r10",
-  "r11",
-  "r12",
-  "sp",
-  "lr",
-  "pc",
-};
-
-
-static const char* shiftNames[4] = {
-  "lsl",
-  "lsr",
-  "asr",
-  "ror"};
-
-/* Decode and print a ARM register name */
-char* decodeRegList(int opcode, int vector, char* buf)
-{
-  int i;
-  bool printed = false;
-  buf[0] = 0;
-  for (i = 0; i < 16; i++, vector >>= 1) {
-    if (vector & 0x1) {
-      int regId = i;
-      if (opcode == kThumbPush && i == 8) {
-        regId = r14lr;
-      } else if (opcode == kThumbPop && i == 8) {
-        regId = r15pc;
-      }
-      if (printed) {
-        sprintf(buf + strlen(buf), ", r%d", regId);
-      } else {
-        printed = true;
-        sprintf(buf, "r%d", regId);
-      }
-    }
-  }
-  return buf;
-}
-
-char*  decodeFPCSRegList(int count, int base, char* buf)
-{
-  sprintf(buf, "s%d", base);
-  for (int i = 1; i < count; i++) {
-    sprintf(buf + strlen(buf), ", s%d",base + i);
-  }
-  return buf;
-}
-
-int expandImmediate(int value)
-{
-  int mode = (value & 0xf00) >> 8;
-  u4 bits = value & 0xff;
-  switch (mode) {
-    case 0:
-      return bits;
-     case 1:
-      return (bits << 16) | bits;
-     case 2:
-      return (bits << 24) | (bits << 8);
-     case 3:
-      return (bits << 24) | (bits << 16) | (bits << 8) | bits;
-    default:
-      break;
-  }
-  bits = (bits | 0x80) << 24;
-  return bits >> (((value & 0xf80) >> 7) - 8);
-}
-
-const char* ccNames[] = {"eq","ne","cs","cc","mi","pl","vs","vc",
-                         "hi","ls","ge","lt","gt","le","al","nv"};
-/*
- * Interpret a format string and build a string no longer than size
- * See format key in Assemble.c.
- */
-std::string buildInsnString(const char* fmt, LIR* lir, unsigned char* baseAddr)
-{
-  std::string buf;
-  int i;
-  const char* fmtEnd = &fmt[strlen(fmt)];
-  char tbuf[256];
-  const char* name;
-  char nc;
-  while (fmt < fmtEnd) {
-    int operand;
-    if (*fmt == '!') {
-      fmt++;
-      DCHECK_LT(fmt, fmtEnd);
-      nc = *fmt++;
-      if (nc=='!') {
-        strcpy(tbuf, "!");
-      } else {
-         DCHECK_LT(fmt, fmtEnd);
-         DCHECK_LT((unsigned)(nc-'0'), 4U);
-         operand = lir->operands[nc-'0'];
-         switch (*fmt++) {
-           case 'H':
-             if (operand != 0) {
-               sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3], operand >> 2);
-             } else {
-               strcpy(tbuf,"");
-             }
-             break;
-           case 'B':
-             switch (operand) {
-               case kSY:
-                 name = "sy";
-                 break;
-               case kST:
-                 name = "st";
-                 break;
-               case kISH:
-                 name = "ish";
-                 break;
-               case kISHST:
-                 name = "ishst";
-                 break;
-               case kNSH:
-                 name = "nsh";
-                 break;
-               case kNSHST:
-                 name = "shst";
-                 break;
-               default:
-                 name = "DecodeError2";
-                 break;
-             }
-             strcpy(tbuf, name);
-             break;
-           case 'b':
-             strcpy(tbuf,"0000");
-             for (i=3; i>= 0; i--) {
-               tbuf[i] += operand & 1;
-               operand >>= 1;
-             }
-             break;
-           case 'n':
-             operand = ~expandImmediate(operand);
-             sprintf(tbuf,"%d [%#x]", operand, operand);
-             break;
-           case 'm':
-             operand = expandImmediate(operand);
-             sprintf(tbuf,"%d [%#x]", operand, operand);
-             break;
-           case 's':
-             sprintf(tbuf,"s%d",operand & ARM_FP_REG_MASK);
-             break;
-           case 'S':
-             sprintf(tbuf,"d%d",(operand & ARM_FP_REG_MASK) >> 1);
-             break;
-           case 'h':
-             sprintf(tbuf,"%04x", operand);
-             break;
-           case 'M':
-           case 'd':
-             sprintf(tbuf,"%d", operand);
-             break;
-           case 'C':
-             DCHECK_LT(operand, static_cast<int>(
-                 sizeof(coreRegNames)/sizeof(coreRegNames[0])));
-             sprintf(tbuf,"%s",coreRegNames[operand]);
-             break;
-           case 'E':
-             sprintf(tbuf,"%d", operand*4);
-             break;
-           case 'F':
-             sprintf(tbuf,"%d", operand*2);
-             break;
-           case 'c':
-             strcpy(tbuf, ccNames[operand]);
-             break;
-           case 't':
-             sprintf(tbuf,"0x%08x (L%p)",
-                 (int) baseAddr + lir->offset + 4 +
-                 (operand << 1),
-                 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->offset + 4) &
-                 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
-                 0xfffffffc;
-             sprintf(tbuf, "%p", (void *) target);
-             break;
-          }
-
-           /* Nothing to print for BLX_2 */
-           case 'v':
-             strcpy(tbuf, "see above");
-             break;
-           case 'R':
-             decodeRegList(lir->opcode, operand, tbuf);
-             break;
-           case 'P':
-             decodeFPCSRegList(operand, 16, tbuf);
-             break;
-           case 'Q':
-             decodeFPCSRegList(operand, 0, tbuf);
-             break;
-           default:
-             strcpy(tbuf,"DecodeError1");
-             break;
-        }
-        buf += tbuf;
-      }
-    } else {
-       buf += *fmt++;
-    }
-  }
-  return buf;
-}
-
-void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix)
-{
-  char buf[256];
-  buf[0] = 0;
-  LIR* armLIR = (LIR*) lir;
-
-  if (mask == ENCODE_ALL) {
-    strcpy(buf, "all");
-  } else {
-    char num[8];
-    int i;
-
-    for (i = 0; i < kArmRegEnd; i++) {
-      if (mask & (1ULL << i)) {
-        sprintf(num, "%d ", i);
-        strcat(buf, num);
-      }
-    }
-
-    if (mask & ENCODE_CCODE) {
-      strcat(buf, "cc ");
-    }
-    if (mask & ENCODE_FP_STATUS) {
-      strcat(buf, "fpcc ");
-    }
-
-    /* Memory bits */
-    if (armLIR && (mask & ENCODE_DALVIK_REG)) {
-      sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff,
-              (armLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
-    }
-    if (mask & ENCODE_LITERAL) {
-      strcat(buf, "lit ");
-    }
-
-    if (mask & ENCODE_HEAP_REF) {
-      strcat(buf, "heap ");
-    }
-    if (mask & ENCODE_MUST_NOT_ALIAS) {
-      strcat(buf, "noalias ");
-    }
-  }
-  if (buf[0]) {
-    LOG(INFO) << prefix << ": " << buf;
-  }
-}
-
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/ArmRallocUtil.cc b/src/compiler/codegen/arm/ArmRallocUtil.cc
deleted file mode 100644
index 05fe7fa..0000000
--- a/src/compiler/codegen/arm/ArmRallocUtil.cc
+++ /dev/null
@@ -1,186 +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.
- */
-
-/*
- * This file contains Arm-specific register allocation support.
- */
-
-#include "../../CompilerUtility.h"
-#include "../../CompilerIR.h"
-#include "../..//Dataflow.h"
-#include "ArmLIR.h"
-#include "Codegen.h"
-#include "../Ralloc.h"
-
-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 << rARM_LR);
-  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).
- */
-void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg)
-{
-  DCHECK_GE(reg, ARM_FP_REG_MASK + ARM_FP_CALLEE_SAVE_BASE);
-  reg = (reg & ARM_FP_REG_MASK) - ARM_FP_CALLEE_SAVE_BASE;
-  // Ensure fpVmapTable is large enough
-  int tableSize = cUnit->fpVmapTable.size();
-  for (int i = tableSize; i < (reg + 1); i++) {
-    cUnit->fpVmapTable.push_back(INVALID_VREG);
-  }
-  // Add the current mapping
-  cUnit->fpVmapTable[reg] = vReg;
-  // Size of fpVmapTable is high-water mark, use to set mask
-  cUnit->numFPSpills = cUnit->fpVmapTable.size();
-  cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << ARM_FP_CALLEE_SAVE_BASE;
-}
-
-void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
-{
-  RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
-  RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
-  DCHECK(info1 && info2 && info1->pair && info2->pair &&
-       (info1->partner == info2->reg) &&
-       (info2->partner == info1->reg));
-  if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
-    if (!(info1->isTemp && info2->isTemp)) {
-      /* Should not happen.  If it does, there's a problem in evalLoc */
-      LOG(FATAL) << "Long half-temp, half-promoted";
-    }
-
-    info1->dirty = false;
-    info2->dirty = false;
-    if (SRegToVReg(cUnit, info2->sReg) <
-      SRegToVReg(cUnit, info1->sReg))
-      info1 = info2;
-    int vReg = SRegToVReg(cUnit, info1->sReg);
-    oatFlushRegWideImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg),
-                        info1->reg, info1->partner);
-  }
-}
-
-void oatFlushReg(CompilationUnit* cUnit, int reg)
-{
-  RegisterInfo* info = oatGetRegInfo(cUnit, reg);
-  if (info->live && info->dirty) {
-    info->dirty = false;
-    int vReg = SRegToVReg(cUnit, info->sReg);
-    oatFlushRegImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
-  }
-}
-
-/* Give access to the target-dependent FP register encoding to common code */
-bool oatIsFpReg(int reg) {
-  return ARM_FPREG(reg);
-}
-
-uint32_t oatFpRegMask() {
-  return ARM_FP_REG_MASK;
-}
-
-/* Clobber all regs that might be used by an external C call */
-void oatClobberCalleeSave(CompilationUnit *cUnit)
-{
-  oatClobber(cUnit, r0);
-  oatClobber(cUnit, r1);
-  oatClobber(cUnit, r2);
-  oatClobber(cUnit, r3);
-  oatClobber(cUnit, r12);
-  oatClobber(cUnit, r14lr);
-  oatClobber(cUnit, fr0);
-  oatClobber(cUnit, fr1);
-  oatClobber(cUnit, fr2);
-  oatClobber(cUnit, fr3);
-  oatClobber(cUnit, fr4);
-  oatClobber(cUnit, fr5);
-  oatClobber(cUnit, fr6);
-  oatClobber(cUnit, fr7);
-  oatClobber(cUnit, fr8);
-  oatClobber(cUnit, fr9);
-  oatClobber(cUnit, fr10);
-  oatClobber(cUnit, fr11);
-  oatClobber(cUnit, fr12);
-  oatClobber(cUnit, fr13);
-  oatClobber(cUnit, fr14);
-  oatClobber(cUnit, fr15);
-}
-
-extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
-{
-  RegLocation res = locCReturnWide();
-  res.lowReg = r2;
-  res.highReg = r3;
-  oatClobber(cUnit, r2);
-  oatClobber(cUnit, r3);
-  oatMarkInUse(cUnit, r2);
-  oatMarkInUse(cUnit, r3);
-  oatMarkPair(cUnit, res.lowReg, res.highReg);
-  return res;
-}
-
-extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
-{
-  RegLocation res = locCReturn();
-  res.lowReg = r1;
-  oatClobber(cUnit, r1);
-  oatMarkInUse(cUnit, r1);
-  return res;
-}
-
-extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
-{
-  return ARM_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & ARM_FP_REG_MASK]
-      : &cUnit->regPool->coreRegs[reg];
-}
-
-/* To be used when explicitly managing register use */
-extern void oatLockCallTemps(CompilationUnit* cUnit)
-{
-  oatLockTemp(cUnit, r0);
-  oatLockTemp(cUnit, r1);
-  oatLockTemp(cUnit, r2);
-  oatLockTemp(cUnit, r3);
-}
-
-/* To be used when explicitly managing register use */
-extern void oatFreeCallTemps(CompilationUnit* cUnit)
-{
-  oatFreeTemp(cUnit, r0);
-  oatFreeTemp(cUnit, r1);
-  oatFreeTemp(cUnit, r2);
-  oatFreeTemp(cUnit, r3);
-}
-
-/* Convert an instruction to a NOP */
-void oatNopLIR( LIR* lir)
-{
-  ((LIR*)lir)->flags.isNop = true;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/Thumb2/Gen.cc b/src/compiler/codegen/arm/Thumb2/Gen.cc
deleted file mode 100644
index 0a8e579..0000000
--- a/src/compiler/codegen/arm/Thumb2/Gen.cc
+++ /dev/null
@@ -1,1063 +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.
- */
-
-/* This file contains codegen for the Thumb2 ISA. */
-
-#include "oat_compilation_unit.h"
-#include "oat/runtime/oat_support_entrypoints.h"
-
-namespace art {
-
-
-/* Return the position of an ssa name within the argument list */
-int inPosition(CompilationUnit* cUnit, int sReg)
-{
-  int vReg = SRegToVReg(cUnit, sReg);
-  return vReg - cUnit->numRegs;
-}
-
-/*
- * Describe an argument.  If it's already in an arg register, just leave it
- * there.  NOTE: all live arg registers must be locked prior to this call
- * to avoid having them allocated as a temp by downstream utilities.
- */
-RegLocation argLoc(CompilationUnit* cUnit, RegLocation loc)
-{
-  int argNum = inPosition(cUnit, loc.sRegLow);
-  if (loc.wide) {
-    if (argNum == 2) {
-      // Bad case - half in register, half in frame.  Just punt
-      loc.location = kLocInvalid;
-    } else if (argNum < 2) {
-      loc.lowReg = rARM_ARG1 + argNum;
-      loc.highReg = loc.lowReg + 1;
-      loc.location = kLocPhysReg;
-    } else {
-      loc.location = kLocDalvikFrame;
-    }
-  } else {
-    if (argNum < 3) {
-      loc.lowReg = rARM_ARG1 + argNum;
-      loc.location = kLocPhysReg;
-    } else {
-      loc.location = kLocDalvikFrame;
-    }
-  }
-  return loc;
-}
-
-/*
- * Load an argument.  If already in a register, just return.  If in
- * the frame, we can't use the normal loadValue() because it assumed
- * a proper frame - and we're frameless.
- */
-RegLocation loadArg(CompilationUnit* cUnit, RegLocation loc)
-{
-  if (loc.location == kLocDalvikFrame) {
-    int start = (inPosition(cUnit, loc.sRegLow) + 1) * sizeof(uint32_t);
-    loc.lowReg = oatAllocTemp(cUnit);
-    loadWordDisp(cUnit, rARM_SP, start, loc.lowReg);
-    if (loc.wide) {
-      loc.highReg = oatAllocTemp(cUnit);
-      loadWordDisp(cUnit, rARM_SP, start + sizeof(uint32_t), loc.highReg);
-    }
-    loc.location = kLocPhysReg;
-  }
-  return loc;
-}
-
-/* Lock any referenced arguments that arrive in registers */
-void lockLiveArgs(CompilationUnit* cUnit, MIR* mir)
-{
-  int firstIn = cUnit->numRegs;
-  const int numArgRegs = 3;  // TODO: generalize & move to RegUtil.cc
-  for (int i = 0; i < mir->ssaRep->numUses; i++) {
-    int vReg = SRegToVReg(cUnit, mir->ssaRep->uses[i]);
-    int inPosition = vReg - firstIn;
-    if (inPosition < numArgRegs) {
-      oatLockTemp(cUnit, rARM_ARG1 + inPosition);
-    }
-  }
-}
-
-/* Find the next MIR, which may be in a following basic block */
-MIR* getNextMir(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir)
-{
-  BasicBlock* bb = *pBb;
-  MIR* origMir = mir;
-  while (bb != NULL) {
-    if (mir != NULL) {
-      mir = mir->next;
-    }
-    if (mir != NULL) {
-      return mir;
-    } else {
-      bb = bb->fallThrough;
-      *pBb = bb;
-      if (bb) {
-         mir = bb->firstMIRInsn;
-         if (mir != NULL) {
-           return mir;
-         }
-      }
-    }
-  }
-  return origMir;
-}
-
-/* Used for the "printMe" listing */
-void genPrintLabel(CompilationUnit *cUnit, MIR* mir)
-{
-  /* Mark the beginning of a Dalvik instruction for line tracking */
-  char* instStr = cUnit->printMe ?
-     oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
-  markBoundary(cUnit, mir->offset, instStr);
-  /* Don't generate the SSA annotation unless verbose mode is on */
-  if (cUnit->printMe && mir->ssaRep) {
-    char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
-    newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
-  }
-}
-
-MIR* specialIGet(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
-                 OpSize size, bool longOrDouble, bool isObject)
-{
-  int fieldOffset;
-  bool isVolatile;
-  uint32_t fieldIdx = mir->dalvikInsn.vC;
-  bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
-  if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
-    return NULL;
-  }
-  RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
-  lockLiveArgs(cUnit, mir);
-  rlObj = argLoc(cUnit, rlObj);
-  RegLocation rlDest;
-  if (longOrDouble) {
-    rlDest = oatGetReturnWide(cUnit, false);
-  } else {
-    rlDest = oatGetReturn(cUnit, false);
-  }
-  // Point of no return - no aborts after this
-  genPrintLabel(cUnit, mir);
-  rlObj = loadArg(cUnit, rlObj);
-  genIGet(cUnit, fieldIdx, mir->optimizationFlags, size, rlDest, rlObj,
-          longOrDouble, isObject);
-  return getNextMir(cUnit, bb, mir);
-}
-
-MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
-                 OpSize size, bool longOrDouble, bool isObject)
-{
-  int fieldOffset;
-  bool isVolatile;
-  uint32_t fieldIdx = mir->dalvikInsn.vC;
-  bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
-  if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
-    return NULL;
-  }
-  RegLocation rlSrc;
-  RegLocation rlObj;
-  lockLiveArgs(cUnit, mir);
-  if (longOrDouble) {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0);
-    rlObj = oatGetSrc(cUnit, mir, 2);
-  } else {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
-    rlObj = oatGetSrc(cUnit, mir, 1);
-  }
-  rlSrc = argLoc(cUnit, rlSrc);
-  rlObj = argLoc(cUnit, rlObj);
-  // Reject if source is split across registers & frame
-  if (rlObj.location == kLocInvalid) {
-    oatResetRegPool(cUnit);
-    return NULL;
-  }
-  // Point of no return - no aborts after this
-  genPrintLabel(cUnit, mir);
-  rlObj = loadArg(cUnit, rlObj);
-  rlSrc = loadArg(cUnit, rlSrc);
-  genIPut(cUnit, fieldIdx, mir->optimizationFlags, size, rlSrc, rlObj,
-          longOrDouble, isObject);
-  return getNextMir(cUnit, bb, mir);
-}
-
-MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir)
-{
-  RegLocation rlSrc;
-  RegLocation rlDest;
-  bool wide = (mir->ssaRep->numUses == 2);
-  if (wide) {
-    rlSrc = oatGetSrcWide(cUnit, mir, 0);
-    rlDest = oatGetReturnWide(cUnit, false);
-  } else {
-    rlSrc = oatGetSrc(cUnit, mir, 0);
-    rlDest = oatGetReturn(cUnit, false);
-  }
-  lockLiveArgs(cUnit, mir);
-  rlSrc = argLoc(cUnit, rlSrc);
-  if (rlSrc.location == kLocInvalid) {
-    oatResetRegPool(cUnit);
-    return NULL;
-  }
-  // Point of no return - no aborts after this
-  genPrintLabel(cUnit, mir);
-  rlSrc = loadArg(cUnit, rlSrc);
-  if (wide) {
-    storeValueWide(cUnit, rlDest, rlSrc);
-  } else {
-    storeValue(cUnit, rlDest, rlSrc);
-  }
-  return mir;
-}
-
-/*
- * Special-case code genration for simple non-throwing leaf methods.
- */
-void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
-          SpecialCaseHandler specialCase)
-{
-   cUnit->currentDalvikOffset = mir->offset;
-   MIR* nextMir = NULL;
-   switch (specialCase) {
-     case kNullMethod:
-       DCHECK(mir->dalvikInsn.opcode == Instruction::RETURN_VOID);
-       nextMir = mir;
-       break;
-     case kConstFunction:
-       genPrintLabel(cUnit, mir);
-       loadConstant(cUnit, rARM_RET0, mir->dalvikInsn.vB);
-       nextMir = getNextMir(cUnit, &bb, mir);
-       break;
-     case kIGet:
-       nextMir = specialIGet(cUnit, &bb, mir, kWord, false, false);
-       break;
-     case kIGetBoolean:
-     case kIGetByte:
-       nextMir = specialIGet(cUnit, &bb, mir, kUnsignedByte, false, false);
-       break;
-     case kIGetObject:
-       nextMir = specialIGet(cUnit, &bb, mir, kWord, false, true);
-       break;
-     case kIGetChar:
-       nextMir = specialIGet(cUnit, &bb, mir, kUnsignedHalf, false, false);
-       break;
-     case kIGetShort:
-       nextMir = specialIGet(cUnit, &bb, mir, kSignedHalf, false, false);
-       break;
-     case kIGetWide:
-       nextMir = specialIGet(cUnit, &bb, mir, kLong, true, false);
-       break;
-     case kIPut:
-       nextMir = specialIPut(cUnit, &bb, mir, kWord, false, false);
-       break;
-     case kIPutBoolean:
-     case kIPutByte:
-       nextMir = specialIPut(cUnit, &bb, mir, kUnsignedByte, false, false);
-       break;
-     case kIPutObject:
-       nextMir = specialIPut(cUnit, &bb, mir, kWord, false, true);
-       break;
-     case kIPutChar:
-       nextMir = specialIPut(cUnit, &bb, mir, kUnsignedHalf, false, false);
-       break;
-     case kIPutShort:
-       nextMir = specialIPut(cUnit, &bb, mir, kSignedHalf, false, false);
-       break;
-     case kIPutWide:
-       nextMir = specialIPut(cUnit, &bb, mir, kLong, true, false);
-       break;
-     case kIdentity:
-       nextMir = specialIdentity(cUnit, mir);
-       break;
-     default:
-       return;
-   }
-   if (nextMir != NULL) {
-    cUnit->currentDalvikOffset = nextMir->offset;
-    if (specialCase != kIdentity) {
-      genPrintLabel(cUnit, nextMir);
-    }
-    newLIR1(cUnit, kThumbBx, rARM_LR);
-    cUnit->coreSpillMask = 0;
-    cUnit->numCoreSpills = 0;
-    cUnit->fpSpillMask = 0;
-    cUnit->numFPSpills = 0;
-    cUnit->frameSize = 0;
-    cUnit->coreVmapTable.clear();
-    cUnit->fpVmapTable.clear();
-  }
-}
-
-LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
-         int src2, LIR* target)
-{
-  opRegReg(cUnit, kOpCmp, src1, src2);
-  return opCondBranch(cUnit, cond, target);
-}
-
-/*
- * Generate a Thumb2 IT instruction, which can nullify up to
- * four subsequent instructions based on a condition and its
- * inverse.  The condition applies to the first instruction, which
- * is executed if the condition is met.  The string "guide" consists
- * of 0 to 3 chars, and applies to the 2nd through 4th instruction.
- * A "T" means the instruction is executed if the condition is
- * met, and an "E" means the instruction is executed if the condition
- * is not met.
- */
-LIR* opIT(CompilationUnit* cUnit, ArmConditionCode code, const char* guide)
-{
-  int mask;
-  int condBit = code & 1;
-  int altBit = condBit ^ 1;
-  int mask3 = 0;
-  int mask2 = 0;
-  int mask1 = 0;
-
-  //Note: case fallthroughs intentional
-  switch (strlen(guide)) {
-    case 3:
-      mask1 = (guide[2] == 'T') ? condBit : altBit;
-    case 2:
-      mask2 = (guide[1] == 'T') ? condBit : altBit;
-    case 1:
-      mask3 = (guide[0] == 'T') ? condBit : altBit;
-      break;
-    case 0:
-      break;
-    default:
-      LOG(FATAL) << "OAT: bad case in opIT";
-  }
-  mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
-       (1 << (3 - strlen(guide)));
-  return newLIR2(cUnit, kThumb2It, code, mask);
-}
-
-/*
- * 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
- * must be lower than the reg for the displacement.
- *
- * The test loop will look something like:
- *
- *   adr   rBase, <table>
- *   ldr   rVal, [rARM_SP, vRegOff]
- *   mov   rIdx, #tableSize
- * lp:
- *   ldmia rBase!, {rKey, rDisp}
- *   sub   rIdx, #1
- *   cmp   rVal, rKey
- *   ifeq
- *   add   rARM_PC, rDisp   ; This is the branch from which we compute displacement
- *   cbnz  rIdx, lp
- */
-void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
-                     RegLocation rlSrc)
-{
-  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
-  if (cUnit->printMe) {
-    dumpSparseSwitchTable(table);
-  }
-  // Add the table to the list - we'll process it later
-  SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
-                                              true, kAllocData);
-  tabRec->table = table;
-  tabRec->vaddr = cUnit->currentDalvikOffset;
-  int size = table[1];
-  tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
-  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
-
-  // Get the switch value
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  int rBase = oatAllocTemp(cUnit);
-  /* Allocate key and disp temps */
-  int rKey = oatAllocTemp(cUnit);
-  int rDisp = oatAllocTemp(cUnit);
-  // Make sure rKey's register number is less than rDisp's number for ldmia
-  if (rKey > rDisp) {
-    int tmp = rDisp;
-    rDisp = rKey;
-    rKey = tmp;
-  }
-  // Materialize a pointer to the switch table
-  newLIR3(cUnit, kThumb2Adr, rBase, 0, (intptr_t)tabRec);
-  // Set up rIdx
-  int rIdx = oatAllocTemp(cUnit);
-  loadConstant(cUnit, rIdx, size);
-  // Establish loop branch target
-  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-  // 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
-  opIT(cUnit, kArmCondEq, "");
-  LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
-  tabRec->anchor = switchBranch;
-  // Needs to use setflags encoding here
-  newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
-  opCondBranch(cUnit, kCondNe, target);
-}
-
-
-void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
-                     RegLocation rlSrc)
-{
-  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
-  if (cUnit->printMe) {
-    dumpPackedSwitchTable(table);
-  }
-  // Add the table to the list - we'll process it later
-  SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
-                                              true, kAllocData);
-  tabRec->table = table;
-  tabRec->vaddr = cUnit->currentDalvikOffset;
-  int size = table[1];
-  tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
-  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
-
-  // Get the switch value
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  int tableBase = oatAllocTemp(cUnit);
-  // Materialize a pointer to the switch table
-  newLIR3(cUnit, kThumb2Adr, tableBase, 0, (intptr_t)tabRec);
-  int lowKey = s4FromSwitchData(&table[2]);
-  int keyReg;
-  // Remove the bias, if necessary
-  if (lowKey == 0) {
-    keyReg = rlSrc.lowReg;
-  } else {
-    keyReg = oatAllocTemp(cUnit);
-    opRegRegImm(cUnit, kOpSub, keyReg, rlSrc.lowReg, lowKey);
-  }
-  // Bounds check - if < 0 or >= size continue following switch
-  opRegImm(cUnit, kOpCmp, keyReg, size-1);
-  LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);
-
-  // 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
-  LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
-  tabRec->anchor = switchBranch;
-
-  /* branchOver target here */
-  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-  branchOver->target = (LIR*)target;
-}
-
-/*
- * Array data table format:
- *  ushort ident = 0x0300   magic value
- *  ushort width            width of each element in the table
- *  uint   size             number of elements in the table
- *  ubyte  data[size*width] table of data values (may contain a single-byte
- *                          padding at the end)
- *
- * Total size is 4+(width * size + 1)/2 16-bit code units.
- */
-void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc)
-{
-  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
-  // Add the table to the list - we'll process it later
-  FillArrayData *tabRec = (FillArrayData *)
-     oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
-  tabRec->table = table;
-  tabRec->vaddr = cUnit->currentDalvikOffset;
-  u2 width = tabRec->table[1];
-  u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
-  tabRec->size = (size * width) + 8;
-
-  oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec);
-
-  // Making a call - use explicit registers
-  oatFlushAllRegs(cUnit);   /* Everything to home location */
-  loadValueDirectFixed(cUnit, rlSrc, r0);
-  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode),
-               rARM_LR);
-  // Materialize a pointer to the fill data image
-  newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
-  markSafepointPC(cUnit, callInst);
-}
-
-void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValue(cUnit, rlSrc, kFPReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
-  newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg);
-  storeValue(cUnit, rlDest, rlResult);
-}
-
-void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
-  newLIR2(cUnit, kThumb2Vnegd, s2d(rlResult.lowReg, rlResult.highReg),
-          s2d(rlSrc.lowReg, rlSrc.highReg));
-  storeValueWide(cUnit, rlDest, rlResult);
-}
-
-/*
- * Handle simple case (thin lock) inline.  If it's complicated, bail
- * out to the heavyweight lock/unlock routines.  We'll use dedicated
- * registers here in order to be in the right position in case we
- * to bail to dvm[Lock/Unlock]Object(self, object)
- *
- * r0 -> self pointer [arg0 for dvm[Lock/Unlock]Object
- * r1 -> object [arg1 for dvm[Lock/Unlock]Object
- * r2 -> intial contents of object->lock, later result of strex
- * r3 -> self->threadId
- * r12 -> allow to be used by utilities as general temp
- *
- * The result of the strex is 0 if we acquire the lock.
- *
- * See comments in Sync.c for the layout of the lock word.
- * Of particular interest to this code is the test for the
- * simple case - which we handle inline.  For monitor enter, the
- * simple case is thin lock, held by no-one.  For monitor exit,
- * the simple case is thin lock, held by the unlocking thread with
- * a recurse count of 0.
- *
- * A minor complication is that there is a field in the lock word
- * unrelated to locking: the hash state.  This field must be ignored, but
- * preserved.
- *
- */
-void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  DCHECK_EQ(LW_SHAPE_THIN, 0);
-  loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
-  loadWordDisp(cUnit, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
-  newLIR3(cUnit, kThumb2Ldrex, r1, r0,
-          Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
-  // Align owner
-  opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
-  // Is lock unheld on lock or held by us (==threadId) on unlock?
-  newLIR4(cUnit, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
-  newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
-  opRegImm(cUnit, kOpCmp, r1, 0);
-  opIT(cUnit, kArmCondEq, "");
-  newLIR4(cUnit, kThumb2Strex, r1, r2, r0,
-          Object::MonitorOffset().Int32Value() >> 2);
-  opRegImm(cUnit, kOpCmp, r1, 0);
-  opIT(cUnit, kArmCondNe, "T");
-  // Go expensive route - artLockObjectFromCode(self, obj);
-  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pLockObjectFromCode), rARM_LR);
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
-  markSafepointPC(cUnit, callInst);
-  oatGenMemBarrier(cUnit, kSY);
-}
-
-/*
- * For monitor unlock, we don't have to use ldrex/strex.  Once
- * we've determined that the lock is thin and that we own it with
- * a zero recursion count, it's safe to punch it back to the
- * initial, unlock thin state with a store word.
- */
-void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  DCHECK_EQ(LW_SHAPE_THIN, 0);
-  oatFlushAllRegs(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
-  loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
-  loadWordDisp(cUnit, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
-  // Is lock unheld on lock or held by us (==threadId) on unlock?
-  opRegRegImm(cUnit, kOpAnd, r3, r1,
-              (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
-  // Align owner
-  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);
-  opIT(cUnit, kArmCondEq, "EE");
-  storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
-  // Go expensive route - UnlockObjectFromCode(obj);
-  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rARM_LR);
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
-  markSafepointPC(cUnit, callInst);
-  oatGenMemBarrier(cUnit, kSY);
-}
-
-/*
- * 64-bit 3way compare function.
- *     mov   rX, #-1
- *     cmp   op1hi, op2hi
- *     blt   done
- *     bgt   flip
- *     sub   rX, op1lo, op2lo (treat as unsigned)
- *     beq   done
- *     ite   hi
- *     mov(hi)   rX, #-1
- *     mov(!hi)  rX, #1
- * flip:
- *     neg   rX
- * done:
- */
-void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
-        RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  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);
-  LIR* branch1 = opCondBranch(cUnit, kCondLt, NULL);
-  LIR* branch2 = opCondBranch(cUnit, kCondGt, NULL);
-  opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
-  LIR* branch3 = opCondBranch(cUnit, kCondEq, NULL);
-
-  opIT(cUnit, kArmCondHi, "E");
-  newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
-  loadConstant(cUnit, tReg, 1);
-  genBarrier(cUnit);
-
-  target2 = newLIR0(cUnit, kPseudoTargetLabel);
-  opRegReg(cUnit, kOpNeg, tReg, tReg);
-
-  target1 = newLIR0(cUnit, kPseudoTargetLabel);
-
-  RegLocation rlTemp = locCReturn(); // Just using as template, will change
-  rlTemp.lowReg = tReg;
-  storeValue(cUnit, rlDest, rlTemp);
-  oatFreeTemp(cUnit, tReg);
-
-  branch1->target = (LIR*)target1;
-  branch2->target = (LIR*)target2;
-  branch3->target = branch1->target;
-}
-
-void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
-{
-  LIR* labelList = cUnit->blockLabelList;
-  LIR* taken = &labelList[bb->taken->id];
-  LIR* notTaken = &labelList[bb->fallThrough->id];
-  RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
-  RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
-  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-  ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
-  opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
-  switch(ccode) {
-    case kCondEq:
-      opCondBranch(cUnit, kCondNe, notTaken);
-      break;
-    case kCondNe:
-      opCondBranch(cUnit, kCondNe, taken);
-      break;
-    case kCondLt:
-      opCondBranch(cUnit, kCondLt, taken);
-      opCondBranch(cUnit, kCondGt, notTaken);
-      ccode = kCondCc;
-      break;
-    case kCondLe:
-      opCondBranch(cUnit, kCondLt, taken);
-      opCondBranch(cUnit, kCondGt, notTaken);
-      ccode = kCondLs;
-      break;
-    case kCondGt:
-      opCondBranch(cUnit, kCondGt, taken);
-      opCondBranch(cUnit, kCondLt, notTaken);
-      ccode = kCondHi;
-      break;
-    case kCondGe:
-      opCondBranch(cUnit, kCondGt, taken);
-      opCondBranch(cUnit, kCondLt, notTaken);
-      ccode = kCondCs;
-      break;
-    default:
-      LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
-  }
-  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
-  opCondBranch(cUnit, ccode, taken);
-}
-
-/*
- * Generate a register comparison to an immediate and branch.  Caller
- * is responsible for setting branch target field.
- */
-LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
-          int checkValue, LIR* target)
-{
-  LIR* branch;
-  int modImm;
-  ArmConditionCode armCond = oatArmConditionEncoding(cond);
-  if ((ARM_LOWREG(reg)) && (checkValue == 0) &&
-     ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
-    branch = newLIR2(cUnit, (armCond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
-                     reg, 0);
-  } else {
-    modImm = modifiedImmediate(checkValue);
-    if (ARM_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, armCond);
-  }
-  branch->target = target;
-  return branch;
-}
-LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
-{
-  LIR* res;
-  int opcode;
-  if (ARM_FPREG(rDest) || ARM_FPREG(rSrc))
-    return fpRegCopy(cUnit, rDest, rSrc);
-  if (ARM_LOWREG(rDest) && ARM_LOWREG(rSrc))
-    opcode = kThumbMovRR;
-  else if (!ARM_LOWREG(rDest) && !ARM_LOWREG(rSrc))
-     opcode = kThumbMovRR_H2H;
-  else if (ARM_LOWREG(rDest))
-     opcode = kThumbMovRR_H2L;
-  else
-     opcode = kThumbMovRR_L2H;
-  res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
-  if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
-    res->flags.isNop = true;
-  }
-  return res;
-}
-
-LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
-{
-  LIR* res = opRegCopyNoInsert(cUnit, rDest, rSrc);
-  oatAppendLIR(cUnit, (LIR*)res);
-  return res;
-}
-
-void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
-               int srcLo, int srcHi)
-{
-  bool destFP = ARM_FPREG(destLo) && ARM_FPREG(destHi);
-  bool srcFP = ARM_FPREG(srcLo) && ARM_FPREG(srcHi);
-  DCHECK_EQ(ARM_FPREG(srcLo), ARM_FPREG(srcHi));
-  DCHECK_EQ(ARM_FPREG(destLo), ARM_FPREG(destHi));
-  if (destFP) {
-    if (srcFP) {
-      opRegCopy(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) {
-        opRegCopy(cUnit, destHi, srcHi);
-        opRegCopy(cUnit, destLo, srcLo);
-      } else {
-        opRegCopy(cUnit, destLo, srcLo);
-        opRegCopy(cUnit, destHi, srcHi);
-      }
-    }
-  }
-}
-
-// Table of magic divisors
-enum DividePattern {
-  DivideNone,
-  Divide3,
-  Divide5,
-  Divide7,
-};
-
-struct MagicTable {
-  uint32_t magic;
-  uint32_t shift;
-  DividePattern pattern;
-};
-
-static const MagicTable magicTable[] = {
-  {0, 0, DivideNone},        // 0
-  {0, 0, DivideNone},        // 1
-  {0, 0, DivideNone},        // 2
-  {0x55555556, 0, Divide3},  // 3
-  {0, 0, DivideNone},        // 4
-  {0x66666667, 1, Divide5},  // 5
-  {0x2AAAAAAB, 0, Divide3},  // 6
-  {0x92492493, 2, Divide7},  // 7
-  {0, 0, DivideNone},        // 8
-  {0x38E38E39, 1, Divide5},  // 9
-  {0x66666667, 2, Divide5},  // 10
-  {0x2E8BA2E9, 1, Divide5},  // 11
-  {0x2AAAAAAB, 1, Divide5},  // 12
-  {0x4EC4EC4F, 2, Divide5},  // 13
-  {0x92492493, 3, Divide7},  // 14
-  {0x88888889, 3, Divide7},  // 15
-};
-
-// Integer division by constant via reciprocal multiply (Hacker's Delight, 10-4)
-bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
-                        RegLocation rlSrc, RegLocation rlDest, int lit)
-{
-  if ((lit < 0) || (lit >= (int)(sizeof(magicTable)/sizeof(magicTable[0])))) {
-    return false;
-  }
-  DividePattern pattern = magicTable[lit].pattern;
-  if (pattern == DivideNone) {
-    return false;
-  }
-  // Tuning: add rem patterns
-  if (dalvikOpcode != Instruction::DIV_INT_LIT8) {
-    return false;
-  }
-
-  int rMagic = oatAllocTemp(cUnit);
-  loadConstant(cUnit, rMagic, magicTable[lit].magic);
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  int rHi = oatAllocTemp(cUnit);
-  int rLo = oatAllocTemp(cUnit);
-  newLIR4(cUnit, kThumb2Smull, rLo, rHi, rMagic, rlSrc.lowReg);
-  switch(pattern) {
-    case Divide3:
-      opRegRegRegShift(cUnit, kOpSub, rlResult.lowReg, rHi,
-               rlSrc.lowReg, encodeShift(kArmAsr, 31));
-      break;
-    case Divide5:
-      opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
-      opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
-               encodeShift(kArmAsr, magicTable[lit].shift));
-      break;
-    case Divide7:
-      opRegReg(cUnit, kOpAdd, rHi, rlSrc.lowReg);
-      opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
-      opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
-               encodeShift(kArmAsr, magicTable[lit].shift));
-      break;
-    default:
-      LOG(FATAL) << "Unexpected pattern: " << (int)pattern;
-  }
-  storeValue(cUnit, rlDest, rlResult);
-  return true;
-}
-
-/*
- * 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 = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL);
-  loadWordDisp(cUnit, rARM_SELF, Thread::CardTableOffset().Int32Value(), regCardBase);
-  opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, CardTable::kCardShift);
-  storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
-                   kUnsignedByte);
-  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-  branchOver->target = (LIR*)target;
-  oatFreeTemp(cUnit, regCardBase);
-  oatFreeTemp(cUnit, regCardNo);
-}
-
-LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode,
-                    int reg1, int base, int offset, ThrowKind kind)
-{
-  LOG(FATAL) << "Unexpected use of genRegMemCheck for Arm";
-  return NULL;
-}
-
-RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int lit, bool isDiv)
-{
-  LOG(FATAL) << "Unexpected use of genDivRemLit for Arm";
-  return rlDest;
-}
-
-RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int reg2, bool isDiv)
-{
-  LOG(FATAL) << "Unexpected use of genDivRem for Arm";
-  return rlDest;
-}
-
-bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
-{
-  DCHECK_EQ(cUnit->instructionSet, kThumb2);
-  RegLocation rlSrc1 = info->args[0];
-  RegLocation rlSrc2 = info->args[1];
-  rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
-  rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
-  RegLocation rlDest = inlineTarget(cUnit, info);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
-  opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
-  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
-  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
-  genBarrier(cUnit);
-  storeValue(cUnit, rlDest, rlResult);
-  return true;
-}
-
-void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset)
-{
-  LOG(FATAL) << "Unexpected use of opLea for Arm";
-}
-
-void opTlsCmp(CompilationUnit* cUnit, int offset, int val)
-{
-  LOG(FATAL) << "Unexpected use of opTlsCmp for Arm";
-}
-
-bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) {
-  DCHECK_EQ(cUnit->instructionSet, kThumb2);
-  // Unused - RegLocation rlSrcUnsafe = info->args[0];
-  RegLocation rlSrcObj= info->args[1];  // Object - known non-null
-  RegLocation rlSrcOffset= info->args[2];  // long low
-  rlSrcOffset.wide = 0;  // ignore high half in info->args[3]
-  RegLocation rlSrcExpected= info->args[4];  // int or Object
-  RegLocation rlSrcNewValue= info->args[5];  // int or Object
-  RegLocation rlDest = inlineTarget(cUnit, info);  // boolean place for result
-
-
-  // Release store semantics, get the barrier out of the way.
-  oatGenMemBarrier(cUnit, kSY);
-
-  RegLocation rlObject = loadValue(cUnit, rlSrcObj, kCoreReg);
-  RegLocation rlNewValue = loadValue(cUnit, rlSrcNewValue, kCoreReg);
-
-  if (need_write_barrier) {
-    // Mark card for object assuming new value is stored.
-    markGCCard(cUnit, rlNewValue.lowReg, rlObject.lowReg);
-  }
-
-  RegLocation rlOffset = loadValue(cUnit, rlSrcOffset, kCoreReg);
-
-  int rPtr = oatAllocTemp(cUnit);
-  opRegRegReg(cUnit, kOpAdd, rPtr, rlObject.lowReg, rlOffset.lowReg);
-
-  // Free now unneeded rlObject and rlOffset to give more temps.
-  oatClobberSReg(cUnit, rlObject.sRegLow);
-  oatFreeTemp(cUnit, rlObject.lowReg);
-  oatClobberSReg(cUnit, rlOffset.sRegLow);
-  oatFreeTemp(cUnit, rlOffset.lowReg);
-
-  int rOldValue = oatAllocTemp(cUnit);
-  newLIR3(cUnit, kThumb2Ldrex, rOldValue, rPtr, 0);  // rOldValue := [rPtr]
-
-  RegLocation rlExpected = loadValue(cUnit, rlSrcExpected, kCoreReg);
-
-  // if (rOldValue == rExpected) {
-  //   [rPtr] <- rNewValue && rResult := success ? 0 : 1
-  //   rResult ^= 1
-  // } else {
-  //   rResult := 0
-  // }
-  opRegReg(cUnit, kOpCmp, rOldValue, rlExpected.lowReg);
-  oatFreeTemp(cUnit, rOldValue);  // Now unneeded.
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opIT(cUnit, kArmCondEq, "TE");
-  newLIR4(cUnit, kThumb2Strex, rlResult.lowReg, rlNewValue.lowReg, rPtr, 0);
-  oatFreeTemp(cUnit, rPtr);  // Now unneeded.
-  opRegImm(cUnit, kOpXor, rlResult.lowReg, 1);
-  opRegReg(cUnit, kOpXor, rlResult.lowReg, rlResult.lowReg);
-
-  storeValue(cUnit, rlDest, rlResult);
-
-  return true;
-}
-
-bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
-  DCHECK_EQ(cUnit->instructionSet, kThumb2);
-  LIR *branch;
-  RegLocation rlSrc = info->args[0];
-  RegLocation rlDest = inlineTargetWide(cUnit, info);  // double place for result
-  rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
-  newLIR2(cUnit, kThumb2Vsqrtd, s2d(rlResult.lowReg, rlResult.highReg),
-          s2d(rlSrc.lowReg, rlSrc.highReg));
-  newLIR2(cUnit, kThumb2Vcmpd, s2d(rlResult.lowReg, rlResult.highReg),
-          s2d(rlResult.lowReg, rlResult.highReg));
-  newLIR0(cUnit, kThumb2Fmstat);
-  branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq);
-  oatClobberCalleeSave(cUnit);
-  oatLockCallTemps(cUnit);  // Using fixed registers
-  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt));
-  newLIR3(cUnit, kThumb2Fmrrd, r0, r1, s2d(rlSrc.lowReg, rlSrc.highReg));
-  newLIR1(cUnit, kThumbBlxR, rTgt);
-  newLIR3(cUnit, kThumb2Fmdrr, s2d(rlResult.lowReg, rlResult.highReg), r0, r1);
-  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
-  storeValueWide(cUnit, rlDest, rlResult);
-  return true;
-}
-
-LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target)
-{
-  return rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2LdrPcRel12, reg, 0, 0, 0, 0, target);
-}
-
-LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
-{
-  return newLIR3(cUnit, kThumb2Vldms, rBase, fr0, count);
-}
-
-LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
-{
-  return newLIR3(cUnit, kThumb2Vstms, rBase, fr0, count);
-}
-
-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);
-  }
-}
-
-void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
-{
-  int tReg = oatAllocTemp(cUnit);
-  newLIR4(cUnit, kThumb2OrrRRRs, tReg, regLo, regHi, 0);
-  oatFreeTemp(cUnit, tReg);
-  genCheck(cUnit, kCondEq, kThrowDivZero);
-}
-
-// Test suspend flag, return target of taken suspend branch
-LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
-{
-  newLIR2(cUnit, kThumbSubRI8, rARM_SUSPEND, 1);
-  return opCondBranch(cUnit, (target == NULL) ? kCondEq : kCondNe, target);
-}
-
-// Decrement register and branch on condition
-LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
-{
-  // Combine sub & test using sub setflags encoding here
-  newLIR3(cUnit, kThumb2SubsRRI12, reg, reg, 1);
-  return opCondBranch(cUnit, cCode, target);
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/Thumb2/Ralloc.cc b/src/compiler/codegen/arm/Thumb2/Ralloc.cc
deleted file mode 100644
index ab5cf33..0000000
--- a/src/compiler/codegen/arm/Thumb2/Ralloc.cc
+++ /dev/null
@@ -1,119 +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 for the Thumb ISA. */
-
-/*
- * Alloc a pair of core registers, or a double.  Low reg in low byte,
- * high reg in next byte.
- */
-int oatAllocTypedTempPair(CompilationUnit* cUnit, bool fpHint, int regClass)
-{
-  int highReg;
-  int lowReg;
-  int res = 0;
-
-  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
-    lowReg = oatAllocTempDouble(cUnit);
-    highReg = lowReg + 1;
-  } else {
-    lowReg = oatAllocTemp(cUnit);
-    highReg = oatAllocTemp(cUnit);
-  }
-  res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
-  return res;
-}
-
-int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass)
-{
-  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
-    return oatAllocTempFloat(cUnit);
-  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 && (reservedRegs[i] == rARM_SUSPEND)) {
-      //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]);
-  }
-
-  // Start allocation at r2 in an attempt to avoid clobbering return values
-  pool->nextCoreReg = r2;
-
-  // 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/ArmLIR.h b/src/compiler/codegen/arm/arm_lir.h
similarity index 99%
rename from src/compiler/codegen/arm/ArmLIR.h
rename to src/compiler/codegen/arm/arm_lir.h
index 7eebc83..a068502 100644
--- a/src/compiler/codegen/arm/ArmLIR.h
+++ b/src/compiler/codegen/arm/arm_lir.h
@@ -17,8 +17,8 @@
 #ifndef ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
 #define ART_SRC_COMPILER_CODEGEN_ARM_ARMLIR_H_
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/arm/armv7-a/ArchVariant.cc b/src/compiler/codegen/arm/armv7-a/ArchVariant.cc
deleted file mode 100644
index 3977d50..0000000
--- a/src/compiler/codegen/arm/armv7-a/ArchVariant.cc
+++ /dev/null
@@ -1,55 +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 {
-
-/*
- * Determine the initial instruction set to be used for this trace.
- * Later components may decide to change this.
- */
-InstructionSet oatInstructionSet()
-{
-  return kThumb2;
-}
-
-/* Architecture-specific initializations and checks go here */
-bool oatArchVariantInit(void)
-{
-  return true;
-}
-
-int oatTargetOptHint(int key)
-{
-  int res = 0;
-  switch (key) {
-    case kMaxHoistDistance:
-      res = 7;
-      break;
-    default:
-      LOG(FATAL) << "Unknown target optimization hint key: " << key;
-    }
-  return res;
-}
-
-void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind)
-{
-#if ANDROID_SMP != 0
-  LIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
-  dmb->defMask = ENCODE_ALL;
-#endif
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/arm/armv7-a/Codegen.cc b/src/compiler/codegen/arm/armv7-a/Codegen.cc
deleted file mode 100644
index c398b8e..0000000
--- a/src/compiler/codegen/arm/armv7-a/Codegen.cc
+++ /dev/null
@@ -1,57 +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.
- */
-#define _CODEGEN_C
-#define _ARMV7_A
-
-#include "../../../Dalvik.h"
-#include "../../../CompilerInternals.h"
-#include "../ArmLIR.h"
-#include "../../Ralloc.h"
-#include "../Codegen.h"
-
-/* 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"
-
-/* Thumb2-specific codegen routines */
-#include "../Thumb2/Gen.cc"
-/* Thumb2+VFP codegen routines */
-#include "../FP/Thumb2VFP.cc"
-
-/* Thumb2-specific register allocation */
-#include "../Thumb2/Ralloc.cc"
-
-/* Bitcode conversion */
-#include "../../MethodBitcode.cc"
-
-/* MIR2LIR dispatcher and architectural independent codegen routines */
-#include "../../MethodCodegenDriver.cc"
-
-/* Target-independent local optimizations */
-#include "../../LocalOptimizations.cc"
-
-/* Architecture manifest */
-#include "ArchVariant.cc"
diff --git a/src/compiler/codegen/arm/Assemble.cc b/src/compiler/codegen/arm/assemble_arm.cc
similarity index 99%
rename from src/compiler/codegen/arm/Assemble.cc
rename to src/compiler/codegen/arm/assemble_arm.cc
index 765a8ff..e1b8672 100644
--- a/src/compiler/codegen/arm/Assemble.cc
+++ b/src/compiler/codegen/arm/assemble_arm.cc
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
-#include "ArmLIR.h"
-#include "Codegen.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "arm_lir.h"
+#include "codegen.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/arm/backend_arm.cc b/src/compiler/codegen/arm/backend_arm.cc
new file mode 100644
index 0000000..d8f2996
--- /dev/null
+++ b/src/compiler/codegen/arm/backend_arm.cc
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+#define _CODEGEN_C
+#define _ARMV7_A
+
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "arm_lir.h"
+#include "../ralloc.h"
+#include "codegen.h"
+
+/* Common codegen utility code */
+#include "../codegen_util.cc"
+
+#include "utility_arm.cc"
+#include "../codegen_factory.cc"
+#include "../gen_common.cc"
+#include "../gen_invoke.cc"
+#include "call_arm.cc"
+#include "fp_arm.cc"
+#include "int_arm.cc"
+
+/* Bitcode conversion */
+#include "../method_bitcode.cc"
+
+/* MIR2LIR dispatcher and architectural independent codegen routines */
+#include "../method_codegen_driver.cc"
+
+/* Target-independent local optimizations */
+#include "../local_optimizations.cc"
diff --git a/src/compiler/codegen/arm/call_arm.cc b/src/compiler/codegen/arm/call_arm.cc
new file mode 100644
index 0000000..3fd5b15
--- /dev/null
+++ b/src/compiler/codegen/arm/call_arm.cc
@@ -0,0 +1,642 @@
+/*
+ * 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.
+ */
+
+/* This file contains codegen for the Thumb2 ISA. */
+
+#include "oat_compilation_unit.h"
+#include "oat/runtime/oat_support_entrypoints.h"
+
+namespace art {
+
+
+/* Return the position of an ssa name within the argument list */
+int inPosition(CompilationUnit* cUnit, int sReg)
+{
+  int vReg = SRegToVReg(cUnit, sReg);
+  return vReg - cUnit->numRegs;
+}
+
+/*
+ * Describe an argument.  If it's already in an arg register, just leave it
+ * there.  NOTE: all live arg registers must be locked prior to this call
+ * to avoid having them allocated as a temp by downstream utilities.
+ */
+RegLocation argLoc(CompilationUnit* cUnit, RegLocation loc)
+{
+  int argNum = inPosition(cUnit, loc.sRegLow);
+  if (loc.wide) {
+    if (argNum == 2) {
+      // Bad case - half in register, half in frame.  Just punt
+      loc.location = kLocInvalid;
+    } else if (argNum < 2) {
+      loc.lowReg = rARM_ARG1 + argNum;
+      loc.highReg = loc.lowReg + 1;
+      loc.location = kLocPhysReg;
+    } else {
+      loc.location = kLocDalvikFrame;
+    }
+  } else {
+    if (argNum < 3) {
+      loc.lowReg = rARM_ARG1 + argNum;
+      loc.location = kLocPhysReg;
+    } else {
+      loc.location = kLocDalvikFrame;
+    }
+  }
+  return loc;
+}
+
+/*
+ * Load an argument.  If already in a register, just return.  If in
+ * the frame, we can't use the normal loadValue() because it assumed
+ * a proper frame - and we're frameless.
+ */
+RegLocation loadArg(CompilationUnit* cUnit, RegLocation loc)
+{
+  if (loc.location == kLocDalvikFrame) {
+    int start = (inPosition(cUnit, loc.sRegLow) + 1) * sizeof(uint32_t);
+    loc.lowReg = oatAllocTemp(cUnit);
+    loadWordDisp(cUnit, rARM_SP, start, loc.lowReg);
+    if (loc.wide) {
+      loc.highReg = oatAllocTemp(cUnit);
+      loadWordDisp(cUnit, rARM_SP, start + sizeof(uint32_t), loc.highReg);
+    }
+    loc.location = kLocPhysReg;
+  }
+  return loc;
+}
+
+/* Lock any referenced arguments that arrive in registers */
+void lockLiveArgs(CompilationUnit* cUnit, MIR* mir)
+{
+  int firstIn = cUnit->numRegs;
+  const int numArgRegs = 3;  // TODO: generalize & move to RegUtil.cc
+  for (int i = 0; i < mir->ssaRep->numUses; i++) {
+    int vReg = SRegToVReg(cUnit, mir->ssaRep->uses[i]);
+    int inPosition = vReg - firstIn;
+    if (inPosition < numArgRegs) {
+      oatLockTemp(cUnit, rARM_ARG1 + inPosition);
+    }
+  }
+}
+
+/* Find the next MIR, which may be in a following basic block */
+MIR* getNextMir(CompilationUnit* cUnit, BasicBlock** pBb, MIR* mir)
+{
+  BasicBlock* bb = *pBb;
+  MIR* origMir = mir;
+  while (bb != NULL) {
+    if (mir != NULL) {
+      mir = mir->next;
+    }
+    if (mir != NULL) {
+      return mir;
+    } else {
+      bb = bb->fallThrough;
+      *pBb = bb;
+      if (bb) {
+         mir = bb->firstMIRInsn;
+         if (mir != NULL) {
+           return mir;
+         }
+      }
+    }
+  }
+  return origMir;
+}
+
+/* Used for the "printMe" listing */
+void genPrintLabel(CompilationUnit *cUnit, MIR* mir)
+{
+  /* Mark the beginning of a Dalvik instruction for line tracking */
+  char* instStr = cUnit->printMe ?
+     oatGetDalvikDisassembly(cUnit, mir->dalvikInsn, "") : NULL;
+  markBoundary(cUnit, mir->offset, instStr);
+  /* Don't generate the SSA annotation unless verbose mode is on */
+  if (cUnit->printMe && mir->ssaRep) {
+    char* ssaString = oatGetSSAString(cUnit, mir->ssaRep);
+    newLIR1(cUnit, kPseudoSSARep, (int) ssaString);
+  }
+}
+
+MIR* specialIGet(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
+                 OpSize size, bool longOrDouble, bool isObject)
+{
+  int fieldOffset;
+  bool isVolatile;
+  uint32_t fieldIdx = mir->dalvikInsn.vC;
+  bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
+  if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+    return NULL;
+  }
+  RegLocation rlObj = oatGetSrc(cUnit, mir, 0);
+  lockLiveArgs(cUnit, mir);
+  rlObj = argLoc(cUnit, rlObj);
+  RegLocation rlDest;
+  if (longOrDouble) {
+    rlDest = oatGetReturnWide(cUnit, false);
+  } else {
+    rlDest = oatGetReturn(cUnit, false);
+  }
+  // Point of no return - no aborts after this
+  genPrintLabel(cUnit, mir);
+  rlObj = loadArg(cUnit, rlObj);
+  genIGet(cUnit, fieldIdx, mir->optimizationFlags, size, rlDest, rlObj,
+          longOrDouble, isObject);
+  return getNextMir(cUnit, bb, mir);
+}
+
+MIR* specialIPut(CompilationUnit* cUnit, BasicBlock** bb, MIR* mir,
+                 OpSize size, bool longOrDouble, bool isObject)
+{
+  int fieldOffset;
+  bool isVolatile;
+  uint32_t fieldIdx = mir->dalvikInsn.vC;
+  bool fastPath = fastInstance(cUnit, fieldIdx, fieldOffset, isVolatile, false);
+  if (!fastPath || !(mir->optimizationFlags & MIR_IGNORE_NULL_CHECK)) {
+    return NULL;
+  }
+  RegLocation rlSrc;
+  RegLocation rlObj;
+  lockLiveArgs(cUnit, mir);
+  if (longOrDouble) {
+    rlSrc = oatGetSrcWide(cUnit, mir, 0);
+    rlObj = oatGetSrc(cUnit, mir, 2);
+  } else {
+    rlSrc = oatGetSrc(cUnit, mir, 0);
+    rlObj = oatGetSrc(cUnit, mir, 1);
+  }
+  rlSrc = argLoc(cUnit, rlSrc);
+  rlObj = argLoc(cUnit, rlObj);
+  // Reject if source is split across registers & frame
+  if (rlObj.location == kLocInvalid) {
+    oatResetRegPool(cUnit);
+    return NULL;
+  }
+  // Point of no return - no aborts after this
+  genPrintLabel(cUnit, mir);
+  rlObj = loadArg(cUnit, rlObj);
+  rlSrc = loadArg(cUnit, rlSrc);
+  genIPut(cUnit, fieldIdx, mir->optimizationFlags, size, rlSrc, rlObj,
+          longOrDouble, isObject);
+  return getNextMir(cUnit, bb, mir);
+}
+
+MIR* specialIdentity(CompilationUnit* cUnit, MIR* mir)
+{
+  RegLocation rlSrc;
+  RegLocation rlDest;
+  bool wide = (mir->ssaRep->numUses == 2);
+  if (wide) {
+    rlSrc = oatGetSrcWide(cUnit, mir, 0);
+    rlDest = oatGetReturnWide(cUnit, false);
+  } else {
+    rlSrc = oatGetSrc(cUnit, mir, 0);
+    rlDest = oatGetReturn(cUnit, false);
+  }
+  lockLiveArgs(cUnit, mir);
+  rlSrc = argLoc(cUnit, rlSrc);
+  if (rlSrc.location == kLocInvalid) {
+    oatResetRegPool(cUnit);
+    return NULL;
+  }
+  // Point of no return - no aborts after this
+  genPrintLabel(cUnit, mir);
+  rlSrc = loadArg(cUnit, rlSrc);
+  if (wide) {
+    storeValueWide(cUnit, rlDest, rlSrc);
+  } else {
+    storeValue(cUnit, rlDest, rlSrc);
+  }
+  return mir;
+}
+
+/*
+ * Special-case code genration for simple non-throwing leaf methods.
+ */
+void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+          SpecialCaseHandler specialCase)
+{
+   cUnit->currentDalvikOffset = mir->offset;
+   MIR* nextMir = NULL;
+   switch (specialCase) {
+     case kNullMethod:
+       DCHECK(mir->dalvikInsn.opcode == Instruction::RETURN_VOID);
+       nextMir = mir;
+       break;
+     case kConstFunction:
+       genPrintLabel(cUnit, mir);
+       loadConstant(cUnit, rARM_RET0, mir->dalvikInsn.vB);
+       nextMir = getNextMir(cUnit, &bb, mir);
+       break;
+     case kIGet:
+       nextMir = specialIGet(cUnit, &bb, mir, kWord, false, false);
+       break;
+     case kIGetBoolean:
+     case kIGetByte:
+       nextMir = specialIGet(cUnit, &bb, mir, kUnsignedByte, false, false);
+       break;
+     case kIGetObject:
+       nextMir = specialIGet(cUnit, &bb, mir, kWord, false, true);
+       break;
+     case kIGetChar:
+       nextMir = specialIGet(cUnit, &bb, mir, kUnsignedHalf, false, false);
+       break;
+     case kIGetShort:
+       nextMir = specialIGet(cUnit, &bb, mir, kSignedHalf, false, false);
+       break;
+     case kIGetWide:
+       nextMir = specialIGet(cUnit, &bb, mir, kLong, true, false);
+       break;
+     case kIPut:
+       nextMir = specialIPut(cUnit, &bb, mir, kWord, false, false);
+       break;
+     case kIPutBoolean:
+     case kIPutByte:
+       nextMir = specialIPut(cUnit, &bb, mir, kUnsignedByte, false, false);
+       break;
+     case kIPutObject:
+       nextMir = specialIPut(cUnit, &bb, mir, kWord, false, true);
+       break;
+     case kIPutChar:
+       nextMir = specialIPut(cUnit, &bb, mir, kUnsignedHalf, false, false);
+       break;
+     case kIPutShort:
+       nextMir = specialIPut(cUnit, &bb, mir, kSignedHalf, false, false);
+       break;
+     case kIPutWide:
+       nextMir = specialIPut(cUnit, &bb, mir, kLong, true, false);
+       break;
+     case kIdentity:
+       nextMir = specialIdentity(cUnit, mir);
+       break;
+     default:
+       return;
+   }
+   if (nextMir != NULL) {
+    cUnit->currentDalvikOffset = nextMir->offset;
+    if (specialCase != kIdentity) {
+      genPrintLabel(cUnit, nextMir);
+    }
+    newLIR1(cUnit, kThumbBx, rARM_LR);
+    cUnit->coreSpillMask = 0;
+    cUnit->numCoreSpills = 0;
+    cUnit->fpSpillMask = 0;
+    cUnit->numFPSpills = 0;
+    cUnit->frameSize = 0;
+    cUnit->coreVmapTable.clear();
+    cUnit->fpVmapTable.clear();
+  }
+}
+
+/*
+ * 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
+ * must be lower than the reg for the displacement.
+ *
+ * The test loop will look something like:
+ *
+ *   adr   rBase, <table>
+ *   ldr   rVal, [rARM_SP, vRegOff]
+ *   mov   rIdx, #tableSize
+ * lp:
+ *   ldmia rBase!, {rKey, rDisp}
+ *   sub   rIdx, #1
+ *   cmp   rVal, rKey
+ *   ifeq
+ *   add   rARM_PC, rDisp   ; This is the branch from which we compute displacement
+ *   cbnz  rIdx, lp
+ */
+void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
+{
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
+  if (cUnit->printMe) {
+    dumpSparseSwitchTable(table);
+  }
+  // Add the table to the list - we'll process it later
+  SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
+                                              true, kAllocData);
+  tabRec->table = table;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
+  int size = table[1];
+  tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
+  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
+
+  // Get the switch value
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  int rBase = oatAllocTemp(cUnit);
+  /* Allocate key and disp temps */
+  int rKey = oatAllocTemp(cUnit);
+  int rDisp = oatAllocTemp(cUnit);
+  // Make sure rKey's register number is less than rDisp's number for ldmia
+  if (rKey > rDisp) {
+    int tmp = rDisp;
+    rDisp = rKey;
+    rKey = tmp;
+  }
+  // Materialize a pointer to the switch table
+  newLIR3(cUnit, kThumb2Adr, rBase, 0, (intptr_t)tabRec);
+  // Set up rIdx
+  int rIdx = oatAllocTemp(cUnit);
+  loadConstant(cUnit, rIdx, size);
+  // Establish loop branch target
+  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+  // 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
+  opIT(cUnit, kArmCondEq, "");
+  LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, rDisp);
+  tabRec->anchor = switchBranch;
+  // Needs to use setflags encoding here
+  newLIR3(cUnit, kThumb2SubsRRI12, rIdx, rIdx, 1);
+  opCondBranch(cUnit, kCondNe, target);
+}
+
+
+void genPackedSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
+{
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
+  if (cUnit->printMe) {
+    dumpPackedSwitchTable(table);
+  }
+  // Add the table to the list - we'll process it later
+  SwitchTable *tabRec = (SwitchTable *)oatNew(cUnit, sizeof(SwitchTable),
+                                              true, kAllocData);
+  tabRec->table = table;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
+  int size = table[1];
+  tabRec->targets = (LIR* *)oatNew(cUnit, size * sizeof(LIR*), true, kAllocLIR);
+  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
+
+  // Get the switch value
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  int tableBase = oatAllocTemp(cUnit);
+  // Materialize a pointer to the switch table
+  newLIR3(cUnit, kThumb2Adr, tableBase, 0, (intptr_t)tabRec);
+  int lowKey = s4FromSwitchData(&table[2]);
+  int keyReg;
+  // Remove the bias, if necessary
+  if (lowKey == 0) {
+    keyReg = rlSrc.lowReg;
+  } else {
+    keyReg = oatAllocTemp(cUnit);
+    opRegRegImm(cUnit, kOpSub, keyReg, rlSrc.lowReg, lowKey);
+  }
+  // Bounds check - if < 0 or >= size continue following switch
+  opRegImm(cUnit, kOpCmp, keyReg, size-1);
+  LIR* branchOver = opCondBranch(cUnit, kCondHi, NULL);
+
+  // 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
+  LIR* switchBranch = newLIR1(cUnit, kThumb2AddPCR, dispReg);
+  tabRec->anchor = switchBranch;
+
+  /* branchOver target here */
+  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+  branchOver->target = (LIR*)target;
+}
+
+/*
+ * Array data table format:
+ *  ushort ident = 0x0300   magic value
+ *  ushort width            width of each element in the table
+ *  uint   size             number of elements in the table
+ *  ubyte  data[size*width] table of data values (may contain a single-byte
+ *                          padding at the end)
+ *
+ * Total size is 4+(width * size + 1)/2 16-bit code units.
+ */
+void genFillArrayData(CompilationUnit* cUnit, uint32_t tableOffset, RegLocation rlSrc)
+{
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
+  // Add the table to the list - we'll process it later
+  FillArrayData *tabRec = (FillArrayData *)
+     oatNew(cUnit, sizeof(FillArrayData), true, kAllocData);
+  tabRec->table = table;
+  tabRec->vaddr = cUnit->currentDalvikOffset;
+  u2 width = tabRec->table[1];
+  u4 size = tabRec->table[2] | (((u4)tabRec->table[3]) << 16);
+  tabRec->size = (size * width) + 8;
+
+  oatInsertGrowableList(cUnit, &cUnit->fillArrayData, (intptr_t)tabRec);
+
+  // Making a call - use explicit registers
+  oatFlushAllRegs(cUnit);   /* Everything to home location */
+  loadValueDirectFixed(cUnit, rlSrc, r0);
+  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode),
+               rARM_LR);
+  // Materialize a pointer to the fill data image
+  newLIR3(cUnit, kThumb2Adr, r1, 0, (intptr_t)tabRec);
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
+  markSafepointPC(cUnit, callInst);
+}
+
+/*
+ * Handle simple case (thin lock) inline.  If it's complicated, bail
+ * out to the heavyweight lock/unlock routines.  We'll use dedicated
+ * registers here in order to be in the right position in case we
+ * to bail to dvm[Lock/Unlock]Object(self, object)
+ *
+ * r0 -> self pointer [arg0 for dvm[Lock/Unlock]Object
+ * r1 -> object [arg1 for dvm[Lock/Unlock]Object
+ * r2 -> intial contents of object->lock, later result of strex
+ * r3 -> self->threadId
+ * r12 -> allow to be used by utilities as general temp
+ *
+ * The result of the strex is 0 if we acquire the lock.
+ *
+ * See comments in Sync.c for the layout of the lock word.
+ * Of particular interest to this code is the test for the
+ * simple case - which we handle inline.  For monitor enter, the
+ * simple case is thin lock, held by no-one.  For monitor exit,
+ * the simple case is thin lock, held by the unlocking thread with
+ * a recurse count of 0.
+ *
+ * A minor complication is that there is a field in the lock word
+ * unrelated to locking: the hash state.  This field must be ignored, but
+ * preserved.
+ *
+ */
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  DCHECK_EQ(LW_SHAPE_THIN, 0);
+  loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
+  loadWordDisp(cUnit, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
+  newLIR3(cUnit, kThumb2Ldrex, r1, r0,
+          Object::MonitorOffset().Int32Value() >> 2); // Get object->lock
+  // Align owner
+  opRegImm(cUnit, kOpLsl, r2, LW_LOCK_OWNER_SHIFT);
+  // Is lock unheld on lock or held by us (==threadId) on unlock?
+  newLIR4(cUnit, kThumb2Bfi, r2, r1, 0, LW_LOCK_OWNER_SHIFT - 1);
+  newLIR3(cUnit, kThumb2Bfc, r1, LW_HASH_STATE_SHIFT, LW_LOCK_OWNER_SHIFT - 1);
+  opRegImm(cUnit, kOpCmp, r1, 0);
+  opIT(cUnit, kArmCondEq, "");
+  newLIR4(cUnit, kThumb2Strex, r1, r2, r0,
+          Object::MonitorOffset().Int32Value() >> 2);
+  opRegImm(cUnit, kOpCmp, r1, 0);
+  opIT(cUnit, kArmCondNe, "T");
+  // Go expensive route - artLockObjectFromCode(self, obj);
+  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pLockObjectFromCode), rARM_LR);
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
+  markSafepointPC(cUnit, callInst);
+  oatGenMemBarrier(cUnit, kSY);
+}
+
+/*
+ * For monitor unlock, we don't have to use ldrex/strex.  Once
+ * we've determined that the lock is thin and that we own it with
+ * a zero recursion count, it's safe to punch it back to the
+ * initial, unlock thin state with a store word.
+ */
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  DCHECK_EQ(LW_SHAPE_THIN, 0);
+  oatFlushAllRegs(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, r0);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, r0, optFlags);
+  loadWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r1); // Get lock
+  loadWordDisp(cUnit, rARM_SELF, Thread::ThinLockIdOffset().Int32Value(), r2);
+  // Is lock unheld on lock or held by us (==threadId) on unlock?
+  opRegRegImm(cUnit, kOpAnd, r3, r1,
+              (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT));
+  // Align owner
+  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);
+  opIT(cUnit, kArmCondEq, "EE");
+  storeWordDisp(cUnit, r0, Object::MonitorOffset().Int32Value(), r3);
+  // Go expensive route - UnlockObjectFromCode(obj);
+  loadWordDisp(cUnit, rARM_SELF, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rARM_LR);
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rARM_LR);
+  markSafepointPC(cUnit, callInst);
+  oatGenMemBarrier(cUnit, kSY);
+}
+
+/*
+ * 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 = opCmpImmBranch(cUnit, kCondEq, valReg, 0, NULL);
+  loadWordDisp(cUnit, rARM_SELF, Thread::CardTableOffset().Int32Value(), regCardBase);
+  opRegRegImm(cUnit, kOpLsr, regCardNo, tgtAddrReg, CardTable::kCardShift);
+  storeBaseIndexed(cUnit, regCardBase, regCardNo, regCardBase, 0,
+                   kUnsignedByte);
+  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+  branchOver->target = (LIR*)target;
+  oatFreeTemp(cUnit, regCardBase);
+  oatFreeTemp(cUnit, regCardNo);
+}
+
+void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
+                      RegLocation rlMethod)
+{
+  int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
+  /*
+   * On entry, r0, r1, r2 & r3 are live.  Let the register allocation
+   * mechanism know so it doesn't try to use any of them when
+   * expanding the frame or flushing.  This leaves the utility
+   * code with a single temp: r12.  This should be enough.
+   */
+  oatLockTemp(cUnit, r0);
+  oatLockTemp(cUnit, r1);
+  oatLockTemp(cUnit, r2);
+  oatLockTemp(cUnit, r3);
+
+  /*
+   * We can safely skip the stack overflow check if we're
+   * a leaf *and* our frame size < fudge factor.
+   */
+  bool skipOverflowCheck = ((cUnit->attrs & METHOD_IS_LEAF) &&
+                            ((size_t)cUnit->frameSize <
+                            Thread::kStackOverflowReservedBytes));
+  newLIR0(cUnit, kPseudoMethodEntry);
+  if (!skipOverflowCheck) {
+    /* Load stack limit */
+    loadWordDisp(cUnit, rARM_SELF, Thread::StackEndOffset().Int32Value(), r12);
+  }
+  /* Spill core callee saves */
+  newLIR1(cUnit, kThumb2Push, cUnit->coreSpillMask);
+  /* Need to spill any FP regs? */
+  if (cUnit->numFPSpills) {
+    /*
+     * NOTE: fp spills are a little different from core spills in that
+     * they are pushed as a contiguous block.  When promoting from
+     * the fp set, we must allocate all singles from s16..highest-promoted
+     */
+    newLIR1(cUnit, kThumb2VPushCS, cUnit->numFPSpills);
+  }
+  if (!skipOverflowCheck) {
+    opRegRegImm(cUnit, kOpSub, rARM_LR, rARM_SP, cUnit->frameSize - (spillCount * 4));
+    genRegRegCheck(cUnit, kCondCc, rARM_LR, r12, kThrowStackOverflow);
+    opRegCopy(cUnit, rARM_SP, rARM_LR);     // Establish stack
+  } else {
+    opRegImm(cUnit, kOpSub, rARM_SP, cUnit->frameSize - (spillCount * 4));
+  }
+
+  flushIns(cUnit, argLocs, rlMethod);
+
+  oatFreeTemp(cUnit, r0);
+  oatFreeTemp(cUnit, r1);
+  oatFreeTemp(cUnit, r2);
+  oatFreeTemp(cUnit, r3);
+}
+
+void genExitSequence(CompilationUnit* cUnit)
+{
+  int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
+  /*
+   * In the exit path, r0/r1 are live - make sure they aren't
+   * allocated by the register utilities as temps.
+   */
+  oatLockTemp(cUnit, r0);
+  oatLockTemp(cUnit, r1);
+
+  newLIR0(cUnit, kPseudoMethodExit);
+  opRegImm(cUnit, kOpAdd, rARM_SP, cUnit->frameSize - (spillCount * 4));
+  /* Need to restore any FP callee saves? */
+  if (cUnit->numFPSpills) {
+    newLIR1(cUnit, kThumb2VPopCS, cUnit->numFPSpills);
+  }
+  if (cUnit->coreSpillMask & (1 << rARM_LR)) {
+    /* Unspill rARM_LR to rARM_PC */
+    cUnit->coreSpillMask &= ~(1 << rARM_LR);
+    cUnit->coreSpillMask |= (1 << rARM_PC);
+  }
+  newLIR1(cUnit, kThumb2Pop, cUnit->coreSpillMask);
+  if (!(cUnit->coreSpillMask & (1 << rARM_PC))) {
+    /* We didn't pop to rARM_PC, so must do a bv rARM_LR */
+    newLIR1(cUnit, kThumbBx, rARM_LR);
+  }
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/arm/Codegen.h b/src/compiler/codegen/arm/codegen.h
similarity index 99%
rename from src/compiler/codegen/arm/Codegen.h
rename to src/compiler/codegen/arm/codegen.h
index 0890c15..47f45c6 100644
--- a/src/compiler/codegen/arm/Codegen.h
+++ b/src/compiler/codegen/arm/codegen.h
@@ -16,7 +16,7 @@
 
 /* This file contains register alloction support. */
 
-#include "../../CompilerIR.h"
+#include "../../compiler_ir.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/arm/FP/Thumb2VFP.cc b/src/compiler/codegen/arm/fp_arm.cc
similarity index 81%
rename from src/compiler/codegen/arm/FP/Thumb2VFP.cc
rename to src/compiler/codegen/arm/fp_arm.cc
index 1774a5b..8c22050 100644
--- a/src/compiler/codegen/arm/FP/Thumb2VFP.cc
+++ b/src/compiler/codegen/arm/fp_arm.cc
@@ -272,4 +272,48 @@
   return false;
 }
 
+void genNegFloat(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValue(cUnit, rlSrc, kFPReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
+  newLIR2(cUnit, kThumb2Vnegs, rlResult.lowReg, rlSrc.lowReg);
+  storeValue(cUnit, rlDest, rlResult);
+}
+
+void genNegDouble(CompilationUnit* cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
+  newLIR2(cUnit, kThumb2Vnegd, s2d(rlResult.lowReg, rlResult.highReg),
+          s2d(rlSrc.lowReg, rlSrc.highReg));
+  storeValueWide(cUnit, rlDest, rlResult);
+}
+
+bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
+  DCHECK_EQ(cUnit->instructionSet, kThumb2);
+  LIR *branch;
+  RegLocation rlSrc = info->args[0];
+  RegLocation rlDest = inlineTargetWide(cUnit, info);  // double place for result
+  rlSrc = loadValueWide(cUnit, rlSrc, kFPReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kFPReg, true);
+  newLIR2(cUnit, kThumb2Vsqrtd, s2d(rlResult.lowReg, rlResult.highReg),
+          s2d(rlSrc.lowReg, rlSrc.highReg));
+  newLIR2(cUnit, kThumb2Vcmpd, s2d(rlResult.lowReg, rlResult.highReg),
+          s2d(rlResult.lowReg, rlResult.highReg));
+  newLIR0(cUnit, kThumb2Fmstat);
+  branch = newLIR2(cUnit, kThumbBCond, 0, kArmCondEq);
+  oatClobberCalleeSave(cUnit);
+  oatLockCallTemps(cUnit);  // Using fixed registers
+  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pSqrt));
+  newLIR3(cUnit, kThumb2Fmrrd, r0, r1, s2d(rlSrc.lowReg, rlSrc.highReg));
+  newLIR1(cUnit, kThumbBlxR, rTgt);
+  newLIR3(cUnit, kThumb2Fmdrr, s2d(rlResult.lowReg, rlResult.highReg), r0, r1);
+  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+  storeValueWide(cUnit, rlDest, rlResult);
+  return true;
+}
+
+
 }  // namespace art
diff --git a/src/compiler/codegen/arm/int_arm.cc b/src/compiler/codegen/arm/int_arm.cc
new file mode 100644
index 0000000..d7bd523
--- /dev/null
+++ b/src/compiler/codegen/arm/int_arm.cc
@@ -0,0 +1,549 @@
+/*
+ * 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.
+ */
+
+/* This file contains codegen for the Thumb2 ISA. */
+
+#include "oat_compilation_unit.h"
+#include "oat/runtime/oat_support_entrypoints.h"
+
+namespace art {
+
+LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+         int src2, LIR* target)
+{
+  opRegReg(cUnit, kOpCmp, src1, src2);
+  return opCondBranch(cUnit, cond, target);
+}
+
+/*
+ * Generate a Thumb2 IT instruction, which can nullify up to
+ * four subsequent instructions based on a condition and its
+ * inverse.  The condition applies to the first instruction, which
+ * is executed if the condition is met.  The string "guide" consists
+ * of 0 to 3 chars, and applies to the 2nd through 4th instruction.
+ * A "T" means the instruction is executed if the condition is
+ * met, and an "E" means the instruction is executed if the condition
+ * is not met.
+ */
+LIR* opIT(CompilationUnit* cUnit, ArmConditionCode code, const char* guide)
+{
+  int mask;
+  int condBit = code & 1;
+  int altBit = condBit ^ 1;
+  int mask3 = 0;
+  int mask2 = 0;
+  int mask1 = 0;
+
+  //Note: case fallthroughs intentional
+  switch (strlen(guide)) {
+    case 3:
+      mask1 = (guide[2] == 'T') ? condBit : altBit;
+    case 2:
+      mask2 = (guide[1] == 'T') ? condBit : altBit;
+    case 1:
+      mask3 = (guide[0] == 'T') ? condBit : altBit;
+      break;
+    case 0:
+      break;
+    default:
+      LOG(FATAL) << "OAT: bad case in opIT";
+  }
+  mask = (mask3 << 3) | (mask2 << 2) | (mask1 << 1) |
+       (1 << (3 - strlen(guide)));
+  return newLIR2(cUnit, kThumb2It, code, mask);
+}
+
+/*
+ * 64-bit 3way compare function.
+ *     mov   rX, #-1
+ *     cmp   op1hi, op2hi
+ *     blt   done
+ *     bgt   flip
+ *     sub   rX, op1lo, op2lo (treat as unsigned)
+ *     beq   done
+ *     ite   hi
+ *     mov(hi)   rX, #-1
+ *     mov(!hi)  rX, #1
+ * flip:
+ *     neg   rX
+ * done:
+ */
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
+        RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  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);
+  LIR* branch1 = opCondBranch(cUnit, kCondLt, NULL);
+  LIR* branch2 = opCondBranch(cUnit, kCondGt, NULL);
+  opRegRegReg(cUnit, kOpSub, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
+  LIR* branch3 = opCondBranch(cUnit, kCondEq, NULL);
+
+  opIT(cUnit, kArmCondHi, "E");
+  newLIR2(cUnit, kThumb2MovImmShift, tReg, modifiedImmediate(-1));
+  loadConstant(cUnit, tReg, 1);
+  genBarrier(cUnit);
+
+  target2 = newLIR0(cUnit, kPseudoTargetLabel);
+  opRegReg(cUnit, kOpNeg, tReg, tReg);
+
+  target1 = newLIR0(cUnit, kPseudoTargetLabel);
+
+  RegLocation rlTemp = locCReturn(); // Just using as template, will change
+  rlTemp.lowReg = tReg;
+  storeValue(cUnit, rlDest, rlTemp);
+  oatFreeTemp(cUnit, tReg);
+
+  branch1->target = (LIR*)target1;
+  branch2->target = (LIR*)target2;
+  branch3->target = branch1->target;
+}
+
+void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+{
+  LIR* labelList = cUnit->blockLabelList;
+  LIR* taken = &labelList[bb->taken->id];
+  LIR* notTaken = &labelList[bb->fallThrough->id];
+  RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
+  RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
+  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+  ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
+  opRegReg(cUnit, kOpCmp, rlSrc1.highReg, rlSrc2.highReg);
+  switch(ccode) {
+    case kCondEq:
+      opCondBranch(cUnit, kCondNe, notTaken);
+      break;
+    case kCondNe:
+      opCondBranch(cUnit, kCondNe, taken);
+      break;
+    case kCondLt:
+      opCondBranch(cUnit, kCondLt, taken);
+      opCondBranch(cUnit, kCondGt, notTaken);
+      ccode = kCondCc;
+      break;
+    case kCondLe:
+      opCondBranch(cUnit, kCondLt, taken);
+      opCondBranch(cUnit, kCondGt, notTaken);
+      ccode = kCondLs;
+      break;
+    case kCondGt:
+      opCondBranch(cUnit, kCondGt, taken);
+      opCondBranch(cUnit, kCondLt, notTaken);
+      ccode = kCondHi;
+      break;
+    case kCondGe:
+      opCondBranch(cUnit, kCondGt, taken);
+      opCondBranch(cUnit, kCondLt, notTaken);
+      ccode = kCondCs;
+      break;
+    default:
+      LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
+  }
+  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
+  opCondBranch(cUnit, ccode, taken);
+}
+
+/*
+ * Generate a register comparison to an immediate and branch.  Caller
+ * is responsible for setting branch target field.
+ */
+LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+          int checkValue, LIR* target)
+{
+  LIR* branch;
+  int modImm;
+  ArmConditionCode armCond = oatArmConditionEncoding(cond);
+  if ((ARM_LOWREG(reg)) && (checkValue == 0) &&
+     ((armCond == kArmCondEq) || (armCond == kArmCondNe))) {
+    branch = newLIR2(cUnit, (armCond == kArmCondEq) ? kThumb2Cbz : kThumb2Cbnz,
+                     reg, 0);
+  } else {
+    modImm = modifiedImmediate(checkValue);
+    if (ARM_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, armCond);
+  }
+  branch->target = target;
+  return branch;
+}
+LIR* opRegCopyNoInsert(CompilationUnit* cUnit, int rDest, int rSrc)
+{
+  LIR* res;
+  int opcode;
+  if (ARM_FPREG(rDest) || ARM_FPREG(rSrc))
+    return fpRegCopy(cUnit, rDest, rSrc);
+  if (ARM_LOWREG(rDest) && ARM_LOWREG(rSrc))
+    opcode = kThumbMovRR;
+  else if (!ARM_LOWREG(rDest) && !ARM_LOWREG(rSrc))
+     opcode = kThumbMovRR_H2H;
+  else if (ARM_LOWREG(rDest))
+     opcode = kThumbMovRR_H2L;
+  else
+     opcode = kThumbMovRR_L2H;
+  res = rawLIR(cUnit, cUnit->currentDalvikOffset, opcode, rDest, rSrc);
+  if (!(cUnit->disableOpt & (1 << kSafeOptimizations)) && rDest == rSrc) {
+    res->flags.isNop = true;
+  }
+  return res;
+}
+
+LIR* opRegCopy(CompilationUnit* cUnit, int rDest, int rSrc)
+{
+  LIR* res = opRegCopyNoInsert(cUnit, rDest, rSrc);
+  oatAppendLIR(cUnit, (LIR*)res);
+  return res;
+}
+
+void opRegCopyWide(CompilationUnit* cUnit, int destLo, int destHi,
+               int srcLo, int srcHi)
+{
+  bool destFP = ARM_FPREG(destLo) && ARM_FPREG(destHi);
+  bool srcFP = ARM_FPREG(srcLo) && ARM_FPREG(srcHi);
+  DCHECK_EQ(ARM_FPREG(srcLo), ARM_FPREG(srcHi));
+  DCHECK_EQ(ARM_FPREG(destLo), ARM_FPREG(destHi));
+  if (destFP) {
+    if (srcFP) {
+      opRegCopy(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) {
+        opRegCopy(cUnit, destHi, srcHi);
+        opRegCopy(cUnit, destLo, srcLo);
+      } else {
+        opRegCopy(cUnit, destLo, srcLo);
+        opRegCopy(cUnit, destHi, srcHi);
+      }
+    }
+  }
+}
+
+// Table of magic divisors
+enum DividePattern {
+  DivideNone,
+  Divide3,
+  Divide5,
+  Divide7,
+};
+
+struct MagicTable {
+  uint32_t magic;
+  uint32_t shift;
+  DividePattern pattern;
+};
+
+static const MagicTable magicTable[] = {
+  {0, 0, DivideNone},        // 0
+  {0, 0, DivideNone},        // 1
+  {0, 0, DivideNone},        // 2
+  {0x55555556, 0, Divide3},  // 3
+  {0, 0, DivideNone},        // 4
+  {0x66666667, 1, Divide5},  // 5
+  {0x2AAAAAAB, 0, Divide3},  // 6
+  {0x92492493, 2, Divide7},  // 7
+  {0, 0, DivideNone},        // 8
+  {0x38E38E39, 1, Divide5},  // 9
+  {0x66666667, 2, Divide5},  // 10
+  {0x2E8BA2E9, 1, Divide5},  // 11
+  {0x2AAAAAAB, 1, Divide5},  // 12
+  {0x4EC4EC4F, 2, Divide5},  // 13
+  {0x92492493, 3, Divide7},  // 14
+  {0x88888889, 3, Divide7},  // 15
+};
+
+// Integer division by constant via reciprocal multiply (Hacker's Delight, 10-4)
+bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
+                        RegLocation rlSrc, RegLocation rlDest, int lit)
+{
+  if ((lit < 0) || (lit >= (int)(sizeof(magicTable)/sizeof(magicTable[0])))) {
+    return false;
+  }
+  DividePattern pattern = magicTable[lit].pattern;
+  if (pattern == DivideNone) {
+    return false;
+  }
+  // Tuning: add rem patterns
+  if (dalvikOpcode != Instruction::DIV_INT_LIT8) {
+    return false;
+  }
+
+  int rMagic = oatAllocTemp(cUnit);
+  loadConstant(cUnit, rMagic, magicTable[lit].magic);
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  int rHi = oatAllocTemp(cUnit);
+  int rLo = oatAllocTemp(cUnit);
+  newLIR4(cUnit, kThumb2Smull, rLo, rHi, rMagic, rlSrc.lowReg);
+  switch(pattern) {
+    case Divide3:
+      opRegRegRegShift(cUnit, kOpSub, rlResult.lowReg, rHi,
+               rlSrc.lowReg, encodeShift(kArmAsr, 31));
+      break;
+    case Divide5:
+      opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
+      opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
+               encodeShift(kArmAsr, magicTable[lit].shift));
+      break;
+    case Divide7:
+      opRegReg(cUnit, kOpAdd, rHi, rlSrc.lowReg);
+      opRegRegImm(cUnit, kOpAsr, rLo, rlSrc.lowReg, 31);
+      opRegRegRegShift(cUnit, kOpRsub, rlResult.lowReg, rLo, rHi,
+               encodeShift(kArmAsr, magicTable[lit].shift));
+      break;
+    default:
+      LOG(FATAL) << "Unexpected pattern: " << (int)pattern;
+  }
+  storeValue(cUnit, rlDest, rlResult);
+  return true;
+}
+
+LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode,
+                    int reg1, int base, int offset, ThrowKind kind)
+{
+  LOG(FATAL) << "Unexpected use of genRegMemCheck for Arm";
+  return NULL;
+}
+
+RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int lit, bool isDiv)
+{
+  LOG(FATAL) << "Unexpected use of genDivRemLit for Arm";
+  return rlDest;
+}
+
+RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int reg2, bool isDiv)
+{
+  LOG(FATAL) << "Unexpected use of genDivRem for Arm";
+  return rlDest;
+}
+
+bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
+{
+  DCHECK_EQ(cUnit->instructionSet, kThumb2);
+  RegLocation rlSrc1 = info->args[0];
+  RegLocation rlSrc2 = info->args[1];
+  rlSrc1 = loadValue(cUnit, rlSrc1, kCoreReg);
+  rlSrc2 = loadValue(cUnit, rlSrc2, kCoreReg);
+  RegLocation rlDest = inlineTarget(cUnit, info);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opRegReg(cUnit, kOpCmp, rlSrc1.lowReg, rlSrc2.lowReg);
+  opIT(cUnit, (isMin) ? kArmCondGt : kArmCondLt, "E");
+  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
+  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
+  genBarrier(cUnit);
+  storeValue(cUnit, rlDest, rlResult);
+  return true;
+}
+
+void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset)
+{
+  LOG(FATAL) << "Unexpected use of opLea for Arm";
+}
+
+void opTlsCmp(CompilationUnit* cUnit, int offset, int val)
+{
+  LOG(FATAL) << "Unexpected use of opTlsCmp for Arm";
+}
+
+bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) {
+  DCHECK_EQ(cUnit->instructionSet, kThumb2);
+  // Unused - RegLocation rlSrcUnsafe = info->args[0];
+  RegLocation rlSrcObj= info->args[1];  // Object - known non-null
+  RegLocation rlSrcOffset= info->args[2];  // long low
+  rlSrcOffset.wide = 0;  // ignore high half in info->args[3]
+  RegLocation rlSrcExpected= info->args[4];  // int or Object
+  RegLocation rlSrcNewValue= info->args[5];  // int or Object
+  RegLocation rlDest = inlineTarget(cUnit, info);  // boolean place for result
+
+
+  // Release store semantics, get the barrier out of the way.
+  oatGenMemBarrier(cUnit, kSY);
+
+  RegLocation rlObject = loadValue(cUnit, rlSrcObj, kCoreReg);
+  RegLocation rlNewValue = loadValue(cUnit, rlSrcNewValue, kCoreReg);
+
+  if (need_write_barrier) {
+    // Mark card for object assuming new value is stored.
+    markGCCard(cUnit, rlNewValue.lowReg, rlObject.lowReg);
+  }
+
+  RegLocation rlOffset = loadValue(cUnit, rlSrcOffset, kCoreReg);
+
+  int rPtr = oatAllocTemp(cUnit);
+  opRegRegReg(cUnit, kOpAdd, rPtr, rlObject.lowReg, rlOffset.lowReg);
+
+  // Free now unneeded rlObject and rlOffset to give more temps.
+  oatClobberSReg(cUnit, rlObject.sRegLow);
+  oatFreeTemp(cUnit, rlObject.lowReg);
+  oatClobberSReg(cUnit, rlOffset.sRegLow);
+  oatFreeTemp(cUnit, rlOffset.lowReg);
+
+  int rOldValue = oatAllocTemp(cUnit);
+  newLIR3(cUnit, kThumb2Ldrex, rOldValue, rPtr, 0);  // rOldValue := [rPtr]
+
+  RegLocation rlExpected = loadValue(cUnit, rlSrcExpected, kCoreReg);
+
+  // if (rOldValue == rExpected) {
+  //   [rPtr] <- rNewValue && rResult := success ? 0 : 1
+  //   rResult ^= 1
+  // } else {
+  //   rResult := 0
+  // }
+  opRegReg(cUnit, kOpCmp, rOldValue, rlExpected.lowReg);
+  oatFreeTemp(cUnit, rOldValue);  // Now unneeded.
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opIT(cUnit, kArmCondEq, "TE");
+  newLIR4(cUnit, kThumb2Strex, rlResult.lowReg, rlNewValue.lowReg, rPtr, 0);
+  oatFreeTemp(cUnit, rPtr);  // Now unneeded.
+  opRegImm(cUnit, kOpXor, rlResult.lowReg, 1);
+  opRegReg(cUnit, kOpXor, rlResult.lowReg, rlResult.lowReg);
+
+  storeValue(cUnit, rlDest, rlResult);
+
+  return true;
+}
+
+LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target)
+{
+  return rawLIR(cUnit, cUnit->currentDalvikOffset, kThumb2LdrPcRel12, reg, 0, 0, 0, 0, target);
+}
+
+LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
+{
+  return newLIR3(cUnit, kThumb2Vldms, rBase, fr0, count);
+}
+
+LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
+{
+  return newLIR3(cUnit, kThumb2Vstms, rBase, fr0, count);
+}
+
+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);
+  }
+}
+
+void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
+{
+  int tReg = oatAllocTemp(cUnit);
+  newLIR4(cUnit, kThumb2OrrRRRs, tReg, regLo, regHi, 0);
+  oatFreeTemp(cUnit, tReg);
+  genCheck(cUnit, kCondEq, kThrowDivZero);
+}
+
+// Test suspend flag, return target of taken suspend branch
+LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
+{
+  newLIR2(cUnit, kThumbSubRI8, rARM_SUSPEND, 1);
+  return opCondBranch(cUnit, (target == NULL) ? kCondEq : kCondNe, target);
+}
+
+// Decrement register and branch on condition
+LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
+{
+  // Combine sub & test using sub setflags encoding here
+  newLIR3(cUnit, kThumb2SubsRRI12, reg, reg, 1);
+  return opCondBranch(cUnit, cCode, target);
+}
+
+void oatGenMemBarrier(CompilationUnit* cUnit, int barrierKind)
+{
+#if ANDROID_SMP != 0
+  LIR* dmb = newLIR1(cUnit, kThumb2Dmb, barrierKind);
+  dmb->defMask = ENCODE_ALL;
+#endif
+}
+
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc)
+{
+  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  int zReg = oatAllocTemp(cUnit);
+  loadConstantNoClobber(cUnit, zReg, 0);
+  // Check for destructive overlap
+  if (rlResult.lowReg == rlSrc.highReg) {
+    int tReg = oatAllocTemp(cUnit);
+    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, zReg, rlSrc.lowReg);
+    opRegRegReg(cUnit, kOpSbc, rlResult.highReg, zReg, tReg);
+    oatFreeTemp(cUnit, tReg);
+  } else {
+    opRegRegReg(cUnit, kOpSub, rlResult.lowReg, zReg, rlSrc.lowReg);
+    opRegRegReg(cUnit, kOpSbc, rlResult.highReg, zReg, rlSrc.highReg);
+  }
+  oatFreeTemp(cUnit, zReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genAddLong for Arm";
+  return false;
+}
+
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genSubLong for Arm";
+  return false;
+}
+
+bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genAndLong for Arm";
+  return false;
+}
+
+bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
+               RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genOrLong for Arm";
+  return false;
+}
+
+bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
+               RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genXoLong for Arm";
+  return false;
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/arm/target_arm.cc b/src/compiler/codegen/arm/target_arm.cc
new file mode 100644
index 0000000..fc643ea
--- /dev/null
+++ b/src/compiler/codegen/arm/target_arm.cc
@@ -0,0 +1,867 @@
+/*
+ * 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.
+ */
+
+#include "../../compiler_internals.h"
+#include "arm_lir.h"
+#include "../ralloc.h"
+
+#include <string>
+
+namespace art {
+
+static int coreRegs[] = {r0, r1, r2, r3, rARM_SUSPEND, r5, r6, r7, r8, rARM_SELF, r10,
+                         r11, r12, rARM_SP, rARM_LR, rARM_PC};
+static int reservedRegs[] = {rARM_SUSPEND, rARM_SELF, rARM_SP, rARM_LR, rARM_PC};
+static int fpRegs[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
+                       fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15,
+                       fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
+                       fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31};
+static int coreTemps[] = {r0, r1, r2, r3, r12};
+static int fpTemps[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
+                        fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15};
+
+RegLocation locCReturn()
+{
+  RegLocation res = ARM_LOC_C_RETURN;
+  return res;
+}
+
+RegLocation locCReturnWide()
+{
+  RegLocation res = ARM_LOC_C_RETURN_WIDE;
+  return res;
+}
+
+RegLocation locCReturnFloat()
+{
+  RegLocation res = ARM_LOC_C_RETURN_FLOAT;
+  return res;
+}
+
+RegLocation locCReturnDouble()
+{
+  RegLocation res = ARM_LOC_C_RETURN_DOUBLE;
+  return res;
+}
+
+// Return a target-dependent special register.
+int targetReg(SpecialTargetRegister reg) {
+  int res = INVALID_REG;
+  switch (reg) {
+    case kSelf: res = rARM_SELF; break;
+    case kSuspend: res =  rARM_SUSPEND; break;
+    case kLr: res =  rARM_LR; break;
+    case kPc: res =  rARM_PC; break;
+    case kSp: res =  rARM_SP; break;
+    case kArg0: res = rARM_ARG0; break;
+    case kArg1: res = rARM_ARG1; break;
+    case kArg2: res = rARM_ARG2; break;
+    case kArg3: res = rARM_ARG3; break;
+    case kFArg0: res = rARM_FARG0; break;
+    case kFArg1: res = rARM_FARG1; break;
+    case kFArg2: res = rARM_FARG2; break;
+    case kFArg3: res = rARM_FARG3; break;
+    case kRet0: res = rARM_RET0; break;
+    case kRet1: res = rARM_RET1; break;
+    case kInvokeTgt: res = rARM_INVOKE_TGT; break;
+    case kCount: res = rARM_COUNT; break;
+  }
+  return res;
+}
+
+
+// Create a double from a pair of singles.
+int s2d(int lowReg, int highReg)
+{
+  return ARM_S2D(lowReg, highReg);
+}
+
+// Is reg a single or double?
+bool fpReg(int reg)
+{
+  return ARM_FPREG(reg);
+}
+
+// Is reg a single?
+bool singleReg(int reg)
+{
+  return ARM_SINGLEREG(reg);
+}
+
+// Is reg a double?
+bool doubleReg(int reg)
+{
+  return ARM_DOUBLEREG(reg);
+}
+
+// Return mask to strip off fp reg flags and bias.
+uint32_t fpRegMask()
+{
+  return ARM_FP_REG_MASK;
+}
+
+// True if both regs single, both core or both double.
+bool sameRegType(int reg1, int reg2)
+{
+  return (ARM_REGTYPE(reg1) == ARM_REGTYPE(reg2));
+}
+
+/*
+ * Decode the register id.
+ */
+u8 getRegMaskCommon(CompilationUnit* cUnit, int reg)
+{
+  u8 seed;
+  int shift;
+  int regId;
+
+
+  regId = reg & 0x1f;
+  /* Each double register is equal to a pair of single-precision FP registers */
+  seed = ARM_DOUBLEREG(reg) ? 3 : 1;
+  /* FP register starts at bit position 16 */
+  shift = ARM_FPREG(reg) ? kArmFPReg0 : 0;
+  /* Expand the double register id into single offset */
+  shift += regId;
+  return (seed << shift);
+}
+
+uint64_t getPCUseDefEncoding()
+{
+  return ENCODE_ARM_REG_PC;
+}
+
+void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
+{
+  DCHECK_EQ(cUnit->instructionSet, kThumb2);
+
+  // Thumb2 specific setup
+  uint64_t flags = EncodingMap[lir->opcode].flags;
+  int opcode = lir->opcode;
+
+  if (flags & REG_DEF_SP) {
+    lir->defMask |= ENCODE_ARM_REG_SP;
+  }
+
+  if (flags & REG_USE_SP) {
+    lir->useMask |= ENCODE_ARM_REG_SP;
+  }
+
+  if (flags & REG_DEF_LIST0) {
+    lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[0]);
+  }
+
+  if (flags & REG_DEF_LIST1) {
+    lir->defMask |= ENCODE_ARM_REG_LIST(lir->operands[1]);
+  }
+
+  if (flags & REG_DEF_FPCS_LIST0) {
+    lir->defMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]);
+  }
+
+  if (flags & REG_DEF_FPCS_LIST2) {
+    for (int i = 0; i < lir->operands[2]; i++) {
+      oatSetupRegMask(cUnit, &lir->defMask, lir->operands[1] + i);
+    }
+  }
+
+  if (flags & REG_USE_PC) {
+    lir->useMask |= ENCODE_ARM_REG_PC;
+  }
+
+  /* Conservatively treat the IT block */
+  if (flags & IS_IT) {
+    lir->defMask = ENCODE_ALL;
+  }
+
+  if (flags & REG_USE_LIST0) {
+    lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[0]);
+  }
+
+  if (flags & REG_USE_LIST1) {
+    lir->useMask |= ENCODE_ARM_REG_LIST(lir->operands[1]);
+  }
+
+  if (flags & REG_USE_FPCS_LIST0) {
+    lir->useMask |= ENCODE_ARM_REG_FPCS_LIST(lir->operands[0]);
+  }
+
+  if (flags & REG_USE_FPCS_LIST2) {
+    for (int i = 0; i < lir->operands[2]; i++) {
+      oatSetupRegMask(cUnit, &lir->useMask, lir->operands[1] + i);
+    }
+  }
+  /* Fixup for kThumbPush/lr and kThumbPop/pc */
+  if (opcode == kThumbPush || opcode == kThumbPop) {
+    u8 r8Mask = oatGetRegMaskCommon(cUnit, r8);
+    if ((opcode == kThumbPush) && (lir->useMask & r8Mask)) {
+      lir->useMask &= ~r8Mask;
+      lir->useMask |= ENCODE_ARM_REG_LR;
+    } else if ((opcode == kThumbPop) && (lir->defMask & r8Mask)) {
+      lir->defMask &= ~r8Mask;
+      lir->defMask |= ENCODE_ARM_REG_PC;
+    }
+  }
+  if (flags & REG_DEF_LR) {
+    lir->defMask |= ENCODE_ARM_REG_LR;
+  }
+}
+
+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",
+  "r2",
+  "r3",
+  "r4",
+  "r5",
+  "r6",
+  "r7",
+  "r8",
+  "rSELF",
+  "r10",
+  "r11",
+  "r12",
+  "sp",
+  "lr",
+  "pc",
+};
+
+
+static const char* shiftNames[4] = {
+  "lsl",
+  "lsr",
+  "asr",
+  "ror"};
+
+/* Decode and print a ARM register name */
+char* decodeRegList(int opcode, int vector, char* buf)
+{
+  int i;
+  bool printed = false;
+  buf[0] = 0;
+  for (i = 0; i < 16; i++, vector >>= 1) {
+    if (vector & 0x1) {
+      int regId = i;
+      if (opcode == kThumbPush && i == 8) {
+        regId = r14lr;
+      } else if (opcode == kThumbPop && i == 8) {
+        regId = r15pc;
+      }
+      if (printed) {
+        sprintf(buf + strlen(buf), ", r%d", regId);
+      } else {
+        printed = true;
+        sprintf(buf, "r%d", regId);
+      }
+    }
+  }
+  return buf;
+}
+
+char*  decodeFPCSRegList(int count, int base, char* buf)
+{
+  sprintf(buf, "s%d", base);
+  for (int i = 1; i < count; i++) {
+    sprintf(buf + strlen(buf), ", s%d",base + i);
+  }
+  return buf;
+}
+
+int expandImmediate(int value)
+{
+  int mode = (value & 0xf00) >> 8;
+  u4 bits = value & 0xff;
+  switch (mode) {
+    case 0:
+      return bits;
+     case 1:
+      return (bits << 16) | bits;
+     case 2:
+      return (bits << 24) | (bits << 8);
+     case 3:
+      return (bits << 24) | (bits << 16) | (bits << 8) | bits;
+    default:
+      break;
+  }
+  bits = (bits | 0x80) << 24;
+  return bits >> (((value & 0xf80) >> 7) - 8);
+}
+
+const char* ccNames[] = {"eq","ne","cs","cc","mi","pl","vs","vc",
+                         "hi","ls","ge","lt","gt","le","al","nv"};
+/*
+ * Interpret a format string and build a string no longer than size
+ * See format key in Assemble.c.
+ */
+std::string buildInsnString(const char* fmt, LIR* lir, unsigned char* baseAddr)
+{
+  std::string buf;
+  int i;
+  const char* fmtEnd = &fmt[strlen(fmt)];
+  char tbuf[256];
+  const char* name;
+  char nc;
+  while (fmt < fmtEnd) {
+    int operand;
+    if (*fmt == '!') {
+      fmt++;
+      DCHECK_LT(fmt, fmtEnd);
+      nc = *fmt++;
+      if (nc=='!') {
+        strcpy(tbuf, "!");
+      } else {
+         DCHECK_LT(fmt, fmtEnd);
+         DCHECK_LT((unsigned)(nc-'0'), 4U);
+         operand = lir->operands[nc-'0'];
+         switch (*fmt++) {
+           case 'H':
+             if (operand != 0) {
+               sprintf(tbuf, ", %s %d",shiftNames[operand & 0x3], operand >> 2);
+             } else {
+               strcpy(tbuf,"");
+             }
+             break;
+           case 'B':
+             switch (operand) {
+               case kSY:
+                 name = "sy";
+                 break;
+               case kST:
+                 name = "st";
+                 break;
+               case kISH:
+                 name = "ish";
+                 break;
+               case kISHST:
+                 name = "ishst";
+                 break;
+               case kNSH:
+                 name = "nsh";
+                 break;
+               case kNSHST:
+                 name = "shst";
+                 break;
+               default:
+                 name = "DecodeError2";
+                 break;
+             }
+             strcpy(tbuf, name);
+             break;
+           case 'b':
+             strcpy(tbuf,"0000");
+             for (i=3; i>= 0; i--) {
+               tbuf[i] += operand & 1;
+               operand >>= 1;
+             }
+             break;
+           case 'n':
+             operand = ~expandImmediate(operand);
+             sprintf(tbuf,"%d [%#x]", operand, operand);
+             break;
+           case 'm':
+             operand = expandImmediate(operand);
+             sprintf(tbuf,"%d [%#x]", operand, operand);
+             break;
+           case 's':
+             sprintf(tbuf,"s%d",operand & ARM_FP_REG_MASK);
+             break;
+           case 'S':
+             sprintf(tbuf,"d%d",(operand & ARM_FP_REG_MASK) >> 1);
+             break;
+           case 'h':
+             sprintf(tbuf,"%04x", operand);
+             break;
+           case 'M':
+           case 'd':
+             sprintf(tbuf,"%d", operand);
+             break;
+           case 'C':
+             DCHECK_LT(operand, static_cast<int>(
+                 sizeof(coreRegNames)/sizeof(coreRegNames[0])));
+             sprintf(tbuf,"%s",coreRegNames[operand]);
+             break;
+           case 'E':
+             sprintf(tbuf,"%d", operand*4);
+             break;
+           case 'F':
+             sprintf(tbuf,"%d", operand*2);
+             break;
+           case 'c':
+             strcpy(tbuf, ccNames[operand]);
+             break;
+           case 't':
+             sprintf(tbuf,"0x%08x (L%p)",
+                 (int) baseAddr + lir->offset + 4 +
+                 (operand << 1),
+                 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->offset + 4) &
+                 ~3) + (offset_1 << 21 >> 9) + (offset_2 << 1)) &
+                 0xfffffffc;
+             sprintf(tbuf, "%p", (void *) target);
+             break;
+          }
+
+           /* Nothing to print for BLX_2 */
+           case 'v':
+             strcpy(tbuf, "see above");
+             break;
+           case 'R':
+             decodeRegList(lir->opcode, operand, tbuf);
+             break;
+           case 'P':
+             decodeFPCSRegList(operand, 16, tbuf);
+             break;
+           case 'Q':
+             decodeFPCSRegList(operand, 0, tbuf);
+             break;
+           default:
+             strcpy(tbuf,"DecodeError1");
+             break;
+        }
+        buf += tbuf;
+      }
+    } else {
+       buf += *fmt++;
+    }
+  }
+  return buf;
+}
+
+void oatDumpResourceMask(LIR* lir, u8 mask, const char* prefix)
+{
+  char buf[256];
+  buf[0] = 0;
+  LIR* armLIR = (LIR*) lir;
+
+  if (mask == ENCODE_ALL) {
+    strcpy(buf, "all");
+  } else {
+    char num[8];
+    int i;
+
+    for (i = 0; i < kArmRegEnd; i++) {
+      if (mask & (1ULL << i)) {
+        sprintf(num, "%d ", i);
+        strcat(buf, num);
+      }
+    }
+
+    if (mask & ENCODE_CCODE) {
+      strcat(buf, "cc ");
+    }
+    if (mask & ENCODE_FP_STATUS) {
+      strcat(buf, "fpcc ");
+    }
+
+    /* Memory bits */
+    if (armLIR && (mask & ENCODE_DALVIK_REG)) {
+      sprintf(buf + strlen(buf), "dr%d%s", armLIR->aliasInfo & 0xffff,
+              (armLIR->aliasInfo & 0x80000000) ? "(+1)" : "");
+    }
+    if (mask & ENCODE_LITERAL) {
+      strcat(buf, "lit ");
+    }
+
+    if (mask & ENCODE_HEAP_REF) {
+      strcat(buf, "heap ");
+    }
+    if (mask & ENCODE_MUST_NOT_ALIAS) {
+      strcat(buf, "noalias ");
+    }
+  }
+  if (buf[0]) {
+    LOG(INFO) << prefix << ": " << buf;
+  }
+}
+
+/*
+ * Nop any unconditional branches that go to the next instruction.
+ * Note: new redundant branches may be inserted later, and we'll
+ * use a check in final instruction assembly to nop those out.
+ */
+void removeRedundantBranches(CompilationUnit* cUnit)
+{
+  LIR* thisLIR;
+
+  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)) {
+      LIR* nextLIR = thisLIR;
+
+      while (true) {
+        nextLIR = NEXT_LIR(nextLIR);
+
+        /*
+         * Is the branch target the next instruction?
+         */
+        if (nextLIR == (LIR*) thisLIR->target) {
+          thisLIR->flags.isNop = true;
+          break;
+        }
+
+        /*
+         * Found real useful stuff between the branch and the target.
+         * Need to explicitly check the lastLIRInsn here because it
+         * might be the last real instruction.
+         */
+        if (!isPseudoOpcode(nextLIR->opcode) ||
+          (nextLIR = (LIR*) cUnit->lastLIRInsn))
+          break;
+      }
+    }
+  }
+}
+
+/* Common initialization routine for an architecture family */
+bool oatArchInit()
+{
+  int i;
+
+  for (i = 0; i < kArmLast; i++) {
+    if (EncodingMap[i].opcode != i) {
+      LOG(FATAL) << "Encoding order for " << EncodingMap[i].name
+                 << " is wrong: expecting " << i << ", seeing "
+                 << (int)EncodingMap[i].opcode;
+    }
+  }
+
+  return oatArchVariantInit();
+}
+/*
+ * Determine the initial instruction set to be used for this trace.
+ * Later components may decide to change this.
+ */
+InstructionSet oatInstructionSet()
+{
+  return kThumb2;
+}
+
+/* Architecture-specific initializations and checks go here */
+bool oatArchVariantInit(void)
+{
+  return true;
+}
+
+int oatTargetOptHint(int key)
+{
+  int res = 0;
+  switch (key) {
+    case kMaxHoistDistance:
+      res = 7;
+      break;
+    default:
+      LOG(FATAL) << "Unknown target optimization hint key: " << key;
+    }
+  return res;
+}
+
+/* This file contains codegen for the Thumb ISA. */
+
+/*
+ * Alloc a pair of core registers, or a double.  Low reg in low byte,
+ * high reg in next byte.
+ */
+int oatAllocTypedTempPair(CompilationUnit* cUnit, bool fpHint, int regClass)
+{
+  int highReg;
+  int lowReg;
+  int res = 0;
+
+  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
+    lowReg = oatAllocTempDouble(cUnit);
+    highReg = lowReg + 1;
+  } else {
+    lowReg = oatAllocTemp(cUnit);
+    highReg = oatAllocTemp(cUnit);
+  }
+  res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
+  return res;
+}
+
+int oatAllocTypedTemp(CompilationUnit* cUnit, bool fpHint, int regClass)
+{
+  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
+    return oatAllocTempFloat(cUnit);
+  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 && (reservedRegs[i] == rARM_SUSPEND)) {
+      //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]);
+  }
+
+  // Start allocation at r2 in an attempt to avoid clobbering return values
+  pool->nextCoreReg = r2;
+
+  // 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);
+  }
+}
+/*
+ * 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 << rARM_LR);
+  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).
+ */
+void oatMarkPreservedSingle(CompilationUnit* cUnit, int vReg, int reg)
+{
+  DCHECK_GE(reg, ARM_FP_REG_MASK + ARM_FP_CALLEE_SAVE_BASE);
+  reg = (reg & ARM_FP_REG_MASK) - ARM_FP_CALLEE_SAVE_BASE;
+  // Ensure fpVmapTable is large enough
+  int tableSize = cUnit->fpVmapTable.size();
+  for (int i = tableSize; i < (reg + 1); i++) {
+    cUnit->fpVmapTable.push_back(INVALID_VREG);
+  }
+  // Add the current mapping
+  cUnit->fpVmapTable[reg] = vReg;
+  // Size of fpVmapTable is high-water mark, use to set mask
+  cUnit->numFPSpills = cUnit->fpVmapTable.size();
+  cUnit->fpSpillMask = ((1 << cUnit->numFPSpills) - 1) << ARM_FP_CALLEE_SAVE_BASE;
+}
+
+void oatFlushRegWide(CompilationUnit* cUnit, int reg1, int reg2)
+{
+  RegisterInfo* info1 = oatGetRegInfo(cUnit, reg1);
+  RegisterInfo* info2 = oatGetRegInfo(cUnit, reg2);
+  DCHECK(info1 && info2 && info1->pair && info2->pair &&
+       (info1->partner == info2->reg) &&
+       (info2->partner == info1->reg));
+  if ((info1->live && info1->dirty) || (info2->live && info2->dirty)) {
+    if (!(info1->isTemp && info2->isTemp)) {
+      /* Should not happen.  If it does, there's a problem in evalLoc */
+      LOG(FATAL) << "Long half-temp, half-promoted";
+    }
+
+    info1->dirty = false;
+    info2->dirty = false;
+    if (SRegToVReg(cUnit, info2->sReg) <
+      SRegToVReg(cUnit, info1->sReg))
+      info1 = info2;
+    int vReg = SRegToVReg(cUnit, info1->sReg);
+    oatFlushRegWideImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg),
+                        info1->reg, info1->partner);
+  }
+}
+
+void oatFlushReg(CompilationUnit* cUnit, int reg)
+{
+  RegisterInfo* info = oatGetRegInfo(cUnit, reg);
+  if (info->live && info->dirty) {
+    info->dirty = false;
+    int vReg = SRegToVReg(cUnit, info->sReg);
+    oatFlushRegImpl(cUnit, rARM_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
+  }
+}
+
+/* Give access to the target-dependent FP register encoding to common code */
+bool oatIsFpReg(int reg) {
+  return ARM_FPREG(reg);
+}
+
+uint32_t oatFpRegMask() {
+  return ARM_FP_REG_MASK;
+}
+
+/* Clobber all regs that might be used by an external C call */
+void oatClobberCalleeSave(CompilationUnit *cUnit)
+{
+  oatClobber(cUnit, r0);
+  oatClobber(cUnit, r1);
+  oatClobber(cUnit, r2);
+  oatClobber(cUnit, r3);
+  oatClobber(cUnit, r12);
+  oatClobber(cUnit, r14lr);
+  oatClobber(cUnit, fr0);
+  oatClobber(cUnit, fr1);
+  oatClobber(cUnit, fr2);
+  oatClobber(cUnit, fr3);
+  oatClobber(cUnit, fr4);
+  oatClobber(cUnit, fr5);
+  oatClobber(cUnit, fr6);
+  oatClobber(cUnit, fr7);
+  oatClobber(cUnit, fr8);
+  oatClobber(cUnit, fr9);
+  oatClobber(cUnit, fr10);
+  oatClobber(cUnit, fr11);
+  oatClobber(cUnit, fr12);
+  oatClobber(cUnit, fr13);
+  oatClobber(cUnit, fr14);
+  oatClobber(cUnit, fr15);
+}
+
+extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
+{
+  RegLocation res = locCReturnWide();
+  res.lowReg = r2;
+  res.highReg = r3;
+  oatClobber(cUnit, r2);
+  oatClobber(cUnit, r3);
+  oatMarkInUse(cUnit, r2);
+  oatMarkInUse(cUnit, r3);
+  oatMarkPair(cUnit, res.lowReg, res.highReg);
+  return res;
+}
+
+extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
+{
+  RegLocation res = locCReturn();
+  res.lowReg = r1;
+  oatClobber(cUnit, r1);
+  oatMarkInUse(cUnit, r1);
+  return res;
+}
+
+extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
+{
+  return ARM_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & ARM_FP_REG_MASK]
+      : &cUnit->regPool->coreRegs[reg];
+}
+
+/* To be used when explicitly managing register use */
+extern void oatLockCallTemps(CompilationUnit* cUnit)
+{
+  oatLockTemp(cUnit, r0);
+  oatLockTemp(cUnit, r1);
+  oatLockTemp(cUnit, r2);
+  oatLockTemp(cUnit, r3);
+}
+
+/* To be used when explicitly managing register use */
+extern void oatFreeCallTemps(CompilationUnit* cUnit)
+{
+  oatFreeTemp(cUnit, r0);
+  oatFreeTemp(cUnit, r1);
+  oatFreeTemp(cUnit, r2);
+  oatFreeTemp(cUnit, r3);
+}
+
+/* Convert an instruction to a NOP */
+void oatNopLIR( LIR* lir)
+{
+  ((LIR*)lir)->flags.isNop = true;
+}
+
+int loadHelper(CompilationUnit* cUnit, int offset)
+{
+  loadWordDisp(cUnit, rARM_SELF, offset, rARM_LR);
+  return rARM_LR;
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/arm/Thumb2/Factory.cc b/src/compiler/codegen/arm/utility_arm.cc
similarity index 97%
rename from src/compiler/codegen/arm/Thumb2/Factory.cc
rename to src/compiler/codegen/arm/utility_arm.cc
index fc3aaa0..e83093b 100644
--- a/src/compiler/codegen/arm/Thumb2/Factory.cc
+++ b/src/compiler/codegen/arm/utility_arm.cc
@@ -18,17 +18,6 @@
 
 /* This file contains codegen for the Thumb ISA. */
 
-static int coreRegs[] = {r0, r1, r2, r3, rARM_SUSPEND, r5, r6, r7, r8, rARM_SELF, r10,
-                         r11, r12, rARM_SP, rARM_LR, rARM_PC};
-static int reservedRegs[] = {rARM_SUSPEND, rARM_SELF, rARM_SP, rARM_LR, rARM_PC};
-static int fpRegs[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
-                       fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15,
-                       fr16, fr17, fr18, fr19, fr20, fr21, fr22, fr23,
-                       fr24, fr25, fr26, fr27, fr28, fr29, fr30, fr31};
-static int coreTemps[] = {r0, r1, r2, r3, r12};
-static int fpTemps[] = {fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
-                        fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15};
-
 int encodeImmSingle(int value)
 {
   int res;
