diff --git a/src/ia32/assembler-ia32.cc b/src/ia32/assembler-ia32.cc index bc28710f93..6af548acc8 100644 --- a/src/ia32/assembler-ia32.cc +++ b/src/ia32/assembler-ia32.cc @@ -1850,6 +1850,14 @@ void Assembler::fucompp() { } +void Assembler::fucomip() { + EnsureSpace ensure_space(this); + last_pc_ = pc_; + EMIT(0xDF); + EMIT(0xE9); +} + + void Assembler::fcompp() { EnsureSpace ensure_space(this); last_pc_ = pc_; diff --git a/src/ia32/assembler-ia32.h b/src/ia32/assembler-ia32.h index 4719f2dcfc..e31cd3f2fd 100644 --- a/src/ia32/assembler-ia32.h +++ b/src/ia32/assembler-ia32.h @@ -702,6 +702,7 @@ class Assembler : public Malloced { void ftst(); void fucomp(int i); void fucompp(); + void fucomip(); void fcompp(); void fnstsw_ax(); void fwait(); diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index e7b96485c7..5ed3b20b3d 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -6500,11 +6500,7 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { __ j(not_equal, &true_result); __ fldz(); __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); - __ fucompp(); - __ push(eax); - __ fnstsw_ax(); - __ sahf(); - __ pop(eax); + __ FCmp(); __ j(zero, &false_result); // Fall through to |true_result|. @@ -6908,18 +6904,14 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { // Check if right operand is int32. __ fist_s(Operand(esp, 0 * kPointerSize)); __ fild_s(Operand(esp, 0 * kPointerSize)); - __ fucompp(); - __ fnstsw_ax(); - __ sahf(); + __ FCmp(); __ j(not_zero, &operand_conversion_failure); __ j(parity_even, &operand_conversion_failure); // Check if left operand is int32. __ fist_s(Operand(esp, 1 * kPointerSize)); __ fild_s(Operand(esp, 1 * kPointerSize)); - __ fucompp(); - __ fnstsw_ax(); - __ sahf(); + __ FCmp(); __ j(not_zero, &operand_conversion_failure); __ j(parity_even, &operand_conversion_failure); } diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index af21c74ed4..08c4c0c51b 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -319,11 +319,17 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) { void MacroAssembler::FCmp() { - fucompp(); - push(eax); - fnstsw_ax(); - sahf(); - pop(eax); + if (CpuFeatures::IsSupported(CpuFeatures::CMOV)) { + fucomip(); + ffree(0); + fincstp(); + } else { + fucompp(); + push(eax); + fnstsw_ax(); + sahf(); + pop(eax); + } } diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc index eaa3004407..bcd4d87535 100644 --- a/src/x64/assembler-x64.cc +++ b/src/x64/assembler-x64.cc @@ -2229,6 +2229,14 @@ void Assembler::fucompp() { } +void Assembler::fucomip() { + EnsureSpace ensure_space(this); + last_pc_ = pc_; + emit(0xDF); + emit(0xE9); +} + + void Assembler::fcompp() { EnsureSpace ensure_space(this); last_pc_ = pc_; diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index a24f267398..265f839a4a 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -1049,6 +1049,8 @@ class Assembler : public Malloced { void ftst(); void fucomp(int i); void fucompp(); + void fucomip(); + void fcompp(); void fnstsw_ax(); void fwait(); diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 527e9c065c..001c65b62b 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -6206,16 +6206,11 @@ void ToBooleanStub::Generate(MacroAssembler* masm) { // These three cases set C3 when compared to zero in the FPU. __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); __ j(not_equal, &true_result); - // TODO(x64): Don't use fp stack, use MMX registers? __ fldz(); // Load zero onto fp stack // Load heap-number double value onto fp stack __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); - __ fucompp(); // Compare and pop both values. - __ movq(kScratchRegister, rax); - __ fnstsw_ax(); // Store fp status word in ax, no checking for exceptions. - __ testl(rax, Immediate(0x4000)); // Test FP condition flag C3, bit 16. - __ movq(rax, kScratchRegister); - __ j(not_zero, &false_result); + __ FCmp(); + __ j(zero, &false_result); // Fall through to |true_result|. // Return 1/0 for true/false in rax. @@ -7512,31 +7507,16 @@ void GenericBinaryOpStub::Generate(MacroAssembler* masm) { // Check if right operand is int32. __ fist_s(Operand(rsp, 0 * kPointerSize)); __ fild_s(Operand(rsp, 0 * kPointerSize)); - __ fucompp(); - __ fnstsw_ax(); - if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { - __ sahf(); - __ j(not_zero, &operand_conversion_failure); - __ j(parity_even, &operand_conversion_failure); - } else { - __ and_(rax, Immediate(0x4400)); - __ cmpl(rax, Immediate(0x4000)); - __ j(not_zero, &operand_conversion_failure); - } + __ FCmp(); + __ j(not_zero, &operand_conversion_failure); + __ j(parity_even, &operand_conversion_failure); + // Check if left operand is int32. __ fist_s(Operand(rsp, 1 * kPointerSize)); __ fild_s(Operand(rsp, 1 * kPointerSize)); - __ fucompp(); - __ fnstsw_ax(); - if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { - __ sahf(); - __ j(not_zero, &operand_conversion_failure); - __ j(parity_even, &operand_conversion_failure); - } else { - __ and_(rax, Immediate(0x4400)); - __ cmpl(rax, Immediate(0x4000)); - __ j(not_zero, &operand_conversion_failure); - } + __ FCmp(); + __ j(not_zero, &operand_conversion_failure); + __ j(parity_even, &operand_conversion_failure); } // Get int32 operands and perform bitop. diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 25c9dcf7ac..61a8319fd2 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -1421,18 +1421,9 @@ void MacroAssembler::Ret() { void MacroAssembler::FCmp() { - fucompp(); - push(rax); - fnstsw_ax(); - if (CpuFeatures::IsSupported(CpuFeatures::SAHF)) { - sahf(); - } else { - shrl(rax, Immediate(8)); - and_(rax, Immediate(0xFF)); - push(rax); - popfq(); - } - pop(rax); + fucomip(); + ffree(0); + fincstp(); }