1 Upstream patch for DFG implementation for MIPS
3 Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
5 From c921d19863ccf66bdd0ffa5d38eaf05efab6b136 Mon Sep 17 00:00:00 2001
6 From: "commit-queue@webkit.org"
7 <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
8 Date: Mon, 18 Feb 2013 19:25:23 +0000
9 Subject: [PATCH] MIPS DFG implementation.
10 https://bugs.webkit.org/show_bug.cgi?id=101328
12 Patch by Balazs Kilvady <kilvadyb@homejinni.com> on 2013-02-18
13 Reviewed by Oliver Hunt.
15 DFG implementation for MIPS.
17 Source/JavaScriptCore:
19 * assembler/MIPSAssembler.h:
20 (JSC::MIPSAssembler::MIPSAssembler):
21 (JSC::MIPSAssembler::sllv):
22 (JSC::MIPSAssembler::movd):
24 (JSC::MIPSAssembler::negd):
25 (JSC::MIPSAssembler::labelForWatchpoint):
26 (JSC::MIPSAssembler::label):
27 (JSC::MIPSAssembler::vmov):
28 (JSC::MIPSAssembler::linkDirectJump):
29 (JSC::MIPSAssembler::maxJumpReplacementSize):
30 (JSC::MIPSAssembler::revertJumpToMove):
31 (JSC::MIPSAssembler::replaceWithJump):
32 * assembler/MacroAssembler.h:
34 (JSC::MacroAssembler::poke):
35 * assembler/MacroAssemblerMIPS.h:
36 (JSC::MacroAssemblerMIPS::add32):
38 (JSC::MacroAssemblerMIPS::and32):
39 (JSC::MacroAssemblerMIPS::lshift32):
40 (JSC::MacroAssemblerMIPS::mul32):
41 (JSC::MacroAssemblerMIPS::or32):
42 (JSC::MacroAssemblerMIPS::rshift32):
43 (JSC::MacroAssemblerMIPS::urshift32):
44 (JSC::MacroAssemblerMIPS::sub32):
45 (JSC::MacroAssemblerMIPS::xor32):
46 (JSC::MacroAssemblerMIPS::store32):
47 (JSC::MacroAssemblerMIPS::jump):
48 (JSC::MacroAssemblerMIPS::branchAdd32):
49 (JSC::MacroAssemblerMIPS::branchMul32):
50 (JSC::MacroAssemblerMIPS::branchSub32):
51 (JSC::MacroAssemblerMIPS::branchNeg32):
52 (JSC::MacroAssemblerMIPS::call):
53 (JSC::MacroAssemblerMIPS::loadDouble):
54 (JSC::MacroAssemblerMIPS::moveDouble):
55 (JSC::MacroAssemblerMIPS::swapDouble):
56 (JSC::MacroAssemblerMIPS::subDouble):
57 (JSC::MacroAssemblerMIPS::mulDouble):
58 (JSC::MacroAssemblerMIPS::divDouble):
59 (JSC::MacroAssemblerMIPS::negateDouble):
60 (JSC::MacroAssemblerMIPS::branchEqual):
61 (JSC::MacroAssemblerMIPS::branchNotEqual):
62 (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
63 (JSC::MacroAssemblerMIPS::branchTruncateDoubleToUint32):
64 (JSC::MacroAssemblerMIPS::truncateDoubleToInt32):
65 (JSC::MacroAssemblerMIPS::truncateDoubleToUint32):
66 (JSC::MacroAssemblerMIPS::branchDoubleNonZero):
67 (JSC::MacroAssemblerMIPS::branchDoubleZeroOrNaN):
68 (JSC::MacroAssemblerMIPS::invert):
69 (JSC::MacroAssemblerMIPS::replaceWithJump):
70 (JSC::MacroAssemblerMIPS::maxJumpReplacementSize):
71 * dfg/DFGAssemblyHelpers.h:
73 (JSC::DFG::AssemblyHelpers::preserveReturnAddressAfterCall):
74 (JSC::DFG::AssemblyHelpers::restoreReturnAddressBeforeReturn):
75 (JSC::DFG::AssemblyHelpers::debugCall):
76 * dfg/DFGCCallHelpers.h:
78 (JSC::DFG::CCallHelpers::setupArguments):
79 (JSC::DFG::CCallHelpers::setupArgumentsWithExecState):
83 (JSC::DFG::FPRInfo::toRegister):
84 (JSC::DFG::FPRInfo::toIndex):
85 (JSC::DFG::FPRInfo::debugName):
89 (JSC::DFG::GPRInfo::toRegister):
90 (JSC::DFG::GPRInfo::toIndex):
91 (JSC::DFG::GPRInfo::debugName):
92 * dfg/DFGSpeculativeJIT.h:
94 * jit/JSInterfaceJIT.h:
96 * runtime/JSGlobalData.h:
97 (JSC::ScratchBuffer::allocationSize):
104 git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143247 268f45cc-cd09-0410-ab3c-d52691b4dbfc
106 Source/JavaScriptCore/ChangeLog | 90 ++++
107 Source/JavaScriptCore/assembler/MIPSAssembler.h | 109 ++++-
108 Source/JavaScriptCore/assembler/MacroAssembler.h | 7 +
109 .../JavaScriptCore/assembler/MacroAssemblerMIPS.h | 480 +++++++++++++++++++--
110 Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h | 19 +-
111 Source/JavaScriptCore/dfg/DFGCCallHelpers.h | 92 ++--
112 Source/JavaScriptCore/dfg/DFGFPRInfo.h | 68 +++
113 Source/JavaScriptCore/dfg/DFGGPRInfo.h | 67 +++
114 Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h | 4 +-
115 Source/JavaScriptCore/jit/JSInterfaceJIT.h | 4 +
116 Source/JavaScriptCore/runtime/JSGlobalData.h | 6 +-
117 Source/WTF/ChangeLog | 11 +
118 Source/WTF/wtf/Platform.h | 4 +
119 13 files changed, 888 insertions(+), 73 deletions(-)
121 diff --git a/Source/JavaScriptCore/assembler/MIPSAssembler.h b/Source/JavaScriptCore/assembler/MIPSAssembler.h
122 index 026f87e..7f553bb 100644
123 --- a/Source/JavaScriptCore/assembler/MIPSAssembler.h
124 +++ b/Source/JavaScriptCore/assembler/MIPSAssembler.h
125 @@ -152,6 +152,8 @@ public:
126 typedef SegmentedVector<AssemblerLabel, 64> Jumps;
129 + : m_indexOfLastWatchpoint(INT_MIN)
130 + , m_indexOfTailOfLastWatchpoint(INT_MIN)
134 @@ -325,7 +327,7 @@ public:
135 emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | ((shamt & 0x1f) << OP_SH_SHAMT));
138 - void sllv(RegisterID rd, RegisterID rt, int rs)
139 + void sllv(RegisterID rd, RegisterID rt, RegisterID rs)
141 emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT) | (rs << OP_SH_RS));
143 @@ -527,6 +529,16 @@ public:
144 emitInst(0x46200004 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
147 + void movd(FPRegisterID fd, FPRegisterID fs)
149 + emitInst(0x46200006 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
152 + void negd(FPRegisterID fd, FPRegisterID fs)
154 + emitInst(0x46200007 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
157 void truncwd(FPRegisterID fd, FPRegisterID fs)
159 emitInst(0x4620000d | (fd << OP_SH_FD) | (fs << OP_SH_FS));
160 @@ -619,9 +631,24 @@ public:
161 return m_buffer.label();
164 + AssemblerLabel labelForWatchpoint()
166 + AssemblerLabel result = m_buffer.label();
167 + if (static_cast<int>(result.m_offset) != m_indexOfLastWatchpoint)
169 + m_indexOfLastWatchpoint = result.m_offset;
170 + m_indexOfTailOfLastWatchpoint = result.m_offset + maxJumpReplacementSize();
174 AssemblerLabel label()
176 - return m_buffer.label();
177 + AssemblerLabel result = m_buffer.label();
178 + while (UNLIKELY(static_cast<int>(result.m_offset) < m_indexOfTailOfLastWatchpoint)) {
180 + result = m_buffer.label();
185 AssemblerLabel align(int alignment)
186 @@ -664,14 +691,24 @@ public:
187 // Assembly helpers for moving data between fp and registers.
188 void vmov(RegisterID rd1, RegisterID rd2, FPRegisterID rn)
190 +#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
195 mfc1(rd2, FPRegisterID(rn + 1));
199 void vmov(FPRegisterID rd, RegisterID rn1, RegisterID rn2)
201 +#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
206 mtc1(rn2, FPRegisterID(rd + 1));
210 static unsigned getCallReturnOffset(AssemblerLabel call)
211 @@ -688,6 +725,35 @@ public:
212 // writable region of memory; to modify the code in an execute-only execuable
213 // pool the 'repatch' and 'relink' methods should be used.
215 + static size_t linkDirectJump(void* code, void* to)
217 + MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code));
219 + int32_t slotAddr = reinterpret_cast<int>(insn) + 4;
220 + int32_t toAddr = reinterpret_cast<int>(to);
222 + if ((slotAddr & 0xf0000000) != (toAddr & 0xf0000000)) {
224 + *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((toAddr >> 16) & 0xffff);
227 + *insn = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (toAddr & 0xffff);
230 + *insn = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
232 + ops = 4 * sizeof(MIPSWord);
235 + *insn = 0x08000000 | ((toAddr & 0x0fffffff) >> 2);
237 + ops = 2 * sizeof(MIPSWord);
240 + *insn = 0x00000000;
244 void linkJump(AssemblerLabel from, AssemblerLabel to)
247 @@ -825,29 +891,36 @@ public:
251 - static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
252 + static ptrdiff_t maxJumpReplacementSize()
254 - MIPSWord* insn = static_cast<MIPSWord*>(instructionStart) + 1;
255 - ASSERT((*insn & 0xfc000000) == 0x34000000);
256 - *insn = (*insn & 0xfc1f0000) | (imm & 0xffff);
257 - cacheFlush(insn, sizeof(MIPSWord));
258 + return sizeof(MIPSWord) * 4;
261 - static void replaceWithJump(void* instructionStart, void* to)
262 + static void revertJumpToMove(void* instructionStart, RegisterID rt, int imm)
264 - MIPSWord* instruction = reinterpret_cast<MIPSWord*>(instructionStart);
265 - intptr_t jumpTo = reinterpret_cast<intptr_t>(to);
266 + MIPSWord* insn = static_cast<MIPSWord*>(instructionStart);
267 + size_t codeSize = 2 * sizeof(MIPSWord);
270 - instruction[0] = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((jumpTo >> 16) & 0xffff);
271 + *insn = 0x3c000000 | (rt << OP_SH_RT) | ((imm >> 16) & 0xffff);
274 - instruction[1] = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (jumpTo & 0xffff);
276 - instruction[2] = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
278 - instruction[3] = 0x0;
279 + *insn = 0x34000000 | (rt << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff);
282 + if (*insn == 0x03200008) {
283 + *insn = 0x00000000;
284 + codeSize += sizeof(MIPSWord);
286 + cacheFlush(insn, codeSize);
289 - cacheFlush(instruction, sizeof(MIPSWord) * 4);
290 + static void replaceWithJump(void* instructionStart, void* to)
292 + ASSERT(!(bitwise_cast<uintptr_t>(instructionStart) & 3));
293 + ASSERT(!(bitwise_cast<uintptr_t>(to) & 3));
294 + size_t ops = linkDirectJump(instructionStart, to);
295 + cacheFlush(instructionStart, ops);
298 static void replaceWithLoad(void* instructionStart)
299 @@ -1023,6 +1096,8 @@ private:
301 AssemblerBuffer m_buffer;
303 + int m_indexOfLastWatchpoint;
304 + int m_indexOfTailOfLastWatchpoint;
308 diff --git a/Source/JavaScriptCore/assembler/MacroAssembler.h b/Source/JavaScriptCore/assembler/MacroAssembler.h
309 index 60a93db..1f0c3de 100644
310 --- a/Source/JavaScriptCore/assembler/MacroAssembler.h
311 +++ b/Source/JavaScriptCore/assembler/MacroAssembler.h
312 @@ -200,6 +200,13 @@ public:
317 + void poke(FPRegisterID src, int index = 0)
319 + ASSERT(!(index & 1));
320 + storeDouble(src, addressForPoke(index));
324 // Backwards banches, these are currently all implemented using existing forwards branch mechanisms.
325 void branchPtr(RelationalCondition cond, RegisterID op1, TrustedImmPtr imm, Label target)
326 diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
327 index 43ad434..4f14960 100644
328 --- a/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
329 +++ b/Source/JavaScriptCore/assembler/MacroAssemblerMIPS.h
330 @@ -114,6 +114,11 @@ public:
331 m_assembler.addu(dest, dest, src);
334 + void add32(RegisterID op1, RegisterID op2, RegisterID dest)
336 + m_assembler.addu(dest, op1, op2);
339 void add32(TrustedImm32 imm, RegisterID dest)
341 add32(imm, dest, dest);
342 @@ -267,6 +272,11 @@ public:
343 m_assembler.andInsn(dest, dest, src);
346 + void and32(RegisterID op1, RegisterID op2, RegisterID dest)
348 + m_assembler.andInsn(dest, op1, op2);
351 void and32(TrustedImm32 imm, RegisterID dest)
353 if (!imm.m_value && !m_fixedWidth)
354 @@ -283,9 +293,16 @@ public:
358 - void lshift32(TrustedImm32 imm, RegisterID dest)
359 + void and32(TrustedImm32 imm, RegisterID src, RegisterID dest)
361 - m_assembler.sll(dest, dest, imm.m_value);
362 + if (!imm.m_value && !m_fixedWidth)
363 + move(MIPSRegisters::zero, dest);
364 + else if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth)
365 + m_assembler.andi(dest, src, imm.m_value);
367 + move(imm, immTempRegister);
368 + m_assembler.andInsn(dest, src, immTempRegister);
372 void lshift32(RegisterID shiftAmount, RegisterID dest)
373 @@ -293,11 +310,33 @@ public:
374 m_assembler.sllv(dest, dest, shiftAmount);
377 + void lshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
379 + m_assembler.sllv(dest, src, shiftAmount);
382 + void lshift32(TrustedImm32 imm, RegisterID dest)
384 + move(imm, immTempRegister);
385 + m_assembler.sllv(dest, dest, immTempRegister);
388 + void lshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
390 + move(imm, immTempRegister);
391 + m_assembler.sllv(dest, src, immTempRegister);
394 void mul32(RegisterID src, RegisterID dest)
396 m_assembler.mul(dest, dest, src);
399 + void mul32(RegisterID op1, RegisterID op2, RegisterID dest)
401 + m_assembler.mul(dest, op1, op2);
404 void mul32(TrustedImm32 imm, RegisterID src, RegisterID dest)
406 if (!imm.m_value && !m_fixedWidth)
407 @@ -348,6 +387,24 @@ public:
408 m_assembler.orInsn(dest, dest, dataTempRegister);
411 + void or32(TrustedImm32 imm, RegisterID src, RegisterID dest)
413 + if (!imm.m_value && !m_fixedWidth)
416 + if (imm.m_value > 0 && imm.m_value < 65535 && !m_fixedWidth) {
417 + m_assembler.ori(dest, src, imm.m_value);
423 + or dest, src, dataTemp
425 + move(imm, dataTempRegister);
426 + m_assembler.orInsn(dest, src, dataTempRegister);
429 void or32(RegisterID src, AbsoluteAddress dest)
431 load32(dest.m_ptr, dataTempRegister);
432 @@ -360,6 +417,11 @@ public:
433 m_assembler.srav(dest, dest, shiftAmount);
436 + void rshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
438 + m_assembler.srav(dest, src, shiftAmount);
441 void rshift32(TrustedImm32 imm, RegisterID dest)
443 m_assembler.sra(dest, dest, imm.m_value);
444 @@ -375,16 +437,31 @@ public:
445 m_assembler.srlv(dest, dest, shiftAmount);
448 + void urshift32(RegisterID src, RegisterID shiftAmount, RegisterID dest)
450 + m_assembler.srlv(dest, src, shiftAmount);
453 void urshift32(TrustedImm32 imm, RegisterID dest)
455 m_assembler.srl(dest, dest, imm.m_value);
458 + void urshift32(RegisterID src, TrustedImm32 imm, RegisterID dest)
460 + m_assembler.srl(dest, src, imm.m_value);
463 void sub32(RegisterID src, RegisterID dest)
465 m_assembler.subu(dest, dest, src);
468 + void sub32(RegisterID op1, RegisterID op2, RegisterID dest)
470 + m_assembler.subu(dest, op1, op2);
473 void sub32(TrustedImm32 imm, RegisterID dest)
475 if (imm.m_value >= -32767 && imm.m_value <= 32768
476 @@ -495,6 +572,11 @@ public:
477 m_assembler.xorInsn(dest, dest, src);
480 + void xor32(RegisterID op1, RegisterID op2, RegisterID dest)
482 + m_assembler.xorInsn(dest, op1, op2);
485 void xor32(TrustedImm32 imm, RegisterID dest)
487 if (imm.m_value == -1) {
488 @@ -510,6 +592,21 @@ public:
489 m_assembler.xorInsn(dest, dest, immTempRegister);
492 + void xor32(TrustedImm32 imm, RegisterID src, RegisterID dest)
494 + if (imm.m_value == -1) {
495 + m_assembler.nor(dest, src, MIPSRegisters::zero);
501 + xor dest, dest, immTemp
503 + move(imm, immTempRegister);
504 + m_assembler.xorInsn(dest, src, immTempRegister);
507 void sqrtDouble(FPRegisterID src, FPRegisterID dst)
509 m_assembler.sqrtd(dst, src);
510 @@ -989,6 +1086,44 @@ public:
514 + void store32(TrustedImm32 imm, BaseIndex address)
516 + if (address.offset >= -32768 && address.offset <= 32767 && !m_fixedWidth) {
518 + sll addrTemp, address.index, address.scale
519 + addu addrTemp, addrTemp, address.base
520 + sw src, address.offset(addrTemp)
522 + m_assembler.sll(addrTempRegister, address.index, address.scale);
523 + m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
525 + m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset);
527 + move(imm, immTempRegister);
528 + m_assembler.sw(immTempRegister, addrTempRegister, address.offset);
532 + sll addrTemp, address.index, address.scale
533 + addu addrTemp, addrTemp, address.base
534 + lui immTemp, (address.offset + 0x8000) >> 16
535 + addu addrTemp, addrTemp, immTemp
536 + sw src, (address.offset & 0xffff)(at)
538 + m_assembler.sll(addrTempRegister, address.index, address.scale);
539 + m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
540 + m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
541 + m_assembler.addu(addrTempRegister, addrTempRegister, immTempRegister);
542 + if (!imm.m_value && !m_fixedWidth)
543 + m_assembler.sw(MIPSRegisters::zero, addrTempRegister, address.offset);
545 + move(imm, immTempRegister);
546 + m_assembler.sw(immTempRegister, addrTempRegister, address.offset);
552 void store32(RegisterID src, const void* address)
555 @@ -1336,6 +1471,15 @@ public:
556 m_fixedWidth = false;
559 + void jump(AbsoluteAddress address)
561 + m_fixedWidth = true;
562 + load32(address.m_ptr, MIPSRegisters::t9);
563 + m_assembler.jr(MIPSRegisters::t9);
565 + m_fixedWidth = false;
568 void moveDoubleToInts(FPRegisterID src, RegisterID dest1, RegisterID dest2)
570 m_assembler.vmov(dest1, dest2, src);
571 @@ -1404,6 +1548,53 @@ public:
575 + Jump branchAdd32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
577 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
578 + if (cond == Overflow) {
581 + xor cmpTemp, dataTemp, op2
582 + bltz cmpTemp, No_overflow # diff sign bit -> no overflow
583 + addu dest, dataTemp, op2
584 + xor cmpTemp, dest, dataTemp
585 + bgez cmpTemp, No_overflow # same sign big -> no overflow
595 + move(op1, dataTempRegister);
596 + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2);
597 + m_assembler.bltz(cmpTempRegister, 10);
598 + m_assembler.addu(dest, dataTempRegister, op2);
599 + m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
600 + m_assembler.bgez(cmpTempRegister, 7);
604 + if (cond == Signed) {
605 + add32(op1, op2, dest);
606 + // Check if dest is negative.
607 + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
608 + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
610 + if (cond == Zero) {
611 + add32(op1, op2, dest);
612 + return branchEqual(dest, MIPSRegisters::zero);
614 + if (cond == NonZero) {
615 + add32(op1, op2, dest);
616 + return branchNotEqual(dest, MIPSRegisters::zero);
622 Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, RegisterID dest)
624 move(imm, immTempRegister);
625 @@ -1417,6 +1608,111 @@ public:
626 return branchAdd32(cond, immTempRegister, dest);
629 + Jump branchAdd32(ResultCondition cond, TrustedImm32 imm, AbsoluteAddress dest)
631 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
632 + if (cond == Overflow) {
634 + move dataTemp, dest
635 + xori cmpTemp, dataTemp, imm
636 + bltz cmpTemp, No_overflow # diff sign bit -> no overflow
637 + addiu dataTemp, dataTemp, imm
638 + move dest, dataTemp
639 + xori cmpTemp, dataTemp, imm
640 + bgez cmpTemp, No_overflow # same sign big -> no overflow
650 + if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth) {
651 + load32(dest.m_ptr, dataTempRegister);
652 + m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value);
653 + m_assembler.bltz(cmpTempRegister, 10);
654 + m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
655 + store32(dataTempRegister, dest.m_ptr);
656 + m_assembler.xori(cmpTempRegister, dataTempRegister, imm.m_value);
657 + m_assembler.bgez(cmpTempRegister, 7);
660 + load32(dest.m_ptr, dataTempRegister);
661 + move(imm, immTempRegister);
662 + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, immTempRegister);
663 + m_assembler.bltz(cmpTempRegister, 10);
664 + m_assembler.addiu(dataTempRegister, dataTempRegister, immTempRegister);
665 + store32(dataTempRegister, dest.m_ptr);
666 + m_assembler.xori(cmpTempRegister, dataTempRegister, immTempRegister);
667 + m_assembler.bgez(cmpTempRegister, 7);
672 + move(imm, immTempRegister);
673 + load32(dest.m_ptr, dataTempRegister);
674 + add32(immTempRegister, dataTempRegister);
675 + store32(dataTempRegister, dest.m_ptr);
676 + if (cond == Signed) {
677 + // Check if dest is negative.
678 + m_assembler.slt(cmpTempRegister, dataTempRegister, MIPSRegisters::zero);
679 + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
682 + return branchEqual(dataTempRegister, MIPSRegisters::zero);
683 + if (cond == NonZero)
684 + return branchNotEqual(dataTempRegister, MIPSRegisters::zero);
689 + Jump branchMul32(ResultCondition cond, RegisterID src1, RegisterID src2, RegisterID dest)
691 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
692 + if (cond == Overflow) {
697 + sra addrTemp, dest, 31
698 + beq dataTemp, addrTemp, No_overflow # all sign bits (bit 63 to bit 31) are the same -> no overflow
708 + m_assembler.mult(src1, src2);
709 + m_assembler.mfhi(dataTempRegister);
710 + m_assembler.mflo(dest);
711 + m_assembler.sra(addrTempRegister, dest, 31);
712 + m_assembler.beq(dataTempRegister, addrTempRegister, 7);
716 + if (cond == Signed) {
717 + mul32(src1, src2, dest);
718 + // Check if dest is negative.
719 + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
720 + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
722 + if (cond == Zero) {
723 + mul32(src1, src2, dest);
724 + return branchEqual(dest, MIPSRegisters::zero);
726 + if (cond == NonZero) {
727 + mul32(src1, src2, dest);
728 + return branchNotEqual(dest, MIPSRegisters::zero);
734 Jump branchMul32(ResultCondition cond, RegisterID src, RegisterID dest)
736 ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
737 @@ -1465,8 +1761,7 @@ public:
738 Jump branchMul32(ResultCondition cond, TrustedImm32 imm, RegisterID src, RegisterID dest)
740 move(imm, immTempRegister);
742 - return branchMul32(cond, immTempRegister, dest);
743 + return branchMul32(cond, immTempRegister, src, dest);
746 Jump branchSub32(ResultCondition cond, RegisterID src, RegisterID dest)
747 @@ -1525,8 +1820,60 @@ public:
748 Jump branchSub32(ResultCondition cond, RegisterID src, TrustedImm32 imm, RegisterID dest)
750 move(imm, immTempRegister);
752 - return branchSub32(cond, immTempRegister, dest);
753 + return branchSub32(cond, src, immTempRegister, dest);
756 + Jump branchSub32(ResultCondition cond, RegisterID op1, RegisterID op2, RegisterID dest)
758 + ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
759 + if (cond == Overflow) {
762 + xor cmpTemp, dataTemp, op2
763 + bgez cmpTemp, No_overflow # same sign bit -> no overflow
764 + subu dest, dataTemp, op2
765 + xor cmpTemp, dest, dataTemp
766 + bgez cmpTemp, No_overflow # same sign bit -> no overflow
776 + move(op1, dataTempRegister);
777 + m_assembler.xorInsn(cmpTempRegister, dataTempRegister, op2);
778 + m_assembler.bgez(cmpTempRegister, 10);
779 + m_assembler.subu(dest, dataTempRegister, op2);
780 + m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
781 + m_assembler.bgez(cmpTempRegister, 7);
785 + if (cond == Signed) {
786 + sub32(op1, op2, dest);
787 + // Check if dest is negative.
788 + m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
789 + return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
791 + if (cond == Zero) {
792 + sub32(op1, op2, dest);
793 + return branchEqual(dest, MIPSRegisters::zero);
795 + if (cond == NonZero) {
796 + sub32(op1, op2, dest);
797 + return branchNotEqual(dest, MIPSRegisters::zero);
803 + Jump branchNeg32(ResultCondition cond, RegisterID srcDest)
805 + m_assembler.li(dataTempRegister, -1);
806 + return branchMul32(cond, dataTempRegister, srcDest);
809 Jump branchOr32(ResultCondition cond, RegisterID src, RegisterID dest)
810 @@ -1578,7 +1925,8 @@ public:
812 Call call(RegisterID target)
814 - m_assembler.jalr(target);
815 + move(target, MIPSRegisters::t9);
816 + m_assembler.jalr(MIPSRegisters::t9);
818 return Call(m_assembler.label(), Call::None);
820 @@ -1822,7 +2170,7 @@ public:
821 lui immTemp, (address.offset + 0x8000) >> 16
822 addu addrTemp, addrTemp, immTemp
823 lwc1 dest, (address.offset & 0xffff)(at)
824 - lwc1 dest+4, (address.offset & 0xffff + 4)(at)
825 + lwc1 dest+1, (address.offset & 0xffff + 4)(at)
827 m_assembler.sll(addrTempRegister, address.index, address.scale);
828 m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
829 @@ -2009,6 +2357,19 @@ public:
833 + void moveDouble(FPRegisterID src, FPRegisterID dest)
835 + if (src != dest || m_fixedWidth)
836 + m_assembler.movd(dest, src);
839 + void swapDouble(FPRegisterID fr1, FPRegisterID fr2)
841 + moveDouble(fr1, fpTempRegister);
842 + moveDouble(fr2, fr1);
843 + moveDouble(fpTempRegister, fr2);
846 void addDouble(FPRegisterID src, FPRegisterID dest)
848 m_assembler.addd(dest, dest, src);
849 @@ -2036,6 +2397,11 @@ public:
850 m_assembler.subd(dest, dest, src);
853 + void subDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
855 + m_assembler.subd(dest, op1, op2);
858 void subDouble(Address src, FPRegisterID dest)
860 loadDouble(src, fpTempRegister);
861 @@ -2053,11 +2419,32 @@ public:
862 m_assembler.muld(dest, dest, fpTempRegister);
865 + void mulDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
867 + m_assembler.muld(dest, op1, op2);
870 void divDouble(FPRegisterID src, FPRegisterID dest)
872 m_assembler.divd(dest, dest, src);
875 + void divDouble(FPRegisterID op1, FPRegisterID op2, FPRegisterID dest)
877 + m_assembler.divd(dest, op1, op2);
880 + void divDouble(Address src, FPRegisterID dest)
882 + loadDouble(src, fpTempRegister);
883 + m_assembler.divd(dest, dest, fpTempRegister);
886 + void negateDouble(FPRegisterID src, FPRegisterID dest)
888 + m_assembler.negd(dest, src);
891 void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
893 m_assembler.mtc1(src, fpTempRegister);
894 @@ -2117,6 +2504,8 @@ public:
896 Jump branchEqual(RegisterID rs, RegisterID rt)
900 m_assembler.appendJump();
901 m_assembler.beq(rs, rt, 0);
903 @@ -2126,6 +2515,8 @@ public:
905 Jump branchNotEqual(RegisterID rs, RegisterID rt)
909 m_assembler.appendJump();
910 m_assembler.bne(rs, rt, 0);
912 @@ -2192,11 +2583,33 @@ public:
913 // If the result is not representable as a 32 bit value, branch.
914 // May also branch for some values that are representable in 32 bits
915 // (specifically, in this case, INT_MAX 0x7fffffff).
916 - Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
917 + enum BranchTruncateType { BranchIfTruncateFailed, BranchIfTruncateSuccessful };
918 + Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
920 + m_assembler.truncwd(fpTempRegister, src);
921 + m_assembler.mfc1(dest, fpTempRegister);
922 + return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0x7fffffff));
925 + Jump branchTruncateDoubleToUint32(FPRegisterID src, RegisterID dest, BranchTruncateType branchType = BranchIfTruncateFailed)
927 + m_assembler.truncwd(fpTempRegister, src);
928 + m_assembler.mfc1(dest, fpTempRegister);
929 + return branch32(branchType == BranchIfTruncateFailed ? Equal : NotEqual, dest, TrustedImm32(0));
932 + // Result is undefined if the value is outside of the integer range.
933 + void truncateDoubleToInt32(FPRegisterID src, RegisterID dest)
935 + m_assembler.truncwd(fpTempRegister, src);
936 + m_assembler.mfc1(dest, fpTempRegister);
939 + // Result is undefined if src > 2^31
940 + void truncateDoubleToUint32(FPRegisterID src, RegisterID dest)
942 m_assembler.truncwd(fpTempRegister, src);
943 m_assembler.mfc1(dest, fpTempRegister);
944 - return branch32(Equal, dest, TrustedImm32(0x7fffffff));
947 // Convert 'src' to an integer, and places the resulting 'dest'.
948 @@ -2218,28 +2631,43 @@ public:
950 Jump branchDoubleNonZero(FPRegisterID reg, FPRegisterID scratch)
952 -#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
953 - m_assembler.mtc1(MIPSRegisters::zero, scratch);
954 - m_assembler.mthc1(MIPSRegisters::zero, scratch);
956 - m_assembler.mtc1(MIPSRegisters::zero, scratch);
957 - m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1));
959 + m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero);
960 return branchDouble(DoubleNotEqual, reg, scratch);
963 Jump branchDoubleZeroOrNaN(FPRegisterID reg, FPRegisterID scratch)
965 -#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
966 - m_assembler.mtc1(MIPSRegisters::zero, scratch);
967 - m_assembler.mthc1(MIPSRegisters::zero, scratch);
969 - m_assembler.mtc1(MIPSRegisters::zero, scratch);
970 - m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(scratch + 1));
972 + m_assembler.vmov(scratch, MIPSRegisters::zero, MIPSRegisters::zero);
973 return branchDouble(DoubleEqualOrUnordered, reg, scratch);
976 + // Invert a relational condition, e.g. == becomes !=, < becomes >=, etc.
977 + static RelationalCondition invert(RelationalCondition cond)
979 + RelationalCondition r;
982 + else if (cond == NotEqual)
984 + else if (cond == Above)
986 + else if (cond == AboveOrEqual)
988 + else if (cond == Below)
990 + else if (cond == BelowOrEqual)
992 + else if (cond == GreaterThan)
993 + r = LessThanOrEqual;
994 + else if (cond == GreaterThanOrEqual)
996 + else if (cond == LessThan)
997 + r = GreaterThanOrEqual;
998 + else if (cond == LessThanOrEqual)
1006 @@ -2252,12 +2680,12 @@ public:
1008 static void replaceWithJump(CodeLocationLabel instructionStart, CodeLocationLabel destination)
1010 - RELEASE_ASSERT_NOT_REACHED();
1011 + MIPSAssembler::replaceWithJump(instructionStart.dataLocation(), destination.dataLocation());
1014 static ptrdiff_t maxJumpReplacementSize()
1016 - RELEASE_ASSERT_NOT_REACHED();
1017 + MIPSAssembler::maxJumpReplacementSize();
1021 diff --git a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
1022 index fa0f5e0..573d8dc 100644
1023 --- a/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
1024 +++ b/Source/JavaScriptCore/dfg/DFGAssemblyHelpers.h
1025 @@ -93,6 +93,23 @@ public:
1030 + ALWAYS_INLINE void preserveReturnAddressAfterCall(RegisterID reg)
1032 + move(returnAddressRegister, reg);
1035 + ALWAYS_INLINE void restoreReturnAddressBeforeReturn(RegisterID reg)
1037 + move(reg, returnAddressRegister);
1040 + ALWAYS_INLINE void restoreReturnAddressBeforeReturn(Address address)
1042 + loadPtr(address, returnAddressRegister);
1046 void emitGetFromCallFrameHeaderPtr(JSStack::CallFrameHeaderEntry entry, GPRReg to)
1048 loadPtr(Address(GPRInfo::callFrameRegister, entry * sizeof(Register)), to);
1049 @@ -193,7 +210,7 @@ public:
1050 move(TrustedImmPtr(scratchBuffer->activeLengthPtr()), GPRInfo::regT0);
1051 storePtr(TrustedImmPtr(scratchSize), GPRInfo::regT0);
1053 -#if CPU(X86_64) || CPU(ARM)
1054 +#if CPU(X86_64) || CPU(ARM) || CPU(MIPS)
1055 move(TrustedImmPtr(buffer), GPRInfo::argumentGPR2);
1056 move(TrustedImmPtr(argument), GPRInfo::argumentGPR1);
1057 move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1058 diff --git a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
1059 index 8adde05..3d99f6f 100644
1060 --- a/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
1061 +++ b/Source/JavaScriptCore/dfg/DFGCCallHelpers.h
1062 @@ -576,6 +576,39 @@ public:
1063 poke(GPRInfo::nonArgGPR0);
1065 #endif // CPU(ARM_HARDFP)
1067 + ALWAYS_INLINE void setupArguments(FPRReg arg1)
1069 + moveDouble(arg1, FPRInfo::argumentFPR0);
1072 + ALWAYS_INLINE void setupArguments(FPRReg arg1, FPRReg arg2)
1074 + if (arg2 != FPRInfo::argumentFPR0) {
1075 + moveDouble(arg1, FPRInfo::argumentFPR0);
1076 + moveDouble(arg2, FPRInfo::argumentFPR1);
1077 + } else if (arg1 != FPRInfo::argumentFPR1) {
1078 + moveDouble(arg2, FPRInfo::argumentFPR1);
1079 + moveDouble(arg1, FPRInfo::argumentFPR0);
1081 + // Swap arg1, arg2.
1082 + swapDouble(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1);
1086 + ALWAYS_INLINE void setupArgumentsWithExecState(FPRReg arg1, GPRReg arg2)
1088 + assembler().vmov(GPRInfo::argumentGPR2, GPRInfo::argumentGPR3, arg1);
1089 + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1093 + ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, FPRReg arg3)
1095 + setupStubArguments(arg1, arg2);
1096 + move(GPRInfo::callFrameRegister, GPRInfo::argumentGPR0);
1100 #error "DFG JIT not supported on this platform."
1102 @@ -803,119 +836,126 @@ public:
1103 // These methods are suitable for any calling convention that provides for
1104 // exactly 4 argument registers, e.g. ARMv7.
1105 #if NUMBER_OF_ARGUMENT_REGISTERS == 4
1108 +#define POKE_ARGUMENT_OFFSET 4
1110 +#define POKE_ARGUMENT_OFFSET 0
1113 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
1116 + poke(arg4, POKE_ARGUMENT_OFFSET);
1117 setupArgumentsWithExecState(arg1, arg2, arg3);
1120 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4)
1123 + poke(arg4, POKE_ARGUMENT_OFFSET);
1124 setupArgumentsWithExecState(arg1, arg2, arg3);
1127 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4)
1130 + poke(arg4, POKE_ARGUMENT_OFFSET);
1131 setupArgumentsWithExecState(arg1, arg2, arg3);
1134 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, TrustedImmPtr arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1138 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1139 + poke(arg4, POKE_ARGUMENT_OFFSET);
1140 setupArgumentsWithExecState(arg1, arg2, arg3);
1143 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImm32 arg4)
1146 + poke(arg4, POKE_ARGUMENT_OFFSET);
1147 setupArgumentsWithExecState(arg1, arg2, arg3);
1150 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, GPRReg arg3, GPRReg arg4)
1153 + poke(arg4, POKE_ARGUMENT_OFFSET);
1154 setupArgumentsWithExecState(arg1, arg2, arg3);
1157 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1160 + poke(arg4, POKE_ARGUMENT_OFFSET);
1161 setupArgumentsWithExecState(arg1, arg2, arg3);
1164 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
1168 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1169 + poke(arg4, POKE_ARGUMENT_OFFSET);
1170 setupArgumentsWithExecState(arg1, arg2, arg3);
1173 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4)
1176 + poke(arg4, POKE_ARGUMENT_OFFSET);
1177 setupArgumentsWithExecState(arg1, arg2, arg3);
1180 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImmPtr arg4)
1183 + poke(arg4, POKE_ARGUMENT_OFFSET);
1184 setupArgumentsWithExecState(arg1, arg2, arg3);
1187 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, TrustedImmPtr arg4)
1190 + poke(arg4, POKE_ARGUMENT_OFFSET);
1191 setupArgumentsWithExecState(arg1, arg2, arg3);
1194 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4)
1197 + poke(arg4, POKE_ARGUMENT_OFFSET);
1198 setupArgumentsWithExecState(arg1, arg2, arg3);
1201 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1205 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1206 + poke(arg4, POKE_ARGUMENT_OFFSET);
1207 setupArgumentsWithExecState(arg1, arg2, arg3);
1210 ALWAYS_INLINE void setupArgumentsWithExecState(GPRReg arg1, GPRReg arg2, TrustedImm32 arg3, GPRReg arg4, TrustedImm32 arg5)
1214 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1215 + poke(arg4, POKE_ARGUMENT_OFFSET);
1216 setupArgumentsWithExecState(arg1, arg2, arg3);
1219 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, TrustedImmPtr arg5)
1223 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1224 + poke(arg4, POKE_ARGUMENT_OFFSET);
1225 setupArgumentsWithExecState(arg1, arg2, arg3);
1228 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, TrustedImm32 arg4, TrustedImm32 arg5)
1232 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1233 + poke(arg4, POKE_ARGUMENT_OFFSET);
1234 setupArgumentsWithExecState(arg1, arg2, arg3);
1237 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, TrustedImm32 arg2, TrustedImm32 arg3, GPRReg arg4, GPRReg arg5)
1241 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1242 + poke(arg4, POKE_ARGUMENT_OFFSET);
1243 setupArgumentsWithExecState(arg1, arg2, arg3);
1246 ALWAYS_INLINE void setupArgumentsWithExecState(TrustedImm32 arg1, GPRReg arg2, GPRReg arg3, GPRReg arg4, GPRReg arg5)
1250 + poke(arg5, POKE_ARGUMENT_OFFSET + 1);
1251 + poke(arg4, POKE_ARGUMENT_OFFSET);
1252 setupArgumentsWithExecState(arg1, arg2, arg3);
1255 diff --git a/Source/JavaScriptCore/dfg/DFGFPRInfo.h b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
1256 index 17aaa7d..e18ec06 100644
1257 --- a/Source/JavaScriptCore/dfg/DFGFPRInfo.h
1258 +++ b/Source/JavaScriptCore/dfg/DFGFPRInfo.h
1259 @@ -164,6 +164,74 @@ public:
1267 + typedef FPRReg RegisterType;
1268 + static const unsigned numberOfRegisters = 6;
1270 + // Temporary registers.
1271 + static const FPRReg fpRegT0 = MIPSRegisters::f0;
1272 + static const FPRReg fpRegT1 = MIPSRegisters::f4;
1273 + static const FPRReg fpRegT2 = MIPSRegisters::f6;
1274 + static const FPRReg fpRegT3 = MIPSRegisters::f8;
1275 + static const FPRReg fpRegT4 = MIPSRegisters::f10;
1276 + static const FPRReg fpRegT5 = MIPSRegisters::f18;
1278 + static const FPRReg returnValueFPR = MIPSRegisters::f0;
1280 + static const FPRReg argumentFPR0 = MIPSRegisters::f12;
1281 + static const FPRReg argumentFPR1 = MIPSRegisters::f14;
1283 + static FPRReg toRegister(unsigned index)
1285 + static const FPRReg registerForIndex[numberOfRegisters] = {
1286 + fpRegT0, fpRegT1, fpRegT2, fpRegT3, fpRegT4, fpRegT5 };
1288 + ASSERT(index < numberOfRegisters);
1289 + return registerForIndex[index];
1292 + static unsigned toIndex(FPRReg reg)
1294 + ASSERT(reg != InvalidFPRReg);
1296 + static const unsigned indexForRegister[20] = {
1297 + 0, InvalidIndex, InvalidIndex, InvalidIndex,
1298 + 1, InvalidIndex, 2, InvalidIndex,
1299 + 3, InvalidIndex, 4, InvalidIndex,
1300 + InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex,
1301 + InvalidIndex, InvalidIndex, 5, InvalidIndex,
1303 + unsigned result = indexForRegister[reg];
1304 + ASSERT(result != InvalidIndex);
1308 + static const char* debugName(FPRReg reg)
1310 + ASSERT(reg != InvalidFPRReg);
1312 + static const char* nameForRegister[32] = {
1313 + "f0", "f1", "f2", "f3",
1314 + "f4", "f5", "f6", "f7",
1315 + "f8", "f9", "f10", "f11",
1316 + "f12", "f13", "f14", "f15"
1317 + "f16", "f17", "f18", "f19"
1318 + "f20", "f21", "f22", "f23"
1319 + "f24", "f25", "f26", "f27"
1320 + "f28", "f29", "f30", "f31"
1322 + return nameForRegister[reg];
1326 + static const unsigned InvalidIndex = 0xffffffff;
1331 typedef RegisterBank<FPRInfo>::iterator fpr_iterator;
1333 } } // namespace JSC::DFG
1334 diff --git a/Source/JavaScriptCore/dfg/DFGGPRInfo.h b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
1335 index 3d07556..aa634cd 100644
1336 --- a/Source/JavaScriptCore/dfg/DFGGPRInfo.h
1337 +++ b/Source/JavaScriptCore/dfg/DFGGPRInfo.h
1338 @@ -461,6 +461,73 @@ private:
1343 +#define NUMBER_OF_ARGUMENT_REGISTERS 4
1347 + typedef GPRReg RegisterType;
1348 + static const unsigned numberOfRegisters = 6;
1350 + // Temporary registers.
1351 + static const GPRReg regT0 = MIPSRegisters::v0;
1352 + static const GPRReg regT1 = MIPSRegisters::v1;
1353 + static const GPRReg regT2 = MIPSRegisters::t4;
1354 + static const GPRReg regT3 = MIPSRegisters::t5;
1355 + static const GPRReg regT4 = MIPSRegisters::t6;
1356 + static const GPRReg regT5 = MIPSRegisters::t7;
1357 + // These registers match the baseline JIT.
1358 + static const GPRReg cachedResultRegister = regT0;
1359 + static const GPRReg cachedResultRegister2 = regT1;
1360 + static const GPRReg callFrameRegister = MIPSRegisters::s0;
1361 + // These constants provide the names for the general purpose argument & return value registers.
1362 + static const GPRReg argumentGPR0 = MIPSRegisters::a0;
1363 + static const GPRReg argumentGPR1 = MIPSRegisters::a1;
1364 + static const GPRReg argumentGPR2 = MIPSRegisters::a2;
1365 + static const GPRReg argumentGPR3 = MIPSRegisters::a3;
1366 + static const GPRReg nonArgGPR0 = regT2;
1367 + static const GPRReg nonArgGPR1 = regT3;
1368 + static const GPRReg nonArgGPR2 = regT4;
1369 + static const GPRReg returnValueGPR = regT0;
1370 + static const GPRReg returnValueGPR2 = regT1;
1371 + static const GPRReg nonPreservedNonReturnGPR = regT5;
1373 + static GPRReg toRegister(unsigned index)
1375 + ASSERT(index < numberOfRegisters);
1376 + static const GPRReg registerForIndex[numberOfRegisters] = { regT0, regT1, regT2, regT3, regT4, regT5 };
1377 + return registerForIndex[index];
1380 + static unsigned toIndex(GPRReg reg)
1382 + ASSERT(reg != InvalidGPRReg);
1384 + static const unsigned indexForRegister[16] = { InvalidIndex, InvalidIndex, 0, 1, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, InvalidIndex, 2, 3, 4, 5 };
1385 + unsigned result = indexForRegister[reg];
1386 + ASSERT(result != InvalidIndex);
1390 + static const char* debugName(GPRReg reg)
1392 + ASSERT(reg != InvalidGPRReg);
1394 + static const char* nameForRegister[16] = {
1395 + "zero", "at", "v0", "v1",
1396 + "a0", "a1", "a2", "a3",
1397 + "t0", "t1", "t2", "t3",
1398 + "t4", "t5", "t6", "t7"
1400 + return nameForRegister[reg];
1404 + static const unsigned InvalidIndex = 0xffffffff;
1409 typedef RegisterBank<GPRInfo>::iterator gpr_iterator;
1411 } } // namespace JSC::DFG
1412 diff --git a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
1413 index ea33f38..247274b 100644
1414 --- a/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
1415 +++ b/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.h
1416 @@ -1241,7 +1241,7 @@ public:
1418 // 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]).
1419 // To avoid assemblies from using wrong registers, let's occupy r1 or r3 with a dummy argument when necessary.
1420 -#if COMPILER_SUPPORTS(EABI) && CPU(ARM)
1421 +#if (COMPILER_SUPPORTS(EABI) && CPU(ARM)) || CPU(MIPS)
1422 #define EABI_32BIT_DUMMY_ARG TrustedImm32(0),
1424 #define EABI_32BIT_DUMMY_ARG
1425 @@ -1691,7 +1691,7 @@ public:
1429 -#if !defined(NDEBUG) && !CPU(ARM)
1430 +#if !defined(NDEBUG) && !CPU(ARM) && !CPU(MIPS)
1431 void prepareForExternalCall()
1433 // We're about to call out to a "native" helper function. The helper
1434 diff --git a/Source/JavaScriptCore/jit/JSInterfaceJIT.h b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
1435 index 7fdeaf0..48ad6b2 100644
1436 --- a/Source/JavaScriptCore/jit/JSInterfaceJIT.h
1437 +++ b/Source/JavaScriptCore/jit/JSInterfaceJIT.h
1438 @@ -125,6 +125,10 @@ namespace JSC {
1439 static const RegisterID cachedResultRegister = MIPSRegisters::v0;
1440 static const RegisterID firstArgumentRegister = MIPSRegisters::a0;
1442 +#if ENABLE(VALUE_PROFILER)
1443 + static const RegisterID bucketCounterRegister = MIPSRegisters::s3;
1446 // regT0 must be v0 for returning a 32-bit value.
1447 static const RegisterID regT0 = MIPSRegisters::v0;
1449 diff --git a/Source/JavaScriptCore/runtime/JSGlobalData.h b/Source/JavaScriptCore/runtime/JSGlobalData.h
1450 index 5d47ab9..c02f336 100644
1451 --- a/Source/JavaScriptCore/runtime/JSGlobalData.h
1452 +++ b/Source/JavaScriptCore/runtime/JSGlobalData.h
1453 @@ -141,14 +141,18 @@ namespace JSC {
1457 - static size_t allocationSize(size_t bufferSize) { return sizeof(size_t) + bufferSize; }
1458 + static size_t allocationSize(size_t bufferSize) { return sizeof(ScratchBuffer) + bufferSize; }
1459 void setActiveLength(size_t activeLength) { m_activeLength = activeLength; }
1460 size_t activeLength() const { return m_activeLength; };
1461 size_t* activeLengthPtr() { return &m_activeLength; };
1462 void* dataBuffer() { return m_buffer; }
1464 size_t m_activeLength;
1465 +#if CPU(MIPS) && (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == 2)
1466 + void* m_buffer[0] __attribute__((aligned(8)));
1472 #pragma warning(pop)
1473 diff --git a/Source/WTF/wtf/Platform.h b/Source/WTF/wtf/Platform.h
1474 index 1698247..2d90359 100644
1475 --- a/Source/WTF/wtf/Platform.h
1476 +++ b/Source/WTF/wtf/Platform.h
1477 @@ -818,6 +818,10 @@
1478 #if CPU(ARM_TRADITIONAL)
1479 #define ENABLE_DFG_JIT 1
1481 +/* Enable the DFG JIT on MIPS. */
1483 +#define ENABLE_DFG_JIT 1
1487 /* If the jit is not available, enable the LLInt C Loop: */