Index: src/compiler/x87/code-generator-x87.cc |
diff --git a/src/compiler/x87/code-generator-x87.cc b/src/compiler/x87/code-generator-x87.cc |
index 937d735874c519cb46af4986025d7a719b7c6671..0ac411e431ecc002bed904c2b637f6cde2eea909 100644 |
--- a/src/compiler/x87/code-generator-x87.cc |
+++ b/src/compiler/x87/code-generator-x87.cc |
@@ -195,6 +195,9 @@ class OutOfLineLoadFloat final : public OutOfLineCode { |
void Generate() final { |
DCHECK(result_.code() == 0); |
USE(result_); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ push(Immediate(0xffffffff)); |
__ push(Immediate(0x7fffffff)); |
@@ -364,6 +367,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
switch (ArchOpcodeField::decode(instr->opcode())) { |
case kArchCallCodeObject: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ __ fstp(0); |
EnsureSpaceForLazyDeopt(); |
if (HasImmediateInput(instr, 0)) { |
Handle<Code> code = Handle<Code>::cast(i.InputHeapObject(0)); |
@@ -391,6 +398,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kArchTailCallCodeObject: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ __ fstp(0); |
int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
AssembleDeconstructActivationRecord(stack_param_delta); |
if (HasImmediateInput(instr, 0)) { |
@@ -412,6 +423,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
__ Assert(equal, kWrongFunctionContext); |
} |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ __ fstp(0); |
__ call(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
RecordCallPosition(instr); |
bool double_result = |
@@ -437,6 +452,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ cmp(esi, FieldOperand(func, JSFunction::kContextOffset)); |
__ Assert(equal, kWrongFunctionContext); |
} |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ __ fstp(0); |
int stack_param_delta = i.InputInt32(instr->InputCount() - 1); |
AssembleDeconstructActivationRecord(stack_param_delta); |
__ jmp(FieldOperand(func, JSFunction::kCodeEntryOffset)); |
@@ -446,6 +465,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kArchLazyBailout: { |
EnsureSpaceForLazyDeopt(); |
RecordCallPosition(instr); |
+ // Lazy Bailout entry, need to re-initialize FPU state. |
+ __ fninit(); |
+ __ fld1(); |
break; |
} |
case kArchPrepareCallCFunction: { |
@@ -459,6 +481,10 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
AssemblePrepareTailCall(i.InputInt32(instr->InputCount() - 1)); |
break; |
case kArchCallCFunction: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ __ fstp(0); |
int const num_parameters = MiscField::decode(instr->opcode()); |
if (HasImmediateInput(instr, 0)) { |
ExternalReference ref = i.InputExternalReference(0); |
@@ -467,6 +493,19 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
Register func = i.InputRegister(0); |
__ CallCFunction(func, num_parameters); |
} |
+ bool double_result = |
+ instr->HasOutput() && instr->Output()->IsDoubleRegister(); |
+ if (double_result) { |
+ __ lea(esp, Operand(esp, -kDoubleSize)); |
+ __ fstp_d(Operand(esp, 0)); |
+ } |
+ __ fninit(); |
+ if (double_result) { |
+ __ fld_d(Operand(esp, 0)); |
+ __ lea(esp, Operand(esp, kDoubleSize)); |
+ } else { |
+ __ fld1(); |
+ } |
frame_access_state()->SetFrameAccessToDefault(); |
frame_access_state()->ClearSPDelta(); |
break; |
@@ -689,6 +728,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Add: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_s(MemOperand(esp, 0)); |
@@ -701,6 +743,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Sub: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_s(MemOperand(esp, kFloatSize)); |
@@ -713,6 +758,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Mul: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_s(MemOperand(esp, kFloatSize)); |
@@ -725,6 +773,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Div: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_s(MemOperand(esp, kFloatSize)); |
@@ -739,6 +790,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Float32Max: { |
Label check_nan_left, check_zero, return_left, return_right; |
Condition condition = below; |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(MemOperand(esp, kFloatSize)); |
__ fld_s(MemOperand(esp, 0)); |
@@ -773,6 +827,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Float32Min: { |
Label check_nan_left, check_zero, return_left, return_right; |
Condition condition = above; |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(MemOperand(esp, kFloatSize)); |
__ fld_s(MemOperand(esp, 0)); |
@@ -818,6 +875,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Sqrt: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(MemOperand(esp, 0)); |
__ fsqrt(); |
@@ -825,6 +885,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float32Abs: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(MemOperand(esp, 0)); |
__ fabs(); |
@@ -841,6 +904,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
InstructionOperand* input = instr->InputAt(0); |
USE(input); |
DCHECK(input->IsDoubleStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(i.InputOperand(0)); |
} |
@@ -849,6 +915,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Add: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_d(MemOperand(esp, 0)); |
@@ -861,6 +930,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Sub: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_d(MemOperand(esp, kDoubleSize)); |
@@ -872,6 +944,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Mul: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_d(MemOperand(esp, kDoubleSize)); |
@@ -883,6 +958,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Div: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_d(MemOperand(esp, kDoubleSize)); |
@@ -895,6 +973,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
} |
case kX87Float64Mod: { |
FrameScope frame_scope(&masm_, StackFrame::MANUAL); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ mov(eax, esp); |
__ PrepareCallCFunction(4, eax); |
__ fstp(0); |
@@ -910,6 +991,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Float64Max: { |
Label check_zero, return_left, return_right; |
Condition condition = below; |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(MemOperand(esp, kDoubleSize)); |
__ fld_d(MemOperand(esp, 0)); |
@@ -939,6 +1023,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Float64Min: { |
Label check_zero, return_left, return_right; |
Condition condition = above; |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(MemOperand(esp, kDoubleSize)); |
__ fld_d(MemOperand(esp, 0)); |
@@ -966,6 +1053,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Abs: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(MemOperand(esp, 0)); |
__ fabs(); |
@@ -975,6 +1065,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Int32ToFloat32: { |
InstructionOperand* input = instr->InputAt(0); |
DCHECK(input->IsRegister() || input->IsStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
if (input->IsRegister()) { |
Register input_reg = i.InputRegister(0); |
@@ -989,6 +1082,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
case kX87Int32ToFloat64: { |
InstructionOperand* input = instr->InputAt(0); |
DCHECK(input->IsRegister() || input->IsStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
if (input->IsRegister()) { |
Register input_reg = i.InputRegister(0); |
@@ -1009,12 +1105,18 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ add(esp, Immediate(kDoubleSize)); |
} else { |
DCHECK(input->IsDoubleStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(i.InputOperand(0)); |
} |
break; |
} |
case kX87Uint32ToFloat64: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ LoadUint32NoSSE2(i.InputRegister(0)); |
break; |
@@ -1048,6 +1150,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
__ add(esp, Immediate(kDoubleSize)); |
} else { |
DCHECK(input->IsDoubleStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(i.InputOperand(0)); |
__ sub(esp, Immediate(kDoubleSize)); |
@@ -1118,6 +1223,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87Float64Sqrt: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ X87SetFPUCW(0x027F); |
__ fstp(0); |
__ fld_d(MemOperand(esp, 0)); |
@@ -1136,6 +1244,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
InstructionOperand* input = instr->InputAt(0); |
USE(input); |
DCHECK(input->IsDoubleStackSlot()); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(i.InputOperand(0)); |
} |
@@ -1200,6 +1311,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
X87Register output = i.OutputDoubleRegister(); |
USE(output); |
DCHECK(output.code() == 0); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_d(i.MemoryOperand()); |
} else { |
@@ -1214,6 +1328,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
X87Register output = i.OutputDoubleRegister(); |
USE(output); |
DCHECK(output.code() == 0); |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
__ fld_s(i.MemoryOperand()); |
} else { |
@@ -1229,6 +1346,9 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) { |
break; |
} |
case kX87BitcastIF: { |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
__ fstp(0); |
if (instr->InputAt(0)->IsRegister()) { |
__ lea(esp, Operand(esp, -kFloatSize)); |
@@ -1754,6 +1874,21 @@ void CodeGenerator::AssemblePrologue() { |
void CodeGenerator::AssembleReturn() { |
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor(); |
+ // Clear the FPU stack only if there is no return value in the stack. |
+ if (FLAG_debug_code && FLAG_enable_slow_asserts) { |
+ __ VerifyX87StackDepth(1); |
+ } |
+ bool clear_stack = true; |
+ for (int i = 0; i < descriptor->ReturnCount(); i++) { |
+ MachineRepresentation rep = descriptor->GetReturnType(i).representation(); |
+ LinkageLocation loc = descriptor->GetReturnLocation(i); |
+ if (IsFloatingPoint(rep) && loc == LinkageLocation::ForRegister(0)) { |
+ clear_stack = false; |
+ break; |
+ } |
+ } |
+ if (clear_stack) __ fstp(0); |
+ |
int pop_count = static_cast<int>(descriptor->StackParameterCount()); |
const RegList saves = descriptor->CalleeSavedRegisters(); |
// Restore registers. |