| 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 |