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_IA32 | 5 #if V8_TARGET_ARCH_IA32 |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/base/division-by-constant.h" | 8 #include "src/base/division-by-constant.h" |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 1112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 | 1123 |
1124 void MacroAssembler::LeaveFrame(StackFrame::Type type) { | 1124 void MacroAssembler::LeaveFrame(StackFrame::Type type) { |
1125 if (emit_debug_code()) { | 1125 if (emit_debug_code()) { |
1126 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), | 1126 cmp(Operand(ebp, CommonFrameConstants::kContextOrFrameTypeOffset), |
1127 Immediate(Smi::FromInt(type))); | 1127 Immediate(Smi::FromInt(type))); |
1128 Check(equal, kStackFrameTypesMustMatch); | 1128 Check(equal, kStackFrameTypesMustMatch); |
1129 } | 1129 } |
1130 leave(); | 1130 leave(); |
1131 } | 1131 } |
1132 | 1132 |
1133 void MacroAssembler::EnterExitFramePrologue(StackFrame::Type frame_type) { | |
1134 DCHECK(frame_type == StackFrame::EXIT || | |
1135 frame_type == StackFrame::BUILTIN_EXIT); | |
1136 | 1133 |
| 1134 void MacroAssembler::EnterExitFramePrologue() { |
1137 // Set up the frame structure on the stack. | 1135 // Set up the frame structure on the stack. |
1138 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 1136 DCHECK_EQ(+2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1139 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 1137 DCHECK_EQ(+1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1140 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 1138 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1141 push(ebp); | 1139 push(ebp); |
1142 mov(ebp, esp); | 1140 mov(ebp, esp); |
1143 | 1141 |
1144 // Reserve room for entry stack pointer and push the code object. | 1142 // Reserve room for entry stack pointer and push the code object. |
1145 push(Immediate(Smi::FromInt(frame_type))); | 1143 push(Immediate(Smi::FromInt(StackFrame::EXIT))); |
1146 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); | 1144 DCHECK_EQ(-2 * kPointerSize, ExitFrameConstants::kSPOffset); |
1147 push(Immediate(0)); // Saved entry sp, patched before call. | 1145 push(Immediate(0)); // Saved entry sp, patched before call. |
1148 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); | 1146 DCHECK_EQ(-3 * kPointerSize, ExitFrameConstants::kCodeOffset); |
1149 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. | 1147 push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. |
1150 | 1148 |
1151 // Save the frame pointer and the context in top. | 1149 // Save the frame pointer and the context in top. |
1152 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); | 1150 ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress, isolate()); |
1153 ExternalReference context_address(Isolate::kContextAddress, isolate()); | 1151 ExternalReference context_address(Isolate::kContextAddress, isolate()); |
1154 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); | 1152 ExternalReference c_function_address(Isolate::kCFunctionAddress, isolate()); |
1155 mov(Operand::StaticVariable(c_entry_fp_address), ebp); | 1153 mov(Operand::StaticVariable(c_entry_fp_address), ebp); |
(...skipping 21 matching lines...) Expand all Loading... |
1177 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); | 1175 const int kFrameAlignment = base::OS::ActivationFrameAlignment(); |
1178 if (kFrameAlignment > 0) { | 1176 if (kFrameAlignment > 0) { |
1179 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); | 1177 DCHECK(base::bits::IsPowerOfTwo32(kFrameAlignment)); |
1180 and_(esp, -kFrameAlignment); | 1178 and_(esp, -kFrameAlignment); |
1181 } | 1179 } |
1182 | 1180 |
1183 // Patch the saved entry sp. | 1181 // Patch the saved entry sp. |
1184 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); | 1182 mov(Operand(ebp, ExitFrameConstants::kSPOffset), esp); |
1185 } | 1183 } |
1186 | 1184 |
1187 void MacroAssembler::EnterExitFrame(int argc, bool save_doubles, | 1185 |
1188 StackFrame::Type frame_type) { | 1186 void MacroAssembler::EnterExitFrame(int argc, bool save_doubles) { |
1189 EnterExitFramePrologue(frame_type); | 1187 EnterExitFramePrologue(); |
1190 | 1188 |
1191 // Set up argc and argv in callee-saved registers. | 1189 // Set up argc and argv in callee-saved registers. |
1192 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; | 1190 int offset = StandardFrameConstants::kCallerSPOffset - kPointerSize; |
1193 mov(edi, eax); | 1191 mov(edi, eax); |
1194 lea(esi, Operand(ebp, eax, times_4, offset)); | 1192 lea(esi, Operand(ebp, eax, times_4, offset)); |
1195 | 1193 |
1196 // Reserve space for argc, argv and isolate. | 1194 // Reserve space for argc, argv and isolate. |
1197 EnterExitFrameEpilogue(argc, save_doubles); | 1195 EnterExitFrameEpilogue(argc, save_doubles); |
1198 } | 1196 } |
1199 | 1197 |
1200 | 1198 |
1201 void MacroAssembler::EnterApiExitFrame(int argc) { | 1199 void MacroAssembler::EnterApiExitFrame(int argc) { |
1202 EnterExitFramePrologue(StackFrame::EXIT); | 1200 EnterExitFramePrologue(); |
1203 EnterExitFrameEpilogue(argc, false); | 1201 EnterExitFrameEpilogue(argc, false); |
1204 } | 1202 } |
1205 | 1203 |
1206 | 1204 |
1207 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { | 1205 void MacroAssembler::LeaveExitFrame(bool save_doubles, bool pop_arguments) { |
1208 // Optionally restore all XMM registers. | 1206 // Optionally restore all XMM registers. |
1209 if (save_doubles) { | 1207 if (save_doubles) { |
1210 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; | 1208 const int offset = -ExitFrameConstants::kFixedFrameSizeFromFp; |
1211 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 1209 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
1212 XMMRegister reg = XMMRegister::from_code(i); | 1210 XMMRegister reg = XMMRegister::from_code(i); |
(...skipping 983 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2196 if (function->nargs >= 0) { | 2194 if (function->nargs >= 0) { |
2197 // TODO(1236192): Most runtime routines don't need the number of | 2195 // TODO(1236192): Most runtime routines don't need the number of |
2198 // arguments passed in because it is constant. At some point we | 2196 // arguments passed in because it is constant. At some point we |
2199 // should remove this need and make the runtime routine entry code | 2197 // should remove this need and make the runtime routine entry code |
2200 // smarter. | 2198 // smarter. |
2201 mov(eax, Immediate(function->nargs)); | 2199 mov(eax, Immediate(function->nargs)); |
2202 } | 2200 } |
2203 JumpToExternalReference(ExternalReference(fid, isolate())); | 2201 JumpToExternalReference(ExternalReference(fid, isolate())); |
2204 } | 2202 } |
2205 | 2203 |
2206 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext, | 2204 |
2207 bool builtin_exit_frame) { | 2205 void MacroAssembler::JumpToExternalReference(const ExternalReference& ext) { |
2208 // Set the entry point and jump to the C entry runtime stub. | 2206 // Set the entry point and jump to the C entry runtime stub. |
2209 mov(ebx, Immediate(ext)); | 2207 mov(ebx, Immediate(ext)); |
2210 CEntryStub ces(isolate(), 1, kDontSaveFPRegs, kArgvOnStack, | 2208 CEntryStub ces(isolate(), 1); |
2211 builtin_exit_frame); | |
2212 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); | 2209 jmp(ces.GetCode(), RelocInfo::CODE_TARGET); |
2213 } | 2210 } |
2214 | 2211 |
2215 void MacroAssembler::PrepareForTailCall( | 2212 void MacroAssembler::PrepareForTailCall( |
2216 const ParameterCount& callee_args_count, Register caller_args_count_reg, | 2213 const ParameterCount& callee_args_count, Register caller_args_count_reg, |
2217 Register scratch0, Register scratch1, ReturnAddressState ra_state, | 2214 Register scratch0, Register scratch1, ReturnAddressState ra_state, |
2218 int number_of_temp_values_after_return_address) { | 2215 int number_of_temp_values_after_return_address) { |
2219 #if DEBUG | 2216 #if DEBUG |
2220 if (callee_args_count.is_reg()) { | 2217 if (callee_args_count.is_reg()) { |
2221 DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, | 2218 DCHECK(!AreAliased(callee_args_count.reg(), caller_args_count_reg, scratch0, |
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3437 mov(eax, dividend); | 3434 mov(eax, dividend); |
3438 shr(eax, 31); | 3435 shr(eax, 31); |
3439 add(edx, eax); | 3436 add(edx, eax); |
3440 } | 3437 } |
3441 | 3438 |
3442 | 3439 |
3443 } // namespace internal | 3440 } // namespace internal |
3444 } // namespace v8 | 3441 } // namespace v8 |
3445 | 3442 |
3446 #endif // V8_TARGET_ARCH_IA32 | 3443 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |