diff options
author | commit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | 2013-11-18 07:51:26 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-11-20 15:02:31 +0100 |
commit | 21d9ab61a7efd4a5e55144fb61a968c49b92c3aa (patch) | |
tree | 41575726a7d15bf3a59ce3817e4792fa10dfa730 /Source/JavaScriptCore/assembler/SH4Assembler.h | |
parent | b16a154901c1efbdf877b4fb28daa939ec04c5f5 (diff) | |
download | qtwebkit-21d9ab61a7efd4a5e55144fb61a968c49b92c3aa.tar.gz |
[sh4] Fix revertJumpReplacementToBranchPtrWithPatch in MacroAssembler.
https://bugs.webkit.org/show_bug.cgi?id=124468
Patch by Julien Brianceau <jbriance@cisco.com> on 2013-11-17
Reviewed by Michael Saboff.
Current implementation of revertJumpReplacementToBranchPtrWithPatch is wrong in
the sh4 MacroAssembler part, leading to random instabilities. This patch fixes it
and also renames the bad-named revertJumpToMove to revertJumpReplacementToBranchPtrWithPatch
in the SH4Assembler.
* assembler/MacroAssemblerSH4.h:
(JSC::MacroAssemblerSH4::revertJumpReplacementToBranchPtrWithPatch):
* assembler/SH4Assembler.h:
(JSC::SH4Assembler::replaceWithJump):
(JSC::SH4Assembler::revertJumpReplacementToBranchPtrWithPatch):
Change-Id: Ifbc6851f506a1303c85cff3a47c23e932fad033c
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159400 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/JavaScriptCore/assembler/SH4Assembler.h')
-rw-r--r-- | Source/JavaScriptCore/assembler/SH4Assembler.h | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/Source/JavaScriptCore/assembler/SH4Assembler.h b/Source/JavaScriptCore/assembler/SH4Assembler.h index 41afeaf3c..f9f70ad26 100644 --- a/Source/JavaScriptCore/assembler/SH4Assembler.h +++ b/Source/JavaScriptCore/assembler/SH4Assembler.h @@ -1493,9 +1493,13 @@ public: static void replaceWithJump(void *instructionStart, void *to) { SH4Word* instruction = reinterpret_cast<SH4Word*>(instructionStart); - intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + 2 * sizeof(SH4Word)); + intptr_t difference = reinterpret_cast<intptr_t>(to) - (reinterpret_cast<intptr_t>(instruction) + 3 * sizeof(SH4Word)); if ((instruction[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE) { + // We have an entry in constant pool and we potentially replace a branchPtrWithPatch, so let's backup what would be the + // condition (CMP/xx and Bx opcodes) for later use in revertJumpReplacementToBranchPtrWithPatch before putting the jump. + instruction[4] = instruction[1]; + instruction[5] = instruction[2]; instruction[1] = (BRAF_OPCODE | (instruction[0] & 0x0f00)); instruction[2] = NOP_OPCODE; cacheFlush(&instruction[1], 2 * sizeof(SH4Word)); @@ -1506,22 +1510,32 @@ public: cacheFlush(instruction, 3 * sizeof(SH4Word)); } - changePCrelativeAddress(instruction[0] & 0x00ff, instruction, difference - 2); + changePCrelativeAddress(instruction[0] & 0x00ff, instruction, difference); } - static void revertJumpToMove(void* instructionStart, RegisterID rd, int imm) + static void revertJumpReplacementToBranchPtrWithPatch(void* instructionStart, RegisterID rd, int imm) { SH4Word *insn = reinterpret_cast<SH4Word*>(instructionStart); ASSERT((insn[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE); - - if ((insn[1] & 0xf000) == CMPEQ_OPCODE) { - insn[0] = getOpcodeGroup3(MOVL_READ_OFFPC_OPCODE, SH4Registers::r13, insn[0] & 0x00ff); + ASSERT((insn[0] & 0x00ff) != 1); + + insn[0] = getOpcodeGroup3(MOVL_READ_OFFPC_OPCODE, SH4Registers::r13, insn[0] & 0x00ff); + if ((insn[1] & 0xf0ff) == BRAF_OPCODE) { + insn[1] = (insn[4] & 0xf00f) | (rd << 8) | (SH4Registers::r13 << 4); // Restore CMP/xx opcode. + insn[2] = insn[5]; + ASSERT(((insn[2] & 0xff00) == BT_OPCODE) || ((insn[2] & 0xff00) == BF_OPCODE)); + ASSERT((insn[3] & 0xf000) == MOVL_READ_OFFPC_OPCODE); + insn[4] = (BRAF_OPCODE | (insn[3] & 0x0f00)); + insn[5] = NOP_OPCODE; + cacheFlush(insn, 6 * sizeof(SH4Word)); + } else { + // The branchPtrWithPatch has already been restored, so we just patch the immediate value and ASSERT all is as expected. + ASSERT((insn[1] & 0xf000) == 0x3000); insn[1] = (insn[1] & 0xf00f) | (rd << 8) | (SH4Registers::r13 << 4); cacheFlush(insn, 2 * sizeof(SH4Word)); - } else { - insn[1] = getOpcodeGroup6(BRA_OPCODE, 3); - insn[2] = NOP_OPCODE; - cacheFlush(&insn[1], 2 * sizeof(SH4Word)); + ASSERT(((insn[2] & 0xff00) == BT_OPCODE) || ((insn[2] & 0xff00) == BF_OPCODE)); + ASSERT((insn[3] & 0xf000) == MOVL_READ_OFFPC_OPCODE); + ASSERT(insn[5] == NOP_OPCODE); } changePCrelativeAddress(insn[0] & 0x00ff, insn, imm); |