From f319a2c3b3f9e0f44032a73515ae0102c07888c5 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 1 Apr 2014 18:34:21 +0000 Subject: [PATCH] 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 --- lib/Target/X86/X86FrameLowering.cpp | 7 +++- test/CodeGen/X86/segmented-stacks.ll | 57 ++++++++++++++++++++++++++-- 2 files changed, 59 insertions(+), 5 deletions(-) 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 -- 2.34.1