/*
 * 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 "object_utils.h"

#include <llvm/Support/ToolOutputFile.h>
#include <llvm/Bitcode/ReaderWriter.h>
#include <llvm/Analysis/Verifier.h>
#include <llvm/Metadata.h>
#include <llvm/ADT/DepthFirstIterator.h>
#include <llvm/Instruction.h>
#include <llvm/Type.h>
#include <llvm/Instructions.h>
#include <llvm/Support/Casting.h>
#include <llvm/Support/InstIterator.h>

#include "compiler/dex/compiler_internals.h"

//TODO: move gbc_to_lir code into quick directory (if necessary).
#include "compiler/dex/quick/codegen_util.h"
#include "compiler/dex/quick/local_optimizations.h"
#include "compiler/dex/quick/ralloc_util.h"

static const char* kLabelFormat = "%c0x%x_%d";
static const char kInvalidBlock = 0xff;
static const char kNormalBlock = 'L';
static const char kCatchBlock = 'C';

namespace art {
static RegLocation GetLoc(CompilationUnit* cu, ::llvm::Value* val);

static ::llvm::BasicBlock* GetLLVMBlock(CompilationUnit* cu, int id)
{
  return cu->id_to_block_map.Get(id);
}

static ::llvm::Value* GetLLVMValue(CompilationUnit* cu, int s_reg)
{
  return reinterpret_cast< ::llvm::Value*>(GrowableListGetElement(&cu->llvm_values, s_reg));
}

static void SetVregOnValue(CompilationUnit* cu, ::llvm::Value* val, int s_reg)
{
  // Set vreg for debugging
  art::llvm::IntrinsicHelper::IntrinsicId id = art::llvm::IntrinsicHelper::SetVReg;
  ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
  int v_reg = SRegToVReg(cu, s_reg);
  ::llvm::Value* table_slot = cu->irb->getInt32(v_reg);
  ::llvm::Value* args[] = { table_slot, val };
  cu->irb->CreateCall(func, args);
}

// Replace the placeholder value with the real definition
static void DefineValueOnly(CompilationUnit* cu, ::llvm::Value* val, int s_reg)
{
  ::llvm::Value* placeholder = GetLLVMValue(cu, s_reg);
  if (placeholder == NULL) {
    // This can happen on instruction rewrite on verification failure
    LOG(WARNING) << "Null placeholder";
    return;
  }
  placeholder->replaceAllUsesWith(val);
  val->takeName(placeholder);
  cu->llvm_values.elem_list[s_reg] = reinterpret_cast<uintptr_t>(val);
  ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(placeholder);
  DCHECK(inst != NULL);
  inst->eraseFromParent();

}

static void DefineValue(CompilationUnit* cu, ::llvm::Value* val, int s_reg)
{
  DefineValueOnly(cu, val, s_reg);
  SetVregOnValue(cu, val, s_reg);
}

static ::llvm::Type* LlvmTypeFromLocRec(CompilationUnit* cu, RegLocation loc)
{
  ::llvm::Type* res = NULL;
  if (loc.wide) {
    if (loc.fp)
        res = cu->irb->getDoubleTy();
    else
        res = cu->irb->getInt64Ty();
  } else {
    if (loc.fp) {
      res = cu->irb->getFloatTy();
    } else {
      if (loc.ref)
        res = cu->irb->getJObjectTy();
      else
        res = cu->irb->getInt32Ty();
    }
  }
  return res;
}

/* Create an in-memory RegLocation from an llvm Value. */
static void CreateLocFromValue(CompilationUnit* cu, ::llvm::Value* val)
{
  // NOTE: llvm takes shortcuts with c_str() - get to std::string firstt
  std::string s(val->getName().str());
  const char* val_name = s.c_str();
  SafeMap< ::llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
  DCHECK(it == cu->loc_map.end()) << " - already defined: " << val_name;
  int base_sreg = INVALID_SREG;
  int subscript = -1;
  sscanf(val_name, "v%d_%d", &base_sreg, &subscript);
  if ((base_sreg == INVALID_SREG) && (!strcmp(val_name, "method"))) {
    base_sreg = SSA_METHOD_BASEREG;
    subscript = 0;
  }
  DCHECK_NE(base_sreg, INVALID_SREG);
  DCHECK_NE(subscript, -1);
  // TODO: redo during C++'ification
  RegLocation loc =  {kLocDalvikFrame, 0, 0, 0, 0, 0, 0, 0, 0, INVALID_REG,
                      INVALID_REG, INVALID_SREG, INVALID_SREG};
  ::llvm::Type* ty = val->getType();
  loc.wide = ((ty == cu->irb->getInt64Ty()) ||
              (ty == cu->irb->getDoubleTy()));
  loc.defined = true;
  loc.home = false;  // May change during promotion
  loc.s_reg_low = base_sreg;
  loc.orig_sreg = cu->loc_map.size();
  PromotionMap p_map = cu->promotion_map[base_sreg];
  if (ty == cu->irb->getFloatTy()) {
    loc.fp = true;
    if (p_map.fp_location == kLocPhysReg) {
      loc.low_reg = p_map.FpReg;
      loc.location = kLocPhysReg;
      loc.home = true;
    }
  } else if (ty == cu->irb->getDoubleTy()) {
    loc.fp = true;
    PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
    if ((p_map.fp_location == kLocPhysReg) &&
        (p_map_high.fp_location == kLocPhysReg) &&
        ((p_map.FpReg & 0x1) == 0) &&
        (p_map.FpReg + 1 == p_map_high.FpReg)) {
      loc.low_reg = p_map.FpReg;
      loc.high_reg = p_map_high.FpReg;
      loc.location = kLocPhysReg;
      loc.home = true;
    }
  } else if (ty == cu->irb->getJObjectTy()) {
    loc.ref = true;
    if (p_map.core_location == kLocPhysReg) {
      loc.low_reg = p_map.core_reg;
      loc.location = kLocPhysReg;
      loc.home = true;
    }
  } else if (ty == cu->irb->getInt64Ty()) {
    loc.core = true;
    PromotionMap p_map_high = cu->promotion_map[base_sreg + 1];
    if ((p_map.core_location == kLocPhysReg) &&
        (p_map_high.core_location == kLocPhysReg)) {
      loc.low_reg = p_map.core_reg;
      loc.high_reg = p_map_high.core_reg;
      loc.location = kLocPhysReg;
      loc.home = true;
    }
  } else {
    loc.core = true;
    if (p_map.core_location == kLocPhysReg) {
      loc.low_reg = p_map.core_reg;
      loc.location = kLocPhysReg;
      loc.home = true;
    }
  }

  if (cu->verbose && loc.home) {
    if (loc.wide) {
      LOG(INFO) << "Promoted wide " << s << " to regs " << loc.low_reg << "/" << loc.high_reg;
    } else {
      LOG(INFO) << "Promoted " << s << " to reg " << loc.low_reg;
    }
  }
  cu->loc_map.Put(val, loc);
}

static void InitIR(CompilationUnit* cu)
{
  LLVMInfo* llvm_info = cu->llvm_info;
  if (llvm_info == NULL) {
    CompilerTls* tls = cu->compiler_driver->GetTls();
    CHECK(tls != NULL);
    llvm_info = static_cast<LLVMInfo*>(tls->GetLLVMInfo());
    if (llvm_info == NULL) {
      llvm_info = new LLVMInfo();
      tls->SetLLVMInfo(llvm_info);
    }
  }
  cu->context = llvm_info->GetLLVMContext();
  cu->module = llvm_info->GetLLVMModule();
  cu->intrinsic_helper = llvm_info->GetIntrinsicHelper();
  cu->irb = llvm_info->GetIRBuilder();
}

static const char* LlvmSSAName(CompilationUnit* cu, int ssa_reg) {
  return GET_ELEM_N(cu->ssa_strings, char*, ssa_reg);
}

::llvm::BasicBlock* FindCaseTarget(CompilationUnit* cu, uint32_t vaddr)
{
  BasicBlock* bb = FindBlock(cu, vaddr);
  DCHECK(bb != NULL);
  return GetLLVMBlock(cu, bb->id);
}

static void ConvertPackedSwitch(CompilationUnit* cu, BasicBlock* bb,
                                int32_t table_offset, RegLocation rl_src)
{
  const Instruction::PackedSwitchPayload* payload =
      reinterpret_cast<const Instruction::PackedSwitchPayload*>(
      cu->insns + cu->current_dalvik_offset + table_offset);

  ::llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);

  ::llvm::SwitchInst* sw =
    cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
                             payload->case_count);

  for (uint16_t i = 0; i < payload->case_count; ++i) {
    ::llvm::BasicBlock* llvm_bb =
        FindCaseTarget(cu, cu->current_dalvik_offset + payload->targets[i]);
    sw->addCase(cu->irb->getInt32(payload->first_key + i), llvm_bb);
  }
  ::llvm::MDNode* switch_node =
      ::llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
  sw->setMetadata("SwitchTable", switch_node);
  bb->taken = NULL;
  bb->fall_through = NULL;
}

static void ConvertSparseSwitch(CompilationUnit* cu, BasicBlock* bb,
                                int32_t table_offset, RegLocation rl_src)
{
  const Instruction::SparseSwitchPayload* payload =
      reinterpret_cast<const Instruction::SparseSwitchPayload*>(
      cu->insns + cu->current_dalvik_offset + table_offset);

  const int32_t* keys = payload->GetKeys();
  const int32_t* targets = payload->GetTargets();

  ::llvm::Value* value = GetLLVMValue(cu, rl_src.orig_sreg);

  ::llvm::SwitchInst* sw =
    cu->irb->CreateSwitch(value, GetLLVMBlock(cu, bb->fall_through->id),
                             payload->case_count);

  for (size_t i = 0; i < payload->case_count; ++i) {
    ::llvm::BasicBlock* llvm_bb =
        FindCaseTarget(cu, cu->current_dalvik_offset + targets[i]);
    sw->addCase(cu->irb->getInt32(keys[i]), llvm_bb);
  }
  ::llvm::MDNode* switch_node =
      ::llvm::MDNode::get(*cu->context, cu->irb->getInt32(table_offset));
  sw->setMetadata("SwitchTable", switch_node);
  bb->taken = NULL;
  bb->fall_through = NULL;
}

static void ConvertSget(CompilationUnit* cu, int32_t field_index,
                        art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
{
  ::llvm::Constant* field_idx = cu->irb->getInt32(field_index);
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res = cu->irb->CreateCall(intr, field_idx);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertSput(CompilationUnit* cu, int32_t field_index,
                        art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_src)
{
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(field_index));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(intr, args);
}

static void ConvertFillArrayData(CompilationUnit* cu, int32_t offset, RegLocation rl_array)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::HLFillArrayData;
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(offset));
  args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(intr, args);
}

static ::llvm::Value* EmitConst(CompilationUnit* cu, ::llvm::ArrayRef< ::llvm::Value*> src,
                              RegLocation loc)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  if (loc.wide) {
    if (loc.fp) {
      id = art::llvm::IntrinsicHelper::ConstDouble;
    } else {
      id = art::llvm::IntrinsicHelper::ConstLong;
    }
  } else {
    if (loc.fp) {
      id = art::llvm::IntrinsicHelper::ConstFloat;
    } else if (loc.ref) {
      id = art::llvm::IntrinsicHelper::ConstObj;
    } else {
      id = art::llvm::IntrinsicHelper::ConstInt;
    }
  }
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  return cu->irb->CreateCall(intr, src);
}

static void EmitPopShadowFrame(CompilationUnit* cu)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
      art::llvm::IntrinsicHelper::PopShadowFrame);
  cu->irb->CreateCall(intr);
}

static ::llvm::Value* EmitCopy(CompilationUnit* cu, ::llvm::ArrayRef< ::llvm::Value*> src,
                             RegLocation loc)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  if (loc.wide) {
    if (loc.fp) {
      id = art::llvm::IntrinsicHelper::CopyDouble;
    } else {
      id = art::llvm::IntrinsicHelper::CopyLong;
    }
  } else {
    if (loc.fp) {
      id = art::llvm::IntrinsicHelper::CopyFloat;
    } else if (loc.ref) {
      id = art::llvm::IntrinsicHelper::CopyObj;
    } else {
      id = art::llvm::IntrinsicHelper::CopyInt;
    }
  }
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  return cu->irb->CreateCall(intr, src);
}

static void ConvertMoveException(CompilationUnit* cu, RegLocation rl_dest)
{
  ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
      art::llvm::IntrinsicHelper::GetException);
  ::llvm::Value* res = cu->irb->CreateCall(func);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertThrow(CompilationUnit* cu, RegLocation rl_src)
{
  ::llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
  ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
      art::llvm::IntrinsicHelper::HLThrowException);
  cu->irb->CreateCall(func, src);
}

static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
                                    art::llvm::IntrinsicHelper::IntrinsicId id,
                                    RegLocation rl_src)
{
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(func, args);
}

static void ConvertArrayLength(CompilationUnit* cu, int opt_flags,
                               RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(
      art::llvm::IntrinsicHelper::OptArrayLength);
  ::llvm::Value* res = cu->irb->CreateCall(func, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void EmitSuspendCheck(CompilationUnit* cu)
{
  art::llvm::IntrinsicHelper::IntrinsicId id =
      art::llvm::IntrinsicHelper::CheckSuspend;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(intr);
}

static ::llvm::Value* ConvertCompare(CompilationUnit* cu, ConditionCode cc,
                                   ::llvm::Value* src1, ::llvm::Value* src2)
{
  ::llvm::Value* res = NULL;
  DCHECK_EQ(src1->getType(), src2->getType());
  switch(cc) {
    case kCondEq: res = cu->irb->CreateICmpEQ(src1, src2); break;
    case kCondNe: res = cu->irb->CreateICmpNE(src1, src2); break;
    case kCondLt: res = cu->irb->CreateICmpSLT(src1, src2); break;
    case kCondGe: res = cu->irb->CreateICmpSGE(src1, src2); break;
    case kCondGt: res = cu->irb->CreateICmpSGT(src1, src2); break;
    case kCondLe: res = cu->irb->CreateICmpSLE(src1, src2); break;
    default: LOG(FATAL) << "Unexpected cc value " << cc;
  }
  return res;
}

static void ConvertCompareAndBranch(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
                                    ConditionCode cc, RegLocation rl_src1, RegLocation rl_src2)
{
  if (bb->taken->start_offset <= mir->offset) {
    EmitSuspendCheck(cu);
  }
  ::llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
  ::llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
  ::llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
  cond_value->setName(StringPrintf("t%d", cu->temp_name++));
  cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
                           GetLLVMBlock(cu, bb->fall_through->id));
  // Don't redo the fallthrough branch in the BB driver
  bb->fall_through = NULL;
}

static void ConvertCompareZeroAndBranch(CompilationUnit* cu, BasicBlock* bb,
                                        MIR* mir, ConditionCode cc, RegLocation rl_src1)
{
  if (bb->taken->start_offset <= mir->offset) {
    EmitSuspendCheck(cu);
  }
  ::llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
  ::llvm::Value* src2;
  if (rl_src1.ref) {
    src2 = cu->irb->getJNull();
  } else {
    src2 = cu->irb->getInt32(0);
  }
  ::llvm::Value* cond_value = ConvertCompare(cu, cc, src1, src2);
  cu->irb->CreateCondBr(cond_value, GetLLVMBlock(cu, bb->taken->id),
                           GetLLVMBlock(cu, bb->fall_through->id));
  // Don't redo the fallthrough branch in the BB driver
  bb->fall_through = NULL;
}

static ::llvm::Value* GenDivModOp(CompilationUnit* cu, bool is_div, bool is_long,
                                ::llvm::Value* src1, ::llvm::Value* src2)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  if (is_long) {
    if (is_div) {
      id = art::llvm::IntrinsicHelper::DivLong;
    } else {
      id = art::llvm::IntrinsicHelper::RemLong;
    }
  } else {
    if (is_div) {
      id = art::llvm::IntrinsicHelper::DivInt;
    } else {
      id = art::llvm::IntrinsicHelper::RemInt;
    }
  }
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2>args;
  args.push_back(src1);
  args.push_back(src2);
  return cu->irb->CreateCall(intr, args);
}

static ::llvm::Value* GenArithOp(CompilationUnit* cu, OpKind op, bool is_long,
                               ::llvm::Value* src1, ::llvm::Value* src2)
{
  ::llvm::Value* res = NULL;
  switch(op) {
    case kOpAdd: res = cu->irb->CreateAdd(src1, src2); break;
    case kOpSub: res = cu->irb->CreateSub(src1, src2); break;
    case kOpRsub: res = cu->irb->CreateSub(src2, src1); break;
    case kOpMul: res = cu->irb->CreateMul(src1, src2); break;
    case kOpOr: res = cu->irb->CreateOr(src1, src2); break;
    case kOpAnd: res = cu->irb->CreateAnd(src1, src2); break;
    case kOpXor: res = cu->irb->CreateXor(src1, src2); break;
    case kOpDiv: res = GenDivModOp(cu, true, is_long, src1, src2); break;
    case kOpRem: res = GenDivModOp(cu, false, is_long, src1, src2); break;
    case kOpLsl: res = cu->irb->CreateShl(src1, src2); break;
    case kOpLsr: res = cu->irb->CreateLShr(src1, src2); break;
    case kOpAsr: res = cu->irb->CreateAShr(src1, src2); break;
    default:
      LOG(FATAL) << "Invalid op " << op;
  }
  return res;
}

static void ConvertFPArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
                             RegLocation rl_src1, RegLocation rl_src2)
{
  ::llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
  ::llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
  ::llvm::Value* res = NULL;
  switch(op) {
    case kOpAdd: res = cu->irb->CreateFAdd(src1, src2); break;
    case kOpSub: res = cu->irb->CreateFSub(src1, src2); break;
    case kOpMul: res = cu->irb->CreateFMul(src1, src2); break;
    case kOpDiv: res = cu->irb->CreateFDiv(src1, src2); break;
    case kOpRem: res = cu->irb->CreateFRem(src1, src2); break;
    default:
      LOG(FATAL) << "Invalid op " << op;
  }
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertShift(CompilationUnit* cu, art::llvm::IntrinsicHelper::IntrinsicId id,
                         RegLocation rl_dest, RegLocation rl_src1, RegLocation rl_src2)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2>args;
  args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertShiftLit(CompilationUnit* cu, art::llvm::IntrinsicHelper::IntrinsicId id,
                            RegLocation rl_dest, RegLocation rl_src, int shift_amount)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2>args;
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  args.push_back(cu->irb->getInt32(shift_amount));
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertArithOp(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
                           RegLocation rl_src1, RegLocation rl_src2)
{
  ::llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
  ::llvm::Value* src2 = GetLLVMValue(cu, rl_src2.orig_sreg);
  DCHECK_EQ(src1->getType(), src2->getType());
  ::llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertArithOpLit(CompilationUnit* cu, OpKind op, RegLocation rl_dest,
                              RegLocation rl_src1, int32_t imm)
{
  ::llvm::Value* src1 = GetLLVMValue(cu, rl_src1.orig_sreg);
  ::llvm::Value* src2 = cu->irb->getInt32(imm);
  ::llvm::Value* res = GenArithOp(cu, op, rl_dest.wide, src1, src2);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

/*
 * Process arguments for invoke.  Note: this code is also used to
 * collect and process arguments for NEW_FILLED_ARRAY and NEW_FILLED_ARRAY_RANGE.
 * The requirements are similar.
 */
static void ConvertInvoke(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
                          InvokeType invoke_type, bool is_range, bool is_filled_new_array)
{
  Codegen* cg = cu->cg.get();
  CallInfo* info = cg->NewMemCallInfo(cu, bb, mir, invoke_type, is_range);
  ::llvm::SmallVector< ::llvm::Value*, 10> args;
  // Insert the invoke_type
  args.push_back(cu->irb->getInt32(static_cast<int>(invoke_type)));
  // Insert the method_idx
  args.push_back(cu->irb->getInt32(info->index));
  // Insert the optimization flags
  args.push_back(cu->irb->getInt32(info->opt_flags));
  // Now, insert the actual arguments
  for (int i = 0; i < info->num_arg_words;) {
    ::llvm::Value* val = GetLLVMValue(cu, info->args[i].orig_sreg);
    args.push_back(val);
    i += info->args[i].wide ? 2 : 1;
  }
  /*
   * Choose the invoke return type based on actual usage.  Note: may
   * be different than shorty.  For example, if a function return value
   * is not used, we'll treat this as a void invoke.
   */
  art::llvm::IntrinsicHelper::IntrinsicId id;
  if (is_filled_new_array) {
    id = art::llvm::IntrinsicHelper::HLFilledNewArray;
  } else if (info->result.location == kLocInvalid) {
    id = art::llvm::IntrinsicHelper::HLInvokeVoid;
  } else {
    if (info->result.wide) {
      if (info->result.fp) {
        id = art::llvm::IntrinsicHelper::HLInvokeDouble;
      } else {
        id = art::llvm::IntrinsicHelper::HLInvokeLong;
      }
    } else if (info->result.ref) {
        id = art::llvm::IntrinsicHelper::HLInvokeObj;
    } else if (info->result.fp) {
        id = art::llvm::IntrinsicHelper::HLInvokeFloat;
    } else {
        id = art::llvm::IntrinsicHelper::HLInvokeInt;
    }
  }
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  if (info->result.location != kLocInvalid) {
    DefineValue(cu, res, info->result.orig_sreg);
  }
}

static void ConvertConstObject(CompilationUnit* cu, uint32_t idx,
                               art::llvm::IntrinsicHelper::IntrinsicId id, RegLocation rl_dest)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* index = cu->irb->getInt32(idx);
  ::llvm::Value* res = cu->irb->CreateCall(intr, index);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertCheckCast(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_src)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::HLCheckCast;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(type_idx));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  cu->irb->CreateCall(intr, args);
}

static void ConvertNewInstance(CompilationUnit* cu, uint32_t type_idx, RegLocation rl_dest)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::NewInstance;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* index = cu->irb->getInt32(type_idx);
  ::llvm::Value* res = cu->irb->CreateCall(intr, index);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertNewArray(CompilationUnit* cu, uint32_t type_idx,
                            RegLocation rl_dest, RegLocation rl_src)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::NewArray;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(type_idx));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertAget(CompilationUnit* cu, int opt_flags,
                        art::llvm::IntrinsicHelper::IntrinsicId id,
                        RegLocation rl_dest, RegLocation rl_array, RegLocation rl_index)
{
  ::llvm::SmallVector< ::llvm::Value*, 3> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertAput(CompilationUnit* cu, int opt_flags,
                        art::llvm::IntrinsicHelper::IntrinsicId id,
                        RegLocation rl_src, RegLocation rl_array, RegLocation rl_index)
{
  ::llvm::SmallVector< ::llvm::Value*, 4> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_array.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_index.orig_sreg));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(intr, args);
}

static void ConvertIget(CompilationUnit* cu, int opt_flags,
                        art::llvm::IntrinsicHelper::IntrinsicId id,
                        RegLocation rl_dest, RegLocation rl_obj, int field_index)
{
  ::llvm::SmallVector< ::llvm::Value*, 3> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
  args.push_back(cu->irb->getInt32(field_index));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertIput(CompilationUnit* cu, int opt_flags,
                        art::llvm::IntrinsicHelper::IntrinsicId id,
                        RegLocation rl_src, RegLocation rl_obj, int field_index)
{
  ::llvm::SmallVector< ::llvm::Value*, 4> args;
  args.push_back(cu->irb->getInt32(opt_flags));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_obj.orig_sreg));
  args.push_back(cu->irb->getInt32(field_index));
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  cu->irb->CreateCall(intr, args);
}

static void ConvertInstanceOf(CompilationUnit* cu, uint32_t type_idx,
                              RegLocation rl_dest, RegLocation rl_src)
{
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::InstanceOf;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(cu->irb->getInt32(type_idx));
  args.push_back(GetLLVMValue(cu, rl_src.orig_sreg));
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertIntToLong(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* res = cu->irb->CreateSExt(GetLLVMValue(cu, rl_src.orig_sreg),
                                            cu->irb->getInt64Ty());
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertLongToInt(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
  ::llvm::Value* res = cu->irb->CreateTrunc(src, cu->irb->getInt32Ty());
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertFloatToDouble(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
  ::llvm::Value* res = cu->irb->CreateFPExt(src, cu->irb->getDoubleTy());
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertDoubleToFloat(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
  ::llvm::Value* res = cu->irb->CreateFPTrunc(src, cu->irb->getFloatTy());
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertWideComparison(CompilationUnit* cu,
                                  art::llvm::IntrinsicHelper::IntrinsicId id,
                                  RegLocation rl_dest, RegLocation rl_src1,
                           RegLocation rl_src2)
{
  DCHECK_EQ(rl_src1.fp, rl_src2.fp);
  DCHECK_EQ(rl_src1.wide, rl_src2.wide);
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::SmallVector< ::llvm::Value*, 2> args;
  args.push_back(GetLLVMValue(cu, rl_src1.orig_sreg));
  args.push_back(GetLLVMValue(cu, rl_src2.orig_sreg));
  ::llvm::Value* res = cu->irb->CreateCall(intr, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertIntNarrowing(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src,
                                art::llvm::IntrinsicHelper::IntrinsicId id)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res =
      cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertNeg(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* res = cu->irb->CreateNeg(GetLLVMValue(cu, rl_src.orig_sreg));
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertIntToFP(CompilationUnit* cu, ::llvm::Type* ty, RegLocation rl_dest,
                           RegLocation rl_src)
{
  ::llvm::Value* res =
      cu->irb->CreateSIToFP(GetLLVMValue(cu, rl_src.orig_sreg), ty);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertFPToInt(CompilationUnit* cu, art::llvm::IntrinsicHelper::IntrinsicId id,
                           RegLocation rl_dest,
                    RegLocation rl_src)
{
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Value* res = cu->irb->CreateCall(intr, GetLLVMValue(cu, rl_src.orig_sreg));
  DefineValue(cu, res, rl_dest.orig_sreg);
}


static void ConvertNegFP(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* res =
      cu->irb->CreateFNeg(GetLLVMValue(cu, rl_src.orig_sreg));
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void ConvertNot(CompilationUnit* cu, RegLocation rl_dest, RegLocation rl_src)
{
  ::llvm::Value* src = GetLLVMValue(cu, rl_src.orig_sreg);
  ::llvm::Value* res = cu->irb->CreateXor(src, static_cast<uint64_t>(-1));
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void EmitConstructorBarrier(CompilationUnit* cu) {
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
      art::llvm::IntrinsicHelper::ConstructorBarrier);
  cu->irb->CreateCall(intr);
}

/*
 * Target-independent code generation.  Use only high-level
 * load/store utilities here, or target-dependent genXX() handlers
 * when necessary.
 */
static bool ConvertMIRNode(CompilationUnit* cu, MIR* mir, BasicBlock* bb,
                           ::llvm::BasicBlock* llvm_bb, LIR* label_list)
{
  bool res = false;   // Assume success
  RegLocation rl_src[3];
  RegLocation rl_dest = GetBadLoc();
  Instruction::Code opcode = mir->dalvikInsn.opcode;
  int op_val = opcode;
  uint32_t vB = mir->dalvikInsn.vB;
  uint32_t vC = mir->dalvikInsn.vC;
  int opt_flags = mir->optimization_flags;

  if (cu->verbose) {
    if (op_val < kMirOpFirst) {
      LOG(INFO) << ".. " << Instruction::Name(opcode) << " 0x" << std::hex << op_val;
    } else {
      LOG(INFO) << extended_mir_op_names[op_val - kMirOpFirst] << " 0x" << std::hex << op_val;
    }
  }

  /* Prep Src and Dest locations */
  int next_sreg = 0;
  int next_loc = 0;
  int attrs = oat_data_flow_attributes[opcode];
  rl_src[0] = rl_src[1] = rl_src[2] = GetBadLoc();
  if (attrs & DF_UA) {
    if (attrs & DF_A_WIDE) {
      rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
      next_sreg+= 2;
    } else {
      rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
      next_sreg++;
    }
  }
  if (attrs & DF_UB) {
    if (attrs & DF_B_WIDE) {
      rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
      next_sreg+= 2;
    } else {
      rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
      next_sreg++;
    }
  }
  if (attrs & DF_UC) {
    if (attrs & DF_C_WIDE) {
      rl_src[next_loc++] = GetSrcWide(cu, mir, next_sreg);
    } else {
      rl_src[next_loc++] = GetSrc(cu, mir, next_sreg);
    }
  }
  if (attrs & DF_DA) {
    if (attrs & DF_A_WIDE) {
      rl_dest = GetDestWide(cu, mir);
    } else {
      rl_dest = GetDest(cu, mir);
    }
  }

  switch (opcode) {
    case Instruction::NOP:
      break;

    case Instruction::MOVE:
    case Instruction::MOVE_OBJECT:
    case Instruction::MOVE_16:
    case Instruction::MOVE_OBJECT_16:
    case Instruction::MOVE_OBJECT_FROM16:
    case Instruction::MOVE_FROM16:
    case Instruction::MOVE_WIDE:
    case Instruction::MOVE_WIDE_16:
    case Instruction::MOVE_WIDE_FROM16: {
        /*
         * Moves/copies are meaningless in pure SSA register form,
         * but we need to preserve them for the conversion back into
         * MIR (at least until we stop using the Dalvik register maps).
         * Insert a dummy intrinsic copy call, which will be recognized
         * by the quick path and removed by the portable path.
         */
        ::llvm::Value* src = GetLLVMValue(cu, rl_src[0].orig_sreg);
        ::llvm::Value* res = EmitCopy(cu, src, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;

    case Instruction::CONST:
    case Instruction::CONST_4:
    case Instruction::CONST_16: {
        ::llvm::Constant* imm_value = cu->irb->getJInt(vB);
        ::llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;

    case Instruction::CONST_WIDE_16:
    case Instruction::CONST_WIDE_32: {
        // Sign extend to 64 bits
        int64_t imm = static_cast<int32_t>(vB);
        ::llvm::Constant* imm_value = cu->irb->getJLong(imm);
        ::llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;

    case Instruction::CONST_HIGH16: {
        ::llvm::Constant* imm_value = cu->irb->getJInt(vB << 16);
        ::llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;

    case Instruction::CONST_WIDE: {
        ::llvm::Constant* imm_value =
            cu->irb->getJLong(mir->dalvikInsn.vB_wide);
        ::llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;
    case Instruction::CONST_WIDE_HIGH16: {
        int64_t imm = static_cast<int64_t>(vB) << 48;
        ::llvm::Constant* imm_value = cu->irb->getJLong(imm);
        ::llvm::Value* res = EmitConst(cu, imm_value, rl_dest);
        DefineValue(cu, res, rl_dest.orig_sreg);
      }
      break;

    case Instruction::SPUT_OBJECT:
      ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputObject,
                  rl_src[0]);
      break;
    case Instruction::SPUT:
      if (rl_src[0].fp) {
        ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputFloat,
                    rl_src[0]);
      } else {
        ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSput, rl_src[0]);
      }
      break;
    case Instruction::SPUT_BOOLEAN:
      ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputBoolean,
                  rl_src[0]);
      break;
    case Instruction::SPUT_BYTE:
      ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputByte, rl_src[0]);
      break;
    case Instruction::SPUT_CHAR:
      ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputChar, rl_src[0]);
      break;
    case Instruction::SPUT_SHORT:
      ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputShort, rl_src[0]);
      break;
    case Instruction::SPUT_WIDE:
      if (rl_src[0].fp) {
        ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputDouble,
                    rl_src[0]);
      } else {
        ConvertSput(cu, vB, art::llvm::IntrinsicHelper::HLSputWide,
                    rl_src[0]);
      }
      break;

    case Instruction::SGET_OBJECT:
      ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetObject, rl_dest);
      break;
    case Instruction::SGET:
      if (rl_dest.fp) {
        ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetFloat, rl_dest);
      } else {
        ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSget, rl_dest);
      }
      break;
    case Instruction::SGET_BOOLEAN:
      ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetBoolean, rl_dest);
      break;
    case Instruction::SGET_BYTE:
      ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetByte, rl_dest);
      break;
    case Instruction::SGET_CHAR:
      ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetChar, rl_dest);
      break;
    case Instruction::SGET_SHORT:
      ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetShort, rl_dest);
      break;
    case Instruction::SGET_WIDE:
      if (rl_dest.fp) {
        ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetDouble,
                    rl_dest);
      } else {
        ConvertSget(cu, vB, art::llvm::IntrinsicHelper::HLSgetWide, rl_dest);
      }
      break;

    case Instruction::RETURN_WIDE:
    case Instruction::RETURN:
    case Instruction::RETURN_OBJECT: {
        if (!(cu->attrs & METHOD_IS_LEAF)) {
          EmitSuspendCheck(cu);
        }
        EmitPopShadowFrame(cu);
        cu->irb->CreateRet(GetLLVMValue(cu, rl_src[0].orig_sreg));
        DCHECK(bb->terminated_by_return);
      }
      break;

    case Instruction::RETURN_VOID: {
        if (((cu->access_flags & kAccConstructor) != 0) &&
            cu->compiler_driver->RequiresConstructorBarrier(Thread::Current(),
                                                            cu->dex_file,
                                                            cu->class_def_idx)) {
          EmitConstructorBarrier(cu);
        }
        if (!(cu->attrs & METHOD_IS_LEAF)) {
          EmitSuspendCheck(cu);
        }
        EmitPopShadowFrame(cu);
        cu->irb->CreateRetVoid();
        DCHECK(bb->terminated_by_return);
      }
      break;

    case Instruction::IF_EQ:
      ConvertCompareAndBranch(cu, bb, mir, kCondEq, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_NE:
      ConvertCompareAndBranch(cu, bb, mir, kCondNe, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_LT:
      ConvertCompareAndBranch(cu, bb, mir, kCondLt, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_GE:
      ConvertCompareAndBranch(cu, bb, mir, kCondGe, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_GT:
      ConvertCompareAndBranch(cu, bb, mir, kCondGt, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_LE:
      ConvertCompareAndBranch(cu, bb, mir, kCondLe, rl_src[0], rl_src[1]);
      break;
    case Instruction::IF_EQZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondEq, rl_src[0]);
      break;
    case Instruction::IF_NEZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondNe, rl_src[0]);
      break;
    case Instruction::IF_LTZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondLt, rl_src[0]);
      break;
    case Instruction::IF_GEZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondGe, rl_src[0]);
      break;
    case Instruction::IF_GTZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondGt, rl_src[0]);
      break;
    case Instruction::IF_LEZ:
      ConvertCompareZeroAndBranch(cu, bb, mir, kCondLe, rl_src[0]);
      break;

    case Instruction::GOTO:
    case Instruction::GOTO_16:
    case Instruction::GOTO_32: {
        if (bb->taken->start_offset <= bb->start_offset) {
          EmitSuspendCheck(cu);
        }
        cu->irb->CreateBr(GetLLVMBlock(cu, bb->taken->id));
      }
      break;

    case Instruction::ADD_LONG:
    case Instruction::ADD_LONG_2ADDR:
    case Instruction::ADD_INT:
    case Instruction::ADD_INT_2ADDR:
      ConvertArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SUB_LONG:
    case Instruction::SUB_LONG_2ADDR:
    case Instruction::SUB_INT:
    case Instruction::SUB_INT_2ADDR:
      ConvertArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::MUL_LONG:
    case Instruction::MUL_LONG_2ADDR:
    case Instruction::MUL_INT:
    case Instruction::MUL_INT_2ADDR:
      ConvertArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::DIV_LONG:
    case Instruction::DIV_LONG_2ADDR:
    case Instruction::DIV_INT:
    case Instruction::DIV_INT_2ADDR:
      ConvertArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::REM_LONG:
    case Instruction::REM_LONG_2ADDR:
    case Instruction::REM_INT:
    case Instruction::REM_INT_2ADDR:
      ConvertArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AND_LONG:
    case Instruction::AND_LONG_2ADDR:
    case Instruction::AND_INT:
    case Instruction::AND_INT_2ADDR:
      ConvertArithOp(cu, kOpAnd, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::OR_LONG:
    case Instruction::OR_LONG_2ADDR:
    case Instruction::OR_INT:
    case Instruction::OR_INT_2ADDR:
      ConvertArithOp(cu, kOpOr, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::XOR_LONG:
    case Instruction::XOR_LONG_2ADDR:
    case Instruction::XOR_INT:
    case Instruction::XOR_INT_2ADDR:
      ConvertArithOp(cu, kOpXor, rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHL_LONG:
    case Instruction::SHL_LONG_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::SHLLong,
                    rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHL_INT:
    case Instruction::SHL_INT_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::SHLInt,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHR_LONG:
    case Instruction::SHR_LONG_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::SHRLong,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHR_INT:
    case Instruction::SHR_INT_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::SHRInt,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::USHR_LONG:
    case Instruction::USHR_LONG_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::USHRLong,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::USHR_INT:
    case Instruction::USHR_INT_2ADDR:
      ConvertShift(cu, art::llvm::IntrinsicHelper::USHRInt,
                   rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::ADD_INT_LIT16:
    case Instruction::ADD_INT_LIT8:
      ConvertArithOpLit(cu, kOpAdd, rl_dest, rl_src[0], vC);
      break;
    case Instruction::RSUB_INT:
    case Instruction::RSUB_INT_LIT8:
      ConvertArithOpLit(cu, kOpRsub, rl_dest, rl_src[0], vC);
      break;
    case Instruction::MUL_INT_LIT16:
    case Instruction::MUL_INT_LIT8:
      ConvertArithOpLit(cu, kOpMul, rl_dest, rl_src[0], vC);
      break;
    case Instruction::DIV_INT_LIT16:
    case Instruction::DIV_INT_LIT8:
      ConvertArithOpLit(cu, kOpDiv, rl_dest, rl_src[0], vC);
      break;
    case Instruction::REM_INT_LIT16:
    case Instruction::REM_INT_LIT8:
      ConvertArithOpLit(cu, kOpRem, rl_dest, rl_src[0], vC);
      break;
    case Instruction::AND_INT_LIT16:
    case Instruction::AND_INT_LIT8:
      ConvertArithOpLit(cu, kOpAnd, rl_dest, rl_src[0], vC);
      break;
    case Instruction::OR_INT_LIT16:
    case Instruction::OR_INT_LIT8:
      ConvertArithOpLit(cu, kOpOr, rl_dest, rl_src[0], vC);
      break;
    case Instruction::XOR_INT_LIT16:
    case Instruction::XOR_INT_LIT8:
      ConvertArithOpLit(cu, kOpXor, rl_dest, rl_src[0], vC);
      break;
    case Instruction::SHL_INT_LIT8:
      ConvertShiftLit(cu, art::llvm::IntrinsicHelper::SHLInt,
                      rl_dest, rl_src[0], vC & 0x1f);
      break;
    case Instruction::SHR_INT_LIT8:
      ConvertShiftLit(cu, art::llvm::IntrinsicHelper::SHRInt,
                      rl_dest, rl_src[0], vC & 0x1f);
      break;
    case Instruction::USHR_INT_LIT8:
      ConvertShiftLit(cu, art::llvm::IntrinsicHelper::USHRInt,
                      rl_dest, rl_src[0], vC & 0x1f);
      break;

    case Instruction::ADD_FLOAT:
    case Instruction::ADD_FLOAT_2ADDR:
    case Instruction::ADD_DOUBLE:
    case Instruction::ADD_DOUBLE_2ADDR:
      ConvertFPArithOp(cu, kOpAdd, rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::SUB_FLOAT:
    case Instruction::SUB_FLOAT_2ADDR:
    case Instruction::SUB_DOUBLE:
    case Instruction::SUB_DOUBLE_2ADDR:
      ConvertFPArithOp(cu, kOpSub, rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::MUL_FLOAT:
    case Instruction::MUL_FLOAT_2ADDR:
    case Instruction::MUL_DOUBLE:
    case Instruction::MUL_DOUBLE_2ADDR:
      ConvertFPArithOp(cu, kOpMul, rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::DIV_FLOAT:
    case Instruction::DIV_FLOAT_2ADDR:
    case Instruction::DIV_DOUBLE:
    case Instruction::DIV_DOUBLE_2ADDR:
      ConvertFPArithOp(cu, kOpDiv, rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::REM_FLOAT:
    case Instruction::REM_FLOAT_2ADDR:
    case Instruction::REM_DOUBLE:
    case Instruction::REM_DOUBLE_2ADDR:
      ConvertFPArithOp(cu, kOpRem, rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::INVOKE_STATIC:
      ConvertInvoke(cu, bb, mir, kStatic, false /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::INVOKE_STATIC_RANGE:
      ConvertInvoke(cu, bb, mir, kStatic, true /*range*/,
                    false /* NewFilledArray */);
      break;

    case Instruction::INVOKE_DIRECT:
      ConvertInvoke(cu, bb,  mir, kDirect, false /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::INVOKE_DIRECT_RANGE:
      ConvertInvoke(cu, bb, mir, kDirect, true /*range*/,
                    false /* NewFilledArray */);
      break;

    case Instruction::INVOKE_VIRTUAL:
      ConvertInvoke(cu, bb, mir, kVirtual, false /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::INVOKE_VIRTUAL_RANGE:
      ConvertInvoke(cu, bb, mir, kVirtual, true /*range*/,
                    false /* NewFilledArray */);
      break;

    case Instruction::INVOKE_SUPER:
      ConvertInvoke(cu, bb, mir, kSuper, false /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::INVOKE_SUPER_RANGE:
      ConvertInvoke(cu, bb, mir, kSuper, true /*range*/,
                    false /* NewFilledArray */);
      break;

    case Instruction::INVOKE_INTERFACE:
      ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::INVOKE_INTERFACE_RANGE:
      ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
                    false /* NewFilledArray */);
      break;
    case Instruction::FILLED_NEW_ARRAY:
      ConvertInvoke(cu, bb, mir, kInterface, false /*range*/,
                    true /* NewFilledArray */);
      break;
    case Instruction::FILLED_NEW_ARRAY_RANGE:
      ConvertInvoke(cu, bb, mir, kInterface, true /*range*/,
                    true /* NewFilledArray */);
      break;

    case Instruction::CONST_STRING:
    case Instruction::CONST_STRING_JUMBO:
      ConvertConstObject(cu, vB, art::llvm::IntrinsicHelper::ConstString,
                         rl_dest);
      break;

    case Instruction::CONST_CLASS:
      ConvertConstObject(cu, vB, art::llvm::IntrinsicHelper::ConstClass,
                         rl_dest);
      break;

    case Instruction::CHECK_CAST:
      ConvertCheckCast(cu, vB, rl_src[0]);
      break;

    case Instruction::NEW_INSTANCE:
      ConvertNewInstance(cu, vB, rl_dest);
      break;

   case Instruction::MOVE_EXCEPTION:
      ConvertMoveException(cu, rl_dest);
      break;

   case Instruction::THROW:
      ConvertThrow(cu, rl_src[0]);
      /*
       * If this throw is standalone, terminate.
       * If it might rethrow, force termination
       * of the following block.
       */
      if (bb->fall_through == NULL) {
        cu->irb->CreateUnreachable();
      } else {
        bb->fall_through->fall_through = NULL;
        bb->fall_through->taken = NULL;
      }
      break;

    case Instruction::MOVE_RESULT_WIDE:
    case Instruction::MOVE_RESULT:
    case Instruction::MOVE_RESULT_OBJECT:
      /*
       * All move_results should have been folded into the preceeding invoke.
       */
      LOG(FATAL) << "Unexpected move_result";
      break;

    case Instruction::MONITOR_ENTER:
      ConvertMonitorEnterExit(cu, opt_flags,
                              art::llvm::IntrinsicHelper::MonitorEnter,
                              rl_src[0]);
      break;

    case Instruction::MONITOR_EXIT:
      ConvertMonitorEnterExit(cu, opt_flags,
                              art::llvm::IntrinsicHelper::MonitorExit,
                              rl_src[0]);
      break;

    case Instruction::ARRAY_LENGTH:
      ConvertArrayLength(cu, opt_flags, rl_dest, rl_src[0]);
      break;

    case Instruction::NEW_ARRAY:
      ConvertNewArray(cu, vC, rl_dest, rl_src[0]);
      break;

    case Instruction::INSTANCE_OF:
      ConvertInstanceOf(cu, vC, rl_dest, rl_src[0]);
      break;

    case Instruction::AGET:
      if (rl_dest.fp) {
        ConvertAget(cu, opt_flags,
                    art::llvm::IntrinsicHelper::HLArrayGetFloat,
                    rl_dest, rl_src[0], rl_src[1]);
      } else {
        ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGet,
                    rl_dest, rl_src[0], rl_src[1]);
      }
      break;
    case Instruction::AGET_OBJECT:
      ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGetObject,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_BOOLEAN:
      ConvertAget(cu, opt_flags,
                  art::llvm::IntrinsicHelper::HLArrayGetBoolean,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_BYTE:
      ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGetByte,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_CHAR:
      ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGetChar,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_SHORT:
      ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGetShort,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_WIDE:
      if (rl_dest.fp) {
        ConvertAget(cu, opt_flags,
                    art::llvm::IntrinsicHelper::HLArrayGetDouble,
                    rl_dest, rl_src[0], rl_src[1]);
      } else {
        ConvertAget(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayGetWide,
                    rl_dest, rl_src[0], rl_src[1]);
      }
      break;

    case Instruction::APUT:
      if (rl_src[0].fp) {
        ConvertAput(cu, opt_flags,
                    art::llvm::IntrinsicHelper::HLArrayPutFloat,
                    rl_src[0], rl_src[1], rl_src[2]);
      } else {
        ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPut,
                    rl_src[0], rl_src[1], rl_src[2]);
      }
      break;
    case Instruction::APUT_OBJECT:
      ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPutObject,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_BOOLEAN:
      ConvertAput(cu, opt_flags,
                  art::llvm::IntrinsicHelper::HLArrayPutBoolean,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_BYTE:
      ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPutByte,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_CHAR:
      ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPutChar,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_SHORT:
      ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPutShort,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_WIDE:
      if (rl_src[0].fp) {
        ConvertAput(cu, opt_flags,
                    art::llvm::IntrinsicHelper::HLArrayPutDouble,
                    rl_src[0], rl_src[1], rl_src[2]);
      } else {
        ConvertAput(cu, opt_flags, art::llvm::IntrinsicHelper::HLArrayPutWide,
                    rl_src[0], rl_src[1], rl_src[2]);
      }
      break;

    case Instruction::IGET:
      if (rl_dest.fp) {
        ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetFloat,
                    rl_dest, rl_src[0], vC);
      } else {
        ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGet,
                    rl_dest, rl_src[0], vC);
      }
      break;
    case Instruction::IGET_OBJECT:
      ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetObject,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_BOOLEAN:
      ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetBoolean,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_BYTE:
      ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetByte,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_CHAR:
      ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetChar,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_SHORT:
      ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetShort,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_WIDE:
      if (rl_dest.fp) {
        ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetDouble,
                    rl_dest, rl_src[0], vC);
      } else {
        ConvertIget(cu, opt_flags, art::llvm::IntrinsicHelper::HLIGetWide,
                    rl_dest, rl_src[0], vC);
      }
      break;
    case Instruction::IPUT:
      if (rl_src[0].fp) {
        ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutFloat,
                    rl_src[0], rl_src[1], vC);
      } else {
        ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPut,
                    rl_src[0], rl_src[1], vC);
      }
      break;
    case Instruction::IPUT_OBJECT:
      ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutObject,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_BOOLEAN:
      ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutBoolean,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_BYTE:
      ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutByte,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_CHAR:
      ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutChar,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_SHORT:
      ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutShort,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_WIDE:
      if (rl_src[0].fp) {
        ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutDouble,
                    rl_src[0], rl_src[1], vC);
      } else {
        ConvertIput(cu, opt_flags, art::llvm::IntrinsicHelper::HLIPutWide,
                    rl_src[0], rl_src[1], vC);
      }
      break;

    case Instruction::FILL_ARRAY_DATA:
      ConvertFillArrayData(cu, vB, rl_src[0]);
      break;

    case Instruction::LONG_TO_INT:
      ConvertLongToInt(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::INT_TO_LONG:
      ConvertIntToLong(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::INT_TO_CHAR:
      ConvertIntNarrowing(cu, rl_dest, rl_src[0],
                          art::llvm::IntrinsicHelper::IntToChar);
      break;
    case Instruction::INT_TO_BYTE:
      ConvertIntNarrowing(cu, rl_dest, rl_src[0],
                          art::llvm::IntrinsicHelper::IntToByte);
      break;
    case Instruction::INT_TO_SHORT:
      ConvertIntNarrowing(cu, rl_dest, rl_src[0],
                          art::llvm::IntrinsicHelper::IntToShort);
      break;

    case Instruction::INT_TO_FLOAT:
    case Instruction::LONG_TO_FLOAT:
      ConvertIntToFP(cu, cu->irb->getFloatTy(), rl_dest, rl_src[0]);
      break;

    case Instruction::INT_TO_DOUBLE:
    case Instruction::LONG_TO_DOUBLE:
      ConvertIntToFP(cu, cu->irb->getDoubleTy(), rl_dest, rl_src[0]);
      break;

    case Instruction::FLOAT_TO_DOUBLE:
      ConvertFloatToDouble(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::DOUBLE_TO_FLOAT:
      ConvertDoubleToFloat(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::NEG_LONG:
    case Instruction::NEG_INT:
      ConvertNeg(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::NEG_FLOAT:
    case Instruction::NEG_DOUBLE:
      ConvertNegFP(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::NOT_LONG:
    case Instruction::NOT_INT:
      ConvertNot(cu, rl_dest, rl_src[0]);
      break;

    case Instruction::FLOAT_TO_INT:
      ConvertFPToInt(cu, art::llvm::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
      break;

    case Instruction::DOUBLE_TO_INT:
      ConvertFPToInt(cu, art::llvm::IntrinsicHelper::D2I, rl_dest, rl_src[0]);
      break;

    case Instruction::FLOAT_TO_LONG:
      ConvertFPToInt(cu, art::llvm::IntrinsicHelper::F2L, rl_dest, rl_src[0]);
      break;

    case Instruction::DOUBLE_TO_LONG:
      ConvertFPToInt(cu, art::llvm::IntrinsicHelper::D2L, rl_dest, rl_src[0]);
      break;

    case Instruction::CMPL_FLOAT:
      ConvertWideComparison(cu, art::llvm::IntrinsicHelper::CmplFloat,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPG_FLOAT:
      ConvertWideComparison(cu, art::llvm::IntrinsicHelper::CmpgFloat,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPL_DOUBLE:
      ConvertWideComparison(cu, art::llvm::IntrinsicHelper::CmplDouble,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPG_DOUBLE:
      ConvertWideComparison(cu, art::llvm::IntrinsicHelper::CmpgDouble,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMP_LONG:
      ConvertWideComparison(cu, art::llvm::IntrinsicHelper::CmpLong,
                            rl_dest, rl_src[0], rl_src[1]);
      break;

    case Instruction::PACKED_SWITCH:
      ConvertPackedSwitch(cu, bb, vB, rl_src[0]);
      break;

    case Instruction::SPARSE_SWITCH:
      ConvertSparseSwitch(cu, bb, vB, rl_src[0]);
      break;

    default:
      UNIMPLEMENTED(FATAL) << "Unsupported Dex opcode 0x" << std::hex << opcode;
      res = true;
  }
  return res;
}

static void SetDexOffset(CompilationUnit* cu, int32_t offset)
{
  cu->current_dalvik_offset = offset;
  ::llvm::SmallVector< ::llvm::Value*, 1> array_ref;
  array_ref.push_back(cu->irb->getInt32(offset));
  ::llvm::MDNode* node = ::llvm::MDNode::get(*cu->context, array_ref);
  cu->irb->SetDexOffset(node);
}

// Attach method info as metadata to special intrinsic
static void SetMethodInfo(CompilationUnit* cu)
{
  // We don't want dex offset on this
  cu->irb->SetDexOffset(NULL);
  art::llvm::IntrinsicHelper::IntrinsicId id;
  id = art::llvm::IntrinsicHelper::MethodInfo;
  ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(id);
  ::llvm::Instruction* inst = cu->irb->CreateCall(intr);
  ::llvm::SmallVector< ::llvm::Value*, 2> reg_info;
  reg_info.push_back(cu->irb->getInt32(cu->num_ins));
  reg_info.push_back(cu->irb->getInt32(cu->num_regs));
  reg_info.push_back(cu->irb->getInt32(cu->num_outs));
  reg_info.push_back(cu->irb->getInt32(cu->num_compiler_temps));
  reg_info.push_back(cu->irb->getInt32(cu->num_ssa_regs));
  ::llvm::MDNode* reg_info_node = ::llvm::MDNode::get(*cu->context, reg_info);
  inst->setMetadata("RegInfo", reg_info_node);
  int promo_size = cu->num_dalvik_registers + cu->num_compiler_temps + 1;
  ::llvm::SmallVector< ::llvm::Value*, 50> pmap;
  for (int i = 0; i < promo_size; i++) {
    PromotionMap* p = &cu->promotion_map[i];
    int32_t map_data = ((p->first_in_pair & 0xff) << 24) |
                      ((p->FpReg & 0xff) << 16) |
                      ((p->core_reg & 0xff) << 8) |
                      ((p->fp_location & 0xf) << 4) |
                      (p->core_location & 0xf);
    pmap.push_back(cu->irb->getInt32(map_data));
  }
  ::llvm::MDNode* map_node = ::llvm::MDNode::get(*cu->context, pmap);
  inst->setMetadata("PromotionMap", map_node);
  SetDexOffset(cu, cu->current_dalvik_offset);
}

static void HandlePhiNodes(CompilationUnit* cu, BasicBlock* bb, ::llvm::BasicBlock* llvm_bb)
{
  SetDexOffset(cu, bb->start_offset);
  for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {
    int opcode = mir->dalvikInsn.opcode;
    if (opcode < kMirOpFirst) {
      // Stop after first non-pseudo MIR op.
      continue;
    }
    if (opcode != kMirOpPhi) {
      // Skip other mir Pseudos.
      continue;
    }
    RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
    /*
     * The Art compiler's Phi nodes only handle 32-bit operands,
     * representing wide values using a matched set of Phi nodes
     * for the lower and upper halves.  In the llvm world, we only
     * want a single Phi for wides.  Here we will simply discard
     * the Phi node representing the high word.
     */
    if (rl_dest.high_word) {
      continue;  // No Phi node - handled via low word
    }
    int* incoming = reinterpret_cast<int*>(mir->dalvikInsn.vB);
    ::llvm::Type* phi_type =
        LlvmTypeFromLocRec(cu, rl_dest);
    ::llvm::PHINode* phi = cu->irb->CreatePHI(phi_type, mir->ssa_rep->num_uses);
    for (int i = 0; i < mir->ssa_rep->num_uses; i++) {
      RegLocation loc;
      // Don't check width here.
      loc = GetRawSrc(cu, mir, i);
      DCHECK_EQ(rl_dest.wide, loc.wide);
      DCHECK_EQ(rl_dest.wide & rl_dest.high_word, loc.wide & loc.high_word);
      DCHECK_EQ(rl_dest.fp, loc.fp);
      DCHECK_EQ(rl_dest.core, loc.core);
      DCHECK_EQ(rl_dest.ref, loc.ref);
      SafeMap<unsigned int, unsigned int>::iterator it;
      it = cu->block_id_map.find(incoming[i]);
      DCHECK(it != cu->block_id_map.end());
      DCHECK(GetLLVMValue(cu, loc.orig_sreg) != NULL);
      DCHECK(GetLLVMBlock(cu, it->second) != NULL);
      phi->addIncoming(GetLLVMValue(cu, loc.orig_sreg),
                       GetLLVMBlock(cu, it->second));
    }
    DefineValueOnly(cu, phi, rl_dest.orig_sreg);
  }
}

/* Extended MIR instructions like PHI */
static void ConvertExtendedMIR(CompilationUnit* cu, BasicBlock* bb, MIR* mir,
                               ::llvm::BasicBlock* llvm_bb)
{

  switch (static_cast<ExtendedMIROpcode>(mir->dalvikInsn.opcode)) {
    case kMirOpPhi: {
      // The llvm Phi node already emitted - just DefineValue() here.
      RegLocation rl_dest = cu->reg_location[mir->ssa_rep->defs[0]];
      if (!rl_dest.high_word) {
        // Only consider low word of pairs.
        DCHECK(GetLLVMValue(cu, rl_dest.orig_sreg) != NULL);
        ::llvm::Value* phi = GetLLVMValue(cu, rl_dest.orig_sreg);
        if (1) SetVregOnValue(cu, phi, rl_dest.orig_sreg);
      }
      break;
    }
    case kMirOpCopy: {
      UNIMPLEMENTED(WARNING) << "unimp kMirOpPhi";
      break;
    }
    case kMirOpNop:
      if ((mir == bb->last_mir_insn) && (bb->taken == NULL) &&
          (bb->fall_through == NULL)) {
        cu->irb->CreateUnreachable();
      }
      break;

    // TODO: need GBC intrinsic to take advantage of fused operations
    case kMirOpFusedCmplFloat:
      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpFloat unsupported";
      break;
    case kMirOpFusedCmpgFloat:
      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmgFloat unsupported";
      break;
    case kMirOpFusedCmplDouble:
      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmplDouble unsupported";
      break;
    case kMirOpFusedCmpgDouble:
      UNIMPLEMENTED(FATAL) << "kMirOpFusedCmpgDouble unsupported";
      break;
    case kMirOpFusedCmpLong:
      UNIMPLEMENTED(FATAL) << "kMirOpLongCmpBranch unsupported";
      break;
    default:
      break;
  }
}

/* Handle the content in each basic block */
static bool BlockBitcodeConversion(CompilationUnit* cu, BasicBlock* bb)
{
  if (bb->block_type == kDead) return false;
  ::llvm::BasicBlock* llvm_bb = GetLLVMBlock(cu, bb->id);
  if (llvm_bb == NULL) {
    CHECK(bb->block_type == kExitBlock);
  } else {
    cu->irb->SetInsertPoint(llvm_bb);
    SetDexOffset(cu, bb->start_offset);
  }

  if (cu->verbose) {
    LOG(INFO) << "................................";
    LOG(INFO) << "Block id " << bb->id;
    if (llvm_bb != NULL) {
      LOG(INFO) << "label " << llvm_bb->getName().str().c_str();
    } else {
      LOG(INFO) << "llvm_bb is NULL";
    }
  }

  if (bb->block_type == kEntryBlock) {
    SetMethodInfo(cu);

    { // Allocate shadowframe.
      art::llvm::IntrinsicHelper::IntrinsicId id =
              art::llvm::IntrinsicHelper::AllocaShadowFrame;
      ::llvm::Function* func = cu->intrinsic_helper->GetIntrinsicFunction(id);
      ::llvm::Value* entries = cu->irb->getInt32(cu->num_dalvik_registers);
      cu->irb->CreateCall(func, entries);
    }

    { // Store arguments to vregs.
      uint16_t arg_reg = cu->num_regs;

      ::llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
      ::llvm::Function::arg_iterator arg_end(cu->func->arg_end());

      const char* shorty = cu->shorty;
      uint32_t shorty_size = strlen(shorty);
      CHECK_GE(shorty_size, 1u);

      ++arg_iter; // skip method object

      if ((cu->access_flags & kAccStatic) == 0) {
        SetVregOnValue(cu, arg_iter, arg_reg);
        ++arg_iter;
        ++arg_reg;
      }

      for (uint32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
        SetVregOnValue(cu, arg_iter, arg_reg);

        ++arg_reg;
        if (shorty[i] == 'J' || shorty[i] == 'D') {
          // Wide types, such as long and double, are using a pair of registers
          // to store the value, so we have to increase arg_reg again.
          ++arg_reg;
        }
      }
    }
  } else if (bb->block_type == kExitBlock) {
    /*
     * Because of the differences between how MIR/LIR and llvm handle exit
     * blocks, we won't explicitly covert them.  On the llvm-to-lir
     * path, it will need to be regenereated.
     */
    return false;
  } else if (bb->block_type == kExceptionHandling) {
    /*
     * Because we're deferring null checking, delete the associated empty
     * exception block.
     */
    llvm_bb->eraseFromParent();
    return false;
  }

  HandlePhiNodes(cu, bb, llvm_bb);

  for (MIR* mir = bb->first_mir_insn; mir != NULL; mir = mir->next) {

    SetDexOffset(cu, mir->offset);

    int opcode = mir->dalvikInsn.opcode;
    Instruction::Format dalvik_format =
        Instruction::FormatOf(mir->dalvikInsn.opcode);

    if (opcode == kMirOpCheck) {
      // Combine check and work halves of throwing instruction.
      MIR* work_half = mir->meta.throw_insn;
      mir->dalvikInsn.opcode = work_half->dalvikInsn.opcode;
      opcode = mir->dalvikInsn.opcode;
      SSARepresentation* ssa_rep = work_half->ssa_rep;
      work_half->ssa_rep = mir->ssa_rep;
      mir->ssa_rep = ssa_rep;
      work_half->meta.original_opcode = work_half->dalvikInsn.opcode;
      work_half->dalvikInsn.opcode = static_cast<Instruction::Code>(kMirOpNop);
      if (bb->successor_block_list.block_list_type == kCatch) {
        ::llvm::Function* intr = cu->intrinsic_helper->GetIntrinsicFunction(
            art::llvm::IntrinsicHelper::CatchTargets);
        ::llvm::Value* switch_key =
            cu->irb->CreateCall(intr, cu->irb->getInt32(mir->offset));
        GrowableListIterator iter;
        GrowableListIteratorInit(&bb->successor_block_list.blocks, &iter);
        // New basic block to use for work half
        ::llvm::BasicBlock* work_bb =
            ::llvm::BasicBlock::Create(*cu->context, "", cu->func);
        ::llvm::SwitchInst* sw =
            cu->irb->CreateSwitch(switch_key, work_bb,
                                     bb->successor_block_list.blocks.num_used);
        while (true) {
          SuccessorBlockInfo *successor_block_info =
              reinterpret_cast<SuccessorBlockInfo*>(GrowableListIteratorNext(&iter));
          if (successor_block_info == NULL) break;
          ::llvm::BasicBlock *target =
              GetLLVMBlock(cu, successor_block_info->block->id);
          int type_index = successor_block_info->key;
          sw->addCase(cu->irb->getInt32(type_index), target);
        }
        llvm_bb = work_bb;
        cu->irb->SetInsertPoint(llvm_bb);
      }
    }

    if (opcode >= kMirOpFirst) {
      ConvertExtendedMIR(cu, bb, mir, llvm_bb);
      continue;
    }

    bool not_handled = ConvertMIRNode(cu, mir, bb, llvm_bb,
                                     NULL /* label_list */);
    if (not_handled) {
      Instruction::Code dalvik_opcode = static_cast<Instruction::Code>(opcode);
      LOG(WARNING) << StringPrintf("%#06x: Op %#x (%s) / Fmt %d not handled",
                                   mir->offset, opcode,
                                   Instruction::Name(dalvik_opcode),
                                   dalvik_format);
    }
  }

  if (bb->block_type == kEntryBlock) {
    cu->entryTarget_bb = GetLLVMBlock(cu, bb->fall_through->id);
  } else if ((bb->fall_through != NULL) && !bb->terminated_by_return) {
    cu->irb->CreateBr(GetLLVMBlock(cu, bb->fall_through->id));
  }

  return false;
}

char RemapShorty(char shorty_type) {
  /*
   * TODO: might want to revisit this.  Dalvik registers are 32-bits wide,
   * and longs/doubles are represented as a pair of registers.  When sub-word
   * arguments (and method results) are passed, they are extended to Dalvik
   * virtual register containers.  Because llvm is picky about type consistency,
   * we must either cast the "real" type to 32-bit container multiple Dalvik
   * register types, or always use the expanded values.
   * Here, we're doing the latter.  We map the shorty signature to container
   * types (which is valid so long as we always do a real expansion of passed
   * arguments and field loads).
   */
  switch(shorty_type) {
    case 'Z' : shorty_type = 'I'; break;
    case 'B' : shorty_type = 'I'; break;
    case 'S' : shorty_type = 'I'; break;
    case 'C' : shorty_type = 'I'; break;
    default: break;
  }
  return shorty_type;
}

static ::llvm::FunctionType* GetFunctionType(CompilationUnit* cu) {

  // Get return type
  ::llvm::Type* ret_type = cu->irb->getJType(RemapShorty(cu->shorty[0]));

  // Get argument type
  std::vector< ::llvm::Type*> args_type;

  // method object
  args_type.push_back(cu->irb->getJMethodTy());

  // Do we have  a "this"?
  if ((cu->access_flags & kAccStatic) == 0) {
    args_type.push_back(cu->irb->getJObjectTy());
  }

  for (uint32_t i = 1; i < strlen(cu->shorty); ++i) {
    args_type.push_back(cu->irb->getJType(RemapShorty(cu->shorty[i])));
  }

  return ::llvm::FunctionType::get(ret_type, args_type, false);
}

static bool CreateFunction(CompilationUnit* cu) {
  std::string func_name(PrettyMethod(cu->method_idx, *cu->dex_file,
                                     /* with_signature */ false));
  ::llvm::FunctionType* func_type = GetFunctionType(cu);

  if (func_type == NULL) {
    return false;
  }

  cu->func = ::llvm::Function::Create(func_type,
                                       ::llvm::Function::ExternalLinkage,
                                       func_name, cu->module);

  ::llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
  ::llvm::Function::arg_iterator arg_end(cu->func->arg_end());

  arg_iter->setName("method");
  ++arg_iter;

  int start_sreg = cu->num_regs;

  for (unsigned i = 0; arg_iter != arg_end; ++i, ++arg_iter) {
    arg_iter->setName(StringPrintf("v%i_0", start_sreg));
    start_sreg += cu->reg_location[start_sreg].wide ? 2 : 1;
  }

  return true;
}

static bool CreateLLVMBasicBlock(CompilationUnit* cu, BasicBlock* bb)
{
  // Skip the exit block
  if ((bb->block_type == kDead) ||(bb->block_type == kExitBlock)) {
    cu->id_to_block_map.Put(bb->id, NULL);
  } else {
    int offset = bb->start_offset;
    bool entry_block = (bb->block_type == kEntryBlock);
    ::llvm::BasicBlock* llvm_bb =
        ::llvm::BasicBlock::Create(*cu->context, entry_block ? "entry" :
                                 StringPrintf(kLabelFormat, bb->catch_entry ? kCatchBlock :
                                              kNormalBlock, offset, bb->id), cu->func);
    if (entry_block) {
        cu->entry_bb = llvm_bb;
        cu->placeholder_bb =
            ::llvm::BasicBlock::Create(*cu->context, "placeholder",
                                     cu->func);
    }
    cu->id_to_block_map.Put(bb->id, llvm_bb);
  }
  return false;
}


/*
 * Convert MIR to LLVM_IR
 *  o For each ssa name, create LLVM named value.  Type these
 *    appropriately, and ignore high half of wide and double operands.
 *  o For each MIR basic block, create an LLVM basic block.
 *  o Iterate through the MIR a basic block at a time, setting arguments
 *    to recovered ssa name.
 */
void MethodMIR2Bitcode(CompilationUnit* cu)
{
  InitIR(cu);
  CompilerInitGrowableList(cu, &cu->llvm_values, cu->num_ssa_regs);

  // Create the function
  CreateFunction(cu);

  // Create an LLVM basic block for each MIR block in dfs preorder
  DataFlowAnalysisDispatcher(cu, CreateLLVMBasicBlock,
                                kPreOrderDFSTraversal, false /* is_iterative */);
  /*
   * Create an llvm named value for each MIR SSA name.  Note: we'll use
   * placeholders for all non-argument values (because we haven't seen
   * the definition yet).
   */
  cu->irb->SetInsertPoint(cu->placeholder_bb);
  ::llvm::Function::arg_iterator arg_iter(cu->func->arg_begin());
  arg_iter++;  /* Skip path method */
  for (int i = 0; i < cu->num_ssa_regs; i++) {
    ::llvm::Value* val;
    RegLocation rl_temp = cu->reg_location[i];
    if ((SRegToVReg(cu, i) < 0) || rl_temp.high_word) {
      InsertGrowableList(cu, &cu->llvm_values, 0);
    } else if ((i < cu->num_regs) ||
               (i >= (cu->num_regs + cu->num_ins))) {
      ::llvm::Constant* imm_value = cu->reg_location[i].wide ?
         cu->irb->getJLong(0) : cu->irb->getJInt(0);
      val = EmitConst(cu, imm_value, cu->reg_location[i]);
      val->setName(LlvmSSAName(cu, i));
      InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(val));
    } else {
      // Recover previously-created argument values
      ::llvm::Value* arg_val = arg_iter++;
      InsertGrowableList(cu, &cu->llvm_values, reinterpret_cast<uintptr_t>(arg_val));
    }
  }

  DataFlowAnalysisDispatcher(cu, BlockBitcodeConversion,
                                kPreOrderDFSTraversal, false /* Iterative */);

  /*
   * In a few rare cases of verification failure, the verifier will
   * replace one or more Dalvik opcodes with the special
   * throw-verification-failure opcode.  This can leave the SSA graph
   * in an invalid state, as definitions may be lost, while uses retained.
   * To work around this problem, we insert placeholder definitions for
   * all Dalvik SSA regs in the "placeholder" block.  Here, after
   * bitcode conversion is complete, we examine those placeholder definitions
   * and delete any with no references (which normally is all of them).
   *
   * If any definitions remain, we link the placeholder block into the
   * CFG.  Otherwise, it is deleted.
   */
  for (::llvm::BasicBlock::iterator it = cu->placeholder_bb->begin(),
       it_end = cu->placeholder_bb->end(); it != it_end;) {
    ::llvm::Instruction* inst = ::llvm::dyn_cast< ::llvm::Instruction>(it++);
    DCHECK(inst != NULL);
    ::llvm::Value* val = ::llvm::dyn_cast< ::llvm::Value>(inst);
    DCHECK(val != NULL);
    if (val->getNumUses() == 0) {
      inst->eraseFromParent();
    }
  }
  SetDexOffset(cu, 0);
  if (cu->placeholder_bb->empty()) {
    cu->placeholder_bb->eraseFromParent();
  } else {
    cu->irb->SetInsertPoint(cu->placeholder_bb);
    cu->irb->CreateBr(cu->entryTarget_bb);
    cu->entryTarget_bb = cu->placeholder_bb;
  }
  cu->irb->SetInsertPoint(cu->entry_bb);
  cu->irb->CreateBr(cu->entryTarget_bb);

  if (cu->enable_debug & (1 << kDebugVerifyBitcode)) {
     if (::llvm::verifyFunction(*cu->func, ::llvm::PrintMessageAction)) {
       LOG(INFO) << "Bitcode verification FAILED for "
                 << PrettyMethod(cu->method_idx, *cu->dex_file)
                 << " of size " << cu->insns_size;
       cu->enable_debug |= (1 << kDebugDumpBitcodeFile);
     }
  }

  if (cu->enable_debug & (1 << kDebugDumpBitcodeFile)) {
    // Write bitcode to file
    std::string errmsg;
    std::string fname(PrettyMethod(cu->method_idx, *cu->dex_file));
    ReplaceSpecialChars(fname);
    // TODO: make configurable change naming mechanism to avoid fname length issues.
    fname = StringPrintf("/sdcard/Bitcode/%s.bc", fname.c_str());

    if (fname.size() > 240) {
      LOG(INFO) << "Warning: bitcode filename too long. Truncated.";
      fname.resize(240);
    }

    ::llvm::OwningPtr< ::llvm::tool_output_file> out_file(
        new ::llvm::tool_output_file(fname.c_str(), errmsg,
                                   ::llvm::raw_fd_ostream::F_Binary));

    if (!errmsg.empty()) {
      LOG(ERROR) << "Failed to create bitcode output file: " << errmsg;
    }

    ::llvm::WriteBitcodeToFile(cu->module, out_file->os());
    out_file->keep();
  }
}

static RegLocation GetLoc(CompilationUnit* cu, ::llvm::Value* val) {
  RegLocation res;
  DCHECK(val != NULL);
  SafeMap< ::llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
  if (it == cu->loc_map.end()) {
    std::string val_name = val->getName().str();
    if (val_name.empty()) {
      // FIXME: need to be more robust, handle FP and be in a position to
      // manage unnamed temps whose lifetimes span basic block boundaries
      UNIMPLEMENTED(WARNING) << "Need to handle unnamed llvm temps";
      memset(&res, 0, sizeof(res));
      res.location = kLocPhysReg;
      res.low_reg = AllocTemp(cu);
      res.home = true;
      res.s_reg_low = INVALID_SREG;
      res.orig_sreg = INVALID_SREG;
      ::llvm::Type* ty = val->getType();
      res.wide = ((ty == cu->irb->getInt64Ty()) ||
                  (ty == cu->irb->getDoubleTy()));
      if (res.wide) {
        res.high_reg = AllocTemp(cu);
      }
      cu->loc_map.Put(val, res);
    } else {
      DCHECK_EQ(val_name[0], 'v');
      int base_sreg = INVALID_SREG;
      sscanf(val_name.c_str(), "v%d_", &base_sreg);
      res = cu->reg_location[base_sreg];
      cu->loc_map.Put(val, res);
    }
  } else {
    res = it->second;
  }
  return res;
}

static Instruction::Code GetDalvikOpcode(OpKind op, bool is_const, bool is_wide)
{
  Instruction::Code res = Instruction::NOP;
  if (is_wide) {
    switch(op) {
      case kOpAdd: res = Instruction::ADD_LONG; break;
      case kOpSub: res = Instruction::SUB_LONG; break;
      case kOpMul: res = Instruction::MUL_LONG; break;
      case kOpDiv: res = Instruction::DIV_LONG; break;
      case kOpRem: res = Instruction::REM_LONG; break;
      case kOpAnd: res = Instruction::AND_LONG; break;
      case kOpOr: res = Instruction::OR_LONG; break;
      case kOpXor: res = Instruction::XOR_LONG; break;
      case kOpLsl: res = Instruction::SHL_LONG; break;
      case kOpLsr: res = Instruction::USHR_LONG; break;
      case kOpAsr: res = Instruction::SHR_LONG; break;
      default: LOG(FATAL) << "Unexpected OpKind " << op;
    }
  } else if (is_const){
    switch(op) {
      case kOpAdd: res = Instruction::ADD_INT_LIT16; break;
      case kOpSub: res = Instruction::RSUB_INT_LIT8; break;
      case kOpMul: res = Instruction::MUL_INT_LIT16; break;
      case kOpDiv: res = Instruction::DIV_INT_LIT16; break;
      case kOpRem: res = Instruction::REM_INT_LIT16; break;
      case kOpAnd: res = Instruction::AND_INT_LIT16; break;
      case kOpOr: res = Instruction::OR_INT_LIT16; break;
      case kOpXor: res = Instruction::XOR_INT_LIT16; break;
      case kOpLsl: res = Instruction::SHL_INT_LIT8; break;
      case kOpLsr: res = Instruction::USHR_INT_LIT8; break;
      case kOpAsr: res = Instruction::SHR_INT_LIT8; break;
      default: LOG(FATAL) << "Unexpected OpKind " << op;
    }
  } else {
    switch(op) {
      case kOpAdd: res = Instruction::ADD_INT; break;
      case kOpSub: res = Instruction::SUB_INT; break;
      case kOpMul: res = Instruction::MUL_INT; break;
      case kOpDiv: res = Instruction::DIV_INT; break;
      case kOpRem: res = Instruction::REM_INT; break;
      case kOpAnd: res = Instruction::AND_INT; break;
      case kOpOr: res = Instruction::OR_INT; break;
      case kOpXor: res = Instruction::XOR_INT; break;
      case kOpLsl: res = Instruction::SHL_INT; break;
      case kOpLsr: res = Instruction::USHR_INT; break;
      case kOpAsr: res = Instruction::SHR_INT; break;
      default: LOG(FATAL) << "Unexpected OpKind " << op;
    }
  }
  return res;
}

static Instruction::Code GetDalvikFPOpcode(OpKind op, bool is_const, bool is_wide)
{
  Instruction::Code res = Instruction::NOP;
  if (is_wide) {
    switch(op) {
      case kOpAdd: res = Instruction::ADD_DOUBLE; break;
      case kOpSub: res = Instruction::SUB_DOUBLE; break;
      case kOpMul: res = Instruction::MUL_DOUBLE; break;
      case kOpDiv: res = Instruction::DIV_DOUBLE; break;
      case kOpRem: res = Instruction::REM_DOUBLE; break;
      default: LOG(FATAL) << "Unexpected OpKind " << op;
    }
  } else {
    switch(op) {
      case kOpAdd: res = Instruction::ADD_FLOAT; break;
      case kOpSub: res = Instruction::SUB_FLOAT; break;
      case kOpMul: res = Instruction::MUL_FLOAT; break;
      case kOpDiv: res = Instruction::DIV_FLOAT; break;
      case kOpRem: res = Instruction::REM_FLOAT; break;
      default: LOG(FATAL) << "Unexpected OpKind " << op;
    }
  }
  return res;
}

static void CvtBinFPOp(CompilationUnit* cu, OpKind op, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  /*
   * Normally, we won't ever generate an FP operation with an immediate
   * operand (not supported in Dex instruction set).  However, the IR builder
   * may insert them - in particular for create_neg_fp.  Recognize this case
   * and deal with it.
   */
  ::llvm::ConstantFP* op1C = ::llvm::dyn_cast< ::llvm::ConstantFP>(inst->getOperand(0));
  ::llvm::ConstantFP* op2C = ::llvm::dyn_cast< ::llvm::ConstantFP>(inst->getOperand(1));
  DCHECK(op2C == NULL);
  if ((op1C != NULL) && (op == kOpSub)) {
    RegLocation rl_src = GetLoc(cu, inst->getOperand(1));
    if (rl_dest.wide) {
      cg->GenArithOpDouble(cu, Instruction::NEG_DOUBLE, rl_dest, rl_src, rl_src);
    } else {
      cg->GenArithOpFloat(cu, Instruction::NEG_FLOAT, rl_dest, rl_src, rl_src);
    }
  } else {
    DCHECK(op1C == NULL);
    RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
    RegLocation rl_src2 = GetLoc(cu, inst->getOperand(1));
    Instruction::Code dalvik_op = GetDalvikFPOpcode(op, false, rl_dest.wide);
    if (rl_dest.wide) {
      cg->GenArithOpDouble(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
    } else {
      cg->GenArithOpFloat(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
    }
  }
}

static void CvtIntNarrowing(CompilationUnit* cu, ::llvm::Instruction* inst,
                     Instruction::Code opcode)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  cg->GenIntNarrowing(cu, opcode, rl_dest, rl_src);
}

static void CvtIntToFP(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  Instruction::Code opcode;
  if (rl_dest.wide) {
    if (rl_src.wide) {
      opcode = Instruction::LONG_TO_DOUBLE;
    } else {
      opcode = Instruction::INT_TO_DOUBLE;
    }
  } else {
    if (rl_src.wide) {
      opcode = Instruction::LONG_TO_FLOAT;
    } else {
      opcode = Instruction::INT_TO_FLOAT;
    }
  }
  cg->GenConversion(cu, opcode, rl_dest, rl_src);
}

static void CvtFPToInt(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  RegLocation rl_src = GetLoc(cu, call_inst->getOperand(0));
  Instruction::Code opcode;
  if (rl_dest.wide) {
    if (rl_src.wide) {
      opcode = Instruction::DOUBLE_TO_LONG;
    } else {
      opcode = Instruction::FLOAT_TO_LONG;
    }
  } else {
    if (rl_src.wide) {
      opcode = Instruction::DOUBLE_TO_INT;
    } else {
      opcode = Instruction::FLOAT_TO_INT;
    }
  }
  cg->GenConversion(cu, opcode, rl_dest, rl_src);
}

static void CvtFloatToDouble(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  cg->GenConversion(cu, Instruction::FLOAT_TO_DOUBLE, rl_dest, rl_src);
}

static void CvtTrunc(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  rl_src = UpdateLocWide(cu, rl_src);
  rl_src = WideToNarrow(cu, rl_src);
  cg->StoreValue(cu, rl_dest, rl_src);
}

static void CvtDoubleToFloat(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  cg->GenConversion(cu, Instruction::DOUBLE_TO_FLOAT, rl_dest, rl_src);
}


static void CvtIntExt(CompilationUnit* cu, ::llvm::Instruction* inst, bool is_signed)
{
  Codegen* cg = cu->cg.get();
  // TODO: evaluate src/tgt types and add general support for more than int to long
  RegLocation rl_dest = GetLoc(cu, inst);
  RegLocation rl_src = GetLoc(cu, inst->getOperand(0));
  DCHECK(rl_dest.wide);
  DCHECK(!rl_src.wide);
  DCHECK(!rl_dest.fp);
  DCHECK(!rl_src.fp);
  RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
  if (rl_src.location == kLocPhysReg) {
    cg->OpRegCopy(cu, rl_result.low_reg, rl_src.low_reg);
  } else {
    cg->LoadValueDirect(cu, rl_src, rl_result.low_reg);
  }
  if (is_signed) {
    cg->OpRegRegImm(cu, kOpAsr, rl_result.high_reg, rl_result.low_reg, 31);
  } else {
    cg->LoadConstant(cu, rl_result.high_reg, 0);
  }
  cg->StoreValueWide(cu, rl_dest, rl_result);
}

static void CvtBinOp(CompilationUnit* cu, OpKind op, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, inst);
  ::llvm::Value* lhs = inst->getOperand(0);
  // Special-case RSUB/NEG
  ::llvm::ConstantInt* lhs_imm = ::llvm::dyn_cast< ::llvm::ConstantInt>(lhs);
  if ((op == kOpSub) && (lhs_imm != NULL)) {
    RegLocation rl_src1 = GetLoc(cu, inst->getOperand(1));
    if (rl_src1.wide) {
      DCHECK_EQ(lhs_imm->getSExtValue(), 0);
      cg->GenArithOpLong(cu, Instruction::NEG_LONG, rl_dest, rl_src1, rl_src1);
    } else {
      cg->GenArithOpIntLit(cu, Instruction::RSUB_INT, rl_dest, rl_src1,
                       lhs_imm->getSExtValue());
    }
    return;
  }
  DCHECK(lhs_imm == NULL);
  RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
  ::llvm::Value* rhs = inst->getOperand(1);
  ::llvm::ConstantInt* const_rhs = ::llvm::dyn_cast< ::llvm::ConstantInt>(rhs);
  if (!rl_dest.wide && (const_rhs != NULL)) {
    Instruction::Code dalvik_op = GetDalvikOpcode(op, true, false);
    cg->GenArithOpIntLit(cu, dalvik_op, rl_dest, rl_src1, const_rhs->getSExtValue());
  } else {
    Instruction::Code dalvik_op = GetDalvikOpcode(op, false, rl_dest.wide);
    RegLocation rl_src2;
    if (const_rhs != NULL) {
      // ir_builder converts NOT_LONG to xor src, -1.  Restore
      DCHECK_EQ(dalvik_op, Instruction::XOR_LONG);
      DCHECK_EQ(-1L, const_rhs->getSExtValue());
      dalvik_op = Instruction::NOT_LONG;
      rl_src2 = rl_src1;
    } else {
      rl_src2 = GetLoc(cu, rhs);
    }
    if (rl_dest.wide) {
      cg->GenArithOpLong(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
    } else {
      cg->GenArithOpInt(cu, dalvik_op, rl_dest, rl_src1, rl_src2);
    }
  }
}

static void CvtShiftOp(CompilationUnit* cu, Instruction::Code opcode, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  RegLocation rl_dest = GetLoc(cu, call_inst);
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
  ::llvm::Value* rhs = call_inst->getArgOperand(1);
  if (::llvm::ConstantInt* src2 = ::llvm::dyn_cast< ::llvm::ConstantInt>(rhs)) {
    DCHECK(!rl_dest.wide);
    cg->GenArithOpIntLit(cu, opcode, rl_dest, rl_src, src2->getSExtValue());
  } else {
    RegLocation rl_shift = GetLoc(cu, rhs);
    if (call_inst->getType() == cu->irb->getInt64Ty()) {
      cg->GenShiftOpLong(cu, opcode, rl_dest, rl_src, rl_shift);
    } else {
      cg->GenArithOpInt(cu, opcode, rl_dest, rl_src, rl_shift);
    }
  }
}

static void CvtBr(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  ::llvm::BranchInst* br_inst = ::llvm::dyn_cast< ::llvm::BranchInst>(inst);
  DCHECK(br_inst != NULL);
  DCHECK(br_inst->isUnconditional());  // May change - but this is all we use now
  ::llvm::BasicBlock* target_bb = br_inst->getSuccessor(0);
  cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
}

static void CvtPhi(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  // Nop - these have already been processed
}

static void CvtRet(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  ::llvm::ReturnInst* ret_inst = ::llvm::dyn_cast< ::llvm::ReturnInst>(inst);
  ::llvm::Value* ret_val = ret_inst->getReturnValue();
  if (ret_val != NULL) {
    RegLocation rl_src = GetLoc(cu, ret_val);
    if (rl_src.wide) {
      cg->StoreValueWide(cu, GetReturnWide(cu, rl_src.fp), rl_src);
    } else {
      cg->StoreValue(cu, GetReturn(cu, rl_src.fp), rl_src);
    }
  }
  cg->GenExitSequence(cu);
}

static ConditionCode GetCond(::llvm::ICmpInst::Predicate llvm_cond)
{
  ConditionCode res = kCondAl;
  switch(llvm_cond) {
    case ::llvm::ICmpInst::ICMP_EQ: res = kCondEq; break;
    case ::llvm::ICmpInst::ICMP_NE: res = kCondNe; break;
    case ::llvm::ICmpInst::ICMP_SLT: res = kCondLt; break;
    case ::llvm::ICmpInst::ICMP_SGE: res = kCondGe; break;
    case ::llvm::ICmpInst::ICMP_SGT: res = kCondGt; break;
    case ::llvm::ICmpInst::ICMP_SLE: res = kCondLe; break;
    default: LOG(FATAL) << "Unexpected llvm condition";
  }
  return res;
}

static void CvtICmp(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  // cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2)
  UNIMPLEMENTED(FATAL);
}

static void CvtICmpBr(CompilationUnit* cu, ::llvm::Instruction* inst,
               ::llvm::BranchInst* br_inst)
{
  Codegen* cg = cu->cg.get();
  // Get targets
  ::llvm::BasicBlock* taken_bb = br_inst->getSuccessor(0);
  LIR* taken = cu->block_to_label_map.Get(taken_bb);
  ::llvm::BasicBlock* fallthrough_bb = br_inst->getSuccessor(1);
  LIR* fall_through = cu->block_to_label_map.Get(fallthrough_bb);
  // Get comparison operands
  ::llvm::ICmpInst* i_cmp_inst = ::llvm::dyn_cast< ::llvm::ICmpInst>(inst);
  ConditionCode cond = GetCond(i_cmp_inst->getPredicate());
  ::llvm::Value* lhs = i_cmp_inst->getOperand(0);
  // Not expecting a constant as 1st operand
  DCHECK(::llvm::dyn_cast< ::llvm::ConstantInt>(lhs) == NULL);
  RegLocation rl_src1 = GetLoc(cu, inst->getOperand(0));
  rl_src1 = cg->LoadValue(cu, rl_src1, kCoreReg);
  ::llvm::Value* rhs = inst->getOperand(1);
  if (cu->instruction_set == kMips) {
    // Compare and branch in one shot
    UNIMPLEMENTED(FATAL);
  }
  //Compare, then branch
  // TODO: handle fused CMP_LONG/IF_xxZ case
  if (::llvm::ConstantInt* src2 = ::llvm::dyn_cast< ::llvm::ConstantInt>(rhs)) {
    cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, src2->getSExtValue());
  } else if (::llvm::dyn_cast< ::llvm::ConstantPointerNull>(rhs) != NULL) {
    cg->OpRegImm(cu, kOpCmp, rl_src1.low_reg, 0);
  } else {
    RegLocation rl_src2 = GetLoc(cu, rhs);
    rl_src2 = cg->LoadValue(cu, rl_src2, kCoreReg);
    cg->OpRegReg(cu, kOpCmp, rl_src1.low_reg, rl_src2.low_reg);
  }
  cg->OpCondBranch(cu, cond, taken);
  // Fallthrough
  cg->OpUnconditionalBranch(cu, fall_through);
}

static void CvtCopy(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(0));
  RegLocation rl_dest = GetLoc(cu, call_inst);
  DCHECK_EQ(rl_src.wide, rl_dest.wide);
  DCHECK_EQ(rl_src.fp, rl_dest.fp);
  if (rl_src.wide) {
    cg->StoreValueWide(cu, rl_dest, rl_src);
  } else {
    cg->StoreValue(cu, rl_dest, rl_src);
  }
}

// Note: Immediate arg is a ConstantInt regardless of result type
static void CvtConst(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  ::llvm::ConstantInt* src =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint64_t immval = src->getZExtValue();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  RegLocation rl_result = EvalLoc(cu, rl_dest, kAnyReg, true);
  if (rl_dest.wide) {
    cg->LoadConstantWide(cu, rl_result.low_reg, rl_result.high_reg, immval);
    cg->StoreValueWide(cu, rl_dest, rl_result);
  } else {
    int immediate = immval & 0xffffffff;
    cg->LoadConstantNoClobber(cu, rl_result.low_reg, immediate);
    cg->StoreValue(cu, rl_dest, rl_result);
    if (immediate == 0) {
      cg->Workaround7250540(cu, rl_dest, rl_result.low_reg);
    }
  }
}

static void CvtConstObject(CompilationUnit* cu, ::llvm::CallInst* call_inst, bool is_string)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  ::llvm::ConstantInt* idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t index = idx_val->getZExtValue();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  if (is_string) {
    cg->GenConstString(cu, index, rl_dest);
  } else {
    cg->GenConstClass(cu, index, rl_dest);
  }
}

static void CvtFillArrayData(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* offset_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
  cg->GenFillArrayData(cu, offset_val->getSExtValue(), rl_src);
}

static void CvtNewInstance(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  ::llvm::ConstantInt* type_idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t type_idx = type_idx_val->getZExtValue();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenNewInstance(cu, type_idx, rl_dest);
}

static void CvtNewArray(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* type_idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t type_idx = type_idx_val->getZExtValue();
  ::llvm::Value* len = call_inst->getArgOperand(1);
  RegLocation rl_len = GetLoc(cu, len);
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenNewArray(cu, type_idx, rl_dest, rl_len);
}

static void CvtInstanceOf(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* type_idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t type_idx = type_idx_val->getZExtValue();
  ::llvm::Value* src = call_inst->getArgOperand(1);
  RegLocation rl_src = GetLoc(cu, src);
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenInstanceof(cu, type_idx, rl_dest, rl_src);
}

static void CvtThrow(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  ::llvm::Value* src = call_inst->getArgOperand(0);
  RegLocation rl_src = GetLoc(cu, src);
  cg->GenThrow(cu, rl_src);
}

static void CvtMonitorEnterExit(CompilationUnit* cu, bool is_enter,
                         ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  ::llvm::Value* src = call_inst->getArgOperand(1);
  RegLocation rl_src = GetLoc(cu, src);
  if (is_enter) {
    cg->GenMonitorEnter(cu, opt_flags->getZExtValue(), rl_src);
  } else {
    cg->GenMonitorExit(cu, opt_flags->getZExtValue(), rl_src);
  }
}

static void CvtArrayLength(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  ::llvm::Value* src = call_inst->getArgOperand(1);
  RegLocation rl_src = GetLoc(cu, src);
  rl_src = cg->LoadValue(cu, rl_src, kCoreReg);
  cg->GenNullCheck(cu, rl_src.s_reg_low, rl_src.low_reg, opt_flags->getZExtValue());
  RegLocation rl_dest = GetLoc(cu, call_inst);
  RegLocation rl_result = EvalLoc(cu, rl_dest, kCoreReg, true);
  int len_offset = mirror::Array::LengthOffset().Int32Value();
  cg->LoadWordDisp(cu, rl_src.low_reg, len_offset, rl_result.low_reg);
  cg->StoreValue(cu, rl_dest, rl_result);
}

static void CvtMoveException(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenMoveException(cu, rl_dest);
}

static void CvtSget(CompilationUnit* cu, ::llvm::CallInst* call_inst, bool is_wide, bool is_object)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 1U);
  ::llvm::ConstantInt* type_idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t type_idx = type_idx_val->getZExtValue();
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenSget(cu, type_idx, rl_dest, is_wide, is_object);
}

static void CvtSput(CompilationUnit* cu, ::llvm::CallInst* call_inst, bool is_wide, bool is_object)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* type_idx_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  uint32_t type_idx = type_idx_val->getZExtValue();
  ::llvm::Value* src = call_inst->getArgOperand(1);
  RegLocation rl_src = GetLoc(cu, src);
  cg->GenSput(cu, type_idx, rl_src, is_wide, is_object);
}

static void CvtAget(CompilationUnit* cu, ::llvm::CallInst* call_inst, OpSize size, int scale)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(1));
  RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(2));
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenArrayGet(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
              rl_dest, scale);
}

static void CvtAput(CompilationUnit* cu, ::llvm::CallInst* call_inst, OpSize size,
                    int scale, bool is_object)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
  RegLocation rl_array = GetLoc(cu, call_inst->getArgOperand(2));
  RegLocation rl_index = GetLoc(cu, call_inst->getArgOperand(3));
  if (is_object) {
    cg->GenArrayObjPut(cu, opt_flags->getZExtValue(), rl_array, rl_index,
                   rl_src, scale);
  } else {
    cg->GenArrayPut(cu, opt_flags->getZExtValue(), size, rl_array, rl_index,
                rl_src, scale);
  }
}

static void CvtAputObj(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  CvtAput(cu, call_inst, kWord, 2, true /* is_object */);
}

static void CvtAputPrimitive(CompilationUnit* cu, ::llvm::CallInst* call_inst,
                      OpSize size, int scale)
{
  CvtAput(cu, call_inst, size, scale, false /* is_object */);
}

static void CvtIget(CompilationUnit* cu, ::llvm::CallInst* call_inst, OpSize size,
                    bool is_wide, bool is_obj)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 3U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(1));
  ::llvm::ConstantInt* field_idx =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(2));
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenIGet(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
          size, rl_dest, rl_obj, is_wide, is_obj);
}

static void CvtIput(CompilationUnit* cu, ::llvm::CallInst* call_inst, OpSize size,
                    bool is_wide, bool is_obj)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 4U);
  ::llvm::ConstantInt* opt_flags =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
  RegLocation rl_obj = GetLoc(cu, call_inst->getArgOperand(2));
  ::llvm::ConstantInt* field_idx =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(3));
  cg->GenIPut(cu, field_idx->getZExtValue(), opt_flags->getZExtValue(),
          size, rl_src, rl_obj, is_wide, is_obj);
}

static void CvtCheckCast(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  DCHECK_EQ(call_inst->getNumArgOperands(), 2U);
  ::llvm::ConstantInt* type_idx =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  RegLocation rl_src = GetLoc(cu, call_inst->getArgOperand(1));
  cg->GenCheckCast(cu, type_idx->getZExtValue(), rl_src);
}

static void CvtFPCompare(CompilationUnit* cu, ::llvm::CallInst* call_inst,
                         Instruction::Code opcode)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
  RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenCmpFP(cu, opcode, rl_dest, rl_src1, rl_src2);
}

static void CvtLongCompare(CompilationUnit* cu, ::llvm::CallInst* call_inst)
{
  Codegen* cg = cu->cg.get();
  RegLocation rl_src1 = GetLoc(cu, call_inst->getArgOperand(0));
  RegLocation rl_src2 = GetLoc(cu, call_inst->getArgOperand(1));
  RegLocation rl_dest = GetLoc(cu, call_inst);
  cg->GenCmpLong(cu, rl_dest, rl_src1, rl_src2);
}

static void CvtSwitch(CompilationUnit* cu, ::llvm::Instruction* inst)
{
  Codegen* cg = cu->cg.get();
  ::llvm::SwitchInst* sw_inst = ::llvm::dyn_cast< ::llvm::SwitchInst>(inst);
  DCHECK(sw_inst != NULL);
  ::llvm::Value* test_val = sw_inst->getCondition();
  ::llvm::MDNode* table_offset_node = sw_inst->getMetadata("SwitchTable");
  DCHECK(table_offset_node != NULL);
  ::llvm::ConstantInt* table_offset_value =
          static_cast< ::llvm::ConstantInt*>(table_offset_node->getOperand(0));
  int32_t table_offset = table_offset_value->getSExtValue();
  RegLocation rl_src = GetLoc(cu, test_val);
  const uint16_t* table = cu->insns + cu->current_dalvik_offset + table_offset;
  uint16_t table_magic = *table;
  if (table_magic == 0x100) {
    cg->GenPackedSwitch(cu, table_offset, rl_src);
  } else {
    DCHECK_EQ(table_magic, 0x200);
    cg->GenSparseSwitch(cu, table_offset, rl_src);
  }
}

static void CvtInvoke(CompilationUnit* cu, ::llvm::CallInst* call_inst, bool is_void,
                      bool is_filled_new_array)
{
  Codegen* cg = cu->cg.get();
  CallInfo* info = static_cast<CallInfo*>(NewMem(cu, sizeof(CallInfo), true, kAllocMisc));
  if (is_void) {
    info->result.location = kLocInvalid;
  } else {
    info->result = GetLoc(cu, call_inst);
  }
  ::llvm::ConstantInt* invoke_type_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(0));
  ::llvm::ConstantInt* method_index_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(1));
  ::llvm::ConstantInt* opt_flags_val =
      ::llvm::dyn_cast< ::llvm::ConstantInt>(call_inst->getArgOperand(2));
  info->type = static_cast<InvokeType>(invoke_type_val->getZExtValue());
  info->index = method_index_val->getZExtValue();
  info->opt_flags = opt_flags_val->getZExtValue();
  info->offset = cu->current_dalvik_offset;

  // Count the argument words, and then build argument array.
  info->num_arg_words = 0;
  for (unsigned int i = 3; i < call_inst->getNumArgOperands(); i++) {
    RegLocation t_loc = GetLoc(cu, call_inst->getArgOperand(i));
    info->num_arg_words += t_loc.wide ? 2 : 1;
  }
  info->args = (info->num_arg_words == 0) ? NULL : static_cast<RegLocation*>
      (NewMem(cu, sizeof(RegLocation) * info->num_arg_words, false, kAllocMisc));
  // Now, fill in the location records, synthesizing high loc of wide vals
  for (int i = 3, next = 0; next < info->num_arg_words;) {
    info->args[next] = GetLoc(cu, call_inst->getArgOperand(i++));
    if (info->args[next].wide) {
      next++;
      // TODO: Might make sense to mark this as an invalid loc
      info->args[next].orig_sreg = info->args[next-1].orig_sreg+1;
      info->args[next].s_reg_low = info->args[next-1].s_reg_low+1;
    }
    next++;
  }
  // TODO - rework such that we no longer need is_range
  info->is_range = (info->num_arg_words > 5);

  if (is_filled_new_array) {
    cg->GenFilledNewArray(cu, info);
  } else {
    cg->GenInvoke(cu, info);
  }
}

static void CvtConstructorBarrier(CompilationUnit* cu) {
  Codegen* cg = cu->cg.get();
  cg->GenMemBarrier(cu, kStoreStore);
}

/* Look up the RegLocation associated with a Value.  Must already be defined */
static RegLocation ValToLoc(CompilationUnit* cu, ::llvm::Value* val)
{
  SafeMap< ::llvm::Value*, RegLocation>::iterator it = cu->loc_map.find(val);
  DCHECK(it != cu->loc_map.end()) << "Missing definition";
  return it->second;
}

static bool BitcodeBlockCodeGen(CompilationUnit* cu, ::llvm::BasicBlock* bb)
{
  Codegen* cg = cu->cg.get();
  while (cu->llvm_blocks.find(bb) == cu->llvm_blocks.end()) {
    ::llvm::BasicBlock* next_bb = NULL;
    cu->llvm_blocks.insert(bb);
    bool is_entry = (bb == &cu->func->getEntryBlock());
    // Define the starting label
    LIR* block_label = cu->block_to_label_map.Get(bb);
    // Extract the type and starting offset from the block's name
    char block_type = kInvalidBlock;
    if (is_entry) {
      block_type = kNormalBlock;
      block_label->operands[0] = 0;
    } else if (!bb->hasName()) {
      block_type = kNormalBlock;
      block_label->operands[0] = DexFile::kDexNoIndex;
    } else {
      std::string block_name = bb->getName().str();
      int dummy;
      sscanf(block_name.c_str(), kLabelFormat, &block_type, &block_label->operands[0], &dummy);
      cu->current_dalvik_offset = block_label->operands[0];
    }
    DCHECK((block_type == kNormalBlock) || (block_type == kCatchBlock));
    cu->current_dalvik_offset = block_label->operands[0];
    // Set the label kind
    block_label->opcode = kPseudoNormalBlockLabel;
    // Insert the label
    AppendLIR(cu, block_label);

    LIR* head_lir = NULL;

    if (block_type == kCatchBlock) {
      head_lir = NewLIR0(cu, kPseudoExportedPC);
    }

    // Free temp registers and reset redundant store tracking */
    ResetRegPool(cu);
    ResetDefTracking(cu);

    //TODO: restore oat incoming liveness optimization
    ClobberAllRegs(cu);

    if (is_entry) {
      RegLocation* ArgLocs = static_cast<RegLocation*>
          (NewMem(cu, sizeof(RegLocation) * cu->num_ins, true, kAllocMisc));
      ::llvm::Function::arg_iterator it(cu->func->arg_begin());
      ::llvm::Function::arg_iterator it_end(cu->func->arg_end());
      // Skip past Method*
      it++;
      for (unsigned i = 0; it != it_end; ++it) {
        ::llvm::Value* val = it;
        ArgLocs[i++] = ValToLoc(cu, val);
        ::llvm::Type* ty = val->getType();
        if ((ty == cu->irb->getInt64Ty()) || (ty == cu->irb->getDoubleTy())) {
          ArgLocs[i] = ArgLocs[i-1];
          ArgLocs[i].low_reg = ArgLocs[i].high_reg;
          ArgLocs[i].orig_sreg++;
          ArgLocs[i].s_reg_low = INVALID_SREG;
          ArgLocs[i].high_word = true;
          i++;
        }
      }
      cg->GenEntrySequence(cu, ArgLocs, cu->method_loc);
    }

    // Visit all of the instructions in the block
    for (::llvm::BasicBlock::iterator it = bb->begin(), e = bb->end(); it != e;) {
      ::llvm::Instruction* inst = it;
      ::llvm::BasicBlock::iterator next_it = ++it;
      // Extract the Dalvik offset from the instruction
      uint32_t opcode = inst->getOpcode();
      ::llvm::MDNode* dex_offset_node = inst->getMetadata("DexOff");
      if (dex_offset_node != NULL) {
        ::llvm::ConstantInt* dex_offset_value =
            static_cast< ::llvm::ConstantInt*>(dex_offset_node->getOperand(0));
        cu->current_dalvik_offset = dex_offset_value->getZExtValue();
      }

      ResetRegPool(cu);
      if (cu->disable_opt & (1 << kTrackLiveTemps)) {
        ClobberAllRegs(cu);
      }

      if (cu->disable_opt & (1 << kSuppressLoads)) {
        ResetDefTracking(cu);
      }

  #ifndef NDEBUG
      /* Reset temp tracking sanity check */
      cu->live_sreg = INVALID_SREG;
  #endif

      // TODO: use llvm opcode name here instead of "boundary" if verbose
      LIR* boundary_lir = MarkBoundary(cu, cu->current_dalvik_offset, "boundary");

      /* Remember the first LIR for thisl block*/
      if (head_lir == NULL) {
        head_lir = boundary_lir;
        head_lir->def_mask = ENCODE_ALL;
      }

      switch(opcode) {

        case ::llvm::Instruction::ICmp: {
            ::llvm::Instruction* next_inst = next_it;
            ::llvm::BranchInst* br_inst = ::llvm::dyn_cast< ::llvm::BranchInst>(next_inst);
            if (br_inst != NULL /* and... */) {
              CvtICmpBr(cu, inst, br_inst);
              ++it;
            } else {
              CvtICmp(cu, inst);
            }
          }
          break;

        case ::llvm::Instruction::Call: {
            ::llvm::CallInst* call_inst = ::llvm::dyn_cast< ::llvm::CallInst>(inst);
            ::llvm::Function* callee = call_inst->getCalledFunction();
            art::llvm::IntrinsicHelper::IntrinsicId id =
                cu->intrinsic_helper->GetIntrinsicId(callee);
            switch (id) {
              case art::llvm::IntrinsicHelper::AllocaShadowFrame:
              case art::llvm::IntrinsicHelper::PopShadowFrame:
              case art::llvm::IntrinsicHelper::SetVReg:
                // Ignore shadow frame stuff for quick compiler
                break;
              case art::llvm::IntrinsicHelper::CopyInt:
              case art::llvm::IntrinsicHelper::CopyObj:
              case art::llvm::IntrinsicHelper::CopyFloat:
              case art::llvm::IntrinsicHelper::CopyLong:
              case art::llvm::IntrinsicHelper::CopyDouble:
                CvtCopy(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::ConstInt:
              case art::llvm::IntrinsicHelper::ConstObj:
              case art::llvm::IntrinsicHelper::ConstLong:
              case art::llvm::IntrinsicHelper::ConstFloat:
              case art::llvm::IntrinsicHelper::ConstDouble:
                CvtConst(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::DivInt:
              case art::llvm::IntrinsicHelper::DivLong:
                CvtBinOp(cu, kOpDiv, inst);
                break;
              case art::llvm::IntrinsicHelper::RemInt:
              case art::llvm::IntrinsicHelper::RemLong:
                CvtBinOp(cu, kOpRem, inst);
                break;
              case art::llvm::IntrinsicHelper::MethodInfo:
                // Already dealt with - just ignore it here.
                break;
              case art::llvm::IntrinsicHelper::CheckSuspend:
                cg->GenSuspendTest(cu, 0 /* opt_flags already applied */);
                break;
              case art::llvm::IntrinsicHelper::HLInvokeObj:
              case art::llvm::IntrinsicHelper::HLInvokeFloat:
              case art::llvm::IntrinsicHelper::HLInvokeDouble:
              case art::llvm::IntrinsicHelper::HLInvokeLong:
              case art::llvm::IntrinsicHelper::HLInvokeInt:
                CvtInvoke(cu, call_inst, false /* is_void */, false /* new_array */);
                break;
              case art::llvm::IntrinsicHelper::HLInvokeVoid:
                CvtInvoke(cu, call_inst, true /* is_void */, false /* new_array */);
                break;
              case art::llvm::IntrinsicHelper::HLFilledNewArray:
                CvtInvoke(cu, call_inst, false /* is_void */, true /* new_array */);
                break;
              case art::llvm::IntrinsicHelper::HLFillArrayData:
                CvtFillArrayData(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::ConstString:
                CvtConstObject(cu, call_inst, true /* is_string */);
                break;
              case art::llvm::IntrinsicHelper::ConstClass:
                CvtConstObject(cu, call_inst, false /* is_string */);
                break;
              case art::llvm::IntrinsicHelper::HLCheckCast:
                CvtCheckCast(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::NewInstance:
                CvtNewInstance(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::HLSgetObject:
                CvtSget(cu, call_inst, false /* wide */, true /* Object */);
                break;
              case art::llvm::IntrinsicHelper::HLSget:
              case art::llvm::IntrinsicHelper::HLSgetFloat:
              case art::llvm::IntrinsicHelper::HLSgetBoolean:
              case art::llvm::IntrinsicHelper::HLSgetByte:
              case art::llvm::IntrinsicHelper::HLSgetChar:
              case art::llvm::IntrinsicHelper::HLSgetShort:
                CvtSget(cu, call_inst, false /* wide */, false /* Object */);
                break;
              case art::llvm::IntrinsicHelper::HLSgetWide:
              case art::llvm::IntrinsicHelper::HLSgetDouble:
                CvtSget(cu, call_inst, true /* wide */, false /* Object */);
                break;
              case art::llvm::IntrinsicHelper::HLSput:
              case art::llvm::IntrinsicHelper::HLSputFloat:
              case art::llvm::IntrinsicHelper::HLSputBoolean:
              case art::llvm::IntrinsicHelper::HLSputByte:
              case art::llvm::IntrinsicHelper::HLSputChar:
              case art::llvm::IntrinsicHelper::HLSputShort:
                CvtSput(cu, call_inst, false /* wide */, false /* Object */);
                break;
              case art::llvm::IntrinsicHelper::HLSputWide:
              case art::llvm::IntrinsicHelper::HLSputDouble:
                CvtSput(cu, call_inst, true /* wide */, false /* Object */);
                break;
              case art::llvm::IntrinsicHelper::HLSputObject:
                CvtSput(cu, call_inst, false /* wide */, true /* Object */);
                break;
              case art::llvm::IntrinsicHelper::GetException:
                CvtMoveException(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::HLThrowException:
                CvtThrow(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::MonitorEnter:
                CvtMonitorEnterExit(cu, true /* is_enter */, call_inst);
                break;
              case art::llvm::IntrinsicHelper::MonitorExit:
                CvtMonitorEnterExit(cu, false /* is_enter */, call_inst);
                break;
              case art::llvm::IntrinsicHelper::OptArrayLength:
                CvtArrayLength(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::NewArray:
                CvtNewArray(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::InstanceOf:
                CvtInstanceOf(cu, call_inst);
                break;

              case art::llvm::IntrinsicHelper::HLArrayGet:
              case art::llvm::IntrinsicHelper::HLArrayGetObject:
              case art::llvm::IntrinsicHelper::HLArrayGetFloat:
                CvtAget(cu, call_inst, kWord, 2);
                break;
              case art::llvm::IntrinsicHelper::HLArrayGetWide:
              case art::llvm::IntrinsicHelper::HLArrayGetDouble:
                CvtAget(cu, call_inst, kLong, 3);
                break;
              case art::llvm::IntrinsicHelper::HLArrayGetBoolean:
                CvtAget(cu, call_inst, kUnsignedByte, 0);
                break;
              case art::llvm::IntrinsicHelper::HLArrayGetByte:
                CvtAget(cu, call_inst, kSignedByte, 0);
                break;
              case art::llvm::IntrinsicHelper::HLArrayGetChar:
                CvtAget(cu, call_inst, kUnsignedHalf, 1);
                break;
              case art::llvm::IntrinsicHelper::HLArrayGetShort:
                CvtAget(cu, call_inst, kSignedHalf, 1);
                break;

              case art::llvm::IntrinsicHelper::HLArrayPut:
              case art::llvm::IntrinsicHelper::HLArrayPutFloat:
                CvtAputPrimitive(cu, call_inst, kWord, 2);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutObject:
                CvtAputObj(cu, call_inst);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutWide:
              case art::llvm::IntrinsicHelper::HLArrayPutDouble:
                CvtAputPrimitive(cu, call_inst, kLong, 3);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutBoolean:
                CvtAputPrimitive(cu, call_inst, kUnsignedByte, 0);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutByte:
                CvtAputPrimitive(cu, call_inst, kSignedByte, 0);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutChar:
                CvtAputPrimitive(cu, call_inst, kUnsignedHalf, 1);
                break;
              case art::llvm::IntrinsicHelper::HLArrayPutShort:
                CvtAputPrimitive(cu, call_inst, kSignedHalf, 1);
                break;

              case art::llvm::IntrinsicHelper::HLIGet:
              case art::llvm::IntrinsicHelper::HLIGetFloat:
                CvtIget(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetObject:
                CvtIget(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetWide:
              case art::llvm::IntrinsicHelper::HLIGetDouble:
                CvtIget(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetBoolean:
                CvtIget(cu, call_inst, kUnsignedByte, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetByte:
                CvtIget(cu, call_inst, kSignedByte, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetChar:
                CvtIget(cu, call_inst, kUnsignedHalf, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIGetShort:
                CvtIget(cu, call_inst, kSignedHalf, false /* is_wide */,
                        false /* obj */);
                break;

              case art::llvm::IntrinsicHelper::HLIPut:
              case art::llvm::IntrinsicHelper::HLIPutFloat:
                CvtIput(cu, call_inst, kWord, false /* is_wide */, false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutObject:
                CvtIput(cu, call_inst, kWord, false /* is_wide */, true /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutWide:
              case art::llvm::IntrinsicHelper::HLIPutDouble:
                CvtIput(cu, call_inst, kLong, true /* is_wide */, false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutBoolean:
                CvtIput(cu, call_inst, kUnsignedByte, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutByte:
                CvtIput(cu, call_inst, kSignedByte, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutChar:
                CvtIput(cu, call_inst, kUnsignedHalf, false /* is_wide */,
                        false /* obj */);
                break;
              case art::llvm::IntrinsicHelper::HLIPutShort:
                CvtIput(cu, call_inst, kSignedHalf, false /* is_wide */,
                        false /* obj */);
                break;

              case art::llvm::IntrinsicHelper::IntToChar:
                CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_CHAR);
                break;
              case art::llvm::IntrinsicHelper::IntToShort:
                CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_SHORT);
                break;
              case art::llvm::IntrinsicHelper::IntToByte:
                CvtIntNarrowing(cu, call_inst, Instruction::INT_TO_BYTE);
                break;

              case art::llvm::IntrinsicHelper::F2I:
              case art::llvm::IntrinsicHelper::D2I:
              case art::llvm::IntrinsicHelper::F2L:
              case art::llvm::IntrinsicHelper::D2L:
                CvtFPToInt(cu, call_inst);
                break;

              case art::llvm::IntrinsicHelper::CmplFloat:
                CvtFPCompare(cu, call_inst, Instruction::CMPL_FLOAT);
                break;
              case art::llvm::IntrinsicHelper::CmpgFloat:
                CvtFPCompare(cu, call_inst, Instruction::CMPG_FLOAT);
                break;
              case art::llvm::IntrinsicHelper::CmplDouble:
                CvtFPCompare(cu, call_inst, Instruction::CMPL_DOUBLE);
                break;
              case art::llvm::IntrinsicHelper::CmpgDouble:
                CvtFPCompare(cu, call_inst, Instruction::CMPG_DOUBLE);
                break;

              case art::llvm::IntrinsicHelper::CmpLong:
                CvtLongCompare(cu, call_inst);
                break;

              case art::llvm::IntrinsicHelper::SHLLong:
                CvtShiftOp(cu, Instruction::SHL_LONG, call_inst);
                break;
              case art::llvm::IntrinsicHelper::SHRLong:
                CvtShiftOp(cu, Instruction::SHR_LONG, call_inst);
                break;
              case art::llvm::IntrinsicHelper::USHRLong:
                CvtShiftOp(cu, Instruction::USHR_LONG, call_inst);
                break;
              case art::llvm::IntrinsicHelper::SHLInt:
                CvtShiftOp(cu, Instruction::SHL_INT, call_inst);
                break;
              case art::llvm::IntrinsicHelper::SHRInt:
                CvtShiftOp(cu, Instruction::SHR_INT, call_inst);
                break;
              case art::llvm::IntrinsicHelper::USHRInt:
                CvtShiftOp(cu, Instruction::USHR_INT, call_inst);
                break;

              case art::llvm::IntrinsicHelper::CatchTargets: {
                  ::llvm::SwitchInst* sw_inst =
                      ::llvm::dyn_cast< ::llvm::SwitchInst>(next_it);
                  DCHECK(sw_inst != NULL);
                  /*
                   * Discard the edges and the following conditional branch.
                   * Do a direct branch to the default target (which is the
                   * "work" portion of the pair.
                   * TODO: awful code layout - rework
                   */
                   ::llvm::BasicBlock* target_bb = sw_inst->getDefaultDest();
                   DCHECK(target_bb != NULL);
                   cg->OpUnconditionalBranch(cu, cu->block_to_label_map.Get(target_bb));
                   ++it;
                   // Set next bb to default target - improves code layout
                   next_bb = target_bb;
                }
                break;
              case art::llvm::IntrinsicHelper::ConstructorBarrier: {
                CvtConstructorBarrier(cu);
                break;
              }

              default:
                LOG(FATAL) << "Unexpected intrinsic " << cu->intrinsic_helper->GetName(id);
            }
          }
          break;

        case ::llvm::Instruction::Br: CvtBr(cu, inst); break;
        case ::llvm::Instruction::Add: CvtBinOp(cu, kOpAdd, inst); break;
        case ::llvm::Instruction::Sub: CvtBinOp(cu, kOpSub, inst); break;
        case ::llvm::Instruction::Mul: CvtBinOp(cu, kOpMul, inst); break;
        case ::llvm::Instruction::SDiv: CvtBinOp(cu, kOpDiv, inst); break;
        case ::llvm::Instruction::SRem: CvtBinOp(cu, kOpRem, inst); break;
        case ::llvm::Instruction::And: CvtBinOp(cu, kOpAnd, inst); break;
        case ::llvm::Instruction::Or: CvtBinOp(cu, kOpOr, inst); break;
        case ::llvm::Instruction::Xor: CvtBinOp(cu, kOpXor, inst); break;
        case ::llvm::Instruction::PHI: CvtPhi(cu, inst); break;
        case ::llvm::Instruction::Ret: CvtRet(cu, inst); break;
        case ::llvm::Instruction::FAdd: CvtBinFPOp(cu, kOpAdd, inst); break;
        case ::llvm::Instruction::FSub: CvtBinFPOp(cu, kOpSub, inst); break;
        case ::llvm::Instruction::FMul: CvtBinFPOp(cu, kOpMul, inst); break;
        case ::llvm::Instruction::FDiv: CvtBinFPOp(cu, kOpDiv, inst); break;
        case ::llvm::Instruction::FRem: CvtBinFPOp(cu, kOpRem, inst); break;
        case ::llvm::Instruction::SIToFP: CvtIntToFP(cu, inst); break;
        case ::llvm::Instruction::FPTrunc: CvtDoubleToFloat(cu, inst); break;
        case ::llvm::Instruction::FPExt: CvtFloatToDouble(cu, inst); break;
        case ::llvm::Instruction::Trunc: CvtTrunc(cu, inst); break;

        case ::llvm::Instruction::ZExt: CvtIntExt(cu, inst, false /* signed */);
          break;
        case ::llvm::Instruction::SExt: CvtIntExt(cu, inst, true /* signed */);
          break;

        case ::llvm::Instruction::Switch: CvtSwitch(cu, inst); break;

        case ::llvm::Instruction::Unreachable:
          break;  // FIXME: can we really ignore these?

        case ::llvm::Instruction::Shl:
        case ::llvm::Instruction::LShr:
        case ::llvm::Instruction::AShr:
        case ::llvm::Instruction::Invoke:
        case ::llvm::Instruction::FPToUI:
        case ::llvm::Instruction::FPToSI:
        case ::llvm::Instruction::UIToFP:
        case ::llvm::Instruction::PtrToInt:
        case ::llvm::Instruction::IntToPtr:
        case ::llvm::Instruction::FCmp:
        case ::llvm::Instruction::URem:
        case ::llvm::Instruction::UDiv:
        case ::llvm::Instruction::Resume:
        case ::llvm::Instruction::Alloca:
        case ::llvm::Instruction::GetElementPtr:
        case ::llvm::Instruction::Fence:
        case ::llvm::Instruction::AtomicCmpXchg:
        case ::llvm::Instruction::AtomicRMW:
        case ::llvm::Instruction::BitCast:
        case ::llvm::Instruction::VAArg:
        case ::llvm::Instruction::Select:
        case ::llvm::Instruction::UserOp1:
        case ::llvm::Instruction::UserOp2:
        case ::llvm::Instruction::ExtractElement:
        case ::llvm::Instruction::InsertElement:
        case ::llvm::Instruction::ShuffleVector:
        case ::llvm::Instruction::ExtractValue:
        case ::llvm::Instruction::InsertValue:
        case ::llvm::Instruction::LandingPad:
        case ::llvm::Instruction::IndirectBr:
        case ::llvm::Instruction::Load:
        case ::llvm::Instruction::Store:
          LOG(FATAL) << "Unexpected llvm opcode: " << opcode; break;

        default:
          LOG(FATAL) << "Unknown llvm opcode: " << inst->getOpcodeName();
          break;
      }
    }

    if (head_lir != NULL) {
      ApplyLocalOptimizations(cu, head_lir, cu->last_lir_insn);
    }
    if (next_bb != NULL) {
      bb = next_bb;
      next_bb = NULL;
    }
  }
  return false;
}

/*
 * Convert LLVM_IR to MIR:
 *   o Iterate through the LLVM_IR and construct a graph using
 *     standard MIR building blocks.
 *   o Perform a basic-block optimization pass to remove unnecessary
 *     store/load sequences.
 *   o Convert the LLVM Value operands into RegLocations where applicable.
 *   o Create ssa_rep def/use operand arrays for each converted LLVM opcode
 *   o Perform register promotion
 *   o Iterate through the graph a basic block at a time, generating
 *     LIR.
 *   o Assemble LIR as usual.
 *   o Profit.
 */
void MethodBitcode2LIR(CompilationUnit* cu)
{
  Codegen* cg = cu->cg.get();
  ::llvm::Function* func = cu->func;
  int num_basic_blocks = func->getBasicBlockList().size();
  // Allocate a list for LIR basic block labels
  cu->block_label_list =
    static_cast<LIR*>(NewMem(cu, sizeof(LIR) * num_basic_blocks, true, kAllocLIR));
  LIR* label_list = cu->block_label_list;
  int next_label = 0;
  for (::llvm::Function::iterator i = func->begin(), e = func->end(); i != e; ++i) {
    cu->block_to_label_map.Put(static_cast< ::llvm::BasicBlock*>(i),
                               &label_list[next_label++]);
  }

  /*
   * Keep honest - clear reg_locations, Value => RegLocation,
   * promotion map and VmapTables.
   */
  cu->loc_map.clear();  // Start fresh
  cu->reg_location = NULL;
  for (int i = 0; i < cu->num_dalvik_registers + cu->num_compiler_temps + 1; i++) {
    cu->promotion_map[i].core_location = kLocDalvikFrame;
    cu->promotion_map[i].fp_location = kLocDalvikFrame;
  }
  cu->core_spill_mask = 0;
  cu->num_core_spills = 0;
  cu->fp_spill_mask = 0;
  cu->num_fp_spills = 0;
  cu->core_vmap_table.clear();
  cu->fp_vmap_table.clear();

  /*
   * At this point, we've lost all knowledge of register promotion.
   * Rebuild that info from the MethodInfo intrinsic (if it
   * exists - not required for correctness).  Normally, this will
   * be the first instruction we encounter, so we won't have to iterate
   * through everything.
   */
  for (::llvm::inst_iterator i = ::llvm::inst_begin(func), e = ::llvm::inst_end(func); i != e; ++i) {
    ::llvm::CallInst* call_inst = ::llvm::dyn_cast< ::llvm::CallInst>(&*i);
    if (call_inst != NULL) {
      ::llvm::Function* callee = call_inst->getCalledFunction();
      llvm::IntrinsicHelper::IntrinsicId id =
          cu->intrinsic_helper->GetIntrinsicId(callee);
      if (id == art::llvm::IntrinsicHelper::MethodInfo) {
        if (cu->verbose) {
          LOG(INFO) << "Found MethodInfo";
        }
        ::llvm::MDNode* reg_info_node = call_inst->getMetadata("RegInfo");
        if (reg_info_node != NULL) {
          ::llvm::ConstantInt* num_ins_value =
            static_cast< ::llvm::ConstantInt*>(reg_info_node->getOperand(0));
          ::llvm::ConstantInt* num_regs_value =
            static_cast< ::llvm::ConstantInt*>(reg_info_node->getOperand(1));
          ::llvm::ConstantInt* num_outs_value =
            static_cast< ::llvm::ConstantInt*>(reg_info_node->getOperand(2));
          ::llvm::ConstantInt* num_compiler_temps_value =
            static_cast< ::llvm::ConstantInt*>(reg_info_node->getOperand(3));
          ::llvm::ConstantInt* num_ssa_regs_value =
            static_cast< ::llvm::ConstantInt*>(reg_info_node->getOperand(4));
          if (cu->verbose) {
             LOG(INFO) << "RegInfo - Ins:" << num_ins_value->getZExtValue()
                       << ", Regs:" << num_regs_value->getZExtValue()
                       << ", Outs:" << num_outs_value->getZExtValue()
                       << ", CTemps:" << num_compiler_temps_value->getZExtValue()
                       << ", SSARegs:" << num_ssa_regs_value->getZExtValue();
            }
          }
        ::llvm::MDNode* pmap_info_node = call_inst->getMetadata("PromotionMap");
        if (pmap_info_node != NULL) {
          int elems = pmap_info_node->getNumOperands();
          if (cu->verbose) {
            LOG(INFO) << "PMap size: " << elems;
          }
          for (int i = 0; i < elems; i++) {
            ::llvm::ConstantInt* raw_map_data =
                static_cast< ::llvm::ConstantInt*>(pmap_info_node->getOperand(i));
            uint32_t map_data = raw_map_data->getZExtValue();
            PromotionMap* p = &cu->promotion_map[i];
            p->first_in_pair = (map_data >> 24) & 0xff;
            p->FpReg = (map_data >> 16) & 0xff;
            p->core_reg = (map_data >> 8) & 0xff;
            p->fp_location = static_cast<RegLocationType>((map_data >> 4) & 0xf);
            if (p->fp_location == kLocPhysReg) {
              RecordFpPromotion(cu, p->FpReg, i);
            }
            p->core_location = static_cast<RegLocationType>(map_data & 0xf);
            if (p->core_location == kLocPhysReg) {
              RecordCorePromotion(cu, p->core_reg, i);
            }
          }
          if (cu->verbose) {
            DumpPromotionMap(cu);
          }
        }
        break;
      }
    }
  }
  cg->AdjustSpillMask(cu);
  cu->frame_size = ComputeFrameSize(cu);

  // Create RegLocations for arguments
  ::llvm::Function::arg_iterator it(cu->func->arg_begin());
  ::llvm::Function::arg_iterator it_end(cu->func->arg_end());
  for (; it != it_end; ++it) {
    ::llvm::Value* val = it;
    CreateLocFromValue(cu, val);
  }
  // Create RegLocations for all non-argument defintions
  for (::llvm::inst_iterator i = ::llvm::inst_begin(func), e = ::llvm::inst_end(func); i != e; ++i) {
    ::llvm::Value* val = &*i;
    if (val->hasName() && (val->getName().str().c_str()[0] == 'v')) {
      CreateLocFromValue(cu, val);
    }
  }

  // Walk the blocks, generating code.
  for (::llvm::Function::iterator i = cu->func->begin(), e = cu->func->end(); i != e; ++i) {
    BitcodeBlockCodeGen(cu, static_cast< ::llvm::BasicBlock*>(i));
  }

  cg->HandleSuspendLaunchPads(cu);

  cg->HandleThrowLaunchPads(cu);

  cg->HandleIntrinsicLaunchPads(cu);

  cu->func->eraseFromParent();
  cu->func = NULL;
}


}  // namespace art
