Implement EmitInstruction() and dispatch the instructions.

Change-Id: Iac95fcab79b845bd821a28fc213dde881ad66e4c
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index ea96b2f..b2dc1f2 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -216,11 +216,1253 @@
   // Set the IRBuilder insertion point
   irb_.SetInsertPoint(GetBasicBlock(dex_pc));
 
+#define ARGS dex_pc, insn
+
+  // Dispatch the instruction
+  switch (insn->Opcode()) {
+  case Instruction::NOP:
+    EmitInsn_Nop(ARGS);
+    break;
+
+  case Instruction::MOVE:
+  case Instruction::MOVE_FROM16:
+  case Instruction::MOVE_16:
+    EmitInsn_Move(ARGS, kInt);
+    break;
+
+  case Instruction::MOVE_WIDE:
+  case Instruction::MOVE_WIDE_FROM16:
+  case Instruction::MOVE_WIDE_16:
+    EmitInsn_Move(ARGS, kLong);
+    break;
+
+  case Instruction::MOVE_OBJECT:
+  case Instruction::MOVE_OBJECT_FROM16:
+  case Instruction::MOVE_OBJECT_16:
+    EmitInsn_Move(ARGS, kObject);
+    break;
+
+  case Instruction::MOVE_RESULT:
+    EmitInsn_MoveResult(ARGS, kInt);
+    break;
+
+  case Instruction::MOVE_RESULT_WIDE:
+    EmitInsn_MoveResult(ARGS, kLong);
+    break;
+
+  case Instruction::MOVE_RESULT_OBJECT:
+    EmitInsn_MoveResult(ARGS, kObject);
+    break;
+
+  case Instruction::MOVE_EXCEPTION:
+    EmitInsn_MoveException(ARGS);
+    break;
+
+  case Instruction::RETURN_VOID:
+    EmitInsn_ReturnVoid(ARGS);
+    break;
+
+  case Instruction::RETURN:
+  case Instruction::RETURN_WIDE:
+  case Instruction::RETURN_OBJECT:
+    EmitInsn_Return(ARGS);
+    break;
+
+  case Instruction::CONST_4:
+  case Instruction::CONST_16:
+  case Instruction::CONST:
+  case Instruction::CONST_HIGH16:
+    EmitInsn_LoadConstant(ARGS, kInt);
+    break;
+
+  case Instruction::CONST_WIDE_16:
+  case Instruction::CONST_WIDE_32:
+  case Instruction::CONST_WIDE:
+  case Instruction::CONST_WIDE_HIGH16:
+    EmitInsn_LoadConstant(ARGS, kLong);
+    break;
+
+  case Instruction::CONST_STRING:
+  case Instruction::CONST_STRING_JUMBO:
+    EmitInsn_LoadConstantString(ARGS);
+    break;
+
+  case Instruction::CONST_CLASS:
+    EmitInsn_LoadConstantClass(ARGS);
+    break;
+
+  case Instruction::MONITOR_ENTER:
+    EmitInsn_MonitorEnter(ARGS);
+    break;
+
+  case Instruction::MONITOR_EXIT:
+    EmitInsn_MonitorExit(ARGS);
+    break;
+
+  case Instruction::CHECK_CAST:
+    EmitInsn_CheckCast(ARGS);
+    break;
+
+  case Instruction::INSTANCE_OF:
+    EmitInsn_InstanceOf(ARGS);
+    break;
+
+  case Instruction::ARRAY_LENGTH:
+    EmitInsn_ArrayLength(ARGS);
+    break;
+
+  case Instruction::NEW_INSTANCE:
+    EmitInsn_NewInstance(ARGS);
+    break;
+
+  case Instruction::NEW_ARRAY:
+    EmitInsn_NewArray(ARGS);
+    break;
+
+  case Instruction::FILLED_NEW_ARRAY:
+    EmitInsn_FilledNewArray(ARGS, false);
+    break;
+
+  case Instruction::FILLED_NEW_ARRAY_RANGE:
+    EmitInsn_FilledNewArray(ARGS, true);
+    break;
+
+  case Instruction::FILL_ARRAY_DATA:
+    EmitInsn_FillArrayData(ARGS);
+    break;
+
+  case Instruction::THROW:
+    EmitInsn_ThrowException(ARGS);
+    break;
+
+  case Instruction::GOTO:
+  case Instruction::GOTO_16:
+  case Instruction::GOTO_32:
+    EmitInsn_UnconditionalBranch(ARGS);
+    break;
+
+  case Instruction::PACKED_SWITCH:
+    EmitInsn_PackedSwitch(ARGS);
+    break;
+
+  case Instruction::SPARSE_SWITCH:
+    EmitInsn_SparseSwitch(ARGS);
+    break;
+
+  case Instruction::CMPL_FLOAT:
+    EmitInsn_FPCompare(ARGS, kFloat, false);
+    break;
+
+  case Instruction::CMPG_FLOAT:
+    EmitInsn_FPCompare(ARGS, kFloat, true);
+    break;
+
+  case Instruction::CMPL_DOUBLE:
+    EmitInsn_FPCompare(ARGS, kDouble, false);
+    break;
+
+  case Instruction::CMPG_DOUBLE:
+    EmitInsn_FPCompare(ARGS, kDouble, true);
+    break;
+
+  case Instruction::CMP_LONG:
+    EmitInsn_LongCompare(ARGS);
+    break;
+
+  case Instruction::IF_EQ:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_EQ);
+    break;
+
+  case Instruction::IF_NE:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_NE);
+    break;
+
+  case Instruction::IF_LT:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LT);
+    break;
+
+  case Instruction::IF_GE:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GE);
+    break;
+
+  case Instruction::IF_GT:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_GT);
+    break;
+
+  case Instruction::IF_LE:
+    EmitInsn_BinaryConditionalBranch(ARGS, kCondBranch_LE);
+    break;
+
+  case Instruction::IF_EQZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_EQ);
+    break;
+
+  case Instruction::IF_NEZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_NE);
+    break;
+
+  case Instruction::IF_LTZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LT);
+    break;
+
+  case Instruction::IF_GEZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GE);
+    break;
+
+  case Instruction::IF_GTZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_GT);
+    break;
+
+  case Instruction::IF_LEZ:
+    EmitInsn_UnaryConditionalBranch(ARGS, kCondBranch_LE);
+    break;
+
+  case Instruction::AGET:
+    EmitInsn_AGet(ARGS, kInt);
+    break;
+
+  case Instruction::AGET_WIDE:
+    EmitInsn_AGet(ARGS, kLong);
+    break;
+
+  case Instruction::AGET_OBJECT:
+    EmitInsn_AGet(ARGS, kObject);
+    break;
+
+  case Instruction::AGET_BOOLEAN:
+    EmitInsn_AGet(ARGS, kBoolean);
+    break;
+
+  case Instruction::AGET_BYTE:
+    EmitInsn_AGet(ARGS, kByte);
+    break;
+
+  case Instruction::AGET_CHAR:
+    EmitInsn_AGet(ARGS, kChar);
+    break;
+
+  case Instruction::AGET_SHORT:
+    EmitInsn_AGet(ARGS, kShort);
+    break;
+
+  case Instruction::APUT:
+    EmitInsn_APut(ARGS, kInt);
+    break;
+
+  case Instruction::APUT_WIDE:
+    EmitInsn_APut(ARGS, kLong);
+    break;
+
+  case Instruction::APUT_OBJECT:
+    EmitInsn_APut(ARGS, kObject);
+    break;
+
+  case Instruction::APUT_BOOLEAN:
+    EmitInsn_APut(ARGS, kBoolean);
+    break;
+
+  case Instruction::APUT_BYTE:
+    EmitInsn_APut(ARGS, kByte);
+    break;
+
+  case Instruction::APUT_CHAR:
+    EmitInsn_APut(ARGS, kChar);
+    break;
+
+  case Instruction::APUT_SHORT:
+    EmitInsn_APut(ARGS, kShort);
+    break;
+
+  case Instruction::IGET:
+    EmitInsn_IGet(ARGS, kInt);
+    break;
+
+  case Instruction::IGET_WIDE:
+    EmitInsn_IGet(ARGS, kLong);
+    break;
+
+  case Instruction::IGET_OBJECT:
+    EmitInsn_IGet(ARGS, kObject);
+    break;
+
+  case Instruction::IGET_BOOLEAN:
+    EmitInsn_IGet(ARGS, kBoolean);
+    break;
+
+  case Instruction::IGET_BYTE:
+    EmitInsn_IGet(ARGS, kByte);
+    break;
+
+  case Instruction::IGET_CHAR:
+    EmitInsn_IGet(ARGS, kChar);
+    break;
+
+  case Instruction::IGET_SHORT:
+    EmitInsn_IGet(ARGS, kShort);
+    break;
+
+  case Instruction::IPUT:
+    EmitInsn_IPut(ARGS, kInt);
+    break;
+
+  case Instruction::IPUT_WIDE:
+    EmitInsn_IPut(ARGS, kLong);
+    break;
+
+  case Instruction::IPUT_OBJECT:
+    EmitInsn_IPut(ARGS, kObject);
+    break;
+
+  case Instruction::IPUT_BOOLEAN:
+    EmitInsn_IPut(ARGS, kBoolean);
+    break;
+
+  case Instruction::IPUT_BYTE:
+    EmitInsn_IPut(ARGS, kByte);
+    break;
+
+  case Instruction::IPUT_CHAR:
+    EmitInsn_IPut(ARGS, kChar);
+    break;
+
+  case Instruction::IPUT_SHORT:
+    EmitInsn_IPut(ARGS, kShort);
+    break;
+
+  case Instruction::SGET:
+    EmitInsn_SGet(ARGS, kInt);
+    break;
+
+  case Instruction::SGET_WIDE:
+    EmitInsn_SGet(ARGS, kLong);
+    break;
+
+  case Instruction::SGET_OBJECT:
+    EmitInsn_SGet(ARGS, kObject);
+    break;
+
+  case Instruction::SGET_BOOLEAN:
+    EmitInsn_SGet(ARGS, kBoolean);
+    break;
+
+  case Instruction::SGET_BYTE:
+    EmitInsn_SGet(ARGS, kByte);
+    break;
+
+  case Instruction::SGET_CHAR:
+    EmitInsn_SGet(ARGS, kChar);
+    break;
+
+  case Instruction::SGET_SHORT:
+    EmitInsn_SGet(ARGS, kShort);
+    break;
+
+  case Instruction::SPUT:
+    EmitInsn_SPut(ARGS, kInt);
+    break;
+
+  case Instruction::SPUT_WIDE:
+    EmitInsn_SPut(ARGS, kLong);
+    break;
+
+  case Instruction::SPUT_OBJECT:
+    EmitInsn_SPut(ARGS, kObject);
+    break;
+
+  case Instruction::SPUT_BOOLEAN:
+    EmitInsn_SPut(ARGS, kBoolean);
+    break;
+
+  case Instruction::SPUT_BYTE:
+    EmitInsn_SPut(ARGS, kByte);
+    break;
+
+  case Instruction::SPUT_CHAR:
+    EmitInsn_SPut(ARGS, kChar);
+    break;
+
+  case Instruction::SPUT_SHORT:
+    EmitInsn_SPut(ARGS, kShort);
+    break;
+
+
+  case Instruction::INVOKE_VIRTUAL:
+    EmitInsn_InvokeVirtual(ARGS, false);
+    break;
+
+  case Instruction::INVOKE_SUPER:
+    EmitInsn_InvokeSuper(ARGS, false);
+    break;
+
+  case Instruction::INVOKE_DIRECT:
+    EmitInsn_InvokeDirect(ARGS, false);
+    break;
+
+  case Instruction::INVOKE_STATIC:
+    EmitInsn_InvokeStatic(ARGS, false);
+    break;
+
+  case Instruction::INVOKE_INTERFACE:
+    EmitInsn_InvokeInterface(ARGS, false);
+    break;
+
+  case Instruction::INVOKE_VIRTUAL_RANGE:
+    EmitInsn_InvokeVirtual(ARGS, true);
+    break;
+
+  case Instruction::INVOKE_SUPER_RANGE:
+    EmitInsn_InvokeSuper(ARGS, true);
+    break;
+
+  case Instruction::INVOKE_DIRECT_RANGE:
+    EmitInsn_InvokeDirect(ARGS, true);
+    break;
+
+  case Instruction::INVOKE_STATIC_RANGE:
+    EmitInsn_InvokeStatic(ARGS, true);
+    break;
+
+  case Instruction::INVOKE_INTERFACE_RANGE:
+    EmitInsn_InvokeInterface(ARGS, true);
+    break;
+
+  case Instruction::NEG_INT:
+    EmitInsn_Neg(ARGS, kInt);
+    break;
+
+  case Instruction::NOT_INT:
+    EmitInsn_Not(ARGS, kInt);
+    break;
+
+  case Instruction::NEG_LONG:
+    EmitInsn_Neg(ARGS, kLong);
+    break;
+
+  case Instruction::NOT_LONG:
+    EmitInsn_Not(ARGS, kLong);
+    break;
+
+  case Instruction::NEG_FLOAT:
+    EmitInsn_FNeg(ARGS, kFloat);
+    break;
+
+  case Instruction::NEG_DOUBLE:
+    EmitInsn_FNeg(ARGS, kDouble);
+    break;
+
+  case Instruction::INT_TO_LONG:
+    EmitInsn_SExt(ARGS);
+    break;
+
+  case Instruction::INT_TO_FLOAT:
+    EmitInsn_IntToFP(ARGS, kInt, kFloat);
+    break;
+
+  case Instruction::INT_TO_DOUBLE:
+    EmitInsn_IntToFP(ARGS, kInt, kDouble);
+    break;
+
+  case Instruction::LONG_TO_INT:
+    EmitInsn_Trunc(ARGS);
+    break;
+
+  case Instruction::LONG_TO_FLOAT:
+    EmitInsn_IntToFP(ARGS, kLong, kFloat);
+    break;
+
+  case Instruction::LONG_TO_DOUBLE:
+    EmitInsn_IntToFP(ARGS, kLong, kDouble);
+    break;
+
+  case Instruction::FLOAT_TO_INT:
+    EmitInsn_FPToInt(ARGS, kFloat, kInt);
+    break;
+
+  case Instruction::FLOAT_TO_LONG:
+    EmitInsn_FPToInt(ARGS, kFloat, kLong);
+    break;
+
+  case Instruction::FLOAT_TO_DOUBLE:
+    EmitInsn_FExt(ARGS);
+    break;
+
+  case Instruction::DOUBLE_TO_INT:
+    EmitInsn_FPToInt(ARGS, kDouble, kInt);
+    break;
+
+  case Instruction::DOUBLE_TO_LONG:
+    EmitInsn_FPToInt(ARGS, kDouble, kLong);
+    break;
+
+  case Instruction::DOUBLE_TO_FLOAT:
+    EmitInsn_FTrunc(ARGS);
+    break;
+
+  case Instruction::INT_TO_BYTE:
+    EmitInsn_TruncAndSExt(ARGS, 8);
+    break;
+
+  case Instruction::INT_TO_CHAR:
+    EmitInsn_TruncAndZExt(ARGS, 16);
+    break;
+
+  case Instruction::INT_TO_SHORT:
+    EmitInsn_TruncAndSExt(ARGS, 16);
+    break;
+
+  case Instruction::ADD_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, false);
+    break;
+
+  case Instruction::SUB_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, false);
+    break;
+
+  case Instruction::MUL_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, false);
+    break;
+
+  case Instruction::DIV_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, false);
+    break;
+
+  case Instruction::REM_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, false);
+    break;
+
+  case Instruction::AND_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, false);
+    break;
+
+  case Instruction::OR_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, false);
+    break;
+
+  case Instruction::XOR_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, false);
+    break;
+
+  case Instruction::SHL_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shl, kInt, false);
+    break;
+
+  case Instruction::SHR_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shr, kInt, false);
+    break;
+
+  case Instruction::USHR_INT:
+    EmitInsn_IntArithm(ARGS, kIntArithm_UShr, kInt, false);
+    break;
+
+  case Instruction::ADD_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, false);
+    break;
+
+  case Instruction::SUB_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, false);
+    break;
+
+  case Instruction::MUL_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, false);
+    break;
+
+  case Instruction::DIV_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, false);
+    break;
+
+  case Instruction::REM_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, false);
+    break;
+
+  case Instruction::AND_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, false);
+    break;
+
+  case Instruction::OR_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, false);
+    break;
+
+  case Instruction::XOR_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, false);
+    break;
+
+  case Instruction::SHL_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shl, kLong, false);
+    break;
+
+  case Instruction::SHR_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shr, kLong, false);
+    break;
+
+  case Instruction::USHR_LONG:
+    EmitInsn_IntArithm(ARGS, kIntArithm_UShr, kLong, false);
+    break;
+
+  case Instruction::ADD_FLOAT:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, false);
+    break;
+
+  case Instruction::SUB_FLOAT:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, false);
+    break;
+
+  case Instruction::MUL_FLOAT:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, false);
+    break;
+
+  case Instruction::DIV_FLOAT:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, false);
+    break;
+
+  case Instruction::REM_FLOAT:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, false);
+    break;
+
+  case Instruction::ADD_DOUBLE:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, false);
+    break;
+
+  case Instruction::SUB_DOUBLE:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, false);
+    break;
+
+  case Instruction::MUL_DOUBLE:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, false);
+    break;
+
+  case Instruction::DIV_DOUBLE:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, false);
+    break;
+
+  case Instruction::REM_DOUBLE:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, false);
+    break;
+
+  case Instruction::ADD_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kInt, true);
+    break;
+
+  case Instruction::SUB_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kInt, true);
+    break;
+
+  case Instruction::MUL_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kInt, true);
+    break;
+
+  case Instruction::DIV_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kInt, true);
+    break;
+
+  case Instruction::REM_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kInt, true);
+    break;
+
+  case Instruction::AND_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_And, kInt, true);
+    break;
+
+  case Instruction::OR_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kInt, true);
+    break;
+
+  case Instruction::XOR_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kInt, true);
+    break;
+
+  case Instruction::SHL_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shl, kInt, true);
+    break;
+
+  case Instruction::SHR_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shr, kInt, true);
+    break;
+
+  case Instruction::USHR_INT_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_UShr, kInt, true);
+    break;
+
+  case Instruction::ADD_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Add, kLong, true);
+    break;
+
+  case Instruction::SUB_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Sub, kLong, true);
+    break;
+
+  case Instruction::MUL_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Mul, kLong, true);
+    break;
+
+  case Instruction::DIV_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Div, kLong, true);
+    break;
+
+  case Instruction::REM_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Rem, kLong, true);
+    break;
+
+  case Instruction::AND_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_And, kLong, true);
+    break;
+
+  case Instruction::OR_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Or, kLong, true);
+    break;
+
+  case Instruction::XOR_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Xor, kLong, true);
+    break;
+
+  case Instruction::SHL_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shl, kLong, true);
+    break;
+
+  case Instruction::SHR_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_Shr, kLong, true);
+    break;
+
+  case Instruction::USHR_LONG_2ADDR:
+    EmitInsn_IntArithm(ARGS, kIntArithm_UShr, kLong, true);
+    break;
+
+  case Instruction::ADD_FLOAT_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kFloat, true);
+    break;
+
+  case Instruction::SUB_FLOAT_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kFloat, true);
+    break;
+
+  case Instruction::MUL_FLOAT_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kFloat, true);
+    break;
+
+  case Instruction::DIV_FLOAT_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kFloat, true);
+    break;
+
+  case Instruction::REM_FLOAT_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kFloat, true);
+    break;
+
+  case Instruction::ADD_DOUBLE_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Add, kDouble, true);
+    break;
+
+  case Instruction::SUB_DOUBLE_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Sub, kDouble, true);
+    break;
+
+  case Instruction::MUL_DOUBLE_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Mul, kDouble, true);
+    break;
+
+  case Instruction::DIV_DOUBLE_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Div, kDouble, true);
+    break;
+
+  case Instruction::REM_DOUBLE_2ADDR:
+    EmitInsn_FPArithm(ARGS, kFPArithm_Rem, kDouble, true);
+    break;
+
+  case Instruction::ADD_INT_LIT16:
+  case Instruction::ADD_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Add);
+    break;
+
+  case Instruction::RSUB_INT:
+  case Instruction::RSUB_INT_LIT8:
+    EmitInsn_RSubImmediate(ARGS);
+    break;
+
+  case Instruction::MUL_INT_LIT16:
+  case Instruction::MUL_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Mul);
+    break;
+
+  case Instruction::DIV_INT_LIT16:
+  case Instruction::DIV_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Div);
+    break;
+
+  case Instruction::REM_INT_LIT16:
+  case Instruction::REM_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Rem);
+    break;
+
+  case Instruction::AND_INT_LIT16:
+  case Instruction::AND_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_And);
+    break;
+
+  case Instruction::OR_INT_LIT16:
+  case Instruction::OR_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Or);
+    break;
+
+  case Instruction::XOR_INT_LIT16:
+  case Instruction::XOR_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Xor);
+    break;
+
+  case Instruction::SHL_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Shl);
+    break;
+
+  case Instruction::SHR_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_Shr);
+    break;
+
+  case Instruction::USHR_INT_LIT8:
+    EmitInsn_IntArithmImmediate(ARGS, kIntArithm_UShr);
+    break;
+
+  case Instruction::UNUSED_3E:
+  case Instruction::UNUSED_3F:
+  case Instruction::UNUSED_40:
+  case Instruction::UNUSED_41:
+  case Instruction::UNUSED_42:
+  case Instruction::UNUSED_43:
+  case Instruction::UNUSED_73:
+  case Instruction::UNUSED_79:
+  case Instruction::UNUSED_7A:
+  case Instruction::UNUSED_E3:
+  case Instruction::UNUSED_E4:
+  case Instruction::UNUSED_E5:
+  case Instruction::UNUSED_E6:
+  case Instruction::UNUSED_E7:
+  case Instruction::UNUSED_E8:
+  case Instruction::UNUSED_E9:
+  case Instruction::UNUSED_EA:
+  case Instruction::UNUSED_EB:
+  case Instruction::UNUSED_EC:
+  case Instruction::THROW_VERIFICATION_ERROR:
+  case Instruction::UNUSED_EE:
+  case Instruction::UNUSED_EF:
+  case Instruction::UNUSED_F0:
+  case Instruction::UNUSED_F1:
+  case Instruction::UNUSED_F2:
+  case Instruction::UNUSED_F3:
+  case Instruction::UNUSED_F4:
+  case Instruction::UNUSED_F5:
+  case Instruction::UNUSED_F6:
+  case Instruction::UNUSED_F7:
+  case Instruction::UNUSED_F8:
+  case Instruction::UNUSED_F9:
+  case Instruction::UNUSED_FA:
+  case Instruction::UNUSED_FB:
+  case Instruction::UNUSED_FC:
+  case Instruction::UNUSED_FD:
+  case Instruction::UNUSED_FE:
+  case Instruction::UNUSED_FF:
+    LOG(FATAL) << "Dex file contains UNUSED bytecode: " << insn->Opcode();
+    break;
+  }
+
+#undef ARGS
+}
+
+
+void MethodCompiler::EmitInsn_Nop(uint32_t dex_pc,
+                                  Instruction const* insn) {
   // UNIMPLEMENTED(WARNING);
   irb_.CreateUnreachable();
 }
 
 
+void MethodCompiler::EmitInsn_Move(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_MoveResult(uint32_t dex_pc,
+                                         Instruction const* insn,
+                                         JType jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_MoveException(uint32_t dex_pc,
+                                            Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_ThrowException(uint32_t dex_pc,
+                                             Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_ReturnVoid(uint32_t dex_pc,
+                                         Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_Return(uint32_t dex_pc,
+                                     Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_LoadConstant(uint32_t dex_pc,
+                                           Instruction const* insn,
+                                           JType imm_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_LoadConstantString(uint32_t dex_pc,
+                                                 Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_LoadConstantClass(uint32_t dex_pc,
+                                                Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_MonitorEnter(uint32_t dex_pc,
+                                           Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_MonitorExit(uint32_t dex_pc,
+                                          Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_CheckCast(uint32_t dex_pc,
+                                        Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InstanceOf(uint32_t dex_pc,
+                                         Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_ArrayLength(uint32_t dex_pc,
+                                          Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_NewInstance(uint32_t dex_pc,
+                                          Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_NewArray(uint32_t dex_pc,
+                                       Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FilledNewArray(uint32_t dex_pc,
+                                             Instruction const* insn,
+                                             bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FillArrayData(uint32_t dex_pc,
+                                            Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_UnconditionalBranch(uint32_t dex_pc,
+                                                  Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_PackedSwitch(uint32_t dex_pc,
+                                           Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_SparseSwitch(uint32_t dex_pc,
+                                           Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_FPCompare(uint32_t dex_pc,
+                                        Instruction const* insn,
+                                        JType fp_jty,
+                                        bool gt_bias) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_LongCompare(uint32_t dex_pc,
+                                          Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_BinaryConditionalBranch(uint32_t dex_pc,
+                                                      Instruction const* insn,
+                                                      CondBranchKind cond) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_UnaryConditionalBranch(uint32_t dex_pc,
+                                                     Instruction const* insn,
+                                                     CondBranchKind cond) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateUnreachable();
+}
+
+
+void MethodCompiler::EmitInsn_AGet(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType elem_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_APut(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType elem_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_IGet(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType field_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_IPut(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType field_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_SGet(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType field_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_SPut(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType field_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InvokeVirtual(uint32_t dex_pc,
+                                            Instruction const* insn,
+                                            bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InvokeSuper(uint32_t dex_pc,
+                                          Instruction const* insn,
+                                          bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InvokeDirect(uint32_t dex_pc,
+                                           Instruction const* insn,
+                                           bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InvokeStatic(uint32_t dex_pc,
+                                           Instruction const* insn,
+                                           bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_InvokeInterface(uint32_t dex_pc,
+                                              Instruction const* insn,
+                                              bool is_range) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_Neg(uint32_t dex_pc,
+                                  Instruction const* insn,
+                                  JType op_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_Not(uint32_t dex_pc,
+                                  Instruction const* insn,
+                                  JType op_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_SExt(uint32_t dex_pc,
+                                   Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_Trunc(uint32_t dex_pc,
+                                    Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_TruncAndSExt(uint32_t dex_pc,
+                                           Instruction const* insn,
+                                           unsigned N) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_TruncAndZExt(uint32_t dex_pc,
+                                           Instruction const* insn,
+                                           unsigned N) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FNeg(uint32_t dex_pc,
+                                   Instruction const* insn,
+                                   JType op_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_IntToFP(uint32_t dex_pc,
+                                      Instruction const* insn,
+                                      JType src_jty,
+                                      JType dest_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FPToInt(uint32_t dex_pc,
+                                      Instruction const* insn,
+                                      JType src_jty,
+                                      JType dest_jty) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FExt(uint32_t dex_pc,
+                                   Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FTrunc(uint32_t dex_pc,
+                                     Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_IntArithm(uint32_t dex_pc,
+                                        Instruction const* insn,
+                                        IntArithmKind arithm,
+                                        JType op_jty,
+                                        bool is_2addr) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_IntArithmImmediate(uint32_t dex_pc,
+                                                 Instruction const* insn,
+                                                 IntArithmKind arithm) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_RSubImmediate(uint32_t dex_pc,
+                                            Instruction const* insn) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
+void MethodCompiler::EmitInsn_FPArithm(uint32_t dex_pc,
+                                       Instruction const* insn,
+                                       FPArithmKind arithm,
+                                       JType op_jty,
+                                       bool is_2addr) {
+  // UNIMPLEMENTED(WARNING);
+  irb_.CreateBr(GetNextBasicBlock(dex_pc));
+}
+
+
 CompiledMethod *MethodCompiler::Compile() {
   // Code generation
   CreateFunction();
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index f9e73f9..719ef8b 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -126,14 +126,143 @@
 
  private:
   void CreateFunction();
-
-
   void EmitPrologue();
   void EmitPrologueLastBranch();
   void EmitPrologueAssignArgRegister();
   void EmitInstructions();
   void EmitInstruction(uint32_t dex_pc, Instruction const* insn);
 
+  enum CondBranchKind {
+    kCondBranch_EQ,
+    kCondBranch_NE,
+    kCondBranch_LT,
+    kCondBranch_GE,
+    kCondBranch_GT,
+    kCondBranch_LE,
+  };
+
+  enum IntArithmKind {
+    kIntArithm_Add,
+    kIntArithm_Sub,
+    kIntArithm_Mul,
+    kIntArithm_Div,
+    kIntArithm_Rem,
+    kIntArithm_And,
+    kIntArithm_Or,
+    kIntArithm_Xor,
+    kIntArithm_Shl,
+    kIntArithm_Shr,
+    kIntArithm_UShr,
+  };
+
+  enum FPArithmKind {
+    kFPArithm_Add,
+    kFPArithm_Sub,
+    kFPArithm_Mul,
+    kFPArithm_Div,
+    kFPArithm_Rem,
+  };
+
+#define GEN_INSN_ARGS uint32_t dex_pc, Instruction const* insn
+
+  // NOP, PAYLOAD (unreachable) instructions
+  void EmitInsn_Nop(GEN_INSN_ARGS);
+
+  // MOVE, MOVE_RESULT instructions
+  void EmitInsn_Move(GEN_INSN_ARGS, JType jty);
+  void EmitInsn_MoveResult(GEN_INSN_ARGS, JType jty);
+
+  // MOVE_EXCEPTION, THROW instructions
+  void EmitInsn_MoveException(GEN_INSN_ARGS);
+  void EmitInsn_ThrowException(GEN_INSN_ARGS);
+
+  // RETURN instructions
+  void EmitInsn_ReturnVoid(GEN_INSN_ARGS);
+  void EmitInsn_Return(GEN_INSN_ARGS);
+
+  // CONST, CONST_CLASS, CONST_STRING instructions
+  void EmitInsn_LoadConstant(GEN_INSN_ARGS, JType imm_jty);
+  void EmitInsn_LoadConstantString(GEN_INSN_ARGS);
+  void EmitInsn_LoadConstantClass(GEN_INSN_ARGS);
+
+  // MONITOR_ENTER, MONITOR_EXIT instructions
+  void EmitInsn_MonitorEnter(GEN_INSN_ARGS);
+  void EmitInsn_MonitorExit(GEN_INSN_ARGS);
+
+  // CHECK_CAST, INSTANCE_OF instructions
+  void EmitInsn_CheckCast(GEN_INSN_ARGS);
+  void EmitInsn_InstanceOf(GEN_INSN_ARGS);
+
+  // NEW_INSTANCE instructions
+  void EmitInsn_NewInstance(GEN_INSN_ARGS);
+
+  // ARRAY_LEN, NEW_ARRAY, FILLED_NEW_ARRAY, FILL_ARRAY_DATA instructions
+  void EmitInsn_ArrayLength(GEN_INSN_ARGS);
+  void EmitInsn_NewArray(GEN_INSN_ARGS);
+  void EmitInsn_FilledNewArray(GEN_INSN_ARGS, bool is_range);
+  void EmitInsn_FillArrayData(GEN_INSN_ARGS);
+
+  // GOTO, IF_TEST, IF_TESTZ instructions
+  void EmitInsn_UnconditionalBranch(GEN_INSN_ARGS);
+  void EmitInsn_BinaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
+  void EmitInsn_UnaryConditionalBranch(GEN_INSN_ARGS, CondBranchKind cond);
+
+  // PACKED_SWITCH, SPARSE_SWITCH instrutions
+  void EmitInsn_PackedSwitch(GEN_INSN_ARGS);
+  void EmitInsn_SparseSwitch(GEN_INSN_ARGS);
+
+  // CMPX_FLOAT, CMPX_DOUBLE, CMP_LONG instructions
+  void EmitInsn_FPCompare(GEN_INSN_ARGS, JType fp_jty, bool gt_bias);
+  void EmitInsn_LongCompare(GEN_INSN_ARGS);
+
+  // AGET, APUT instrutions
+  void EmitInsn_AGet(GEN_INSN_ARGS, JType elem_jty);
+  void EmitInsn_APut(GEN_INSN_ARGS, JType elem_jty);
+
+  // IGET, IPUT instructions
+  void EmitInsn_IGet(GEN_INSN_ARGS, JType field_jty);
+  void EmitInsn_IPut(GEN_INSN_ARGS, JType field_jty);
+
+  // SGET, SPUT instructions
+  void EmitInsn_SGet(GEN_INSN_ARGS, JType field_jty);
+  void EmitInsn_SPut(GEN_INSN_ARGS, JType field_jty);
+
+  // INVOKE instructions
+  void EmitInsn_InvokeVirtual(GEN_INSN_ARGS, bool is_range);
+  void EmitInsn_InvokeSuper(GEN_INSN_ARGS, bool is_range);
+  void EmitInsn_InvokeDirect(GEN_INSN_ARGS, bool is_range);
+  void EmitInsn_InvokeStatic(GEN_INSN_ARGS, bool is_range);
+  void EmitInsn_InvokeInterface(GEN_INSN_ARGS, bool is_range);
+
+  // Unary instructions
+  void EmitInsn_Neg(GEN_INSN_ARGS, JType op_jty);
+  void EmitInsn_Not(GEN_INSN_ARGS, JType op_jty);
+  void EmitInsn_SExt(GEN_INSN_ARGS);
+  void EmitInsn_Trunc(GEN_INSN_ARGS);
+  void EmitInsn_TruncAndSExt(GEN_INSN_ARGS, unsigned N);
+  void EmitInsn_TruncAndZExt(GEN_INSN_ARGS, unsigned N);
+
+  void EmitInsn_FNeg(GEN_INSN_ARGS, JType op_jty);
+  void EmitInsn_IntToFP(GEN_INSN_ARGS, JType src_jty, JType dest_jty);
+  void EmitInsn_FPToInt(GEN_INSN_ARGS, JType src_jty, JType dest_jty);
+  void EmitInsn_FExt(GEN_INSN_ARGS);
+  void EmitInsn_FTrunc(GEN_INSN_ARGS);
+
+  // Integer binary arithmetic instructions
+  void EmitInsn_IntArithm(GEN_INSN_ARGS, IntArithmKind arithm,
+                          JType op_jty, bool is_2addr);
+
+  void EmitInsn_IntArithmImmediate(GEN_INSN_ARGS, IntArithmKind arithm);
+
+  void EmitInsn_RSubImmediate(GEN_INSN_ARGS);
+
+
+  // Floating-point binary arithmetic instructions
+  void EmitInsn_FPArithm(GEN_INSN_ARGS, FPArithmKind arithm,
+                         JType op_jty, bool is_2addr);
+
+#undef GEN_INSN_ARGS
+
 
   // Code generation helper function
 
@@ -145,7 +274,7 @@
 
   void EmitBranchExceptionLandingPad(uint32_t dex_pc);
 
-  void EmitGuard_GarbageCollectionSuspend(uint32_t addr);
+  void EmitGuard_GarbageCollectionSuspend(uint32_t dex_pc);
 
 
   // Basic block helper functions