summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp')
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp58
1 files changed, 58 insertions, 0 deletions
diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
index de2025ada..8c3c40d1e 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
@@ -4014,6 +4014,46 @@ void SpeculativeJIT::compileArithDiv(Node* node)
}
int32Result(quotient.gpr(), node);
+#elif CPU(MIPS)
+ SpeculateInt32Operand op1(this, node->child1());
+ SpeculateInt32Operand 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 (!bytecodeCanIgnoreNegativeZero(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 (bytecodeUsesAsNumber(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 (bytecodeUsesAsNumber(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);
+
+ int32Result(quotientGPR, node);
#else
RELEASE_ASSERT_NOT_REACHED();
#endif
@@ -4394,6 +4434,24 @@ void SpeculativeJIT::compileArithMod(Node* node)
done.link(&m_jit);
int32Result(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 (!bytecodeCanIgnoreNegativeZero(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);
+ }
+
+ int32Result(remainderGPR, node);
#else // not architecture that can do integer division
RELEASE_ASSERT_NOT_REACHED();
#endif