mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-05 12:31:33 +00:00
Properly emit __chkstk call instead of __alloca on non-mingw windows targets.
Patch by Cameron Esfahani! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112902 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
831c8ec016
commit
ace53f2fbc
@ -764,7 +764,7 @@ void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// mergeSPUpdatesUp - Merge two stack-manipulating instructions lower iterator.
|
/// mergeSPUpdatesDown - Merge two stack-manipulating instructions lower iterator.
|
||||||
static
|
static
|
||||||
void mergeSPUpdatesDown(MachineBasicBlock &MBB,
|
void mergeSPUpdatesDown(MachineBasicBlock &MBB,
|
||||||
MachineBasicBlock::iterator &MBBI,
|
MachineBasicBlock::iterator &MBBI,
|
||||||
@ -1087,7 +1087,17 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
DL = MBB.findDebugLoc(MBBI);
|
DL = MBB.findDebugLoc(MBBI);
|
||||||
|
|
||||||
// Adjust stack pointer: ESP -= numbytes.
|
// Adjust stack pointer: ESP -= numbytes.
|
||||||
if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) {
|
|
||||||
|
// Windows and cygwin/mingw require a prologue helper routine when allocating
|
||||||
|
// more than 4K bytes on the stack. Windows uses __chkstk and cygwin/mingw
|
||||||
|
// uses __alloca. __alloca and the 32-bit version of __chkstk will probe
|
||||||
|
// the stack and adjust the stack pointer in one go. The 64-bit version
|
||||||
|
// of __chkstk is only responsible for probing the stack. The 64-bit
|
||||||
|
// prologue is responsible for adjusting the stack pointer. Touching the
|
||||||
|
// stack at 4K increments is necessary to ensure that the guard pages used
|
||||||
|
// by the OS virtual memory manager are allocated in correct sequence.
|
||||||
|
if (NumBytes >= 4096 &&
|
||||||
|
(Subtarget->isTargetCygMing() || Subtarget->isTargetWin32())) {
|
||||||
// Check, whether EAX is livein for this function.
|
// Check, whether EAX is livein for this function.
|
||||||
bool isEAXAlive = false;
|
bool isEAXAlive = false;
|
||||||
for (MachineRegisterInfo::livein_iterator
|
for (MachineRegisterInfo::livein_iterator
|
||||||
@ -1098,15 +1108,14 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
Reg == X86::AH || Reg == X86::AL);
|
Reg == X86::AH || Reg == X86::AL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function prologue calls _alloca to probe the stack when allocating more
|
|
||||||
// than 4k bytes in one go. Touching the stack at 4K increments is necessary
|
const char *StackProbeSymbol =
|
||||||
// to ensure that the guard pages used by the OS virtual memory manager are
|
Subtarget->isTargetWindows() ? "_chkstk" : "_alloca";
|
||||||
// allocated in correct sequence.
|
|
||||||
if (!isEAXAlive) {
|
if (!isEAXAlive) {
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||||
.addImm(NumBytes);
|
.addImm(NumBytes);
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||||
.addExternalSymbol("_alloca")
|
.addExternalSymbol(StackProbeSymbol)
|
||||||
.addReg(StackPtr, RegState::Define | RegState::Implicit)
|
.addReg(StackPtr, RegState::Define | RegState::Implicit)
|
||||||
.addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
|
.addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
|
||||||
} else {
|
} else {
|
||||||
@ -1119,7 +1128,7 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const {
|
|||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
|
||||||
.addImm(NumBytes - 4);
|
.addImm(NumBytes - 4);
|
||||||
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
|
||||||
.addExternalSymbol("_alloca")
|
.addExternalSymbol(StackProbeSymbol)
|
||||||
.addReg(StackPtr, RegState::Define | RegState::Implicit)
|
.addReg(StackPtr, RegState::Define | RegState::Implicit)
|
||||||
.addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
|
.addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
|
||||||
|
|
||||||
|
@ -186,6 +186,10 @@ public:
|
|||||||
return Is64Bit && (isTargetMingw() || isTargetWindows());
|
return Is64Bit && (isTargetMingw() || isTargetWindows());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isTargetWin32() const {
|
||||||
|
return !Is64Bit && (isTargetMingw() || isTargetWindows());
|
||||||
|
}
|
||||||
|
|
||||||
std::string getDataLayout() const {
|
std::string getDataLayout() const {
|
||||||
const char *p;
|
const char *p;
|
||||||
if (is64Bit())
|
if (is64Bit())
|
||||||
|
45
test/CodeGen/X86/win_chkstk.ll
Normal file
45
test/CodeGen/X86/win_chkstk.ll
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
; RUN: llc < %s -mtriple=i686-pc-win32 | FileCheck %s -check-prefix=WIN_X32
|
||||||
|
; RUN: llc < %s -mtriple=i686-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X32
|
||||||
|
; RUN: llc < %s -mtriple=x86_64-pc-mingw32 | FileCheck %s -check-prefix=MINGW_X64
|
||||||
|
; RUN: llc < %s -mtriple=i386-pc-linux | FileCheck %s -check-prefix=LINUX
|
||||||
|
|
||||||
|
; Windows and mingw require a prologue helper routine if more than 4096 bytes area
|
||||||
|
; allocated on the stack. Windows uses __chkstk and mingw uses __alloca. __alloca
|
||||||
|
; and the 32-bit version of __chkstk will probe the stack and adjust the stack pointer.
|
||||||
|
; The 64-bit version of __chkstk is only responsible for probing the stack. The 64-bit
|
||||||
|
; prologue is responsible for adjusting the stack pointer.
|
||||||
|
|
||||||
|
; Stack allocation >= 4096 bytes will require call to __chkstk in the Windows ABI.
|
||||||
|
define i32 @main4k() nounwind {
|
||||||
|
entry:
|
||||||
|
; WIN_X32: call __chkstk
|
||||||
|
; WIN_X64: call __chkstk
|
||||||
|
; MINGW_X32: call __alloca
|
||||||
|
; MINGW_X64: call _alloca
|
||||||
|
; LINUX-NOT: call __chkstk
|
||||||
|
%array4096 = alloca [4096 x i8], align 16 ; <[4096 x i8]*> [#uses=0]
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
; Make sure we don't call __chkstk or __alloca when we have less than a 4096 stack
|
||||||
|
; allocation.
|
||||||
|
define i32 @main128() nounwind {
|
||||||
|
entry:
|
||||||
|
; WIN_X32: # BB#0:
|
||||||
|
; WIN_X32-NOT: call __chkstk
|
||||||
|
; WIN_X32: ret
|
||||||
|
|
||||||
|
; WIN_X64: # BB#0:
|
||||||
|
; WIN_X64-NOT: call __chkstk
|
||||||
|
; WIN_X64: ret
|
||||||
|
|
||||||
|
; MINGW_X64: # BB#0:
|
||||||
|
; MINGW_X64-NOT: call _alloca
|
||||||
|
; MINGW_X64: ret
|
||||||
|
|
||||||
|
; LINUX: # BB#0:
|
||||||
|
; LINUX-NOT: call __chkstk
|
||||||
|
; LINUX: ret
|
||||||
|
%array128 = alloca [128 x i8], align 16 ; <[128 x i8]*> [#uses=0]
|
||||||
|
ret i32 0
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user