Changeset 90352 in webkit


Ignore:
Timestamp:
Jul 3, 2011 10:59:03 PM (13 years ago)
Author:
barraclough@apple.com
Message:

https://bugs.webkit.org/show_bug.cgi?id=63879
Reduce code duplication for op_jless, op_jlesseq, op_jnless, op_jnlesseq.

Reviewed by Sam Weinig.

There is a lot of copy & paste code here; we can reduce duplication by making
a shared implementation.

  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::branch32):
(JSC::MacroAssembler::commute):

  • Make these function platform agnostic.
  • assembler/MacroAssemblerX86Common.h:
    • Moved branch32/commute up to MacroAssembler.
  • jit/JIT.h:

(JSC::JIT::emit_op_loop_if_lesseq):
(JSC::JIT::emitSlow_op_loop_if_lesseq):

  • Add an implementation matching that for op_loop_if_less, which just calls op_jless.
  • jit/JITArithmetic.cpp:

(JSC::JIT::emit_op_jless):
(JSC::JIT::emit_op_jlesseq):
(JSC::JIT::emit_op_jnless):
(JSC::JIT::emit_op_jnlesseq):
(JSC::JIT::emitSlow_op_jless):
(JSC::JIT::emitSlow_op_jlesseq):
(JSC::JIT::emitSlow_op_jnless):
(JSC::JIT::emitSlow_op_jnlesseq):

  • Common implmentations of these methods for JSVALUE64 & JSVALUE32_64.

(JSC::JIT::emit_compareAndJump):
(JSC::JIT::emit_compareAndJumpSlow):

  • Internal implmementation of jless etc for JSVALUE64.
  • jit/JITArithmetic32_64.cpp:

(JSC::JIT::emit_compareAndJump):
(JSC::JIT::emit_compareAndJumpSlow):

  • Internal implmementation of jless etc for JSVALUE32_64.
  • jit/JITOpcodes.cpp:
  • jit/JITOpcodes32_64.cpp:
  • jit/JITStubs.cpp:
  • jit/JITStubs.h:
    • Remove old implementation of emit_op_loop_if_lesseq.
Location:
trunk/Source/JavaScriptCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r90349 r90352  
     12011-07-03  Gavin Barraclough  <barraclough@apple.com>
     2
     3        https://bugs.webkit.org/show_bug.cgi?id=63879
     4        Reduce code duplication for op_jless, op_jlesseq, op_jnless, op_jnlesseq.
     5
     6        Reviewed by Sam Weinig.
     7       
     8        There is a lot of copy & paste code here; we can reduce duplication by making
     9        a shared implementation.
     10
     11        * assembler/MacroAssembler.h:
     12        (JSC::MacroAssembler::branch32):
     13        (JSC::MacroAssembler::commute):
     14            - Make these function platform agnostic.
     15        * assembler/MacroAssemblerX86Common.h:
     16            - Moved branch32/commute up to MacroAssembler.
     17        * jit/JIT.h:
     18        (JSC::JIT::emit_op_loop_if_lesseq):
     19        (JSC::JIT::emitSlow_op_loop_if_lesseq):
     20            - Add an implementation matching that for op_loop_if_less, which just calls op_jless.
     21        * jit/JITArithmetic.cpp:
     22        (JSC::JIT::emit_op_jless):
     23        (JSC::JIT::emit_op_jlesseq):
     24        (JSC::JIT::emit_op_jnless):
     25        (JSC::JIT::emit_op_jnlesseq):
     26        (JSC::JIT::emitSlow_op_jless):
     27        (JSC::JIT::emitSlow_op_jlesseq):
     28        (JSC::JIT::emitSlow_op_jnless):
     29        (JSC::JIT::emitSlow_op_jnlesseq):
     30            - Common implmentations of these methods for JSVALUE64 & JSVALUE32_64.
     31        (JSC::JIT::emit_compareAndJump):
     32        (JSC::JIT::emit_compareAndJumpSlow):
     33            - Internal implmementation of jless etc for JSVALUE64.
     34        * jit/JITArithmetic32_64.cpp:
     35        (JSC::JIT::emit_compareAndJump):
     36        (JSC::JIT::emit_compareAndJumpSlow):
     37            - Internal implmementation of jless etc for JSVALUE32_64.
     38        * jit/JITOpcodes.cpp:
     39        * jit/JITOpcodes32_64.cpp:
     40        * jit/JITStubs.cpp:
     41        * jit/JITStubs.h:
     42            - Remove old implementation of emit_op_loop_if_lesseq.
     43
    1442011-07-03  Sheriff Bot  <webkit.review.bot@gmail.com>
    245
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r86699 r90352  
    126126    }
    127127
     128    Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right)
     129    {
     130        return branch32(commute(cond), right, left);
     131    }
     132
    128133    void branch16(RelationalCondition cond, BaseIndex left, RegisterID right, Label target)
    129134    {
     
    141146    }
    142147
     148    // Commute a relational condition, returns a new condition that will produce
     149    // the same results given the same inputs but with their positions exchanged.
     150    static RelationalCondition commute(RelationalCondition condition)
     151    {
     152        switch (condition) {
     153        case Above:
     154            return Below;
     155        case AboveOrEqual:
     156            return BelowOrEqual;
     157        case Below:
     158            return Above;
     159        case BelowOrEqual:
     160            return AboveOrEqual;
     161        case GreaterThan:
     162            return LessThan;
     163        case GreaterThanOrEqual:
     164            return LessThanOrEqual;
     165        case LessThan:
     166            return GreaterThan;
     167        case LessThanOrEqual:
     168            return GreaterThanOrEqual;
     169        default:
     170            break;
     171        }
     172
     173        ASSERT(condition == Equal || condition == NotEqual);
     174        return condition;
     175    }
     176   
    143177
    144178    // Ptr methods
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r90237 r90352  
    845845    }
    846846   
    847     Jump branch32(RelationalCondition cond, TrustedImm32 left, RegisterID right)
    848     {
    849         if (((cond == Equal) || (cond == NotEqual)) && !left.m_value)
    850             m_assembler.testl_rr(right, right);
    851         else
    852             m_assembler.cmpl_ir(left.m_value, right);
    853         return Jump(m_assembler.jCC(x86Condition(commute(cond))));
    854     }
    855    
    856847    Jump branch32(RelationalCondition cond, RegisterID left, Address right)
    857848    {
     
    12021193    }
    12031194
    1204     // Commute a relational condition, returns a new condition that will produce
    1205     // the same results given the same inputs but with their positions exchanged.
    1206     static RelationalCondition commute(RelationalCondition cond)
    1207     {
    1208         // Equality is commutative!
    1209         if (cond == Equal || cond == NotEqual)
    1210             return cond;
    1211 
    1212         // Based on the values of x86 condition codes, remap > with < and >= with <=
    1213         if (cond >= LessThan) {
    1214             ASSERT(cond == LessThan || cond == LessThanOrEqual || cond == GreaterThan || cond == GreaterThanOrEqual);
    1215             return static_cast<RelationalCondition>(X86Assembler::ConditionL + X86Assembler::ConditionG - cond);
    1216         }
    1217 
    1218         // As above, for unsigned conditions.
    1219         ASSERT(cond == Below || cond == BelowOrEqual || cond == Above || cond == AboveOrEqual);
    1220         return static_cast<RelationalCondition>(X86Assembler::ConditionB + X86Assembler::ConditionA - cond);
    1221     }
    1222    
    12231195    void nop()
    12241196    {
  • trunk/Source/JavaScriptCore/jit/JIT.h

    r90060 r90352  
    720720#define END_UNINTERRUPTED_SEQUENCE_FOR_PUT(name, dst) do { endUninterruptedSequence(); } while (false)
    721721#endif
     722
     723        void emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition);
     724        void emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator&);
    722725
    723726        void emit_op_add(Instruction*);
     
    763766        void emit_op_jnless(Instruction*);
    764767        void emit_op_jless(Instruction*);
    765         void emit_op_jlesseq(Instruction*, bool invert = false);
     768        void emit_op_jlesseq(Instruction*);
    766769        void emit_op_jnlesseq(Instruction*);
    767770        void emit_op_jsr(Instruction*);
     
    859862        void emitSlow_op_jnless(Instruction*, Vector<SlowCaseEntry>::iterator&);
    860863        void emitSlow_op_jless(Instruction*, Vector<SlowCaseEntry>::iterator&);
    861         void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&, bool invert = false);
     864        void emitSlow_op_jlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    862865        void emitSlow_op_jnlesseq(Instruction*, Vector<SlowCaseEntry>::iterator&);
    863866        void emitSlow_op_jtrue(Instruction*, Vector<SlowCaseEntry>::iterator&);
     
    10411044    }
    10421045
     1046    inline void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
     1047    {
     1048        emitTimeoutCheck();
     1049        emit_op_jlesseq(currentInstruction);
     1050    }
     1051
     1052    inline void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     1053    {
     1054        emitSlow_op_jlesseq(currentInstruction, iter);
     1055    }
     1056
    10431057} // namespace JSC
    10441058
  • trunk/Source/JavaScriptCore/jit/JITArithmetic.cpp

    r85729 r90352  
    2727
    2828#if ENABLE(JIT)
    29 #if USE(JSVALUE64)
    3029#include "JIT.h"
    3130
     
    4746
    4847namespace JSC {
     48
     49void JIT::emit_op_jless(Instruction* currentInstruction)
     50{
     51    unsigned op1 = currentInstruction[1].u.operand;
     52    unsigned op2 = currentInstruction[2].u.operand;
     53    unsigned target = currentInstruction[3].u.operand;
     54
     55    emit_compareAndJump(op_jless, op1, op2, target, LessThan);
     56}
     57
     58void JIT::emit_op_jlesseq(Instruction* currentInstruction)
     59{
     60    unsigned op1 = currentInstruction[1].u.operand;
     61    unsigned op2 = currentInstruction[2].u.operand;
     62    unsigned target = currentInstruction[3].u.operand;
     63
     64    emit_compareAndJump(op_jlesseq, op1, op2, target, LessThanOrEqual);
     65}
     66
     67void JIT::emit_op_jnless(Instruction* currentInstruction)
     68{
     69    unsigned op1 = currentInstruction[1].u.operand;
     70    unsigned op2 = currentInstruction[2].u.operand;
     71    unsigned target = currentInstruction[3].u.operand;
     72
     73    emit_compareAndJump(op_jnless, op1, op2, target, GreaterThanOrEqual);
     74}
     75
     76void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
     77{
     78    unsigned op1 = currentInstruction[1].u.operand;
     79    unsigned op2 = currentInstruction[2].u.operand;
     80    unsigned target = currentInstruction[3].u.operand;
     81
     82    emit_compareAndJump(op_jnlesseq, op1, op2, target, GreaterThan);
     83}
     84
     85void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     86{
     87    unsigned op1 = currentInstruction[1].u.operand;
     88    unsigned op2 = currentInstruction[2].u.operand;
     89    unsigned target = currentInstruction[3].u.operand;
     90
     91    emit_compareAndJumpSlow(op1, op2, target, DoubleLessThan, cti_op_jless, false, iter);
     92}
     93
     94void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     95{
     96    unsigned op1 = currentInstruction[1].u.operand;
     97    unsigned op2 = currentInstruction[2].u.operand;
     98    unsigned target = currentInstruction[3].u.operand;
     99
     100    emit_compareAndJumpSlow(op1, op2, target, DoubleLessThanOrEqual, cti_op_jlesseq, false, iter);
     101}
     102
     103void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     104{
     105    unsigned op1 = currentInstruction[1].u.operand;
     106    unsigned op2 = currentInstruction[2].u.operand;
     107    unsigned target = currentInstruction[3].u.operand;
     108
     109    emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrEqualOrUnordered, cti_op_jless, true, iter);
     110}
     111
     112void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     113{
     114    unsigned op1 = currentInstruction[1].u.operand;
     115    unsigned op2 = currentInstruction[2].u.operand;
     116    unsigned target = currentInstruction[3].u.operand;
     117
     118    emit_compareAndJumpSlow(op1, op2, target, DoubleGreaterThanOrUnordered, cti_op_jlesseq, true, iter);
     119}
     120
     121#if USE(JSVALUE64)
    49122
    50123void JIT::emit_op_lshift(Instruction* currentInstruction)
     
    243316}
    244317
    245 void JIT::emit_op_jnless(Instruction* currentInstruction)
    246 {
    247     unsigned op1 = currentInstruction[1].u.operand;
    248     unsigned op2 = currentInstruction[2].u.operand;
    249     unsigned target = currentInstruction[3].u.operand;
    250 
     318void JIT::emit_compareAndJump(OpcodeID, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition)
     319{
    251320    // We generate inline code for the following cases in the fast path:
    252321    // - int immediate to constant int immediate
     
    260329        emitLoadCharacterString(regT0, regT0, failures);
    261330        addSlowCase(failures);
    262         addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
     331        addJump(branch32(commute(condition), regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    263332        return;
    264333    }
     
    269338        emitLoadCharacterString(regT0, regT0, failures);
    270339        addSlowCase(failures);
    271         addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
     340        addJump(branch32(condition, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    272341        return;
    273342    }
     
    276345        emitJumpSlowCaseIfNotImmediateInteger(regT0);
    277346        int32_t op2imm = getConstantOperandImmediateInt(op2);
    278         addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target);
     347        addJump(branch32(condition, regT0, Imm32(op2imm)), target);
    279348    } else if (isOperandConstantImmediateInt(op1)) {
    280349        emitGetVirtualRegister(op2, regT1);
    281350        emitJumpSlowCaseIfNotImmediateInteger(regT1);
    282351        int32_t op1imm = getConstantOperandImmediateInt(op1);
    283         addJump(branch32(LessThanOrEqual, regT1, Imm32(op1imm)), target);
     352        addJump(branch32(commute(condition), regT1, Imm32(op1imm)), target);
    284353    } else {
    285354        emitGetVirtualRegisters(op1, regT0, op2, regT1);
     
    287356        emitJumpSlowCaseIfNotImmediateInteger(regT1);
    288357
    289         addJump(branch32(GreaterThanOrEqual, regT0, regT1), target);
    290     }
    291 }
    292 
    293 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    294 {
    295     unsigned op1 = currentInstruction[1].u.operand;
    296     unsigned op2 = currentInstruction[2].u.operand;
    297     unsigned target = currentInstruction[3].u.operand;
    298 
     358        addJump(branch32(condition, regT0, regT1), target);
     359    }
     360}
     361
     362void JIT::emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition condition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator& iter)
     363{
    299364    // We generate inline code for the following cases in the slow path:
    300365    // - floating-point number to constant int immediate
     
    306371        linkSlowCase(iter);
    307372        linkSlowCase(iter);
    308         JITStubCall stubCall(this, cti_op_jless);
     373        JITStubCall stubCall(this, stub);
    309374        stubCall.addArgument(op1, regT0);
    310375        stubCall.addArgument(op2, regT1);
    311376        stubCall.call();
    312         emitJumpSlowToHot(branchTest32(Zero, regT0), target);
     377        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    313378        return;
    314379    }
     
    322387            movePtrToDouble(regT0, fpRegT0);
    323388
    324             int32_t op2imm = getConstantOperand(op2).asInt32();;
     389            int32_t op2imm = getConstantOperand(op2).asInt32();
    325390
    326391            move(Imm32(op2imm), regT1);
    327392            convertInt32ToDouble(regT1, fpRegT1);
    328393
    329             emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
     394            emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
    330395
    331396            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     
    334399        }
    335400
    336         JITStubCall stubCall(this, cti_op_jless);
     401        JITStubCall stubCall(this, stub);
    337402        stubCall.addArgument(regT0);
    338403        stubCall.addArgument(op2, regT2);
    339404        stubCall.call();
    340         emitJumpSlowToHot(branchTest32(Zero, regT0), target);
     405        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    341406
    342407    } else if (isOperandConstantImmediateInt(op1)) {
     
    348413            movePtrToDouble(regT1, fpRegT1);
    349414
    350             int32_t op1imm = getConstantOperand(op1).asInt32();;
     415            int32_t op1imm = getConstantOperand(op1).asInt32();
    351416
    352417            move(Imm32(op1imm), regT0);
    353418            convertInt32ToDouble(regT0, fpRegT0);
    354419
    355             emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
     420            emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
    356421
    357422            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     
    360425        }
    361426
    362         JITStubCall stubCall(this, cti_op_jless);
     427        JITStubCall stubCall(this, stub);
    363428        stubCall.addArgument(op1, regT2);
    364429        stubCall.addArgument(regT1);
    365430        stubCall.call();
    366         emitJumpSlowToHot(branchTest32(Zero, regT0), target);
     431        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    367432
    368433    } else {
     
    378443            movePtrToDouble(regT1, fpRegT1);
    379444
    380             emitJumpSlowToHot(branchDouble(DoubleLessThanOrEqualOrUnordered, fpRegT1, fpRegT0), target);
     445            emitJumpSlowToHot(branchDouble(condition, fpRegT0, fpRegT1), target);
    381446
    382447            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
     
    388453
    389454        linkSlowCase(iter);
    390         JITStubCall stubCall(this, cti_op_jless);
    391         stubCall.addArgument(regT0);
    392         stubCall.addArgument(regT1);
    393         stubCall.call();
    394         emitJumpSlowToHot(branchTest32(Zero, regT0), target);
    395     }
    396 }
    397 
    398 void JIT::emit_op_jless(Instruction* currentInstruction)
    399 {
    400     unsigned op1 = currentInstruction[1].u.operand;
    401     unsigned op2 = currentInstruction[2].u.operand;
    402     unsigned target = currentInstruction[3].u.operand;
    403 
    404     // We generate inline code for the following cases in the fast path:
    405     // - int immediate to constant int immediate
    406     // - constant int immediate to int immediate
    407     // - int immediate to int immediate
    408 
    409     if (isOperandConstantImmediateChar(op1)) {
    410         emitGetVirtualRegister(op2, regT0);
    411         addSlowCase(emitJumpIfNotJSCell(regT0));
    412         JumpList failures;
    413         emitLoadCharacterString(regT0, regT0, failures);
    414         addSlowCase(failures);
    415         addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    416         return;
    417     }
    418     if (isOperandConstantImmediateChar(op2)) {
    419         emitGetVirtualRegister(op1, regT0);
    420         addSlowCase(emitJumpIfNotJSCell(regT0));
    421         JumpList failures;
    422         emitLoadCharacterString(regT0, regT0, failures);
    423         addSlowCase(failures);
    424         addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    425         return;
    426     }
    427     if (isOperandConstantImmediateInt(op2)) {
    428         emitGetVirtualRegister(op1, regT0);
    429         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    430         int32_t op2imm = getConstantOperandImmediateInt(op2);
    431         addJump(branch32(LessThan, regT0, Imm32(op2imm)), target);
    432     } else if (isOperandConstantImmediateInt(op1)) {
    433         emitGetVirtualRegister(op2, regT1);
    434         emitJumpSlowCaseIfNotImmediateInteger(regT1);
    435         int32_t op1imm = getConstantOperandImmediateInt(op1);
    436         addJump(branch32(GreaterThan, regT1, Imm32(op1imm)), target);
    437     } else {
    438         emitGetVirtualRegisters(op1, regT0, op2, regT1);
    439         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    440         emitJumpSlowCaseIfNotImmediateInteger(regT1);
    441 
    442         addJump(branch32(LessThan, regT0, regT1), target);
    443     }
    444 }
    445 
    446 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    447 {
    448     unsigned op1 = currentInstruction[1].u.operand;
    449     unsigned op2 = currentInstruction[2].u.operand;
    450     unsigned target = currentInstruction[3].u.operand;
    451 
    452     // We generate inline code for the following cases in the slow path:
    453     // - floating-point number to constant int immediate
    454     // - constant int immediate to floating-point number
    455     // - floating-point number to floating-point number.
    456     if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
    457         linkSlowCase(iter);
    458         linkSlowCase(iter);
    459         linkSlowCase(iter);
    460         linkSlowCase(iter);
    461         JITStubCall stubCall(this, cti_op_jless);
    462         stubCall.addArgument(op1, regT0);
    463         stubCall.addArgument(op2, regT1);
    464         stubCall.call();
    465         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    466         return;
    467     }
    468 
    469     if (isOperandConstantImmediateInt(op2)) {
    470         linkSlowCase(iter);
    471 
    472         if (supportsFloatingPoint()) {
    473             Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
    474             addPtr(tagTypeNumberRegister, regT0);
    475             movePtrToDouble(regT0, fpRegT0);
    476 
    477             int32_t op2imm = getConstantOperand(op2).asInt32();
    478 
    479             move(Imm32(op2imm), regT1);
    480             convertInt32ToDouble(regT1, fpRegT1);
    481 
    482             emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
    483 
    484             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
    485 
    486             fail1.link(this);
    487         }
    488 
    489         JITStubCall stubCall(this, cti_op_jless);
    490         stubCall.addArgument(regT0);
    491         stubCall.addArgument(op2, regT2);
    492         stubCall.call();
    493         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    494 
    495     } else if (isOperandConstantImmediateInt(op1)) {
    496         linkSlowCase(iter);
    497 
    498         if (supportsFloatingPoint()) {
    499             Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
    500             addPtr(tagTypeNumberRegister, regT1);
    501             movePtrToDouble(regT1, fpRegT1);
    502 
    503             int32_t op1imm = getConstantOperand(op1).asInt32();
    504 
    505             move(Imm32(op1imm), regT0);
    506             convertInt32ToDouble(regT0, fpRegT0);
    507 
    508             emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
    509 
    510             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
    511 
    512             fail1.link(this);
    513         }
    514 
    515         JITStubCall stubCall(this, cti_op_jless);
    516         stubCall.addArgument(op1, regT2);
    517         stubCall.addArgument(regT1);
    518         stubCall.call();
    519         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    520 
    521     } else {
    522         linkSlowCase(iter);
    523 
    524         if (supportsFloatingPoint()) {
    525             Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
    526             Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
    527             Jump fail3 = emitJumpIfImmediateInteger(regT1);
    528             addPtr(tagTypeNumberRegister, regT0);
    529             addPtr(tagTypeNumberRegister, regT1);
    530             movePtrToDouble(regT0, fpRegT0);
    531             movePtrToDouble(regT1, fpRegT1);
    532 
    533             emitJumpSlowToHot(branchDouble(DoubleLessThan, fpRegT0, fpRegT1), target);
    534 
    535             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnless));
    536 
    537             fail1.link(this);
    538             fail2.link(this);
    539             fail3.link(this);
    540         }
    541 
    542         linkSlowCase(iter);
    543         JITStubCall stubCall(this, cti_op_jless);
    544         stubCall.addArgument(regT0);
    545         stubCall.addArgument(regT1);
    546         stubCall.call();
    547         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    548     }
    549 }
    550 
    551 void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
    552 {
    553     unsigned op1 = currentInstruction[1].u.operand;
    554     unsigned op2 = currentInstruction[2].u.operand;
    555     unsigned target = currentInstruction[3].u.operand;
    556 
    557     // We generate inline code for the following cases in the fast path:
    558     // - int immediate to constant int immediate
    559     // - constant int immediate to int immediate
    560     // - int immediate to int immediate
    561 
    562     if (isOperandConstantImmediateChar(op1)) {
    563         emitGetVirtualRegister(op2, regT0);
    564         addSlowCase(emitJumpIfNotJSCell(regT0));
    565         JumpList failures;
    566         emitLoadCharacterString(regT0, regT0, failures);
    567         addSlowCase(failures);
    568         addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    569         return;
    570     }
    571     if (isOperandConstantImmediateChar(op2)) {
    572         emitGetVirtualRegister(op1, regT0);
    573         addSlowCase(emitJumpIfNotJSCell(regT0));
    574         JumpList failures;
    575         emitLoadCharacterString(regT0, regT0, failures);
    576         addSlowCase(failures);
    577         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    578         return;
    579     }
    580     if (isOperandConstantImmediateInt(op2)) {
    581         emitGetVirtualRegister(op1, regT0);
    582         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    583         int32_t op2imm = getConstantOperandImmediateInt(op2);
    584         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(op2imm)), target);
    585     } else if (isOperandConstantImmediateInt(op1)) {
    586         emitGetVirtualRegister(op2, regT1);
    587         emitJumpSlowCaseIfNotImmediateInteger(regT1);
    588         int32_t op1imm = getConstantOperandImmediateInt(op1);
    589         addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT1, Imm32(op1imm)), target);
    590     } else {
    591         emitGetVirtualRegisters(op1, regT0, op2, regT1);
    592         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    593         emitJumpSlowCaseIfNotImmediateInteger(regT1);
    594 
    595         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT1), target);
    596     }
    597 }
    598 
    599 void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert)
    600 {
    601     unsigned op1 = currentInstruction[1].u.operand;
    602     unsigned op2 = currentInstruction[2].u.operand;
    603     unsigned target = currentInstruction[3].u.operand;
    604 
    605     // We generate inline code for the following cases in the slow path:
    606     // - floating-point number to constant int immediate
    607     // - constant int immediate to floating-point number
    608     // - floating-point number to floating-point number.
    609 
    610     if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
    611         linkSlowCase(iter);
    612         linkSlowCase(iter);
    613         linkSlowCase(iter);
    614         linkSlowCase(iter);
    615         JITStubCall stubCall(this, cti_op_jlesseq);
    616         stubCall.addArgument(op1, regT0);
    617         stubCall.addArgument(op2, regT1);
    618         stubCall.call();
    619         emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    620         return;
    621     }
    622 
    623     if (isOperandConstantImmediateInt(op2)) {
    624         linkSlowCase(iter);
    625 
    626         if (supportsFloatingPoint()) {
    627             Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
    628             addPtr(tagTypeNumberRegister, regT0);
    629             movePtrToDouble(regT0, fpRegT0);
    630 
    631             int32_t op2imm = getConstantOperand(op2).asInt32();;
    632 
    633             move(Imm32(op2imm), regT1);
    634             convertInt32ToDouble(regT1, fpRegT1);
    635 
    636             emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
    637 
    638             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
    639 
    640             fail1.link(this);
    641         }
    642 
    643         JITStubCall stubCall(this, cti_op_jlesseq);
    644         stubCall.addArgument(regT0);
    645         stubCall.addArgument(op2, regT2);
    646         stubCall.call();
    647         emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    648 
    649     } else if (isOperandConstantImmediateInt(op1)) {
    650         linkSlowCase(iter);
    651 
    652         if (supportsFloatingPoint()) {
    653             Jump fail1 = emitJumpIfNotImmediateNumber(regT1);
    654             addPtr(tagTypeNumberRegister, regT1);
    655             movePtrToDouble(regT1, fpRegT1);
    656 
    657             int32_t op1imm = getConstantOperand(op1).asInt32();;
    658 
    659             move(Imm32(op1imm), regT0);
    660             convertInt32ToDouble(regT0, fpRegT0);
    661 
    662             emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
    663 
    664             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
    665 
    666             fail1.link(this);
    667         }
    668 
    669         JITStubCall stubCall(this, cti_op_jlesseq);
    670         stubCall.addArgument(op1, regT2);
    671         stubCall.addArgument(regT1);
    672         stubCall.call();
    673         emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    674 
    675     } else {
    676         linkSlowCase(iter);
    677 
    678         if (supportsFloatingPoint()) {
    679             Jump fail1 = emitJumpIfNotImmediateNumber(regT0);
    680             Jump fail2 = emitJumpIfNotImmediateNumber(regT1);
    681             Jump fail3 = emitJumpIfImmediateInteger(regT1);
    682             addPtr(tagTypeNumberRegister, regT0);
    683             addPtr(tagTypeNumberRegister, regT1);
    684             movePtrToDouble(regT0, fpRegT0);
    685             movePtrToDouble(regT1, fpRegT1);
    686 
    687             emitJumpSlowToHot(branchDouble(invert ? DoubleLessThanOrUnordered : DoubleGreaterThanOrEqual, fpRegT1, fpRegT0), target);
    688 
    689             emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_jnlesseq));
    690 
    691             fail1.link(this);
    692             fail2.link(this);
    693             fail3.link(this);
    694         }
    695 
    696         linkSlowCase(iter);
    697         JITStubCall stubCall(this, cti_op_jlesseq);
     455        JITStubCall stubCall(this, stub);
    698456        stubCall.addArgument(regT0);
    699457        stubCall.addArgument(regT1);
     
    701459        emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    702460    }
    703 }
    704 
    705 void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
    706 {
    707     emit_op_jlesseq(currentInstruction, true);
    708 }
    709 
    710 void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    711 {
    712     emitSlow_op_jlesseq(currentInstruction, iter, true);
    713461}
    714462
     
    1239987/* ------------------------------ END: OP_ADD, OP_SUB, OP_MUL ------------------------------ */
    1240988
     989#endif // USE(JSVALUE64)
     990
    1241991} // namespace JSC
    1242992
    1243 #endif // USE(JSVALUE64)
    1244993#endif // ENABLE(JIT)
  • trunk/Source/JavaScriptCore/jit/JITArithmetic32_64.cpp

    r86968 r90352  
    8585}
    8686
    87 void JIT::emit_op_jnless(Instruction* currentInstruction)
    88 {
    89     unsigned op1 = currentInstruction[1].u.operand;
    90     unsigned op2 = currentInstruction[2].u.operand;
    91     unsigned target = currentInstruction[3].u.operand;
    92 
     87void JIT::emit_compareAndJump(OpcodeID opcode, unsigned op1, unsigned op2, unsigned target, RelationalCondition condition)
     88{
    9389    JumpList notInt32Op1;
    9490    JumpList notInt32Op2;
     
    10197        emitLoadCharacterString(regT0, regT0, failures);
    10298        addSlowCase(failures);
    103         addJump(branch32(LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
     99        addJump(branch32(commute(condition), regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    104100        return;
    105101    }
     
    110106        emitLoadCharacterString(regT0, regT0, failures);
    111107        addSlowCase(failures);
    112         addJump(branch32(GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    113         return;
    114     }
     108        addJump(branch32(condition, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
     109        return;
     110    } 
    115111    if (isOperandConstantImmediateInt(op1)) {
    116         // Int32 less.
    117112        emitLoad(op2, regT3, regT2);
    118113        notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    119         addJump(branch32(LessThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
     114        addJump(branch32(commute(condition), regT2, Imm32(getConstantOperand(op1).asInt32())), target);
    120115    } else if (isOperandConstantImmediateInt(op2)) {
    121116        emitLoad(op1, regT1, regT0);
    122117        notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    123         addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
     118        addJump(branch32(condition, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
    124119    } else {
    125120        emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    126121        notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    127122        notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    128         addJump(branch32(GreaterThanOrEqual, regT0, regT2), target);
     123        addJump(branch32(condition, regT0, regT2), target);
    129124    }
    130125
     
    137132
    138133    // Double less.
    139     emitBinaryDoubleOp(op_jnless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
     134    emitBinaryDoubleOp(opcode, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
    140135    end.link(this);
    141136}
    142137
    143 void JIT::emitSlow_op_jnless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    144 {
    145     unsigned op1 = currentInstruction[1].u.operand;
    146     unsigned op2 = currentInstruction[2].u.operand;
    147     unsigned target = currentInstruction[3].u.operand;
    148 
     138void JIT::emit_compareAndJumpSlow(unsigned op1, unsigned op2, unsigned target, DoubleCondition, int (JIT_STUB *stub)(STUB_ARGS_DECLARATION), bool invert, Vector<SlowCaseEntry>::iterator& iter)
     139{
    149140    if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
    150141        linkSlowCase(iter);
     
    166157        }
    167158    }
    168 
    169     JITStubCall stubCall(this, cti_op_jless);
    170     stubCall.addArgument(op1);
    171     stubCall.addArgument(op2);
    172     stubCall.call();
    173     emitJumpSlowToHot(branchTest32(Zero, regT0), target);
    174 }
    175 
    176 void JIT::emit_op_jless(Instruction* currentInstruction)
    177 {
    178     unsigned op1 = currentInstruction[1].u.operand;
    179     unsigned op2 = currentInstruction[2].u.operand;
    180     unsigned target = currentInstruction[3].u.operand;
    181 
    182     JumpList notInt32Op1;
    183     JumpList notInt32Op2;
    184 
    185     // Character less.
    186     if (isOperandConstantImmediateChar(op1)) {
    187         emitLoad(op2, regT1, regT0);
    188         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
    189         JumpList failures;
    190         emitLoadCharacterString(regT0, regT0, failures);
    191         addSlowCase(failures);
    192         addJump(branch32(GreaterThan, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    193         return;
    194     }
    195     if (isOperandConstantImmediateChar(op2)) {
    196         emitLoad(op1, regT1, regT0);
    197         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
    198         JumpList failures;
    199         emitLoadCharacterString(regT0, regT0, failures);
    200         addSlowCase(failures);
    201         addJump(branch32(LessThan, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    202         return;
    203     }
    204     if (isOperandConstantImmediateInt(op1)) {
    205         emitLoad(op2, regT3, regT2);
    206         notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    207         addJump(branch32(GreaterThan, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
    208     } else if (isOperandConstantImmediateInt(op2)) {
    209         emitLoad(op1, regT1, regT0);
    210         notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    211         addJump(branch32(LessThan, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
    212     } else {
    213         emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    214         notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    215         notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    216         addJump(branch32(LessThan, regT0, regT2), target);
    217     }
    218 
    219     if (!supportsFloatingPoint()) {
    220         addSlowCase(notInt32Op1);
    221         addSlowCase(notInt32Op2);
    222         return;
    223     }
    224     Jump end = jump();
    225 
    226     // Double less.
    227     emitBinaryDoubleOp(op_jless, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
    228     end.link(this);
    229 }
    230 
    231 void JIT::emitSlow_op_jless(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    232 {
    233     unsigned op1 = currentInstruction[1].u.operand;
    234     unsigned op2 = currentInstruction[2].u.operand;
    235     unsigned target = currentInstruction[3].u.operand;
    236    
    237     if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
    238         linkSlowCase(iter);
    239         linkSlowCase(iter);
    240         linkSlowCase(iter);
    241         linkSlowCase(iter);
    242     } else {
    243         if (!supportsFloatingPoint()) {
    244             if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
    245                 linkSlowCase(iter); // int32 check
    246             linkSlowCase(iter); // int32 check
    247         } else {
    248             if (!isOperandConstantImmediateInt(op1)) {
    249                 linkSlowCase(iter); // double check
    250                 linkSlowCase(iter); // int32 check
    251             }
    252             if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2))
    253                 linkSlowCase(iter); // double check
    254         }
    255     }
    256     JITStubCall stubCall(this, cti_op_jless);
    257     stubCall.addArgument(op1);
    258     stubCall.addArgument(op2);
    259     stubCall.call();
    260     emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    261 }
    262 
    263 void JIT::emit_op_jlesseq(Instruction* currentInstruction, bool invert)
    264 {
    265     unsigned op1 = currentInstruction[1].u.operand;
    266     unsigned op2 = currentInstruction[2].u.operand;
    267     unsigned target = currentInstruction[3].u.operand;
    268 
    269     JumpList notInt32Op1;
    270     JumpList notInt32Op2;
    271 
    272     // Character less.
    273     if (isOperandConstantImmediateChar(op1)) {
    274         emitLoad(op2, regT1, regT0);
    275         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
    276         JumpList failures;
    277         emitLoadCharacterString(regT0, regT0, failures);
    278         addSlowCase(failures);
    279         addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT0, Imm32(asString(getConstantOperand(op1))->tryGetValue()[0])), target);
    280         return;
    281     }
    282     if (isOperandConstantImmediateChar(op2)) {
    283         emitLoad(op1, regT1, regT0);
    284         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::CellTag)));
    285         JumpList failures;
    286         emitLoadCharacterString(regT0, regT0, failures);
    287         addSlowCase(failures);
    288         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(asString(getConstantOperand(op2))->tryGetValue()[0])), target);
    289         return;
    290     }
    291     if (isOperandConstantImmediateInt(op1)) {
    292         emitLoad(op2, regT3, regT2);
    293         notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    294         addJump(branch32(invert ? LessThan : GreaterThanOrEqual, regT2, Imm32(getConstantOperand(op1).asInt32())), target);
    295     } else if (isOperandConstantImmediateInt(op2)) {
    296         emitLoad(op1, regT1, regT0);
    297         notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    298         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
    299     } else {
    300         emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    301         notInt32Op1.append(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    302         notInt32Op2.append(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    303         addJump(branch32(invert ? GreaterThan : LessThanOrEqual, regT0, regT2), target);
    304     }
    305 
    306     if (!supportsFloatingPoint()) {
    307         addSlowCase(notInt32Op1);
    308         addSlowCase(notInt32Op2);
    309         return;
    310     }
    311     Jump end = jump();
    312 
    313     // Double less.
    314     emitBinaryDoubleOp(invert ? op_jnlesseq : op_jlesseq, target, op1, op2, OperandTypes(), notInt32Op1, notInt32Op2, !isOperandConstantImmediateInt(op1), isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2));
    315     end.link(this);
    316 }
    317 
    318 void JIT::emitSlow_op_jlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter, bool invert)
    319 {
    320     unsigned op1 = currentInstruction[1].u.operand;
    321     unsigned op2 = currentInstruction[2].u.operand;
    322     unsigned target = currentInstruction[3].u.operand;
    323 
    324     if (isOperandConstantImmediateChar(op1) || isOperandConstantImmediateChar(op2)) {
    325         linkSlowCase(iter);
    326         linkSlowCase(iter);
    327         linkSlowCase(iter);
    328         linkSlowCase(iter);
    329     } else {
    330         if (!supportsFloatingPoint()) {
    331             if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
    332                 linkSlowCase(iter); // int32 check
    333             linkSlowCase(iter); // int32 check
    334         } else {
    335             if (!isOperandConstantImmediateInt(op1)) {
    336                 linkSlowCase(iter); // double check
    337                 linkSlowCase(iter); // int32 check
    338             }
    339             if (isOperandConstantImmediateInt(op1) || !isOperandConstantImmediateInt(op2))
    340                 linkSlowCase(iter); // double check
    341         }
    342     }
    343 
    344     JITStubCall stubCall(this, cti_op_jlesseq);
     159    JITStubCall stubCall(this, stub);
    345160    stubCall.addArgument(op1);
    346161    stubCall.addArgument(op2);
    347162    stubCall.call();
    348163    emitJumpSlowToHot(branchTest32(invert ? Zero : NonZero, regT0), target);
    349 }
    350 
    351 void JIT::emit_op_jnlesseq(Instruction* currentInstruction)
    352 {
    353     emit_op_jlesseq(currentInstruction, true);
    354 }
    355 
    356 void JIT::emitSlow_op_jnlesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    357 {
    358     emitSlow_op_jlesseq(currentInstruction, iter, true);
    359164}
    360165
  • trunk/Source/JavaScriptCore/jit/JITOpcodes.cpp

    r89171 r90352  
    329329}
    330330
    331 void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
    332 {
    333     emitTimeoutCheck();
    334 
    335     unsigned op1 = currentInstruction[1].u.operand;
    336     unsigned op2 = currentInstruction[2].u.operand;
    337     unsigned target = currentInstruction[3].u.operand;
    338     if (isOperandConstantImmediateInt(op2)) {
    339         emitGetVirtualRegister(op1, regT0);
    340         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    341         int32_t op2imm = getConstantOperandImmediateInt(op2);
    342         addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target);
    343     } else {
    344         emitGetVirtualRegisters(op1, regT0, op2, regT1);
    345         emitJumpSlowCaseIfNotImmediateInteger(regT0);
    346         emitJumpSlowCaseIfNotImmediateInteger(regT1);
    347         addJump(branch32(LessThanOrEqual, regT0, regT1), target);
    348     }
    349 }
    350 
    351331void JIT::emit_op_new_object(Instruction* currentInstruction)
    352332{
     
    12421222    stubCall.addArgument(regT0);
    12431223    stubCall.call(currentInstruction[1].u.operand);
    1244 }
    1245 
    1246 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    1247 {
    1248     unsigned op2 = currentInstruction[2].u.operand;
    1249     unsigned target = currentInstruction[3].u.operand;
    1250     if (isOperandConstantImmediateInt(op2)) {
    1251         linkSlowCase(iter);
    1252         JITStubCall stubCall(this, cti_op_loop_if_lesseq);
    1253         stubCall.addArgument(regT0);
    1254         stubCall.addArgument(currentInstruction[2].u.operand, regT2);
    1255         stubCall.call();
    1256         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    1257     } else {
    1258         linkSlowCase(iter);
    1259         linkSlowCase(iter);
    1260         JITStubCall stubCall(this, cti_op_loop_if_lesseq);
    1261         stubCall.addArgument(regT0);
    1262         stubCall.addArgument(regT1);
    1263         stubCall.call();
    1264         emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    1265     }
    12661224}
    12671225
  • trunk/Source/JavaScriptCore/jit/JITOpcodes32_64.cpp

    r90232 r90352  
    484484}
    485485
    486 void JIT::emit_op_loop_if_lesseq(Instruction* currentInstruction)
    487 {
    488     unsigned op1 = currentInstruction[1].u.operand;
    489     unsigned op2 = currentInstruction[2].u.operand;
    490     unsigned target = currentInstruction[3].u.operand;
    491 
    492     emitTimeoutCheck();
    493 
    494     if (isOperandConstantImmediateInt(op1)) {
    495         emitLoad(op2, regT1, regT0);
    496         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    497         addJump(branch32(GreaterThanOrEqual, regT0, Imm32(getConstantOperand(op1).asInt32())), target);
    498         return;
    499     }
    500 
    501     if (isOperandConstantImmediateInt(op2)) {
    502         emitLoad(op1, regT1, regT0);
    503         addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    504         addJump(branch32(LessThanOrEqual, regT0, Imm32(getConstantOperand(op2).asInt32())), target);
    505         return;
    506     }
    507 
    508     emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
    509     addSlowCase(branch32(NotEqual, regT1, TrustedImm32(JSValue::Int32Tag)));
    510     addSlowCase(branch32(NotEqual, regT3, TrustedImm32(JSValue::Int32Tag)));
    511     addJump(branch32(LessThanOrEqual, regT0, regT2), target);
    512 }
    513 
    514 void JIT::emitSlow_op_loop_if_lesseq(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    515 {
    516     unsigned op1 = currentInstruction[1].u.operand;
    517     unsigned op2 = currentInstruction[2].u.operand;
    518     unsigned target = currentInstruction[3].u.operand;
    519 
    520     if (!isOperandConstantImmediateInt(op1) && !isOperandConstantImmediateInt(op2))
    521         linkSlowCase(iter); // int32 check
    522     linkSlowCase(iter); // int32 check
    523 
    524     JITStubCall stubCall(this, cti_op_loop_if_lesseq);
    525     stubCall.addArgument(op1);
    526     stubCall.addArgument(op2);
    527     stubCall.call();
    528     emitJumpSlowToHot(branchTest32(NonZero, regT0), target);
    529 }
    530 
    531486void JIT::emit_op_new_object(Instruction* currentInstruction)
    532487{
  • trunk/Source/JavaScriptCore/jit/JITStubs.cpp

    r89954 r90352  
    13691369
    13701370    return callFrame;
    1371 }
    1372 
    1373 DEFINE_STUB_FUNCTION(int, op_loop_if_lesseq)
    1374 {
    1375     STUB_INIT_STACK_FRAME(stackFrame);
    1376 
    1377     JSValue src1 = stackFrame.args[0].jsValue();
    1378     JSValue src2 = stackFrame.args[1].jsValue();
    1379     CallFrame* callFrame = stackFrame.callFrame;
    1380 
    1381     bool result = jsLessEq(callFrame, src1, src2);
    1382     CHECK_FOR_EXCEPTION_AT_END();
    1383     return result;
    13841371}
    13851372
  • trunk/Source/JavaScriptCore/jit/JITStubs.h

    r88873 r90352  
    397397    int JIT_STUB cti_op_jtrue(STUB_ARGS_DECLARATION);
    398398    int JIT_STUB cti_op_load_varargs(STUB_ARGS_DECLARATION);
    399     int JIT_STUB cti_op_loop_if_lesseq(STUB_ARGS_DECLARATION);
    400399    int JIT_STUB cti_timeout_check(STUB_ARGS_DECLARATION);
    401400    int JIT_STUB cti_has_property(STUB_ARGS_DECLARATION);
Note: See TracChangeset for help on using the changeset viewer.