mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-13 04:30:23 +00:00
Fix tail call support in VC++ builds
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22143 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
ad38cd6ad0
commit
8bc6f934e8
@ -28,20 +28,16 @@ void X86JITInfo::replaceMachineCodeForFunction(void *Old, void *New) {
|
||||
}
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma optimize("y", off)
|
||||
#endif
|
||||
|
||||
/// JITCompilerFunction - This contains the address of the JIT function used to
|
||||
/// compile a function lazily.
|
||||
static TargetJITInfo::JITCompilerFn JITCompilerFunction;
|
||||
|
||||
// Provide a wrapper for X86CompilationCallback2 that saves non-traditional
|
||||
// callee saved registers, for the fastcc calling convention.
|
||||
extern "C" void X86CompilationCallback(void);
|
||||
|
||||
#if defined(__i386__) || defined(i386)
|
||||
extern "C" {
|
||||
#if defined(__i386__) || defined(i386) || defined(_M_IX86)
|
||||
#ifndef _MSC_VER
|
||||
void X86CompilationCallback(void);
|
||||
asm(
|
||||
".text\n"
|
||||
".align 8\n"
|
||||
@ -57,7 +53,21 @@ asm(
|
||||
"popl %ebp\n"
|
||||
"ret\n");
|
||||
#else
|
||||
// FIXME: implement this for VC++
|
||||
extern "C" void *_AddressOfReturnAddress(void);
|
||||
#pragma intrinsic(_AddressOfReturnAddress)
|
||||
|
||||
void X86CompilationCallback2(void);
|
||||
|
||||
_declspec(naked) void X86CompilationCallback(void) {
|
||||
__asm {
|
||||
push eax
|
||||
push edx
|
||||
call X86CompilationCallback2
|
||||
pop edx
|
||||
pop eax
|
||||
ret
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
@ -67,6 +77,7 @@ void X86CompilationCallback() {
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// X86CompilationCallback - This is the target-specific function invoked by the
|
||||
/// function stub when we did not know the real target of a call. This function
|
||||
@ -74,14 +85,14 @@ void X86CompilationCallback() {
|
||||
/// compiler function.
|
||||
extern "C" void X86CompilationCallback2() {
|
||||
#ifdef _MSC_VER
|
||||
// FIXME: This needs to go up one more level!
|
||||
unsigned *StackPtr, RetAddr;
|
||||
__asm mov StackPtr, ebp;
|
||||
__asm mov eax, DWORD PTR [ebp + 4];
|
||||
__asm mov RetAddr, eax;
|
||||
assert(sizeof(size_t) == 4); // FIXME: handle Win64
|
||||
unsigned *RetAddrLoc = (unsigned *)_AddressOfReturnAddress();
|
||||
RetAddrLoc += 3; // skip over ret addr, edx, eax
|
||||
unsigned RetAddr = *RetAddrLoc;
|
||||
#else
|
||||
unsigned *StackPtr = (unsigned*)__builtin_frame_address(1);
|
||||
unsigned RetAddr = (unsigned)(intptr_t)__builtin_return_address(1);
|
||||
unsigned *RetAddrLoc = &StackPtr[1];
|
||||
|
||||
// NOTE: __builtin_frame_address doesn't work if frame pointer elimination has
|
||||
// been performed. Having a variable sized alloca disables frame pointer
|
||||
@ -89,7 +100,7 @@ extern "C" void X86CompilationCallback2() {
|
||||
alloca(10+(RetAddr >> 31));
|
||||
|
||||
#endif
|
||||
assert(StackPtr[1] == RetAddr &&
|
||||
assert(*RetAddrLoc == RetAddr &&
|
||||
"Could not find return address on the stack!");
|
||||
|
||||
// It's a stub if there is an interrupt marker after the call.
|
||||
@ -123,13 +134,9 @@ extern "C" void X86CompilationCallback2() {
|
||||
}
|
||||
|
||||
// Change the return address to reexecute the call instruction...
|
||||
StackPtr[1] -= 5;
|
||||
*RetAddrLoc -= 5;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma optimize( "", on )
|
||||
#endif
|
||||
|
||||
TargetJITInfo::LazyResolverFn
|
||||
X86JITInfo::getLazyResolverFunction(JITCompilerFn F) {
|
||||
JITCompilerFunction = F;
|
||||
|
Loading…
Reference in New Issue
Block a user