Chromium Code Reviews| Index: runtime/vm/assembler_mips.cc |
| =================================================================== |
| --- runtime/vm/assembler_mips.cc (revision 20500) |
| +++ runtime/vm/assembler_mips.cc (working copy) |
| @@ -9,7 +9,7 @@ |
| namespace dart { |
| -DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| +DEFINE_FLAG(bool, print_stop_message, false, "Print stop message."); |
| void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) { |
| @@ -27,11 +27,11 @@ |
| ASSERT(!label->IsBound()); |
| int bound_pc = buffer_.Size(); |
| while (label->IsLinked()) { |
| - int32_t position = label->Position(); |
| - int32_t next = buffer_.Load<int32_t>(position); |
| + const int32_t position = label->Position(); |
| + const int32_t next = buffer_.Load<int32_t>(position); |
| // Reletive destination from an instruction after the branch. |
|
regis
2013/03/26 17:52:35
Relative
|
| - int32_t dest = bound_pc - (position + Instr::kInstrSize); |
| - int32_t encoded = Assembler::EncodeBranchOffset(dest, next); |
| + const int32_t dest = bound_pc - (position + Instr::kInstrSize); |
| + const int32_t encoded = Assembler::EncodeBranchOffset(dest, next); |
| buffer_.Store<int32_t>(position, encoded); |
| label->position_ = Assembler::DecodeBranchOffset(next); |
| } |
| @@ -56,6 +56,79 @@ |
| return (((instr & kBranchOffsetMask) << 16) >> 14); |
| } |
| + |
| +void Assembler::LoadWordFromPoolOffset(Register rd, int32_t offset) { |
| + ASSERT(rd != PP); |
| + if (Address::CanHoldOffset(offset)) { |
| + lw(rd, Address(PP, offset)); |
| + } else { |
| + const uint16_t offset_low = Utils::Low16Bits(offset); |
| + const uint16_t offset_high = Utils::High16Bits(offset); |
| + if (offset_high != 0) { |
| + lui(rd, Immediate(offset_high)); |
| + if (Address::CanHoldOffset(offset_low)) { |
|
regis
2013/03/26 17:52:35
You need this test, because you chopped off 16 bit
|
| + addu(rd, rd, PP); |
| + lw(rd, Address(rd, offset_low)); |
| + } else { |
| + ori(rd, rd, Immediate(offset_low)); |
| + addu(rd, rd, PP); |
| + lw(rd, Address(rd)); |
| + } |
| + } else { |
| + ori(rd, ZR, Immediate(offset_low)); |
| + addu(rd, rd, PP); |
| + lw(rd, Address(rd)); |
| + } |
| + } |
| +} |
| + |
| + |
| +int32_t Assembler::AddObject(const Object& obj) { |
| + ASSERT(obj.IsNotTemporaryScopedHandle()); |
| + ASSERT(obj.IsOld()); |
| + if (object_pool_.IsNull()) { |
| + // The object pool cannot be used in the vm isolate. |
| + ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| + object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| + } |
| + for (int i = 0; i < object_pool_.Length(); i++) { |
| + if (object_pool_.At(i) == obj.raw()) { |
| + return i; |
| + } |
| + } |
| + object_pool_.Add(obj, Heap::kOld); |
| + return object_pool_.Length() - 1; |
| +} |
| + |
| + |
| +int32_t Assembler::AddExternalLabel(const ExternalLabel* label) { |
| + if (object_pool_.IsNull()) { |
| + // The object pool cannot be used in the vm isolate. |
| + ASSERT(Isolate::Current() != Dart::vm_isolate()); |
| + object_pool_ = GrowableObjectArray::New(Heap::kOld); |
| + } |
| + const word address = label->address(); |
| + ASSERT(Utils::IsAligned(address, 4)); |
| + // The address is stored in the object array as a RawSmi. |
| + const Smi& smi = Smi::Handle(Smi::New(address >> kSmiTagShift)); |
| + // Do not reuse an existing entry, since each reference may be patched |
| + // independently. |
| + object_pool_.Add(smi, Heap::kOld); |
| + return object_pool_.Length() - 1; |
| +} |
| + |
| + |
| +void Assembler::Stop(const char* message) { |
| + if (FLAG_print_stop_message) { |
| + UNIMPLEMENTED(); |
| + } |
| + Label stop; |
| + b(&stop); |
| + Emit(reinterpret_cast<int32_t>(message)); |
| + Bind(&stop); |
| + break_(Instr::kStopMessageCode); |
| +} |
| + |
| } // namespace dart |
| #endif // defined TARGET_ARCH_MIPS |