| Index: runtime/vm/assembler_mips.cc
|
| ===================================================================
|
| --- runtime/vm/assembler_mips.cc (revision 20399)
|
| +++ runtime/vm/assembler_mips.cc (working copy)
|
| @@ -22,6 +22,40 @@
|
| }
|
| }
|
|
|
| +
|
| +void Assembler::Bind(Label* label) {
|
| + ASSERT(!label->IsBound());
|
| + int bound_pc = buffer_.Size();
|
| + while (label->IsLinked()) {
|
| + int32_t position = label->Position();
|
| + int32_t next = buffer_.Load<int32_t>(position);
|
| + // Reletive destination from an instruction after the branch.
|
| + int32_t dest = bound_pc - (position + Instr::kInstrSize);
|
| + int32_t encoded = Assembler::EncodeBranchOffset(dest, next);
|
| + buffer_.Store<int32_t>(position, encoded);
|
| + label->position_ = Assembler::DecodeBranchOffset(next);
|
| + }
|
| + label->BindTo(bound_pc);
|
| + delay_slot_available_ = false;
|
| +}
|
| +
|
| +
|
| +int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t instr) {
|
| + ASSERT(Utils::IsAligned(offset, 4));
|
| + ASSERT(Utils::IsInt(18, offset));
|
| +
|
| + // Properly preserve only the bits supported in the instruction.
|
| + offset >>= 2;
|
| + offset &= kBranchOffsetMask;
|
| + return (instr & ~kBranchOffsetMask) | offset;
|
| +}
|
| +
|
| +
|
| +int Assembler::DecodeBranchOffset(int32_t instr) {
|
| + // Sign-extend, left-shift by 2.
|
| + return (((instr & kBranchOffsetMask) << 16) >> 14);
|
| +}
|
| +
|
| } // namespace dart
|
|
|
| #endif // defined TARGET_ARCH_MIPS
|
|
|