summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2012-01-12 20:22:08 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2012-01-12 20:22:08 +0000
commit10745d3381c9142ea75aba2c85b41ff57c1de4c9 (patch)
treed000954c05dda6345e46a6f197ae254ab407af3e /llvm/lib
parentb04a09a515e5fc7ab06941104166c3676d12cdc2 (diff)
downloadbcm5719-llvm-10745d3381c9142ea75aba2c85b41ff57c1de4c9.tar.gz
bcm5719-llvm-10745d3381c9142ea75aba2c85b41ff57c1de4c9.zip
Support segmented stacks on win32.
Uses the pvArbitrary slot of the TIB, which is reserved for applications. We only support frames with a static size. llvm-svn: 148040
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp
index c2f2c1ffef4..639f5c20559 100644
--- a/llvm/lib/Target/X86/X86FrameLowering.cpp
+++ b/llvm/lib/Target/X86/X86FrameLowering.cpp
@@ -1357,8 +1357,8 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
if (MF.getFunction()->isVarArg())
report_fatal_error("Segmented stacks do not support vararg functions.");
- if (!ST->isTargetLinux() && !ST->isTargetDarwin())
- report_fatal_error("Segmented stacks supported only on linux and darwin.");
+ if (!ST->isTargetLinux() && !ST->isTargetDarwin() && !ST->isTargetWin32())
+ report_fatal_error("Segmented stacks supported only on linux, darwin and win32.");
MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock();
MachineBasicBlock *checkMBB = MF.CreateMachineBasicBlock();
@@ -1401,6 +1401,8 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
} else if (ST->isTargetDarwin()) {
TlsReg = X86::GS;
TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90.
+ } else {
+ report_fatal_error("Segmented stacks not supported on this platform.");
}
if (CompareStackPointer)
@@ -1412,7 +1414,18 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
BuildMI(checkMBB, DL, TII.get(X86::CMP64rm)).addReg(ScratchReg)
.addReg(0).addImm(1).addReg(0).addImm(TlsOffset).addReg(TlsReg);
} else {
- TlsReg = X86::GS;
+ if (ST->isTargetLinux()) {
+ TlsReg = X86::GS;
+ TlsOffset = 0x30;
+ } else if (ST->isTargetDarwin()) {
+ TlsReg = X86::GS;
+ TlsOffset = 0x48 + 90*4;
+ } else if (ST->isTargetWin32()) {
+ TlsReg = X86::FS;
+ TlsOffset = 0x14; // pvArbitrary, reserved for application use
+ } else {
+ report_fatal_error("Segmented stacks not supported on this platform.");
+ }
if (CompareStackPointer)
ScratchReg = X86::ESP;
@@ -1420,13 +1433,10 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const {
BuildMI(checkMBB, DL, TII.get(X86::LEA32r), ScratchReg).addReg(X86::ESP)
.addImm(1).addReg(0).addImm(-StackSize).addReg(0);
- if (ST->isTargetLinux()) {
- TlsOffset = 0x30;
-
+ if (ST->isTargetLinux() || ST->isTargetWin32()) {
BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg)
.addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg);
} else if (ST->isTargetDarwin()) {
- TlsOffset = 0x48 + 90*4;
// TlsOffset doesn't fit into a mod r/m byte so we need an extra register
unsigned ScratchReg2;
OpenPOWER on IntegriCloud