|
@@ -1,1490 +0,0 @@
|
|
|
-Upstream patch for DFG implementation for MIPS
|
|
|
-
|
|
|
-Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
|
|
|
-
|
|
|
-From c921d19863ccf66bdd0ffa5d38eaf05efab6b136 Mon Sep 17 00:00:00 2001
|
|
|
-From: "commit-queue@webkit.org"
|
|
|
- <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
|
|
|
-Date: Mon, 18 Feb 2013 19:25:23 +0000
|
|
|
-Subject: [PATCH] MIPS DFG implementation.
|
|
|
- https://bugs.webkit.org/show_bug.cgi?id=101328
|
|
|
-
|
|
|
-Patch by Balazs Kilvady <kilvadyb@homejinni.com> on 2013-02-18
|
|
|
-Reviewed by Oliver Hunt.
|
|
|
-
|
|
|
-DFG implementation for MIPS.
|
|
|
-
|
|
|
-Source/JavaScriptCore:
|
|
|
-
|
|
|
-* assembler/MIPSAssembler.h:
|
|
|
-(JSC::MIPSAssembler::MIPSAssembler):
|
|
|
-(JSC::MIPSAssembler::sllv):
|
|
|
-(JSC::MIPSAssembler::movd):
|
|
|
-(MIPSAssembler):
|
|
|
-(JSC::MIPSAssembler::negd):
|
|
|
-(JSC::MIPSAssembler::labelForWatchpoint):
|
|
|
-(JSC::MIPSAssembler::label):
|
|
|
-(JSC::MIPSAssembler::vmov):
|
|
|
-(JSC::MIPSAssembler::linkDirectJump):
|
|
|
-(JSC::MIPSAssembler::maxJumpReplacementSize):
|
|
|
-(JSC::MIPSAssembler::revertJumpToMove):
|
|
|
-(JSC::MIPSAssembler::replaceWithJump):
|
|
|
-* assembler/MacroAssembler.h:
|
|
|
-(MacroAssembler):
|
|
|
-(JSC::MacroAssembler::poke):
|
|
|
-* assembler/MacroAssemblerMIPS.h:
|
|
|
-(JSC::MacroAssemblerMIPS::add32):
|
|
|
-(MacroAssemblerMIPS):
|
|
|
-(JSC::MacroAssemblerMIPS::and32):
|
|
|
-(JSC::MacroAssemblerMIPS::lshift32):
|
|
|
-(JSC::MacroAssemblerMIPS::mul32):
|
|
|
-(JSC::MacroAssemblerMIPS::or32):
|
|
|
-(JSC::MacroAssemblerMIPS::rshift32):
|
|
|
-(JSC::MacroAssemblerMIPS::urshift32):
|
|
|
-(JSC::MacroAssemblerMIPS::sub32):
|
|
|
-(JSC::MacroAssemblerMIPS::xor32):
|
|
|
-(JSC::MacroAssemblerMIPS::store32):
|
|
|
-(JSC::MacroAssemblerMIPS::jump):
|
|
|
-(JSC::MacroAssemblerMIPS::branchAdd32):
|
|
|
-(JSC::MacroAssemblerMIPS::branchMul32):
|
|
|
-(JSC::MacroAssemblerMIPS::branchSub32):
|
|
|
-(JSC::MacroAssemblerMIPS::branchNeg32):
|
|
|
-(JSC::MacroAssemblerMIPS::call):
|
|
|
-(JSC::MacroAssemblerMIPS::loadDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::moveDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::swapDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::subDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::mulDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::divDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::negateDouble):
|
|
|
-(JSC::MacroAssemblerMIPS::branchEqual):
|
|
|
-(JSC::MacroAssemblerMIPS::branchNotEqual):
|
|
|
-(JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
|
|
|
-(JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32):
|
|
|
-(JSC::MacroAssemblerMIPS::truncateDoubleToInt32):
|
|
|
-(JSC::MacroAssemblerMIPS::truncateDoubleToUint32):
|
|
|
-(JSC::MacroAssemblerMIPS::branchDoubleNonZero):
|
|
|
-(JSC::MacroAssemblerMIPS::branchDoubleZeroOrNaN):
|
|
|
-(JSC::MacroAssemblerMIPS::invert):
|
|
|
-(JSC::MacroAssemblerMIPS::replaceWithJump):
|
|
|
-(JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
|
|
|
-* dfg/DFGAssemblyHelpers.h:
|
|
|
-(AssemblyHelpers):
|
|
|
-(JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
|
|
|
-(JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
|
|
|
-(JSC::DFG::AssemblyHelpers::debugCall):
|
|
|
-* dfg/DFGCCallHelpers.h:
|
|
|
-(CCallHelpers):
|
|
|
-(JSC::DFG::CCallHelpers::setupArguments):
|
|
|
-(JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
|
|
|
-* dfg/DFGFPRInfo.h:
|
|
|
-(DFG):
|
|
|
-(FPRInfo):
|
|
|
-(JSC::DFG::FPRInfo::toRegister):
|
|
|
-(JSC::DFG::FPRInfo::toIndex):
|
|
|
-(JSC::DFG::FPRInfo::debugName):
|
|
|
-* dfg/DFGGPRInfo.h:
|
|
|
-(DFG):
|
|
|
-(GPRInfo):
|
|
|
-(JSC::DFG::GPRInfo::toRegister):
|
|
|
-(JSC::DFG::GPRInfo::toIndex):
|
|
|
-(JSC::DFG::GPRInfo::debugName):
|
|
|
-* dfg/DFGSpeculativeJIT.h:
|
|
|
-(SpeculativeJIT):
|
|
|
-* jit/JSInterfaceJIT.h:
|
|
|
-(JSInterfaceJIT):
|
|
|
-* runtime/JSGlobalData.h:
|
|
|
-(JSC::ScratchBuffer::allocationSize):
|
|
|
-(ScratchBuffer):
|
|
|
-
|
|
|
-Source/WTF:
|
|
|
-
|
|
|
-* wtf/Platform.h:
|
|
|
-
|
|
|
-git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143247 268f45cc-cd09-0410-ab3c-d52691b4dbfc
|
|
|
----
|
|
|
- Source/JavaScriptCore/ChangeLog | 90 ++++
|
|
|
- Source/JavaScriptCore/assembler/MIPSAssembler.h | 109 ++++-
|
|
|
- Source/JavaScriptCore/assembler/MacroAssembler.h | 7 +
|
|
|
- .../JavaScriptCore/assembler/MacroAssemblerMIPS.h | 480 +++++++++++++++++++--
|
|
|
- Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h | 19 +-
|
|
|
- Source/JavaScriptCore/dfg/DFGCCallHelpers.h | 92 ++--
|
|
|
- Source/JavaScriptCore/dfg/DFGFPRInfo.h | 68 +++
|
|
|
- Source/JavaScriptCore/dfg/DFGGPRInfo.h | 67 +++
|
|
|
- Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 4 +-
|
|
|
- Source/JavaScriptCore/jit/JSInterfaceJIT.h | 4 +
|
|
|
- Source/JavaScriptCore/runtime/JSGlobalData.h | 6 +-
|
|
|
- Source/WTF/ChangeLog | 11 +
|
|
|
- Source/WTF/wtf/Platform.h | 4 +
|
|
|
- 13 files changed, 888 insertions(+), 73 deletions(-)
|
|
|
-
|
|
|
-diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
|
|
|
-index 026f87e..7f553bb 100644
|
|
|
---- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
|
|
|
-+++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
|
|
|
-@@ -152,6 +152,8 @@ public:
|
|
|
- typedef SegmentedVector<AssemblerLabel, 64> Jumps;
|
|
|
-
|
|
|
- MIPSAssembler()
|
|
|
-+ : m_indexOfLastWatchpoint(INT_MIN)
|
|
|
-+ , m_indexOfTailOfLastWatchpoint(INT_MIN)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
-@@ -325,7 +327,7 @@ public:
|
|
|
- emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT));
|
|
|
- }
|
|
|
-
|
|
|
-- void sllv(RegisterID rd, RegisterID rt, int rs)
|
|
|
-+ void sllv(RegisterID rd, RegisterID rt, RegisterID rs)
|
|
|
- {
|
|
|
- emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS));
|
|
|
- }
|
|
|
-@@ -527,6 +529,16 @@ public:
|
|
|
- emitInst(0x46200004 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
|
|
|
- }
|
|
|
-
|
|
|
-+ void movd(FPRegisterID fd, FPRegisterID fs)
|
|
|
-+ {
|
|
|
-+ emitInst(0x46200006 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void negd(FPRegisterID fd, FPRegisterID fs)
|
|
|
-+ {
|
|
|
-+ emitInst(0x46200007 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
|
|
|
-+ }
|
|
|
-+
|
|
|
- void truncwd(FPRegisterID fd, FPRegisterID fs)
|
|
|
- {
|
|
|
- emitInst(0x4620000d | (fd << OP_SH_FD) | (fs << OP_SH_FS));
|
|
|
-@@ -619,9 +631,24 @@ public:
|
|
|
- return m_buffer.label();
|
|
|
- }
|
|
|
-
|
|
|
-+ AssemblerLabel labelForWatchpoint()
|
|
|
-+ {
|
|
|
-+ AssemblerLabel result = m_buffer.label();
|
|
|
-+ if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
|
|
|
-+ result = label();
|
|
|
-+ m_indexOfLastWatchpoint = result.m_offset;
|
|
|
-+ m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
|
|
|
-+ return result;
|
|
|
-+ }
|
|
|
-+
|
|
|
- AssemblerLabel label()
|
|
|
- {
|
|
|
-- return m_buffer.label();
|
|
|
-+ AssemblerLabel result = m_buffer.label();
|
|
|
-+ while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
|
|
|
-+ nop();
|
|
|
-+ result = m_buffer.label();
|
|
|
-+ }
|
|
|
-+ return result;
|
|
|
- }
|
|
|
-
|
|
|
- AssemblerLabel align(int alignment)
|
|
|
-@@ -664,14 +691,24 @@ public:
|
|
|
- // Assembly helpers for moving data between fp and registers.
|
|
|
- void vmov(RegisterID rd1, RegisterID rd2, FPRegisterID rn)
|
|
|
- {
|
|
|
-+#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
|
|
|
-+ mfc1(rd1, rn);
|
|
|
-+ mfhc1(rd2, rn);
|
|
|
-+#else
|
|
|
- mfc1(rd1, rn);
|
|
|
- mfc1(rd2, FPRegisterID(rn + 1));
|
|
|
-+#endif
|
|
|
- }
|
|
|
-
|
|
|
- void vmov(FPRegisterID rd, RegisterID rn1, RegisterID rn2)
|
|
|
- {
|
|
|
-+#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
|
|
|
-+ mtc1(rn1, rd);
|
|
|
-+ mthc1(rn2, rd);
|
|
|
-+#else
|
|
|
- mtc1(rn1, rd);
|
|
|
- mtc1(rn2, FPRegisterID(rd + 1));
|
|
|
-+#endif
|
|
|
- }
|
|
|
-
|
|
|
- static unsigned getCallReturnOffset(AssemblerLabel call)
|
|
|
-@@ -688,6 +725,35 @@ 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());
|
|
|
-@@ -825,29 +891,36 @@ public:
|
|
|
- #endif
|
|
|
- }
|
|
|
-
|
|
|
-- static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
|
|
|
-+ static ptrdiff_t maxJumpReplacementSize()
|
|
|
- {
|
|
|
-- MIPSWord* insn = static_cast<MIPSWord*>(instructionStart) + 1;
|
|
|
-- ASSERT((*insn & 0xfc000000) == 0x34000000);
|
|
|
-- *insn = (*insn & 0xfc1f0000) | (imm & 0xffff);
|
|
|
-- cacheFlush(insn, sizeof(MIPSWord));
|
|
|
-+ return sizeof(MIPSWord) * 4;
|
|
|
- }
|
|
|
-
|
|
|
-- static void replaceWithJump(void* instructionStart, void* to)
|
|
|
-+ static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
|
|
|
- {
|
|
|
-- MIPSWord* instruction = reinterpret_cast<MIPSWord*>(instructionStart);
|
|
|
-- intptr_t jumpTo = reinterpret_cast<intptr_t>(to);
|
|
|
-+ MIPSWord* insn = static_cast<MIPSWord*>(instructionStart);
|
|
|
-+ size_t codeSize = 2 * sizeof(MIPSWord);
|
|
|
-
|
|
|
- // lui
|
|
|
-- instruction[0] = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((jumpTo >> 16) & 0xffff);
|
|
|
-+ *insn = 0x3c000000 | (rt << OP_SH_RT) | ((imm >> 16) & 0xffff);
|
|
|
-+ ++insn;
|
|
|
- // ori
|
|
|
-- instruction[1] = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (jumpTo & 0xffff);
|
|
|
-- // jr
|
|
|
-- instruction[2] = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
|
|
|
-- // nop
|
|
|
-- instruction[3] = 0x0;
|
|
|
-+ *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(instruction, sizeof(MIPSWord) * 4);
|
|
|
-+ 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);
|
|
|
- }
|
|
|
-
|
|
|
- static void replaceWithLoad(void* instructionStart)
|
|
|
-@@ -1023,6 +1096,8 @@ private:
|
|
|
-
|
|
|
- AssemblerBuffer m_buffer;
|
|
|
- Jumps m_jumps;
|
|
|
-+ int m_indexOfLastWatchpoint;
|
|
|
-+ int m_indexOfTailOfLastWatchpoint;
|
|
|
- };
|
|
|
-
|
|
|
- } // namespace JSC
|
|
|
-diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
|
|
|
-index 60a93db..1f0c3de 100644
|
|
|
---- a/Source/JavaScriptCore/assembler/MacroAssembler.h
|
|
|
-+++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
|
|
|
-@@ -200,6 +200,13 @@ public:
|
|
|
- }
|
|
|
- #endif
|
|
|
-
|
|
|
-+#if CPU(MIPS)
|
|
|
-+ void poke(FPRegisterID src, int index = 0)
|
|
|
-+ {
|
|
|
-+ ASSERT(!(index & 1));
|
|
|
-+ storeDouble(src, addressForPoke(index));
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-
|
|
|
- // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
|
|
|
- void branchPtr(RelationalCondition cond, RegisterID op1, TrustedImmPtr imm, Label target)
|
|
|
-diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
|
|
|
-index 43ad434..4f14960 100644
|
|
|
---- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
|
|
|
-+++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
|
|
|
-@@ -114,6 +114,11 @@ public:
|
|
|
- m_assembler.addu(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void add32(RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.addu(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void add32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- add32(imm, dest, dest);
|
|
|
-@@ -267,6 +272,11 @@ public:
|
|
|
- m_assembler.andInsn(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void and32(RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.andInsn(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void and32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- if (!imm.m_value && !m_fixedWidth)
|
|
|
-@@ -283,9 +293,16 @@ public:
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-- void lshift32(TrustedImm32 imm, RegisterID dest)
|
|
|
-+ void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
-- m_assembler.sll(dest, dest, imm.m_value);
|
|
|
-+ if (!imm.m_value && !m_fixedWidth)
|
|
|
-+ move(MIPSRegisters::zero, dest);
|
|
|
-+ else if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth)
|
|
|
-+ m_assembler.andi(dest, src, imm.m_value);
|
|
|
-+ else {
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.andInsn(dest, src, immTempRegister);
|
|
|
-+ }
|
|
|
- }
|
|
|
-
|
|
|
- void lshift32(RegisterID shiftAmount, RegisterID dest)
|
|
|
-@@ -293,11 +310,33 @@ public:
|
|
|
- m_assembler.sllv(dest, dest, shiftAmount);
|
|
|
- }
|
|
|
-
|
|
|
-+ void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.sllv(dest, src, shiftAmount);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void lshift32(TrustedImm32 imm, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.sllv(dest, dest, immTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.sllv(dest, src, immTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void mul32(RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.mul(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void mul32(RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.mul(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- if (!imm.m_value && !m_fixedWidth)
|
|
|
-@@ -348,6 +387,24 @@ public:
|
|
|
- m_assembler.orInsn(dest, dest, dataTempRegister);
|
|
|
- }
|
|
|
-
|
|
|
-+ void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ if (!imm.m_value && !m_fixedWidth)
|
|
|
-+ return;
|
|
|
-+
|
|
|
-+ if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth) {
|
|
|
-+ m_assembler.ori(dest, src, imm.m_value);
|
|
|
-+ return;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /*
|
|
|
-+ li dataTemp, imm
|
|
|
-+ or dest, src, dataTemp
|
|
|
-+ */
|
|
|
-+ move(imm, dataTempRegister);
|
|
|
-+ m_assembler.orInsn(dest, src, dataTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void or32(RegisterID src, AbsoluteAddress dest)
|
|
|
- {
|
|
|
- load32(dest.m_ptr, dataTempRegister);
|
|
|
-@@ -360,6 +417,11 @@ public:
|
|
|
- m_assembler.srav(dest, dest, shiftAmount);
|
|
|
- }
|
|
|
-
|
|
|
-+ void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.srav(dest, src, shiftAmount);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void rshift32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.sra(dest, dest, imm.m_value);
|
|
|
-@@ -375,16 +437,31 @@ public:
|
|
|
- m_assembler.srlv(dest, dest, shiftAmount);
|
|
|
- }
|
|
|
-
|
|
|
-+ void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.srlv(dest, src, shiftAmount);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void urshift32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.srl(dest, dest, imm.m_value);
|
|
|
- }
|
|
|
-
|
|
|
-+ void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.srl(dest, src, imm.m_value);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void sub32(RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.subu(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void sub32(RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.subu(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void sub32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- if (imm.m_value >= -32767 && imm.m_value <= 32768
|
|
|
-@@ -495,6 +572,11 @@ public:
|
|
|
- m_assembler.xorInsn(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void xor32(RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.xorInsn(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void xor32(TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- if (imm.m_value == -1) {
|
|
|
-@@ -510,6 +592,21 @@ public:
|
|
|
- m_assembler.xorInsn(dest, dest, immTempRegister);
|
|
|
- }
|
|
|
-
|
|
|
-+ void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ if (imm.m_value == -1) {
|
|
|
-+ m_assembler.nor(dest, src, MIPSRegisters::zero);
|
|
|
-+ return;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ /*
|
|
|
-+ li immTemp, imm
|
|
|
-+ xor dest, dest, immTemp
|
|
|
-+ */
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.xorInsn(dest, src, immTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void sqrtDouble(FPRegisterID src, FPRegisterID dst)
|
|
|
- {
|
|
|
- m_assembler.sqrtd(dst, src);
|
|
|
-@@ -989,6 +1086,44 @@ public:
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-+ void store32(TrustedImm32 imm, BaseIndex address)
|
|
|
-+ {
|
|
|
-+ if (address.offset >= -32768 && address.offset <= 32767 && !m_fixedWidth) {
|
|
|
-+ /*
|
|
|
-+ sll addrTemp, address.index, address.scale
|
|
|
-+ addu addrTemp, addrTemp, address.base
|
|
|
-+ sw src, address.offset(addrTemp)
|
|
|
-+ */
|
|
|
-+ m_assembler.sll(addrTempRegister, address.index, address.scale);
|
|
|
-+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
|
|
|
-+ if (!imm.m_value)
|
|
|
-+ m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset);
|
|
|
-+ else {
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.sw(immTempRegister, addrTempRegister, address.offset);
|
|
|
-+ }
|
|
|
-+ } else {
|
|
|
-+ /*
|
|
|
-+ sll addrTemp, address.index, address.scale
|
|
|
-+ addu addrTemp, addrTemp, address.base
|
|
|
-+ lui immTemp, (address.offset + 0x8000) >> 16
|
|
|
-+ addu addrTemp, addrTemp, immTemp
|
|
|
-+ sw src, (address.offset & 0xffff)(at)
|
|
|
-+ */
|
|
|
-+ m_assembler.sll(addrTempRegister, address.index, address.scale);
|
|
|
-+ m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
|
|
|
-+ m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
|
|
|
-+ m_assembler.addu(addrTempRegister, addrTempRegister, immTempRegister);
|
|
|
-+ if (!imm.m_value && !m_fixedWidth)
|
|
|
-+ m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset);
|
|
|
-+ else {
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.sw(immTempRegister, addrTempRegister, address.offset);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+
|
|
|
- void store32(RegisterID src, const void* address)
|
|
|
- {
|
|
|
- /*
|
|
|
-@@ -1336,6 +1471,15 @@ public:
|
|
|
- m_fixedWidth = false;
|
|
|
- }
|
|
|
-
|
|
|
-+ void jump(AbsoluteAddress address)
|
|
|
-+ {
|
|
|
-+ m_fixedWidth = true;
|
|
|
-+ load32(address.m_ptr, MIPSRegisters::t9);
|
|
|
-+ m_assembler.jr(MIPSRegisters::t9);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ m_fixedWidth = false;
|
|
|
-+ }
|
|
|
-+
|
|
|
- void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
|
|
|
- {
|
|
|
- m_assembler.vmov(dest1, dest2, src);
|
|
|
-@@ -1404,6 +1548,53 @@ public:
|
|
|
- return Jump();
|
|
|
- }
|
|
|
-
|
|
|
-+ Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
|
|
|
-+ if (cond == Overflow) {
|
|
|
-+ /*
|
|
|
-+ move dataTemp, op1
|
|
|
-+ xor cmpTemp, dataTemp, op2
|
|
|
-+ bltz cmpTemp, No_overflow # diff sign bit -> no overflow
|
|
|
-+ addu dest, dataTemp, op2
|
|
|
-+ xor cmpTemp, dest, dataTemp
|
|
|
-+ bgez cmpTemp, No_overflow # same sign big -> no overflow
|
|
|
-+ nop
|
|
|
-+ b Overflow
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ No_overflow:
|
|
|
-+ */
|
|
|
-+ move(op1, dataTempRegister);
|
|
|
-+ m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2);
|
|
|
-+ m_assembler.bltz(cmpTempRegister, 10);
|
|
|
-+ m_assembler.addu(dest, dataTempRegister, op2);
|
|
|
-+ m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
|
|
|
-+ m_assembler.bgez(cmpTempRegister, 7);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ return jump();
|
|
|
-+ }
|
|
|
-+ if (cond == Signed) {
|
|
|
-+ add32(op1, op2, dest);
|
|
|
-+ // Check if dest is negative.
|
|
|
-+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
|
|
|
-+ return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == Zero) {
|
|
|
-+ add32(op1, op2, dest);
|
|
|
-+ return branchEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == NonZero) {
|
|
|
-+ add32(op1, op2, dest);
|
|
|
-+ return branchNotEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ ASSERT(0);
|
|
|
-+ return Jump();
|
|
|
-+ }
|
|
|
-+
|
|
|
- Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- move(imm, immTempRegister);
|
|
|
-@@ -1417,6 +1608,111 @@ public:
|
|
|
- return branchAdd32(cond, immTempRegister, dest);
|
|
|
- }
|
|
|
-
|
|
|
-+ Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
|
|
|
-+ {
|
|
|
-+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
|
|
|
-+ if (cond == Overflow) {
|
|
|
-+ /*
|
|
|
-+ move dataTemp, dest
|
|
|
-+ xori cmpTemp, dataTemp, imm
|
|
|
-+ bltz cmpTemp, No_overflow # diff sign bit -> no overflow
|
|
|
-+ addiu dataTemp, dataTemp, imm
|
|
|
-+ move dest, dataTemp
|
|
|
-+ xori cmpTemp, dataTemp, imm
|
|
|
-+ bgez cmpTemp, No_overflow # same sign big -> no overflow
|
|
|
-+ nop
|
|
|
-+ b Overflow
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ No_overflow:
|
|
|
-+ */
|
|
|
-+ if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth) {
|
|
|
-+ load32(dest.m_ptr, dataTempRegister);
|
|
|
-+ m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value);
|
|
|
-+ m_assembler.bltz(cmpTempRegister, 10);
|
|
|
-+ m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
|
|
|
-+ store32(dataTempRegister, dest.m_ptr);
|
|
|
-+ m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value);
|
|
|
-+ m_assembler.bgez(cmpTempRegister, 7);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ } else {
|
|
|
-+ load32(dest.m_ptr, dataTempRegister);
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ m_assembler.xorInsn(cmpTempRegister, dataTempRegister, immTempRegister);
|
|
|
-+ m_assembler.bltz(cmpTempRegister, 10);
|
|
|
-+ m_assembler.addiu(dataTempRegister, dataTempRegister, immTempRegister);
|
|
|
-+ store32(dataTempRegister, dest.m_ptr);
|
|
|
-+ m_assembler.xori(cmpTempRegister, dataTempRegister, immTempRegister);
|
|
|
-+ m_assembler.bgez(cmpTempRegister, 7);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ }
|
|
|
-+ return jump();
|
|
|
-+ }
|
|
|
-+ move(imm, immTempRegister);
|
|
|
-+ load32(dest.m_ptr, dataTempRegister);
|
|
|
-+ add32(immTempRegister, dataTempRegister);
|
|
|
-+ store32(dataTempRegister, dest.m_ptr);
|
|
|
-+ if (cond == Signed) {
|
|
|
-+ // Check if dest is negative.
|
|
|
-+ m_assembler.slt(cmpTempRegister, dataTempRegister, MIPSRegisters::zero);
|
|
|
-+ return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == Zero)
|
|
|
-+ return branchEqual(dataTempRegister, MIPSRegisters::zero);
|
|
|
-+ if (cond == NonZero)
|
|
|
-+ return branchNotEqual(dataTempRegister, MIPSRegisters::zero);
|
|
|
-+ ASSERT(0);
|
|
|
-+ return Jump();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
|
|
|
-+ if (cond == Overflow) {
|
|
|
-+ /*
|
|
|
-+ mult src, dest
|
|
|
-+ mfhi dataTemp
|
|
|
-+ mflo dest
|
|
|
-+ sra addrTemp, dest, 31
|
|
|
-+ beq dataTemp, addrTemp, No_overflow # all sign bits (bit 63 to bit 31) are the same -> no overflow
|
|
|
-+ nop
|
|
|
-+ b Overflow
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ No_overflow:
|
|
|
-+ */
|
|
|
-+ m_assembler.mult(src1, src2);
|
|
|
-+ m_assembler.mfhi(dataTempRegister);
|
|
|
-+ m_assembler.mflo(dest);
|
|
|
-+ m_assembler.sra(addrTempRegister, dest, 31);
|
|
|
-+ m_assembler.beq(dataTempRegister, addrTempRegister, 7);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ return jump();
|
|
|
-+ }
|
|
|
-+ if (cond == Signed) {
|
|
|
-+ mul32(src1, src2, dest);
|
|
|
-+ // Check if dest is negative.
|
|
|
-+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
|
|
|
-+ return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == Zero) {
|
|
|
-+ mul32(src1, src2, dest);
|
|
|
-+ return branchEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == NonZero) {
|
|
|
-+ mul32(src1, src2, dest);
|
|
|
-+ return branchNotEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ ASSERT(0);
|
|
|
-+ return Jump();
|
|
|
-+ }
|
|
|
-+
|
|
|
- Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
|
|
|
-@@ -1465,8 +1761,7 @@ public:
|
|
|
- Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- move(imm, immTempRegister);
|
|
|
-- move(src, dest);
|
|
|
-- return branchMul32(cond, immTempRegister, dest);
|
|
|
-+ return branchMul32(cond, immTempRegister, src, dest);
|
|
|
- }
|
|
|
-
|
|
|
- Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
|
|
|
-@@ -1525,8 +1820,60 @@ public:
|
|
|
- Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
|
|
|
- {
|
|
|
- move(imm, immTempRegister);
|
|
|
-- move(src, dest);
|
|
|
-- return branchSub32(cond, immTempRegister, dest);
|
|
|
-+ return branchSub32(cond, src, immTempRegister, dest);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
|
|
|
-+ if (cond == Overflow) {
|
|
|
-+ /*
|
|
|
-+ move dataTemp, op1
|
|
|
-+ xor cmpTemp, dataTemp, op2
|
|
|
-+ bgez cmpTemp, No_overflow # same sign bit -> no overflow
|
|
|
-+ subu dest, dataTemp, op2
|
|
|
-+ xor cmpTemp, dest, dataTemp
|
|
|
-+ bgez cmpTemp, No_overflow # same sign bit -> no overflow
|
|
|
-+ nop
|
|
|
-+ b Overflow
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ nop
|
|
|
-+ No_overflow:
|
|
|
-+ */
|
|
|
-+ move(op1, dataTempRegister);
|
|
|
-+ m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2);
|
|
|
-+ m_assembler.bgez(cmpTempRegister, 10);
|
|
|
-+ m_assembler.subu(dest, dataTempRegister, op2);
|
|
|
-+ m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
|
|
|
-+ m_assembler.bgez(cmpTempRegister, 7);
|
|
|
-+ m_assembler.nop();
|
|
|
-+ return jump();
|
|
|
-+ }
|
|
|
-+ if (cond == Signed) {
|
|
|
-+ sub32(op1, op2, dest);
|
|
|
-+ // Check if dest is negative.
|
|
|
-+ m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
|
|
|
-+ return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == Zero) {
|
|
|
-+ sub32(op1, op2, dest);
|
|
|
-+ return branchEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ if (cond == NonZero) {
|
|
|
-+ sub32(op1, op2, dest);
|
|
|
-+ return branchNotEqual(dest, MIPSRegisters::zero);
|
|
|
-+ }
|
|
|
-+ ASSERT(0);
|
|
|
-+ return Jump();
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
|
|
|
-+ {
|
|
|
-+ m_assembler.li(dataTempRegister, -1);
|
|
|
-+ return branchMul32(cond, dataTempRegister, srcDest);
|
|
|
- }
|
|
|
-
|
|
|
- Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
|
|
|
-@@ -1578,7 +1925,8 @@ public:
|
|
|
-
|
|
|
- Call call(RegisterID target)
|
|
|
- {
|
|
|
-- m_assembler.jalr(target);
|
|
|
-+ move(target, MIPSRegisters::t9);
|
|
|
-+ m_assembler.jalr(MIPSRegisters::t9);
|
|
|
- m_assembler.nop();
|
|
|
- return Call(m_assembler.label(), Call::None);
|
|
|
- }
|
|
|
-@@ -1822,7 +2170,7 @@ public:
|
|
|
- lui immTemp, (address.offset + 0x8000) >> 16
|
|
|
- addu addrTemp, addrTemp, immTemp
|
|
|
- lwc1 dest, (address.offset & 0xffff)(at)
|
|
|
-- lwc1 dest+4, (address.offset & 0xffff + 4)(at)
|
|
|
-+ lwc1 dest+1, (address.offset & 0xffff + 4)(at)
|
|
|
- */
|
|
|
- m_assembler.sll(addrTempRegister, address.index, address.scale);
|
|
|
- m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
|
|
|
-@@ -2009,6 +2357,19 @@ public:
|
|
|
- #endif
|
|
|
- }
|
|
|
-
|
|
|
-+ void moveDouble(FPRegisterID src, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ if (src != dest || m_fixedWidth)
|
|
|
-+ m_assembler.movd(dest, src);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void swapDouble(FPRegisterID fr1, FPRegisterID fr2)
|
|
|
-+ {
|
|
|
-+ moveDouble(fr1, fpTempRegister);
|
|
|
-+ moveDouble(fr2, fr1);
|
|
|
-+ moveDouble(fpTempRegister, fr2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void addDouble(FPRegisterID src, FPRegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.addd(dest, dest, src);
|
|
|
-@@ -2036,6 +2397,11 @@ public:
|
|
|
- m_assembler.subd(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.subd(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void subDouble(Address src, FPRegisterID dest)
|
|
|
- {
|
|
|
- loadDouble(src, fpTempRegister);
|
|
|
-@@ -2053,11 +2419,32 @@ public:
|
|
|
- m_assembler.muld(dest, dest, fpTempRegister);
|
|
|
- }
|
|
|
-
|
|
|
-+ void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.muld(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void divDouble(FPRegisterID src, FPRegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.divd(dest, dest, src);
|
|
|
- }
|
|
|
-
|
|
|
-+ void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.divd(dest, op1, op2);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void divDouble(Address src, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ loadDouble(src, fpTempRegister);
|
|
|
-+ m_assembler.divd(dest, dest, fpTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ void negateDouble(FPRegisterID src, FPRegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.negd(dest, src);
|
|
|
-+ }
|
|
|
-+
|
|
|
- void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.mtc1(src, fpTempRegister);
|
|
|
-@@ -2117,6 +2504,8 @@ 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();
|
|
|
-@@ -2126,6 +2515,8 @@ 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();
|
|
|
-@@ -2192,11 +2583,33 @@ public:
|
|
|
- // If the result is not representable as a 32 bit value, branch.
|
|
|
- // May also branch for some values that are representable in 32 bits
|
|
|
- // (specifically, in this case, INT_MAX 0x7fffffff).
|
|
|
-- Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
|
|
|
-+ enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
|
|
|
-+ Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
|
|
|
-+ {
|
|
|
-+ m_assembler.truncwd(fpTempRegister, src);
|
|
|
-+ m_assembler.mfc1(dest, fpTempRegister);
|
|
|
-+ return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0x7fffffff));
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
|
|
|
-+ {
|
|
|
-+ m_assembler.truncwd(fpTempRegister, src);
|
|
|
-+ m_assembler.mfc1(dest, fpTempRegister);
|
|
|
-+ return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0));
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ // Result is undefined if the value is outside of the integer range.
|
|
|
-+ void truncateDoubleToInt32(FPRegisterID src, RegisterID dest)
|
|
|
-+ {
|
|
|
-+ m_assembler.truncwd(fpTempRegister, src);
|
|
|
-+ m_assembler.mfc1(dest, fpTempRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ // Result is undefined if src > 2^31
|
|
|
-+ void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
|
|
|
- {
|
|
|
- m_assembler.truncwd(fpTempRegister, src);
|
|
|
- m_assembler.mfc1(dest, fpTempRegister);
|
|
|
-- return branch32(Equal, dest, TrustedImm32(0x7fffffff));
|
|
|
- }
|
|
|
-
|
|
|
- // Convert 'src' to an integer, and places the resulting 'dest'.
|
|
|
-@@ -2218,28 +2631,43 @@ public:
|
|
|
-
|
|
|
- Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
|
|
|
- {
|
|
|
--#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, scratch);
|
|
|
-- m_assembler.mthc1(MIPSRegisters::zero, scratch);
|
|
|
--#else
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, scratch);
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1));
|
|
|
--#endif
|
|
|
-+ m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero);
|
|
|
- return branchDouble(DoubleNotEqual, reg, scratch);
|
|
|
- }
|
|
|
-
|
|
|
- Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
|
|
|
- {
|
|
|
--#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, scratch);
|
|
|
-- m_assembler.mthc1(MIPSRegisters::zero, scratch);
|
|
|
--#else
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, scratch);
|
|
|
-- m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1));
|
|
|
--#endif
|
|
|
-+ m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero);
|
|
|
- return branchDouble(DoubleEqualOrUnordered, reg, scratch);
|
|
|
- }
|
|
|
-
|
|
|
-+ // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc.
|
|
|
-+ static RelationalCondition invert(RelationalCondition cond)
|
|
|
-+ {
|
|
|
-+ RelationalCondition r;
|
|
|
-+ if (cond == Equal)
|
|
|
-+ r = NotEqual;
|
|
|
-+ else if (cond == NotEqual)
|
|
|
-+ r = Equal;
|
|
|
-+ else if (cond == Above)
|
|
|
-+ r = BelowOrEqual;
|
|
|
-+ else if (cond == AboveOrEqual)
|
|
|
-+ r = Below;
|
|
|
-+ else if (cond == Below)
|
|
|
-+ r = AboveOrEqual;
|
|
|
-+ else if (cond == BelowOrEqual)
|
|
|
-+ r = Above;
|
|
|
-+ else if (cond == GreaterThan)
|
|
|
-+ r = LessThanOrEqual;
|
|
|
-+ else if (cond == GreaterThanOrEqual)
|
|
|
-+ r = LessThan;
|
|
|
-+ else if (cond == LessThan)
|
|
|
-+ r = GreaterThanOrEqual;
|
|
|
-+ else if (cond == LessThanOrEqual)
|
|
|
-+ r = GreaterThan;
|
|
|
-+ return r;
|
|
|
-+ }
|
|
|
-+
|
|
|
- void nop()
|
|
|
- {
|
|
|
- m_assembler.nop();
|
|
|
-@@ -2252,12 +2680,12 @@ public:
|
|
|
-
|
|
|
- static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
|
|
|
- {
|
|
|
-- RELEASE_ASSERT_NOT_REACHED();
|
|
|
-+ MIPSAssembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
|
|
|
- }
|
|
|
-
|
|
|
- static ptrdiff_t maxJumpReplacementSize()
|
|
|
- {
|
|
|
-- RELEASE_ASSERT_NOT_REACHED();
|
|
|
-+ MIPSAssembler::maxJumpReplacementSize();
|
|
|
- return 0;
|
|
|
- }
|
|
|
-
|
|
|
-diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
|
|
|
-index fa0f5e0..573d8dc 100644
|
|
|
---- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
|
|
|
-+++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
|
|
|
-@@ -93,6 +93,23 @@ public:
|
|
|
- }
|
|
|
- #endif
|
|
|
-
|
|
|
-+#if CPU(MIPS)
|
|
|
-+ ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
|
|
|
-+ {
|
|
|
-+ move(returnAddressRegister, reg);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg)
|
|
|
-+ {
|
|
|
-+ move(reg, returnAddressRegister);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ ALWAYS_INLINE void restoreReturnAddressBeforeReturn(Address address)
|
|
|
-+ {
|
|
|
-+ loadPtr(address, returnAddressRegister);
|
|
|
-+ }
|
|
|
-+#endif
|
|
|
-+
|
|
|
- void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
|
|
|
- {
|
|
|
- loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
|
|
|
-@@ -193,7 +210,7 @@ public:
|
|
|
- move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::regT0);
|
|
|
- storePtr(TrustedImmPtr(scratchSize), GPRInfo::regT0);
|
|
|
-
|
|
|
--#if CPU(X86_64) || CPU(ARM)
|
|
|
-+#if CPU(X86_64) || CPU(ARM) || CPU(MIPS)
|
|
|
- move(TrustedImmPtr(buffer), GPRInfo::argumentGPR2);
|
|
|
- move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
|
|
|
- move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
|
|
-diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
|
|
|
-index 8adde05..3d99f6f 100644
|
|
|
---- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
|
|
|
-+++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
|
|
|
-@@ -576,6 +576,39 @@ public:
|
|
|
- poke(GPRInfo::nonArgGPR0);
|
|
|
- }
|
|
|
- #endif // CPU(ARM_HARDFP)
|
|
|
-+#elif CPU(MIPS)
|
|
|
-+ ALWAYS_INLINE void setupArguments(FPRReg arg1)
|
|
|
-+ {
|
|
|
-+ moveDouble(arg1, FPRInfo::argumentFPR0);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
|
|
|
-+ {
|
|
|
-+ if (arg2 != FPRInfo::argumentFPR0) {
|
|
|
-+ moveDouble(arg1, FPRInfo::argumentFPR0);
|
|
|
-+ moveDouble(arg2, FPRInfo::argumentFPR1);
|
|
|
-+ } else if (arg1 != FPRInfo::argumentFPR1) {
|
|
|
-+ moveDouble(arg2, FPRInfo::argumentFPR1);
|
|
|
-+ moveDouble(arg1, FPRInfo::argumentFPR0);
|
|
|
-+ } else {
|
|
|
-+ // Swap arg1, arg2.
|
|
|
-+ swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
|
|
|
-+ {
|
|
|
-+ assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
|
|
|
-+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
|
|
-+ poke(arg2, 4);
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
|
|
|
-+ {
|
|
|
-+ setupStubArguments(arg1, arg2);
|
|
|
-+ move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
|
|
|
-+ poke(arg3, 4);
|
|
|
-+ }
|
|
|
- #else
|
|
|
- #error "DFG JIT not supported on this platform."
|
|
|
- #endif
|
|
|
-@@ -803,119 +836,126 @@ public:
|
|
|
- // These methods are suitable for any calling convention that provides for
|
|
|
- // exactly 4 argument registers, e.g. ARMv7.
|
|
|
- #if NUMBER_OF_ARGUMENT_REGISTERS == 4
|
|
|
-+
|
|
|
-+#if CPU(MIPS)
|
|
|
-+#define POKE_ARGUMENT_OFFSET 4
|
|
|
-+#else
|
|
|
-+#define POKE_ARGUMENT_OFFSET 0
|
|
|
-+#endif
|
|
|
-+
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
|
|
|
- {
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
- ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
|
|
|
- {
|
|
|
-- poke(arg5, 1);
|
|
|
-- poke(arg4);
|
|
|
-+ poke(arg5, POKE_ARGUMENT_OFFSET + 1);
|
|
|
-+ poke(arg4, POKE_ARGUMENT_OFFSET);
|
|
|
- setupArgumentsWithExecState(arg1, arg2, arg3);
|
|
|
- }
|
|
|
-
|
|
|
-diff --git a/Source/JavaScriptCore/dfg/DFGFPRInfo.h b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
|
|
|
-index 17aaa7d..e18ec06 100644
|
|
|
---- a/Source/JavaScriptCore/dfg/DFGFPRInfo.h
|
|
|
-+++ b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
|
|
|
-@@ -164,6 +164,74 @@ public:
|
|
|
-
|
|
|
- #endif
|
|
|
-
|
|
|
-+#if CPU(MIPS)
|
|
|
-+
|
|
|
-+class FPRInfo {
|
|
|
-+public:
|
|
|
-+ typedef FPRReg RegisterType;
|
|
|
-+ static const unsigned numberOfRegisters = 6;
|
|
|
-+
|
|
|
-+ // Temporary registers.
|
|
|
-+ static const FPRReg fpRegT0 = MIPSRegisters::f0;
|
|
|
-+ static const FPRReg fpRegT1 = MIPSRegisters::f4;
|
|
|
-+ static const FPRReg fpRegT2 = MIPSRegisters::f6;
|
|
|
-+ static const FPRReg fpRegT3 = MIPSRegisters::f8;
|
|
|
-+ static const FPRReg fpRegT4 = MIPSRegisters::f10;
|
|
|
-+ static const FPRReg fpRegT5 = MIPSRegisters::f18;
|
|
|
-+
|
|
|
-+ static const FPRReg returnValueFPR = MIPSRegisters::f0;
|
|
|
-+
|
|
|
-+ static const FPRReg argumentFPR0 = MIPSRegisters::f12;
|
|
|
-+ static const FPRReg argumentFPR1 = MIPSRegisters::f14;
|
|
|
-+
|
|
|
-+ static FPRReg toRegister(unsigned index)
|
|
|
-+ {
|
|
|
-+ static const FPRReg registerForIndex[numberOfRegisters] = {
|
|
|
-+ fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
|
|
|
-+
|
|
|
-+ ASSERT(index < numberOfRegisters);
|
|
|
-+ return registerForIndex[index];
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ static unsigned toIndex(FPRReg reg)
|
|
|
-+ {
|
|
|
-+ ASSERT(reg != InvalidFPRReg);
|
|
|
-+ ASSERT(reg < 20);
|
|
|
-+ static const unsigned indexForRegister[20] = {
|
|
|
-+ 0, InvalidIndex, InvalidIndex, InvalidIndex,
|
|
|
-+ 1, InvalidIndex, 2, InvalidIndex,
|
|
|
-+ 3, InvalidIndex, 4, InvalidIndex,
|
|
|
-+ InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
|
|
|
-+ InvalidIndex, InvalidIndex, 5, InvalidIndex,
|
|
|
-+ };
|
|
|
-+ unsigned result = indexForRegister[reg];
|
|
|
-+ ASSERT(result != InvalidIndex);
|
|
|
-+ return result;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ static const char* debugName(FPRReg reg)
|
|
|
-+ {
|
|
|
-+ ASSERT(reg != InvalidFPRReg);
|
|
|
-+ ASSERT(reg < 32);
|
|
|
-+ static const char* nameForRegister[32] = {
|
|
|
-+ "f0", "f1", "f2", "f3",
|
|
|
-+ "f4", "f5", "f6", "f7",
|
|
|
-+ "f8", "f9", "f10", "f11",
|
|
|
-+ "f12", "f13", "f14", "f15"
|
|
|
-+ "f16", "f17", "f18", "f19"
|
|
|
-+ "f20", "f21", "f22", "f23"
|
|
|
-+ "f24", "f25", "f26", "f27"
|
|
|
-+ "f28", "f29", "f30", "f31"
|
|
|
-+ };
|
|
|
-+ return nameForRegister[reg];
|
|
|
-+ }
|
|
|
-+private:
|
|
|
-+
|
|
|
-+ static const unsigned InvalidIndex = 0xffffffff;
|
|
|
-+};
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
- typedef RegisterBank<FPRInfo>::iterator fpr_iterator;
|
|
|
-
|
|
|
- } } // namespace JSC::DFG
|
|
|
-diff --git a/Source/JavaScriptCore/dfg/DFGGPRInfo.h b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
|
|
|
-index 3d07556..aa634cd 100644
|
|
|
---- a/Source/JavaScriptCore/dfg/DFGGPRInfo.h
|
|
|
-+++ b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
|
|
|
-@@ -461,6 +461,73 @@ private:
|
|
|
-
|
|
|
- #endif
|
|
|
-
|
|
|
-+#if CPU(MIPS)
|
|
|
-+#define NUMBER_OF_ARGUMENT_REGISTERS 4
|
|
|
-+
|
|
|
-+class GPRInfo {
|
|
|
-+public:
|
|
|
-+ typedef GPRReg RegisterType;
|
|
|
-+ static const unsigned numberOfRegisters = 6;
|
|
|
-+
|
|
|
-+ // Temporary registers.
|
|
|
-+ static const GPRReg regT0 = MIPSRegisters::v0;
|
|
|
-+ static const GPRReg regT1 = MIPSRegisters::v1;
|
|
|
-+ static const GPRReg regT2 = MIPSRegisters::t4;
|
|
|
-+ static const GPRReg regT3 = MIPSRegisters::t5;
|
|
|
-+ static const GPRReg regT4 = MIPSRegisters::t6;
|
|
|
-+ static const GPRReg regT5 = MIPSRegisters::t7;
|
|
|
-+ // These registers match the baseline JIT.
|
|
|
-+ static const GPRReg cachedResultRegister = regT0;
|
|
|
-+ static const GPRReg cachedResultRegister2 = regT1;
|
|
|
-+ static const GPRReg callFrameRegister = MIPSRegisters::s0;
|
|
|
-+ // These constants provide the names for the general purpose argument & return value registers.
|
|
|
-+ static const GPRReg argumentGPR0 = MIPSRegisters::a0;
|
|
|
-+ static const GPRReg argumentGPR1 = MIPSRegisters::a1;
|
|
|
-+ static const GPRReg argumentGPR2 = MIPSRegisters::a2;
|
|
|
-+ static const GPRReg argumentGPR3 = MIPSRegisters::a3;
|
|
|
-+ static const GPRReg nonArgGPR0 = regT2;
|
|
|
-+ static const GPRReg nonArgGPR1 = regT3;
|
|
|
-+ static const GPRReg nonArgGPR2 = regT4;
|
|
|
-+ static const GPRReg returnValueGPR = regT0;
|
|
|
-+ static const GPRReg returnValueGPR2 = regT1;
|
|
|
-+ static const GPRReg nonPreservedNonReturnGPR = regT5;
|
|
|
-+
|
|
|
-+ static GPRReg toRegister(unsigned index)
|
|
|
-+ {
|
|
|
-+ ASSERT(index < numberOfRegisters);
|
|
|
-+ static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 };
|
|
|
-+ return registerForIndex[index];
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ static unsigned toIndex(GPRReg reg)
|
|
|
-+ {
|
|
|
-+ ASSERT(reg != InvalidGPRReg);
|
|
|
-+ ASSERT(reg < 16);
|
|
|
-+ static const unsigned indexForRegister[16] = { InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, 2, 3, 4, 5 };
|
|
|
-+ unsigned result = indexForRegister[reg];
|
|
|
-+ ASSERT(result != InvalidIndex);
|
|
|
-+ return result;
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ static const char* debugName(GPRReg reg)
|
|
|
-+ {
|
|
|
-+ ASSERT(reg != InvalidGPRReg);
|
|
|
-+ ASSERT(reg < 16);
|
|
|
-+ static const char* nameForRegister[16] = {
|
|
|
-+ "zero", "at", "v0", "v1",
|
|
|
-+ "a0", "a1", "a2", "a3",
|
|
|
-+ "t0", "t1", "t2", "t3",
|
|
|
-+ "t4", "t5", "t6", "t7"
|
|
|
-+ };
|
|
|
-+ return nameForRegister[reg];
|
|
|
-+ }
|
|
|
-+private:
|
|
|
-+
|
|
|
-+ static const unsigned InvalidIndex = 0xffffffff;
|
|
|
-+};
|
|
|
-+
|
|
|
-+#endif
|
|
|
-+
|
|
|
- typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
|
|
|
-
|
|
|
- } } // namespace JSC::DFG
|
|
|
-diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
|
|
|
-index ea33f38..247274b 100644
|
|
|
---- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
|
|
|
-+++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
|
|
|
-@@ -1241,7 +1241,7 @@ public:
|
|
|
-
|
|
|
- // EncodedJSValue in JSVALUE32_64 is a 64-bit integer. When being compiled in ARM EABI, it must be aligned even-numbered register (r0, r2 or [sp]).
|
|
|
- // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
|
|
|
--#if COMPILER_SUPPORTS(EABI) && CPU(ARM)
|
|
|
-+#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
|
|
|
- #define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
|
|
|
- #else
|
|
|
- #define EABI_32BIT_DUMMY_ARG
|
|
|
-@@ -1691,7 +1691,7 @@ public:
|
|
|
- }
|
|
|
- #endif
|
|
|
-
|
|
|
--#if !defined(NDEBUG) && !CPU(ARM)
|
|
|
-+#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS)
|
|
|
- void prepareForExternalCall()
|
|
|
- {
|
|
|
- // We're about to call out to a "native" helper function. The helper
|
|
|
-diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
|
|
|
-index 7fdeaf0..48ad6b2 100644
|
|
|
---- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
|
|
|
-+++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
|
|
|
-@@ -125,6 +125,10 @@ namespace JSC {
|
|
|
- static const RegisterID cachedResultRegister = MIPSRegisters::v0;
|
|
|
- static const RegisterID firstArgumentRegister = MIPSRegisters::a0;
|
|
|
-
|
|
|
-+#if ENABLE(VALUE_PROFILER)
|
|
|
-+ static const RegisterID bucketCounterRegister = MIPSRegisters::s3;
|
|
|
-+#endif
|
|
|
-+
|
|
|
- // regT0 must be v0 for returning a 32-bit value.
|
|
|
- static const RegisterID regT0 = MIPSRegisters::v0;
|
|
|
-
|
|
|
-diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
|
|
|
-index 5d47ab9..c02f336 100644
|
|
|
---- a/Source/JavaScriptCore/runtime/JSGlobalData.h
|
|
|
-+++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
|
|
|
-@@ -141,14 +141,18 @@ namespace JSC {
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
-- static size_t allocationSize(size_t bufferSize) { return sizeof(size_t) + bufferSize; }
|
|
|
-+ static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
|
|
|
- void setActiveLength(size_t activeLength) { m_activeLength = activeLength; }
|
|
|
- size_t activeLength() const { return m_activeLength; };
|
|
|
- size_t* activeLengthPtr() { return &m_activeLength; };
|
|
|
- void* dataBuffer() { return m_buffer; }
|
|
|
-
|
|
|
- size_t m_activeLength;
|
|
|
-+#if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
|
|
|
-+ void* m_buffer[0] __attribute__((aligned(8)));
|
|
|
-+#else
|
|
|
- void* m_buffer[0];
|
|
|
-+#endif
|
|
|
- };
|
|
|
- #if COMPILER(MSVC)
|
|
|
- #pragma warning(pop)
|
|
|
-diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
|
|
|
-index 1698247..2d90359 100644
|
|
|
---- a/Source/WTF/wtf/Platform.h
|
|
|
-+++ b/Source/WTF/wtf/Platform.h
|
|
|
-@@ -818,6 +818,10 @@
|
|
|
- #if CPU(ARM_TRADITIONAL)
|
|
|
- #define ENABLE_DFG_JIT 1
|
|
|
- #endif
|
|
|
-+/* Enable the DFG JIT on MIPS. */
|
|
|
-+#if CPU(MIPS)
|
|
|
-+#define ENABLE_DFG_JIT 1
|
|
|
-+#endif
|
|
|
- #endif
|
|
|
-
|
|
|
- /* If the jit is not available, enable the LLInt C Loop: */
|
|
|
---
|
|
|
-1.8.3.2
|
|
|
-
|