Quick compiler source reorganizatio - part 1

A step towards cleanup of the quick compiler source.  In this
CL we rename all files to Art standards, combine some of the
old target-specific files that may have made sense in the
JIT, but no longer do.  Also removed some codegen/<target>/
subdirectories, combined and deleted some existing files.

Still quite a bit of work to do in cleaning up header files,
getting some better consistency in what codegen functions
go where.  That will happen in later CLs.

No logic changes in this CL - just renaming and moving stuff around

Change-Id: Ic172cd3b76d4c670f8e4d5fdd4a3e967db3f4c1e
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;