Add Dalvik registers initialization codegen.
Change-Id: Ibfec30a2badd30d6cfd450f2af122d5a551ac321
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc
index 31e3c07..f2505f4 100644
--- a/src/compiler_llvm/method_compiler.cc
+++ b/src/compiler_llvm/method_compiler.cc
@@ -54,7 +54,8 @@
access_flags_(access_flags), module_(compiler_llvm_->GetModule()),
context_(compiler_llvm_->GetLLVMContext()),
irb_(*compiler_llvm_->GetIRBuilder()), func_(NULL), retval_reg_(NULL),
- basic_block_reg_alloca_(NULL), basic_block_reg_zero_init_(NULL),
+ basic_block_reg_alloca_(NULL),
+ basic_block_reg_zero_init_(NULL), basic_block_reg_arg_init_(NULL),
basic_blocks_(code_item->insns_size_in_code_units_) {
}
@@ -133,12 +134,22 @@
basic_block_reg_zero_init_ =
llvm::BasicBlock::Create(*context_, "prologue.zeroinit", func_);
+ basic_block_reg_arg_init_ =
+ llvm::BasicBlock::Create(*context_, "prologue.arginit", func_);
+
// Create register array
for (uint16_t r = 0; r < code_item_->registers_size_; ++r) {
regs_.push_back(DalvikReg::CreateLocalVarReg(*this, r));
}
retval_reg_.reset(DalvikReg::CreateRetValReg(*this));
+
+ // Store argument to dalvik register
+ irb_.SetInsertPoint(basic_block_reg_arg_init_);
+ EmitPrologueAssignArgRegister();
+
+ // Branch to start address
+ irb_.CreateBr(GetBasicBlock(0));
}
@@ -147,7 +158,40 @@
irb_.CreateBr(basic_block_reg_zero_init_);
irb_.SetInsertPoint(basic_block_reg_zero_init_);
- irb_.CreateBr(GetBasicBlock(0));
+ irb_.CreateBr(basic_block_reg_arg_init_);
+}
+
+
+void MethodCompiler::EmitPrologueAssignArgRegister() {
+ uint16_t arg_reg = code_item_->registers_size_ - code_item_->ins_size_;
+
+ llvm::Function::arg_iterator arg_iter(func_->arg_begin());
+ llvm::Function::arg_iterator arg_end(func_->arg_end());
+
+ char const* shorty = method_helper_.GetShorty();
+ int32_t shorty_size = method_helper_.GetShortyLength();
+ CHECK_LE(1, shorty_size);
+
+ ++arg_iter; // skip method object
+
+ if (!method_->IsStatic()) {
+ EmitStoreDalvikReg(arg_reg, kObject, kAccurate, arg_iter);
+ ++arg_iter;
+ ++arg_reg;
+ }
+
+ for (int32_t i = 1; i < shorty_size; ++i, ++arg_iter) {
+ EmitStoreDalvikReg(arg_reg, shorty[i], kAccurate, arg_iter);
+
+ ++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;
+ }
+ }
+
+ DCHECK_EQ(arg_end, arg_iter);
}