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 #if V8_TARGET_ARCH_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
6 | 6 |
7 #include "src/bootstrapper.h" | 7 #include "src/bootstrapper.h" |
8 #include "src/code-stubs.h" | 8 #include "src/code-stubs.h" |
9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
(...skipping 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1116 __ mov(a2, s1); | 1116 __ mov(a2, s1); |
1117 __ mov(a1, a0); | 1117 __ mov(a1, a0); |
1118 __ mov(a0, sp); | 1118 __ mov(a0, sp); |
1119 } | 1119 } |
1120 | 1120 |
1121 // To let the GC traverse the return address of the exit frames, we need to | 1121 // To let the GC traverse the return address of the exit frames, we need to |
1122 // know where the return address is. The CEntryStub is unmovable, so | 1122 // know where the return address is. The CEntryStub is unmovable, so |
1123 // we can store the address on the stack to be able to find it again and | 1123 // we can store the address on the stack to be able to find it again and |
1124 // we never have to restore it, because it will not change. | 1124 // we never have to restore it, because it will not change. |
1125 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); | 1125 { Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm); |
1126 // This branch-and-link sequence is needed to find the current PC on mips, | 1126 int numInstructionsToJump; |
1127 // saved to the ra register. | |
1128 // Use masm-> here instead of the double-underscore macro since extra | |
1129 // coverage code can interfere with the proper calculation of ra. | |
1130 Label find_ra; | 1127 Label find_ra; |
1131 __ bal(&find_ra); // bal exposes branch delay slot. | |
1132 __ nop(); | |
1133 __ bind(&find_ra); | |
1134 | |
1135 // Adjust the value in ra to point to the correct return location, 2nd | 1128 // Adjust the value in ra to point to the correct return location, 2nd |
1136 // instruction past the real call into C code (the jalr(t9)), and push it. | 1129 // instruction past the real call into C code (the jalr(t9)), and push it. |
1137 // This is the return address of the exit frame. | 1130 // This is the return address of the exit frame. |
1138 const int kNumInstructionsToJump = 5; | 1131 if (kArchVariant >= kMips64r6) { |
1139 __ Daddu(ra, ra, kNumInstructionsToJump * kInt32Size); | 1132 numInstructionsToJump = 4; |
| 1133 __ addiupc(ra, numInstructionsToJump + 1); |
| 1134 } else { |
| 1135 numInstructionsToJump = 5; |
| 1136 // This branch-and-link sequence is needed to find the current PC on mips |
| 1137 // before r6, saved to the ra register. |
| 1138 __ bal(&find_ra); // bal exposes branch delay slot. |
| 1139 __ Daddu(ra, ra, numInstructionsToJump * Instruction::kInstrSize); |
| 1140 } |
| 1141 |
| 1142 __ bind(&find_ra); |
1140 // This spot was reserved in EnterExitFrame. | 1143 // This spot was reserved in EnterExitFrame. |
1141 __ sd(ra, MemOperand(sp, result_stack_size)); | 1144 __ sd(ra, MemOperand(sp, result_stack_size)); |
1142 // Stack space reservation moved to the branch delay slot below. | 1145 // Stack space reservation moved to the branch delay slot below. |
1143 // Stack is still aligned. | 1146 // Stack is still aligned. |
1144 | 1147 |
1145 // Call the C routine. | 1148 // Call the C routine. |
1146 __ mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC. | 1149 __ mov(t9, s2); // Function pointer to t9 to conform to ABI for PIC. |
1147 __ jalr(t9); | 1150 __ jalr(t9); |
1148 // Set up sp in the delay slot. | 1151 // Set up sp in the delay slot. |
1149 __ daddiu(sp, sp, -kCArgsSlotsSize); | 1152 __ daddiu(sp, sp, -kCArgsSlotsSize); |
1150 // Make sure the stored 'ra' points to this position. | 1153 // Make sure the stored 'ra' points to this position. |
1151 DCHECK_EQ(kNumInstructionsToJump, | 1154 DCHECK_EQ(numInstructionsToJump, |
1152 masm->InstructionsGeneratedSince(&find_ra)); | 1155 masm->InstructionsGeneratedSince(&find_ra)); |
1153 } | 1156 } |
1154 if (result_size() > 2) { | 1157 if (result_size() > 2) { |
1155 DCHECK_EQ(3, result_size()); | 1158 DCHECK_EQ(3, result_size()); |
1156 // Read result values stored on stack. | 1159 // Read result values stored on stack. |
1157 __ ld(a0, MemOperand(v0, 2 * kPointerSize)); | 1160 __ ld(a0, MemOperand(v0, 2 * kPointerSize)); |
1158 __ ld(v1, MemOperand(v0, 1 * kPointerSize)); | 1161 __ ld(v1, MemOperand(v0, 1 * kPointerSize)); |
1159 __ ld(v0, MemOperand(v0, 0 * kPointerSize)); | 1162 __ ld(v0, MemOperand(v0, 0 * kPointerSize)); |
1160 } | 1163 } |
1161 // Result returned in v0, v1:v0 or a0:v1:v0 - do not destroy these registers! | 1164 // Result returned in v0, v1:v0 or a0:v1:v0 - do not destroy these registers! |
(...skipping 4515 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5677 return_value_operand, NULL); | 5680 return_value_operand, NULL); |
5678 } | 5681 } |
5679 | 5682 |
5680 | 5683 |
5681 #undef __ | 5684 #undef __ |
5682 | 5685 |
5683 } // namespace internal | 5686 } // namespace internal |
5684 } // namespace v8 | 5687 } // namespace v8 |
5685 | 5688 |
5686 #endif // V8_TARGET_ARCH_MIPS64 | 5689 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |