Index: runtime/vm/instructions_arm.cc |
=================================================================== |
--- runtime/vm/instructions_arm.cc (revision 19723) |
+++ runtime/vm/instructions_arm.cc (working copy) |
@@ -5,23 +5,25 @@ |
#include "vm/globals.h" // Needed here to get TARGET_ARCH_ARM. |
#if defined(TARGET_ARCH_ARM) |
+#include "vm/constants_arm.h" |
+#include "vm/cpu.h" |
#include "vm/instructions.h" |
#include "vm/object.h" |
namespace dart { |
-uword InstructionPattern::Back(int n) const { |
+CallPattern::CallPattern(uword pc, const Code& code) |
+ : end_(reinterpret_cast<uword*>(pc)), |
+ pool_index_(DecodePoolIndex()), |
+ object_pool_(Array::Handle(code.ObjectPool())) { } |
+ |
+ |
+uword CallPattern::Back(int n) const { |
ASSERT(n > 0); |
return *(end_ - n); |
} |
-CallPattern::CallPattern(uword pc, const Code& code) |
- : InstructionPattern(pc), |
- pool_index_(DecodePoolIndex()), |
- object_pool_(Array::Handle(code.ObjectPool())) { } |
- |
- |
int CallPattern::DecodePoolIndex() { |
ASSERT(Back(1) == 0xe12fff3e); // Last instruction: blx lr |
// Decode the second to last instruction. |
@@ -70,23 +72,40 @@ |
// The address is stored in the object array as a RawSmi. |
const Smi& smi = Smi::Handle(reinterpret_cast<RawSmi*>(target_address)); |
object_pool_.SetAt(pool_index_, smi); |
+ // No need to flush the instruction cache, since the code is not modified. |
} |
+JumpPattern::JumpPattern(uword pc) : pc_(pc) { } |
+ |
+ |
bool JumpPattern::IsValid() const { |
- UNIMPLEMENTED(); |
- return false; |
+ Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize)); // movw ip, target_lo |
+ Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize)); // movw ip, target_lo |
+ Instr* bxip = Instr::At(pc_ + (2 * Instr::kInstrSize)); // bx ip |
+ return (movw->InstructionBits() & 0xfff0f000) == 0xe300c000 && |
+ (movt->InstructionBits() & 0xfff0f000) == 0xe340c000 && |
+ (bxip->InstructionBits() & 0xffffffff) == 0xe12fff1c; |
} |
uword JumpPattern::TargetAddress() const { |
- UNIMPLEMENTED(); |
- return 0; |
+ Instr* movw = Instr::At(pc_ + (0 * Instr::kInstrSize)); // movw ip, target_lo |
+ Instr* movt = Instr::At(pc_ + (1 * Instr::kInstrSize)); // movw ip, target_lo |
+ uint16_t target_lo = movw->MovwField(); |
+ uint16_t target_hi = movt->MovwField(); |
+ return (target_hi << 16) | target_lo; |
} |
-void JumpPattern::SetTargetAddress(uword target) const { |
- UNIMPLEMENTED(); |
+void JumpPattern::SetTargetAddress(uword target_address) const { |
+ uint16_t target_lo = target_address & 0xffff; |
+ uint16_t target_hi = target_address >> 16; |
+ uword movw = 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff); |
+ uword movt = 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff); |
+ *reinterpret_cast<uword*>(pc_ + (0 * Instr::kInstrSize)) = movw; |
+ *reinterpret_cast<uword*>(pc_ + (1 * Instr::kInstrSize)) = movt; |
+ CPU::FlushICache(pc_, 2 * Instr::kInstrSize); |
} |
} // namespace dart |