| // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #include "vm/globals.h" |
| #if defined(TARGET_ARCH_MIPS) |
| |
| #include "vm/assembler.h" |
| |
| namespace dart { |
| |
| DEFINE_FLAG(bool, print_stop_message, true, "Print stop message."); |
| |
| |
| void Assembler::InitializeMemoryWithBreakpoints(uword data, int length) { |
| ASSERT(Utils::IsAligned(data, 4)); |
| ASSERT(Utils::IsAligned(length, 4)); |
| const uword end = data + length; |
| while (data < end) { |
| *reinterpret_cast<int32_t*>(data) = Instr::kBreakPointInstruction; |
| data += 4; |
| } |
| } |
| |
| |
| 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 |
| |