⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jitarithmetic.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    addSlowCase(branchSub32(Zero, Imm32(1), regT0));    emitFastArithIntToImmNoCheck(regT0, regT0);#else    addSlowCase(branchSub32(Zero, Imm32(1 << JSImmediate::IntegerPayloadShift), regT0));    signExtend32ToPtr(regT0, regT0);#endif    emitPutVirtualRegister(srcDst);}void JIT::compileFastArithSlow_op_pre_dec(unsigned srcDst, Vector<SlowCaseEntry>::iterator& iter){    Jump notImm = getSlowCase(iter);    linkSlowCase(iter);    emitGetVirtualRegister(srcDst, regT0);    notImm.link(this);    emitPutJITStubArg(regT0, 1);    emitCTICall(JITStubs::cti_op_pre_dec);    emitPutVirtualRegister(srcDst);}#if !ENABLE(JIT_OPTIMIZE_ARITHMETIC)void JIT::compileFastArith_op_add(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);    emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);    emitCTICall(JITStubs::cti_op_add);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_add(Instruction*, Vector<SlowCaseEntry>::iterator&){    ASSERT_NOT_REACHED();}void JIT::compileFastArith_op_mul(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);    emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);    emitCTICall(JITStubs::cti_op_mul);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_mul(Instruction*, Vector<SlowCaseEntry>::iterator&){    ASSERT_NOT_REACHED();}void JIT::compileFastArith_op_sub(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    emitPutJITStubArgFromVirtualRegister(op1, 1, regT2);    emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);    emitCTICall(JITStubs::cti_op_sub);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_sub(Instruction*, Vector<SlowCaseEntry>::iterator&){    ASSERT_NOT_REACHED();}#elif USE(ALTERNATE_JSIMMEDIATE) // *AND* ENABLE(JIT_OPTIMIZE_ARITHMETIC)void JIT::compileBinaryArithOp(OpcodeID opcodeID, unsigned, unsigned op1, unsigned op2, OperandTypes){    emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);    emitJumpSlowCaseIfNotImmediateInteger(X86::eax);    emitJumpSlowCaseIfNotImmediateInteger(X86::edx);    if (opcodeID == op_add)        addSlowCase(branchAdd32(Overflow, X86::edx, X86::eax));    else if (opcodeID == op_sub)        addSlowCase(branchSub32(Overflow, X86::edx, X86::eax));    else {        ASSERT(opcodeID == op_mul);        addSlowCase(branchMul32(Overflow, X86::edx, X86::eax));        addSlowCase(branchTest32(Zero, X86::eax));    }    emitFastArithIntToImmNoCheck(X86::eax, X86::eax);}void JIT::compileBinaryArithOpSlowCase(OpcodeID opcodeID, Vector<SlowCaseEntry>::iterator& iter, unsigned, unsigned op1, unsigned, OperandTypes types){    // We assume that subtracting TagTypeNumber is equivalent to adding DoubleEncodeOffset.    COMPILE_ASSERT(((JSImmediate::TagTypeNumber + JSImmediate::DoubleEncodeOffset) == 0), TagTypeNumber_PLUS_DoubleEncodeOffset_EQUALS_0);    Jump notImm1 = getSlowCase(iter);    Jump notImm2 = getSlowCase(iter);    linkSlowCase(iter); // Integer overflow case - we could handle this in JIT code, but this is likely rare.    if (opcodeID == op_mul) // op_mul has an extra slow case to handle 0 * negative number.        linkSlowCase(iter);    emitGetVirtualRegister(op1, X86::eax);    Label stubFunctionCall(this);    emitPutJITStubArg(X86::eax, 1);    emitPutJITStubArg(X86::edx, 2);    if (opcodeID == op_add)        emitCTICall(JITStubs::cti_op_add);    else if (opcodeID == op_sub)        emitCTICall(JITStubs::cti_op_sub);    else {        ASSERT(opcodeID == op_mul);        emitCTICall(JITStubs::cti_op_mul);    }    Jump end = jump();    // if we get here, eax is not an int32, edx not yet checked.    notImm1.link(this);    if (!types.first().definitelyIsNumber())        emitJumpIfNotImmediateNumber(X86::eax).linkTo(stubFunctionCall, this);    if (!types.second().definitelyIsNumber())        emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);    addPtr(tagTypeNumberRegister, X86::eax);    m_assembler.movq_rr(X86::eax, X86::xmm1);    Jump op2isDouble = emitJumpIfNotImmediateInteger(X86::edx);    m_assembler.cvtsi2sd_rr(X86::edx, X86::xmm2);    Jump op2wasInteger = jump();    // if we get here, eax IS an int32, edx is not.    notImm2.link(this);    if (!types.second().definitelyIsNumber())        emitJumpIfNotImmediateNumber(X86::edx).linkTo(stubFunctionCall, this);    m_assembler.cvtsi2sd_rr(X86::eax, X86::xmm1);    op2isDouble.link(this);    addPtr(tagTypeNumberRegister, X86::edx);    m_assembler.movq_rr(X86::edx, X86::xmm2);    op2wasInteger.link(this);    if (opcodeID == op_add)        m_assembler.addsd_rr(X86::xmm2, X86::xmm1);    else if (opcodeID == op_sub)        m_assembler.subsd_rr(X86::xmm2, X86::xmm1);    else {        ASSERT(opcodeID == op_mul);        m_assembler.mulsd_rr(X86::xmm2, X86::xmm1);    }    m_assembler.movq_rr(X86::xmm1, X86::eax);    subPtr(tagTypeNumberRegister, X86::eax);    end.link(this);}void JIT::compileFastArith_op_add(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    if (!types.first().mightBeNumber() || !types.second().mightBeNumber()) {        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);        emitCTICall(JITStubs::cti_op_add);        emitPutVirtualRegister(result);        return;    }    if (isOperandConstantImmediateInt(op1)) {        emitGetVirtualRegister(op2, X86::eax);        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op1)), X86::eax));        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);    } else if (isOperandConstantImmediateInt(op2)) {        emitGetVirtualRegister(op1, X86::eax);        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);        addSlowCase(branchAdd32(Overflow, Imm32(getConstantOperandImmediateInt(op2)), X86::eax));        emitFastArithIntToImmNoCheck(X86::eax, X86::eax);    } else        compileBinaryArithOp(op_add, result, op1, op2, types);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_add(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    if (isOperandConstantImmediateInt(op1)) {        linkSlowCase(iter);        linkSlowCase(iter);        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);        emitCTICall(JITStubs::cti_op_add);    } else if (isOperandConstantImmediateInt(op2)) {        linkSlowCase(iter);        linkSlowCase(iter);        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);        emitCTICall(JITStubs::cti_op_add);    } else        compileBinaryArithOpSlowCase(op_add, iter, result, op1, op2, types);    emitPutVirtualRegister(result);}void JIT::compileFastArith_op_mul(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    // For now, only plant a fast int case if the constant operand is greater than zero.    int32_t value;    if (isOperandConstantImmediateInt(op1) && ((value = getConstantOperandImmediateInt(op1)) > 0)) {        emitGetVirtualRegister(op2, X86::eax);        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);        addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));        emitFastArithReTagImmediate(X86::eax, X86::eax);    } else if (isOperandConstantImmediateInt(op2) && ((value = getConstantOperandImmediateInt(op2)) > 0)) {        emitGetVirtualRegister(op1, X86::eax);        emitJumpSlowCaseIfNotImmediateInteger(X86::eax);        addSlowCase(branchMul32(Overflow, Imm32(value), X86::eax, X86::eax));        emitFastArithReTagImmediate(X86::eax, X86::eax);    } else        compileBinaryArithOp(op_mul, result, op1, op2, types);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_mul(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    if ((isOperandConstantImmediateInt(op1) && (getConstantOperandImmediateInt(op1) > 0))        || (isOperandConstantImmediateInt(op2) && (getConstantOperandImmediateInt(op2) > 0))) {        linkSlowCase(iter);        linkSlowCase(iter);        // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.        emitPutJITStubArgFromVirtualRegister(op1, 1, X86::ecx);        emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);        emitCTICall(JITStubs::cti_op_mul);    } else        compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);    emitPutVirtualRegister(result);}void JIT::compileFastArith_op_sub(Instruction* currentInstruction){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    compileBinaryArithOp(op_sub, result, op1, op2, types);    emitPutVirtualRegister(result);}void JIT::compileFastArithSlow_op_sub(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter){    unsigned result = currentInstruction[1].u.operand;    unsigned op1 = currentInstruction[2].u.operand;    unsigned op2 = currentInstruction[3].u.operand;    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);    compileBinaryArithOpSlowCase(op_sub, iter, result, op1, op2, types);    emitPutVirtualRegister(result);}#elsetypedef X86Assembler::JmpSrc JmpSrc;typedef X86Assembler::JmpDst JmpDst;typedef X86Assembler::XMMRegisterID XMMRegisterID;#if PLATFORM(MAC)static inline bool isSSE2Present(){    return true; // All X86 Macs are guaranteed to support at least SSE2}#elsestatic bool isSSE2Present(){    static const int SSE2FeatureBit = 1 << 26;    struct SSE2Check {        SSE2Check()        {            int flags;#if COMPILER(MSVC)            _asm {                mov eax, 1 // cpuid function 1 gives us the standard feature set                cpuid;                mov flags, edx;            }#elif COMPILER(GCC)            asm (                "movl $0x1, %%eax;"                "pushl %%ebx;"                "cpuid;"                "popl %%ebx;"                "movl %%edx, %0;"                : "=g" (flags)                :                : "%eax", "%ecx", "%edx"            );#else            flags = 0;#endif            present = (flags & SSE2FeatureBit) != 0;        }        bool present;    };    static SSE2Check check;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -