diff --git a/compiler/dex/quick/codegen_util.cc b/compiler/dex/quick/codegen_util.cc
new file mode 100644
index 0000000..5c10c4c
--- /dev/null
+++ b/compiler/dex/quick/codegen_util.cc
@@ -0,0 +1,1109 @@
+/*
+ * 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 "dex/compiler_internals.h"
+#include "dex_file-inl.h"
+#include "gc_map.h"
+#include "mir_to_lir-inl.h"
+#include "verifier/dex_gc_map.h"
+#include "verifier/method_verifier.h"
+
+namespace art {
+
+bool Mir2Lir::IsInexpensiveConstant(RegLocation rl_src)
+{
+  bool res = false;
+  if (rl_src.is_const) {
+    if (rl_src.wide) {
+      if (rl_src.fp) {
+         res = InexpensiveConstantDouble(mir_graph_->ConstantValueWide(rl_src));
+      } else {
+         res = InexpensiveConstantLong(mir_graph_->ConstantValueWide(rl_src));
+      }
+    } else {
+      if (rl_src.fp) {
+         res = InexpensiveConstantFloat(mir_graph_->ConstantValue(rl_src));
+      } else {
+         res = InexpensiveConstantInt(mir_graph_->ConstantValue(rl_src));
+      }
+    }
+  }
+  return res;
+}
+
+void Mir2Lir::MarkSafepointPC(LIR* inst)
+{
+  inst->def_mask = ENCODE_ALL;
+  LIR* safepoint_pc = NewLIR0(kPseudoSafepointPC);
+  DCHECK_EQ(safepoint_pc->def_mask, ENCODE_ALL);
+}
+
+bool Mir2Lir::FastInstance(uint32_t field_idx, int& field_offset, bool& is_volatile, bool is_put)
+{
+  return cu_->compiler_driver->ComputeInstanceFieldInfo(
+      field_idx, mir_graph_->GetCurrentDexCompilationUnit(), field_offset, is_volatile, is_put);
+}
+
+/* Convert an instruction to a NOP */
+void Mir2Lir::NopLIR( LIR* lir)
+{
+  lir->flags.is_nop = true;
+}
+
+void Mir2Lir::SetMemRefType(LIR* lir, bool is_load, int mem_type)
+{
+  uint64_t *mask_ptr;
+  uint64_t mask = ENCODE_MEM;;
+  DCHECK(GetTargetInstFlags(lir->opcode) & (IS_LOAD | IS_STORE));
+  if (is_load) {
+    mask_ptr = &lir->use_mask;
+  } else {
+    mask_ptr = &lir->def_mask;
+  }
+  /* Clear out the memref flags */
+  *mask_ptr &= ~mask;
+  /* ..and then add back the one we need */
+  switch (mem_type) {
+    case kLiteral:
+      DCHECK(is_load);
+      *mask_ptr |= ENCODE_LITERAL;
+      break;
+    case kDalvikReg:
+      *mask_ptr |= ENCODE_DALVIK_REG;
+      break;
+    case kHeapRef:
+      *mask_ptr |= ENCODE_HEAP_REF;
+      break;
+    case kMustNotAlias:
+      /* Currently only loads can be marked as kMustNotAlias */
+      DCHECK(!(GetTargetInstFlags(lir->opcode) & IS_STORE));
+      *mask_ptr |= ENCODE_MUST_NOT_ALIAS;
+      break;
+    default:
+      LOG(FATAL) << "Oat: invalid memref kind - " << mem_type;
+  }
+}
+
+/*
+ * Mark load/store instructions that access Dalvik registers through the stack.
+ */
+void Mir2Lir::AnnotateDalvikRegAccess(LIR* lir, int reg_id, bool is_load,
+                                      bool is64bit)
+{
+  SetMemRefType(lir, is_load, kDalvikReg);
+
+  /*
+   * Store the Dalvik register id in alias_info. Mark the MSB if it is a 64-bit
+   * access.
+   */
+  lir->alias_info = ENCODE_ALIAS_INFO(reg_id, is64bit);
+}
+
+/*
+ * Debugging macros
+ */
+#define DUMP_RESOURCE_MASK(X)
+
+/* Pretty-print a LIR instruction */
+void Mir2Lir::DumpLIRInsn(LIR* lir, unsigned char* base_addr)
+{
+  int offset = lir->offset;
+  int dest = lir->operands[0];
+  const bool dump_nop = (cu_->enable_debug & (1 << kDebugShowNops));
+
+  /* Handle pseudo-ops individually, and all regular insns as a group */
+  switch (lir->opcode) {
+    case kPseudoMethodEntry:
+      LOG(INFO) << "-------- method entry "
+                << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+      break;
+    case kPseudoMethodExit:
+      LOG(INFO) << "-------- Method_Exit";
+      break;
+    case kPseudoBarrier:
+      LOG(INFO) << "-------- BARRIER";
+      break;
+    case kPseudoEntryBlock:
+      LOG(INFO) << "-------- entry offset: 0x" << std::hex << dest;
+      break;
+    case kPseudoDalvikByteCodeBoundary:
+      if (lir->operands[0] == 0) {
+         lir->operands[0] = reinterpret_cast<uintptr_t>("No instruction string");
+      }
+      LOG(INFO) << "-------- dalvik offset: 0x" << std::hex
+                << lir->dalvik_offset << " @ " << reinterpret_cast<char*>(lir->operands[0]);
+      break;
+    case kPseudoExitBlock:
+      LOG(INFO) << "-------- exit offset: 0x" << std::hex << dest;
+      break;
+    case kPseudoPseudoAlign4:
+      LOG(INFO) << reinterpret_cast<uintptr_t>(base_addr) + offset << " (0x" << std::hex
+                << offset << "): .align4";
+      break;
+    case kPseudoEHBlockLabel:
+      LOG(INFO) << "Exception_Handling:";
+      break;
+    case kPseudoTargetLabel:
+    case kPseudoNormalBlockLabel:
+      LOG(INFO) << "L" << reinterpret_cast<void*>(lir) << ":";
+      break;
+    case kPseudoThrowTarget:
+      LOG(INFO) << "LT" << reinterpret_cast<void*>(lir) << ":";
+      break;
+    case kPseudoIntrinsicRetry:
+      LOG(INFO) << "IR" << reinterpret_cast<void*>(lir) << ":";
+      break;
+    case kPseudoSuspendTarget:
+      LOG(INFO) << "LS" << reinterpret_cast<void*>(lir) << ":";
+      break;
+    case kPseudoSafepointPC:
+      LOG(INFO) << "LsafepointPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
+      break;
+    case kPseudoExportedPC:
+      LOG(INFO) << "LexportedPC_0x" << std::hex << lir->offset << "_" << lir->dalvik_offset << ":";
+      break;
+    case kPseudoCaseLabel:
+      LOG(INFO) << "LC" << reinterpret_cast<void*>(lir) << ": Case target 0x"
+                << std::hex << lir->operands[0] << "|" << std::dec <<
+        lir->operands[0];
+      break;
+    default:
+      if (lir->flags.is_nop && !dump_nop) {
+        break;
+      } else {
+        std::string op_name(BuildInsnString(GetTargetInstName(lir->opcode),
+                                               lir, base_addr));
+        std::string op_operands(BuildInsnString(GetTargetInstFmt(lir->opcode),
+                                                    lir, base_addr));
+        LOG(INFO) << StringPrintf("%05x: %-9s%s%s",
+                                  reinterpret_cast<unsigned int>(base_addr + offset),
+                                  op_name.c_str(), op_operands.c_str(),
+                                  lir->flags.is_nop ? "(nop)" : "");
+      }
+      break;
+  }
+
+  if (lir->use_mask && (!lir->flags.is_nop || dump_nop)) {
+    DUMP_RESOURCE_MASK(DumpResourceMask((LIR* ) lir, lir->use_mask, "use"));
+  }
+  if (lir->def_mask && (!lir->flags.is_nop || dump_nop)) {
+    DUMP_RESOURCE_MASK(DumpResourceMask((LIR* ) lir, lir->def_mask, "def"));
+  }
+}
+
+void Mir2Lir::DumpPromotionMap()
+{
+  int num_regs = cu_->num_dalvik_registers + cu_->num_compiler_temps + 1;
+  for (int i = 0; i < num_regs; i++) {
+    PromotionMap v_reg_map = promotion_map_[i];
+    std::string buf;
+    if (v_reg_map.fp_location == kLocPhysReg) {
+      StringAppendF(&buf, " : s%d", v_reg_map.FpReg & FpRegMask());
+    }
+
+    std::string buf3;
+    if (i < cu_->num_dalvik_registers) {
+      StringAppendF(&buf3, "%02d", i);
+    } else if (i == mir_graph_->GetMethodSReg()) {
+      buf3 = "Method*";
+    } else {
+      StringAppendF(&buf3, "ct%d", i - cu_->num_dalvik_registers);
+    }
+
+    LOG(INFO) << StringPrintf("V[%s] -> %s%d%s", buf3.c_str(),
+                              v_reg_map.core_location == kLocPhysReg ?
+                              "r" : "SP+", v_reg_map.core_location == kLocPhysReg ?
+                              v_reg_map.core_reg : SRegOffset(i),
+                              buf.c_str());
+  }
+}
+
+/* Dump a mapping table */
+void Mir2Lir::DumpMappingTable(const char* table_name, const std::string& descriptor,
+                               const std::string& name, const std::string& signature,
+                               const std::vector<uint32_t>& v) {
+  if (v.size() > 0) {
+    std::string line(StringPrintf("\n  %s %s%s_%s_table[%zu] = {", table_name,
+                     descriptor.c_str(), name.c_str(), signature.c_str(), v.size()));
+    std::replace(line.begin(), line.end(), ';', '_');
+    LOG(INFO) << line;
+    for (uint32_t i = 0; i < v.size(); i+=2) {
+      line = StringPrintf("    {0x%05x, 0x%04x},", v[i], v[i+1]);
+      LOG(INFO) << line;
+    }
+    LOG(INFO) <<"  };\n\n";
+  }
+}
+
+/* Dump instructions and constant pool contents */
+void Mir2Lir::CodegenDump()
+{
+  LOG(INFO) << "Dumping LIR insns for "
+            << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+  LIR* lir_insn;
+  int insns_size = cu_->code_item->insns_size_in_code_units_;
+
+  LOG(INFO) << "Regs (excluding ins) : " << cu_->num_regs;
+  LOG(INFO) << "Ins          : " << cu_->num_ins;
+  LOG(INFO) << "Outs         : " << cu_->num_outs;
+  LOG(INFO) << "CoreSpills       : " << num_core_spills_;
+  LOG(INFO) << "FPSpills       : " << num_fp_spills_;
+  LOG(INFO) << "CompilerTemps    : " << cu_->num_compiler_temps;
+  LOG(INFO) << "Frame size       : " << frame_size_;
+  LOG(INFO) << "code size is " << total_size_ <<
+    " bytes, Dalvik size is " << insns_size * 2;
+  LOG(INFO) << "expansion factor: "
+            << static_cast<float>(total_size_) / static_cast<float>(insns_size * 2);
+  DumpPromotionMap();
+  for (lir_insn = first_lir_insn_; lir_insn != NULL; lir_insn = lir_insn->next) {
+    DumpLIRInsn(lir_insn, 0);
+  }
+  for (lir_insn = literal_list_; lir_insn != NULL; lir_insn = lir_insn->next) {
+    LOG(INFO) << StringPrintf("%x (%04x): .word (%#x)", lir_insn->offset, lir_insn->offset,
+                              lir_insn->operands[0]);
+  }
+
+  const DexFile::MethodId& method_id =
+      cu_->dex_file->GetMethodId(cu_->method_idx);
+  std::string signature(cu_->dex_file->GetMethodSignature(method_id));
+  std::string name(cu_->dex_file->GetMethodName(method_id));
+  std::string descriptor(cu_->dex_file->GetMethodDeclaringClassDescriptor(method_id));
+
+  // Dump mapping tables
+  DumpMappingTable("PC2Dex_MappingTable", descriptor, name, signature, pc2dex_mapping_table_);
+  DumpMappingTable("Dex2PC_MappingTable", descriptor, name, signature, dex2pc_mapping_table_);
+}
+
+/*
+ * Search the existing constants in the literal pool for an exact or close match
+ * within specified delta (greater or equal to 0).
+ */
+LIR* Mir2Lir::ScanLiteralPool(LIR* data_target, int value, unsigned int delta)
+{
+  while (data_target) {
+    if ((static_cast<unsigned>(value - data_target->operands[0])) <= delta)
+      return data_target;
+    data_target = data_target->next;
+  }
+  return NULL;
+}
+
+/* Search the existing constants in the literal pool for an exact wide match */
+LIR* Mir2Lir::ScanLiteralPoolWide(LIR* data_target, int val_lo, int val_hi)
+{
+  bool lo_match = false;
+  LIR* lo_target = NULL;
+  while (data_target) {
+    if (lo_match && (data_target->operands[0] == val_hi)) {
+      // Record high word in case we need to expand this later.
+      lo_target->operands[1] = val_hi;
+      return lo_target;
+    }
+    lo_match = false;
+    if (data_target->operands[0] == val_lo) {
+      lo_match = true;
+      lo_target = data_target;
+    }
+    data_target = data_target->next;
+  }
+  return NULL;
+}
+
+/*
+ * The following are building blocks to insert constants into the pool or
+ * instruction streams.
+ */
+
+/* Add a 32-bit constant to the constant pool */
+LIR* Mir2Lir::AddWordData(LIR* *constant_list_p, int value)
+{
+  /* Add the constant to the literal pool */
+  if (constant_list_p) {
+    LIR* new_value = static_cast<LIR*>(arena_->NewMem(sizeof(LIR), true, ArenaAllocator::kAllocData));
+    new_value->operands[0] = value;
+    new_value->next = *constant_list_p;
+    *constant_list_p = new_value;
+    return new_value;
+  }
+  return NULL;
+}
+
+/* Add a 64-bit constant to the constant pool or mixed with code */
+LIR* Mir2Lir::AddWideData(LIR* *constant_list_p, int val_lo, int val_hi)
+{
+  AddWordData(constant_list_p, val_hi);
+  return AddWordData(constant_list_p, val_lo);
+}
+
+static void PushWord(std::vector<uint8_t>&buf, int data) {
+  buf.push_back( data & 0xff);
+  buf.push_back( (data >> 8) & 0xff);
+  buf.push_back( (data >> 16) & 0xff);
+  buf.push_back( (data >> 24) & 0xff);
+}
+
+static void AlignBuffer(std::vector<uint8_t>&buf, size_t offset) {
+  while (buf.size() < offset) {
+    buf.push_back(0);
+  }
+}
+
+/* Write the literal pool to the output stream */
+void Mir2Lir::InstallLiteralPools()
+{
+  AlignBuffer(code_buffer_, data_offset_);
+  LIR* data_lir = literal_list_;
+  while (data_lir != NULL) {
+    PushWord(code_buffer_, data_lir->operands[0]);
+    data_lir = NEXT_LIR(data_lir);
+  }
+  // Push code and method literals, record offsets for the compiler to patch.
+  data_lir = code_literal_list_;
+  while (data_lir != NULL) {
+    uint32_t target = data_lir->operands[0];
+    cu_->compiler_driver->AddCodePatch(cu_->dex_file,
+                                      cu_->method_idx,
+                                      cu_->invoke_type,
+                                      target,
+                                      static_cast<InvokeType>(data_lir->operands[1]),
+                                      code_buffer_.size());
+    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
+    // unique based on target to ensure code deduplication works
+    uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
+    PushWord(code_buffer_, unique_patch_value);
+    data_lir = NEXT_LIR(data_lir);
+  }
+  data_lir = method_literal_list_;
+  while (data_lir != NULL) {
+    uint32_t target = data_lir->operands[0];
+    cu_->compiler_driver->AddMethodPatch(cu_->dex_file,
+                                        cu_->method_idx,
+                                        cu_->invoke_type,
+                                        target,
+                                        static_cast<InvokeType>(data_lir->operands[1]),
+                                        code_buffer_.size());
+    const DexFile::MethodId& id = cu_->dex_file->GetMethodId(target);
+    // unique based on target to ensure code deduplication works
+    uint32_t unique_patch_value = reinterpret_cast<uint32_t>(&id);
+    PushWord(code_buffer_, unique_patch_value);
+    data_lir = NEXT_LIR(data_lir);
+  }
+}
+
+/* Write the switch tables to the output stream */
+void Mir2Lir::InstallSwitchTables()
+{
+  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
+  while (true) {
+    Mir2Lir::SwitchTable* tab_rec = iterator.Next();
+    if (tab_rec == NULL) break;
+    AlignBuffer(code_buffer_, tab_rec->offset);
+    /*
+     * For Arm, our reference point is the address of the bx
+     * instruction that does the launch, so we have to subtract
+     * the auto pc-advance.  For other targets the reference point
+     * is a label, so we can use the offset as-is.
+     */
+    int bx_offset = INVALID_OFFSET;
+    switch (cu_->instruction_set) {
+      case kThumb2:
+        bx_offset = tab_rec->anchor->offset + 4;
+        break;
+      case kX86:
+        bx_offset = 0;
+        break;
+      case kMips:
+        bx_offset = tab_rec->anchor->offset;
+        break;
+      default: LOG(FATAL) << "Unexpected instruction set: " << cu_->instruction_set;
+    }
+    if (cu_->verbose) {
+      LOG(INFO) << "Switch table for offset 0x" << std::hex << bx_offset;
+    }
+    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
+      const int* keys = reinterpret_cast<const int*>(&(tab_rec->table[2]));
+      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
+        int disp = tab_rec->targets[elems]->offset - bx_offset;
+        if (cu_->verbose) {
+          LOG(INFO) << "  Case[" << elems << "] key: 0x"
+                    << std::hex << keys[elems] << ", disp: 0x"
+                    << std::hex << disp;
+        }
+        PushWord(code_buffer_, keys[elems]);
+        PushWord(code_buffer_,
+          tab_rec->targets[elems]->offset - bx_offset);
+      }
+    } else {
+      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
+                static_cast<int>(Instruction::kPackedSwitchSignature));
+      for (int elems = 0; elems < tab_rec->table[1]; elems++) {
+        int disp = tab_rec->targets[elems]->offset - bx_offset;
+        if (cu_->verbose) {
+          LOG(INFO) << "  Case[" << elems << "] disp: 0x"
+                    << std::hex << disp;
+        }
+        PushWord(code_buffer_, tab_rec->targets[elems]->offset - bx_offset);
+      }
+    }
+  }
+}
+
+/* Write the fill array dta to the output stream */
+void Mir2Lir::InstallFillArrayData()
+{
+  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
+  while (true) {
+    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
+    if (tab_rec == NULL) break;
+    AlignBuffer(code_buffer_, tab_rec->offset);
+    for (int i = 0; i < (tab_rec->size + 1) / 2; i++) {
+      code_buffer_.push_back( tab_rec->table[i] & 0xFF);
+      code_buffer_.push_back( (tab_rec->table[i] >> 8) & 0xFF);
+    }
+  }
+}
+
+static int AssignLiteralOffsetCommon(LIR* lir, int offset)
+{
+  for (;lir != NULL; lir = lir->next) {
+    lir->offset = offset;
+    offset += 4;
+  }
+  return offset;
+}
+
+// Make sure we have a code address for every declared catch entry
+bool Mir2Lir::VerifyCatchEntries()
+{
+  bool success = true;
+  for (std::set<uint32_t>::const_iterator it = mir_graph_->catches_.begin();
+       it != mir_graph_->catches_.end(); ++it) {
+    uint32_t dex_pc = *it;
+    bool found = false;
+    for (size_t i = 0; i < dex2pc_mapping_table_.size(); i += 2) {
+      if (dex_pc == dex2pc_mapping_table_[i+1]) {
+        found = true;
+        break;
+      }
+    }
+    if (!found) {
+      LOG(INFO) << "Missing native PC for catch entry @ 0x" << std::hex << dex_pc;
+      success = false;
+    }
+  }
+  // Now, try in the other direction
+  for (size_t i = 0; i < dex2pc_mapping_table_.size(); i += 2) {
+    uint32_t dex_pc = dex2pc_mapping_table_[i+1];
+    if (mir_graph_->catches_.find(dex_pc) == mir_graph_->catches_.end()) {
+      LOG(INFO) << "Unexpected catch entry @ dex pc 0x" << std::hex << dex_pc;
+      success = false;
+    }
+  }
+  if (!success) {
+    LOG(INFO) << "Bad dex2pcMapping table in " << PrettyMethod(cu_->method_idx, *cu_->dex_file);
+    LOG(INFO) << "Entries @ decode: " << mir_graph_->catches_.size() << ", Entries in table: "
+              << dex2pc_mapping_table_.size()/2;
+  }
+  return success;
+}
+
+
+void Mir2Lir::CreateMappingTables()
+{
+  for (LIR* tgt_lir = first_lir_insn_; tgt_lir != NULL; tgt_lir = NEXT_LIR(tgt_lir)) {
+    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoSafepointPC)) {
+      pc2dex_mapping_table_.push_back(tgt_lir->offset);
+      pc2dex_mapping_table_.push_back(tgt_lir->dalvik_offset);
+    }
+    if (!tgt_lir->flags.is_nop && (tgt_lir->opcode == kPseudoExportedPC)) {
+      dex2pc_mapping_table_.push_back(tgt_lir->offset);
+      dex2pc_mapping_table_.push_back(tgt_lir->dalvik_offset);
+    }
+  }
+  if (kIsDebugBuild) {
+    DCHECK(VerifyCatchEntries());
+  }
+  combined_mapping_table_.push_back(pc2dex_mapping_table_.size() +
+                                        dex2pc_mapping_table_.size());
+  combined_mapping_table_.push_back(pc2dex_mapping_table_.size());
+  combined_mapping_table_.insert(combined_mapping_table_.end(), pc2dex_mapping_table_.begin(),
+                                 pc2dex_mapping_table_.end());
+  combined_mapping_table_.insert(combined_mapping_table_.end(), dex2pc_mapping_table_.begin(),
+                                 dex2pc_mapping_table_.end());
+}
+
+class NativePcToReferenceMapBuilder {
+ public:
+  NativePcToReferenceMapBuilder(std::vector<uint8_t>* table,
+                                size_t entries, uint32_t max_native_offset,
+                                size_t references_width) : entries_(entries),
+                                references_width_(references_width), in_use_(entries),
+                                table_(table) {
+    // Compute width in bytes needed to hold max_native_offset.
+    native_offset_width_ = 0;
+    while (max_native_offset != 0) {
+      native_offset_width_++;
+      max_native_offset >>= 8;
+    }
+    // Resize table and set up header.
+    table->resize((EntryWidth() * entries) + sizeof(uint32_t));
+    CHECK_LT(native_offset_width_, 1U << 3);
+    (*table)[0] = native_offset_width_ & 7;
+    CHECK_LT(references_width_, 1U << 13);
+    (*table)[0] |= (references_width_ << 3) & 0xFF;
+    (*table)[1] = (references_width_ >> 5) & 0xFF;
+    CHECK_LT(entries, 1U << 16);
+    (*table)[2] = entries & 0xFF;
+    (*table)[3] = (entries >> 8) & 0xFF;
+  }
+
+  void AddEntry(uint32_t native_offset, const uint8_t* references) {
+    size_t table_index = TableIndex(native_offset);
+    while (in_use_[table_index]) {
+      table_index = (table_index + 1) % entries_;
+    }
+    in_use_[table_index] = true;
+    SetNativeOffset(table_index, native_offset);
+    DCHECK_EQ(native_offset, GetNativeOffset(table_index));
+    SetReferences(table_index, references);
+  }
+
+ private:
+  size_t TableIndex(uint32_t native_offset) {
+    return NativePcOffsetToReferenceMap::Hash(native_offset) % entries_;
+  }
+
+  uint32_t GetNativeOffset(size_t table_index) {
+    uint32_t native_offset = 0;
+    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
+    for (size_t i = 0; i < native_offset_width_; i++) {
+      native_offset |= (*table_)[table_offset + i] << (i * 8);
+    }
+    return native_offset;
+  }
+
+  void SetNativeOffset(size_t table_index, uint32_t native_offset) {
+    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
+    for (size_t i = 0; i < native_offset_width_; i++) {
+      (*table_)[table_offset + i] = (native_offset >> (i * 8)) & 0xFF;
+    }
+  }
+
+  void SetReferences(size_t table_index, const uint8_t* references) {
+    size_t table_offset = (table_index * EntryWidth()) + sizeof(uint32_t);
+    memcpy(&(*table_)[table_offset + native_offset_width_], references, references_width_);
+  }
+
+  size_t EntryWidth() const {
+    return native_offset_width_ + references_width_;
+  }
+
+  // Number of entries in the table.
+  const size_t entries_;
+  // Number of bytes used to encode the reference bitmap.
+  const size_t references_width_;
+  // Number of bytes used to encode a native offset.
+  size_t native_offset_width_;
+  // Entries that are in use.
+  std::vector<bool> in_use_;
+  // The table we're building.
+  std::vector<uint8_t>* const table_;
+};
+
+void Mir2Lir::CreateNativeGcMap() {
+  const std::vector<uint32_t>& mapping_table = pc2dex_mapping_table_;
+  uint32_t max_native_offset = 0;
+  for (size_t i = 0; i < mapping_table.size(); i += 2) {
+    uint32_t native_offset = mapping_table[i + 0];
+    if (native_offset > max_native_offset) {
+      max_native_offset = native_offset;
+    }
+  }
+  MethodReference method_ref(cu_->dex_file, cu_->method_idx);
+  const std::vector<uint8_t>* gc_map_raw = verifier::MethodVerifier::GetDexGcMap(method_ref);
+  verifier::DexPcToReferenceMap dex_gc_map(&(*gc_map_raw)[4], gc_map_raw->size() - 4);
+  // Compute native offset to references size.
+  NativePcToReferenceMapBuilder native_gc_map_builder(&native_gc_map_,
+                                                      mapping_table.size() / 2, max_native_offset,
+                                                      dex_gc_map.RegWidth());
+
+  for (size_t i = 0; i < mapping_table.size(); i += 2) {
+    uint32_t native_offset = mapping_table[i + 0];
+    uint32_t dex_pc = mapping_table[i + 1];
+    const uint8_t* references = dex_gc_map.FindBitMap(dex_pc, false);
+    CHECK(references != NULL) << "Missing ref for dex pc 0x" << std::hex << dex_pc;
+    native_gc_map_builder.AddEntry(native_offset, references);
+  }
+}
+
+/* Determine the offset of each literal field */
+int Mir2Lir::AssignLiteralOffset(int offset)
+{
+  offset = AssignLiteralOffsetCommon(literal_list_, offset);
+  offset = AssignLiteralOffsetCommon(code_literal_list_, offset);
+  offset = AssignLiteralOffsetCommon(method_literal_list_, offset);
+  return offset;
+}
+
+int Mir2Lir::AssignSwitchTablesOffset(int offset)
+{
+  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
+  while (true) {
+    Mir2Lir::SwitchTable *tab_rec = iterator.Next();
+    if (tab_rec == NULL) break;
+    tab_rec->offset = offset;
+    if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
+      offset += tab_rec->table[1] * (sizeof(int) * 2);
+    } else {
+      DCHECK_EQ(static_cast<int>(tab_rec->table[0]),
+                static_cast<int>(Instruction::kPackedSwitchSignature));
+      offset += tab_rec->table[1] * sizeof(int);
+    }
+  }
+  return offset;
+}
+
+int Mir2Lir::AssignFillArrayDataOffset(int offset)
+{
+  GrowableArray<FillArrayData*>::Iterator iterator(&fill_array_data_);
+  while (true) {
+    Mir2Lir::FillArrayData *tab_rec = iterator.Next();
+    if (tab_rec == NULL) break;
+    tab_rec->offset = offset;
+    offset += tab_rec->size;
+    // word align
+    offset = (offset + 3) & ~3;
+    }
+  return offset;
+}
+
+// LIR offset assignment.
+int Mir2Lir::AssignInsnOffsets()
+{
+  LIR* lir;
+  int offset = 0;
+
+  for (lir = first_lir_insn_; lir != NULL; lir = NEXT_LIR(lir)) {
+    lir->offset = offset;
+    if (lir->opcode >= 0) {
+      if (!lir->flags.is_nop) {
+        offset += lir->flags.size;
+      }
+    } else if (lir->opcode == kPseudoPseudoAlign4) {
+      if (offset & 0x2) {
+        offset += 2;
+        lir->operands[0] = 1;
+      } else {
+        lir->operands[0] = 0;
+      }
+    }
+    /* Pseudo opcodes don't consume space */
+  }
+
+  return offset;
+}
+
+/*
+ * Walk the compilation unit and assign offsets to instructions
+ * and literals and compute the total size of the compiled unit.
+ */
+void Mir2Lir::AssignOffsets()
+{
+  int offset = AssignInsnOffsets();
+
+  /* Const values have to be word aligned */
+  offset = (offset + 3) & ~3;
+
+  /* Set up offsets for literals */
+  data_offset_ = offset;
+
+  offset = AssignLiteralOffset(offset);
+
+  offset = AssignSwitchTablesOffset(offset);
+
+  offset = AssignFillArrayDataOffset(offset);
+
+  total_size_ = offset;
+}
+
+/*
+ * Go over each instruction in the list and calculate the offset from the top
+ * before sending them off to the assembler. If out-of-range branch distance is
+ * seen rearrange the instructions a bit to correct it.
+ */
+void Mir2Lir::AssembleLIR()
+{
+  AssignOffsets();
+  int assembler_retries = 0;
+  /*
+   * Assemble here.  Note that we generate code with optimistic assumptions
+   * and if found now to work, we'll have to redo the sequence and retry.
+   */
+
+  while (true) {
+    AssemblerStatus res = AssembleInstructions(0);
+    if (res == kSuccess) {
+      break;
+    } else {
+      assembler_retries++;
+      if (assembler_retries > MAX_ASSEMBLER_RETRIES) {
+        CodegenDump();
+        LOG(FATAL) << "Assembler error - too many retries";
+      }
+      // Redo offsets and try again
+      AssignOffsets();
+      code_buffer_.clear();
+    }
+  }
+
+  // Install literals
+  InstallLiteralPools();
+
+  // Install switch tables
+  InstallSwitchTables();
+
+  // Install fill array data
+  InstallFillArrayData();
+
+  // Create the mapping table and native offset to reference map.
+  CreateMappingTables();
+
+  CreateNativeGcMap();
+}
+
+/*
+ * Insert a kPseudoCaseLabel at the beginning of the Dalvik
+ * offset vaddr.  This label will be used to fix up the case
+ * branch table during the assembly phase.  Be sure to set
+ * all resource flags on this to prevent code motion across
+ * target boundaries.  KeyVal is just there for debugging.
+ */
+LIR* Mir2Lir::InsertCaseLabel(int vaddr, int keyVal)
+{
+  SafeMap<unsigned int, LIR*>::iterator it;
+  it = boundary_map_.find(vaddr);
+  if (it == boundary_map_.end()) {
+    LOG(FATAL) << "Error: didn't find vaddr 0x" << std::hex << vaddr;
+  }
+  LIR* new_label = static_cast<LIR*>(arena_->NewMem(sizeof(LIR), true, ArenaAllocator::kAllocLIR));
+  new_label->dalvik_offset = vaddr;
+  new_label->opcode = kPseudoCaseLabel;
+  new_label->operands[0] = keyVal;
+  InsertLIRAfter(it->second, new_label);
+  return new_label;
+}
+
+void Mir2Lir::MarkPackedCaseLabels(Mir2Lir::SwitchTable *tab_rec)
+{
+  const uint16_t* table = tab_rec->table;
+  int base_vaddr = tab_rec->vaddr;
+  const int *targets = reinterpret_cast<const int*>(&table[4]);
+  int entries = table[1];
+  int low_key = s4FromSwitchData(&table[2]);
+  for (int i = 0; i < entries; i++) {
+    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], i + low_key);
+  }
+}
+
+void Mir2Lir::MarkSparseCaseLabels(Mir2Lir::SwitchTable *tab_rec)
+{
+  const uint16_t* table = tab_rec->table;
+  int base_vaddr = tab_rec->vaddr;
+  int entries = table[1];
+  const int* keys = reinterpret_cast<const int*>(&table[2]);
+  const int* targets = &keys[entries];
+  for (int i = 0; i < entries; i++) {
+    tab_rec->targets[i] = InsertCaseLabel(base_vaddr + targets[i], keys[i]);
+  }
+}
+
+void Mir2Lir::ProcessSwitchTables()
+{
+  GrowableArray<SwitchTable*>::Iterator iterator(&switch_tables_);
+  while (true) {
+    Mir2Lir::SwitchTable *tab_rec = iterator.Next();
+    if (tab_rec == NULL) break;
+    if (tab_rec->table[0] == Instruction::kPackedSwitchSignature) {
+      MarkPackedCaseLabels(tab_rec);
+    } else if (tab_rec->table[0] == Instruction::kSparseSwitchSignature) {
+      MarkSparseCaseLabels(tab_rec);
+    } else {
+      LOG(FATAL) << "Invalid switch table";
+    }
+  }
+}
+
+void Mir2Lir::DumpSparseSwitchTable(const uint16_t* table)
+  /*
+   * Sparse switch data format:
+   *  ushort ident = 0x0200   magic value
+   *  ushort size       number of entries in the table; > 0
+   *  int keys[size]      keys, sorted low-to-high; 32-bit aligned
+   *  int targets[size]     branch targets, relative to switch opcode
+   *
+   * Total size is (2+size*4) 16-bit code units.
+   */
+{
+  uint16_t ident = table[0];
+  int entries = table[1];
+  const int* keys = reinterpret_cast<const int*>(&table[2]);
+  const int* targets = &keys[entries];
+  LOG(INFO) <<  "Sparse switch table - ident:0x" << std::hex << ident
+            << ", entries: " << std::dec << entries;
+  for (int i = 0; i < entries; i++) {
+    LOG(INFO) << "  Key[" << keys[i] << "] -> 0x" << std::hex << targets[i];
+  }
+}
+
+void Mir2Lir::DumpPackedSwitchTable(const uint16_t* table)
+  /*
+   * Packed switch data format:
+   *  ushort ident = 0x0100   magic value
+   *  ushort size       number of entries in the table
+   *  int first_key       first (and lowest) switch case value
+   *  int targets[size]     branch targets, relative to switch opcode
+   *
+   * Total size is (4+size*2) 16-bit code units.
+   */
+{
+  uint16_t ident = table[0];
+  const int* targets = reinterpret_cast<const int*>(&table[4]);
+  int entries = table[1];
+  int low_key = s4FromSwitchData(&table[2]);
+  LOG(INFO) << "Packed switch table - ident:0x" << std::hex << ident
+            << ", entries: " << std::dec << entries << ", low_key: " << low_key;
+  for (int i = 0; i < entries; i++) {
+    LOG(INFO) << "  Key[" << (i + low_key) << "] -> 0x" << std::hex
+              << targets[i];
+  }
+}
+
+/*
+ * Set up special LIR to mark a Dalvik byte-code instruction start and
+ * record it in the boundary_map.  NOTE: in cases such as kMirOpCheck in
+ * which we split a single Dalvik instruction, only the first MIR op
+ * associated with a Dalvik PC should be entered into the map.
+ */
+LIR* Mir2Lir::MarkBoundary(int offset, const char* inst_str)
+{
+  LIR* res = NewLIR1(kPseudoDalvikByteCodeBoundary, reinterpret_cast<uintptr_t>(inst_str));
+  if (boundary_map_.find(offset) == boundary_map_.end()) {
+    boundary_map_.Put(offset, res);
+  }
+  return res;
+}
+
+bool Mir2Lir::EvaluateBranch(Instruction::Code opcode, int32_t src1, int32_t src2)
+{
+  bool is_taken;
+  switch (opcode) {
+    case Instruction::IF_EQ: is_taken = (src1 == src2); break;
+    case Instruction::IF_NE: is_taken = (src1 != src2); break;
+    case Instruction::IF_LT: is_taken = (src1 < src2); break;
+    case Instruction::IF_GE: is_taken = (src1 >= src2); break;
+    case Instruction::IF_GT: is_taken = (src1 > src2); break;
+    case Instruction::IF_LE: is_taken = (src1 <= src2); break;
+    case Instruction::IF_EQZ: is_taken = (src1 == 0); break;
+    case Instruction::IF_NEZ: is_taken = (src1 != 0); break;
+    case Instruction::IF_LTZ: is_taken = (src1 < 0); break;
+    case Instruction::IF_GEZ: is_taken = (src1 >= 0); break;
+    case Instruction::IF_GTZ: is_taken = (src1 > 0); break;
+    case Instruction::IF_LEZ: is_taken = (src1 <= 0); break;
+    default:
+      LOG(FATAL) << "Unexpected opcode " << opcode;
+      is_taken = false;
+  }
+  return is_taken;
+}
+
+// Convert relation of src1/src2 to src2/src1
+ConditionCode Mir2Lir::FlipComparisonOrder(ConditionCode before) {
+  ConditionCode res;
+  switch (before) {
+    case kCondEq: res = kCondEq; break;
+    case kCondNe: res = kCondNe; break;
+    case kCondLt: res = kCondGt; break;
+    case kCondGt: res = kCondLt; break;
+    case kCondLe: res = kCondGe; break;
+    case kCondGe: res = kCondLe; break;
+    default:
+      res = static_cast<ConditionCode>(0);
+      LOG(FATAL) << "Unexpected ccode " << before;
+  }
+  return res;
+}
+
+// TODO: move to mir_to_lir.cc
+Mir2Lir::Mir2Lir(CompilationUnit* cu, MIRGraph* mir_graph, ArenaAllocator* arena)
+    : Backend(arena),
+      literal_list_(NULL),
+      method_literal_list_(NULL),
+      code_literal_list_(NULL),
+      cu_(cu),
+      mir_graph_(mir_graph),
+      switch_tables_(arena, 4, kGrowableArraySwitchTables),
+      fill_array_data_(arena, 4, kGrowableArrayFillArrayData),
+      throw_launchpads_(arena, 2048, kGrowableArrayThrowLaunchPads),
+      suspend_launchpads_(arena, 4, kGrowableArraySuspendLaunchPads),
+      intrinsic_launchpads_(arena, 2048, kGrowableArrayMisc),
+      data_offset_(0),
+      total_size_(0),
+      block_label_list_(NULL),
+      current_dalvik_offset_(0),
+      reg_pool_(NULL),
+      live_sreg_(0),
+      num_core_spills_(0),
+      num_fp_spills_(0),
+      frame_size_(0),
+      core_spill_mask_(0),
+      fp_spill_mask_(0),
+      first_lir_insn_(NULL),
+      last_lir_insn_(NULL)
+ {
+  promotion_map_ = static_cast<PromotionMap*>
+      (arena_->NewMem((cu_->num_dalvik_registers  + cu_->num_compiler_temps + 1) *
+                      sizeof(promotion_map_[0]), true, ArenaAllocator::kAllocRegAlloc));
+}
+
+void Mir2Lir::Materialize() {
+  CompilerInitializeRegAlloc();  // Needs to happen after SSA naming
+
+  /* Allocate Registers using simple local allocation scheme */
+  SimpleRegAlloc();
+
+  //FIXME: re-enable by retrieving from mir_graph
+  SpecialCaseHandler special_case = kNoHandler;
+
+  if (special_case != kNoHandler) {
+      /*
+       * Custom codegen for special cases.  If for any reason the
+       * special codegen doesn't succeed, first_lir_insn_ will
+       * set to NULL;
+       */
+      SpecialMIR2LIR(special_case);
+    }
+
+  /* Convert MIR to LIR, etc. */
+  if (first_lir_insn_ == NULL) {
+    MethodMIR2LIR();
+  }
+
+  /* Method is not empty */
+  if (first_lir_insn_) {
+
+    // mark the targets of switch statement case labels
+    ProcessSwitchTables();
+
+    /* Convert LIR into machine code. */
+    AssembleLIR();
+
+    if (cu_->verbose) {
+      CodegenDump();
+    }
+
+  }
+
+}
+
+CompiledMethod* Mir2Lir::GetCompiledMethod() {
+  // Combine vmap tables - core regs, then fp regs - into vmap_table
+  std::vector<uint16_t> vmap_table;
+  // Core regs may have been inserted out of order - sort first
+  std::sort(core_vmap_table_.begin(), core_vmap_table_.end());
+  for (size_t i = 0 ; i < core_vmap_table_.size(); i++) {
+    // Copy, stripping out the phys register sort key
+    vmap_table.push_back(~(-1 << VREG_NUM_WIDTH) & core_vmap_table_[i]);
+  }
+  // If we have a frame, push a marker to take place of lr
+  if (frame_size_ > 0) {
+    vmap_table.push_back(INVALID_VREG);
+  } else {
+    DCHECK_EQ(__builtin_popcount(core_spill_mask_), 0);
+    DCHECK_EQ(__builtin_popcount(fp_spill_mask_), 0);
+  }
+  // Combine vmap tables - core regs, then fp regs. fp regs already sorted
+  for (uint32_t i = 0; i < fp_vmap_table_.size(); i++) {
+    vmap_table.push_back(fp_vmap_table_[i]);
+  }
+  CompiledMethod* result =
+      new CompiledMethod(cu_->instruction_set, code_buffer_,
+                         frame_size_, core_spill_mask_, fp_spill_mask_,
+                         combined_mapping_table_, vmap_table, native_gc_map_);
+  return result;
+}
+
+int Mir2Lir::ComputeFrameSize() {
+  /* Figure out the frame size */
+  static const uint32_t kAlignMask = kStackAlignment - 1;
+  uint32_t size = (num_core_spills_ + num_fp_spills_ +
+                   1 /* filler word */ + cu_->num_regs + cu_->num_outs +
+                   cu_->num_compiler_temps + 1 /* cur_method* */)
+                   * sizeof(uint32_t);
+  /* Align and set */
+  return (size + kAlignMask) & ~(kAlignMask);
+}
+
+/*
+ * Append an LIR instruction to the LIR list maintained by a compilation
+ * unit
+ */
+void Mir2Lir::AppendLIR(LIR* lir)
+{
+  if (first_lir_insn_ == NULL) {
+    DCHECK(last_lir_insn_ == NULL);
+    last_lir_insn_ = first_lir_insn_ = lir;
+    lir->prev = lir->next = NULL;
+  } else {
+    last_lir_insn_->next = lir;
+    lir->prev = last_lir_insn_;
+    lir->next = NULL;
+    last_lir_insn_ = lir;
+  }
+}
+
+/*
+ * Insert an LIR instruction before the current instruction, which cannot be the
+ * first instruction.
+ *
+ * prev_lir <-> new_lir <-> current_lir
+ */
+void Mir2Lir::InsertLIRBefore(LIR* current_lir, LIR* new_lir)
+{
+  DCHECK(current_lir->prev != NULL);
+  LIR *prev_lir = current_lir->prev;
+
+  prev_lir->next = new_lir;
+  new_lir->prev = prev_lir;
+  new_lir->next = current_lir;
+  current_lir->prev = new_lir;
+}
+
+/*
+ * Insert an LIR instruction after the current instruction, which cannot be the
+ * first instruction.
+ *
+ * current_lir -> new_lir -> old_next
+ */
+void Mir2Lir::InsertLIRAfter(LIR* current_lir, LIR* new_lir)
+{
+  new_lir->prev = current_lir;
+  new_lir->next = current_lir->next;
+  current_lir->next = new_lir;
+  new_lir->next->prev = new_lir;
+}
+
+
+} // namespace art
