| 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
|
|
|