diff options
author | commit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-11-04 18:21:37 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-20 15:02:14 +0100 |
commit | 966168b00e96a42391090037bd1fc1af13634dea (patch) | |
tree | 98891462a3fc2f7dfa5690663a4d31a90c97deee /Source/JavaScriptCore/assembler | |
parent | cd3b33ac489a22c23d2d0a94c8df2b87a8b34eb9 (diff) | |
download | qtwebkit-966168b00e96a42391090037bd1fc1af13634dea.tar.gz |
[sh4] Refactor jumps in baseline JIT to return label after the jump.
https://bugs.webkit.org/show_bug.cgi?id=123734
Patch by Julien Brianceau <jbriance@cisco.com> on 2013-11-04
Reviewed by Michael Saboff.
Current implementation of jumps in sh4 baseline JIT returns a label on the jump itself
and not after it. This is not correct and leads to issues like infinite loop the DFG
(https://bugs.webkit.org/show_bug.cgi?id=122597 for instance). This refactor fixes this
and also simplifies the link and relink procedures for sh4 jumps.
* assembler/MacroAssemblerSH4.h:
(JSC::MacroAssemblerSH4::branchDouble):
(JSC::MacroAssemblerSH4::branchTrue):
(JSC::MacroAssemblerSH4::branchFalse):
* assembler/SH4Assembler.h:
(JSC::SH4Assembler::jmp):
(JSC::SH4Assembler::extraInstrForBranch):
(JSC::SH4Assembler::jne):
(JSC::SH4Assembler::je):
(JSC::SH4Assembler::bra):
(JSC::SH4Assembler::linkJump):
(JSC::SH4Assembler::relinkJump):
Change-Id: Ia31b326a1f3c41e9c913e513563ff1e6b8f8e55e
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@158580 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/assembler')
-rw-r--r-- | Source/JavaScriptCore/assembler/MacroAssemblerSH4.h | 25 | ||||
-rw-r--r-- | Source/JavaScriptCore/assembler/SH4Assembler.h | 101 |
2 files changed, 33 insertions, 93 deletions
diff --git a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h index ad5acfaeb..c2293ed14 100644 --- a/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h +++ b/Source/JavaScriptCore/assembler/MacroAssemblerSH4.h @@ -1452,10 +1452,9 @@ public: m_assembler.dcmppeq(right, right); takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppeq(left, right); - Jump m_jump = Jump(m_assembler.je()); + m_assembler.branch(BF_OPCODE, 2); takeBranch.link(this); - m_assembler.extraInstrForBranch(scratchReg3); - return m_jump; + return Jump(m_assembler.extraInstrForBranch(scratchReg3)); } if (cond == DoubleGreaterThanOrUnordered) { @@ -1466,10 +1465,9 @@ public: m_assembler.dcmppeq(right, right); takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(right, left); - Jump m_jump = Jump(m_assembler.je()); + m_assembler.branch(BF_OPCODE, 2); takeBranch.link(this); - m_assembler.extraInstrForBranch(scratchReg3); - return m_jump; + return Jump(m_assembler.extraInstrForBranch(scratchReg3)); } if (cond == DoubleGreaterThanOrEqualOrUnordered) { @@ -1485,10 +1483,9 @@ public: m_assembler.dcmppeq(right, right); takeBranch.append(Jump(m_assembler.jne(), SH4Assembler::JumpNear)); m_assembler.dcmppgt(left, right); - Jump m_jump = Jump(m_assembler.je()); + m_assembler.branch(BF_OPCODE, 2); takeBranch.link(this); - m_assembler.extraInstrForBranch(scratchReg3); - return m_jump; + return Jump(m_assembler.extraInstrForBranch(scratchReg3)); } if (cond == DoubleLessThanOrEqualOrUnordered) { @@ -1504,17 +1501,15 @@ public: Jump branchTrue() { m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t)); - Jump m_jump = Jump(m_assembler.je()); - m_assembler.extraInstrForBranch(scratchReg3); - return m_jump; + m_assembler.branch(BF_OPCODE, 2); + return Jump(m_assembler.extraInstrForBranch(scratchReg3)); } Jump branchFalse() { m_assembler.ensureSpace(m_assembler.maxInstructionSize + 6, sizeof(uint32_t)); - Jump m_jump = Jump(m_assembler.jne()); - m_assembler.extraInstrForBranch(scratchReg3); - return m_jump; + m_assembler.branch(BT_OPCODE, 2); + return Jump(m_assembler.extraInstrForBranch(scratchReg3)); } Jump branch32(RelationalCondition cond, BaseIndex left, TrustedImm32 right) diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h index 55f974a29..59d42d6e2 100644 --- a/Source/JavaScriptCore/assembler/SH4Assembler.h +++ b/Source/JavaScriptCore/assembler/SH4Assembler.h @@ -1241,19 +1241,19 @@ public: { RegisterID scr = claimScratch(); m_buffer.ensureSpace(maxInstructionSize + 4, sizeof(uint32_t)); - AssemblerLabel label = m_buffer.label(); loadConstantUnReusable(0x0, scr); branch(BRAF_OPCODE, scr); nop(); releaseScratch(scr); - return label; + return m_buffer.label(); } - void extraInstrForBranch(RegisterID dst) + AssemblerLabel extraInstrForBranch(RegisterID dst) { loadConstantUnReusable(0x0, dst); + branch(BRAF_OPCODE, dst); nop(); - nop(); + return m_buffer.label(); } AssemblerLabel jmp(RegisterID dst) @@ -1271,23 +1271,20 @@ public: AssemblerLabel jne() { - AssemblerLabel label = m_buffer.label(); branch(BF_OPCODE, 0); - return label; + return m_buffer.label(); } AssemblerLabel je() { - AssemblerLabel label = m_buffer.label(); branch(BT_OPCODE, 0); - return label; + return m_buffer.label(); } AssemblerLabel bra() { - AssemblerLabel label = m_buffer.label(); branch(BRA_OPCODE, 0); - return label; + return m_buffer.label(); } void ret() @@ -1361,33 +1358,16 @@ public: { ASSERT(from.isSet()); - uint16_t* instructionPtr = getInstructionPtr(code, from.m_offset); - uint16_t instruction = *instructionPtr; + uint16_t* instructionPtr = getInstructionPtr(code, from.m_offset) - 3; int offsetBits = (reinterpret_cast<uint32_t>(to) - reinterpret_cast<uint32_t>(code)) - from.m_offset; - if (((instruction & 0xff00) == BT_OPCODE) || ((instruction & 0xff00) == BF_OPCODE)) { - /* BT label ==> BF 2 - nop LDR reg - nop braf @reg - nop nop - */ - offsetBits -= 8; - instruction ^= 0x0202; - *instructionPtr++ = instruction; - changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits); - instruction = (BRAF_OPCODE | (*instructionPtr++ & 0xf00)); - *instructionPtr = instruction; - printBlockInstr(instructionPtr - 2, from.m_offset, 3); - return; - } - - /* MOV #imm, reg => LDR reg - braf @reg braf @reg - nop nop - */ + /* MOV #imm, reg => LDR reg + braf @reg braf @reg + nop nop + */ ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE); ASSERT((instructionPtr[1] & 0xf0ff) == BRAF_OPCODE); - changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 6); + changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits); printInstr(*instructionPtr, from.m_offset + 2); } @@ -1490,24 +1470,10 @@ public: static void relinkJump(void* from, void* to) { uint16_t* instructionPtr = reinterpret_cast<uint16_t*> (from); - uint16_t instruction = *instructionPtr; - int32_t offsetBits = (reinterpret_cast<uint32_t>(to) - reinterpret_cast<uint32_t>(from)); - - if (((*instructionPtr & 0xff00) == BT_OPCODE) || ((*instructionPtr & 0xff00) == BF_OPCODE)) { - offsetBits -= 8; - instructionPtr++; - ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE); - changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits); - instruction = (BRAF_OPCODE | (*instructionPtr++ & 0xf00)); - *instructionPtr = instruction; - printBlockInstr(instructionPtr, reinterpret_cast<uint32_t>(from) + 1, 3); - cacheFlush(instructionPtr, sizeof(SH4Word)); - return; - } - + instructionPtr -= 3; + ASSERT((instructionPtr[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE); ASSERT((instructionPtr[1] & 0xf0ff) == BRAF_OPCODE); - changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits - 6); - printInstr(*instructionPtr, reinterpret_cast<uint32_t>(from)); + changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, reinterpret_cast<uint32_t>(to) - reinterpret_cast<uint32_t>(from)); } // Linking & patching @@ -1559,12 +1525,12 @@ public: ASSERT(to.isSet()); ASSERT(from.isSet()); - uint16_t* instructionPtr = getInstructionPtr(data(), from.m_offset); - uint16_t instruction = *instructionPtr; - int offsetBits; + uint16_t* instructionPtr = getInstructionPtr(data(), from.m_offset) - 1; + int offsetBits = (to.m_offset - from.m_offset); if (type == JumpNear) { - int offset = (codeSize() - from.m_offset) - 4; + uint16_t instruction = instructionPtr[0]; + int offset = (offsetBits - 2); ASSERT((((instruction == BT_OPCODE) || (instruction == BF_OPCODE)) && (offset >= -256) && (offset <= 254)) || ((instruction == BRA_OPCODE) && (offset >= -4096) && (offset <= 4094))); *instructionPtr++ = instruction | (offset >> 1); @@ -1572,35 +1538,14 @@ public: return; } - if (((instruction & 0xff00) == BT_OPCODE) || ((instruction & 0xff00) == BF_OPCODE)) { - /* BT label => BF 2 - nop LDR reg - nop braf @reg - nop nop - */ - offsetBits = (to.m_offset - from.m_offset) - 8; - instruction ^= 0x0202; - *instructionPtr++ = instruction; - if ((*instructionPtr & 0xf000) == MOVIMM_OPCODE) { - uint32_t* addr = getLdrImmAddressOnPool(instructionPtr, m_buffer.poolAddress()); - *addr = offsetBits; - } else - changePCrelativeAddress((*instructionPtr & 0xff), instructionPtr, offsetBits); - instruction = (BRAF_OPCODE | (*instructionPtr++ & 0xf00)); - *instructionPtr = instruction; - printBlockInstr(instructionPtr - 2, from.m_offset, 3); - return; - } - /* MOV # imm, reg => LDR reg braf @reg braf @reg nop nop */ - ASSERT((*(instructionPtr + 1) & BRAF_OPCODE) == BRAF_OPCODE); - offsetBits = (to.m_offset - from.m_offset) - 6; + instructionPtr -= 2; + ASSERT((instructionPtr[1] & 0xf0ff) == BRAF_OPCODE); - instruction = *instructionPtr; - if ((instruction & 0xf000) == MOVIMM_OPCODE) { + if ((instructionPtr[0] & 0xf000) == MOVIMM_OPCODE) { uint32_t* addr = getLdrImmAddressOnPool(instructionPtr, m_buffer.poolAddress()); *addr = offsetBits; printInstr(*instructionPtr, from.m_offset + 2); |