Ignore:
Timestamp:
Nov 4, 2009, 9:02:09 PM (16 years ago)
Author:
[email protected]
Message:

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

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

The ARMv7 JIT is currently using ARMv7Assembler::ConditionEQ to branch
for DoubleEqualOrUnordered, however this is incorrect – ConditionEQ won't
branch on unordered operands. Similarly, DoubleLessThanOrUnordered &
DoubleLessThanOrEqualOrUnordered use ARMv7Assembler::ConditionLO &
ARMv7Assembler::ConditionLS, whereas they should be using
ARMv7Assembler::ConditionLT & ARMv7Assembler::ConditionLE.

Fix these, and fill out the missing DoubleConditions.

  • assembler/MacroAssemblerARMv7.h:

(JSC::MacroAssemblerARMv7::):
(JSC::MacroAssemblerARMv7::branchDouble):

File:
1 edited

Legend:

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

    r50531 r50541  
    9494        NonZero = ARMv7Assembler::ConditionNE
    9595    };
    96 
    9796    enum DoubleCondition {
    98         DoubleEqualOrUnordered = ARMv7Assembler::ConditionEQ,
     97        // These conditions will only evaluate to true if the comparison is ordered - i.e. neither operand is NaN.
     98        DoubleEqual = ARMv7Assembler::ConditionEQ,
     99        DoubleNotEqual = ARMv7Assembler::ConditionVC, // Not the right flag! check for this & handle differently.
    99100        DoubleGreaterThan = ARMv7Assembler::ConditionGT,
    100101        DoubleGreaterThanOrEqual = ARMv7Assembler::ConditionGE,
    101         DoubleLessThanOrUnordered = ARMv7Assembler::ConditionLO,
    102         DoubleLessThanOrEqualOrUnordered = ARMv7Assembler::ConditionLS,
     102        DoubleLessThan = ARMv7Assembler::ConditionLO,
     103        DoubleLessThanOrEqual = ARMv7Assembler::ConditionLS,
     104        // If either operand is NaN, these conditions always evaluate to true.
     105        DoubleEqualOrUnordered = ARMv7Assembler::ConditionVS, // Not the right flag! check for this & handle differently.
     106        DoubleNotEqualOrUnordered = ARMv7Assembler::ConditionNE,
     107        DoubleGreaterThanOrUnordered = ARMv7Assembler::ConditionHI,
     108        DoubleGreaterThanOrEqualOrUnordered = ARMv7Assembler::ConditionHS,
     109        DoubleLessThanOrUnordered = ARMv7Assembler::ConditionLT,
     110        DoubleLessThanOrEqualOrUnordered = ARMv7Assembler::ConditionLE,
    103111    };
    104112
     
    532540        m_assembler.vcmp_F64(left, right);
    533541        m_assembler.vmrs_APSR_nzcv_FPSCR();
     542
     543        if (cond == DoubleNotEqual) {
     544            // ConditionNE jumps if NotEqual *or* unordered - force the unordered cases not to jump.
     545            Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
     546            Jump result = makeBranch(ARMv7Assembler::ConditionNE);
     547            unordered.link(this);
     548            return result;
     549        }
     550        if (cond == DoubleEqualOrUnordered) {
     551            Jump unordered = makeBranch(ARMv7Assembler::ConditionVS);
     552            Jump notEqual = makeBranch(ARMv7Assembler::ConditionNE);
     553            unordered.link(this);
     554            // We get here if either unordered, or equal.
     555            Jump result = makeJump();
     556            notEqual.link(this);
     557            return result;
     558        }
    534559        return makeBranch(cond);
    535560    }
Note: See TracChangeset for help on using the changeset viewer.