diff options
Diffstat (limited to 'Source/JavaScriptCore')
-rw-r--r-- | Source/JavaScriptCore/assembler/AbstractMacroAssembler.h | 9 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/MIPSAssembler.h | 59 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h | 4 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGFixupPhase.cpp | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp | 61 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 2 | ||||
-rw-r--r-- | Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp | 20 | ||||
-rw-r--r-- | Source/JavaScriptCore/jit/ExecutableAllocator.h | 2 |
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; |