diff options
author | Julien Brianceau <jbriance@cisco.com> | 2014-08-22 11:09:51 +0200 |
---|---|---|
committer | Julien Brianceau <jbriance@cisco.com> | 2014-08-23 02:16:21 +0200 |
commit | 8fc64042dfdf7e3ef050f9b64cb77e90f549de32 (patch) | |
tree | c3e9cc0fe42384a4878700736602635be86f4f1d /Source/JavaScriptCore | |
parent | 84f3a89974631f015d7ab6c82e6fbb84c72fb5f1 (diff) | |
download | qtwebkit-8fc64042dfdf7e3ef050f9b64cb77e90f549de32.tar.gz |
[mips] Take advantage of integer divide instruction for ArithDiv and ArithMod.
Added MIPS integer divide path for ArithDiv and ArithMod where operands and results are integer.
Change-Id: I00d5b58e6e0be39f083676fb0c435b3545d3aca1
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore')
5 files changed, 75 insertions, 1 deletions
diff --git a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h index 1861dc15c..09a688804 100644 --- a/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h +++ b/Source/JavaScriptCore/assembler/AbstractMacroAssembler.h @@ -54,6 +54,15 @@ inline bool isARMv7s() #endif } +inline bool isMIPS() +{ +#if CPU(MIPS) + return true; +#else + return false; +#endif +} + inline bool isX86() { #if CPU(X86_64) || CPU(X86) diff --git a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp index ea201d73b..0bbd3f20f 100644 --- a/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp +++ b/Source/JavaScriptCore/dfg/DFGFixupPhase.cpp @@ -214,7 +214,7 @@ private: case ArithDiv: { if (Node::shouldSpeculateIntegerForArithmetic(node->child1().node(), node->child2().node()) && node->canSpeculateInteger()) { - if (isX86() || isARMv7s()) { + if (isX86() || isARMv7s() || isMIPS()) { setUseKindAndUnboxIfProfitable<Int32Use>(node->child1()); setUseKindAndUnboxIfProfitable<Int32Use>(node->child2()); break; diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp index 1348f94be..71fd99a04 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp @@ -3042,6 +3042,24 @@ void SpeculativeJIT::compileSoftModulo(Node* node) } integerResult(quotientThenRemainderGPR, node); +#elif CPU(MIPS) + GPRTemporary remainder(this); + GPRReg dividendGPR = op1.gpr(); + GPRReg divisorGPR = op2.gpr(); + GPRReg remainderGPR = remainder.gpr(); + + speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, dividendGPR, TrustedImm32(-2147483647-1))); + m_jit.assembler().div(dividendGPR, divisorGPR); + m_jit.assembler().mfhi(remainderGPR); + + if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { + // Check that we're not about to create negative zero. + JITCompiler::Jump numeratorPositive = m_jit.branch32(JITCompiler::GreaterThanOrEqual, dividendGPR, TrustedImm32(0)); + speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, remainderGPR)); + numeratorPositive.link(&m_jit); + } + + integerResult(remainderGPR, node); #else // not architecture that can do integer division // Do this the *safest* way possible: call out to a C function that will do the modulo, // and then attempt to convert back. @@ -3523,6 +3541,49 @@ void SpeculativeJIT::compileIntegerArithDivForARMv7s(Node* node) integerResult(quotient.gpr(), node); } +#elif CPU(MIPS) +void SpeculativeJIT::compileIntegerArithDivForMIPS(Node* node) +{ + SpeculateIntegerOperand op1(this, node->child1()); + SpeculateIntegerOperand op2(this, node->child2()); + GPRTemporary quotient(this); + GPRReg op1GPR = op1.gpr(); + GPRReg op2GPR = op2.gpr(); + GPRReg quotientGPR = quotient.gpr(); + JITCompiler::Jump done; + + // If the user cares about negative zero, then speculate that we're not about + // to produce negative zero. + if (!nodeCanIgnoreNegativeZero(node->arithNodeFlags())) { + MacroAssembler::Jump numeratorNonZero = m_jit.branchTest32(MacroAssembler::NonZero, op1GPR); + speculationCheck(NegativeZero, JSValueRegs(), 0, m_jit.branch32(MacroAssembler::LessThan, op2GPR, TrustedImm32(0))); + numeratorNonZero.link(&m_jit); + } + + if (nodeUsedAsNumber(node->arithNodeFlags())) { + speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(JITCompiler::Zero, op2GPR)); + speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branch32(JITCompiler::Equal, op1GPR, TrustedImm32(-2147483647-1))); + } else { + JITCompiler::Jump notZero = m_jit.branchTest32(JITCompiler::NonZero, op2GPR); + m_jit.move(TrustedImm32(0), quotientGPR); + done = m_jit.jump(); + notZero.link(&m_jit); + } + + m_jit.assembler().div(op1GPR, op2GPR); + m_jit.assembler().mflo(quotientGPR); + + // Check that there was no remainder. If there had been, then we'd be obligated to + // produce a double result instead. + if (nodeUsedAsNumber(node->arithNodeFlags())) { + GPRTemporary remainder(this); + m_jit.assembler().mfhi(remainder.gpr()); + speculationCheck(Overflow, JSValueRegs(), 0, m_jit.branchTest32(MacroAssembler::NonZero, remainder.gpr())); + } else + done.link(&m_jit); + + integerResult(quotientGPR, node); +} #endif void SpeculativeJIT::compileArithMod(Node* node) diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h index 54f736600..f4e80996e 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h @@ -1994,6 +1994,8 @@ public: void compileIntegerArithDivForX86(Node*); #elif CPU(APPLE_ARMV7S) void compileIntegerArithDivForARMv7s(Node*); +#elif CPU(MIPS) + void compileIntegerArithDivForMIPS(Node*); #endif void compileArithMod(Node*); void compileSoftModulo(Node*); diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp index 871a59c2a..4a75cbdba 100644 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp @@ -2255,6 +2255,8 @@ void SpeculativeJIT::compile(Node* node) compileIntegerArithDivForX86(node); #elif CPU(APPLE_ARMV7S) compileIntegerArithDivForARMv7s(node); +#elif CPU(MIPS) + compileIntegerArithDivForMIPS(node); #else // CPU type without integer divide RELEASE_ASSERT_NOT_REACHED(); // should have been coverted into a double divide. #endif |