Skip to content
Permalink
Browse files
2010-10-27 Chao-ying Fu <fu@mips.com>
        Reviewed by Oliver Hunt.

        Support emit_op_mod() for MIPS on JSVALUE32_64
        https://bugs.webkit.org/show_bug.cgi?id=46511

        This patch uses MIPS div instructions for op_mod to improve performance.

        * jit/JITArithmetic32_64.cpp:
        (JSC::JIT::emit_op_mod):

Canonical link: https://commits.webkit.org/61252@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@70736 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
webkit-commit-queue committed Oct 28, 2010
1 parent 57589ca commit a44c72b7fb87a9eeedb76241d6b385babd781680
Showing 2 changed files with 41 additions and 16 deletions.
@@ -1,3 +1,15 @@
2010-10-27 Chao-ying Fu <fu@mips.com>

Reviewed by Oliver Hunt.

Support emit_op_mod() for MIPS on JSVALUE32_64
https://bugs.webkit.org/show_bug.cgi?id=46511

This patch uses MIPS div instructions for op_mod to improve performance.

* jit/JITArithmetic32_64.cpp:
(JSC::JIT::emit_op_mod):

2010-10-27 Brent Fulgham <bfulgham@webkit.org>

Unreviewed build correction.
@@ -1293,42 +1293,55 @@ void JIT::emitSlow_op_div(Instruction* currentInstruction, Vector<SlowCaseEntry>

/* ------------------------------ BEGIN: OP_MOD ------------------------------ */

#if CPU(X86) || CPU(X86_64)
#if CPU(X86) || CPU(X86_64) || CPU(MIPS)

void JIT::emit_op_mod(Instruction* currentInstruction)
{
unsigned dst = currentInstruction[1].u.operand;
unsigned op1 = currentInstruction[2].u.operand;
unsigned op2 = currentInstruction[3].u.operand;

#if CPU(X86) || CPU(X86_64)
// Make sure registers are correct for x86 IDIV instructions.
ASSERT(regT0 == X86Registers::eax);
ASSERT(regT1 == X86Registers::edx);
ASSERT(regT2 == X86Registers::ecx);
ASSERT(regT3 == X86Registers::ebx);
#endif

if (isOperandConstantImmediateInt(op2) && getConstantOperand(op2).asInt32() != 0) {
emitLoad(op1, X86Registers::edx, X86Registers::eax);
move(Imm32(getConstantOperand(op2).asInt32()), X86Registers::ecx);
addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
emitLoad(op1, regT1, regT0);
move(Imm32(getConstantOperand(op2).asInt32()), regT2);
addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
if (getConstantOperand(op2).asInt32() == -1)
addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
} else {
emitLoad2(op1, X86Registers::edx, X86Registers::eax, op2, X86Registers::ebx, X86Registers::ecx);
addSlowCase(branch32(NotEqual, X86Registers::edx, Imm32(JSValue::Int32Tag)));
addSlowCase(branch32(NotEqual, X86Registers::ebx, Imm32(JSValue::Int32Tag)));
emitLoad2(op1, regT1, regT0, op2, regT3, regT2);
addSlowCase(branch32(NotEqual, regT1, Imm32(JSValue::Int32Tag)));
addSlowCase(branch32(NotEqual, regT3, Imm32(JSValue::Int32Tag)));

addSlowCase(branch32(Equal, X86Registers::eax, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
addSlowCase(branch32(Equal, X86Registers::ecx, Imm32(0))); // divide by 0
addSlowCase(branch32(Equal, regT0, Imm32(0x80000000))); // -2147483648 / -1 => EXC_ARITHMETIC
addSlowCase(branch32(Equal, regT2, Imm32(0))); // divide by 0
}

move(X86Registers::eax, X86Registers::ebx); // Save dividend payload, in case of 0.
move(regT0, regT3); // Save dividend payload, in case of 0.
#if CPU(X86) || CPU(X86_64)
m_assembler.cdq();
m_assembler.idivl_r(X86Registers::ecx);
m_assembler.idivl_r(regT2);
#elif CPU(MIPS)
m_assembler.div(regT0, regT2);
m_assembler.mfhi(regT1);
#endif

// If the remainder is zero and the dividend is negative, the result is -0.
Jump storeResult1 = branchTest32(NonZero, X86Registers::edx);
Jump storeResult2 = branchTest32(Zero, X86Registers::ebx, Imm32(0x80000000)); // not negative
Jump storeResult1 = branchTest32(NonZero, regT1);
Jump storeResult2 = branchTest32(Zero, regT3, Imm32(0x80000000)); // not negative
emitStore(dst, jsNumber(-0.0));
Jump end = jump();

storeResult1.link(this);
storeResult2.link(this);
emitStoreInt32(dst, X86Registers::edx, (op1 == dst || op2 == dst));
emitStoreInt32(dst, regT1, (op1 == dst || op2 == dst));
end.link(this);
}

@@ -1355,7 +1368,7 @@ void JIT::emitSlow_op_mod(Instruction* currentInstruction, Vector<SlowCaseEntry>
stubCall.call(dst);
}

#else // CPU(X86) || CPU(X86_64)
#else // CPU(X86) || CPU(X86_64) || CPU(MIPS)

void JIT::emit_op_mod(Instruction* currentInstruction)
{

0 comments on commit a44c72b

Please sign in to comment.