/*
 * 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_internals.h"
#include "local_optimizations.h"
#include "codegen_util.h"
#include "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
  greenland::IntrinsicHelper::IntrinsicId id =
      greenland::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->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,
                        greenland::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,
                        greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  if (loc.wide) {
    if (loc.fp) {
      id = greenland::IntrinsicHelper::ConstDouble;
    } else {
      id = greenland::IntrinsicHelper::ConstLong;
    }
  } else {
    if (loc.fp) {
      id = greenland::IntrinsicHelper::ConstFloat;
    } else if (loc.ref) {
      id = greenland::IntrinsicHelper::ConstObj;
    } else {
      id = greenland::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(
      greenland::IntrinsicHelper::PopShadowFrame);
  cu->irb->CreateCall(intr);
}

static llvm::Value* EmitCopy(CompilationUnit* cu, llvm::ArrayRef<llvm::Value*> src,
                             RegLocation loc)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  if (loc.wide) {
    if (loc.fp) {
      id = greenland::IntrinsicHelper::CopyDouble;
    } else {
      id = greenland::IntrinsicHelper::CopyLong;
    }
  } else {
    if (loc.fp) {
      id = greenland::IntrinsicHelper::CopyFloat;
    } else if (loc.ref) {
      id = greenland::IntrinsicHelper::CopyObj;
    } else {
      id = greenland::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(
      greenland::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(
      greenland::IntrinsicHelper::HLThrowException);
  cu->irb->CreateCall(func, src);
}

static void ConvertMonitorEnterExit(CompilationUnit* cu, int opt_flags,
                                    greenland::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(
      greenland::IntrinsicHelper::OptArrayLength);
  llvm::Value* res = cu->irb->CreateCall(func, args);
  DefineValue(cu, res, rl_dest.orig_sreg);
}

static void EmitSuspendCheck(CompilationUnit* cu)
{
  greenland::IntrinsicHelper::IntrinsicId id =
      greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  if (is_long) {
    if (is_div) {
      id = greenland::IntrinsicHelper::DivLong;
    } else {
      id = greenland::IntrinsicHelper::RemLong;
    }
  } else {
    if (is_div) {
      id = greenland::IntrinsicHelper::DivInt;
    } else {
      id = greenland::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, greenland::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, greenland::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.
   */
  greenland::IntrinsicHelper::IntrinsicId id;
  if (is_filled_new_array) {
    id = greenland::IntrinsicHelper::HLFilledNewArray;
  } else if (info->result.location == kLocInvalid) {
    id = greenland::IntrinsicHelper::HLInvokeVoid;
  } else {
    if (info->result.wide) {
      if (info->result.fp) {
        id = greenland::IntrinsicHelper::HLInvokeDouble;
      } else {
        id = greenland::IntrinsicHelper::HLInvokeLong;
      }
    } else if (info->result.ref) {
        id = greenland::IntrinsicHelper::HLInvokeObj;
    } else if (info->result.fp) {
        id = greenland::IntrinsicHelper::HLInvokeFloat;
    } else {
        id = greenland::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,
                               greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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,
                        greenland::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,
                        greenland::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,
                        greenland::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,
                        greenland::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)
{
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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,
                                  greenland::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,
                                greenland::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, greenland::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);
}

/*
 * 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, greenland::IntrinsicHelper::HLSputObject,
                  rl_src[0]);
      break;
    case Instruction::SPUT:
      if (rl_src[0].fp) {
        ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputFloat,
                    rl_src[0]);
      } else {
        ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSput, rl_src[0]);
      }
      break;
    case Instruction::SPUT_BOOLEAN:
      ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputBoolean,
                  rl_src[0]);
      break;
    case Instruction::SPUT_BYTE:
      ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputByte, rl_src[0]);
      break;
    case Instruction::SPUT_CHAR:
      ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputChar, rl_src[0]);
      break;
    case Instruction::SPUT_SHORT:
      ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputShort, rl_src[0]);
      break;
    case Instruction::SPUT_WIDE:
      if (rl_src[0].fp) {
        ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputDouble,
                    rl_src[0]);
      } else {
        ConvertSput(cu, vB, greenland::IntrinsicHelper::HLSputWide,
                    rl_src[0]);
      }
      break;

    case Instruction::SGET_OBJECT:
      ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetObject, rl_dest);
      break;
    case Instruction::SGET:
      if (rl_dest.fp) {
        ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetFloat, rl_dest);
      } else {
        ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSget, rl_dest);
      }
      break;
    case Instruction::SGET_BOOLEAN:
      ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetBoolean, rl_dest);
      break;
    case Instruction::SGET_BYTE:
      ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetByte, rl_dest);
      break;
    case Instruction::SGET_CHAR:
      ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetChar, rl_dest);
      break;
    case Instruction::SGET_SHORT:
      ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetShort, rl_dest);
      break;
    case Instruction::SGET_WIDE:
      if (rl_dest.fp) {
        ConvertSget(cu, vB, greenland::IntrinsicHelper::HLSgetDouble,
                    rl_dest);
      } else {
        ConvertSget(cu, vB, greenland::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));
        bb->has_return = true;
      }
      break;

    case Instruction::RETURN_VOID: {
        if (!(cu->attrs & METHOD_IS_LEAF)) {
          EmitSuspendCheck(cu);
        }
        EmitPopShadowFrame(cu);
        cu->irb->CreateRetVoid();
        bb->has_return = true;
      }
      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, greenland::IntrinsicHelper::SHLLong,
                    rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHL_INT:
    case Instruction::SHL_INT_2ADDR:
      ConvertShift(cu, greenland::IntrinsicHelper::SHLInt,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHR_LONG:
    case Instruction::SHR_LONG_2ADDR:
      ConvertShift(cu, greenland::IntrinsicHelper::SHRLong,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::SHR_INT:
    case Instruction::SHR_INT_2ADDR:
      ConvertShift(cu, greenland::IntrinsicHelper::SHRInt,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::USHR_LONG:
    case Instruction::USHR_LONG_2ADDR:
      ConvertShift(cu, greenland::IntrinsicHelper::USHRLong,
                   rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::USHR_INT:
    case Instruction::USHR_INT_2ADDR:
      ConvertShift(cu, greenland::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, greenland::IntrinsicHelper::SHLInt,
                      rl_dest, rl_src[0], vC & 0x1f);
      break;
    case Instruction::SHR_INT_LIT8:
      ConvertShiftLit(cu, greenland::IntrinsicHelper::SHRInt,
                      rl_dest, rl_src[0], vC & 0x1f);
      break;
    case Instruction::USHR_INT_LIT8:
      ConvertShiftLit(cu, greenland::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, greenland::IntrinsicHelper::ConstString,
                         rl_dest);
      break;

    case Instruction::CONST_CLASS:
      ConvertConstObject(cu, vB, greenland::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,
                              greenland::IntrinsicHelper::MonitorEnter,
                              rl_src[0]);
      break;

    case Instruction::MONITOR_EXIT:
      ConvertMonitorEnterExit(cu, opt_flags,
                              greenland::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,
                    greenland::IntrinsicHelper::HLArrayGetFloat,
                    rl_dest, rl_src[0], rl_src[1]);
      } else {
        ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGet,
                    rl_dest, rl_src[0], rl_src[1]);
      }
      break;
    case Instruction::AGET_OBJECT:
      ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetObject,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_BOOLEAN:
      ConvertAget(cu, opt_flags,
                  greenland::IntrinsicHelper::HLArrayGetBoolean,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_BYTE:
      ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetByte,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_CHAR:
      ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetChar,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_SHORT:
      ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetShort,
                  rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::AGET_WIDE:
      if (rl_dest.fp) {
        ConvertAget(cu, opt_flags,
                    greenland::IntrinsicHelper::HLArrayGetDouble,
                    rl_dest, rl_src[0], rl_src[1]);
      } else {
        ConvertAget(cu, opt_flags, greenland::IntrinsicHelper::HLArrayGetWide,
                    rl_dest, rl_src[0], rl_src[1]);
      }
      break;

    case Instruction::APUT:
      if (rl_src[0].fp) {
        ConvertAput(cu, opt_flags,
                    greenland::IntrinsicHelper::HLArrayPutFloat,
                    rl_src[0], rl_src[1], rl_src[2]);
      } else {
        ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPut,
                    rl_src[0], rl_src[1], rl_src[2]);
      }
      break;
    case Instruction::APUT_OBJECT:
      ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutObject,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_BOOLEAN:
      ConvertAput(cu, opt_flags,
                  greenland::IntrinsicHelper::HLArrayPutBoolean,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_BYTE:
      ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutByte,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_CHAR:
      ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutChar,
                    rl_src[0], rl_src[1], rl_src[2]);
      break;
    case Instruction::APUT_SHORT:
      ConvertAput(cu, opt_flags, greenland::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,
                    greenland::IntrinsicHelper::HLArrayPutDouble,
                    rl_src[0], rl_src[1], rl_src[2]);
      } else {
        ConvertAput(cu, opt_flags, greenland::IntrinsicHelper::HLArrayPutWide,
                    rl_src[0], rl_src[1], rl_src[2]);
      }
      break;

    case Instruction::IGET:
      if (rl_dest.fp) {
        ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetFloat,
                    rl_dest, rl_src[0], vC);
      } else {
        ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGet,
                    rl_dest, rl_src[0], vC);
      }
      break;
    case Instruction::IGET_OBJECT:
      ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetObject,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_BOOLEAN:
      ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetBoolean,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_BYTE:
      ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetByte,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_CHAR:
      ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetChar,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_SHORT:
      ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetShort,
                  rl_dest, rl_src[0], vC);
      break;
    case Instruction::IGET_WIDE:
      if (rl_dest.fp) {
        ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetDouble,
                    rl_dest, rl_src[0], vC);
      } else {
        ConvertIget(cu, opt_flags, greenland::IntrinsicHelper::HLIGetWide,
                    rl_dest, rl_src[0], vC);
      }
      break;
    case Instruction::IPUT:
      if (rl_src[0].fp) {
        ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutFloat,
                    rl_src[0], rl_src[1], vC);
      } else {
        ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPut,
                    rl_src[0], rl_src[1], vC);
      }
      break;
    case Instruction::IPUT_OBJECT:
      ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutObject,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_BOOLEAN:
      ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutBoolean,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_BYTE:
      ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutByte,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_CHAR:
      ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutChar,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_SHORT:
      ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutShort,
                  rl_src[0], rl_src[1], vC);
      break;
    case Instruction::IPUT_WIDE:
      if (rl_src[0].fp) {
        ConvertIput(cu, opt_flags, greenland::IntrinsicHelper::HLIPutDouble,
                    rl_src[0], rl_src[1], vC);
      } else {
        ConvertIput(cu, opt_flags, greenland::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],
                          greenland::IntrinsicHelper::IntToChar);
      break;
    case Instruction::INT_TO_BYTE:
      ConvertIntNarrowing(cu, rl_dest, rl_src[0],
                          greenland::IntrinsicHelper::IntToByte);
      break;
    case Instruction::INT_TO_SHORT:
      ConvertIntNarrowing(cu, rl_dest, rl_src[0],
                          greenland::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, greenland::IntrinsicHelper::F2I, rl_dest, rl_src[0]);
      break;

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

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

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

    case Instruction::CMPL_FLOAT:
      ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplFloat,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPG_FLOAT:
      ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgFloat,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPL_DOUBLE:
      ConvertWideComparison(cu, greenland::IntrinsicHelper::CmplDouble,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMPG_DOUBLE:
      ConvertWideComparison(cu, greenland::IntrinsicHelper::CmpgDouble,
                            rl_dest, rl_src[0], rl_src[1]);
      break;
    case Instruction::CMP_LONG:
      ConvertWideComparison(cu, greenland::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);
  greenland::IntrinsicHelper::IntrinsicId id;
  id = greenland::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.
      greenland::IntrinsicHelper::IntrinsicId id =
              greenland::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(
            greenland::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->has_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]),
                                              greenland::kAccurate);

  // 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]),
                                             greenland::kAccurate));
  }

  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->LoadConstantValueWide(cu, rl_result.low_reg, rl_result.high_reg,
                          (immval) & 0xffffffff, (immval >> 32) & 0xffffffff);
    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 = 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);
  }
}

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

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

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

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

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

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

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

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

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

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

              case greenland::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;

              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();
      greenland::IntrinsicHelper::IntrinsicId id =
          cu->intrinsic_helper->GetIntrinsicId(callee);
      if (id == greenland::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
