Implement new-array instruction.
Change-Id: Ib8b1880082b91c2b388f5e06c2b58347c4aa61e9
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 1912ad0..f4a8a36 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -1540,9 +1540,52 @@
}
+llvm::Value* MethodCompiler::EmitAllocNewArray(uint32_t dex_pc,
+ int32_t length,
+ uint32_t type_idx,
+ bool is_filled_new_array) {
+ llvm::Function* runtime_func;
+
+ bool skip_access_check =
+ compiler_->CanAccessTypeWithoutChecks(method_idx_, dex_cache_,
+ *dex_file_, type_idx);
+
+ if (is_filled_new_array) {
+ runtime_func = skip_access_check ?
+ irb_.GetRuntime(CheckAndAllocArray) :
+ irb_.GetRuntime(CheckAndAllocArrayWithAccessCheck);
+ } else {
+ runtime_func = skip_access_check ?
+ irb_.GetRuntime(AllocArray) :
+ irb_.GetRuntime(AllocArrayWithAccessCheck);
+ }
+
+ llvm::Constant* type_index_value = irb_.getInt32(type_idx);
+
+ llvm::Value* method_object_addr = EmitLoadMethodObjectAddr();
+
+ llvm::Value* array_length_value = irb_.getInt32(length);
+
+ llvm::Value* object_addr =
+ irb_.CreateCall3(runtime_func, type_index_value, method_object_addr,
+ array_length_value);
+
+ EmitGuard_ExceptionLandingPad(dex_pc);
+
+ return object_addr;
+}
+
+
void MethodCompiler::EmitInsn_NewArray(uint32_t dex_pc,
Instruction const* insn) {
- // UNIMPLEMENTED(WARNING);
+
+ Instruction::DecodedInstruction dec_insn(insn);
+
+ llvm::Value* object_addr =
+ EmitAllocNewArray(dex_pc, dec_insn.vB_, dec_insn.vC_, false);
+
+ EmitStoreDalvikReg(dec_insn.vA_, kObject, kAccurate, object_addr);
+
irb_.CreateBr(GetNextBasicBlock(dex_pc));
}
diff --git a/src/compiler_llvm/method_compiler.h b/src/compiler_llvm/method_compiler.h
index b5877e8..df381ee 100644
--- a/src/compiler_llvm/method_compiler.h
+++ b/src/compiler_llvm/method_compiler.h
@@ -309,6 +309,11 @@
llvm::Value* rhs,
FPArithmKind arithm);
+ llvm::Value* EmitAllocNewArray(uint32_t dex_pc,
+ int32_t length,
+ uint32_t type_idx,
+ bool is_filled_new_array);
+
llvm::Value* EmitLoadArrayLength(llvm::Value* array);
llvm::Value* EmitArrayGEP(llvm::Value* array_addr,