Index: runtime/vm/assembler_mips.cc |
=================================================================== |
--- runtime/vm/assembler_mips.cc (revision 20394) |
+++ runtime/vm/assembler_mips.cc (working copy) |
@@ -22,6 +22,37 @@ |
} |
} |
+ |
+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); |
+ int32_t encoded = Assembler::EncodeBranchOffset(bound_pc - position, next); |
+ buffer_.Store<int32_t>(position, encoded); |
+ label->position_ = Assembler::DecodeBranchOffset(next); |
+ } |
+ label->BindTo(bound_pc); |
+} |
+ |
+ |
+int32_t Assembler::EncodeBranchOffset(int32_t offset, int32_t inst) { |
regis
2013/03/22 19:51:16
inst -> instr
zra
2013/03/22 20:16:01
Done.
|
+ ASSERT(Utils::IsAligned(offset, 4)); |
+ ASSERT(Utils::IsInt(16, offset)); |
regis
2013/03/22 19:51:16
Not 16, but 18.
zra
2013/03/22 20:16:01
Done.
|
+ |
+ // Properly preserve only the bits supported in the instruction. |
+ offset >>= 2; |
+ offset &= kBranchOffsetMask; |
+ return (inst & ~kBranchOffsetMask) | offset; |
+} |
+ |
+ |
+int Assembler::DecodeBranchOffset(int32_t inst) { |
regis
2013/03/22 19:51:16
Do you use this call while assembling instructions
zra
2013/03/22 20:16:01
It's used in Bind above. This also mirrors the ARM
|
+ // Sign-extend, left-shift by 2. |
+ return (((inst & kBranchOffsetMask) << 16) >> 14); |
+} |
+ |
} // namespace dart |
#endif // defined TARGET_ARCH_MIPS |