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