summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r--Source/JavaScriptCore/assembler/AbstractMacroAssembler.h9
-rw-r--r--Source/JavaScriptCore/assembler/MIPSAssembler.h59
-rw-r--r--Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h4
-rw-r--r--Source/JavaScriptCore/dfg/DFGFixupPhase.cpp2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp61
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h2
-rw-r--r--Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp20
-rw-r--r--Source/JavaScriptCore/jit/ExecutableAllocator.h2
8 files changed, 101 insertions, 58 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/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
index 03ef23ba7..7e49e9fd6 100644
--- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
@@ -730,35 +730,6 @@ public:
// writable region of memory; to modify the code in an execute-only execuable
// pool the 'repatch' and 'relink' methods should be used.
- static size_t linkDirectJump(void* code, void* to)
- {
- MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code));
- size_t ops = 0;
- int32_t slotAddr = reinterpret_cast<int>(insn) + 4;
- int32_t toAddr = reinterpret_cast<int>(to);
-
- if ((slotAddr & 0xf0000000) != (toAddr & 0xf0000000)) {
- // lui
- *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((toAddr >> 16) & 0xffff);
- ++insn;
- // ori
- *insn = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (toAddr & 0xffff);
- ++insn;
- // jr
- *insn = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
- ++insn;
- ops = 4 * sizeof(MIPSWord);
- } else {
- // j
- *insn = 0x08000000 | ((toAddr & 0x0fffffff) >> 2);
- ++insn;
- ops = 2 * sizeof(MIPSWord);
- }
- // nop
- *insn = 0x00000000;
- return ops;
- }
-
void linkJump(AssemblerLabel from, AssemblerLabel to)
{
ASSERT(to.isSet());
@@ -898,34 +869,42 @@ public:
static ptrdiff_t maxJumpReplacementSize()
{
- return sizeof(MIPSWord) * 4;
+ return sizeof(MIPSWord) * 2;
}
static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
{
MIPSWord* insn = static_cast<MIPSWord*>(instructionStart);
- size_t codeSize = 2 * sizeof(MIPSWord);
// lui
*insn = 0x3c000000 | (rt << OP_SH_RT) | ((imm >> 16) & 0xffff);
++insn;
// ori
*insn = 0x34000000 | (rt << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff);
- ++insn;
- // if jr $t9
- if (*insn == 0x03200008) {
- *insn = 0x00000000;
- codeSize += sizeof(MIPSWord);
- }
- cacheFlush(insn, codeSize);
+ cacheFlush(insn, 2 * sizeof(MIPSWord));
+ }
+
+ static bool canJumpWithJ(void* instructionStart, void* to)
+ {
+ intptr_t slotAddr = reinterpret_cast<intptr_t>(instructionStart) + 4;
+ intptr_t toAddr = reinterpret_cast<intptr_t>(to);
+ return (slotAddr & 0xf0000000) == (toAddr & 0xf0000000);
}
static void replaceWithJump(void* instructionStart, void* to)
{
ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 3));
ASSERT(!(bitwise_cast<uintptr_t>(to) & 3));
- size_t ops = linkDirectJump(instructionStart, to);
- cacheFlush(instructionStart, ops);
+ ASSERT(canJumpWithJ(instructionStart, to));
+ MIPSWord* insn = reinterpret_cast<MIPSWord*>(instructionStart);
+ int32_t toAddr = reinterpret_cast<int32_t>(to);
+
+ // j <to>
+ *insn = 0x08000000 | ((toAddr & 0x0fffffff) >> 2);
+ ++insn;
+ // nop
+ *insn = 0x00000000;
+ cacheFlush(instructionStart, 2 * sizeof(MIPSWord));
}
static void replaceWithLoad(void* instructionStart)
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
index 669021965..754e5cf4e 100644
--- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -2538,8 +2538,6 @@ public:
Jump branchEqual(RegisterID rs, RegisterID rt)
{
- m_assembler.nop();
- m_assembler.nop();
m_assembler.appendJump();
m_assembler.beq(rs, rt, 0);
m_assembler.nop();
@@ -2549,8 +2547,6 @@ public:
Jump branchNotEqual(RegisterID rs, RegisterID rt)
{
- m_assembler.nop();
- m_assembler.nop();
m_assembler.appendJump();
m_assembler.bne(rs, rt, 0);
m_assembler.nop();
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..0957f0eab 100644
--- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
@@ -421,8 +421,7 @@ void SpeculativeJIT::nonSpeculativeNonPeepholeCompareNull(Edge operand, bool inv
notCell.link(&m_jit);
// null or undefined?
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
- m_jit.move(argTagGPR, resultPayloadGPR);
- m_jit.or32(TrustedImm32(1), resultPayloadGPR);
+ m_jit.or32(TrustedImm32(1), argTagGPR, resultPayloadGPR);
m_jit.compare32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultPayloadGPR, TrustedImm32(JSValue::NullTag), resultPayloadGPR);
done.link(&m_jit);
@@ -483,8 +482,7 @@ void SpeculativeJIT::nonSpeculativePeepholeBranchNull(Edge operand, Node* branch
notCell.link(&m_jit);
// null or undefined?
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
- m_jit.move(argTagGPR, resultGPR);
- m_jit.or32(TrustedImm32(1), resultGPR);
+ m_jit.or32(TrustedImm32(1), argTagGPR, resultGPR);
branch32(invert ? JITCompiler::NotEqual : JITCompiler::Equal, resultGPR, JITCompiler::TrustedImm32(JSValue::NullTag), taken);
}
@@ -1422,8 +1420,7 @@ void SpeculativeJIT::compileObjectToObjectOrOtherEquality(Edge leftChild, Edge r
// We know that within this branch, rightChild must not be a cell. Check if that is enough to
// prove that it is either null or undefined.
if (needsTypeCheck(rightChild, SpecCell | SpecOther)) {
- m_jit.move(op2TagGPR, resultGPR);
- m_jit.or32(TrustedImm32(1), resultGPR);
+ m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
typeCheck(
JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
@@ -1531,8 +1528,7 @@ void SpeculativeJIT::compilePeepHoleObjectToObjectOrOtherEquality(Edge leftChild
jump(notTaken, ForceJump);
rightNotCell.link(&m_jit);
- m_jit.move(op2TagGPR, resultGPR);
- m_jit.or32(TrustedImm32(1), resultGPR);
+ m_jit.or32(TrustedImm32(1), op2TagGPR, resultGPR);
typeCheck(
JSValueRegs(op2TagGPR, op2PayloadGPR), rightChild, SpecCell | SpecOther,
@@ -1653,8 +1649,7 @@ void SpeculativeJIT::compileObjectOrOtherLogicalNot(Edge nodeUse)
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
- m_jit.move(valueTagGPR, resultPayloadGPR);
- m_jit.or32(TrustedImm32(1), resultPayloadGPR);
+ m_jit.or32(TrustedImm32(1), valueTagGPR, resultPayloadGPR);
typeCheck(
JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
m_jit.branch32(
@@ -1778,8 +1773,7 @@ void SpeculativeJIT::emitObjectOrOtherBranch(Edge nodeUse, BlockIndex taken, Blo
COMPILE_ASSERT((JSValue::UndefinedTag | 1) == JSValue::NullTag, UndefinedTag_OR_1_EQUALS_NullTag);
if (needsTypeCheck(nodeUse, SpecCell | SpecOther)) {
- m_jit.move(valueTagGPR, scratchGPR);
- m_jit.or32(TrustedImm32(1), scratchGPR);
+ m_jit.or32(TrustedImm32(1), valueTagGPR, scratchGPR);
typeCheck(
JSValueRegs(valueTagGPR, valuePayloadGPR), nodeUse, SpecCell | SpecOther,
m_jit.branch32(MacroAssembler::NotEqual, scratchGPR, TrustedImm32(JSValue::NullTag)));
@@ -2255,6 +2249,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
diff --git a/Source/JavaScriptCore/jit/ExecutableAllocator.h b/Source/JavaScriptCore/jit/ExecutableAllocator.h
index 0ec4668fd..42e1f9594 100644
--- a/Source/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/Source/JavaScriptCore/jit/ExecutableAllocator.h
@@ -102,7 +102,7 @@ class DemandExecutableAllocator;
#endif
#if ENABLE(EXECUTABLE_ALLOCATOR_FIXED)
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
static const size_t fixedExecutableMemoryPoolSize = 16 * 1024 * 1024;
#elif CPU(X86_64) && !CPU(X32)
static const size_t fixedExecutableMemoryPoolSize = 1024 * 1024 * 1024;