+ static ptrdiff_t maxJumpReplacementSize()
+ {
+ return sizeof(SH4Word) * 6;
+ }
+
+ 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));
+ int nbinst = 0;
+
+ if ((difference >= -4096) && (difference <= 4094)) {
+ instruction[0] = getOpcodeGroup6(BRA_OPCODE, difference >> 1);
+ instruction[1] = NOP_OPCODE;
+ cacheFlush(instruction, sizeof(SH4Word) * 2);
+ return;
+ }
+
+ instruction[nbinst++] = getOpcodeGroup3(MOVL_READ_OFFPC_OPCODE, scratchReg2, 1);
+ instruction[nbinst++] = getOpcodeGroup2(JMP_OPCODE, scratchReg2);
+ instruction[nbinst++] = NOP_OPCODE;
+
+ if (!(reinterpret_cast<unsigned>(instruction) & 3))
+ instruction[nbinst++] = NOP_OPCODE;
+
+ instruction[nbinst++] = reinterpret_cast<unsigned>(to) & 0xffff;
+ instruction[nbinst++] = reinterpret_cast<unsigned>(to) >> 16;
+ cacheFlush(instruction, sizeof(SH4Word) * nbinst);
+ }
+
+ static void revertJump(void* instructionStart, void *immptr)
+ {
+ SH4Word *insn = reinterpret_cast<SH4Word*>(instructionStart);
+ ASSERT((insn[0] & 0xf000) == MOVL_READ_OFFPC_OPCODE);
+ changePCrelativeAddress(insn[0] & 0x00ff, insn, reinterpret_cast<uint32_t>(immptr));
+ }
+