Ignore:
Timestamp:
Jan 15, 2009, 10:51:20 PM (16 years ago)
Author:
[email protected]
Message:

2009-01-15 Gavin Barraclough <[email protected]>

Reviewed by Oliver Hunt.

Add support for integer addition, subtraction and multiplication
in JIT code on x86-64.

  • assembler/MacroAssembler.h: (JSC::MacroAssembler::mul32): (JSC::MacroAssembler::sub32): (JSC::MacroAssembler::joMul32): (JSC::MacroAssembler::joSub32):
  • jit/JIT.cpp: (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases):
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_add): (JSC::JIT::compileFastArithSlow_op_add): (JSC::JIT::compileFastArith_op_mul): (JSC::JIT::compileFastArithSlow_op_mul): (JSC::JIT::compileFastArith_op_sub): (JSC::JIT::compileFastArithSlow_op_sub):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JITArithmetic.cpp

    r39958 r39960  
    225225}
    226226
    227 void JIT::compileFastArith_op_add(Instruction* currentInstruction)
    228 {
    229     unsigned result = currentInstruction[1].u.operand;
    230     unsigned op1 = currentInstruction[2].u.operand;
    231     unsigned op2 = currentInstruction[3].u.operand;
    232 
    233     if (isOperandConstantImmediateInt(op1)) {
    234         emitGetVirtualRegister(op2, X86::eax);
    235         emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    236 #if USE(ALTERNATE_JSIMMEDIATE)
    237         // FIXME: investigate performing a 31-bit add here (can we preserve upper bit & detect overflow from low word to high?)
    238         //        (or, detect carry? - if const is positive, will only carry when overflowing from negative to positive?)
    239         addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
    240         emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    241 #else
    242         addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
    243         signExtend32ToPtr(X86::eax, X86::eax);
    244 #endif
    245         emitPutVirtualRegister(result);
    246     } else if (isOperandConstantImmediateInt(op2)) {
    247         emitGetVirtualRegister(op1, X86::eax);
    248         emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    249 #if USE(ALTERNATE_JSIMMEDIATE)
    250         emitFastArithImmToInt(X86::eax);
    251         addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
    252         emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
    253 #else
    254         addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
    255         signExtend32ToPtr(X86::eax, X86::eax);
    256 #endif
    257         emitPutVirtualRegister(result);
    258     } else {
    259         OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    260         if (types.first().mightBeNumber() && types.second().mightBeNumber())
    261             compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
    262         else {
    263             emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    264             emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    265             emitCTICall(Interpreter::cti_op_add);
    266             emitPutVirtualRegister(result);
    267         }
    268     }
    269 }
    270 void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    271 {
    272     unsigned result = currentInstruction[1].u.operand;
    273     unsigned op1 = currentInstruction[2].u.operand;
    274     unsigned op2 = currentInstruction[3].u.operand;
    275 
    276     if (isOperandConstantImmediateInt(op1)) {
    277 #if USE(ALTERNATE_JSIMMEDIATE)
    278         linkSlowCase(iter);
    279         linkSlowCase(iter);
    280         emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    281         emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    282 #else
    283         Jump notImm = getSlowCase(iter);
    284         linkSlowCase(iter);
    285         sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax);
    286         notImm.link(this);
    287         emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    288         emitPutJITStubArg(X86::eax, 2);
    289 #endif
    290         emitCTICall(Interpreter::cti_op_add);
    291         emitPutVirtualRegister(result);
    292     } else if (isOperandConstantImmediateInt(op2)) {
    293 #if USE(ALTERNATE_JSIMMEDIATE)
    294         linkSlowCase(iter);
    295         linkSlowCase(iter);
    296         emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    297         emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    298 #else
    299         Jump notImm = getSlowCase(iter);
    300         linkSlowCase(iter);
    301         sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax);
    302         notImm.link(this);
    303         emitPutJITStubArg(X86::eax, 1);
    304         emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    305 #endif
    306         emitCTICall(Interpreter::cti_op_add);
    307         emitPutVirtualRegister(result);
    308     } else {
    309         OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
    310         ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
    311         compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
    312     }
    313 }
    314 
    315 void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
    316 {
    317     unsigned result = currentInstruction[1].u.operand;
    318     unsigned op1 = currentInstruction[2].u.operand;
    319     unsigned op2 = currentInstruction[3].u.operand;
    320 
    321     // For now, only plant a fast int case if the constant operand is greater than zero.
    322     int32_t value;
    323     if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
    324         emitGetVirtualRegister(op2, X86::eax);
    325         emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    326 #if USE(ALTERNATE_JSIMMEDIATE)
    327         addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    328 #else
    329         emitFastArithDeTagImmediate(X86::eax);
    330         addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    331         signExtend32ToPtr(X86::eax, X86::eax);
    332 #endif
    333         emitFastArithReTagImmediate(X86::eax, X86::eax);
    334         emitPutVirtualRegister(result);
    335     } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
    336         emitGetVirtualRegister(op1, X86::eax);
    337         emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    338 #if USE(ALTERNATE_JSIMMEDIATE)
    339         addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    340 #else
    341         emitFastArithDeTagImmediate(X86::eax);
    342         addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
    343         signExtend32ToPtr(X86::eax, X86::eax);
    344 #endif
    345         emitFastArithReTagImmediate(X86::eax, X86::eax);
    346         emitPutVirtualRegister(result);
    347     } else
    348         compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
    349 }
    350 void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
    351 {
    352     int result = currentInstruction[1].u.operand;
    353     int op1 = currentInstruction[2].u.operand;
    354     int op2 = currentInstruction[3].u.operand;
    355 
    356     if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
    357         || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
    358         linkSlowCase(iter);
    359         linkSlowCase(iter);
    360         // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
    361         emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
    362         emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    363         emitCTICall(Interpreter::cti_op_mul);
    364         emitPutVirtualRegister(result);
    365     } else
    366         compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
    367 }
    368 
    369227void JIT::compileFastArith_op_post_inc(unsigned result, unsigned srcDst)
    370228{
     
    469327#if !ENABLE(JIT_OPTIMIZE_ARITHMETIC)
    470328
    471 void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned dst, unsigned src1, unsigned src2, OperandTypes)
    472 {
    473     emitPutJITStubArgFromVirtualRegister(src1, 1, X86::ecx);
    474     emitPutJITStubArgFromVirtualRegister(src2, 2, X86::ecx);
    475     if (opcodeID == op_add)
     329void JIT::compileFastArith_op_add(Instruction* currentInstruction)
     330{
     331    unsigned result = currentInstruction[1].u.operand;
     332    unsigned op1 = currentInstruction[2].u.operand;
     333    unsigned op2 = currentInstruction[3].u.operand;
     334
     335    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     336    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     337    emitCTICall(Interpreter::cti_op_add);
     338    emitPutVirtualRegister(result);
     339}
     340void JIT::compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&)
     341{
     342    ASSERT_NOT_REACHED();
     343}
     344
     345void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
     346{
     347    unsigned result = currentInstruction[1].u.operand;
     348    unsigned op1 = currentInstruction[2].u.operand;
     349    unsigned op2 = currentInstruction[3].u.operand;
     350
     351    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     352    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     353    emitCTICall(Interpreter::cti_op_mul);
     354    emitPutVirtualRegister(result);
     355}
     356void JIT::compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&)
     357{
     358    ASSERT_NOT_REACHED();
     359}
     360
     361void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
     362{
     363    unsigned result = currentInstruction[1].u.operand;
     364    unsigned op1 = currentInstruction[2].u.operand;
     365    unsigned op2 = currentInstruction[3].u.operand;
     366
     367    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     368    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     369    emitCTICall(Interpreter::cti_op_sub);
     370    emitPutVirtualRegister(result);
     371}
     372void JIT::compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&)
     373{
     374    ASSERT_NOT_REACHED();
     375}
     376
     377#elif USE(ALTERNATE_JSIMMEDIATE) // *AND* ENABLE(JIT_OPTIMIZE_ARITHMETIC)
     378
     379void JIT::compileFastArith_op_add(Instruction* currentInstruction)
     380{
     381    unsigned result = currentInstruction[1].u.operand;
     382    unsigned op1 = currentInstruction[2].u.operand;
     383    unsigned op2 = currentInstruction[3].u.operand;
     384
     385    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     386    if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {
     387        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     388        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    476389        emitCTICall(Interpreter::cti_op_add);
    477     else if (opcodeID == op_sub)
    478         emitCTICall(Interpreter::cti_op_sub);
    479     else {
    480         ASSERT(opcodeID == op_mul);
     390        emitPutVirtualRegister(result);
     391        return;
     392    }
     393
     394    if (isOperandConstantImmediateInt(op1)) {
     395        emitGetVirtualRegister(op2, X86::eax);
     396        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     397        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1)), X86::eax));
     398        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     399    } else if (isOperandConstantImmediateInt(op2)) {
     400        emitGetVirtualRegister(op1, X86::eax);
     401        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     402        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2)), X86::eax));
     403        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     404    } else {
     405        emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
     406        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     407        emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
     408        addSlowCase(joAdd32(X86::edx, X86::eax));
     409        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     410    }
     411
     412    emitPutVirtualRegister(result);
     413}
     414void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     415{
     416    unsigned result = currentInstruction[1].u.operand;
     417    unsigned op1 = currentInstruction[2].u.operand;
     418    unsigned op2 = currentInstruction[3].u.operand;
     419
     420    if (isOperandConstantImmediateInt(op1)) {
     421        linkSlowCase(iter);
     422        linkSlowCase(iter);
     423        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     424        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     425        emitCTICall(Interpreter::cti_op_add);
     426    } else if (isOperandConstantImmediateInt(op2)) {
     427        linkSlowCase(iter);
     428        linkSlowCase(iter);
     429        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     430        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     431        emitCTICall(Interpreter::cti_op_add);
     432    } else {
     433        linkSlowCase(iter);
     434        linkSlowCase(iter);
     435        linkSlowCase(iter);
     436        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     437        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     438        emitCTICall(Interpreter::cti_op_add);
     439    }
     440
     441    emitPutVirtualRegister(result);
     442}
     443
     444void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
     445{
     446    unsigned result = currentInstruction[1].u.operand;
     447    unsigned op1 = currentInstruction[2].u.operand;
     448    unsigned op2 = currentInstruction[3].u.operand;
     449
     450    // For now, only plant a fast int case if the constant operand is greater than zero.
     451    int32_t value;
     452    if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
     453        emitGetVirtualRegister(op2, X86::eax);
     454        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     455        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
     456        emitFastArithReTagImmediate(X86::eax, X86::eax);
     457    } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
     458        emitGetVirtualRegister(op1, X86::eax);
     459        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     460        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
     461        emitFastArithReTagImmediate(X86::eax, X86::eax);
     462    } else {
     463        emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
     464        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     465        emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
     466        addSlowCase(joMul32(X86::edx, X86::eax));
     467        addSlowCase(jz32(X86::eax));
     468        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     469    }
     470
     471    emitPutVirtualRegister(result);
     472}
     473void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     474{
     475    unsigned result = currentInstruction[1].u.operand;
     476    unsigned op1 = currentInstruction[2].u.operand;
     477    unsigned op2 = currentInstruction[3].u.operand;
     478
     479    if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
     480        || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
     481        linkSlowCase(iter);
     482        linkSlowCase(iter);
     483        // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
     484        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     485        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
    481486        emitCTICall(Interpreter::cti_op_mul);
    482     }
    483     emitPutVirtualRegister(dst);
    484 }
    485 
    486 void JIT::compileBinaryArithOpSlowCase(OpcodeID, Vector<SlowCaseEntry>::iterator&, unsigned, unsigned, unsigned, OperandTypes)
    487 {
    488     ASSERT_NOT_REACHED();
     487    } else {
     488        linkSlowCase(iter);
     489        linkSlowCase(iter);
     490        linkSlowCase(iter);
     491        linkSlowCase(iter);
     492        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     493        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     494        emitCTICall(Interpreter::cti_op_mul);
     495    }
     496
     497    emitPutVirtualRegister(result);
     498}
     499
     500void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
     501{
     502    unsigned result = currentInstruction[1].u.operand;
     503    unsigned op1 = currentInstruction[2].u.operand;
     504    unsigned op2 = currentInstruction[3].u.operand;
     505
     506    emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
     507    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     508    emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
     509    addSlowCase(joSub32(X86::edx, X86::eax));
     510    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     511
     512    emitPutVirtualRegister(result);
     513}
     514void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     515{
     516    unsigned result = currentInstruction[1].u.operand;
     517    unsigned op1 = currentInstruction[2].u.operand;
     518    unsigned op2 = currentInstruction[3].u.operand;
     519
     520    linkSlowCase(iter);
     521    linkSlowCase(iter);
     522    linkSlowCase(iter);
     523    emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     524    emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     525    emitCTICall(Interpreter::cti_op_sub);
     526
     527    emitPutVirtualRegister(result);
    489528}
    490529
     
    763802}
    764803
     804void JIT::compileFastArith_op_add(Instruction* currentInstruction)
     805{
     806    unsigned result = currentInstruction[1].u.operand;
     807    unsigned op1 = currentInstruction[2].u.operand;
     808    unsigned op2 = currentInstruction[3].u.operand;
     809
     810    if (isOperandConstantImmediateInt(op1)) {
     811        emitGetVirtualRegister(op2, X86::eax);
     812        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     813        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax));
     814        signExtend32ToPtr(X86::eax, X86::eax);
     815        emitPutVirtualRegister(result);
     816    } else if (isOperandConstantImmediateInt(op2)) {
     817        emitGetVirtualRegister(op1, X86::eax);
     818        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     819        addSlowCase(joAdd32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax));
     820        signExtend32ToPtr(X86::eax, X86::eax);
     821        emitPutVirtualRegister(result);
     822    } else {
     823        OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     824        if (types.first().mightBeNumber() && types.second().mightBeNumber())
     825            compileBinaryArithOp(op_add, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
     826        else {
     827            emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     828            emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     829            emitCTICall(Interpreter::cti_op_add);
     830            emitPutVirtualRegister(result);
     831        }
     832    }
     833}
     834void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     835{
     836    unsigned result = currentInstruction[1].u.operand;
     837    unsigned op1 = currentInstruction[2].u.operand;
     838    unsigned op2 = currentInstruction[3].u.operand;
     839
     840    if (isOperandConstantImmediateInt(op1)) {
     841        Jump notImm = getSlowCase(iter);
     842        linkSlowCase(iter);
     843        sub32(Imm32(getConstantOperandImmediateInt(op1) << JSImmediate::IntegerPayloadShift), X86::eax);
     844        notImm.link(this);
     845        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     846        emitPutJITStubArg(X86::eax, 2);
     847        emitCTICall(Interpreter::cti_op_add);
     848        emitPutVirtualRegister(result);
     849    } else if (isOperandConstantImmediateInt(op2)) {
     850        Jump notImm = getSlowCase(iter);
     851        linkSlowCase(iter);
     852        sub32(Imm32(getConstantOperandImmediateInt(op2) << JSImmediate::IntegerPayloadShift), X86::eax);
     853        notImm.link(this);
     854        emitPutJITStubArg(X86::eax, 1);
     855        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     856        emitCTICall(Interpreter::cti_op_add);
     857        emitPutVirtualRegister(result);
     858    } else {
     859        OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     860        ASSERT(types.first().mightBeNumber() && types.second().mightBeNumber());
     861        compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);
     862    }
     863}
     864
     865void JIT::compileFastArith_op_mul(Instruction* currentInstruction)
     866{
     867    unsigned result = currentInstruction[1].u.operand;
     868    unsigned op1 = currentInstruction[2].u.operand;
     869    unsigned op2 = currentInstruction[3].u.operand;
     870
     871    // For now, only plant a fast int case if the constant operand is greater than zero.
     872    int32_t value;
     873    if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {
     874        emitGetVirtualRegister(op2, X86::eax);
     875        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     876        emitFastArithDeTagImmediate(X86::eax);
     877        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
     878        signExtend32ToPtr(X86::eax, X86::eax);
     879        emitFastArithReTagImmediate(X86::eax, X86::eax);
     880        emitPutVirtualRegister(result);
     881    } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {
     882        emitGetVirtualRegister(op1, X86::eax);
     883        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     884        emitFastArithDeTagImmediate(X86::eax);
     885        addSlowCase(joMul32(Imm32(value), X86::eax, X86::eax));
     886        signExtend32ToPtr(X86::eax, X86::eax);
     887        emitFastArithReTagImmediate(X86::eax, X86::eax);
     888        emitPutVirtualRegister(result);
     889    } else
     890        compileBinaryArithOp(op_mul, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
     891}
     892void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     893{
     894    unsigned result = currentInstruction[1].u.operand;
     895    unsigned op1 = currentInstruction[2].u.operand;
     896    unsigned op2 = currentInstruction[3].u.operand;
     897
     898    if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))
     899        || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {
     900        linkSlowCase(iter);
     901        linkSlowCase(iter);
     902        // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
     903        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);
     904        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     905        emitCTICall(Interpreter::cti_op_mul);
     906        emitPutVirtualRegister(result);
     907    } else
     908        compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, OperandTypes::fromInt(currentInstruction[4].u.operand));
     909}
     910
     911void JIT::compileFastArith_op_sub(Instruction* currentInstruction)
     912{
     913    compileBinaryArithOp(op_sub, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
     914}
     915void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     916{
     917    compileBinaryArithOpSlowCase(op_sub, iter, currentInstruction[1].u.operand, currentInstruction[2].u.operand, currentInstruction[3].u.operand, OperandTypes::fromInt(currentInstruction[4].u.operand));
     918}
     919
    765920#endif
    766921
Note: See TracChangeset for help on using the changeset viewer.