Index: src/x64/deoptimizer-x64.cc |
=================================================================== |
--- src/x64/deoptimizer-x64.cc (revision 15486) |
+++ src/x64/deoptimizer-x64.cc (working copy) |
@@ -84,8 +84,13 @@ |
// There is room enough to write a long call instruction because we pad |
// LLazyBailout instructions with nops if necessary. |
CodePatcher patcher(call_address, Assembler::kCallInstructionLength); |
+#ifndef V8_TARGET_ARCH_X32 |
patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY), |
RelocInfo::NONE64); |
+#else |
+ patcher.masm()->Call(GetDeoptimizationEntry(isolate, i, LAZY), |
+ RelocInfo::NONE32); |
+#endif |
ASSERT(prev_call_address == NULL || |
call_address >= prev_call_address + patch_size()); |
ASSERT(call_address + patch_size() <= code->instruction_end()); |
@@ -116,7 +121,11 @@ |
static const byte kJnsInstruction = 0x79; |
+#ifndef V8_TARGET_ARCH_X32 |
static const byte kJnsOffset = 0x1d; |
+#else |
+static const byte kJnsOffset = 0x14; |
+#endif |
static const byte kCallInstruction = 0xe8; |
static const byte kNopByteOne = 0x66; |
static const byte kNopByteTwo = 0x90; |
@@ -304,6 +313,15 @@ |
for (int i = StandardFrameConstants::kCallerPCOffset; |
ok && i >= StandardFrameConstants::kMarkerOffset; |
i -= kPointerSize) { |
+#ifdef V8_TARGET_ARCH_X32 |
+ if (i == StandardFrameConstants::kCallerPCOffset || |
+ i == StandardFrameConstants::kCallerFPOffset) { |
+ // Set the high-32 bit of PC and FP to 0. |
+ output_[0]->SetFrameSlot(output_offset, 0); |
+ input_offset -= kPointerSize; |
+ output_offset -= kPointerSize; |
+ } |
+#endif |
intptr_t input_value = input_->GetFrameSlot(input_offset); |
if (FLAG_trace_osr) { |
const char* name = "UNKNOWN"; |
@@ -331,6 +349,11 @@ |
output_[0]->SetFrameSlot(output_offset, input_->GetFrameSlot(input_offset)); |
input_offset -= kPointerSize; |
output_offset -= kPointerSize; |
+#ifdef V8_TARGET_ARCH_X32 |
+ if (i == StandardFrameConstants::kCallerPCOffset) { |
+ i -= kHWRegSize - kPointerSize; |
+ } |
+#endif |
} |
// Translate the rest of the frame. |
@@ -383,7 +406,11 @@ |
// Fill the frame content from the actual data on the frame. |
for (unsigned i = 0; i < input_->GetFrameSize(); i += kPointerSize) { |
+#ifndef V8_TARGET_ARCH_X32 |
input_->SetFrameSlot(i, Memory::uint64_at(tos + i)); |
+#else |
+ input_->SetFrameSlot(i, Memory::uint32_at(tos + i)); |
+#endif |
} |
} |
@@ -416,6 +443,8 @@ |
#define __ masm()-> |
+#define __k __ |
+#define __q __ |
void Deoptimizer::EntryGenerator::Generate() { |
GeneratePrologue(); |
@@ -437,11 +466,16 @@ |
// to restore all later. |
for (int i = 0; i < kNumberOfRegisters; i++) { |
Register r = Register::from_code(i); |
- __ push(r); |
+ __k push(r); |
} |
+#ifndef V8_TARGET_ARCH_X32 |
const int kSavedRegistersAreaSize = kNumberOfRegisters * kPointerSize + |
kDoubleRegsSize; |
+#else |
+ const int kSavedRegistersAreaSize = kNumberOfRegisters * kHWRegSize + |
+ kDoubleRegsSize; |
+#endif |
// We use this to keep the value of the fifth argument temporarily. |
// Unfortunately we can't store it directly in r8 (used for passing |
@@ -455,11 +489,15 @@ |
// and compute the fp-to-sp delta in register arg5. |
if (type() == EAGER || type() == SOFT) { |
__ Set(arg_reg_4, 0); |
- __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize)); |
+ __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize)); |
} else { |
+#ifndef V8_TARGET_ARCH_X32 |
__ movq(arg_reg_4, |
Operand(rsp, kSavedRegistersAreaSize + 1 * kPointerSize)); |
- __ lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize)); |
+#else |
+ __ movl(arg_reg_4, Operand(rsp, kSavedRegistersAreaSize + 1 * kHWRegSize)); |
+#endif |
+ __q lea(arg5, Operand(rsp, kSavedRegistersAreaSize + 2 * kPointerSize)); |
} |
__ subq(arg5, rbp); |
@@ -493,21 +531,26 @@ |
// Fill in the input registers. |
for (int i = kNumberOfRegisters -1; i >= 0; i--) { |
int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
+#ifndef V8_TARGET_ARCH_X32 |
__ pop(Operand(rbx, offset)); |
+#else |
+ __ pop(kScratchRegister); |
+ __ movl(Operand(rbx, offset), kScratchRegister); |
+#endif |
} |
// Fill in the double input registers. |
int double_regs_offset = FrameDescription::double_registers_offset(); |
for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { |
int dst_offset = i * kDoubleSize + double_regs_offset; |
- __ pop(Operand(rbx, dst_offset)); |
+ __k pop(Operand(rbx, dst_offset)); |
} |
// Remove the bailout id from the stack. |
if (type() == EAGER || type() == SOFT) { |
- __ addq(rsp, Immediate(kPointerSize)); |
+ __q addq(rsp, Immediate(kPointerSize)); |
} else { |
- __ addq(rsp, Immediate(2 * kPointerSize)); |
+ __q addq(rsp, Immediate(2 * kPointerSize)); |
} |
// Compute a pointer to the unwinding limit in register rcx; that is |
@@ -530,7 +573,7 @@ |
__ j(not_equal, &pop_loop); |
// Compute the output frame in the deoptimizer. |
- __ push(rax); |
+ __k push(rax); |
__ PrepareCallCFunction(2); |
__ movq(arg_reg_1, rax); |
__ LoadAddress(arg_reg_2, ExternalReference::isolate_address(isolate())); |
@@ -539,7 +582,7 @@ |
__ CallCFunction( |
ExternalReference::compute_output_frames_function(isolate()), 2); |
} |
- __ pop(rax); |
+ __k pop(rax); |
// Replace the current frame with the output frames. |
Label outer_push_loop, inner_push_loop, |
@@ -574,15 +617,29 @@ |
// Push state, pc, and continuation from the last output frame. |
if (type() != OSR) { |
+#ifdef V8_TARGET_ARCH_X32 |
+ __ Push(Immediate(0)); |
+#endif |
__ push(Operand(rbx, FrameDescription::state_offset())); |
} |
+#ifdef V8_TARGET_ARCH_X32 |
+ __ Push(Immediate(0)); |
+#endif |
__ push(Operand(rbx, FrameDescription::pc_offset())); |
+#ifdef V8_TARGET_ARCH_X32 |
+ __ Push(Immediate(0)); |
+#endif |
__ push(Operand(rbx, FrameDescription::continuation_offset())); |
// Push the registers from the last output frame. |
for (int i = 0; i < kNumberOfRegisters; i++) { |
int offset = (i * kPointerSize) + FrameDescription::registers_offset(); |
+#ifndef V8_TARGET_ARCH_X32 |
__ push(Operand(rbx, offset)); |
+#else |
+ __ movl(kScratchRegister, Operand(rbx, offset)); |
+ __ push(kScratchRegister); |
+#endif |
} |
// Restore the registers from the stack. |
@@ -594,7 +651,7 @@ |
ASSERT(i > 0); |
r = Register::from_code(i - 1); |
} |
- __ pop(r); |
+ __k pop(r); |
} |
// Set up the roots register. |
@@ -612,13 +669,15 @@ |
for (int i = 0; i < count(); i++) { |
int start = masm()->pc_offset(); |
USE(start); |
- __ push_imm32(i); |
+ __k push_imm32(i); |
__ jmp(&done); |
ASSERT(masm()->pc_offset() - start == table_entry_size_); |
} |
__ bind(&done); |
} |
+#undef __k |
+#undef __k |
#undef __ |