mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-27 14:34:58 +00:00
Implement the first hunk of CompilationCallback. The pieces missing are the
ones noted, which require funny PPC specific inline assembly. If some angel felt the desire to help me, I think this is that last bit missing for JIT support (however, generic code emitter might night work right with the constant pool yet). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@18151 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4fa5fa8f61
commit
e61198b323
@ -34,16 +34,6 @@ static TargetJITInfo::JITCompilerFn JITCompilerFunction;
|
||||
#define BUILD_MTCTR(RS) BUILD_MTSPR(RS,9)
|
||||
#define BUILD_BCTR(LINK) BUILD_BCCTRx(20,0,LINK)
|
||||
|
||||
static void CompilationCallback() {
|
||||
//JITCompilerFunction
|
||||
assert(0 && "CompilationCallback not implemented yet!");
|
||||
}
|
||||
|
||||
|
||||
TargetJITInfo::LazyResolverFn
|
||||
PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
|
||||
return CompilationCallback;
|
||||
}
|
||||
|
||||
static void EmitBranchToAt(void *At, void *To, bool isCall) {
|
||||
intptr_t Addr = (intptr_t)To;
|
||||
@ -57,6 +47,60 @@ static void EmitBranchToAt(void *At, void *To, bool isCall) {
|
||||
AtI[3] = BUILD_BCTR(isCall); // bctr/bctrl
|
||||
}
|
||||
|
||||
static void CompilationCallback() {
|
||||
// FIXME: Should save R3-R10 and F1-F13 onto the stack, just like the Sparc
|
||||
// version does.
|
||||
//int IntRegs[8];
|
||||
//uint64_t FPRegs[13];
|
||||
unsigned *CameFromStub = (unsigned*)__builtin_return_address(0);
|
||||
unsigned *CameFromOrig = (unsigned*)__builtin_return_address(1);
|
||||
|
||||
// Adjust our pointers to the branches, not the return addresses.
|
||||
--CameFromStub; --CameFromOrig;
|
||||
|
||||
void *Target = JITCompilerFunction(CameFromStub);
|
||||
|
||||
// Check to see if CameFromOrig[-1] is a 'bl' instruction, and if we can
|
||||
// rewrite it to branch directly to the destination. If so, rewrite it so it
|
||||
// does not need to go through the stub anymore.
|
||||
unsigned CameFromOrigInst = *CameFromOrig;
|
||||
if ((CameFromOrigInst >> 26) == 18) { // Direct call.
|
||||
intptr_t Offset = ((intptr_t)Target-(intptr_t)CameFromOrig) >> 2;
|
||||
if (Offset >= -(1 << 23) && Offset < (1 << 23)) { // In range?
|
||||
// FIXME: hasn't been tested at all.
|
||||
// Clear the original target out:
|
||||
CameFromOrigInst &= (63 << 26) | 3;
|
||||
CameFromOrigInst |= Offset << 2;
|
||||
*CameFromOrig = CameFromOrigInst;
|
||||
}
|
||||
}
|
||||
|
||||
// Locate the start of the stub. If this is a short call, adjust backwards
|
||||
// the short amount, otherwise the full amount.
|
||||
bool isShortStub = (*CameFromStub >> 26) == 18;
|
||||
CameFromStub -= isShortStub ? 3 : 7;
|
||||
|
||||
// Rewrite the stub with an unconditional branch to the target, for any users
|
||||
// who took the address of the stub.
|
||||
EmitBranchToAt(CameFromStub, Target, false);
|
||||
|
||||
|
||||
// FIXME: Need to restore the registers from IntRegs/FPRegs.
|
||||
|
||||
// FIXME: Need to pop two frames off of the stack and return to a place where
|
||||
// we magically reexecute the call, or jump directly to the caller. This
|
||||
// requires inline asm majik.
|
||||
assert(0 && "CompilationCallback not finished yet!");
|
||||
}
|
||||
|
||||
|
||||
|
||||
TargetJITInfo::LazyResolverFn
|
||||
PPC32JITInfo::getLazyResolverFunction(JITCompilerFn Fn) {
|
||||
JITCompilerFunction = Fn;
|
||||
return CompilationCallback;
|
||||
}
|
||||
|
||||
void *PPC32JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
|
||||
// If this is just a call to an external function, emit a branch instead of a
|
||||
// call. The code is the same except for one bit of the last instruction.
|
||||
|
Loading…
x
Reference in New Issue
Block a user