diff options
Diffstat (limited to 'deps/v8/src/compiler/x87/code-generator-x87.cc')
-rw-r--r-- | deps/v8/src/compiler/x87/code-generator-x87.cc | 129 |
1 files changed, 67 insertions, 62 deletions
diff --git a/deps/v8/src/compiler/x87/code-generator-x87.cc b/deps/v8/src/compiler/x87/code-generator-x87.cc index 1335d3f568..d39fda6761 100644 --- a/deps/v8/src/compiler/x87/code-generator-x87.cc +++ b/deps/v8/src/compiler/x87/code-generator-x87.cc @@ -7,8 +7,10 @@ #include "src/compiler/code-generator-impl.h" #include "src/compiler/gap-resolver.h" #include "src/compiler/node-matchers.h" +#include "src/compiler/osr.h" #include "src/scopes.h" #include "src/x87/assembler-x87.h" +#include "src/x87/frames-x87.h" #include "src/x87/macro-assembler-x87.h" namespace v8 { @@ -38,15 +40,12 @@ class X87OperandConverter : public InstructionOperandConverter { if (op->IsRegister()) { DCHECK(extra == 0); return Operand(ToRegister(op)); - } else if (op->IsDoubleRegister()) { - DCHECK(extra == 0); - UNIMPLEMENTED(); } DCHECK(op->IsStackSlot() || op->IsDoubleStackSlot()); - // The linkage computes where all spill slots are located. - FrameOffset offset = linkage()->GetFrameOffset( - AllocatedOperand::cast(op)->index(), frame(), extra); - return Operand(offset.from_stack_pointer() ? esp : ebp, offset.offset()); + FrameOffset offset = + linkage()->GetFrameOffset(AllocatedOperand::cast(op)->index(), frame()); + return Operand(offset.from_stack_pointer() ? esp : ebp, + offset.offset() + extra); } Operand HighOperand(InstructionOperand* op) { @@ -338,7 +337,8 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { __ jmp(code, RelocInfo::CODE_TARGET); } else { Register reg = i.InputRegister(0); - __ jmp(Operand(reg, Code::kHeaderSize - kHeapObjectTag)); + __ add(reg, Immediate(Code::kHeaderSize - kHeapObjectTag)); + __ jmp(reg); } break; } @@ -1105,7 +1105,29 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { break; } case kX87Push: - if (HasImmediateInput(instr, 0)) { + if (instr->InputAt(0)->IsDoubleRegister()) { + auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); + if (allocated.machine_type() == kRepFloat32) { + __ sub(esp, Immediate(kDoubleSize)); + __ fst_s(Operand(esp, 0)); + } else { + DCHECK(allocated.machine_type() == kRepFloat64); + __ sub(esp, Immediate(kDoubleSize)); + __ fst_d(Operand(esp, 0)); + } + } else if (instr->InputAt(0)->IsDoubleStackSlot()) { + auto allocated = AllocatedOperand::cast(*instr->InputAt(0)); + if (allocated.machine_type() == kRepFloat32) { + __ sub(esp, Immediate(kDoubleSize)); + __ fld_s(i.InputOperand(0)); + __ fstp_s(MemOperand(esp, 0)); + } else { + DCHECK(allocated.machine_type() == kRepFloat64); + __ sub(esp, Immediate(kDoubleSize)); + __ fld_d(i.InputOperand(0)); + __ fstp_d(MemOperand(esp, 0)); + } + } else if (HasImmediateInput(instr, 0)) { __ push(i.InputImmediate(0)); } else { __ push(i.InputOperand(0)); @@ -1509,34 +1531,22 @@ void CodeGenerator::AssembleDeoptimizerCall( void CodeGenerator::AssemblePrologue() { CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); - int stack_slots = frame()->GetSpillSlotCount(); if (descriptor->kind() == CallDescriptor::kCallAddress) { // Assemble a prologue similar the to cdecl calling convention. __ push(ebp); __ mov(ebp, esp); - const RegList saves = descriptor->CalleeSavedRegisters(); - if (saves != 0) { // Save callee-saved registers. - int register_save_area_size = 0; - for (int i = Register::kNumRegisters - 1; i >= 0; i--) { - if (!((1 << i) & saves)) continue; - __ push(Register::from_code(i)); - register_save_area_size += kPointerSize; - } - frame()->SetRegisterSaveAreaSize(register_save_area_size); - } } else if (descriptor->IsJSFunctionCall()) { // TODO(turbofan): this prologue is redundant with OSR, but needed for // code aging. CompilationInfo* info = this->info(); __ Prologue(info->IsCodePreAgingActive()); - frame()->SetRegisterSaveAreaSize( - StandardFrameConstants::kFixedFrameSizeFromFp); } else if (needs_frame_) { __ StubPrologue(); - frame()->SetRegisterSaveAreaSize( - StandardFrameConstants::kFixedFrameSizeFromFp); + } else { + frame()->SetElidedFrameSizeInSlots(kPCOnStackSize / kPointerSize); } + int stack_shrink_slots = frame()->GetSpillSlotCount(); if (info()->is_osr()) { // TurboFan OSR-compiled functions cannot be entered directly. __ Abort(kShouldNotDirectlyEnterOsrFunction); @@ -1549,13 +1559,23 @@ void CodeGenerator::AssemblePrologue() { osr_pc_offset_ = __ pc_offset(); // TODO(titzer): cannot address target function == local #-1 __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); - DCHECK(stack_slots >= frame()->GetOsrStackSlotCount()); - stack_slots -= frame()->GetOsrStackSlotCount(); + stack_shrink_slots -= OsrHelper(info()).UnoptimizedFrameSlots(); + } + + const RegList saves = descriptor->CalleeSavedRegisters(); + if (stack_shrink_slots > 0) { + __ sub(esp, Immediate(stack_shrink_slots * kPointerSize)); } - if (stack_slots > 0) { - // Allocate the stack slots used by this frame. - __ sub(esp, Immediate(stack_slots * kPointerSize)); + if (saves != 0) { // Save callee-saved registers. + DCHECK(!info()->is_osr()); + int pushed = 0; + for (int i = Register::kNumRegisters - 1; i >= 0; i--) { + if (!((1 << i) & saves)) continue; + __ push(Register::from_code(i)); + ++pushed; + } + frame()->AllocateSavedCalleeRegisterSlots(pushed); } // Initailize FPU state. @@ -1566,50 +1586,35 @@ void CodeGenerator::AssemblePrologue() { void CodeGenerator::AssembleReturn() { CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); - int stack_slots = frame()->GetSpillSlotCount(); - if (descriptor->kind() == CallDescriptor::kCallAddress) { - const RegList saves = descriptor->CalleeSavedRegisters(); - if (frame()->GetRegisterSaveAreaSize() > 0) { - // Remove this frame's spill slots first. - if (stack_slots > 0) { - __ add(esp, Immediate(stack_slots * kPointerSize)); - } - // Restore registers. - if (saves != 0) { - for (int i = 0; i < Register::kNumRegisters; i++) { - if (!((1 << i) & saves)) continue; - __ pop(Register::from_code(i)); - } - } - __ pop(ebp); // Pop caller's frame pointer. - __ ret(0); - } else { - // No saved registers. - __ mov(esp, ebp); // Move stack pointer back to frame pointer. - __ pop(ebp); // Pop caller's frame pointer. - __ ret(0); + + int pop_count = static_cast<int>(descriptor->StackParameterCount()); + const RegList saves = descriptor->CalleeSavedRegisters(); + // Restore registers. + if (saves != 0) { + for (int i = 0; i < Register::kNumRegisters; i++) { + if (!((1 << i) & saves)) continue; + __ pop(Register::from_code(i)); } + } + + if (descriptor->kind() == CallDescriptor::kCallAddress) { + __ mov(esp, ebp); // Move stack pointer back to frame pointer. + __ pop(ebp); // Pop caller's frame pointer. } else if (descriptor->IsJSFunctionCall() || needs_frame_) { // Canonicalize JSFunction return sites for now. if (return_label_.is_bound()) { __ jmp(&return_label_); + return; } else { __ bind(&return_label_); __ mov(esp, ebp); // Move stack pointer back to frame pointer. __ pop(ebp); // Pop caller's frame pointer. - int pop_count = descriptor->IsJSFunctionCall() - ? static_cast<int>(descriptor->JSParameterCount()) - : (info()->IsStub() - ? info()->code_stub()->GetStackParameterCount() - : 0); - if (pop_count == 0) { - __ ret(0); - } else { - __ Ret(pop_count * kPointerSize, ebx); - } } - } else { + } + if (pop_count == 0) { __ ret(0); + } else { + __ Ret(pop_count * kPointerSize, ebx); } } |