| Index: runtime/vm/assembler_mips.cc
|
| diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
|
| index d14d63512d5e9459c1dd7dac5034f6ab498f5b4d..a839a5849a8936892008e2be18108768c3e73bfb 100644
|
| --- a/runtime/vm/assembler_mips.cc
|
| +++ b/runtime/vm/assembler_mips.cc
|
| @@ -457,33 +457,51 @@ void Assembler::SubuDetectOverflow(Register rd, Register rs, Register rt,
|
|
|
|
|
| void Assembler::Branch(const StubEntry& stub_entry) {
|
| - const ExternalLabel label(stub_entry.EntryPoint());
|
| - Branch(&label);
|
| + ASSERT(!in_delay_slot_);
|
| + LoadImmediate(TMP, stub_entry.label().address());
|
| + jr(TMP);
|
| }
|
|
|
|
|
| void Assembler::BranchPatchable(const StubEntry& stub_entry) {
|
| - const ExternalLabel label(stub_entry.EntryPoint());
|
| - BranchPatchable(&label);
|
| + ASSERT(!in_delay_slot_);
|
| + const ExternalLabel& label = stub_entry.label();
|
| + const uint16_t low = Utils::Low16Bits(label.address());
|
| + const uint16_t high = Utils::High16Bits(label.address());
|
| + lui(T9, Immediate(high));
|
| + ori(T9, T9, Immediate(low));
|
| + jr(T9);
|
| + delay_slot_available_ = false; // CodePatcher expects a nop.
|
| }
|
|
|
|
|
| -void Assembler::BranchLink(const StubEntry& stub_entry) {
|
| - const ExternalLabel label(stub_entry.EntryPoint());
|
| - BranchLink(&label);
|
| +void Assembler::BranchLink(const ExternalLabel* label) {
|
| + ASSERT(!in_delay_slot_);
|
| + LoadImmediate(T9, label->address());
|
| + jalr(T9);
|
| +}
|
| +
|
| +
|
| +void Assembler::BranchLink(const ExternalLabel* label, Patchability patchable) {
|
| + ASSERT(!in_delay_slot_);
|
| + const int32_t offset = ObjectPool::element_offset(
|
| + object_pool_wrapper_.FindExternalLabel(label, patchable));
|
| + LoadWordFromPoolOffset(T9, offset - kHeapObjectTag);
|
| + jalr(T9);
|
| + if (patchable == kPatchable) {
|
| + delay_slot_available_ = false; // CodePatcher expects a nop.
|
| + }
|
| }
|
|
|
|
|
| void Assembler::BranchLink(const StubEntry& stub_entry,
|
| Patchability patchable) {
|
| - const ExternalLabel label(stub_entry.EntryPoint());
|
| - BranchLink(&label, patchable);
|
| + BranchLink(&stub_entry.label(), patchable);
|
| }
|
|
|
|
|
| void Assembler::BranchLinkPatchable(const StubEntry& stub_entry) {
|
| - const ExternalLabel label(stub_entry.EntryPoint());
|
| - BranchLink(&label, kPatchable);
|
| + BranchLink(&stub_entry.label(), kPatchable);
|
| }
|
|
|
|
|
| @@ -1153,7 +1171,7 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
|
| ASSERT(!in_delay_slot_);
|
| const intptr_t kPushedRegistersSize =
|
| kDartVolatileCpuRegCount * kWordSize +
|
| - 2 * kWordSize + // FP and RA.
|
| + 3 * kWordSize + // PP, FP and RA.
|
| kDartVolatileFpuRegCount * kWordSize;
|
|
|
| SetPrologueOffset();
|
| @@ -1174,18 +1192,21 @@ void Assembler::EnterCallRuntimeFrame(intptr_t frame_space) {
|
| for (int i = kDartFirstVolatileFpuReg; i <= kDartLastVolatileFpuReg; i++) {
|
| // These go above the volatile CPU registers.
|
| const int slot =
|
| - (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 2;
|
| + (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 3;
|
| FRegister reg = static_cast<FRegister>(i);
|
| swc1(reg, Address(SP, slot * kWordSize));
|
| }
|
| for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
|
| // + 2 because FP goes in slot 0.
|
| - const int slot = (i - kDartFirstVolatileCpuReg) + 2;
|
| + const int slot = (i - kDartFirstVolatileCpuReg) + 3;
|
| Register reg = static_cast<Register>(i);
|
| sw(reg, Address(SP, slot * kWordSize));
|
| }
|
| - sw(RA, Address(SP, 1 * kWordSize));
|
| - sw(FP, Address(SP, 0 * kWordSize));
|
| + sw(RA, Address(SP, 2 * kWordSize));
|
| + sw(FP, Address(SP, 1 * kWordSize));
|
| + sw(PP, Address(SP, 0 * kWordSize));
|
| + LoadPoolPointer();
|
| +
|
| mov(FP, SP);
|
|
|
| ReserveAlignedFrameSpace(frame_space);
|
| @@ -1196,7 +1217,7 @@ void Assembler::LeaveCallRuntimeFrame() {
|
| ASSERT(!in_delay_slot_);
|
| const intptr_t kPushedRegistersSize =
|
| kDartVolatileCpuRegCount * kWordSize +
|
| - 2 * kWordSize + // FP and RA.
|
| + 3 * kWordSize + // FP and RA.
|
| kDartVolatileFpuRegCount * kWordSize;
|
|
|
| Comment("LeaveCallRuntimeFrame");
|
| @@ -1207,18 +1228,19 @@ void Assembler::LeaveCallRuntimeFrame() {
|
| mov(SP, FP);
|
|
|
| // Restore volatile CPU and FPU registers from the stack.
|
| - lw(FP, Address(SP, 0 * kWordSize));
|
| - lw(RA, Address(SP, 1 * kWordSize));
|
| + lw(PP, Address(SP, 0 * kWordSize));
|
| + lw(FP, Address(SP, 1 * kWordSize));
|
| + lw(RA, Address(SP, 2 * kWordSize));
|
| for (int i = kDartFirstVolatileCpuReg; i <= kDartLastVolatileCpuReg; i++) {
|
| // + 2 because FP goes in slot 0.
|
| - const int slot = (i - kDartFirstVolatileCpuReg) + 2;
|
| + const int slot = (i - kDartFirstVolatileCpuReg) + 3;
|
| Register reg = static_cast<Register>(i);
|
| lw(reg, Address(SP, slot * kWordSize));
|
| }
|
| for (int i = kDartFirstVolatileFpuReg; i <= kDartLastVolatileFpuReg; i++) {
|
| // These go above the volatile CPU registers.
|
| const int slot =
|
| - (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 2;
|
| + (i - kDartFirstVolatileFpuReg) + kDartVolatileCpuRegCount + 3;
|
| FRegister reg = static_cast<FRegister>(i);
|
| lwc1(reg, Address(SP, slot * kWordSize));
|
| }
|
|
|