mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 16:36:40 +00:00
Implement MipsJITInfo::replaceMachineCodeForFunction.
No new test case is added. This patch makes test JITTest.FunctionIsRecompiledAndRelinked pass on mips platform. Patch by Petar Jovanovic. llvm-svn: 161098
This commit is contained in:
parent
e5d91bee71
commit
731add334a
@ -27,7 +27,52 @@ using namespace llvm;
|
||||
|
||||
|
||||
void MipsJITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
|
||||
report_fatal_error("MipsJITInfo::replaceMachineCodeForFunction");
|
||||
unsigned NewAddr = (intptr_t)New;
|
||||
unsigned OldAddr = (intptr_t)Old;
|
||||
const unsigned NopInstr = 0x0;
|
||||
|
||||
// If the functions are in the same memory segment, insert PC-region branch.
|
||||
if ((NewAddr & 0xF0000000) == ((OldAddr + 4) & 0xF0000000)) {
|
||||
unsigned *OldInstruction = (unsigned *)Old;
|
||||
*OldInstruction = 0x08000000;
|
||||
unsigned JTargetAddr = NewAddr & 0x0FFFFFFC;
|
||||
|
||||
JTargetAddr >>= 2;
|
||||
*OldInstruction |= JTargetAddr;
|
||||
|
||||
// Insert a NOP.
|
||||
OldInstruction++;
|
||||
*OldInstruction = NopInstr;
|
||||
|
||||
sys::Memory::InvalidateInstructionCache(Old, 2 * 4);
|
||||
} else {
|
||||
// We need to clear hint bits from the instruction, in case it is 'jr ra'.
|
||||
const unsigned HintMask = 0xFFFFF83F, ReturnSequence = 0x03e00008;
|
||||
unsigned* CurrentInstr = (unsigned*)Old;
|
||||
unsigned CurrInstrHintClear = (*CurrentInstr) & HintMask;
|
||||
unsigned* NextInstr = CurrentInstr + 1;
|
||||
unsigned NextInstrHintClear = (*NextInstr) & HintMask;
|
||||
|
||||
// Do absolute jump if there are 2 or more instructions before return from
|
||||
// the old function.
|
||||
if ((CurrInstrHintClear != ReturnSequence) &&
|
||||
(NextInstrHintClear != ReturnSequence)) {
|
||||
const unsigned LuiT0Instr = 0x3c080000, AddiuT0Instr = 0x25080000;
|
||||
const unsigned JrT0Instr = 0x01000008;
|
||||
// lui t0, high 16 bit of the NewAddr
|
||||
(*(CurrentInstr++)) = LuiT0Instr | ((NewAddr & 0xffff0000) >> 16);
|
||||
// addiu t0, t0, low 16 bit of the NewAddr
|
||||
(*(CurrentInstr++)) = AddiuT0Instr | (NewAddr & 0x0000ffff);
|
||||
// jr t0
|
||||
(*(CurrentInstr++)) = JrT0Instr;
|
||||
(*CurrentInstr) = NopInstr;
|
||||
|
||||
sys::Memory::InvalidateInstructionCache(Old, 4 * 4);
|
||||
} else {
|
||||
// Unsupported case
|
||||
report_fatal_error("MipsJITInfo::replaceMachineCodeForFunction");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// JITCompilerFunction - This contains the address of the JIT function used to
|
||||
|
@ -555,10 +555,10 @@ TEST_F(JITTest, FunctionPointersOutliveTheirCreator) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// ARM and MIPS do not have an implementation
|
||||
// ARM does not have an implementation
|
||||
// of replaceMachineCodeForFunction(), so recompileAndRelinkFunction
|
||||
// doesn't work.
|
||||
#if !defined(__arm__) && !defined(__mips__)
|
||||
#if !defined(__arm__)
|
||||
TEST_F(JITTest, FunctionIsRecompiledAndRelinked) {
|
||||
Function *F = Function::Create(TypeBuilder<int(void), false>::get(Context),
|
||||
GlobalValue::ExternalLinkage, "test", M);
|
||||
|
Loading…
Reference in New Issue
Block a user