Ignore:
Timestamp:
Sep 24, 2009, 7:40:59 PM (16 years ago)
Author:
[email protected]
Message:

Division is needlessly slow in 64-bit
https://bugs.webkit.org/show_bug.cgi?id=29723

Reviewed by Gavin Barraclough.

Add codegen for op_div on x86-64

File:
1 edited

Legend:

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

    r47530 r48744  
    19791979    else if (opcodeID == op_sub)
    19801980        subDouble(fpRegT2, fpRegT1);
     1981    else if (opcodeID == op_mul)
     1982        mulDouble(fpRegT2, fpRegT1);
    19811983    else {
    1982         ASSERT(opcodeID == op_mul);
    1983         mulDouble(fpRegT2, fpRegT1);
     1984        ASSERT(opcodeID == op_div);
     1985        divDouble(fpRegT2, fpRegT1);
    19841986    }
    19851987    moveDoubleToPtr(fpRegT1, regT0);
     
    20812083    } else
    20822084        compileBinaryArithOpSlowCase(op_mul, iter, result, op1, op2, types);
     2085}
     2086
     2087void JIT::emit_op_div(Instruction* currentInstruction)
     2088{
     2089    unsigned dst = currentInstruction[1].u.operand;
     2090    unsigned op1 = currentInstruction[2].u.operand;
     2091    unsigned op2 = currentInstruction[3].u.operand;
     2092    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     2093
     2094    if (isOperandConstantImmediateDouble(op1)) {
     2095        emitGetVirtualRegister(op1, regT0);
     2096        addPtr(tagTypeNumberRegister, regT0);
     2097        movePtrToDouble(regT0, fpRegT0);
     2098    } else if (isOperandConstantImmediateInt(op1)) {
     2099        emitLoadInt32ToDouble(op1, fpRegT0);
     2100    } else {
     2101        emitGetVirtualRegister(op1, regT0);
     2102        if (!types.first().definitelyIsNumber())
     2103            emitJumpSlowCaseIfNotImmediateNumber(regT0);
     2104        Jump notInt = emitJumpIfNotImmediateInteger(regT0);
     2105        convertInt32ToDouble(regT0, fpRegT0);
     2106        Jump skipDoubleLoad = jump();
     2107        notInt.link(this);
     2108        addPtr(tagTypeNumberRegister, regT0);
     2109        movePtrToDouble(regT0, fpRegT0);
     2110        skipDoubleLoad.link(this);
     2111    }
     2112   
     2113    if (isOperandConstantImmediateDouble(op2)) {
     2114        emitGetVirtualRegister(op2, regT1);
     2115        addPtr(tagTypeNumberRegister, regT1);
     2116        movePtrToDouble(regT1, fpRegT1);
     2117    } else if (isOperandConstantImmediateInt(op2)) {
     2118        emitLoadInt32ToDouble(op2, fpRegT1);
     2119    } else {
     2120        emitGetVirtualRegister(op2, regT1);
     2121        if (!types.second().definitelyIsNumber())
     2122            emitJumpSlowCaseIfNotImmediateNumber(regT1);
     2123        Jump notInt = emitJumpIfNotImmediateInteger(regT1);
     2124        convertInt32ToDouble(regT1, fpRegT1);
     2125        Jump skipDoubleLoad = jump();
     2126        notInt.link(this);
     2127        addPtr(tagTypeNumberRegister, regT1);
     2128        movePtrToDouble(regT1, fpRegT1);
     2129        skipDoubleLoad.link(this);
     2130    }
     2131    divDouble(fpRegT1, fpRegT0);
     2132
     2133    JumpList doubleResult;
     2134    Jump end;
     2135    bool attemptIntConversion = (!isOperandConstantImmediateInt(op1) || getConstantOperand(op1).asInt32() > 1) && isOperandConstantImmediateInt(op2);
     2136    if (attemptIntConversion) {
     2137        m_assembler.cvttsd2si_rr(fpRegT0, regT0);
     2138        doubleResult.append(branchTest32(Zero, regT0));
     2139        m_assembler.ucomisd_rr(fpRegT1, fpRegT0);
     2140       
     2141        doubleResult.append(m_assembler.jne());
     2142        doubleResult.append(m_assembler.jp());
     2143        emitFastArithIntToImmNoCheck(regT0, regT0);
     2144        end = jump();
     2145    }
     2146
     2147    // Double result.
     2148    doubleResult.link(this);
     2149    moveDoubleToPtr(fpRegT0, regT0);
     2150    subPtr(tagTypeNumberRegister, regT0);
     2151
     2152    if (attemptIntConversion)
     2153        end.link(this);
     2154    emitPutVirtualRegister(dst, regT0);
     2155}
     2156
     2157void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>::iterator& iter)
     2158{
     2159    unsigned result = currentInstruction[1].u.operand;
     2160    unsigned op1 = currentInstruction[2].u.operand;
     2161    unsigned op2 = currentInstruction[3].u.operand;
     2162    OperandTypes types = OperandTypes::fromInt(currentInstruction[4].u.operand);
     2163    if (types.first().definitelyIsNumber() && types.second().definitelyIsNumber()) {
     2164#ifndef NDEBUG
     2165        breakpoint();
     2166#endif
     2167        return;
     2168    }
     2169    if (!isOperandConstantImmediateDouble(op1) && !isOperandConstantImmediateInt(op1)) {
     2170        if (!types.first().definitelyIsNumber())
     2171            linkSlowCase(iter);
     2172    }
     2173    if (!isOperandConstantImmediateDouble(op2) && !isOperandConstantImmediateInt(op2)) {
     2174        if (!types.second().definitelyIsNumber())
     2175            linkSlowCase(iter);
     2176    }
     2177    // There is an extra slow case for (op1 * -N) or (-N * op2), to check for 0 since this should produce a result of -0.
     2178    JITStubCall stubCall(this, cti_op_div);
     2179    stubCall.addArgument(op1, regT2);
     2180    stubCall.addArgument(op2, regT2);
     2181    stubCall.call(result);
    20832182}
    20842183
Note: See TracChangeset for help on using the changeset viewer.