diff options
| author | 2012-01-03 16:06:32 +0800 | |
|---|---|---|
| committer | 2012-02-17 01:09:11 -0800 | |
| commit | dd6aa87f0484c6097df0657f242eeef9ac9ff9e8 (patch) | |
| tree | 070b36cf9c88b3553bcf8d958ca89456233dcdc8 /src/compiler_llvm/method_compiler.cc | |
| parent | 48f1d2a5c2ff904feb21b55be086903392e7548c (diff) | |
Implement iput* instructions.
Change-Id: Id356c95f5ae4ed576ee02837be9cc376501ce4df
Diffstat (limited to 'src/compiler_llvm/method_compiler.cc')
| -rw-r--r-- | src/compiler_llvm/method_compiler.cc | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/compiler_llvm/method_compiler.cc b/src/compiler_llvm/method_compiler.cc index 3f5766648d..59b31d49aa 100644 --- a/src/compiler_llvm/method_compiler.cc +++ b/src/compiler_llvm/method_compiler.cc @@ -1759,7 +1759,55 @@ void MethodCompiler::EmitInsn_IGet(uint32_t dex_pc, void MethodCompiler::EmitInsn_IPut(uint32_t dex_pc, Instruction const* insn, JType field_jty) { - // UNIMPLEMENTED(WARNING); + + Instruction::DecodedInstruction dec_insn(insn); + + uint32_t reg_idx = dec_insn.vB_; + uint32_t field_idx = dec_insn.vC_; + + Field* field = dex_cache_->GetResolvedField(field_idx); + + llvm::Value* object_addr = EmitLoadDalvikReg(reg_idx, kObject, kAccurate); + + EmitGuard_NullPointerException(dex_pc, object_addr); + + llvm::Value* new_value = EmitLoadDalvikReg(dec_insn.vA_, field_jty, kField); + + if (field == NULL) { + PrintUnresolvedFieldWarning(field_idx); + + llvm::Function* runtime_func; + + if (field_jty == kObject) { + runtime_func = irb_.GetRuntime(SetObjectInstance); + } else if (field_jty == kLong || field_jty == kDouble) { + runtime_func = irb_.GetRuntime(Set64Instance); + } else { + runtime_func = irb_.GetRuntime(Set32Instance); + } + + llvm::Value* field_idx_value = irb_.getInt32(field_idx); + + llvm::Value* method_object_addr = EmitLoadMethodObjectAddr(); + + irb_.CreateCall3(runtime_func, field_idx_value, + method_object_addr, new_value); + + EmitGuard_ExceptionLandingPad(dex_pc); + + } else { + llvm::PointerType* field_type = + irb_.getJType(field_jty, kField)->getPointerTo(); + + llvm::Value* field_offset = + irb_.getPtrEquivInt(field->GetOffset().Int32Value()); + + llvm::Value* field_addr = + irb_.CreatePtrDisp(object_addr, field_offset, field_type); + + irb_.CreateStore(new_value, field_addr); + } + irb_.CreateBr(GetNextBasicBlock(dex_pc)); } |