OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 | 95 |
96 void MacroAssembler::StoreRoot(Register source, | 96 void MacroAssembler::StoreRoot(Register source, |
97 Heap::RootListIndex index, | 97 Heap::RootListIndex index, |
98 Condition cond, | 98 Condition cond, |
99 Register src1, const Operand& src2) { | 99 Register src1, const Operand& src2) { |
100 DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); | 100 DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); |
101 Branch(2, NegateCondition(cond), src1, src2); | 101 Branch(2, NegateCondition(cond), src1, src2); |
102 sd(source, MemOperand(s6, index << kPointerSizeLog2)); | 102 sd(source, MemOperand(s6, index << kPointerSizeLog2)); |
103 } | 103 } |
104 | 104 |
| 105 void MacroAssembler::PushCommonFrame(Register marker_reg) { |
| 106 if (marker_reg.is_valid()) { |
| 107 Push(ra, fp, marker_reg); |
| 108 Daddu(fp, sp, Operand(kPointerSize)); |
| 109 } else { |
| 110 Push(ra, fp); |
| 111 mov(fp, sp); |
| 112 } |
| 113 } |
| 114 |
| 115 void MacroAssembler::PopCommonFrame(Register marker_reg) { |
| 116 if (marker_reg.is_valid()) { |
| 117 Pop(ra, fp, marker_reg); |
| 118 } else { |
| 119 Pop(ra, fp); |
| 120 } |
| 121 } |
| 122 |
| 123 void MacroAssembler::PushStandardFrame(Register function_reg) { |
| 124 int offset = -StandardFrameConstants::kContextOffset; |
| 125 if (function_reg.is_valid()) { |
| 126 Push(ra, fp, cp, function_reg); |
| 127 offset += kPointerSize; |
| 128 } else { |
| 129 Push(ra, fp, cp); |
| 130 } |
| 131 Daddu(fp, sp, Operand(offset)); |
| 132 } |
105 | 133 |
106 // Push and pop all registers that can hold pointers. | 134 // Push and pop all registers that can hold pointers. |
107 void MacroAssembler::PushSafepointRegisters() { | 135 void MacroAssembler::PushSafepointRegisters() { |
108 // Safepoints expect a block of kNumSafepointRegisters values on the | 136 // Safepoints expect a block of kNumSafepointRegisters values on the |
109 // stack, so adjust the stack for unsaved registers. | 137 // stack, so adjust the stack for unsaved registers. |
110 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; | 138 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; |
111 DCHECK(num_unsaved >= 0); | 139 DCHECK(num_unsaved >= 0); |
112 if (num_unsaved > 0) { | 140 if (num_unsaved > 0) { |
113 Dsubu(sp, sp, Operand(num_unsaved * kPointerSize)); | 141 Dsubu(sp, sp, Operand(num_unsaved * kPointerSize)); |
114 } | 142 } |
(...skipping 5437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5552 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); | 5580 CheckMap(map, scratch, Heap::kMetaMapRootIndex, &fail, DO_SMI_CHECK); |
5553 Branch(&ok); | 5581 Branch(&ok); |
5554 bind(&fail); | 5582 bind(&fail); |
5555 Abort(kGlobalFunctionsMustHaveInitialMap); | 5583 Abort(kGlobalFunctionsMustHaveInitialMap); |
5556 bind(&ok); | 5584 bind(&ok); |
5557 } | 5585 } |
5558 } | 5586 } |
5559 | 5587 |
5560 | 5588 |
5561 void MacroAssembler::StubPrologue() { | 5589 void MacroAssembler::StubPrologue() { |
5562 Push(ra, fp, cp); | 5590 li(at, Operand(Smi::FromInt(StackFrame::STUB))); |
5563 Push(Smi::FromInt(StackFrame::STUB)); | 5591 PushCommonFrame(at); |
5564 // Adjust FP to point to saved FP. | |
5565 Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
5566 } | 5592 } |
5567 | 5593 |
5568 | 5594 |
5569 void MacroAssembler::Prologue(bool code_pre_aging) { | 5595 void MacroAssembler::Prologue(bool code_pre_aging) { |
5570 PredictableCodeSizeScope predictible_code_size_scope( | 5596 PredictableCodeSizeScope predictible_code_size_scope( |
5571 this, kNoCodeAgeSequenceLength); | 5597 this, kNoCodeAgeSequenceLength); |
5572 // The following three instructions must remain together and unmodified | 5598 // The following three instructions must remain together and unmodified |
5573 // for code aging to work properly. | 5599 // for code aging to work properly. |
5574 if (code_pre_aging) { | 5600 if (code_pre_aging) { |
5575 // Pre-age the code. | 5601 // Pre-age the code. |
5576 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); | 5602 Code* stub = Code::GetPreAgedCodeAgeStub(isolate()); |
5577 nop(Assembler::CODE_AGE_MARKER_NOP); | 5603 nop(Assembler::CODE_AGE_MARKER_NOP); |
5578 // Load the stub address to t9 and call it, | 5604 // Load the stub address to t9 and call it, |
5579 // GetCodeAgeAndParity() extracts the stub address from this instruction. | 5605 // GetCodeAgeAndParity() extracts the stub address from this instruction. |
5580 li(t9, | 5606 li(t9, |
5581 Operand(reinterpret_cast<uint64_t>(stub->instruction_start())), | 5607 Operand(reinterpret_cast<uint64_t>(stub->instruction_start())), |
5582 ADDRESS_LOAD); | 5608 ADDRESS_LOAD); |
5583 nop(); // Prevent jalr to jal optimization. | 5609 nop(); // Prevent jalr to jal optimization. |
5584 jalr(t9, a0); | 5610 jalr(t9, a0); |
5585 nop(); // Branch delay slot nop. | 5611 nop(); // Branch delay slot nop. |
5586 nop(); // Pad the empty space. | 5612 nop(); // Pad the empty space. |
5587 } else { | 5613 } else { |
5588 Push(ra, fp, cp, a1); | 5614 PushStandardFrame(a1); |
5589 nop(Assembler::CODE_AGE_SEQUENCE_NOP); | 5615 nop(Assembler::CODE_AGE_SEQUENCE_NOP); |
5590 nop(Assembler::CODE_AGE_SEQUENCE_NOP); | 5616 nop(Assembler::CODE_AGE_SEQUENCE_NOP); |
5591 nop(Assembler::CODE_AGE_SEQUENCE_NOP); | 5617 nop(Assembler::CODE_AGE_SEQUENCE_NOP); |
5592 // Adjust fp to point to caller's fp. | |
5593 Daddu(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
5594 } | 5618 } |
5595 } | 5619 } |
5596 | 5620 |
5597 | |
5598 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { | 5621 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { |
5599 ld(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 5622 ld(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
5600 ld(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); | 5623 ld(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); |
5601 ld(vector, | 5624 ld(vector, |
5602 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); | 5625 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); |
5603 } | 5626 } |
5604 | 5627 |
5605 | 5628 |
5606 void MacroAssembler::EnterFrame(StackFrame::Type type, | 5629 void MacroAssembler::EnterFrame(StackFrame::Type type, |
5607 bool load_constant_pool_pointer_reg) { | 5630 bool load_constant_pool_pointer_reg) { |
5608 // Out-of-line constant pool not implemented on mips64. | 5631 // Out-of-line constant pool not implemented on mips64. |
5609 UNREACHABLE(); | 5632 UNREACHABLE(); |
5610 } | 5633 } |
5611 | 5634 |
5612 | 5635 |
5613 void MacroAssembler::EnterFrame(StackFrame::Type type) { | 5636 void MacroAssembler::EnterFrame(StackFrame::Type type) { |
5614 daddiu(sp, sp, -5 * kPointerSize); | 5637 int stack_offset, fp_offset; |
5615 li(t8, Operand(Smi::FromInt(type))); | 5638 if (type == StackFrame::INTERNAL) { |
5616 li(t9, Operand(CodeObject()), CONSTANT_SIZE); | 5639 stack_offset = -4 * kPointerSize; |
5617 sd(ra, MemOperand(sp, 4 * kPointerSize)); | 5640 fp_offset = 2 * kPointerSize; |
5618 sd(fp, MemOperand(sp, 3 * kPointerSize)); | 5641 } else { |
5619 sd(cp, MemOperand(sp, 2 * kPointerSize)); | 5642 stack_offset = -3 * kPointerSize; |
5620 sd(t8, MemOperand(sp, 1 * kPointerSize)); | 5643 fp_offset = 1 * kPointerSize; |
5621 sd(t9, MemOperand(sp, 0 * kPointerSize)); | 5644 } |
| 5645 daddiu(sp, sp, stack_offset); |
| 5646 stack_offset = -stack_offset - kPointerSize; |
| 5647 sd(ra, MemOperand(sp, stack_offset)); |
| 5648 stack_offset -= kPointerSize; |
| 5649 sd(fp, MemOperand(sp, stack_offset)); |
| 5650 stack_offset -= kPointerSize; |
| 5651 li(t9, Operand(Smi::FromInt(type))); |
| 5652 sd(t9, MemOperand(sp, stack_offset)); |
| 5653 if (type == StackFrame::INTERNAL) { |
| 5654 DCHECK_EQ(stack_offset, kPointerSize); |
| 5655 li(t9, Operand(CodeObject())); |
| 5656 sd(t9, MemOperand(sp, 0)); |
| 5657 } else { |
| 5658 DCHECK_EQ(stack_offset, 0); |
| 5659 } |
5622 // Adjust FP to point to saved FP. | 5660 // Adjust FP to point to saved FP. |
5623 Daddu(fp, sp, | 5661 Daddu(fp, sp, Operand(fp_offset)); |
5624 Operand(StandardFrameConstants::kFixedFrameSizeFromFp + kPointerSize)); | |
5625 } | 5662 } |
5626 | 5663 |
5627 | 5664 |
5628 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 5665 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
5629 mov(sp, fp); | 5666 daddiu(sp, fp, 2 * kPointerSize); |
5630 ld(fp, MemOperand(sp, 0 * kPointerSize)); | 5667 ld(ra, MemOperand(fp, 1 * kPointerSize)); |
5631 ld(ra, MemOperand(sp, 1 * kPointerSize)); | 5668 ld(fp, MemOperand(fp, 0 * kPointerSize)); |
5632 daddiu(sp, sp, 2 * kPointerSize); | |
5633 } | 5669 } |
5634 | 5670 |
5635 | 5671 void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) { |
5636 void MacroAssembler::EnterExitFrame(bool save_doubles, | |
5637 int stack_space) { | |
5638 // Set up the frame structure on the stack. | 5672 // Set up the frame structure on the stack. |
5639 STATIC_ASSERT(2 * kPointerSize == ExitFrameConstants::kCallerSPDisplacement); | 5673 STATIC_ASSERT(2 * kPointerSize == ExitFrameConstants::kCallerSPDisplacement); |
5640 STATIC_ASSERT(1 * kPointerSize == ExitFrameConstants::kCallerPCOffset); | 5674 STATIC_ASSERT(1 * kPointerSize == ExitFrameConstants::kCallerPCOffset); |
5641 STATIC_ASSERT(0 * kPointerSize == ExitFrameConstants::kCallerFPOffset); | 5675 STATIC_ASSERT(0 * kPointerSize == ExitFrameConstants::kCallerFPOffset); |
5642 | 5676 |
5643 // This is how the stack will look: | 5677 // This is how the stack will look: |
5644 // fp + 2 (==kCallerSPDisplacement) - old stack's end | 5678 // fp + 2 (==kCallerSPDisplacement) - old stack's end |
5645 // [fp + 1 (==kCallerPCOffset)] - saved old ra | 5679 // [fp + 1 (==kCallerPCOffset)] - saved old ra |
5646 // [fp + 0 (==kCallerFPOffset)] - saved old fp | 5680 // [fp + 0 (==kCallerFPOffset)] - saved old fp |
5647 // [fp - 1 (==kSPOffset)] - sp of the called function | 5681 // [fp - 1 StackFrame::EXIT Smi |
5648 // [fp - 2 (==kCodeOffset)] - CodeObject | 5682 // [fp - 2 (==kSPOffset)] - sp of the called function |
| 5683 // [fp - 3 (==kCodeOffset)] - CodeObject |
5649 // fp - (2 + stack_space + alignment) == sp == [fp - kSPOffset] - top of the | 5684 // fp - (2 + stack_space + alignment) == sp == [fp - kSPOffset] - top of the |
5650 // new stack (will contain saved ra) | 5685 // new stack (will contain saved ra) |
5651 | 5686 |
5652 // Save registers. | 5687 // Save registers and reserve room for saved entry sp and code object. |
5653 daddiu(sp, sp, -4 * kPointerSize); | 5688 daddiu(sp, sp, -2 * kPointerSize - ExitFrameConstants::kFixedFrameSizeFromFp); |
5654 sd(ra, MemOperand(sp, 3 * kPointerSize)); | 5689 sd(ra, MemOperand(sp, 4 * kPointerSize)); |
5655 sd(fp, MemOperand(sp, 2 * kPointerSize)); | 5690 sd(fp, MemOperand(sp, 3 * kPointerSize)); |
5656 daddiu(fp, sp, 2 * kPointerSize); // Set up new frame pointer. | 5691 li(at, Operand(Smi::FromInt(StackFrame::EXIT))); |
| 5692 sd(at, MemOperand(sp, 2 * kPointerSize)); |
| 5693 // Set up new frame pointer. |
| 5694 daddiu(fp, sp, ExitFrameConstants::kFixedFrameSizeFromFp); |
5657 | 5695 |
5658 if (emit_debug_code()) { | 5696 if (emit_debug_code()) { |
5659 sd(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 5697 sd(zero_reg, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
5660 } | 5698 } |
5661 | 5699 |
5662 // Accessed from ExitFrame::code_slot. | 5700 // Accessed from ExitFrame::code_slot. |
5663 li(t8, Operand(CodeObject()), CONSTANT_SIZE); | 5701 li(t8, Operand(CodeObject()), CONSTANT_SIZE); |
5664 sd(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 5702 sd(t8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
5665 | 5703 |
5666 // Save the frame pointer and the context in top. | 5704 // Save the frame pointer and the context in top. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5699 } | 5737 } |
5700 | 5738 |
5701 | 5739 |
5702 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 5740 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
5703 bool restore_context, bool do_return, | 5741 bool restore_context, bool do_return, |
5704 bool argument_count_is_length) { | 5742 bool argument_count_is_length) { |
5705 // Optionally restore all double registers. | 5743 // Optionally restore all double registers. |
5706 if (save_doubles) { | 5744 if (save_doubles) { |
5707 // Remember: we only need to restore every 2nd double FPU value. | 5745 // Remember: we only need to restore every 2nd double FPU value. |
5708 int kNumOfSavedRegisters = FPURegister::kMaxNumRegisters / 2; | 5746 int kNumOfSavedRegisters = FPURegister::kMaxNumRegisters / 2; |
5709 Dsubu(t8, fp, Operand(ExitFrameConstants::kFrameSize + | 5747 Dsubu(t8, fp, Operand(ExitFrameConstants::kFixedFrameSizeFromFp + |
5710 kNumOfSavedRegisters * kDoubleSize)); | 5748 kNumOfSavedRegisters * kDoubleSize)); |
5711 for (int i = 0; i < kNumOfSavedRegisters; i++) { | 5749 for (int i = 0; i < kNumOfSavedRegisters; i++) { |
5712 FPURegister reg = FPURegister::from_code(2 * i); | 5750 FPURegister reg = FPURegister::from_code(2 * i); |
5713 ldc1(reg, MemOperand(t8, i * kDoubleSize)); | 5751 ldc1(reg, MemOperand(t8, i * kDoubleSize)); |
5714 } | 5752 } |
5715 } | 5753 } |
5716 | 5754 |
5717 // Clear top frame. | 5755 // Clear top frame. |
5718 li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 5756 li(t8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
5719 sd(zero_reg, MemOperand(t8)); | 5757 sd(zero_reg, MemOperand(t8)); |
5720 | 5758 |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6656 if (mag.shift > 0) sra(result, result, mag.shift); | 6694 if (mag.shift > 0) sra(result, result, mag.shift); |
6657 srl(at, dividend, 31); | 6695 srl(at, dividend, 31); |
6658 Addu(result, result, Operand(at)); | 6696 Addu(result, result, Operand(at)); |
6659 } | 6697 } |
6660 | 6698 |
6661 | 6699 |
6662 } // namespace internal | 6700 } // namespace internal |
6663 } // namespace v8 | 6701 } // namespace v8 |
6664 | 6702 |
6665 #endif // V8_TARGET_ARCH_MIPS64 | 6703 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |