diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index 2766b658fd..f8872d7187 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -2272,6 +2272,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { if (instr->op() != Token::MOD) { X87PrepareBinaryOp(left, right, result); } + // Set the precision control to double-precision. + __ X87SetFPUCW(0x027F); switch (instr->op()) { case Token::ADD: __ fadd_i(1); @@ -2306,12 +2308,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { break; } - // Only always explicitly storing to memory to force the round-down for double - // arithmetic. - __ lea(esp, Operand(esp, -kDoubleSize)); - __ fstp_d(Operand(esp, 0)); - __ fld_d(Operand(esp, 0)); - __ lea(esp, Operand(esp, kDoubleSize)); + // Restore the default value of control word. + __ X87SetFPUCW(0x037F); } diff --git a/src/x87/macro-assembler-x87.cc b/src/x87/macro-assembler-x87.cc index ff5db7bdbd..3f522fcb1a 100644 --- a/src/x87/macro-assembler-x87.cc +++ b/src/x87/macro-assembler-x87.cc @@ -767,6 +767,13 @@ void MacroAssembler::X87SetRC(int rc) { } +void MacroAssembler::X87SetFPUCW(int cw) { + push(Immediate(cw)); + fldcw(MemOperand(esp, 0)); + add(esp, Immediate(kPointerSize)); +} + + void MacroAssembler::AssertNumber(Register object) { if (emit_debug_code()) { Label ok; diff --git a/src/x87/macro-assembler-x87.h b/src/x87/macro-assembler-x87.h index 07964562bb..ad308a4958 100644 --- a/src/x87/macro-assembler-x87.h +++ b/src/x87/macro-assembler-x87.h @@ -425,6 +425,7 @@ class MacroAssembler: public Assembler { void FXamSign(); void X87CheckIA(); void X87SetRC(int rc); + void X87SetFPUCW(int cw); void ClampUint8(Register reg); void ClampTOSToUint8(Register result_reg);