diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk
index 48731f4..4f89883 100644
--- a/build/Android.libart-compiler-llvm.mk
+++ b/build/Android.libart-compiler-llvm.mk
@@ -37,17 +37,16 @@
 
 ifeq ($(ART_USE_PORTABLE_COMPILER),true)
   LIBART_COMPILER_LLVM_SRC_FILES += \
-    src/compiler/Dataflow.cc \
-    src/compiler/Frontend.cc \
-    src/compiler/IntermediateRep.cc \
-    src/compiler/Ralloc.cc \
-    src/compiler/SSATransformation.cc \
-    src/compiler/Utility.cc \
-    src/compiler/codegen/RallocUtil.cc \
-    src/compiler/codegen/arm/ArchUtility.cc \
-    src/compiler/codegen/arm/ArmRallocUtil.cc \
-    src/compiler/codegen/arm/Assemble.cc \
-    src/compiler/codegen/arm/armv7-a/Codegen.cc \
+    src/compiler/dataflow.cc \
+    src/compiler/frontend.cc \
+    src/compiler/intermediate_rep.cc \
+    src/compiler/ralloc.cc \
+    src/compiler/ssa_transformation.cc \
+    src/compiler/utility.cc \
+    src/compiler/codegen/ralloc_util.cc \
+    src/compiler/codegen/arm/target_arm.cc \
+    src/compiler/codegen/arm/assemble_arm.cc \
+    src/compiler/codegen/arm/backend_arm.cc \
     src/compiler_llvm/dalvik_reg.cc \
     src/compiler_llvm/gbc_expander.cc \
     src/compiler_llvm/method_compiler.cc \
diff --git a/build/Android.libart-compiler.mk b/build/Android.libart-compiler.mk
index 323017a..fa51a99 100644
--- a/build/Android.libart-compiler.mk
+++ b/build/Android.libart-compiler.mk
@@ -15,13 +15,13 @@
 #
 
 LIBART_COMPILER_COMMON_SRC_FILES += \
-	src/compiler/Dataflow.cc \
-	src/compiler/Frontend.cc \
-	src/compiler/IntermediateRep.cc \
-	src/compiler/Ralloc.cc \
-	src/compiler/SSATransformation.cc \
-	src/compiler/Utility.cc \
-	src/compiler/codegen/RallocUtil.cc \
+	src/compiler/dataflow.cc \
+	src/compiler/frontend.cc \
+	src/compiler/intermediate_rep.cc \
+	src/compiler/ralloc.cc \
+	src/compiler/ssa_transformation.cc \
+	src/compiler/utility.cc \
+	src/compiler/codegen/ralloc_util.cc \
 	src/oat/jni/calling_convention.cc \
 	src/oat/jni/jni_compiler.cc \
 	src/oat/jni/arm/calling_convention_arm.cc \
@@ -32,26 +32,23 @@
 
 LIBART_COMPILER_arm_SRC_FILES += \
 	$(LIBART_COMPILER_COMMON_SRC_FILES) \
-	src/compiler/codegen/arm/ArchUtility.cc \
-	src/compiler/codegen/arm/ArmRallocUtil.cc \
-	src/compiler/codegen/arm/Assemble.cc \
-	src/compiler/codegen/arm/armv7-a/Codegen.cc \
+	src/compiler/codegen/arm/target_arm.cc \
+	src/compiler/codegen/arm/assemble_arm.cc \
+	src/compiler/codegen/arm/backend_arm.cc \
 	src/oat/jni/arm/jni_internal_arm.cc
 
 LIBART_COMPILER_mips_SRC_FILES += \
 	$(LIBART_COMPILER_COMMON_SRC_FILES) \
-	src/compiler/codegen/mips/ArchUtility.cc \
-	src/compiler/codegen/mips/MipsRallocUtil.cc \
-	src/compiler/codegen/mips/Assemble.cc \
-	src/compiler/codegen/mips/mips/Codegen.cc \
+	src/compiler/codegen/mips/target_mips.cc \
+	src/compiler/codegen/mips/assemble_mips.cc \
+	src/compiler/codegen/mips/backend_mips.cc \
 	src/oat/jni/mips/jni_internal_mips.cc
 
 LIBART_COMPILER_x86_SRC_FILES += \
 	$(LIBART_COMPILER_COMMON_SRC_FILES) \
-	src/compiler/codegen/x86/ArchUtility.cc \
-	src/compiler/codegen/x86/X86RallocUtil.cc \
-	src/compiler/codegen/x86/Assemble.cc \
-	src/compiler/codegen/x86/x86/Codegen.cc \
+	src/compiler/codegen/x86/target_x86.cc \
+	src/compiler/codegen/x86/assemble_x86.cc \
+	src/compiler/codegen/x86/backend_x86.cc \
 	src/oat/jni/x86/jni_internal_x86.cc
 
 # $(1): target or host
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;
diff --git a/src/compiler/codegen/CodegenFactory.cc b/src/compiler/codegen/codegen_factory.cc
similarity index 100%
rename from src/compiler/codegen/CodegenFactory.cc
rename to src/compiler/codegen/codegen_factory.cc
diff --git a/src/compiler/codegen/CodegenUtil.cc b/src/compiler/codegen/codegen_util.cc
similarity index 100%
rename from src/compiler/codegen/CodegenUtil.cc
rename to src/compiler/codegen/codegen_util.cc
diff --git a/src/compiler/codegen/CompilerCodegen.h b/src/compiler/codegen/compiler_codegen.h
similarity index 93%
rename from src/compiler/codegen/CompilerCodegen.h
rename to src/compiler/codegen/compiler_codegen.h
index 868e666..45838c1 100644
--- a/src/compiler/codegen/CompilerCodegen.h
+++ b/src/compiler/codegen/compiler_codegen.h
@@ -17,7 +17,7 @@
 #ifndef ART_SRC_COMPILER_COMPILERCODEGEN_H_
 #define ART_SRC_COMPILER_COMPILERCODEGEN_H_
 
-#include "../CompilerIR.h"
+#include "../compiler_ir.h"
 
 namespace art {
 
@@ -222,6 +222,7 @@
 LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide);
 uint64_t getPCUseDefEncoding();
 uint64_t getRegMaskCommon(CompilationUnit* cUnit, int reg);
+// TODO: clean up include files
 int s2d(int lowReg, int highReg);
 bool fpReg(int reg);
 bool singleReg(int reg);
@@ -233,6 +234,16 @@
 RegLocation locCReturnWide();
 RegLocation locCReturnFloat();
 RegLocation locCReturnDouble();
+LIR* loadWordDisp(CompilationUnit* cUnit, int rBase, int displacement, int rDest);
+LIR *storeWordDisp(CompilationUnit *cUnit, int rBase,
+                       int displacement, int rSrc);
+void removeRedundantBranches(CompilationUnit* cUnit);
+LIR* newLIR0(CompilationUnit* cUnit, int opcode);
+LIR* newLIR1(CompilationUnit* cUnit, int opcode, int dest);
+LIR *opRegImm(CompilationUnit *cUnit, OpKind op, int rDestSrc1, int value);
+void spillCoreRegs(CompilationUnit* cUnit);
+void unSpillCoreRegs(CompilationUnit* cUnit);
+void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset);
 
 }  // namespace art
 
diff --git a/src/compiler/codegen/GenCommon.cc b/src/compiler/codegen/gen_common.cc
similarity index 100%
rename from src/compiler/codegen/GenCommon.cc
rename to src/compiler/codegen/gen_common.cc
diff --git a/src/compiler/codegen/GenInvoke.cc b/src/compiler/codegen/gen_invoke.cc
similarity index 100%
rename from src/compiler/codegen/GenInvoke.cc
rename to src/compiler/codegen/gen_invoke.cc
diff --git a/src/compiler/codegen/LocalOptimizations.cc b/src/compiler/codegen/local_optimizations.cc
similarity index 100%
rename from src/compiler/codegen/LocalOptimizations.cc
rename to src/compiler/codegen/local_optimizations.cc
diff --git a/src/compiler/codegen/MethodBitcode.cc b/src/compiler/codegen/method_bitcode.cc
similarity index 100%
rename from src/compiler/codegen/MethodBitcode.cc
rename to src/compiler/codegen/method_bitcode.cc
diff --git a/src/compiler/codegen/MethodCodegenDriver.cc b/src/compiler/codegen/method_codegen_driver.cc
similarity index 100%
rename from src/compiler/codegen/MethodCodegenDriver.cc
rename to src/compiler/codegen/method_codegen_driver.cc
diff --git a/src/compiler/codegen/mips/ArchFactory.cc b/src/compiler/codegen/mips/ArchFactory.cc
deleted file mode 100644
index 90c0ede..0000000
--- a/src/compiler/codegen/mips/ArchFactory.cc
+++ /dev/null
@@ -1,281 +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 mips-specific codegen factory support. */
-
-#include "oat/runtime/oat_support_entrypoints.h"
-
-namespace art {
-
-bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  /*
-   *  [v1 v0] =  [a1 a0] + [a3 a2];
-   *  addu v0,a2,a0
-   *  addu t1,a3,a1
-   *  sltu v1,v0,a2
-   *  addu v1,v1,t1
-   */
-
-  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg);
-  int tReg = oatAllocTemp(cUnit);
-  opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg);
-  newLIR3(cUnit, kMipsSltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg);
-  opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg);
-  oatFreeTemp(cUnit, tReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
-        RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  /*
-   *  [v1 v0] =  [a1 a0] - [a3 a2];
-   *  sltu  t1,a0,a2
-   *  subu  v0,a0,a2
-   *  subu  v1,a1,a3
-   *  subu  v1,v1,t1
-   */
-
-  int tReg = oatAllocTemp(cUnit);
-  newLIR3(cUnit, kMipsSltu, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
-  opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
-  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
-  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
-  oatFreeTemp(cUnit, tReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc)
-{
-  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  /*
-   *  [v1 v0] =  -[a1 a0]
-   *  negu  v0,a0
-   *  negu  v1,a1
-   *  sltu  t1,r_zero
-   *  subu  v1,v1,t1
-   */
-
-  opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg);
-  opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg);
-  int tReg = oatAllocTemp(cUnit);
-  newLIR3(cUnit, kMipsSltu, tReg, r_ZERO, rlResult.lowReg);
-  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
-  oatFreeTemp(cUnit, tReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-/*
- * In the Arm code a it is typical to use the link register
- * to hold the target address.  However, for Mips we must
- * ensure that all branch instructions can be restarted if
- * there is a trap in the shadow.  Allocate a temp register.
- */
-int loadHelper(CompilationUnit* cUnit, int offset)
-{
-  loadWordDisp(cUnit, rMIPS_SELF, offset, r_T9);
-  return r_T9;
-}
-
-void spillCoreRegs(CompilationUnit* cUnit)
-{
-  if (cUnit->numCoreSpills == 0) {
-    return;
-  }
-  uint32_t mask = cUnit->coreSpillMask;
-  int offset = cUnit->numCoreSpills * 4;
-  opRegImm(cUnit, kOpSub, rMIPS_SP, offset);
-  for (int reg = 0; mask; mask >>= 1, reg++) {
-    if (mask & 0x1) {
-      offset -= 4;
-      storeWordDisp(cUnit, rMIPS_SP, offset, reg);
-    }
-  }
-}
-
-void unSpillCoreRegs(CompilationUnit* cUnit)
-{
-  if (cUnit->numCoreSpills == 0) {
-    return;
-  }
-  uint32_t mask = cUnit->coreSpillMask;
-  int offset = cUnit->frameSize;
-  for (int reg = 0; mask; mask >>= 1, reg++) {
-    if (mask & 0x1) {
-      offset -= 4;
-      loadWordDisp(cUnit, rMIPS_SP, offset, reg);
-    }
-  }
-  opRegImm(cUnit, kOpAdd, rMIPS_SP, cUnit->frameSize);
-}
-
-void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
-                      RegLocation rlMethod)
-{
-  int spillCount = cUnit->numCoreSpills + cUnit->numFPSpills;
-  /*
-   * On entry, rMIPS_ARG0, rMIPS_ARG1, rMIPS_ARG2 & rMIPS_ARG3 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, rMIPS_ARG0);
-  oatLockTemp(cUnit, rMIPS_ARG1);
-  oatLockTemp(cUnit, rMIPS_ARG2);
-  oatLockTemp(cUnit, rMIPS_ARG3);
-
-  /*
-   * 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);
-  int checkReg = oatAllocTemp(cUnit);
-  int newSP = oatAllocTemp(cUnit);
-  if (!skipOverflowCheck) {
-    /* Load stack limit */
-    loadWordDisp(cUnit, rMIPS_SELF, Thread::StackEndOffset().Int32Value(), checkReg);
-  }
-  /* Spill core callee saves */
-  spillCoreRegs(cUnit);
-  /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
-  DCHECK_EQ(cUnit->numFPSpills, 0);
-  if (!skipOverflowCheck) {
-    opRegRegImm(cUnit, kOpSub, newSP, rMIPS_SP, cUnit->frameSize - (spillCount * 4));
-    genRegRegCheck(cUnit, kCondCc, newSP, checkReg, kThrowStackOverflow);
-    opRegCopy(cUnit, rMIPS_SP, newSP);     // Establish stack
-  } else {
-    opRegImm(cUnit, kOpSub, rMIPS_SP, cUnit->frameSize - (spillCount * 4));
-  }
-
-  flushIns(cUnit, argLocs, rlMethod);
-
-  oatFreeTemp(cUnit, rMIPS_ARG0);
-  oatFreeTemp(cUnit, rMIPS_ARG1);
-  oatFreeTemp(cUnit, rMIPS_ARG2);
-  oatFreeTemp(cUnit, rMIPS_ARG3);
-}
-
-void genExitSequence(CompilationUnit* cUnit)
-{
-  /*
-   * In the exit path, rMIPS_RET0/rMIPS_RET1 are live - make sure they aren't
-   * allocated by the register utilities as temps.
-   */
-  oatLockTemp(cUnit, rMIPS_RET0);
-  oatLockTemp(cUnit, rMIPS_RET1);
-
-  newLIR0(cUnit, kPseudoMethodExit);
-  unSpillCoreRegs(cUnit);
-  opReg(cUnit, kOpBx, r_RA);
-}
-
-/*
- * 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 == kMipsB) {
-      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 < kMipsLast; 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 genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genAndLong for Mips";
-  return false;
-}
-
-bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
-               RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genOrLong for Mips";
-  return false;
-}
-
-bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
-               RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  LOG(FATAL) << "Unexpected use of genXorLong for Mips";
-  return false;
-}
-
-
-
-}  // namespace art
diff --git a/src/compiler/codegen/mips/ArchUtility.cc b/src/compiler/codegen/mips/ArchUtility.cc
deleted file mode 100644
index 3063e69..0000000
--- a/src/compiler/codegen/mips/ArchUtility.cc
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../../CompilerInternals.h"
-#include "MipsLIR.h"
-#include "../Ralloc.h"
-
-#include <string>
-
-namespace art {
-
-RegLocation locCReturn()
-{
-  RegLocation res = MIPS_LOC_C_RETURN;
-  return res;
-}
-
-RegLocation locCReturnWide()
-{
-  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
-  return res;
-}
-
-RegLocation locCReturnFloat()
-{
-  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
-  return res;
-}
-
-RegLocation locCReturnDouble()
-{
-  RegLocation res = MIPS_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 = rMIPS_SELF; break;
-    case kSuspend: res =  rMIPS_SUSPEND; break;
-    case kLr: res =  rMIPS_LR; break;
-    case kPc: res =  rMIPS_PC; break;
-    case kSp: res =  rMIPS_SP; break;
-    case kArg0: res = rMIPS_ARG0; break;
-    case kArg1: res = rMIPS_ARG1; break;
-    case kArg2: res = rMIPS_ARG2; break;
-    case kArg3: res = rMIPS_ARG3; break;
-    case kFArg0: res = rMIPS_FARG0; break;
-    case kFArg1: res = rMIPS_FARG1; break;
-    case kFArg2: res = rMIPS_FARG2; break;
-    case kFArg3: res = rMIPS_FARG3; break;
-    case kRet0: res = rMIPS_RET0; break;
-    case kRet1: res = rMIPS_RET1; break;
-    case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
-    case kCount: res = rMIPS_COUNT; break;
-  }
-  return res;
-}
-
-// Create a double from a pair of singles.
-int s2d(int lowReg, int highReg)
-{
-  return MIPS_S2D(lowReg, highReg);
-}
-
-// Is reg a single or double?
-bool fpReg(int reg)
-{
-  return MIPS_FPREG(reg);
-}
-
-// Is reg a single?
-bool singleReg(int reg)
-{
-  return MIPS_SINGLEREG(reg);
-}
-
-// Is reg a double?
-bool doubleReg(int reg)
-{
-  return MIPS_DOUBLEREG(reg);
-}
-
-// Return mask to strip off fp reg flags and bias.
-uint32_t fpRegMask()
-{
-  return MIPS_FP_REG_MASK;
-}
-
-// True if both regs single, both core or both double.
-bool sameRegType(int reg1, int reg2)
-{
-  return (MIPS_REGTYPE(reg1) == MIPS_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 = MIPS_DOUBLEREG(reg) ? 3 : 1;
-  /* FP register starts at bit position 16 */
-  shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
-  /* Expand the double register id into single offset */
-  shift += regId;
-  return (seed << shift);
-}
-
-uint64_t getPCUseDefEncoding()
-{
-  return ENCODE_MIPS_REG_PC;
-}
-
-
-void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
-{
-  DCHECK_EQ(cUnit->instructionSet, kMips);
-
-  // Mips-specific resource map setup here.
-  uint64_t flags = EncodingMap[lir->opcode].flags;
-
-  if (flags & REG_DEF_SP) {
-    lir->defMask |= ENCODE_MIPS_REG_SP;
-  }
-
-  if (flags & REG_USE_SP) {
-    lir->useMask |= ENCODE_MIPS_REG_SP;
-  }
-
-  if (flags & REG_DEF_LR) {
-    lir->defMask |= ENCODE_MIPS_REG_LR;
-  }
-}
-
-/* For dumping instructions */
-#define MIPS_REG_COUNT 32
-static const char *mipsRegName[MIPS_REG_COUNT] = {
-  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
-  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
-  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
-  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
-};
-
-/*
- * 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];
-  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 'b':
-             strcpy(tbuf,"0000");
-             for (i=3; i>= 0; i--) {
-               tbuf[i] += operand & 1;
-               operand >>= 1;
-             }
-             break;
-           case 's':
-             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
-             break;
-           case 'S':
-             DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
-             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
-             break;
-           case 'h':
-             sprintf(tbuf,"%04x", operand);
-             break;
-           case 'M':
-           case 'd':
-             sprintf(tbuf,"%d", operand);
-             break;
-           case 'D':
-             sprintf(tbuf,"%d", operand+1);
-             break;
-           case 'E':
-             sprintf(tbuf,"%d", operand*4);
-             break;
-           case 'F':
-             sprintf(tbuf,"%d", operand*2);
-             break;
-           case 't':
-             sprintf(tbuf,"0x%08x (L%p)", (int) baseAddr + lir->offset + 4 +
-                     (operand << 2), lir->target);
-             break;
-           case 'T':
-             sprintf(tbuf,"0x%08x", (int) (operand << 2));
-             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':
-             DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
-             strcpy(tbuf, mipsRegName[operand]);
-             break;
-           case 'N':
-             // Placeholder for delay slot handling
-             strcpy(tbuf, ";  nop");
-             break;
-           default:
-             strcpy(tbuf,"DecodeError");
-             break;
-         }
-         buf += tbuf;
-      }
-    } else {
-       buf += *fmt++;
-    }
-  }
-  return buf;
-}
-
-// FIXME: need to redo resource maps for MIPS - fix this at that time
-void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
-{
-  char buf[256];
-  buf[0] = 0;
-  LIR *mipsLIR = (LIR *) lir;
-
-  if (mask == ENCODE_ALL) {
-    strcpy(buf, "all");
-  } else {
-    char num[8];
-    int i;
-
-    for (i = 0; i < kMipsRegEnd; 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 (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
-      sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
-              (mipsLIR->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/mips/Mips32/Gen.cc b/src/compiler/codegen/mips/Mips32/Gen.cc
deleted file mode 100644
index a772c09..0000000
--- a/src/compiler/codegen/mips/Mips32/Gen.cc
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* This file contains codegen for the Mips ISA */
-
-#include "oat/runtime/oat_support_entrypoints.h"
-
-namespace art {
-
-void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
-                    SpecialCaseHandler specialCase)
-{
-    // TODO
-}
-
-/*
- * The lack of pc-relative loads on Mips presents somewhat of a challenge
- * for our PIC switch table strategy.  To materialize the current location
- * we'll do a dummy JAL and reference our tables using r_RA as the
- * base register.  Note that r_RA will be used both as the base to
- * locate the switch table data and as the reference base for the switch
- * target offsets stored in the table.  We'll use a special pseudo-instruction
- * to represent the jal and trigger the construction of the
- * switch table offsets (which will happen after final assembly and all
- * labels are fixed).
- *
- * The test loop will look something like:
- *
- *   ori   rEnd, r_ZERO, #tableSize  ; size in bytes
- *   jal   BaseLabel         ; stores "return address" (BaseLabel) in r_RA
- *   nop                     ; opportunistically fill
- * BaseLabel:
- *   addiu rBase, r_RA, <table> - <BaseLabel>  ; table relative to BaseLabel
-     addu  rEnd, rEnd, rBase                   ; end of table
- *   lw    rVal, [rSP, vRegOff]                ; Test Value
- * loop:
- *   beq   rBase, rEnd, done
- *   lw    rKey, 0(rBase)
- *   addu  rBase, 8
- *   bne   rVal, rKey, loop
- *   lw    rDisp, -4(rBase)
- *   addu  r_RA, rDisp
- *   jr    r_RA
- * done:
- *
- */
-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 elements = table[1];
-  tabRec->targets = (LIR* *)oatNew(cUnit, elements * sizeof(LIR*), true,
-                                   kAllocLIR);
-  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
-
-  // The table is composed of 8-byte key/disp pairs
-  int byteSize = elements * 8;
-
-  int sizeHi = byteSize >> 16;
-  int sizeLo = byteSize & 0xffff;
-
-  int rEnd = oatAllocTemp(cUnit);
-  if (sizeHi) {
-    newLIR2(cUnit, kMipsLui, rEnd, sizeHi);
-  }
-  // Must prevent code motion for the curr pc pair
-  genBarrier(cUnit);  // Scheduling barrier
-  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
-  // Now, fill the branch delay slot
-  if (sizeHi) {
-    newLIR3(cUnit, kMipsOri, rEnd, rEnd, sizeLo);
-  } else {
-    newLIR3(cUnit, kMipsOri, rEnd, r_ZERO, sizeLo);
-  }
-  genBarrier(cUnit);  // Scheduling barrier
-
-  // Construct BaseLabel and set up table base register
-  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
-  // Remember base label so offsets can be computed later
-  tabRec->anchor = baseLabel;
-  int rBase = oatAllocTemp(cUnit);
-  newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
-  opRegRegReg(cUnit, kOpAdd, rEnd, rEnd, rBase);
-
-  // Grab switch test value
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-
-  // Test loop
-  int rKey = oatAllocTemp(cUnit);
-  LIR* loopLabel = newLIR0(cUnit, kPseudoTargetLabel);
-  LIR* exitBranch = opCmpBranch(cUnit , kCondEq, rBase, rEnd, NULL);
-  loadWordDisp(cUnit, rBase, 0, rKey);
-  opRegImm(cUnit, kOpAdd, rBase, 8);
-  opCmpBranch(cUnit, kCondNe, rlSrc.lowReg, rKey, loopLabel);
-  int rDisp = oatAllocTemp(cUnit);
-  loadWordDisp(cUnit, rBase, -4, rDisp);
-  opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp);
-  opReg(cUnit, kOpBx, r_RA);
-
-  // Loop exit
-  LIR* exitLabel = newLIR0(cUnit, kPseudoTargetLabel);
-  exitBranch->target = exitLabel;
-}
-
-/*
- * Code pattern will look something like:
- *
- *   lw    rVal
- *   jal   BaseLabel         ; stores "return address" (BaseLabel) in r_RA
- *   nop                     ; opportunistically fill
- *   [subiu rVal, bias]      ; Remove bias if lowVal != 0
- *   bound check -> done
- *   lw    rDisp, [r_RA, rVal]
- *   addu  r_RA, rDisp
- *   jr    r_RA
- * done:
- */
-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);
-
-  // Prepare the bias.  If too big, handle 1st stage here
-  int lowKey = s4FromSwitchData(&table[2]);
-  bool largeBias = false;
-  int rKey;
-  if (lowKey == 0) {
-    rKey = rlSrc.lowReg;
-  } else if ((lowKey & 0xffff) != lowKey) {
-    rKey = oatAllocTemp(cUnit);
-    loadConstant(cUnit, rKey, lowKey);
-    largeBias = true;
-  } else {
-    rKey = oatAllocTemp(cUnit);
-  }
-
-  // Must prevent code motion for the curr pc pair
-  genBarrier(cUnit);
-  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
-  // Now, fill the branch delay slot with bias strip
-  if (lowKey == 0) {
-    newLIR0(cUnit, kMipsNop);
-  } else {
-    if (largeBias) {
-      opRegRegReg(cUnit, kOpSub, rKey, rlSrc.lowReg, rKey);
-    } else {
-      opRegRegImm(cUnit, kOpSub, rKey, rlSrc.lowReg, lowKey);
-    }
-  }
-  genBarrier(cUnit);  // Scheduling barrier
-
-  // Construct BaseLabel and set up table base register
-  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
-  // Remember base label so offsets can be computed later
-  tabRec->anchor = baseLabel;
-
-  // Bounds check - if < 0 or >= size continue following switch
-  LIR* branchOver = opCmpImmBranch(cUnit, kCondHi, rKey, size-1, NULL);
-
-  // Materialize the table base pointer
-  int rBase = oatAllocTemp(cUnit);
-  newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
-
-  // Load the displacement from the switch table
-  int rDisp = oatAllocTemp(cUnit);
-  loadBaseIndexed(cUnit, rBase, rKey, rDisp, 2, kWord);
-
-  // Add to r_AP and go
-  opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp);
-  opReg(cUnit, kOpBx, r_RA);
-
-  /* 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 */
-  oatLockCallTemps(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);
-
-  // Must prevent code motion for the curr pc pair
-  genBarrier(cUnit);
-  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
-  // Now, fill the branch delay slot with the helper load
-  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode));
-  genBarrier(cUnit);  // Scheduling barrier
-
-  // Construct BaseLabel and set up table base register
-  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
-
-  // Materialize a pointer to the fill data image
-  newLIR4(cUnit, kMipsDelta, rMIPS_ARG1, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
-
-  // And go...
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rTgt); // ( array*, fill_data* )
-  markSafepointPC(cUnit, callInst);
-}
-
-void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, 0x80000000);
-  storeValue(cUnit, rlDest, rlResult);
-}
-
-void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 0x80000000);
-  opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-}
-
-/*
- * TODO: implement fast path to short-circuit thin-lock case
- */
-void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rMIPS_ARG0, optFlags);
-  // Go expensive route - artLockObjectFromCode(self, obj);
-  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode));
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rTgt);
-  markSafepointPC(cUnit, callInst);
-}
-
-/*
- * TODO: implement fast path to short-circuit thin-lock case
- */
-void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rMIPS_ARG0, optFlags);
-  // Go expensive route - UnlockObjectFromCode(obj);
-  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode));
-  oatClobberCalleeSave(cUnit);
-  LIR* callInst = opReg(cUnit, kOpBlx, rTgt);
-  markSafepointPC(cUnit, callInst);
-}
-
-/*
- * Compare two 64-bit values
- *    x = y     return  0
- *    x < y     return -1
- *    x > y     return  1
- *
- *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
- *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
- *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
- *    bnez  res, finish
- *    sltu  t0, x.lo, y.lo
- *    sgtu  r1, x.lo, y.lo
- *    subu  res, t0, t1
- * finish:
- *
- */
-void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
-        RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
-  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
-  int t0 = oatAllocTemp(cUnit);
-  int t1 = oatAllocTemp(cUnit);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  newLIR3(cUnit, kMipsSlt, t0, rlSrc1.highReg, rlSrc2.highReg);
-  newLIR3(cUnit, kMipsSlt, t1, rlSrc2.highReg, rlSrc1.highReg);
-  newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
-  LIR* branch = opCmpImmBranch(cUnit, kCondNe, rlResult.lowReg, 0, NULL);
-  newLIR3(cUnit, kMipsSltu, t0, rlSrc1.lowReg, rlSrc2.lowReg);
-  newLIR3(cUnit, kMipsSltu, t1, rlSrc2.lowReg, rlSrc1.lowReg);
-  newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
-  oatFreeTemp(cUnit, t0);
-  oatFreeTemp(cUnit, t1);
-  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-  branch->target = (LIR*)target;
-  storeValue(cUnit, rlDest, rlResult);
-}
-
-LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
-         int src2, LIR* target)
-{
-  LIR* branch;
-  MipsOpCode sltOp;
-  MipsOpCode brOp;
-  bool cmpZero = false;
-  bool swapped = false;
-  switch (cond) {
-    case kCondEq:
-      brOp = kMipsBeq;
-      cmpZero = true;
-      break;
-    case kCondNe:
-      brOp = kMipsBne;
-      cmpZero = true;
-      break;
-    case kCondCc:
-      sltOp = kMipsSltu;
-      brOp = kMipsBnez;
-      break;
-    case kCondCs:
-      sltOp = kMipsSltu;
-      brOp = kMipsBeqz;
-      break;
-    case kCondGe:
-      sltOp = kMipsSlt;
-      brOp = kMipsBeqz;
-      break;
-    case kCondGt:
-      sltOp = kMipsSlt;
-      brOp = kMipsBnez;
-      swapped = true;
-      break;
-    case kCondLe:
-      sltOp = kMipsSlt;
-      brOp = kMipsBeqz;
-      swapped = true;
-      break;
-    case kCondLt:
-      sltOp = kMipsSlt;
-      brOp = kMipsBnez;
-      break;
-    case kCondHi:  // Gtu
-      sltOp = kMipsSltu;
-      brOp = kMipsBnez;
-      swapped = true;
-      break;
-    default:
-      LOG(FATAL) << "No support for ConditionCode: " << (int) cond;
-      return NULL;
-  }
-  if (cmpZero) {
-    branch = newLIR2(cUnit, brOp, src1, src2);
-  } else {
-    int tReg = oatAllocTemp(cUnit);
-    if (swapped) {
-      newLIR3(cUnit, sltOp, tReg, src2, src1);
-    } else {
-      newLIR3(cUnit, sltOp, tReg, src1, src2);
-    }
-    branch = newLIR1(cUnit, brOp, tReg);
-    oatFreeTemp(cUnit, tReg);
-  }
-  branch->target = target;
-  return branch;
-}
-
-LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
-          int checkValue, LIR* target)
-{
-  LIR* branch;
-  if (checkValue != 0) {
-    // TUNING: handle s16 & kCondLt/Mi case using slti
-    int tReg = oatAllocTemp(cUnit);
-    loadConstant(cUnit, tReg, checkValue);
-    branch = opCmpBranch(cUnit, cond, reg, tReg, target);
-    oatFreeTemp(cUnit, tReg);
-    return branch;
-  }
-  MipsOpCode opc;
-  switch (cond) {
-    case kCondEq: opc = kMipsBeqz; break;
-    case kCondGe: opc = kMipsBgez; break;
-    case kCondGt: opc = kMipsBgtz; break;
-    case kCondLe: opc = kMipsBlez; break;
-    //case KCondMi:
-    case kCondLt: opc = kMipsBltz; break;
-    case kCondNe: opc = kMipsBnez; break;
-    default:
-      // Tuning: use slti when applicable
-      int tReg = oatAllocTemp(cUnit);
-      loadConstant(cUnit, tReg, checkValue);
-      branch = opCmpBranch(cUnit, cond, reg, tReg, target);
-      oatFreeTemp(cUnit, tReg);
-      return branch;
-  }
-  branch = newLIR1(cUnit, opc, reg);
-  branch->target = target;
-  return branch;
-}
-
-LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
-{
-#ifdef __mips_hard_float
-  if (MIPS_FPREG(rDest) || MIPS_FPREG(rSrc))
-    return fpRegCopy(cUnit, rDest, rSrc);
-#endif
-  LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove,
-            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)
-{
-#ifdef __mips_hard_float
-  bool destFP = MIPS_FPREG(destLo) && MIPS_FPREG(destHi);
-  bool srcFP = MIPS_FPREG(srcLo) && MIPS_FPREG(srcHi);
-  assert(MIPS_FPREG(srcLo) == MIPS_FPREG(srcHi));
-  assert(MIPS_FPREG(destLo) == MIPS_FPREG(destHi));
-  if (destFP) {
-    if (srcFP) {
-      opRegCopy(cUnit, s2d(destLo, destHi), s2d(srcLo, srcHi));
-    } else {
-       /* note the operands are swapped for the mtc1 instr */
-      newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
-      newLIR2(cUnit, kMipsMtc1, srcHi, destHi);
-    }
-  } else {
-    if (srcFP) {
-      newLIR2(cUnit, kMipsMfc1, destLo, srcLo);
-      newLIR2(cUnit, kMipsMfc1, destHi, srcHi);
-    } else {
-      // Handle overlap
-      if (srcHi == destLo) {
-        opRegCopy(cUnit, destHi, srcHi);
-        opRegCopy(cUnit, destLo, srcLo);
-      } else {
-        opRegCopy(cUnit, destLo, srcLo);
-        opRegCopy(cUnit, destHi, srcHi);
-      }
-    }
-  }
-#else
-  // Handle overlap
-  if (srcHi == destLo) {
-    opRegCopy(cUnit, destHi, srcHi);
-    opRegCopy(cUnit, destLo, srcLo);
-  } else {
-    opRegCopy(cUnit, destLo, srcLo);
-    opRegCopy(cUnit, destHi, srcHi);
-  }
-#endif
-}
-
-void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
-{
-  UNIMPLEMENTED(FATAL) << "Need codegen for fused long cmp branch";
-}
-
-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 genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int reg2, bool isDiv)
-{
-  newLIR4(cUnit, kMipsDiv, r_HI, r_LO, reg1, reg2);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  if (isDiv) {
-    newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
-  } else {
-    newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
-  }
-  return rlResult;
-}
-
-RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int lit, bool isDiv)
-{
-  int tReg = oatAllocTemp(cUnit);
-  newLIR3(cUnit, kMipsAddiu, tReg, r_ZERO, lit);
-  newLIR4(cUnit, kMipsDiv, r_HI, r_LO, reg1, tReg);
-  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  if (isDiv) {
-    newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
-  } else {
-    newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
-  }
-  oatFreeTemp(cUnit, tReg);
-  return rlResult;
-}
-
-/*
- * 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, rMIPS_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);
-}
-
-bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
-{
-  // TODO: need Mips implementation
-  return false;
-}
-
-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_NE(cUnit->instructionSet, kThumb2);
-  return false;
-}
-
-bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
-  DCHECK_NE(cUnit->instructionSet, kThumb2);
-  return false;
-}
-
-LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target) {
-  LOG(FATAL) << "Unexpected use of opPcRelLoad for Mips";
-  return NULL;
-}
-
-LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
-{
-  LOG(FATAL) << "Unexpected use of opVldm for Mips";
-  return NULL;
-}
-
-LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
-{
-  LOG(FATAL) << "Unexpected use of opVstm for Mips";
-  return NULL;
-}
-
-void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
-                                   RegLocation rlResult, int lit,
-                                   int firstBit, int secondBit)
-{
-  int tReg = oatAllocTemp(cUnit);
-  opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, secondBit - firstBit);
-  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, tReg);
-  oatFreeTemp(cUnit, tReg);
-  if (firstBit != 0) {
-    opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
-  }
-}
-
-void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
-{
-  int tReg = oatAllocTemp(cUnit);
-  opRegRegReg(cUnit, kOpOr, tReg, regLo, regHi);
-  genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
-  oatFreeTemp(cUnit, tReg);
-}
-
-// Test suspend flag, return target of taken suspend branch
-LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
-{
-  opRegImm(cUnit, kOpSub, rMIPS_SUSPEND, 1);
-  return opCmpImmBranch(cUnit, (target == NULL) ? kCondEq : kCondNe, rMIPS_SUSPEND, 0, target);
-}
-
-// Decrement register and branch on condition
-LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
-{
-  opRegImm(cUnit, kOpSub, reg, 1);
-  return opCmpImmBranch(cUnit, cCode, reg, 0, target);
-}
-
-bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
-                        RegLocation rlSrc, RegLocation rlDest, int lit)
-{
-  LOG(FATAL) << "Unexpected use of smallLiteralDive in Mips";
-  return false;
-}
-
-LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide)
-{
-  LOG(FATAL) << "Unexpected use of opIT in Mips";
-  return NULL;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/mips/Mips32/Ralloc.cc b/src/compiler/codegen/mips/Mips32/Ralloc.cc
deleted file mode 100644
index b913bfb..0000000
--- a/src/compiler/codegen/mips/Mips32/Ralloc.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace art {
-
-/* This file contains codegen for the Mips 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;
-
-#ifdef __mips_hard_float
-  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
-    lowReg = oatAllocTempDouble(cUnit);
-    highReg = lowReg + 1;
-    res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
-    return res;
-  }
-#endif
-
-  lowReg = oatAllocTemp(cUnit);
-  highReg = oatAllocTemp(cUnit);
-  res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
-  return res;
-}
-
-int oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass)
-{
-#ifdef __mips_hard_float
-  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
-{
-    return oatAllocTempFloat(cUnit);
-}
-#endif
-  return oatAllocTemp(cUnit);
-}
-
-void oatInitializeRegAlloc(CompilationUnit* cUnit)
-{
-  int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
-  int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
-  int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
-#ifdef __mips_hard_float
-  int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
-  int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
-#else
-  int numFPRegs = 0;
-  int numFPTemps = 0;
-#endif
-  RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
-                        kAllocRegAlloc);
-  cUnit->regPool = pool;
-  pool->numCoreRegs = numRegs;
-  pool->coreRegs = (RegisterInfo *)
-      oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
-             true, kAllocRegAlloc);
-  pool->numFPRegs = numFPRegs;
-  pool->FPRegs = (RegisterInfo *)
-      oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
-             kAllocRegAlloc);
-  oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
-  oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
-  // Keep special registers from being allocated
-  for (int i = 0; i < numReserved; i++) {
-    if (NO_SUSPEND && (reservedRegs[i] == rMIPS_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]);
-  }
-  // Construct the alias map.
-  cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
-                                    sizeof(cUnit->phiAliasMap[0]), false,
-                                    kAllocDFInfo);
-  for (int i = 0; i < cUnit->numSSARegs; i++) {
-    cUnit->phiAliasMap[i] = i;
-  }
-  for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
-    int defReg = phi->ssaRep->defs[0];
-    for (int i = 0; i < phi->ssaRep->numUses; i++) {
-       for (int j = 0; j < cUnit->numSSARegs; j++) {
-         if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
-           cUnit->phiAliasMap[j] = defReg;
-         }
-       }
-    }
-  }
-}
-
-void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
-           RegLocation rlFree)
-{
-  if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
-    (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
-    // No overlap, free both
-    oatFreeTemp(cUnit, rlFree.lowReg);
-    oatFreeTemp(cUnit, rlFree.highReg);
-  }
-}
-
-
-}  // namespace art
diff --git a/src/compiler/codegen/mips/MipsRallocUtil.cc b/src/compiler/codegen/mips/MipsRallocUtil.cc
deleted file mode 100644
index 4979ae0..0000000
--- a/src/compiler/codegen/mips/MipsRallocUtil.cc
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file contains Mips-specific register allocation support.
- */
-
-#include "../../CompilerUtility.h"
-#include "../../CompilerIR.h"
-#include "../..//Dataflow.h"
-#include "MipsLIR.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 << r_RA);
-  cUnit->numCoreSpills++;
-}
-
-/*
- * Mark a callee-save fp register as promoted.  Note that
- * vpush/vpop uses contiguous register lists so we must
- * include any holes in the mask.  Associate holes with
- * Dalvik register INVALID_VREG (0xFFFFU).
- */
-void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
-{
-  LOG(FATAL) << "No support yet for promoted FP regs";
-}
-
-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, rMIPS_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, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
-  }
-}
-
-/* Give access to the target-dependent FP register encoding to common code */
-bool oatIsFpReg(int reg) {
-  return MIPS_FPREG(reg);
-}
-
-uint32_t oatFpRegMask() {
-  return MIPS_FP_REG_MASK;
-}
-
-/* Clobber all regs that might be used by an external C call */
-extern void oatClobberCalleeSave(CompilationUnit *cUnit)
-{
-  oatClobber(cUnit, r_ZERO);
-  oatClobber(cUnit, r_AT);
-  oatClobber(cUnit, r_V0);
-  oatClobber(cUnit, r_V1);
-  oatClobber(cUnit, r_A0);
-  oatClobber(cUnit, r_A1);
-  oatClobber(cUnit, r_A2);
-  oatClobber(cUnit, r_A3);
-  oatClobber(cUnit, r_T0);
-  oatClobber(cUnit, r_T1);
-  oatClobber(cUnit, r_T2);
-  oatClobber(cUnit, r_T3);
-  oatClobber(cUnit, r_T4);
-  oatClobber(cUnit, r_T5);
-  oatClobber(cUnit, r_T6);
-  oatClobber(cUnit, r_T7);
-  oatClobber(cUnit, r_T8);
-  oatClobber(cUnit, r_T9);
-  oatClobber(cUnit, r_K0);
-  oatClobber(cUnit, r_K1);
-  oatClobber(cUnit, r_GP);
-  oatClobber(cUnit, r_FP);
-  oatClobber(cUnit, r_RA);
-  oatClobber(cUnit, r_F0);
-  oatClobber(cUnit, r_F1);
-  oatClobber(cUnit, r_F2);
-  oatClobber(cUnit, r_F3);
-  oatClobber(cUnit, r_F4);
-  oatClobber(cUnit, r_F5);
-  oatClobber(cUnit, r_F6);
-  oatClobber(cUnit, r_F7);
-  oatClobber(cUnit, r_F8);
-  oatClobber(cUnit, r_F9);
-  oatClobber(cUnit, r_F10);
-  oatClobber(cUnit, r_F11);
-  oatClobber(cUnit, r_F12);
-  oatClobber(cUnit, r_F13);
-  oatClobber(cUnit, r_F14);
-  oatClobber(cUnit, r_F15);
-}
-
-extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
-{
-  UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS";
-  RegLocation res = locCReturnWide();
-  return res;
-}
-
-extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
-{
-  UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS";
-  RegLocation res = locCReturn();
-  return res;
-}
-
-extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
-{
-  return MIPS_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & MIPS_FP_REG_MASK]
-            : &cUnit->regPool->coreRegs[reg];
-}
-
-/* To be used when explicitly managing register use */
-extern void oatLockCallTemps(CompilationUnit* cUnit)
-{
-  oatLockTemp(cUnit, rMIPS_ARG0);
-  oatLockTemp(cUnit, rMIPS_ARG1);
-  oatLockTemp(cUnit, rMIPS_ARG2);
-  oatLockTemp(cUnit, rMIPS_ARG3);
-}
-
-/* To be used when explicitly managing register use */
-extern void oatFreeCallTemps(CompilationUnit* cUnit)
-{
-  oatFreeTemp(cUnit, rMIPS_ARG0);
-  oatFreeTemp(cUnit, rMIPS_ARG1);
-  oatFreeTemp(cUnit, rMIPS_ARG2);
-  oatFreeTemp(cUnit, rMIPS_ARG3);
-}
-
-/* Convert an instruction to a NOP */
-void oatNopLIR( LIR* lir)
-{
-  ((LIR*)lir)->flags.isNop = true;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/mips/Assemble.cc b/src/compiler/codegen/mips/assemble_mips.cc
similarity index 99%
rename from src/compiler/codegen/mips/Assemble.cc
rename to src/compiler/codegen/mips/assemble_mips.cc
index e9dd219..ab7a677 100644
--- a/src/compiler/codegen/mips/Assemble.cc
+++ b/src/compiler/codegen/mips/assemble_mips.cc
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
-#include "MipsLIR.h"
-#include "Codegen.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "mips_lir.h"
+#include "codegen.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/mips/backend_mips.cc b/src/compiler/codegen/mips/backend_mips.cc
new file mode 100644
index 0000000..023d613
--- /dev/null
+++ b/src/compiler/codegen/mips/backend_mips.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _CODEGEN_C
+
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "mips_lir.h"
+#include "../ralloc.h"
+#include "codegen.h"
+
+/* Common codegen building blocks */
+#include "../codegen_util.cc"
+
+#include "utility_mips.cc"
+#include "../codegen_factory.cc"
+#include "../gen_common.cc"
+#include "../gen_invoke.cc"
+#include "call_mips.cc"
+#include "fp_mips.cc"
+#include "int_mips.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/mips/call_mips.cc b/src/compiler/codegen/mips/call_mips.cc
new file mode 100644
index 0000000..50cb594
--- /dev/null
+++ b/src/compiler/codegen/mips/call_mips.cc
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file contains codegen for the Mips ISA */
+
+#include "oat/runtime/oat_support_entrypoints.h"
+
+namespace art {
+
+void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+                    SpecialCaseHandler specialCase)
+{
+    // TODO
+}
+
+/*
+ * The lack of pc-relative loads on Mips presents somewhat of a challenge
+ * for our PIC switch table strategy.  To materialize the current location
+ * we'll do a dummy JAL and reference our tables using r_RA as the
+ * base register.  Note that r_RA will be used both as the base to
+ * locate the switch table data and as the reference base for the switch
+ * target offsets stored in the table.  We'll use a special pseudo-instruction
+ * to represent the jal and trigger the construction of the
+ * switch table offsets (which will happen after final assembly and all
+ * labels are fixed).
+ *
+ * The test loop will look something like:
+ *
+ *   ori   rEnd, r_ZERO, #tableSize  ; size in bytes
+ *   jal   BaseLabel         ; stores "return address" (BaseLabel) in r_RA
+ *   nop                     ; opportunistically fill
+ * BaseLabel:
+ *   addiu rBase, r_RA, <table> - <BaseLabel>  ; table relative to BaseLabel
+     addu  rEnd, rEnd, rBase                   ; end of table
+ *   lw    rVal, [rSP, vRegOff]                ; Test Value
+ * loop:
+ *   beq   rBase, rEnd, done
+ *   lw    rKey, 0(rBase)
+ *   addu  rBase, 8
+ *   bne   rVal, rKey, loop
+ *   lw    rDisp, -4(rBase)
+ *   addu  r_RA, rDisp
+ *   jr    r_RA
+ * done:
+ *
+ */
+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 elements = table[1];
+  tabRec->targets = (LIR* *)oatNew(cUnit, elements * sizeof(LIR*), true,
+                                   kAllocLIR);
+  oatInsertGrowableList(cUnit, &cUnit->switchTables, (intptr_t)tabRec);
+
+  // The table is composed of 8-byte key/disp pairs
+  int byteSize = elements * 8;
+
+  int sizeHi = byteSize >> 16;
+  int sizeLo = byteSize & 0xffff;
+
+  int rEnd = oatAllocTemp(cUnit);
+  if (sizeHi) {
+    newLIR2(cUnit, kMipsLui, rEnd, sizeHi);
+  }
+  // Must prevent code motion for the curr pc pair
+  genBarrier(cUnit);  // Scheduling barrier
+  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
+  // Now, fill the branch delay slot
+  if (sizeHi) {
+    newLIR3(cUnit, kMipsOri, rEnd, rEnd, sizeLo);
+  } else {
+    newLIR3(cUnit, kMipsOri, rEnd, r_ZERO, sizeLo);
+  }
+  genBarrier(cUnit);  // Scheduling barrier
+
+  // Construct BaseLabel and set up table base register
+  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
+  // Remember base label so offsets can be computed later
+  tabRec->anchor = baseLabel;
+  int rBase = oatAllocTemp(cUnit);
+  newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
+  opRegRegReg(cUnit, kOpAdd, rEnd, rEnd, rBase);
+
+  // Grab switch test value
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+
+  // Test loop
+  int rKey = oatAllocTemp(cUnit);
+  LIR* loopLabel = newLIR0(cUnit, kPseudoTargetLabel);
+  LIR* exitBranch = opCmpBranch(cUnit , kCondEq, rBase, rEnd, NULL);
+  loadWordDisp(cUnit, rBase, 0, rKey);
+  opRegImm(cUnit, kOpAdd, rBase, 8);
+  opCmpBranch(cUnit, kCondNe, rlSrc.lowReg, rKey, loopLabel);
+  int rDisp = oatAllocTemp(cUnit);
+  loadWordDisp(cUnit, rBase, -4, rDisp);
+  opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp);
+  opReg(cUnit, kOpBx, r_RA);
+
+  // Loop exit
+  LIR* exitLabel = newLIR0(cUnit, kPseudoTargetLabel);
+  exitBranch->target = exitLabel;
+}
+
+/*
+ * Code pattern will look something like:
+ *
+ *   lw    rVal
+ *   jal   BaseLabel         ; stores "return address" (BaseLabel) in r_RA
+ *   nop                     ; opportunistically fill
+ *   [subiu rVal, bias]      ; Remove bias if lowVal != 0
+ *   bound check -> done
+ *   lw    rDisp, [r_RA, rVal]
+ *   addu  r_RA, rDisp
+ *   jr    r_RA
+ * done:
+ */
+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);
+
+  // Prepare the bias.  If too big, handle 1st stage here
+  int lowKey = s4FromSwitchData(&table[2]);
+  bool largeBias = false;
+  int rKey;
+  if (lowKey == 0) {
+    rKey = rlSrc.lowReg;
+  } else if ((lowKey & 0xffff) != lowKey) {
+    rKey = oatAllocTemp(cUnit);
+    loadConstant(cUnit, rKey, lowKey);
+    largeBias = true;
+  } else {
+    rKey = oatAllocTemp(cUnit);
+  }
+
+  // Must prevent code motion for the curr pc pair
+  genBarrier(cUnit);
+  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
+  // Now, fill the branch delay slot with bias strip
+  if (lowKey == 0) {
+    newLIR0(cUnit, kMipsNop);
+  } else {
+    if (largeBias) {
+      opRegRegReg(cUnit, kOpSub, rKey, rlSrc.lowReg, rKey);
+    } else {
+      opRegRegImm(cUnit, kOpSub, rKey, rlSrc.lowReg, lowKey);
+    }
+  }
+  genBarrier(cUnit);  // Scheduling barrier
+
+  // Construct BaseLabel and set up table base register
+  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
+  // Remember base label so offsets can be computed later
+  tabRec->anchor = baseLabel;
+
+  // Bounds check - if < 0 or >= size continue following switch
+  LIR* branchOver = opCmpImmBranch(cUnit, kCondHi, rKey, size-1, NULL);
+
+  // Materialize the table base pointer
+  int rBase = oatAllocTemp(cUnit);
+  newLIR4(cUnit, kMipsDelta, rBase, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
+
+  // Load the displacement from the switch table
+  int rDisp = oatAllocTemp(cUnit);
+  loadBaseIndexed(cUnit, rBase, rKey, rDisp, 2, kWord);
+
+  // Add to r_AP and go
+  opRegRegReg(cUnit, kOpAdd, r_RA, r_RA, rDisp);
+  opReg(cUnit, kOpBx, r_RA);
+
+  /* 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 */
+  oatLockCallTemps(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);
+
+  // Must prevent code motion for the curr pc pair
+  genBarrier(cUnit);
+  newLIR0(cUnit, kMipsCurrPC);  // Really a jal to .+8
+  // Now, fill the branch delay slot with the helper load
+  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode));
+  genBarrier(cUnit);  // Scheduling barrier
+
+  // Construct BaseLabel and set up table base register
+  LIR* baseLabel = newLIR0(cUnit, kPseudoTargetLabel);
+
+  // Materialize a pointer to the fill data image
+  newLIR4(cUnit, kMipsDelta, rMIPS_ARG1, 0, (intptr_t)baseLabel, (intptr_t)tabRec);
+
+  // And go...
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rTgt); // ( array*, fill_data* )
+  markSafepointPC(cUnit, callInst);
+}
+
+/*
+ * TODO: implement fast path to short-circuit thin-lock case
+ */
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, rMIPS_ARG0, optFlags);
+  // Go expensive route - artLockObjectFromCode(self, obj);
+  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode));
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rTgt);
+  markSafepointPC(cUnit, callInst);
+}
+
+/*
+ * TODO: implement fast path to short-circuit thin-lock case
+ */
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, rMIPS_ARG0);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, rMIPS_ARG0, optFlags);
+  // Go expensive route - UnlockObjectFromCode(obj);
+  int rTgt = loadHelper(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode));
+  oatClobberCalleeSave(cUnit);
+  LIR* callInst = opReg(cUnit, kOpBlx, rTgt);
+  markSafepointPC(cUnit, callInst);
+}
+
+/*
+ * 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, rMIPS_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, rMIPS_ARG0, rMIPS_ARG1, rMIPS_ARG2 & rMIPS_ARG3 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, rMIPS_ARG0);
+  oatLockTemp(cUnit, rMIPS_ARG1);
+  oatLockTemp(cUnit, rMIPS_ARG2);
+  oatLockTemp(cUnit, rMIPS_ARG3);
+
+  /*
+   * 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);
+  int checkReg = oatAllocTemp(cUnit);
+  int newSP = oatAllocTemp(cUnit);
+  if (!skipOverflowCheck) {
+    /* Load stack limit */
+    loadWordDisp(cUnit, rMIPS_SELF, Thread::StackEndOffset().Int32Value(), checkReg);
+  }
+  /* Spill core callee saves */
+  spillCoreRegs(cUnit);
+  /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
+  DCHECK_EQ(cUnit->numFPSpills, 0);
+  if (!skipOverflowCheck) {
+    opRegRegImm(cUnit, kOpSub, newSP, rMIPS_SP, cUnit->frameSize - (spillCount * 4));
+    genRegRegCheck(cUnit, kCondCc, newSP, checkReg, kThrowStackOverflow);
+    opRegCopy(cUnit, rMIPS_SP, newSP);     // Establish stack
+  } else {
+    opRegImm(cUnit, kOpSub, rMIPS_SP, cUnit->frameSize - (spillCount * 4));
+  }
+
+  flushIns(cUnit, argLocs, rlMethod);
+
+  oatFreeTemp(cUnit, rMIPS_ARG0);
+  oatFreeTemp(cUnit, rMIPS_ARG1);
+  oatFreeTemp(cUnit, rMIPS_ARG2);
+  oatFreeTemp(cUnit, rMIPS_ARG3);
+}
+
+void genExitSequence(CompilationUnit* cUnit)
+{
+  /*
+   * In the exit path, rMIPS_RET0/rMIPS_RET1 are live - make sure they aren't
+   * allocated by the register utilities as temps.
+   */
+  oatLockTemp(cUnit, rMIPS_RET0);
+  oatLockTemp(cUnit, rMIPS_RET1);
+
+  newLIR0(cUnit, kPseudoMethodExit);
+  unSpillCoreRegs(cUnit);
+  opReg(cUnit, kOpBx, r_RA);
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/mips/Codegen.h b/src/compiler/codegen/mips/codegen.h
similarity index 99%
rename from src/compiler/codegen/mips/Codegen.h
rename to src/compiler/codegen/mips/codegen.h
index 03efe03..0b3a01e 100644
--- a/src/compiler/codegen/mips/Codegen.h
+++ b/src/compiler/codegen/mips/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/mips/FP/MipsFP.cc b/src/compiler/codegen/mips/fp_mips.cc
similarity index 88%
rename from src/compiler/codegen/mips/FP/MipsFP.cc
rename to src/compiler/codegen/mips/fp_mips.cc
index fb6c8df..04056ad 100644
--- a/src/compiler/codegen/mips/FP/MipsFP.cc
+++ b/src/compiler/codegen/mips/fp_mips.cc
@@ -217,4 +217,29 @@
   UNIMPLEMENTED(FATAL) << "Need codegen for fused fp cmp branch";
 }
 
+void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, 0x80000000);
+  storeValue(cUnit, rlDest, rlResult);
+}
+
+void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 0x80000000);
+  opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+}
+
+bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
+{
+  // TODO: need Mips implementation
+  return false;
+}
+
 } //  namespace art
diff --git a/src/compiler/codegen/mips/int_mips.cc b/src/compiler/codegen/mips/int_mips.cc
new file mode 100644
index 0000000..0e1ae62
--- /dev/null
+++ b/src/compiler/codegen/mips/int_mips.cc
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file contains codegen for the Mips ISA */
+
+#include "oat/runtime/oat_support_entrypoints.h"
+
+namespace art {
+
+/*
+ * Compare two 64-bit values
+ *    x = y     return  0
+ *    x < y     return -1
+ *    x > y     return  1
+ *
+ *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
+ *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
+ *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
+ *    bnez  res, finish
+ *    sltu  t0, x.lo, y.lo
+ *    sgtu  r1, x.lo, y.lo
+ *    subu  res, t0, t1
+ * finish:
+ *
+ */
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
+        RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+  int t0 = oatAllocTemp(cUnit);
+  int t1 = oatAllocTemp(cUnit);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  newLIR3(cUnit, kMipsSlt, t0, rlSrc1.highReg, rlSrc2.highReg);
+  newLIR3(cUnit, kMipsSlt, t1, rlSrc2.highReg, rlSrc1.highReg);
+  newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
+  LIR* branch = opCmpImmBranch(cUnit, kCondNe, rlResult.lowReg, 0, NULL);
+  newLIR3(cUnit, kMipsSltu, t0, rlSrc1.lowReg, rlSrc2.lowReg);
+  newLIR3(cUnit, kMipsSltu, t1, rlSrc2.lowReg, rlSrc1.lowReg);
+  newLIR3(cUnit, kMipsSubu, rlResult.lowReg, t1, t0);
+  oatFreeTemp(cUnit, t0);
+  oatFreeTemp(cUnit, t1);
+  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+  branch->target = (LIR*)target;
+  storeValue(cUnit, rlDest, rlResult);
+}
+
+LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+         int src2, LIR* target)
+{
+  LIR* branch;
+  MipsOpCode sltOp;
+  MipsOpCode brOp;
+  bool cmpZero = false;
+  bool swapped = false;
+  switch (cond) {
+    case kCondEq:
+      brOp = kMipsBeq;
+      cmpZero = true;
+      break;
+    case kCondNe:
+      brOp = kMipsBne;
+      cmpZero = true;
+      break;
+    case kCondCc:
+      sltOp = kMipsSltu;
+      brOp = kMipsBnez;
+      break;
+    case kCondCs:
+      sltOp = kMipsSltu;
+      brOp = kMipsBeqz;
+      break;
+    case kCondGe:
+      sltOp = kMipsSlt;
+      brOp = kMipsBeqz;
+      break;
+    case kCondGt:
+      sltOp = kMipsSlt;
+      brOp = kMipsBnez;
+      swapped = true;
+      break;
+    case kCondLe:
+      sltOp = kMipsSlt;
+      brOp = kMipsBeqz;
+      swapped = true;
+      break;
+    case kCondLt:
+      sltOp = kMipsSlt;
+      brOp = kMipsBnez;
+      break;
+    case kCondHi:  // Gtu
+      sltOp = kMipsSltu;
+      brOp = kMipsBnez;
+      swapped = true;
+      break;
+    default:
+      LOG(FATAL) << "No support for ConditionCode: " << (int) cond;
+      return NULL;
+  }
+  if (cmpZero) {
+    branch = newLIR2(cUnit, brOp, src1, src2);
+  } else {
+    int tReg = oatAllocTemp(cUnit);
+    if (swapped) {
+      newLIR3(cUnit, sltOp, tReg, src2, src1);
+    } else {
+      newLIR3(cUnit, sltOp, tReg, src1, src2);
+    }
+    branch = newLIR1(cUnit, brOp, tReg);
+    oatFreeTemp(cUnit, tReg);
+  }
+  branch->target = target;
+  return branch;
+}
+
+LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+          int checkValue, LIR* target)
+{
+  LIR* branch;
+  if (checkValue != 0) {
+    // TUNING: handle s16 & kCondLt/Mi case using slti
+    int tReg = oatAllocTemp(cUnit);
+    loadConstant(cUnit, tReg, checkValue);
+    branch = opCmpBranch(cUnit, cond, reg, tReg, target);
+    oatFreeTemp(cUnit, tReg);
+    return branch;
+  }
+  MipsOpCode opc;
+  switch (cond) {
+    case kCondEq: opc = kMipsBeqz; break;
+    case kCondGe: opc = kMipsBgez; break;
+    case kCondGt: opc = kMipsBgtz; break;
+    case kCondLe: opc = kMipsBlez; break;
+    //case KCondMi:
+    case kCondLt: opc = kMipsBltz; break;
+    case kCondNe: opc = kMipsBnez; break;
+    default:
+      // Tuning: use slti when applicable
+      int tReg = oatAllocTemp(cUnit);
+      loadConstant(cUnit, tReg, checkValue);
+      branch = opCmpBranch(cUnit, cond, reg, tReg, target);
+      oatFreeTemp(cUnit, tReg);
+      return branch;
+  }
+  branch = newLIR1(cUnit, opc, reg);
+  branch->target = target;
+  return branch;
+}
+
+LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
+{
+#ifdef __mips_hard_float
+  if (MIPS_FPREG(rDest) || MIPS_FPREG(rSrc))
+    return fpRegCopy(cUnit, rDest, rSrc);
+#endif
+  LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kMipsMove,
+            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)
+{
+#ifdef __mips_hard_float
+  bool destFP = MIPS_FPREG(destLo) && MIPS_FPREG(destHi);
+  bool srcFP = MIPS_FPREG(srcLo) && MIPS_FPREG(srcHi);
+  assert(MIPS_FPREG(srcLo) == MIPS_FPREG(srcHi));
+  assert(MIPS_FPREG(destLo) == MIPS_FPREG(destHi));
+  if (destFP) {
+    if (srcFP) {
+      opRegCopy(cUnit, s2d(destLo, destHi), s2d(srcLo, srcHi));
+    } else {
+       /* note the operands are swapped for the mtc1 instr */
+      newLIR2(cUnit, kMipsMtc1, srcLo, destLo);
+      newLIR2(cUnit, kMipsMtc1, srcHi, destHi);
+    }
+  } else {
+    if (srcFP) {
+      newLIR2(cUnit, kMipsMfc1, destLo, srcLo);
+      newLIR2(cUnit, kMipsMfc1, destHi, srcHi);
+    } else {
+      // Handle overlap
+      if (srcHi == destLo) {
+        opRegCopy(cUnit, destHi, srcHi);
+        opRegCopy(cUnit, destLo, srcLo);
+      } else {
+        opRegCopy(cUnit, destLo, srcLo);
+        opRegCopy(cUnit, destHi, srcHi);
+      }
+    }
+  }
+#else
+  // Handle overlap
+  if (srcHi == destLo) {
+    opRegCopy(cUnit, destHi, srcHi);
+    opRegCopy(cUnit, destLo, srcLo);
+  } else {
+    opRegCopy(cUnit, destLo, srcLo);
+    opRegCopy(cUnit, destHi, srcHi);
+  }
+#endif
+}
+
+void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir)
+{
+  UNIMPLEMENTED(FATAL) << "Need codegen for fused long cmp branch";
+}
+
+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 genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int reg2, bool isDiv)
+{
+  newLIR4(cUnit, kMipsDiv, r_HI, r_LO, reg1, reg2);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  if (isDiv) {
+    newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
+  } else {
+    newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
+  }
+  return rlResult;
+}
+
+RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int reg1, int lit, bool isDiv)
+{
+  int tReg = oatAllocTemp(cUnit);
+  newLIR3(cUnit, kMipsAddiu, tReg, r_ZERO, lit);
+  newLIR4(cUnit, kMipsDiv, r_HI, r_LO, reg1, tReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  if (isDiv) {
+    newLIR2(cUnit, kMipsMflo, rlResult.lowReg, r_LO);
+  } else {
+    newLIR2(cUnit, kMipsMfhi, rlResult.lowReg, r_HI);
+  }
+  oatFreeTemp(cUnit, tReg);
+  return rlResult;
+}
+
+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_NE(cUnit->instructionSet, kThumb2);
+  return false;
+}
+
+bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
+  DCHECK_NE(cUnit->instructionSet, kThumb2);
+  return false;
+}
+
+LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target) {
+  LOG(FATAL) << "Unexpected use of opPcRelLoad for Mips";
+  return NULL;
+}
+
+LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
+{
+  LOG(FATAL) << "Unexpected use of opVldm for Mips";
+  return NULL;
+}
+
+LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
+{
+  LOG(FATAL) << "Unexpected use of opVstm for Mips";
+  return NULL;
+}
+
+void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
+                                   RegLocation rlResult, int lit,
+                                   int firstBit, int secondBit)
+{
+  int tReg = oatAllocTemp(cUnit);
+  opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, secondBit - firstBit);
+  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, tReg);
+  oatFreeTemp(cUnit, tReg);
+  if (firstBit != 0) {
+    opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
+  }
+}
+
+void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
+{
+  int tReg = oatAllocTemp(cUnit);
+  opRegRegReg(cUnit, kOpOr, tReg, regLo, regHi);
+  genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
+  oatFreeTemp(cUnit, tReg);
+}
+
+// Test suspend flag, return target of taken suspend branch
+LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
+{
+  opRegImm(cUnit, kOpSub, rMIPS_SUSPEND, 1);
+  return opCmpImmBranch(cUnit, (target == NULL) ? kCondEq : kCondNe, rMIPS_SUSPEND, 0, target);
+}
+
+// Decrement register and branch on condition
+LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
+{
+  opRegImm(cUnit, kOpSub, reg, 1);
+  return opCmpImmBranch(cUnit, cCode, reg, 0, target);
+}
+
+bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
+                        RegLocation rlSrc, RegLocation rlDest, int lit)
+{
+  LOG(FATAL) << "Unexpected use of smallLiteralDive in Mips";
+  return false;
+}
+
+LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide)
+{
+  LOG(FATAL) << "Unexpected use of opIT in Mips";
+  return NULL;
+}
+
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  /*
+   *  [v1 v0] =  [a1 a0] + [a3 a2];
+   *  addu v0,a2,a0
+   *  addu t1,a3,a1
+   *  sltu v1,v0,a2
+   *  addu v1,v1,t1
+   */
+
+  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc2.lowReg, rlSrc1.lowReg);
+  int tReg = oatAllocTemp(cUnit);
+  opRegRegReg(cUnit, kOpAdd, tReg, rlSrc2.highReg, rlSrc1.highReg);
+  newLIR3(cUnit, kMipsSltu, rlResult.highReg, rlResult.lowReg, rlSrc2.lowReg);
+  opRegRegReg(cUnit, kOpAdd, rlResult.highReg, rlResult.highReg, tReg);
+  oatFreeTemp(cUnit, tReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
+        RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  rlSrc1 = loadValueWide(cUnit, rlSrc1, kCoreReg);
+  rlSrc2 = loadValueWide(cUnit, rlSrc2, kCoreReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  /*
+   *  [v1 v0] =  [a1 a0] - [a3 a2];
+   *  sltu  t1,a0,a2
+   *  subu  v0,a0,a2
+   *  subu  v1,a1,a3
+   *  subu  v1,v1,t1
+   */
+
+  int tReg = oatAllocTemp(cUnit);
+  newLIR3(cUnit, kMipsSltu, tReg, rlSrc1.lowReg, rlSrc2.lowReg);
+  opRegRegReg(cUnit, kOpSub, rlResult.lowReg, rlSrc1.lowReg, rlSrc2.lowReg);
+  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlSrc1.highReg, rlSrc2.highReg);
+  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
+  oatFreeTemp(cUnit, tReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc)
+{
+  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+  RegLocation rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  /*
+   *  [v1 v0] =  -[a1 a0]
+   *  negu  v0,a0
+   *  negu  v1,a1
+   *  sltu  t1,r_zero
+   *  subu  v1,v1,t1
+   */
+
+  opRegReg(cUnit, kOpNeg, rlResult.lowReg, rlSrc.lowReg);
+  opRegReg(cUnit, kOpNeg, rlResult.highReg, rlSrc.highReg);
+  int tReg = oatAllocTemp(cUnit);
+  newLIR3(cUnit, kMipsSltu, tReg, r_ZERO, rlResult.lowReg);
+  opRegRegReg(cUnit, kOpSub, rlResult.highReg, rlResult.highReg, tReg);
+  oatFreeTemp(cUnit, tReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genAndLong for Mips";
+  return false;
+}
+
+bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
+               RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genOrLong for Mips";
+  return false;
+}
+
+bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
+               RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  LOG(FATAL) << "Unexpected use of genXorLong for Mips";
+  return false;
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/mips/mips/ArchVariant.cc b/src/compiler/codegen/mips/mips/ArchVariant.cc
deleted file mode 100644
index 3018ffe..0000000
--- a/src/compiler/codegen/mips/mips/ArchVariant.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace art {
-
-/*
- * This file is included by Codegen-mips.c, and implements architecture
- * variant-specific code.
- */
-
-/*
- * Determine the initial instruction set to be used for this trace.
- * Later components may decide to change this.
- */
-InstructionSet oatInstructionSet()
-{
-  return kMips;
-}
-
-/* Architecture-specific initializations and checks go here */
-bool oatArchVariantInit(void)
-{
-  return true;
-}
-
-int dvmCompilerTargetOptHint(int key)
-{
-  int res;
-  switch (key) {
-    case kMaxHoistDistance:
-      res = 2;
-      break;
-    default:
-      LOG(FATAL) << "Unknown target optimization hint key: " << key;
-  }
-  return res;
-}
-
-void oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
-{
-#if ANDROID_SMP != 0
-  newLIR1(cUnit, kMipsSync, barrierKind);
-#endif
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/mips/mips/Codegen.cc b/src/compiler/codegen/mips/mips/Codegen.cc
deleted file mode 100644
index 0c726d3..0000000
--- a/src/compiler/codegen/mips/mips/Codegen.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _CODEGEN_C
-
-#include "../../../Dalvik.h"
-#include "../../../CompilerInternals.h"
-#include "../MipsLIR.h"
-#include "../../Ralloc.h"
-#include "../Codegen.h"
-
-/* Mips codegen building blocks */
-#include "../../CodegenUtil.cc"
-
-/* Mips-specific factory utilities */
-#include "../Mips32/Factory.cc"
-/* Target independent factory utilities */
-#include "../../CodegenFactory.cc"
-/* Target independent gen routines */
-#include "../../GenCommon.cc"
-/* Shared invoke gen routines */
-#include "../../GenInvoke.cc"
-/* Mips-specific factory utilities */
-#include "../ArchFactory.cc"
-
-/* Mips32-specific codegen routines */
-#include "../Mips32/Gen.cc"
-/* FP codegen routines */
-#include "../FP/MipsFP.cc"
-
-/* Mips32-specific register allocation */
-#include "../Mips32/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/mips/MipsLIR.h b/src/compiler/codegen/mips/mips_lir.h
similarity index 99%
rename from src/compiler/codegen/mips/MipsLIR.h
rename to src/compiler/codegen/mips/mips_lir.h
index c0fde46..03dd714 100644
--- a/src/compiler/codegen/mips/MipsLIR.h
+++ b/src/compiler/codegen/mips/mips_lir.h
@@ -17,8 +17,8 @@
 #ifndef ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
 #define ART_COMPILER_COMPILER_CODEGEN_MIPS_MIPSLIR_H_
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/mips/target_mips.cc b/src/compiler/codegen/mips/target_mips.cc
new file mode 100644
index 0000000..f32f6c2
--- /dev/null
+++ b/src/compiler/codegen/mips/target_mips.cc
@@ -0,0 +1,719 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../compiler_internals.h"
+#include "mips_lir.h"
+#include "../ralloc.h"
+
+#include <string>
+
+namespace art {
+
+static int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
+                         r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
+                         r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
+                         r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
+static int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
+                             r_RA};
+static int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
+                          r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
+#ifdef __mips_hard_float
+static int fpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
+                       r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
+static int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
+                        r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
+#endif
+
+RegLocation locCReturn()
+{
+  RegLocation res = MIPS_LOC_C_RETURN;
+  return res;
+}
+
+RegLocation locCReturnWide()
+{
+  RegLocation res = MIPS_LOC_C_RETURN_WIDE;
+  return res;
+}
+
+RegLocation locCReturnFloat()
+{
+  RegLocation res = MIPS_LOC_C_RETURN_FLOAT;
+  return res;
+}
+
+RegLocation locCReturnDouble()
+{
+  RegLocation res = MIPS_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 = rMIPS_SELF; break;
+    case kSuspend: res =  rMIPS_SUSPEND; break;
+    case kLr: res =  rMIPS_LR; break;
+    case kPc: res =  rMIPS_PC; break;
+    case kSp: res =  rMIPS_SP; break;
+    case kArg0: res = rMIPS_ARG0; break;
+    case kArg1: res = rMIPS_ARG1; break;
+    case kArg2: res = rMIPS_ARG2; break;
+    case kArg3: res = rMIPS_ARG3; break;
+    case kFArg0: res = rMIPS_FARG0; break;
+    case kFArg1: res = rMIPS_FARG1; break;
+    case kFArg2: res = rMIPS_FARG2; break;
+    case kFArg3: res = rMIPS_FARG3; break;
+    case kRet0: res = rMIPS_RET0; break;
+    case kRet1: res = rMIPS_RET1; break;
+    case kInvokeTgt: res = rMIPS_INVOKE_TGT; break;
+    case kCount: res = rMIPS_COUNT; break;
+  }
+  return res;
+}
+
+// Create a double from a pair of singles.
+int s2d(int lowReg, int highReg)
+{
+  return MIPS_S2D(lowReg, highReg);
+}
+
+// Is reg a single or double?
+bool fpReg(int reg)
+{
+  return MIPS_FPREG(reg);
+}
+
+// Is reg a single?
+bool singleReg(int reg)
+{
+  return MIPS_SINGLEREG(reg);
+}
+
+// Is reg a double?
+bool doubleReg(int reg)
+{
+  return MIPS_DOUBLEREG(reg);
+}
+
+// Return mask to strip off fp reg flags and bias.
+uint32_t fpRegMask()
+{
+  return MIPS_FP_REG_MASK;
+}
+
+// True if both regs single, both core or both double.
+bool sameRegType(int reg1, int reg2)
+{
+  return (MIPS_REGTYPE(reg1) == MIPS_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 = MIPS_DOUBLEREG(reg) ? 3 : 1;
+  /* FP register starts at bit position 16 */
+  shift = MIPS_FPREG(reg) ? kMipsFPReg0 : 0;
+  /* Expand the double register id into single offset */
+  shift += regId;
+  return (seed << shift);
+}
+
+uint64_t getPCUseDefEncoding()
+{
+  return ENCODE_MIPS_REG_PC;
+}
+
+
+void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
+{
+  DCHECK_EQ(cUnit->instructionSet, kMips);
+
+  // Mips-specific resource map setup here.
+  uint64_t flags = EncodingMap[lir->opcode].flags;
+
+  if (flags & REG_DEF_SP) {
+    lir->defMask |= ENCODE_MIPS_REG_SP;
+  }
+
+  if (flags & REG_USE_SP) {
+    lir->useMask |= ENCODE_MIPS_REG_SP;
+  }
+
+  if (flags & REG_DEF_LR) {
+    lir->defMask |= ENCODE_MIPS_REG_LR;
+  }
+}
+
+/* For dumping instructions */
+#define MIPS_REG_COUNT 32
+static const char *mipsRegName[MIPS_REG_COUNT] = {
+  "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
+  "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
+  "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
+  "t8", "t9", "k0", "k1", "gp", "sp", "fp", "ra"
+};
+
+/*
+ * 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];
+  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 'b':
+             strcpy(tbuf,"0000");
+             for (i=3; i>= 0; i--) {
+               tbuf[i] += operand & 1;
+               operand >>= 1;
+             }
+             break;
+           case 's':
+             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
+             break;
+           case 'S':
+             DCHECK_EQ(((operand & MIPS_FP_REG_MASK) & 1), 0);
+             sprintf(tbuf,"$f%d",operand & MIPS_FP_REG_MASK);
+             break;
+           case 'h':
+             sprintf(tbuf,"%04x", operand);
+             break;
+           case 'M':
+           case 'd':
+             sprintf(tbuf,"%d", operand);
+             break;
+           case 'D':
+             sprintf(tbuf,"%d", operand+1);
+             break;
+           case 'E':
+             sprintf(tbuf,"%d", operand*4);
+             break;
+           case 'F':
+             sprintf(tbuf,"%d", operand*2);
+             break;
+           case 't':
+             sprintf(tbuf,"0x%08x (L%p)", (int) baseAddr + lir->offset + 4 +
+                     (operand << 2), lir->target);
+             break;
+           case 'T':
+             sprintf(tbuf,"0x%08x", (int) (operand << 2));
+             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':
+             DCHECK(operand >= 0 && operand < MIPS_REG_COUNT);
+             strcpy(tbuf, mipsRegName[operand]);
+             break;
+           case 'N':
+             // Placeholder for delay slot handling
+             strcpy(tbuf, ";  nop");
+             break;
+           default:
+             strcpy(tbuf,"DecodeError");
+             break;
+         }
+         buf += tbuf;
+      }
+    } else {
+       buf += *fmt++;
+    }
+  }
+  return buf;
+}
+
+// FIXME: need to redo resource maps for MIPS - fix this at that time
+void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
+{
+  char buf[256];
+  buf[0] = 0;
+  LIR *mipsLIR = (LIR *) lir;
+
+  if (mask == ENCODE_ALL) {
+    strcpy(buf, "all");
+  } else {
+    char num[8];
+    int i;
+
+    for (i = 0; i < kMipsRegEnd; 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 (mipsLIR && (mask & ENCODE_DALVIK_REG)) {
+      sprintf(buf + strlen(buf), "dr%d%s", mipsLIR->aliasInfo & 0xffff,
+              (mipsLIR->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;
+  }
+}
+
+/*
+ * TUNING: is leaf?  Can't just use "hasInvoke" to determine as some
+ * instructions might call out to C/assembly helper functions.  Until
+ * machinery is in place, always spill lr.
+ */
+
+void oatAdjustSpillMask(CompilationUnit* cUnit)
+{
+  cUnit->coreSpillMask |= (1 << r_RA);
+  cUnit->numCoreSpills++;
+}
+
+/*
+ * Mark a callee-save fp register as promoted.  Note that
+ * vpush/vpop uses contiguous register lists so we must
+ * include any holes in the mask.  Associate holes with
+ * Dalvik register INVALID_VREG (0xFFFFU).
+ */
+void oatMarkPreservedSingle(CompilationUnit* cUnit, int sReg, int reg)
+{
+  LOG(FATAL) << "No support yet for promoted FP regs";
+}
+
+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, rMIPS_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, rMIPS_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
+  }
+}
+
+/* Give access to the target-dependent FP register encoding to common code */
+bool oatIsFpReg(int reg) {
+  return MIPS_FPREG(reg);
+}
+
+uint32_t oatFpRegMask() {
+  return MIPS_FP_REG_MASK;
+}
+
+/* Clobber all regs that might be used by an external C call */
+extern void oatClobberCalleeSave(CompilationUnit *cUnit)
+{
+  oatClobber(cUnit, r_ZERO);
+  oatClobber(cUnit, r_AT);
+  oatClobber(cUnit, r_V0);
+  oatClobber(cUnit, r_V1);
+  oatClobber(cUnit, r_A0);
+  oatClobber(cUnit, r_A1);
+  oatClobber(cUnit, r_A2);
+  oatClobber(cUnit, r_A3);
+  oatClobber(cUnit, r_T0);
+  oatClobber(cUnit, r_T1);
+  oatClobber(cUnit, r_T2);
+  oatClobber(cUnit, r_T3);
+  oatClobber(cUnit, r_T4);
+  oatClobber(cUnit, r_T5);
+  oatClobber(cUnit, r_T6);
+  oatClobber(cUnit, r_T7);
+  oatClobber(cUnit, r_T8);
+  oatClobber(cUnit, r_T9);
+  oatClobber(cUnit, r_K0);
+  oatClobber(cUnit, r_K1);
+  oatClobber(cUnit, r_GP);
+  oatClobber(cUnit, r_FP);
+  oatClobber(cUnit, r_RA);
+  oatClobber(cUnit, r_F0);
+  oatClobber(cUnit, r_F1);
+  oatClobber(cUnit, r_F2);
+  oatClobber(cUnit, r_F3);
+  oatClobber(cUnit, r_F4);
+  oatClobber(cUnit, r_F5);
+  oatClobber(cUnit, r_F6);
+  oatClobber(cUnit, r_F7);
+  oatClobber(cUnit, r_F8);
+  oatClobber(cUnit, r_F9);
+  oatClobber(cUnit, r_F10);
+  oatClobber(cUnit, r_F11);
+  oatClobber(cUnit, r_F12);
+  oatClobber(cUnit, r_F13);
+  oatClobber(cUnit, r_F14);
+  oatClobber(cUnit, r_F15);
+}
+
+extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit)
+{
+  UNIMPLEMENTED(FATAL) << "No oatGetReturnWideAlt for MIPS";
+  RegLocation res = locCReturnWide();
+  return res;
+}
+
+extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
+{
+  UNIMPLEMENTED(FATAL) << "No oatGetReturnAlt for MIPS";
+  RegLocation res = locCReturn();
+  return res;
+}
+
+extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
+{
+  return MIPS_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & MIPS_FP_REG_MASK]
+            : &cUnit->regPool->coreRegs[reg];
+}
+
+/* To be used when explicitly managing register use */
+extern void oatLockCallTemps(CompilationUnit* cUnit)
+{
+  oatLockTemp(cUnit, rMIPS_ARG0);
+  oatLockTemp(cUnit, rMIPS_ARG1);
+  oatLockTemp(cUnit, rMIPS_ARG2);
+  oatLockTemp(cUnit, rMIPS_ARG3);
+}
+
+/* To be used when explicitly managing register use */
+extern void oatFreeCallTemps(CompilationUnit* cUnit)
+{
+  oatFreeTemp(cUnit, rMIPS_ARG0);
+  oatFreeTemp(cUnit, rMIPS_ARG1);
+  oatFreeTemp(cUnit, rMIPS_ARG2);
+  oatFreeTemp(cUnit, rMIPS_ARG3);
+}
+
+/* Convert an instruction to a NOP */
+void oatNopLIR( LIR* lir)
+{
+  ((LIR*)lir)->flags.isNop = true;
+}
+
+/*
+ * Determine the initial instruction set to be used for this trace.
+ * Later components may decide to change this.
+ */
+InstructionSet oatInstructionSet()
+{
+  return kMips;
+}
+
+/* Architecture-specific initializations and checks go here */
+bool oatArchVariantInit(void)
+{
+  return true;
+}
+
+int dvmCompilerTargetOptHint(int key)
+{
+  int res;
+  switch (key) {
+    case kMaxHoistDistance:
+      res = 2;
+      break;
+    default:
+      LOG(FATAL) << "Unknown target optimization hint key: " << key;
+  }
+  return res;
+}
+
+void oatGenMemBarrier(CompilationUnit *cUnit, int barrierKind)
+{
+#if ANDROID_SMP != 0
+  newLIR1(cUnit, kMipsSync, barrierKind);
+#endif
+}
+
+/*
+ * 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;
+
+#ifdef __mips_hard_float
+  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg)) {
+    lowReg = oatAllocTempDouble(cUnit);
+    highReg = lowReg + 1;
+    res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
+    return res;
+  }
+#endif
+
+  lowReg = oatAllocTemp(cUnit);
+  highReg = oatAllocTemp(cUnit);
+  res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
+  return res;
+}
+
+int oatAllocTypedTemp(CompilationUnit *cUnit, bool fpHint, int regClass)
+{
+#ifdef __mips_hard_float
+  if (((regClass == kAnyReg) && fpHint) || (regClass == kFPReg))
+{
+    return oatAllocTempFloat(cUnit);
+}
+#endif
+  return oatAllocTemp(cUnit);
+}
+
+void oatInitializeRegAlloc(CompilationUnit* cUnit)
+{
+  int numRegs = sizeof(coreRegs)/sizeof(*coreRegs);
+  int numReserved = sizeof(reservedRegs)/sizeof(*reservedRegs);
+  int numTemps = sizeof(coreTemps)/sizeof(*coreTemps);
+#ifdef __mips_hard_float
+  int numFPRegs = sizeof(fpRegs)/sizeof(*fpRegs);
+  int numFPTemps = sizeof(fpTemps)/sizeof(*fpTemps);
+#else
+  int numFPRegs = 0;
+  int numFPTemps = 0;
+#endif
+  RegisterPool *pool = (RegisterPool *)oatNew(cUnit, sizeof(*pool), true,
+                        kAllocRegAlloc);
+  cUnit->regPool = pool;
+  pool->numCoreRegs = numRegs;
+  pool->coreRegs = (RegisterInfo *)
+      oatNew(cUnit, numRegs * sizeof(*cUnit->regPool->coreRegs),
+             true, kAllocRegAlloc);
+  pool->numFPRegs = numFPRegs;
+  pool->FPRegs = (RegisterInfo *)
+      oatNew(cUnit, numFPRegs * sizeof(*cUnit->regPool->FPRegs), true,
+             kAllocRegAlloc);
+  oatInitPool(pool->coreRegs, coreRegs, pool->numCoreRegs);
+  oatInitPool(pool->FPRegs, fpRegs, pool->numFPRegs);
+  // Keep special registers from being allocated
+  for (int i = 0; i < numReserved; i++) {
+    if (NO_SUSPEND && (reservedRegs[i] == rMIPS_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]);
+  }
+  // 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);
+  }
+}
+/*
+ * In the Arm code a it is typical to use the link register
+ * to hold the target address.  However, for Mips we must
+ * ensure that all branch instructions can be restarted if
+ * there is a trap in the shadow.  Allocate a temp register.
+ */
+int loadHelper(CompilationUnit* cUnit, int offset)
+{
+  loadWordDisp(cUnit, rMIPS_SELF, offset, r_T9);
+  return r_T9;
+}
+
+void spillCoreRegs(CompilationUnit* cUnit)
+{
+  if (cUnit->numCoreSpills == 0) {
+    return;
+  }
+  uint32_t mask = cUnit->coreSpillMask;
+  int offset = cUnit->numCoreSpills * 4;
+  opRegImm(cUnit, kOpSub, rMIPS_SP, offset);
+  for (int reg = 0; mask; mask >>= 1, reg++) {
+    if (mask & 0x1) {
+      offset -= 4;
+      storeWordDisp(cUnit, rMIPS_SP, offset, reg);
+    }
+  }
+}
+
+void unSpillCoreRegs(CompilationUnit* cUnit)
+{
+  if (cUnit->numCoreSpills == 0) {
+    return;
+  }
+  uint32_t mask = cUnit->coreSpillMask;
+  int offset = cUnit->frameSize;
+  for (int reg = 0; mask; mask >>= 1, reg++) {
+    if (mask & 0x1) {
+      offset -= 4;
+      loadWordDisp(cUnit, rMIPS_SP, offset, reg);
+    }
+  }
+  opRegImm(cUnit, kOpAdd, rMIPS_SP, cUnit->frameSize);
+}
+
+/*
+ * 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 == kMipsB) {
+      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 < kMipsLast; 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();
+}
+
+} // namespace art
diff --git a/src/compiler/codegen/mips/Mips32/Factory.cc b/src/compiler/codegen/mips/utility_mips.cc
similarity index 95%
rename from src/compiler/codegen/mips/Mips32/Factory.cc
rename to src/compiler/codegen/mips/utility_mips.cc
index 0a0d906..a7faa1d 100644
--- a/src/compiler/codegen/mips/Mips32/Factory.cc
+++ b/src/compiler/codegen/mips/utility_mips.cc
@@ -18,21 +18,6 @@
 
 /* This file contains codegen for the MIPS32 ISA. */
 
-static int coreRegs[] = {r_ZERO, r_AT, r_V0, r_V1, r_A0, r_A1, r_A2, r_A3,
-                         r_T0, r_T1, r_T2, r_T3, r_T4, r_T5, r_T6, r_T7,
-                         r_S0, r_S1, r_S2, r_S3, r_S4, r_S5, r_S6, r_S7, r_T8,
-                         r_T9, r_K0, r_K1, r_GP, r_SP, r_FP, r_RA};
-static int reservedRegs[] = {r_ZERO, r_AT, r_S0, r_S1, r_K0, r_K1, r_GP, r_SP,
-                             r_RA};
-static int coreTemps[] = {r_V0, r_V1, r_A0, r_A1, r_A2, r_A3, r_T0, r_T1, r_T2,
-                          r_T3, r_T4, r_T5, r_T6, r_T7, r_T8};
-#ifdef __mips_hard_float
-static int fpRegs[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
-                       r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
-static int fpTemps[] = {r_F0, r_F1, r_F2, r_F3, r_F4, r_F5, r_F6, r_F7,
-                        r_F8, r_F9, r_F10, r_F11, r_F12, r_F13, r_F14, r_F15};
-#endif
-
 void genBarrier(CompilationUnit *cUnit);
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
 LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
diff --git a/src/compiler/codegen/Optimizer.h b/src/compiler/codegen/optimizer.h
similarity index 97%
rename from src/compiler/codegen/Optimizer.h
rename to src/compiler/codegen/optimizer.h
index 94b1907..f5c81a6 100644
--- a/src/compiler/codegen/Optimizer.h
+++ b/src/compiler/codegen/optimizer.h
@@ -17,7 +17,7 @@
 #ifndef ART_SRC_COMPILER_COMPILER_OPTIMIZATION_H_
 #define ART_SRC_COMPILER_COMPILER_OPTIMIZATION_H_
 
-#include "../Dalvik.h"
+#include "../dalvik.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/Ralloc.h b/src/compiler/codegen/ralloc.h
similarity index 98%
rename from src/compiler/codegen/Ralloc.h
rename to src/compiler/codegen/ralloc.h
index 55e62b1..8c327e4 100644
--- a/src/compiler/codegen/Ralloc.h
+++ b/src/compiler/codegen/ralloc.h
@@ -21,9 +21,9 @@
  * This file contains target independent register alloction support.
  */
 
-#include "../CompilerUtility.h"
-#include "../CompilerIR.h"
-#include "../Dataflow.h"
+#include "../compiler_utility.h"
+#include "../compiler_ir.h"
+#include "../dataflow.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/RallocUtil.cc b/src/compiler/codegen/ralloc_util.cc
similarity index 99%
rename from src/compiler/codegen/RallocUtil.cc
rename to src/compiler/codegen/ralloc_util.cc
index 4848a59..059d1c3 100644
--- a/src/compiler/codegen/RallocUtil.cc
+++ b/src/compiler/codegen/ralloc_util.cc
@@ -16,10 +16,10 @@
 
 /* This file contains register alloction support. */
 
-#include "../CompilerUtility.h"
-#include "../CompilerIR.h"
-#include "../Dataflow.h"
-#include "Ralloc.h"
+#include "../compiler_utility.h"
+#include "../compiler_ir.h"
+#include "../dataflow.h"
+#include "ralloc.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/x86/ArchFactory.cc b/src/compiler/codegen/x86/ArchFactory.cc
deleted file mode 100644
index 0ed6848..0000000
--- a/src/compiler/codegen/x86/ArchFactory.cc
+++ /dev/null
@@ -1,282 +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 x86-specific codegen factory support. */
-
-namespace art {
-
-bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) + (r2:r3)
-  opRegReg(cUnit, kOpAdd, r0, r2);  // r0 = r0 + r2
-  opRegReg(cUnit, kOpAdc, r1, r3);  // r1 = r1 + r3 + CF
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) + (r2:r3)
-  opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
-  opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) + (r2:r3)
-  opRegReg(cUnit, kOpAnd, r0, r2);  // r0 = r0 - r2
-  opRegReg(cUnit, kOpAnd, r1, r3);  // r1 = r1 - r3 - CF
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
-               RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) + (r2:r3)
-  opRegReg(cUnit, kOpOr, r0, r2);  // r0 = r0 - r2
-  opRegReg(cUnit, kOpOr, r1, r3);  // r1 = r1 - r3 - CF
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) + (r2:r3)
-  opRegReg(cUnit, kOpXor, r0, r2);  // r0 = r0 - r2
-  opRegReg(cUnit, kOpXor, r1, r3);  // r1 = r1 - r3 - CF
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
-  // Compute (r1:r0) = -(r1:r0)
-  opRegReg(cUnit, kOpNeg, r0, r0);  // r0 = -r0
-  opRegImm(cUnit, kOpAdc, r1, 0);   // r1 = r1 + CF
-  opRegReg(cUnit, kOpNeg, r1, r1);  // r1 = -r1
-  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
-                          INVALID_SREG, INVALID_SREG};
-  storeValueWide(cUnit, rlDest, rlResult);
-  return false;
-}
-
-void spillCoreRegs(CompilationUnit* cUnit) {
-  if (cUnit->numCoreSpills == 0) {
-    return;
-  }
-  // Spill mask not including fake return address register
-  uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
-  int offset = cUnit->frameSize - (4 * cUnit->numCoreSpills);
-  for (int reg = 0; mask; mask >>= 1, reg++) {
-    if (mask & 0x1) {
-      storeWordDisp(cUnit, rX86_SP, offset, reg);
-      offset += 4;
-    }
-  }
-}
-
-void unSpillCoreRegs(CompilationUnit* cUnit) {
-  if (cUnit->numCoreSpills == 0) {
-    return;
-  }
-  // Spill mask not including fake return address register
-  uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
-  int offset = cUnit->frameSize - (4 * cUnit->numCoreSpills);
-  for (int reg = 0; mask; mask >>= 1, reg++) {
-    if (mask & 0x1) {
-      loadWordDisp(cUnit, rX86_SP, offset, reg);
-      offset += 4;
-    }
-  }
-}
-
-void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset) {
-  X86OpCode opcode = kX86Bkpt;
-  switch (op) {
-  case kOpCmp: opcode = kX86Cmp32RT;  break;
-  default:
-    LOG(FATAL) << "Bad opcode: " << op;
-    break;
-  }
-  newLIR2(cUnit, opcode, rDest, threadOffset);
-}
-
-void genEntrySequence(CompilationUnit* cUnit, RegLocation* argLocs,
-                      RegLocation rlMethod)
-{
-  /*
-   * On entry, rX86_ARG0, rX86_ARG1, rX86_ARG2 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 no spare temps.
-   */
-  oatLockTemp(cUnit, rX86_ARG0);
-  oatLockTemp(cUnit, rX86_ARG1);
-  oatLockTemp(cUnit, rX86_ARG2);
-
-  /* Build frame, return address already on stack */
-  opRegImm(cUnit, kOpSub, rX86_SP, cUnit->frameSize - 4);
-
-  /*
-   * 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);
-  /* Spill core callee saves */
-  spillCoreRegs(cUnit);
-  /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
-  DCHECK_EQ(cUnit->numFPSpills, 0);
-  if (!skipOverflowCheck) {
-    // cmp rX86_SP, fs:[stack_end_]; jcc throw_launchpad
-    LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kThrowStackOverflow, 0, 0, 0, 0);
-    opRegThreadMem(cUnit, kOpCmp, rX86_SP, Thread::StackEndOffset().Int32Value());
-    opCondBranch(cUnit, kCondUlt, tgt);
-    // Remember branch target - will process later
-    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-  }
-
-  flushIns(cUnit, argLocs, rlMethod);
-
-  oatFreeTemp(cUnit, rX86_ARG0);
-  oatFreeTemp(cUnit, rX86_ARG1);
-  oatFreeTemp(cUnit, rX86_ARG2);
-}
-
-void genExitSequence(CompilationUnit* cUnit) {
-  /*
-   * In the exit path, rX86_RET0/rX86_RET1 are live - make sure they aren't
-   * allocated by the register utilities as temps.
-   */
-  oatLockTemp(cUnit, rX86_RET0);
-  oatLockTemp(cUnit, rX86_RET1);
-
-  newLIR0(cUnit, kPseudoMethodExit);
-  unSpillCoreRegs(cUnit);
-  /* Remove frame except for return address */
-  opRegImm(cUnit, kOpAdd, rX86_SP, cUnit->frameSize - 4);
-  newLIR0(cUnit, kX86Ret);
-}
-
-/*
- * 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 == kX86Jmp8 || thisLIR->opcode == kX86Jmp32) {
-    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 < kX86Last; 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();
-}
-
-// Not used in x86
-int loadHelper(CompilationUnit* cUnit, int offset)
-{
-  LOG(FATAL) << "Unexpected use of loadHelper in x86";
-  return INVALID_REG;
-}
-
-
-
-}  // namespace art
diff --git a/src/compiler/codegen/x86/ArchUtility.cc b/src/compiler/codegen/x86/ArchUtility.cc
deleted file mode 100644
index 32dd811..0000000
--- a/src/compiler/codegen/x86/ArchUtility.cc
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "../../CompilerInternals.h"
-#include "X86LIR.h"
-#include "../Ralloc.h"
-
-#include <string>
-
-namespace art {
-
-RegLocation locCReturn()
-{
-  RegLocation res = X86_LOC_C_RETURN;
-  return res;
-}
-
-RegLocation locCReturnWide()
-{
-  RegLocation res = X86_LOC_C_RETURN_WIDE;
-  return res;
-}
-
-RegLocation locCReturnFloat()
-{
-  RegLocation res = X86_LOC_C_RETURN_FLOAT;
-  return res;
-}
-
-RegLocation locCReturnDouble()
-{
-  RegLocation res = X86_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 = rX86_SELF; break;
-    case kSuspend: res =  rX86_SUSPEND; break;
-    case kLr: res =  rX86_LR; break;
-    case kPc: res =  rX86_PC; break;
-    case kSp: res =  rX86_SP; break;
-    case kArg0: res = rX86_ARG0; break;
-    case kArg1: res = rX86_ARG1; break;
-    case kArg2: res = rX86_ARG2; break;
-    case kArg3: res = rX86_ARG3; break;
-    case kFArg0: res = rX86_FARG0; break;
-    case kFArg1: res = rX86_FARG1; break;
-    case kFArg2: res = rX86_FARG2; break;
-    case kFArg3: res = rX86_FARG3; break;
-    case kRet0: res = rX86_RET0; break;
-    case kRet1: res = rX86_RET1; break;
-    case kInvokeTgt: res = rX86_INVOKE_TGT; break;
-    case kCount: res = rX86_COUNT; break;
-  }
-  return res;
-}
-
-// Create a double from a pair of singles.
-int s2d(int lowReg, int highReg)
-{
-  return X86_S2D(lowReg, highReg);
-}
-
-// Is reg a single or double?
-bool fpReg(int reg)
-{
-  return X86_FPREG(reg);
-}
-
-// Is reg a single?
-bool singleReg(int reg)
-{
-  return X86_SINGLEREG(reg);
-}
-
-// Is reg a double?
-bool doubleReg(int reg)
-{
-  return X86_DOUBLEREG(reg);
-}
-
-// Return mask to strip off fp reg flags and bias.
-uint32_t fpRegMask()
-{
-  return X86_FP_REG_MASK;
-}
-
-// True if both regs single, both core or both double.
-bool sameRegType(int reg1, int reg2)
-{
-  return (X86_REGTYPE(reg1) == X86_REGTYPE(reg2));
-}
-
-/*
- * Decode the register id.
- */
-u8 getRegMaskCommon(CompilationUnit* cUnit, int reg)
-{
-  u8 seed;
-  int shift;
-  int regId;
-
-  regId = reg & 0xf;
-  /* Double registers in x86 are just a single FP register */
-  seed = 1;
-  /* FP register starts at bit position 16 */
-  shift = X86_FPREG(reg) ? kX86FPReg0 : 0;
-  /* Expand the double register id into single offset */
-  shift += regId;
-  return (seed << shift);
-}
-
-uint64_t getPCUseDefEncoding()
-{
-  /*
-   * FIXME: might make sense to use a virtual resource encoding bit for pc.  Might be
-   * able to clean up some of the x86/Arm_Mips differences
-   */
-  LOG(FATAL) << "Unexpected call to getPCUseDefEncoding for x86";
-  return 0ULL;
-}
-
-void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
-{
-  DCHECK_EQ(cUnit->instructionSet, kX86);
-
-  // X86-specific resource map setup here.
-  uint64_t flags = EncodingMap[lir->opcode].flags;
-
-  if (flags & REG_USE_SP) {
-    lir->useMask |= ENCODE_X86_REG_SP;
-  }
-
-  if (flags & REG_DEF_SP) {
-    lir->defMask |= ENCODE_X86_REG_SP;
-  }
-
-  if (flags & REG_DEFA) {
-    oatSetupRegMask(cUnit, &lir->defMask, rAX);
-  }
-
-  if (flags & REG_DEFD) {
-    oatSetupRegMask(cUnit, &lir->defMask, rDX);
-  }
-  if (flags & REG_USEA) {
-    oatSetupRegMask(cUnit, &lir->useMask, rAX);
-  }
-
-  if (flags & REG_USEC) {
-    oatSetupRegMask(cUnit, &lir->useMask, rCX);
-  }
-
-  if (flags & REG_USED) {
-    oatSetupRegMask(cUnit, &lir->useMask, rDX);
-  }
-}
-
-/* For dumping instructions */
-static const char* x86RegName[] = {
-  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
-  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
-};
-
-static const char* x86CondName[] = {
-  "O",
-  "NO",
-  "B/NAE/C",
-  "NB/AE/NC",
-  "Z/EQ",
-  "NZ/NE",
-  "BE/NA",
-  "NBE/A",
-  "S",
-  "NS",
-  "P/PE",
-  "NP/PO",
-  "L/NGE",
-  "NL/GE",
-  "LE/NG",
-  "NLE/G"
-};
-
-/*
- * Interpret a format string and build a string no longer than size
- * See format key in Assemble.cc.
- */
-std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) {
-  std::string buf;
-  size_t i = 0;
-  size_t fmt_len = strlen(fmt);
-  while (i < fmt_len) {
-    if (fmt[i] != '!') {
-      buf += fmt[i];
-      i++;
-    } else {
-      i++;
-      DCHECK_LT(i, fmt_len);
-      char operand_number_ch = fmt[i];
-      i++;
-      if (operand_number_ch == '!') {
-        buf += "!";
-      } else {
-        int operand_number = operand_number_ch - '0';
-        DCHECK_LT(operand_number, 6);  // Expect upto 6 LIR operands.
-        DCHECK_LT(i, fmt_len);
-        int operand = lir->operands[operand_number];
-        switch (fmt[i]) {
-          case 'c':
-            DCHECK_LT(static_cast<size_t>(operand), sizeof(x86CondName));
-            buf += x86CondName[operand];
-            break;
-          case 'd':
-            buf += StringPrintf("%d", operand);
-            break;
-          case 'p': {
-            SwitchTable *tabRec = reinterpret_cast<SwitchTable*>(operand);
-            buf += StringPrintf("0x%08x", tabRec->offset);
-            break;
-          }
-          case 'r':
-            if (X86_FPREG(operand) || X86_DOUBLEREG(operand)) {
-              int fp_reg = operand & X86_FP_REG_MASK;
-              buf += StringPrintf("xmm%d", fp_reg);
-            } else {
-              DCHECK_LT(static_cast<size_t>(operand), sizeof(x86RegName));
-              buf += x86RegName[operand];
-            }
-            break;
-          case 't':
-            buf += StringPrintf("0x%08x (L%p)",
-                                reinterpret_cast<uint32_t>(baseAddr)
-                                + lir->offset + operand, lir->target);
-            break;
-          default:
-            buf += StringPrintf("DecodeError '%c'", fmt[i]);
-            break;
-        }
-        i++;
-      }
-    }
-  }
-  return buf;
-}
-
-void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
-{
-  char buf[256];
-  buf[0] = 0;
-  LIR *x86LIR = (LIR *) lir;
-
-  if (mask == ENCODE_ALL) {
-    strcpy(buf, "all");
-  } else {
-    char num[8];
-    int i;
-
-    for (i = 0; i < kX86RegEnd; i++) {
-      if (mask & (1ULL << i)) {
-        sprintf(num, "%d ", i);
-        strcat(buf, num);
-      }
-    }
-
-    if (mask & ENCODE_CCODE) {
-      strcat(buf, "cc ");
-    }
-    /* Memory bits */
-    if (x86LIR && (mask & ENCODE_DALVIK_REG)) {
-      sprintf(buf + strlen(buf), "dr%d%s", x86LIR->aliasInfo & 0xffff,
-              (x86LIR->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/x86/X86/Gen.cc b/src/compiler/codegen/x86/X86/Gen.cc
deleted file mode 100644
index 37cd725..0000000
--- a/src/compiler/codegen/x86/X86/Gen.cc
+++ /dev/null
@@ -1,551 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* This file contains codegen for the X86 ISA */
-
-namespace art {
-
-void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
-                    SpecialCaseHandler specialCase)
-{
-  // TODO
-}
-
-/*
- * Perform register memory operation.
- */
-LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode,
-                    int reg1, int base, int offset, ThrowKind kind)
-{
-  LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
-                    cUnit->currentDalvikOffset, reg1, base, offset);
-  opRegMem(cUnit, kOpCmp, reg1, base, offset);
-  LIR* branch = opCondBranch(cUnit, cCode, tgt);
-  // Remember branch target - will process later
-  oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
-  return branch;
-}
-
-/*
- * The sparse table in the literal pool is an array of <key,displacement>
- * pairs.
- */
-BasicBlock *findBlock(CompilationUnit* cUnit, unsigned int codeOffset,
-                      bool split, bool create, BasicBlock** immedPredBlockP);
-void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
-                     RegLocation rlSrc)
-{
-  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
-  if (cUnit->printMe) {
-    dumpSparseSwitchTable(table);
-  }
-  int entries = table[1];
-  int* keys = (int*)&table[2];
-  int* targets = &keys[entries];
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  for (int i = 0; i < entries; i++) {
-    int key = keys[i];
-    BasicBlock* case_block = findBlock(cUnit,
-                                       cUnit->currentDalvikOffset + targets[i],
-                                       false, false, NULL);
-    LIR* labelList = cUnit->blockLabelList;
-    opCmpImmBranch(cUnit, kCondEq, rlSrc.lowReg, key,
-                   &labelList[case_block->id]);
-  }
-}
-
-/*
- * Code pattern will look something like:
- *
- * mov  rVal, ..
- * call 0
- * pop  rStartOfMethod
- * sub  rStartOfMethod, ..
- * mov  rKeyReg, rVal
- * sub  rKeyReg, lowKey
- * cmp  rKeyReg, size-1  ; bound check
- * ja   done
- * mov  rDisp, [rStartOfMethod + rKeyReg * 4 + tableOffset]
- * add  rStartOfMethod, rDisp
- * jmp  rStartOfMethod
- * done:
- */
-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 startOfMethodReg = oatAllocTemp(cUnit);
-  // Materialize a pointer to the switch table
-  //newLIR0(cUnit, kX86Bkpt);
-  newLIR1(cUnit, kX86StartOfMethod, startOfMethodReg);
-  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);
-  newLIR5(cUnit, kX86PcRelLoadRA, dispReg, startOfMethodReg, keyReg, 2,
-          (intptr_t)tabRec);
-  // Add displacement to start of method
-  opRegReg(cUnit, kOpAdd, startOfMethodReg, dispReg);
-  // ..and go!
-  LIR* switchBranch = newLIR1(cUnit, kX86JmpR, startOfMethodReg);
-  tabRec->anchor = switchBranch;
-
-  /* branchOver target here */
-  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
-  branchOver->target = (LIR*)target;
-}
-
-void callRuntimeHelperRegReg(CompilationUnit* cUnit, int helperOffset,
-                             int arg0, int arg1, bool safepointPC);
-/*
- * 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, rX86_ARG0);
-  // Materialize a pointer to the fill data image
-  newLIR1(cUnit, kX86StartOfMethod, rX86_ARG2);
-  newLIR2(cUnit, kX86PcRelAdr, rX86_ARG1, (intptr_t)tabRec);
-  newLIR2(cUnit, kX86Add32RR, rX86_ARG1, rX86_ARG2);
-  callRuntimeHelperRegReg(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode), rX86_ARG0, rX86_ARG1,
-                          true);
-}
-
-void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, 0x80000000);
-  storeValue(cUnit, rlDest, rlResult);
-}
-
-void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
-{
-  RegLocation rlResult;
-  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
-  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
-  opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 0x80000000);
-  opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
-  storeValueWide(cUnit, rlDest, rlResult);
-}
-
-LIR* genNullCheck(CompilationUnit* cUnit, int sReg, int mReg, int optFlags);
-void callRuntimeHelperReg(CompilationUnit* cUnit, int helperOffset, int arg0, bool safepointPC);
-
-void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, rCX);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rCX, optFlags);
-  // If lock is unheld, try to grab it quickly with compare and exchange
-  // TODO: copy and clear hash state?
-  newLIR2(cUnit, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
-  newLIR2(cUnit, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
-  newLIR2(cUnit, kX86Xor32RR, rAX, rAX);
-  newLIR3(cUnit, kX86LockCmpxchgMR, rCX, Object::MonitorOffset().Int32Value(), rDX);
-  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondEq);
-  // If lock is held, go the expensive route - artLockObjectFromCode(self, obj);
-  callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode), rCX, true);
-  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
-}
-
-void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
-{
-  oatFlushAllRegs(cUnit);
-  loadValueDirectFixed(cUnit, rlSrc, rAX);  // Get obj
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  genNullCheck(cUnit, rlSrc.sRegLow, rAX, optFlags);
-  // If lock is held by the current thread, clear it to quickly release it
-  // TODO: clear hash state?
-  newLIR2(cUnit, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
-  newLIR2(cUnit, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
-  newLIR3(cUnit, kX86Mov32RM, rCX, rAX, Object::MonitorOffset().Int32Value());
-  opRegReg(cUnit, kOpSub, rCX, rDX);
-  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondNe);
-  newLIR3(cUnit, kX86Mov32MR, rAX, Object::MonitorOffset().Int32Value(), rCX);
-  LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
-  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
-  // Otherwise, go the expensive route - UnlockObjectFromCode(obj);
-  callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rAX, true);
-  branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
-}
-
-/*
- * Compare two 64-bit values
- *    x = y     return  0
- *    x < y     return -1
- *    x > y     return  1
- *
- *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
- *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
- *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
- *    bnez  res, finish
- *    sltu  t0, x.lo, y.lo
- *    sgtu  r1, x.lo, y.lo
- *    subu  res, t0, t1
- * finish:
- *
- */
-void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
-                RegLocation rlSrc1, RegLocation rlSrc2)
-{
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  // Compute (r1:r0) = (r1:r0) - (r3:r2)
-  opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
-  opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
-  newLIR2(cUnit, kX86Set8R, r2, kX86CondL);  // r2 = (r1:r0) < (r3:r2) ? 1 : 0
-  newLIR2(cUnit, kX86Movzx8RR, r2, r2);
-  opReg(cUnit, kOpNeg, r2);         // r2 = -r2
-  opRegReg(cUnit, kOpOr, r0, r1);   // r0 = high | low - sets ZF
-  newLIR2(cUnit, kX86Set8R, r0, kX86CondNz);  // r0 = (r1:r0) != (r3:r2) ? 1 : 0
-  newLIR2(cUnit, kX86Movzx8RR, r0, r0);
-  opRegReg(cUnit, kOpOr, r0, r2);   // r0 = r0 | r2
-  RegLocation rlResult = locCReturn();
-  storeValue(cUnit, rlDest, rlResult);
-}
-
-X86ConditionCode oatX86ConditionEncoding(ConditionCode cond) {
-  switch (cond) {
-    case kCondEq: return kX86CondEq;
-    case kCondNe: return kX86CondNe;
-    case kCondCs: return kX86CondC;
-    case kCondCc: return kX86CondNc;
-    case kCondMi: return kX86CondS;
-    case kCondPl: return kX86CondNs;
-    case kCondVs: return kX86CondO;
-    case kCondVc: return kX86CondNo;
-    case kCondHi: return kX86CondA;
-    case kCondLs: return kX86CondBe;
-    case kCondGe: return kX86CondGe;
-    case kCondLt: return kX86CondL;
-    case kCondGt: return kX86CondG;
-    case kCondLe: return kX86CondLe;
-    case kCondAl:
-    case kCondNv: LOG(FATAL) << "Should not reach here";
-  }
-  return kX86CondO;
-}
-
-LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
-                 int src2, LIR* target)
-{
-  newLIR2(cUnit, kX86Cmp32RR, src1, src2);
-  X86ConditionCode cc = oatX86ConditionEncoding(cond);
-  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0 /* lir operand for Jcc offset */ ,
-                        cc);
-  branch->target = target;
-  return branch;
-}
-
-LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
-                    int checkValue, LIR* target)
-{
-  if ((checkValue == 0) && (cond == kCondEq || cond == kCondNe)) {
-    // TODO: when checkValue == 0 and reg is rCX, use the jcxz/nz opcode
-    newLIR2(cUnit, kX86Test32RR, reg, reg);
-  } else {
-    newLIR2(cUnit, IS_SIMM8(checkValue) ? kX86Cmp32RI8 : kX86Cmp32RI, reg, checkValue);
-  }
-  X86ConditionCode cc = oatX86ConditionEncoding(cond);
-  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0 /* lir operand for Jcc offset */ , cc);
-  branch->target = target;
-  return branch;
-}
-
-LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
-{
-  if (X86_FPREG(rDest) || X86_FPREG(rSrc))
-    return fpRegCopy(cUnit, rDest, rSrc);
-  LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kX86Mov32RR,
-                    rDest, rSrc);
-  if (rDest == rSrc) {
-    res->flags.isNop = true;
-  }
-  return res;
-}
-
-LIR* opRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
-{
-  LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc);
-  oatAppendLIR(cUnit, res);
-  return res;
-}
-
-void opRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
-                   int srcLo, int srcHi)
-{
-  bool destFP = X86_FPREG(destLo) && X86_FPREG(destHi);
-  bool srcFP = X86_FPREG(srcLo) && X86_FPREG(srcHi);
-  assert(X86_FPREG(srcLo) == X86_FPREG(srcHi));
-  assert(X86_FPREG(destLo) == X86_FPREG(destHi));
-  if (destFP) {
-    if (srcFP) {
-      opRegCopy(cUnit, s2d(destLo, destHi), s2d(srcLo, srcHi));
-    } else {
-      // TODO: Prevent this from happening in the code. The result is often
-      // unused or could have been loaded more easily from memory.
-      newLIR2(cUnit, kX86MovdxrRR, destLo, srcLo);
-      newLIR2(cUnit, kX86MovdxrRR, destHi, srcHi);
-      newLIR2(cUnit, kX86PsllqRI, destHi, 32);
-      newLIR2(cUnit, kX86OrpsRR, destLo, destHi);
-    }
-  } else {
-    if (srcFP) {
-      newLIR2(cUnit, kX86MovdrxRR, destLo, srcLo);
-      newLIR2(cUnit, kX86PsrlqRI, srcLo, 32);
-      newLIR2(cUnit, kX86MovdrxRR, destHi, srcLo);
-    } else {
-      // Handle overlap
-      if (srcHi == destLo) {
-        opRegCopy(cUnit, destHi, srcHi);
-        opRegCopy(cUnit, destLo, srcLo);
-      } else {
-        opRegCopy(cUnit, destLo, srcLo);
-        opRegCopy(cUnit, destHi, srcHi);
-      }
-    }
-  }
-}
-
-void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir) {
-  LIR* labelList = cUnit->blockLabelList;
-  LIR* taken = &labelList[bb->taken->id];
-  RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
-  RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
-  oatFlushAllRegs(cUnit);
-  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
-  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
-  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
-  ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
-  // Swap operands and condition code to prevent use of zero flag.
-  if (ccode == kCondLe || ccode == kCondGt) {
-    // Compute (r3:r2) = (r3:r2) - (r1:r0)
-    opRegReg(cUnit, kOpSub, r2, r0);  // r2 = r2 - r0
-    opRegReg(cUnit, kOpSbc, r3, r1);  // r3 = r3 - r1 - CF
-  } else {
-    // Compute (r1:r0) = (r1:r0) - (r3:r2)
-    opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
-    opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
-  }
-  switch (ccode) {
-    case kCondEq:
-    case kCondNe:
-      opRegReg(cUnit, kOpOr, r0, r1);  // r0 = r0 | r1
-      break;
-    case kCondLe:
-      ccode = kCondGe;
-      break;
-    case kCondGt:
-      ccode = kCondLt;
-      break;
-    case kCondLt:
-    case kCondGe:
-      break;
-    default:
-      LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
-  }
-  opCondBranch(cUnit, ccode, taken);
-}
-RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int lit, bool isDiv)
-{
-  LOG(FATAL) << "Unexpected use of genDivRemLit for x86";
-  return rlDest;
-}
-
-RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int regHi, bool isDiv)
-{
-  LOG(FATAL) << "Unexpected use of genDivRem for x86";
-  return rlDest;
-}
-
-/*
- * 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);
-  newLIR2(cUnit, kX86Mov32RT, regCardBase, Thread::CardTableOffset().Int32Value());
-  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);
-}
-
-bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
-{
-  DCHECK_EQ(cUnit->instructionSet, kX86);
-  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);
-  DCHECK_EQ(cUnit->instructionSet, kX86);
-  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, isMin ? kX86CondG : kX86CondL);
-  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
-  LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
-  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
-  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
-  branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
-  storeValue(cUnit, rlDest, rlResult);
-  return true;
-}
-
-void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset)
-{
-  newLIR5(cUnit, kX86Lea32RA, rBase, reg1, reg2, scale, offset);
-}
-
-void opTlsCmp(CompilationUnit* cUnit, int offset, int val)
-{
-  newLIR2(cUnit, kX86Cmp16TI8, offset, val);
-}
-
-bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) {
-  DCHECK_NE(cUnit->instructionSet, kThumb2);
-  return false;
-}
-
-bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
-  DCHECK_NE(cUnit->instructionSet, kThumb2);
-  return false;
-}
-
-LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target) {
-  LOG(FATAL) << "Unexpected use of opPcRelLoad for x86";
-  return NULL;
-}
-
-LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
-{
-  LOG(FATAL) << "Unexpected use of opVldm for x86";
-  return NULL;
-}
-
-LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
-{
-  LOG(FATAL) << "Unexpected use of opVstm for x86";
-  return NULL;
-}
-
-void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
-                                   RegLocation rlResult, int lit,
-                                   int firstBit, int secondBit)
-{
-  int tReg = oatAllocTemp(cUnit);
-  opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, secondBit - firstBit);
-  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, tReg);
-  oatFreeTemp(cUnit, tReg);
-  if (firstBit != 0) {
-    opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
-  }
-}
-
-void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
-{
-  int tReg = oatAllocTemp(cUnit);
-  opRegRegReg(cUnit, kOpOr, tReg, regLo, regHi);
-  genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
-  oatFreeTemp(cUnit, tReg);
-}
-
-// Test suspend flag, return target of taken suspend branch
-LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
-{
-  opTlsCmp(cUnit, Thread::ThreadFlagsOffset().Int32Value(), 0);
-  return opCondBranch(cUnit, (target == NULL) ? kCondNe : kCondEq, target);
-}
-
-// Decrement register and branch on condition
-LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
-{
-  opRegImm(cUnit, kOpSub, reg, 1);
-  return opCmpImmBranch(cUnit, cCode, reg, 0, target);
-}
-
-bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
-                        RegLocation rlSrc, RegLocation rlDest, int lit)
-{
-  LOG(FATAL) << "Unexpected use of smallLiteralDive in x86";
-  return false;
-}
-
-LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide)
-{
-  LOG(FATAL) << "Unexpected use of opIT in x86";
-  return NULL;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/x86/X86/Ralloc.cc b/src/compiler/codegen/x86/X86/Ralloc.cc
deleted file mode 100644
index ef72e52..0000000
--- a/src/compiler/codegen/x86/X86/Ralloc.cc
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace art {
-
-/* This file contains codegen for the X86 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;
-    res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
-    return res;
-  }
-
-  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++) {
-    oatMarkInUse(cUnit, reservedRegs[i]);
-  }
-  // Mark temp regs - all others not in use can be used for promotion
-  for (int i = 0; i < numTemps; i++) {
-    oatMarkTemp(cUnit, coreTemps[i]);
-  }
-  for (int i = 0; i < numFPTemps; i++) {
-    oatMarkTemp(cUnit, fpTemps[i]);
-  }
-  // Construct the alias map.
-  cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
-                                    sizeof(cUnit->phiAliasMap[0]), false,
-                                    kAllocDFInfo);
-  for (int i = 0; i < cUnit->numSSARegs; i++) {
-    cUnit->phiAliasMap[i] = i;
-  }
-  for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
-    int defReg = phi->ssaRep->defs[0];
-    for (int i = 0; i < phi->ssaRep->numUses; i++) {
-      for (int j = 0; j < cUnit->numSSARegs; j++) {
-        if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
-          cUnit->phiAliasMap[j] = defReg;
-        }
-      }
-    }
-  }
-}
-
-void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
-                     RegLocation rlFree)
-{
-  if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
-      (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
-    // No overlap, free both
-    oatFreeTemp(cUnit, rlFree.lowReg);
-    oatFreeTemp(cUnit, rlFree.highReg);
-  }
-}
-
-
-}  // namespace art
diff --git a/src/compiler/codegen/x86/X86RallocUtil.cc b/src/compiler/codegen/x86/X86RallocUtil.cc
deleted file mode 100644
index caf4e08..0000000
--- a/src/compiler/codegen/x86/X86RallocUtil.cc
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/*
- * This file contains X86-specific register allocation support.
- */
-
-#include "../../CompilerUtility.h"
-#include "../../CompilerIR.h"
-#include "../..//Dataflow.h"
-#include "X86LIR.h"
-#include "Codegen.h"
-#include "../Ralloc.h"
-
-namespace art {
-
-void oatAdjustSpillMask(CompilationUnit* cUnit) {
-  // Adjustment for LR spilling, x86 has no LR so nothing to do here
-  cUnit->coreSpillMask |= (1 << rRET);
-  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)
-{
-  UNIMPLEMENTED(WARNING) << "oatMarkPreservedSingle";
-#if 0
-  LOG(FATAL) << "No support yet for promoted FP regs";
-#endif
-}
-
-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, rX86_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, rX86_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
-  }
-}
-
-/* Give access to the target-dependent FP register encoding to common code */
-bool oatIsFpReg(int reg) {
-  return X86_FPREG(reg);
-}
-
-uint32_t oatFpRegMask() {
-  return X86_FP_REG_MASK;
-}
-
-/* Clobber all regs that might be used by an external C call */
-extern void oatClobberCalleeSave(CompilationUnit *cUnit)
-{
-  oatClobber(cUnit, rAX);
-  oatClobber(cUnit, rCX);
-  oatClobber(cUnit, rDX);
-}
-
-extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit) {
-  RegLocation res = locCReturnWide();
-  CHECK(res.lowReg == rAX);
-  CHECK(res.highReg == rDX);
-  oatClobber(cUnit, rAX);
-  oatClobber(cUnit, rDX);
-  oatMarkInUse(cUnit, rAX);
-  oatMarkInUse(cUnit, rDX);
-  oatMarkPair(cUnit, res.lowReg, res.highReg);
-  return res;
-}
-
-extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
-{
-  RegLocation res = locCReturn();
-  res.lowReg = rDX;
-  oatClobber(cUnit, rDX);
-  oatMarkInUse(cUnit, rDX);
-  return res;
-}
-
-extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
-{
-  return X86_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & X86_FP_REG_MASK]
-                    : &cUnit->regPool->coreRegs[reg];
-}
-
-/* To be used when explicitly managing register use */
-extern void oatLockCallTemps(CompilationUnit* cUnit)
-{
-  oatLockTemp(cUnit, rX86_ARG0);
-  oatLockTemp(cUnit, rX86_ARG1);
-  oatLockTemp(cUnit, rX86_ARG2);
-  oatLockTemp(cUnit, rX86_ARG3);
-}
-
-/* To be used when explicitly managing register use */
-extern void oatFreeCallTemps(CompilationUnit* cUnit)
-{
-  oatFreeTemp(cUnit, rX86_ARG0);
-  oatFreeTemp(cUnit, rX86_ARG1);
-  oatFreeTemp(cUnit, rX86_ARG2);
-  oatFreeTemp(cUnit, rX86_ARG3);
-}
-
-/* Convert an instruction to a NOP */
-void oatNopLIR( LIR* lir)
-{
-  ((LIR*)lir)->flags.isNop = true;
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/x86/Assemble.cc b/src/compiler/codegen/x86/assemble_x86.cc
similarity index 99%
rename from src/compiler/codegen/x86/Assemble.cc
rename to src/compiler/codegen/x86/assemble_x86.cc
index a5388e8..79ed075 100644
--- a/src/compiler/codegen/x86/Assemble.cc
+++ b/src/compiler/codegen/x86/assemble_x86.cc
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
-#include "X86LIR.h"
-#include "Codegen.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "x86_lir.h"
+#include "codegen.h"
 
 namespace art {
 
diff --git a/src/compiler/codegen/x86/backend_x86.cc b/src/compiler/codegen/x86/backend_x86.cc
new file mode 100644
index 0000000..6abfb23
--- /dev/null
+++ b/src/compiler/codegen/x86/backend_x86.cc
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _CODEGEN_C
+
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
+#include "x86_lir.h"
+#include "../ralloc.h"
+#include "codegen.h"
+
+/* Common codegen utility code */
+#include "../codegen_util.cc"
+
+#include "utility_x86.cc"
+#include "../codegen_factory.cc"
+#include "../gen_common.cc"
+#include "../gen_invoke.cc"
+#include "call_x86.cc"
+#include "fp_x86.cc"
+#include "int_x86.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/x86/call_x86.cc b/src/compiler/codegen/x86/call_x86.cc
new file mode 100644
index 0000000..0cd9b2d
--- /dev/null
+++ b/src/compiler/codegen/x86/call_x86.cc
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file contains codegen for the X86 ISA */
+
+namespace art {
+
+void genSpecialCase(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir,
+                    SpecialCaseHandler specialCase)
+{
+  // TODO
+}
+
+/*
+ * The sparse table in the literal pool is an array of <key,displacement>
+ * pairs.
+ */
+BasicBlock *findBlock(CompilationUnit* cUnit, unsigned int codeOffset,
+                      bool split, bool create, BasicBlock** immedPredBlockP);
+void genSparseSwitch(CompilationUnit* cUnit, uint32_t tableOffset,
+                     RegLocation rlSrc)
+{
+  const u2* table = cUnit->insns + cUnit->currentDalvikOffset + tableOffset;
+  if (cUnit->printMe) {
+    dumpSparseSwitchTable(table);
+  }
+  int entries = table[1];
+  int* keys = (int*)&table[2];
+  int* targets = &keys[entries];
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  for (int i = 0; i < entries; i++) {
+    int key = keys[i];
+    BasicBlock* case_block = findBlock(cUnit,
+                                       cUnit->currentDalvikOffset + targets[i],
+                                       false, false, NULL);
+    LIR* labelList = cUnit->blockLabelList;
+    opCmpImmBranch(cUnit, kCondEq, rlSrc.lowReg, key,
+                   &labelList[case_block->id]);
+  }
+}
+
+/*
+ * Code pattern will look something like:
+ *
+ * mov  rVal, ..
+ * call 0
+ * pop  rStartOfMethod
+ * sub  rStartOfMethod, ..
+ * mov  rKeyReg, rVal
+ * sub  rKeyReg, lowKey
+ * cmp  rKeyReg, size-1  ; bound check
+ * ja   done
+ * mov  rDisp, [rStartOfMethod + rKeyReg * 4 + tableOffset]
+ * add  rStartOfMethod, rDisp
+ * jmp  rStartOfMethod
+ * done:
+ */
+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 startOfMethodReg = oatAllocTemp(cUnit);
+  // Materialize a pointer to the switch table
+  //newLIR0(cUnit, kX86Bkpt);
+  newLIR1(cUnit, kX86StartOfMethod, startOfMethodReg);
+  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);
+  newLIR5(cUnit, kX86PcRelLoadRA, dispReg, startOfMethodReg, keyReg, 2,
+          (intptr_t)tabRec);
+  // Add displacement to start of method
+  opRegReg(cUnit, kOpAdd, startOfMethodReg, dispReg);
+  // ..and go!
+  LIR* switchBranch = newLIR1(cUnit, kX86JmpR, startOfMethodReg);
+  tabRec->anchor = switchBranch;
+
+  /* branchOver target here */
+  LIR* target = newLIR0(cUnit, kPseudoTargetLabel);
+  branchOver->target = (LIR*)target;
+}
+
+void callRuntimeHelperRegReg(CompilationUnit* cUnit, int helperOffset,
+                             int arg0, int arg1, bool safepointPC);
+/*
+ * 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, rX86_ARG0);
+  // Materialize a pointer to the fill data image
+  newLIR1(cUnit, kX86StartOfMethod, rX86_ARG2);
+  newLIR2(cUnit, kX86PcRelAdr, rX86_ARG1, (intptr_t)tabRec);
+  newLIR2(cUnit, kX86Add32RR, rX86_ARG1, rX86_ARG2);
+  callRuntimeHelperRegReg(cUnit, ENTRYPOINT_OFFSET(pHandleFillArrayDataFromCode), rX86_ARG0, rX86_ARG1,
+                          true);
+}
+
+void genMonitorEnter(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, rCX);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, rCX, optFlags);
+  // If lock is unheld, try to grab it quickly with compare and exchange
+  // TODO: copy and clear hash state?
+  newLIR2(cUnit, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
+  newLIR2(cUnit, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
+  newLIR2(cUnit, kX86Xor32RR, rAX, rAX);
+  newLIR3(cUnit, kX86LockCmpxchgMR, rCX, Object::MonitorOffset().Int32Value(), rDX);
+  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondEq);
+  // If lock is held, go the expensive route - artLockObjectFromCode(self, obj);
+  callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pLockObjectFromCode), rCX, true);
+  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+}
+
+void genMonitorExit(CompilationUnit* cUnit, int optFlags, RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  loadValueDirectFixed(cUnit, rlSrc, rAX);  // Get obj
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  genNullCheck(cUnit, rlSrc.sRegLow, rAX, optFlags);
+  // If lock is held by the current thread, clear it to quickly release it
+  // TODO: clear hash state?
+  newLIR2(cUnit, kX86Mov32RT, rDX, Thread::ThinLockIdOffset().Int32Value());
+  newLIR2(cUnit, kX86Sal32RI, rDX, LW_LOCK_OWNER_SHIFT);
+  newLIR3(cUnit, kX86Mov32RM, rCX, rAX, Object::MonitorOffset().Int32Value());
+  opRegReg(cUnit, kOpSub, rCX, rDX);
+  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, kX86CondNe);
+  newLIR3(cUnit, kX86Mov32MR, rAX, Object::MonitorOffset().Int32Value(), rCX);
+  LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
+  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+  // Otherwise, go the expensive route - UnlockObjectFromCode(obj);
+  callRuntimeHelperReg(cUnit, ENTRYPOINT_OFFSET(pUnlockObjectFromCode), rAX, true);
+  branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
+}
+
+/*
+ * 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);
+  newLIR2(cUnit, kX86Mov32RT, regCardBase, Thread::CardTableOffset().Int32Value());
+  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)
+{
+  /*
+   * On entry, rX86_ARG0, rX86_ARG1, rX86_ARG2 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 no spare temps.
+   */
+  oatLockTemp(cUnit, rX86_ARG0);
+  oatLockTemp(cUnit, rX86_ARG1);
+  oatLockTemp(cUnit, rX86_ARG2);
+
+  /* Build frame, return address already on stack */
+  opRegImm(cUnit, kOpSub, rX86_SP, cUnit->frameSize - 4);
+
+  /*
+   * 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);
+  /* Spill core callee saves */
+  spillCoreRegs(cUnit);
+  /* NOTE: promotion of FP regs currently unsupported, thus no FP spill */
+  DCHECK_EQ(cUnit->numFPSpills, 0);
+  if (!skipOverflowCheck) {
+    // cmp rX86_SP, fs:[stack_end_]; jcc throw_launchpad
+    LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kThrowStackOverflow, 0, 0, 0, 0);
+    opRegThreadMem(cUnit, kOpCmp, rX86_SP, Thread::StackEndOffset().Int32Value());
+    opCondBranch(cUnit, kCondUlt, tgt);
+    // Remember branch target - will process later
+    oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
+  }
+
+  flushIns(cUnit, argLocs, rlMethod);
+
+  oatFreeTemp(cUnit, rX86_ARG0);
+  oatFreeTemp(cUnit, rX86_ARG1);
+  oatFreeTemp(cUnit, rX86_ARG2);
+}
+
+void genExitSequence(CompilationUnit* cUnit) {
+  /*
+   * In the exit path, rX86_RET0/rX86_RET1 are live - make sure they aren't
+   * allocated by the register utilities as temps.
+   */
+  oatLockTemp(cUnit, rX86_RET0);
+  oatLockTemp(cUnit, rX86_RET1);
+
+  newLIR0(cUnit, kPseudoMethodExit);
+  unSpillCoreRegs(cUnit);
+  /* Remove frame except for return address */
+  opRegImm(cUnit, kOpAdd, rX86_SP, cUnit->frameSize - 4);
+  newLIR0(cUnit, kX86Ret);
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/x86/Codegen.h b/src/compiler/codegen/x86/codegen.h
similarity index 99%
rename from src/compiler/codegen/x86/Codegen.h
rename to src/compiler/codegen/x86/codegen.h
index 3755e50..c95fa67 100644
--- a/src/compiler/codegen/x86/Codegen.h
+++ b/src/compiler/codegen/x86/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/x86/FP/X86FP.cc b/src/compiler/codegen/x86/fp_x86.cc
similarity index 92%
rename from src/compiler/codegen/x86/FP/X86FP.cc
rename to src/compiler/codegen/x86/fp_x86.cc
index 5e97a50..0a08ab0 100644
--- a/src/compiler/codegen/x86/FP/X86FP.cc
+++ b/src/compiler/codegen/x86/fp_x86.cc
@@ -331,4 +331,30 @@
   opCondBranch(cUnit, ccode, taken);
 }
 
+void genNegFloat(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValue(cUnit, rlSrc, kCoreReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opRegRegImm(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, 0x80000000);
+  storeValue(cUnit, rlDest, rlResult);
+}
+
+void genNegDouble(CompilationUnit *cUnit, RegLocation rlDest, RegLocation rlSrc)
+{
+  RegLocation rlResult;
+  rlSrc = loadValueWide(cUnit, rlSrc, kCoreReg);
+  rlResult = oatEvalLoc(cUnit, rlDest, kCoreReg, true);
+  opRegRegImm(cUnit, kOpAdd, rlResult.highReg, rlSrc.highReg, 0x80000000);
+  opRegCopy(cUnit, rlResult.lowReg, rlSrc.lowReg);
+  storeValueWide(cUnit, rlDest, rlResult);
+}
+
+bool genInlinedSqrt(CompilationUnit* cUnit, CallInfo* info) {
+  DCHECK_NE(cUnit->instructionSet, kThumb2);
+  return false;
+}
+
+
+
 } //  namespace art
diff --git a/src/compiler/codegen/x86/int_x86.cc b/src/compiler/codegen/x86/int_x86.cc
new file mode 100644
index 0000000..1673b55
--- /dev/null
+++ b/src/compiler/codegen/x86/int_x86.cc
@@ -0,0 +1,434 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file contains codegen for the X86 ISA */
+
+namespace art {
+
+/*
+ * Perform register memory operation.
+ */
+LIR* genRegMemCheck(CompilationUnit* cUnit, ConditionCode cCode,
+                    int reg1, int base, int offset, ThrowKind kind)
+{
+  LIR* tgt = rawLIR(cUnit, 0, kPseudoThrowTarget, kind,
+                    cUnit->currentDalvikOffset, reg1, base, offset);
+  opRegMem(cUnit, kOpCmp, reg1, base, offset);
+  LIR* branch = opCondBranch(cUnit, cCode, tgt);
+  // Remember branch target - will process later
+  oatInsertGrowableList(cUnit, &cUnit->throwLaunchpads, (intptr_t)tgt);
+  return branch;
+}
+
+/*
+ * Compare two 64-bit values
+ *    x = y     return  0
+ *    x < y     return -1
+ *    x > y     return  1
+ *
+ *    slt   t0,  x.hi, y.hi;        # (x.hi < y.hi) ? 1:0
+ *    sgt   t1,  x.hi, y.hi;        # (y.hi > x.hi) ? 1:0
+ *    subu  res, t0, t1             # res = -1:1:0 for [ < > = ]
+ *    bnez  res, finish
+ *    sltu  t0, x.lo, y.lo
+ *    sgtu  r1, x.lo, y.lo
+ *    subu  res, t0, t1
+ * finish:
+ *
+ */
+void genCmpLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) - (r3:r2)
+  opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
+  newLIR2(cUnit, kX86Set8R, r2, kX86CondL);  // r2 = (r1:r0) < (r3:r2) ? 1 : 0
+  newLIR2(cUnit, kX86Movzx8RR, r2, r2);
+  opReg(cUnit, kOpNeg, r2);         // r2 = -r2
+  opRegReg(cUnit, kOpOr, r0, r1);   // r0 = high | low - sets ZF
+  newLIR2(cUnit, kX86Set8R, r0, kX86CondNz);  // r0 = (r1:r0) != (r3:r2) ? 1 : 0
+  newLIR2(cUnit, kX86Movzx8RR, r0, r0);
+  opRegReg(cUnit, kOpOr, r0, r2);   // r0 = r0 | r2
+  RegLocation rlResult = locCReturn();
+  storeValue(cUnit, rlDest, rlResult);
+}
+
+X86ConditionCode oatX86ConditionEncoding(ConditionCode cond) {
+  switch (cond) {
+    case kCondEq: return kX86CondEq;
+    case kCondNe: return kX86CondNe;
+    case kCondCs: return kX86CondC;
+    case kCondCc: return kX86CondNc;
+    case kCondMi: return kX86CondS;
+    case kCondPl: return kX86CondNs;
+    case kCondVs: return kX86CondO;
+    case kCondVc: return kX86CondNo;
+    case kCondHi: return kX86CondA;
+    case kCondLs: return kX86CondBe;
+    case kCondGe: return kX86CondGe;
+    case kCondLt: return kX86CondL;
+    case kCondGt: return kX86CondG;
+    case kCondLe: return kX86CondLe;
+    case kCondAl:
+    case kCondNv: LOG(FATAL) << "Should not reach here";
+  }
+  return kX86CondO;
+}
+
+LIR* opCmpBranch(CompilationUnit* cUnit, ConditionCode cond, int src1,
+                 int src2, LIR* target)
+{
+  newLIR2(cUnit, kX86Cmp32RR, src1, src2);
+  X86ConditionCode cc = oatX86ConditionEncoding(cond);
+  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0 /* lir operand for Jcc offset */ ,
+                        cc);
+  branch->target = target;
+  return branch;
+}
+
+LIR* opCmpImmBranch(CompilationUnit* cUnit, ConditionCode cond, int reg,
+                    int checkValue, LIR* target)
+{
+  if ((checkValue == 0) && (cond == kCondEq || cond == kCondNe)) {
+    // TODO: when checkValue == 0 and reg is rCX, use the jcxz/nz opcode
+    newLIR2(cUnit, kX86Test32RR, reg, reg);
+  } else {
+    newLIR2(cUnit, IS_SIMM8(checkValue) ? kX86Cmp32RI8 : kX86Cmp32RI, reg, checkValue);
+  }
+  X86ConditionCode cc = oatX86ConditionEncoding(cond);
+  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0 /* lir operand for Jcc offset */ , cc);
+  branch->target = target;
+  return branch;
+}
+
+LIR* opRegCopyNoInsert(CompilationUnit *cUnit, int rDest, int rSrc)
+{
+  if (X86_FPREG(rDest) || X86_FPREG(rSrc))
+    return fpRegCopy(cUnit, rDest, rSrc);
+  LIR* res = rawLIR(cUnit, cUnit->currentDalvikOffset, kX86Mov32RR,
+                    rDest, rSrc);
+  if (rDest == rSrc) {
+    res->flags.isNop = true;
+  }
+  return res;
+}
+
+LIR* opRegCopy(CompilationUnit *cUnit, int rDest, int rSrc)
+{
+  LIR *res = opRegCopyNoInsert(cUnit, rDest, rSrc);
+  oatAppendLIR(cUnit, res);
+  return res;
+}
+
+void opRegCopyWide(CompilationUnit *cUnit, int destLo, int destHi,
+                   int srcLo, int srcHi)
+{
+  bool destFP = X86_FPREG(destLo) && X86_FPREG(destHi);
+  bool srcFP = X86_FPREG(srcLo) && X86_FPREG(srcHi);
+  assert(X86_FPREG(srcLo) == X86_FPREG(srcHi));
+  assert(X86_FPREG(destLo) == X86_FPREG(destHi));
+  if (destFP) {
+    if (srcFP) {
+      opRegCopy(cUnit, s2d(destLo, destHi), s2d(srcLo, srcHi));
+    } else {
+      // TODO: Prevent this from happening in the code. The result is often
+      // unused or could have been loaded more easily from memory.
+      newLIR2(cUnit, kX86MovdxrRR, destLo, srcLo);
+      newLIR2(cUnit, kX86MovdxrRR, destHi, srcHi);
+      newLIR2(cUnit, kX86PsllqRI, destHi, 32);
+      newLIR2(cUnit, kX86OrpsRR, destLo, destHi);
+    }
+  } else {
+    if (srcFP) {
+      newLIR2(cUnit, kX86MovdrxRR, destLo, srcLo);
+      newLIR2(cUnit, kX86PsrlqRI, srcLo, 32);
+      newLIR2(cUnit, kX86MovdrxRR, destHi, srcLo);
+    } else {
+      // Handle overlap
+      if (srcHi == destLo) {
+        opRegCopy(cUnit, destHi, srcHi);
+        opRegCopy(cUnit, destLo, srcLo);
+      } else {
+        opRegCopy(cUnit, destLo, srcLo);
+        opRegCopy(cUnit, destHi, srcHi);
+      }
+    }
+  }
+}
+
+void genFusedLongCmpBranch(CompilationUnit* cUnit, BasicBlock* bb, MIR* mir) {
+  LIR* labelList = cUnit->blockLabelList;
+  LIR* taken = &labelList[bb->taken->id];
+  RegLocation rlSrc1 = oatGetSrcWide(cUnit, mir, 0);
+  RegLocation rlSrc2 = oatGetSrcWide(cUnit, mir, 2);
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  ConditionCode ccode = static_cast<ConditionCode>(mir->dalvikInsn.arg[0]);
+  // Swap operands and condition code to prevent use of zero flag.
+  if (ccode == kCondLe || ccode == kCondGt) {
+    // Compute (r3:r2) = (r3:r2) - (r1:r0)
+    opRegReg(cUnit, kOpSub, r2, r0);  // r2 = r2 - r0
+    opRegReg(cUnit, kOpSbc, r3, r1);  // r3 = r3 - r1 - CF
+  } else {
+    // Compute (r1:r0) = (r1:r0) - (r3:r2)
+    opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
+    opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
+  }
+  switch (ccode) {
+    case kCondEq:
+    case kCondNe:
+      opRegReg(cUnit, kOpOr, r0, r1);  // r0 = r0 | r1
+      break;
+    case kCondLe:
+      ccode = kCondGe;
+      break;
+    case kCondGt:
+      ccode = kCondLt;
+      break;
+    case kCondLt:
+    case kCondGe:
+      break;
+    default:
+      LOG(FATAL) << "Unexpected ccode: " << (int)ccode;
+  }
+  opCondBranch(cUnit, ccode, taken);
+}
+RegLocation genDivRemLit(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int lit, bool isDiv)
+{
+  LOG(FATAL) << "Unexpected use of genDivRemLit for x86";
+  return rlDest;
+}
+
+RegLocation genDivRem(CompilationUnit* cUnit, RegLocation rlDest, int regLo, int regHi, bool isDiv)
+{
+  LOG(FATAL) << "Unexpected use of genDivRem for x86";
+  return rlDest;
+}
+
+bool genInlinedMinMaxInt(CompilationUnit *cUnit, CallInfo* info, bool isMin)
+{
+  DCHECK_EQ(cUnit->instructionSet, kX86);
+  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);
+  DCHECK_EQ(cUnit->instructionSet, kX86);
+  LIR* branch = newLIR2(cUnit, kX86Jcc8, 0, isMin ? kX86CondG : kX86CondL);
+  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc1.lowReg);
+  LIR* branch2 = newLIR1(cUnit, kX86Jmp8, 0);
+  branch->target = newLIR0(cUnit, kPseudoTargetLabel);
+  opRegReg(cUnit, kOpMov, rlResult.lowReg, rlSrc2.lowReg);
+  branch2->target = newLIR0(cUnit, kPseudoTargetLabel);
+  storeValue(cUnit, rlDest, rlResult);
+  return true;
+}
+
+void opLea(CompilationUnit* cUnit, int rBase, int reg1, int reg2, int scale, int offset)
+{
+  newLIR5(cUnit, kX86Lea32RA, rBase, reg1, reg2, scale, offset);
+}
+
+void opTlsCmp(CompilationUnit* cUnit, int offset, int val)
+{
+  newLIR2(cUnit, kX86Cmp16TI8, offset, val);
+}
+
+bool genInlinedCas32(CompilationUnit* cUnit, CallInfo* info, bool need_write_barrier) {
+  DCHECK_NE(cUnit->instructionSet, kThumb2);
+  return false;
+}
+
+LIR* opPcRelLoad(CompilationUnit* cUnit, int reg, LIR* target) {
+  LOG(FATAL) << "Unexpected use of opPcRelLoad for x86";
+  return NULL;
+}
+
+LIR* opVldm(CompilationUnit* cUnit, int rBase, int count)
+{
+  LOG(FATAL) << "Unexpected use of opVldm for x86";
+  return NULL;
+}
+
+LIR* opVstm(CompilationUnit* cUnit, int rBase, int count)
+{
+  LOG(FATAL) << "Unexpected use of opVstm for x86";
+  return NULL;
+}
+
+void genMultiplyByTwoBitMultiplier(CompilationUnit* cUnit, RegLocation rlSrc,
+                                   RegLocation rlResult, int lit,
+                                   int firstBit, int secondBit)
+{
+  int tReg = oatAllocTemp(cUnit);
+  opRegRegImm(cUnit, kOpLsl, tReg, rlSrc.lowReg, secondBit - firstBit);
+  opRegRegReg(cUnit, kOpAdd, rlResult.lowReg, rlSrc.lowReg, tReg);
+  oatFreeTemp(cUnit, tReg);
+  if (firstBit != 0) {
+    opRegRegImm(cUnit, kOpLsl, rlResult.lowReg, rlResult.lowReg, firstBit);
+  }
+}
+
+void genDivZeroCheck(CompilationUnit* cUnit, int regLo, int regHi)
+{
+  int tReg = oatAllocTemp(cUnit);
+  opRegRegReg(cUnit, kOpOr, tReg, regLo, regHi);
+  genImmedCheck(cUnit, kCondEq, tReg, 0, kThrowDivZero);
+  oatFreeTemp(cUnit, tReg);
+}
+
+// Test suspend flag, return target of taken suspend branch
+LIR* opTestSuspend(CompilationUnit* cUnit, LIR* target)
+{
+  opTlsCmp(cUnit, Thread::ThreadFlagsOffset().Int32Value(), 0);
+  return opCondBranch(cUnit, (target == NULL) ? kCondNe : kCondEq, target);
+}
+
+// Decrement register and branch on condition
+LIR* opDecAndBranch(CompilationUnit* cUnit, ConditionCode cCode, int reg, LIR* target)
+{
+  opRegImm(cUnit, kOpSub, reg, 1);
+  return opCmpImmBranch(cUnit, cCode, reg, 0, target);
+}
+
+bool smallLiteralDivide(CompilationUnit* cUnit, Instruction::Code dalvikOpcode,
+                        RegLocation rlSrc, RegLocation rlDest, int lit)
+{
+  LOG(FATAL) << "Unexpected use of smallLiteralDive in x86";
+  return false;
+}
+
+LIR* opIT(CompilationUnit* cUnit, ArmConditionCode cond, const char* guide)
+{
+  LOG(FATAL) << "Unexpected use of opIT in x86";
+  return NULL;
+}
+bool genAddLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpAdd, r0, r2);  // r0 = r0 + r2
+  opRegReg(cUnit, kOpAdc, r1, r3);  // r1 = r1 + r3 + CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genSubLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpSub, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpSbc, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genAndLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpAnd, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpAnd, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genOrLong(CompilationUnit* cUnit, RegLocation rlDest,
+               RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpOr, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpOr, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genXorLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc1, RegLocation rlSrc2)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc1, r0, r1);
+  loadValueDirectWideFixed(cUnit, rlSrc2, r2, r3);
+  // Compute (r1:r0) = (r1:r0) + (r2:r3)
+  opRegReg(cUnit, kOpXor, r0, r2);  // r0 = r0 - r2
+  opRegReg(cUnit, kOpXor, r1, r3);  // r1 = r1 - r3 - CF
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+bool genNegLong(CompilationUnit* cUnit, RegLocation rlDest,
+                RegLocation rlSrc)
+{
+  oatFlushAllRegs(cUnit);
+  oatLockCallTemps(cUnit);  // Prepare for explicit register usage
+  loadValueDirectWideFixed(cUnit, rlSrc, r0, r1);
+  // Compute (r1:r0) = -(r1:r0)
+  opRegReg(cUnit, kOpNeg, r0, r0);  // r0 = -r0
+  opRegImm(cUnit, kOpAdc, r1, 0);   // r1 = r1 + CF
+  opRegReg(cUnit, kOpNeg, r1, r1);  // r1 = -r1
+  RegLocation rlResult = {kLocPhysReg, 1, 0, 0, 0, 0, 0, 0, 1, r0, r1,
+                          INVALID_SREG, INVALID_SREG};
+  storeValueWide(cUnit, rlDest, rlResult);
+  return false;
+}
+
+void opRegThreadMem(CompilationUnit* cUnit, OpKind op, int rDest, int threadOffset) {
+  X86OpCode opcode = kX86Bkpt;
+  switch (op) {
+  case kOpCmp: opcode = kX86Cmp32RT;  break;
+  default:
+    LOG(FATAL) << "Bad opcode: " << op;
+    break;
+  }
+  newLIR2(cUnit, opcode, rDest, threadOffset);
+}
+
+}  // namespace art
diff --git a/src/compiler/codegen/x86/target_x86.cc b/src/compiler/codegen/x86/target_x86.cc
new file mode 100644
index 0000000..a211c2f
--- /dev/null
+++ b/src/compiler/codegen/x86/target_x86.cc
@@ -0,0 +1,664 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "../../compiler_internals.h"
+#include "x86_lir.h"
+#include "../ralloc.h"
+
+#include <string>
+
+namespace art {
+
+//FIXME: restore "static" when usage uncovered
+/*static*/ int coreRegs[] = {
+  rAX, rCX, rDX, rBX, rX86_SP, rBP, rSI, rDI
+#ifdef TARGET_REX_SUPPORT
+  r8, r9, r10, r11, r12, r13, r14, 15
+#endif
+};
+/*static*/ int reservedRegs[] = {rX86_SP};
+/*static*/ int coreTemps[] = {rAX, rCX, rDX, rBX};
+/*static*/ int fpRegs[] = {
+  fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
+#ifdef TARGET_REX_SUPPORT
+  fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15
+#endif
+};
+/*static*/ int fpTemps[] = {
+  fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
+#ifdef TARGET_REX_SUPPORT
+  fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15
+#endif
+};
+
+RegLocation locCReturn()
+{
+  RegLocation res = X86_LOC_C_RETURN;
+  return res;
+}
+
+RegLocation locCReturnWide()
+{
+  RegLocation res = X86_LOC_C_RETURN_WIDE;
+  return res;
+}
+
+RegLocation locCReturnFloat()
+{
+  RegLocation res = X86_LOC_C_RETURN_FLOAT;
+  return res;
+}
+
+RegLocation locCReturnDouble()
+{
+  RegLocation res = X86_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 = rX86_SELF; break;
+    case kSuspend: res =  rX86_SUSPEND; break;
+    case kLr: res =  rX86_LR; break;
+    case kPc: res =  rX86_PC; break;
+    case kSp: res =  rX86_SP; break;
+    case kArg0: res = rX86_ARG0; break;
+    case kArg1: res = rX86_ARG1; break;
+    case kArg2: res = rX86_ARG2; break;
+    case kArg3: res = rX86_ARG3; break;
+    case kFArg0: res = rX86_FARG0; break;
+    case kFArg1: res = rX86_FARG1; break;
+    case kFArg2: res = rX86_FARG2; break;
+    case kFArg3: res = rX86_FARG3; break;
+    case kRet0: res = rX86_RET0; break;
+    case kRet1: res = rX86_RET1; break;
+    case kInvokeTgt: res = rX86_INVOKE_TGT; break;
+    case kCount: res = rX86_COUNT; break;
+  }
+  return res;
+}
+
+// Create a double from a pair of singles.
+int s2d(int lowReg, int highReg)
+{
+  return X86_S2D(lowReg, highReg);
+}
+
+// Is reg a single or double?
+bool fpReg(int reg)
+{
+  return X86_FPREG(reg);
+}
+
+// Is reg a single?
+bool singleReg(int reg)
+{
+  return X86_SINGLEREG(reg);
+}
+
+// Is reg a double?
+bool doubleReg(int reg)
+{
+  return X86_DOUBLEREG(reg);
+}
+
+// Return mask to strip off fp reg flags and bias.
+uint32_t fpRegMask()
+{
+  return X86_FP_REG_MASK;
+}
+
+// True if both regs single, both core or both double.
+bool sameRegType(int reg1, int reg2)
+{
+  return (X86_REGTYPE(reg1) == X86_REGTYPE(reg2));
+}
+
+/*
+ * Decode the register id.
+ */
+u8 getRegMaskCommon(CompilationUnit* cUnit, int reg)
+{
+  u8 seed;
+  int shift;
+  int regId;
+
+  regId = reg & 0xf;
+  /* Double registers in x86 are just a single FP register */
+  seed = 1;
+  /* FP register starts at bit position 16 */
+  shift = X86_FPREG(reg) ? kX86FPReg0 : 0;
+  /* Expand the double register id into single offset */
+  shift += regId;
+  return (seed << shift);
+}
+
+uint64_t getPCUseDefEncoding()
+{
+  /*
+   * FIXME: might make sense to use a virtual resource encoding bit for pc.  Might be
+   * able to clean up some of the x86/Arm_Mips differences
+   */
+  LOG(FATAL) << "Unexpected call to getPCUseDefEncoding for x86";
+  return 0ULL;
+}
+
+void setupTargetResourceMasks(CompilationUnit* cUnit, LIR* lir)
+{
+  DCHECK_EQ(cUnit->instructionSet, kX86);
+
+  // X86-specific resource map setup here.
+  uint64_t flags = EncodingMap[lir->opcode].flags;
+
+  if (flags & REG_USE_SP) {
+    lir->useMask |= ENCODE_X86_REG_SP;
+  }
+
+  if (flags & REG_DEF_SP) {
+    lir->defMask |= ENCODE_X86_REG_SP;
+  }
+
+  if (flags & REG_DEFA) {
+    oatSetupRegMask(cUnit, &lir->defMask, rAX);
+  }
+
+  if (flags & REG_DEFD) {
+    oatSetupRegMask(cUnit, &lir->defMask, rDX);
+  }
+  if (flags & REG_USEA) {
+    oatSetupRegMask(cUnit, &lir->useMask, rAX);
+  }
+
+  if (flags & REG_USEC) {
+    oatSetupRegMask(cUnit, &lir->useMask, rCX);
+  }
+
+  if (flags & REG_USED) {
+    oatSetupRegMask(cUnit, &lir->useMask, rDX);
+  }
+}
+
+/* For dumping instructions */
+static const char* x86RegName[] = {
+  "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
+  "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+};
+
+static const char* x86CondName[] = {
+  "O",
+  "NO",
+  "B/NAE/C",
+  "NB/AE/NC",
+  "Z/EQ",
+  "NZ/NE",
+  "BE/NA",
+  "NBE/A",
+  "S",
+  "NS",
+  "P/PE",
+  "NP/PO",
+  "L/NGE",
+  "NL/GE",
+  "LE/NG",
+  "NLE/G"
+};
+
+/*
+ * Interpret a format string and build a string no longer than size
+ * See format key in Assemble.cc.
+ */
+std::string buildInsnString(const char *fmt, LIR *lir, unsigned char* baseAddr) {
+  std::string buf;
+  size_t i = 0;
+  size_t fmt_len = strlen(fmt);
+  while (i < fmt_len) {
+    if (fmt[i] != '!') {
+      buf += fmt[i];
+      i++;
+    } else {
+      i++;
+      DCHECK_LT(i, fmt_len);
+      char operand_number_ch = fmt[i];
+      i++;
+      if (operand_number_ch == '!') {
+        buf += "!";
+      } else {
+        int operand_number = operand_number_ch - '0';
+        DCHECK_LT(operand_number, 6);  // Expect upto 6 LIR operands.
+        DCHECK_LT(i, fmt_len);
+        int operand = lir->operands[operand_number];
+        switch (fmt[i]) {
+          case 'c':
+            DCHECK_LT(static_cast<size_t>(operand), sizeof(x86CondName));
+            buf += x86CondName[operand];
+            break;
+          case 'd':
+            buf += StringPrintf("%d", operand);
+            break;
+          case 'p': {
+            SwitchTable *tabRec = reinterpret_cast<SwitchTable*>(operand);
+            buf += StringPrintf("0x%08x", tabRec->offset);
+            break;
+          }
+          case 'r':
+            if (X86_FPREG(operand) || X86_DOUBLEREG(operand)) {
+              int fp_reg = operand & X86_FP_REG_MASK;
+              buf += StringPrintf("xmm%d", fp_reg);
+            } else {
+              DCHECK_LT(static_cast<size_t>(operand), sizeof(x86RegName));
+              buf += x86RegName[operand];
+            }
+            break;
+          case 't':
+            buf += StringPrintf("0x%08x (L%p)",
+                                reinterpret_cast<uint32_t>(baseAddr)
+                                + lir->offset + operand, lir->target);
+            break;
+          default:
+            buf += StringPrintf("DecodeError '%c'", fmt[i]);
+            break;
+        }
+        i++;
+      }
+    }
+  }
+  return buf;
+}
+
+void oatDumpResourceMask(LIR *lir, u8 mask, const char *prefix)
+{
+  char buf[256];
+  buf[0] = 0;
+  LIR *x86LIR = (LIR *) lir;
+
+  if (mask == ENCODE_ALL) {
+    strcpy(buf, "all");
+  } else {
+    char num[8];
+    int i;
+
+    for (i = 0; i < kX86RegEnd; i++) {
+      if (mask & (1ULL << i)) {
+        sprintf(num, "%d ", i);
+        strcat(buf, num);
+      }
+    }
+
+    if (mask & ENCODE_CCODE) {
+      strcat(buf, "cc ");
+    }
+    /* Memory bits */
+    if (x86LIR && (mask & ENCODE_DALVIK_REG)) {
+      sprintf(buf + strlen(buf), "dr%d%s", x86LIR->aliasInfo & 0xffff,
+              (x86LIR->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;
+  }
+}
+void oatAdjustSpillMask(CompilationUnit* cUnit) {
+  // Adjustment for LR spilling, x86 has no LR so nothing to do here
+  cUnit->coreSpillMask |= (1 << rRET);
+  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)
+{
+  UNIMPLEMENTED(WARNING) << "oatMarkPreservedSingle";
+#if 0
+  LOG(FATAL) << "No support yet for promoted FP regs";
+#endif
+}
+
+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, rX86_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, rX86_SP, oatVRegOffset(cUnit, vReg), reg, kWord);
+  }
+}
+
+/* Give access to the target-dependent FP register encoding to common code */
+bool oatIsFpReg(int reg) {
+  return X86_FPREG(reg);
+}
+
+uint32_t oatFpRegMask() {
+  return X86_FP_REG_MASK;
+}
+
+/* Clobber all regs that might be used by an external C call */
+extern void oatClobberCalleeSave(CompilationUnit *cUnit)
+{
+  oatClobber(cUnit, rAX);
+  oatClobber(cUnit, rCX);
+  oatClobber(cUnit, rDX);
+}
+
+extern RegLocation oatGetReturnWideAlt(CompilationUnit* cUnit) {
+  RegLocation res = locCReturnWide();
+  CHECK(res.lowReg == rAX);
+  CHECK(res.highReg == rDX);
+  oatClobber(cUnit, rAX);
+  oatClobber(cUnit, rDX);
+  oatMarkInUse(cUnit, rAX);
+  oatMarkInUse(cUnit, rDX);
+  oatMarkPair(cUnit, res.lowReg, res.highReg);
+  return res;
+}
+
+extern RegLocation oatGetReturnAlt(CompilationUnit* cUnit)
+{
+  RegLocation res = locCReturn();
+  res.lowReg = rDX;
+  oatClobber(cUnit, rDX);
+  oatMarkInUse(cUnit, rDX);
+  return res;
+}
+
+extern RegisterInfo* oatGetRegInfo(CompilationUnit* cUnit, int reg)
+{
+  return X86_FPREG(reg) ? &cUnit->regPool->FPRegs[reg & X86_FP_REG_MASK]
+                    : &cUnit->regPool->coreRegs[reg];
+}
+
+/* To be used when explicitly managing register use */
+extern void oatLockCallTemps(CompilationUnit* cUnit)
+{
+  oatLockTemp(cUnit, rX86_ARG0);
+  oatLockTemp(cUnit, rX86_ARG1);
+  oatLockTemp(cUnit, rX86_ARG2);
+  oatLockTemp(cUnit, rX86_ARG3);
+}
+
+/* To be used when explicitly managing register use */
+extern void oatFreeCallTemps(CompilationUnit* cUnit)
+{
+  oatFreeTemp(cUnit, rX86_ARG0);
+  oatFreeTemp(cUnit, rX86_ARG1);
+  oatFreeTemp(cUnit, rX86_ARG2);
+  oatFreeTemp(cUnit, rX86_ARG3);
+}
+
+/* Convert an instruction to a NOP */
+void oatNopLIR( LIR* lir)
+{
+  ((LIR*)lir)->flags.isNop = true;
+}
+
+/*
+ * Determine the initial instruction set to be used for this trace.
+ * Later components may decide to change this.
+ */
+InstructionSet oatInstructionSet()
+{
+  return kX86;
+}
+
+/* Architecture-specific initializations and checks go here */
+bool oatArchVariantInit(void)
+{
+  return true;
+}
+
+int dvmCompilerTargetOptHint(int key)
+{
+  int res;
+  switch (key) {
+    case kMaxHoistDistance:
+      res = 2;
+      break;
+    default:
+      LOG(FATAL) << "Unknown target optimization hint key: " << key;
+  }
+  return res;
+}
+
+void oatGenMemBarrier(CompilationUnit *cUnit, int /* barrierKind */)
+{
+#if ANDROID_SMP != 0
+  // TODO: optimize fences
+  newLIR0(cUnit, kX86Mfence);
+#endif
+}
+/*
+ * 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;
+    res = (lowReg & 0xff) | ((highReg & 0xff) << 8);
+    return res;
+  }
+
+  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++) {
+    oatMarkInUse(cUnit, reservedRegs[i]);
+  }
+  // Mark temp regs - all others not in use can be used for promotion
+  for (int i = 0; i < numTemps; i++) {
+    oatMarkTemp(cUnit, coreTemps[i]);
+  }
+  for (int i = 0; i < numFPTemps; i++) {
+    oatMarkTemp(cUnit, fpTemps[i]);
+  }
+  // Construct the alias map.
+  cUnit->phiAliasMap = (int*)oatNew(cUnit, cUnit->numSSARegs *
+                                    sizeof(cUnit->phiAliasMap[0]), false,
+                                    kAllocDFInfo);
+  for (int i = 0; i < cUnit->numSSARegs; i++) {
+    cUnit->phiAliasMap[i] = i;
+  }
+  for (MIR* phi = cUnit->phiList; phi; phi = phi->meta.phiNext) {
+    int defReg = phi->ssaRep->defs[0];
+    for (int i = 0; i < phi->ssaRep->numUses; i++) {
+      for (int j = 0; j < cUnit->numSSARegs; j++) {
+        if (cUnit->phiAliasMap[j] == phi->ssaRep->uses[i]) {
+          cUnit->phiAliasMap[j] = defReg;
+        }
+      }
+    }
+  }
+}
+
+void freeRegLocTemps(CompilationUnit* cUnit, RegLocation rlKeep,
+                     RegLocation rlFree)
+{
+  if ((rlFree.lowReg != rlKeep.lowReg) && (rlFree.lowReg != rlKeep.highReg) &&
+      (rlFree.highReg != rlKeep.lowReg) && (rlFree.highReg != rlKeep.highReg)) {
+    // No overlap, free both
+    oatFreeTemp(cUnit, rlFree.lowReg);
+    oatFreeTemp(cUnit, rlFree.highReg);
+  }
+}
+
+void spillCoreRegs(CompilationUnit* cUnit) {
+  if (cUnit->numCoreSpills == 0) {
+    return;
+  }
+  // Spill mask not including fake return address register
+  uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
+  int offset = cUnit->frameSize - (4 * cUnit->numCoreSpills);
+  for (int reg = 0; mask; mask >>= 1, reg++) {
+    if (mask & 0x1) {
+      storeWordDisp(cUnit, rX86_SP, offset, reg);
+      offset += 4;
+    }
+  }
+}
+
+void unSpillCoreRegs(CompilationUnit* cUnit) {
+  if (cUnit->numCoreSpills == 0) {
+    return;
+  }
+  // Spill mask not including fake return address register
+  uint32_t mask = cUnit->coreSpillMask & ~(1 << rRET);
+  int offset = cUnit->frameSize - (4 * cUnit->numCoreSpills);
+  for (int reg = 0; mask; mask >>= 1, reg++) {
+    if (mask & 0x1) {
+      loadWordDisp(cUnit, rX86_SP, offset, reg);
+      offset += 4;
+    }
+  }
+}
+
+/*
+ * 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 == kX86Jmp8 || thisLIR->opcode == kX86Jmp32) {
+    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 < kX86Last; 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();
+}
+
+// Not used in x86
+int loadHelper(CompilationUnit* cUnit, int offset)
+{
+  LOG(FATAL) << "Unexpected use of loadHelper in x86";
+  return INVALID_REG;
+}
+
+} // namespace art
diff --git a/src/compiler/codegen/x86/X86/Factory.cc b/src/compiler/codegen/x86/utility_x86.cc
similarity index 96%
rename from src/compiler/codegen/x86/X86/Factory.cc
rename to src/compiler/codegen/x86/utility_x86.cc
index 454b98d..418a6fe 100644
--- a/src/compiler/codegen/x86/X86/Factory.cc
+++ b/src/compiler/codegen/x86/utility_x86.cc
@@ -18,28 +18,6 @@
 
 /* This file contains codegen for the X86 ISA */
 
-//FIXME: restore "static" when usage uncovered
-/*static*/ int coreRegs[] = {
-  rAX, rCX, rDX, rBX, rX86_SP, rBP, rSI, rDI
-#ifdef TARGET_REX_SUPPORT
-  r8, r9, r10, r11, r12, r13, r14, 15
-#endif
-};
-/*static*/ int reservedRegs[] = {rX86_SP};
-/*static*/ int coreTemps[] = {rAX, rCX, rDX, rBX};
-/*static*/ int fpRegs[] = {
-  fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
-#ifdef TARGET_REX_SUPPORT
-  fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15
-#endif
-};
-/*static*/ int fpTemps[] = {
-  fr0, fr1, fr2, fr3, fr4, fr5, fr6, fr7,
-#ifdef TARGET_REX_SUPPORT
-  fr8, fr9, fr10, fr11, fr12, fr13, fr14, fr15
-#endif
-};
-
 void genBarrier(CompilationUnit *cUnit);
 void loadPair(CompilationUnit *cUnit, int base, int lowReg, int highReg);
 LIR *loadWordDisp(CompilationUnit *cUnit, int rBase, int displacement,
diff --git a/src/compiler/codegen/x86/x86/ArchVariant.cc b/src/compiler/codegen/x86/x86/ArchVariant.cc
deleted file mode 100644
index 4b70202..0000000
--- a/src/compiler/codegen/x86/x86/ArchVariant.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-namespace art {
-
-/*
- * This file is included by Codegen-x86.c, and implements architecture
- * variant-specific code.
- */
-
-/*
- * Determine the initial instruction set to be used for this trace.
- * Later components may decide to change this.
- */
-InstructionSet oatInstructionSet()
-{
-  return kX86;
-}
-
-/* Architecture-specific initializations and checks go here */
-bool oatArchVariantInit(void)
-{
-  return true;
-}
-
-int dvmCompilerTargetOptHint(int key)
-{
-  int res;
-  switch (key) {
-    case kMaxHoistDistance:
-      res = 2;
-      break;
-    default:
-      LOG(FATAL) << "Unknown target optimization hint key: " << key;
-  }
-  return res;
-}
-
-void oatGenMemBarrier(CompilationUnit *cUnit, int /* barrierKind */)
-{
-#if ANDROID_SMP != 0
-  // TODO: optimize fences
-  newLIR0(cUnit, kX86Mfence);
-#endif
-}
-
-}  // namespace art
diff --git a/src/compiler/codegen/x86/x86/Codegen.cc b/src/compiler/codegen/x86/x86/Codegen.cc
deleted file mode 100644
index 744a7d2..0000000
--- a/src/compiler/codegen/x86/x86/Codegen.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define _CODEGEN_C
-
-#include "../../../Dalvik.h"
-#include "../../../CompilerInternals.h"
-#include "../X86LIR.h"
-#include "../../Ralloc.h"
-#include "../Codegen.h"
-
-/* X86 codegen building blocks */
-#include "../../CodegenUtil.cc"
-
-/* X86-specific factory utilities */
-#include "../X86/Factory.cc"
-/* Target independent factory utilities */
-#include "../../CodegenFactory.cc"
-/* X86-specific codegen routines */
-#include "../X86/Gen.cc"
-/* FP codegen routines */
-#include "../FP/X86FP.cc"
-/* Target independent gen routines */
-#include "../../GenCommon.cc"
-/* Shared invoke gen routines */
-#include "../../GenInvoke.cc"
-/* X86-specific factory utilities */
-#include "../ArchFactory.cc"
-
-/* X86-specific register allocation */
-#include "../X86/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/x86/X86LIR.h b/src/compiler/codegen/x86/x86_lir.h
similarity index 99%
rename from src/compiler/codegen/x86/X86LIR.h
rename to src/compiler/codegen/x86/x86_lir.h
index bccd365..fe6d8cb 100644
--- a/src/compiler/codegen/x86/X86LIR.h
+++ b/src/compiler/codegen/x86/x86_lir.h
@@ -17,8 +17,8 @@
 #ifndef ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_
 #define ART_COMPILER_COMPILER_CODEGEN_X86_X86LIR_H_
 
-#include "../../Dalvik.h"
-#include "../../CompilerInternals.h"
+#include "../../dalvik.h"
+#include "../../compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler/CompilerInternals.h b/src/compiler/compiler_internals.h
similarity index 86%
rename from src/compiler/CompilerInternals.h
rename to src/compiler/compiler_internals.h
index 7cad878..2f81afe 100644
--- a/src/compiler/CompilerInternals.h
+++ b/src/compiler/compiler_internals.h
@@ -17,9 +17,9 @@
 #ifndef ART_SRC_COMPILER_COMPILER_INTERNAL_H_
 #define ART_SRC_COMPILER_COMPILER_INTERNAL_H_
 
-#include "Dalvik.h"
-#include "CompilerUtility.h"
-#include "CompilerIR.h"
-#include "codegen/CompilerCodegen.h"
+#include "dalvik.h"
+#include "compiler_utility.h"
+#include "compiler_ir.h"
+#include "codegen/compiler_codegen.h"
 
 #endif  // ART_SRC_COMPILER_COMPILER_INTERNAL_H_
diff --git a/src/compiler/CompilerIR.h b/src/compiler/compiler_ir.h
similarity index 99%
rename from src/compiler/CompilerIR.h
rename to src/compiler/compiler_ir.h
index 5de9c4e..6c6442d 100644
--- a/src/compiler/CompilerIR.h
+++ b/src/compiler/compiler_ir.h
@@ -19,8 +19,8 @@
 
 #include <vector>
 
-#include "codegen/Optimizer.h"
-#include "CompilerUtility.h"
+#include "codegen/optimizer.h"
+#include "compiler_utility.h"
 #include "oat_compilation_unit.h"
 #include "safe_map.h"
 #include "greenland/ir_builder.h"
diff --git a/src/compiler/CompilerUtility.h b/src/compiler/compiler_utility.h
similarity index 99%
rename from src/compiler/CompilerUtility.h
rename to src/compiler/compiler_utility.h
index da3a237..5dfb95f 100644
--- a/src/compiler/CompilerUtility.h
+++ b/src/compiler/compiler_utility.h
@@ -17,7 +17,7 @@
 #ifndef ART_SRC_COMPILER_COMPILER_UTILITY_H_
 #define ART_SRC_COMPILER_COMPILER_UTILITY_H_
 
-#include "Dalvik.h"
+#include "dalvik.h"
 
 namespace art {
 
diff --git a/src/compiler/Dalvik.h b/src/compiler/dalvik.h
similarity index 98%
rename from src/compiler/Dalvik.h
rename to src/compiler/dalvik.h
index 5406f53..7ceb817 100644
--- a/src/compiler/Dalvik.h
+++ b/src/compiler/dalvik.h
@@ -46,6 +46,6 @@
 typedef int64_t             s8;
 typedef unsigned long long  u8;
 
-#include "Compiler.h"
+#include "frontend.h"
 
 #endif
diff --git a/src/compiler/Dataflow.cc b/src/compiler/dataflow.cc
similarity index 99%
rename from src/compiler/Dataflow.cc
rename to src/compiler/dataflow.cc
index c59b637..a20a428 100644
--- a/src/compiler/Dataflow.cc
+++ b/src/compiler/dataflow.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "Dataflow.h"
+#include "dalvik.h"
+#include "dataflow.h"
 
 namespace art {
 
diff --git a/src/compiler/Dataflow.h b/src/compiler/dataflow.h
similarity index 98%
rename from src/compiler/Dataflow.h
rename to src/compiler/dataflow.h
index 8e99e4d..44f40c3 100644
--- a/src/compiler/Dataflow.h
+++ b/src/compiler/dataflow.h
@@ -17,8 +17,8 @@
 #ifndef ART_SRC_COMPILER_DATAFLOW_H_
 #define ART_SRC_COMPILER_DATAFLOW_H_
 
-#include "Dalvik.h"
-#include "CompilerInternals.h"
+#include "dalvik.h"
+#include "compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler/Frontend.cc b/src/compiler/frontend.cc
similarity index 99%
rename from src/compiler/Frontend.cc
rename to src/compiler/frontend.cc
index 16a7fea..d753cec 100644
--- a/src/compiler/Frontend.cc
+++ b/src/compiler/frontend.cc
@@ -14,9 +14,9 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "CompilerInternals.h"
-#include "Dataflow.h"
+#include "dalvik.h"
+#include "compiler_internals.h"
+#include "dataflow.h"
 #include "leb128.h"
 #include "object.h"
 #include "runtime.h"
diff --git a/src/compiler/Compiler.h b/src/compiler/frontend.h
similarity index 100%
rename from src/compiler/Compiler.h
rename to src/compiler/frontend.h
diff --git a/src/compiler/IntermediateRep.cc b/src/compiler/intermediate_rep.cc
similarity index 98%
rename from src/compiler/IntermediateRep.cc
rename to src/compiler/intermediate_rep.cc
index 031d3d3..96bec22 100644
--- a/src/compiler/IntermediateRep.cc
+++ b/src/compiler/intermediate_rep.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "CompilerInternals.h"
+#include "dalvik.h"
+#include "compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler/Ralloc.cc b/src/compiler/ralloc.cc
similarity index 99%
rename from src/compiler/Ralloc.cc
rename to src/compiler/ralloc.cc
index ca25b38..d9c6a57 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/ralloc.cc
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "CompilerInternals.h"
-#include "Dataflow.h"
-#include "codegen/Ralloc.h"
+#include "dalvik.h"
+#include "compiler_internals.h"
+#include "dataflow.h"
+#include "codegen/ralloc.h"
 
 namespace art {
 
diff --git a/src/compiler/SSATransformation.cc b/src/compiler/ssa_transformation.cc
similarity index 99%
rename from src/compiler/SSATransformation.cc
rename to src/compiler/ssa_transformation.cc
index f625261..09562fa 100644
--- a/src/compiler/SSATransformation.cc
+++ b/src/compiler/ssa_transformation.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "Dataflow.h"
+#include "dalvik.h"
+#include "dataflow.h"
 
 namespace art {
 
diff --git a/src/compiler/Utility.cc b/src/compiler/utility.cc
similarity index 99%
rename from src/compiler/Utility.cc
rename to src/compiler/utility.cc
index c865718..4a138c6 100644
--- a/src/compiler/Utility.cc
+++ b/src/compiler/utility.cc
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#include "Dalvik.h"
-#include "CompilerInternals.h"
+#include "dalvik.h"
+#include "compiler_internals.h"
 
 namespace art {
 
diff --git a/src/compiler_llvm/gbc_expander.cc b/src/compiler_llvm/gbc_expander.cc
index c094397..f881e70 100644
--- a/src/compiler_llvm/gbc_expander.cc
+++ b/src/compiler_llvm/gbc_expander.cc
@@ -24,7 +24,7 @@
 #include "thread.h"
 #include "verifier/method_verifier.h"
 
-#include "compiler/CompilerIR.h"
+#include "compiler/compiler_ir.h"
 using art::kMIRIgnoreNullCheck;
 using art::kMIRIgnoreRangeCheck;
 
