Ignore:
Timestamp:
Nov 5, 2009, 11:28:56 PM (16 years ago)
Author:
Csaba Osztrogonác
Message:

https://bugs.webkit.org/show_bug.cgi?id=31159
Fix branchDouble behaviour on ARM THUMB2 JIT.

Patch by Zoltan Herczeg <[email protected]> on 2009-11-05
Reviewed by Gavin Barraclough.

The x86 branchDouble behaviour is reworked, and all JIT
ports should follow the x86 port. See bug 31104 and 31151

This patch contains a fix for the traditional ARM port

  • assembler/ARMAssembler.h:

(JSC::ARMAssembler::):
(JSC::ARMAssembler::fmrs_r):
(JSC::ARMAssembler::ftosid_r):

  • assembler/MacroAssemblerARM.h:

(JSC::MacroAssemblerARM::):
(JSC::MacroAssemblerARM::branchDouble):
(JSC::MacroAssemblerARM::branchConvertDoubleToInt32):

File:
1 edited

Legend:

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

    r50531 r50593  
    3939
    4040class MacroAssemblerARM : public AbstractMacroAssembler<ARMAssembler> {
     41    static const int DoubleConditionMask = 0x0f;
     42    static const int DoubleConditionBitSpecial = 0x10;
     43    COMPILE_ASSERT(!(DoubleConditionBitSpecial & DoubleConditionMask), DoubleConditionBitSpecial_should_not_interfere_with_ARMAssembler_Condition_codes);
    4144public:
    4245    enum Condition {
     
    5861
    5962    enum DoubleCondition {
    60         DoubleEqualOrUnordered = ARMAssembler::EQ,
     63        // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
     64        DoubleEqual = ARMAssembler::EQ,
     65        DoubleNotEqual = ARMAssembler::NE | DoubleConditionBitSpecial,
    6166        DoubleGreaterThan = ARMAssembler::GT,
    6267        DoubleGreaterThanOrEqual = ARMAssembler::GE,
     68        DoubleLessThan = ARMAssembler::CC,
     69        DoubleLessThanOrEqual = ARMAssembler::LS,
     70        // If either operand is NaN, these conditions always evaluate to true.
     71        DoubleEqualOrUnordered = ARMAssembler::EQ | DoubleConditionBitSpecial,
     72        DoubleNotEqualOrUnordered = ARMAssembler::NE,
     73        DoubleGreaterThanOrUnordered = ARMAssembler::HI,
     74        DoubleGreaterThanOrEqualOrUnordered = ARMAssembler::CS,
    6375        DoubleLessThanOrUnordered = ARMAssembler::LT,
    6476        DoubleLessThanOrEqualOrUnordered = ARMAssembler::LE,
     
    715727        m_assembler.fcmpd_r(left, right);
    716728        m_assembler.fmstat();
    717         return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond)));
     729        if (cond & DoubleConditionBitSpecial)
     730            m_assembler.cmp_r(ARMRegisters::S0, ARMRegisters::S0, ARMAssembler::VS);
     731        return Jump(m_assembler.jmp(static_cast<ARMAssembler::Condition>(cond & ~DoubleConditionMask)));
    718732    }
    719733
     
    728742        ASSERT_NOT_REACHED();
    729743        return jump();
     744    }
     745
     746    // Convert 'src' to an integer, and places the resulting 'dest'.
     747    // If the result is not representable as a 32 bit value, branch.
     748    // May also branch for some values that are representable in 32 bits
     749    // (specifically, in this case, 0).
     750    void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
     751    {
     752        m_assembler.ftosid_r(src, ARMRegisters::SD0);
     753        m_assembler.fmrs_r(ARMRegisters::SD0, dest);
     754
     755        // Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
     756        m_assembler.fsitod_r(ARMRegisters::SD0, ARMRegisters::SD0);
     757        failureCases.append(branchDouble(DoubleNotEqual, src, ARMRegisters::SD0));
     758
     759        // If the result is zero, it might have been -0.0, and 0.0 equals to -0.0
     760        failureCases.append(branchTest32(Zero, dest));
    730761    }
    731762
Note: See TracChangeset for help on using the changeset viewer.