From: Reid Kleckner Date: Tue, 1 Apr 2014 18:34:21 +0000 (+0000) Subject: Support segmented stacks on Win64 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f319a2c3b3f9e0f44032a73515ae0102c07888c5;p=oota-llvm.git Support segmented stacks on Win64 Identical to Win32 method except the GS segment register is used for TLS instead of FS and pvArbitrary is at TEB offset 0x28 instead of 0x14. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@205342 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Target/X86/X86FrameLowering.cpp b/lib/Target/X86/X86FrameLowering.cpp index 5054d293cf0..f0ad4d12d00 100644 --- a/lib/Target/X86/X86FrameLowering.cpp +++ b/lib/Target/X86/X86FrameLowering.cpp @@ -1167,7 +1167,7 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const { if (MF.getFunction()->isVarArg()) report_fatal_error("Segmented stacks do not support vararg functions."); if (!STI.isTargetLinux() && !STI.isTargetDarwin() && - !STI.isTargetWin32() && !STI.isTargetFreeBSD()) + !STI.isTargetWin32() && !STI.isTargetWin64() && !STI.isTargetFreeBSD()) report_fatal_error("Segmented stacks not supported on this platform."); MachineBasicBlock *allocMBB = MF.CreateMachineBasicBlock(); @@ -1211,6 +1211,9 @@ X86FrameLowering::adjustForSegmentedStacks(MachineFunction &MF) const { } else if (STI.isTargetDarwin()) { TlsReg = X86::GS; TlsOffset = 0x60 + 90*8; // See pthread_machdep.h. Steal TLS slot 90. + } else if (STI.isTargetWin64()) { + TlsReg = X86::GS; + TlsOffset = 0x28; // pvArbitrary, reserved for application use } else if (STI.isTargetFreeBSD()) { TlsReg = X86::FS; TlsOffset = 0x18; @@ -1248,7 +1251,7 @@ 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 (STI.isTargetLinux() || STI.isTargetWin32()) { + if (STI.isTargetLinux() || STI.isTargetWin32() || STI.isTargetWin64()) { BuildMI(checkMBB, DL, TII.get(X86::CMP32rm)).addReg(ScratchReg) .addReg(0).addImm(0).addReg(0).addImm(TlsOffset).addReg(TlsReg); } else if (STI.isTargetDarwin()) { diff --git a/test/CodeGen/X86/segmented-stacks.ll b/test/CodeGen/X86/segmented-stacks.ll index 08a98ef51ec..c02152bb638 100644 --- a/test/CodeGen/X86/segmented-stacks.ll +++ b/test/CodeGen/X86/segmented-stacks.ll @@ -4,6 +4,7 @@ ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-Darwin ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X32-MinGW ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-FreeBSD +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks -verify-machineinstrs | FileCheck %s -check-prefix=X64-MinGW ; We used to crash with filetype=obj ; RUN: llc < %s -mcpu=generic -mtriple=i686-linux -segmented-stacks -filetype=obj @@ -12,16 +13,14 @@ ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-darwin -segmented-stacks -filetype=obj ; RUN: llc < %s -mcpu=generic -mtriple=i686-mingw32 -segmented-stacks -filetype=obj ; RUN: llc < %s -mcpu=generic -mtriple=x86_64-freebsd -segmented-stacks -filetype=obj +; RUN: llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks -filetype=obj ; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-solaris -segmented-stacks 2> %t.log ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-Solaris -; RUN: not llc < %s -mcpu=generic -mtriple=x86_64-mingw32 -segmented-stacks 2> %t.log -; RUN: FileCheck %s -input-file=%t.log -check-prefix=X64-MinGW ; RUN: not llc < %s -mcpu=generic -mtriple=i686-freebsd -segmented-stacks 2> %t.log ; RUN: FileCheck %s -input-file=%t.log -check-prefix=X32-FreeBSD ; X64-Solaris: Segmented stacks not supported on this platform -; X64-MinGW: Segmented stacks not supported on this platform ; X32-FreeBSD: Segmented stacks not supported on FreeBSD i386 ; Just to prevent the alloca from being optimized away @@ -83,6 +82,16 @@ define void @test_basic() { ; X32-MinGW-NEXT: calll ___morestack ; X32-MinGW-NEXT: ret +; X64-MinGW-LABEL: test_basic: + +; X64-MinGW: cmpq %gs:40, %rsp +; X64-MinGW-NEXT: ja .LBB0_2 + +; X64-MinGW: movabsq $72, %r10 +; X64-MinGW-NEXT: movabsq $32, %r11 +; X64-MinGW-NEXT: callq __morestack +; X64-MinGW-NEXT: retq + ; X64-FreeBSD-LABEL: test_basic: ; X64-FreeBSD: cmpq %fs:24, %rsp @@ -145,6 +154,17 @@ define i32 @test_nested(i32 * nest %closure, i32 %other) { ; X32-MinGW-NEXT: calll ___morestack ; X32-MinGW-NEXT: ret +; X64-MinGW-LABEL: test_nested: +; X64-MinGW: cmpq %gs:40, %rsp +; X64-MinGW-NEXT: ja .LBB1_2 + +; X64-MinGW: movq %r10, %rax +; X64-MinGW-NEXT: movabsq $0, %r10 +; X64-MinGW-NEXT: movabsq $32, %r11 +; X64-MinGW-NEXT: callq __morestack +; X64-MinGW-NEXT: retq +; X64-MinGW-NEXT: movq %rax, %r10 + ; X64-FreeBSD: cmpq %fs:24, %rsp ; X64-FreeBSD-NEXT: ja .LBB1_2 @@ -208,6 +228,16 @@ define void @test_large() { ; X32-MinGW-NEXT: calll ___morestack ; X32-MinGW-NEXT: ret +; X64-MinGW-LABEL: test_large: +; X64-MinGW: leaq -40040(%rsp), %r11 +; X64-MinGW-NEXT: cmpq %gs:40, %r11 +; X64-MinGW-NEXT: ja .LBB2_2 + +; X64-MinGW: movabsq $40040, %r10 +; X64-MinGW-NEXT: movabsq $32, %r11 +; X64-MinGW-NEXT: callq __morestack +; X64-MinGW-NEXT: retq + ; X64-FreeBSD: leaq -40008(%rsp), %r11 ; X64-FreeBSD-NEXT: cmpq %fs:24, %r11 ; X64-FreeBSD-NEXT: ja .LBB2_2 @@ -275,6 +305,16 @@ define fastcc void @test_fastcc() { ; X32-MinGW-NEXT: calll ___morestack ; X32-MinGW-NEXT: ret +; X64-MinGW-LABEL: test_fastcc: + +; X64-MinGW: cmpq %gs:40, %rsp +; X64-MinGW-NEXT: ja .LBB3_2 + +; X64-MinGW: movabsq $72, %r10 +; X64-MinGW-NEXT: movabsq $32, %r11 +; X64-MinGW-NEXT: callq __morestack +; X64-MinGW-NEXT: retq + ; X64-FreeBSD-LABEL: test_fastcc: ; X64-FreeBSD: cmpq %fs:24, %rsp @@ -348,6 +388,17 @@ define fastcc void @test_fastcc_large() { ; X32-MinGW-NEXT: calll ___morestack ; X32-MinGW-NEXT: ret +; X64-MinGW-LABEL: test_fastcc_large: + +; X64-MinGW: leaq -40040(%rsp), %r11 +; X64-MinGW-NEXT: cmpq %gs:40, %r11 +; X64-MinGW-NEXT: ja .LBB4_2 + +; X64-MinGW: movabsq $40040, %r10 +; X64-MinGW-NEXT: movabsq $32, %r11 +; X64-MinGW-NEXT: callq __morestack +; X64-MinGW-NEXT: retq + ; X64-FreeBSD-LABEL: test_fastcc_large: ; X64-FreeBSD: leaq -40008(%rsp), %r11