Ignore:
Timestamp:
Nov 4, 2009, 3:59:14 PM (16 years ago)
Author:
[email protected]
Message:

https://bugs.webkit.org/show_bug.cgi?id=31104
Refactor x86-specific behaviour out of the JIT.

Patch by Gavin Barraclough <[email protected]> on 2009-11-04
Reviewed by Oliver Hunt.

  • Add explicit double branch conditions for ordered and unordered comparisons (presently the brehaviour is a mix).
  • Refactor double to int conversion out into the MacroAssembler.
  • Remove broken double to int conversion for !JSVALUE32_64 builds - this code was broken and slowing us down, fixing it showed it not to be an improvement.
  • Remove exclusion of double to int conversion from (1 % X) cases in JSVALUE32_64 builds - if this was of benefit this is no longer the case; simplify.
  • assembler/MacroAssemblerARM.h:

(JSC::MacroAssemblerARM::):

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::):
(JSC::MacroAssemblerX86Common::convertInt32ToDouble):
(JSC::MacroAssemblerX86Common::branchDouble):
(JSC::MacroAssemblerX86Common::branchConvertDoubleToInt32):

  • jit/JITArithmetic.cpp:

(JSC::JIT::emitBinaryDoubleOp):
(JSC::JIT::emit_op_div):
(JSC::JIT::emitSlow_op_jnless):
(JSC::JIT::emitSlow_op_jnlesseq):

  • jit/JITOpcodes.cpp:

(JSC::JIT::emit_op_jfalse):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r48782 r50531  
    3737
    3838class MacroAssemblerX86Common : public AbstractMacroAssembler<X86Assembler> {
     39    static const int DoubleConditionBitInvert = 0x10;
     40    static const int DoubleConditionBitSpecial = 0x20;
     41    static const int DoubleConditionBits = DoubleConditionBitInvert | DoubleConditionBitSpecial;
     42
    3943public:
    4044
     
    5761
    5862    enum DoubleCondition {
    59         DoubleEqual = X86Assembler::ConditionE,
     63        // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
     64        DoubleEqual = X86Assembler::ConditionE | DoubleConditionBitSpecial,
    6065        DoubleNotEqual = X86Assembler::ConditionNE,
    6166        DoubleGreaterThan = X86Assembler::ConditionA,
    6267        DoubleGreaterThanOrEqual = X86Assembler::ConditionAE,
    63         DoubleLessThan = X86Assembler::ConditionB,
    64         DoubleLessThanOrEqual = X86Assembler::ConditionBE,
     68        DoubleLessThan = X86Assembler::ConditionA | DoubleConditionBitInvert,
     69        DoubleLessThanOrEqual = X86Assembler::ConditionAE | DoubleConditionBitInvert,
     70        // If either operand is NaN, these conditions always evaluate to true.
     71        DoubleEqualOrUnordered = X86Assembler::ConditionE,
     72        DoubleNotEqualOrUnordered = X86Assembler::ConditionNE | DoubleConditionBitSpecial,
     73        DoubleGreaterThanOrUnordered = X86Assembler::ConditionB | DoubleConditionBitInvert,
     74        DoubleGreaterThanOrEqualOrUnordered = X86Assembler::ConditionBE | DoubleConditionBitInvert,
     75        DoubleLessThanOrUnordered = X86Assembler::ConditionB,
     76        DoubleLessThanOrEqualOrUnordered = X86Assembler::ConditionBE,
    6577    };
     78    COMPILE_ASSERT(
     79        !((X86Assembler::ConditionE | X86Assembler::ConditionNE | X86Assembler::ConditionA | X86Assembler::ConditionAE | X86Assembler::ConditionB | X86Assembler::ConditionBE) & DoubleConditionBits),
     80        DoubleConditionBits_should_not_interfere_with_X86Assembler_Condition_codes);
    6681
    6782    static const RegisterID stackPointerRegister = X86Registers::esp;
     
    417432    void convertInt32ToDouble(Address src, FPRegisterID dest)
    418433    {
     434        ASSERT(isSSE2Present());
    419435        m_assembler.cvtsi2sd_mr(src.offset, src.base, dest);
    420436    }
     
    423439    {
    424440        ASSERT(isSSE2Present());
    425         m_assembler.ucomisd_rr(right, left);
    426         return Jump(m_assembler.jCC(x86Condition(cond)));
    427     }
    428 
    429     Jump branchDouble(DoubleCondition cond, FPRegisterID left, Address right)
    430     {
    431         m_assembler.ucomisd_mr(right.offset, right.base, left);
    432         return Jump(m_assembler.jCC(x86Condition(cond)));
     441
     442        if (cond & DoubleConditionBitInvert)
     443            m_assembler.ucomisd_rr(left, right);
     444        else
     445            m_assembler.ucomisd_rr(right, left);
     446
     447        if (cond == DoubleEqual) {
     448            Jump isUnordered(m_assembler.jp());
     449            Jump result = Jump(m_assembler.je());
     450            isUnordered.link(this);
     451            return result;
     452        } else if (cond == DoubleNotEqualOrUnordered) {
     453            Jump isUnordered(m_assembler.jp());
     454            Jump isEqual(m_assembler.je());
     455            isUnordered.link(this);
     456            Jump result = jump();
     457            isEqual.link(this);
     458            return result;
     459        }
     460
     461        ASSERT(!(cond & DoubleConditionBitSpecial));
     462        return Jump(m_assembler.jCC(static_cast<X86Assembler::Condition>(cond & ~DoubleConditionBits)));
    433463    }
    434464
     
    442472        m_assembler.cvttsd2si_rr(src, dest);
    443473        return branch32(Equal, dest, Imm32(0x80000000));
     474    }
     475
     476    // Convert 'src' to an integer, and places the resulting 'dest'.
     477    // If the result is not representable as a 32 bit value, branch.
     478    // May also branch for some values that are representable in 32 bits
     479    // (specifically, in this case, 0).
     480    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
     481    {
     482        ASSERT(isSSE2Present());
     483        m_assembler.cvttsd2si_rr(src, dest);
     484
     485        // If the result is zero, it might have been -0.0, and the double comparison won't catch this!
     486        failureCases.append(branchTest32(Zero, dest));
     487
     488        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
     489        convertInt32ToDouble(dest, fpTemp);
     490        m_assembler.ucomisd_rr(fpTemp, src);
     491        failureCases.append(m_assembler.jp());
     492        failureCases.append(m_assembler.jne());
    444493    }
    445494
     
    886935protected:
    887936    X86Assembler::Condition x86Condition(Condition cond)
    888     {
    889         return static_cast<X86Assembler::Condition>(cond);
    890     }
    891 
    892     X86Assembler::Condition x86Condition(DoubleCondition cond)
    893937    {
    894938        return static_cast<X86Assembler::Condition>(cond);
Note: See TracChangeset for help on using the changeset viewer.