From 40eb83ba56ba9c1d2e6de44deacf889ac0143cf7 Mon Sep 17 00:00:00 2001 From: Martell Malone Date: Tue, 3 Nov 2015 15:46:23 +0000 Subject: [PATCH] Support for 32-bit mingw-w64 in compiler-rt. Add chkstk/alloca for gcc objects. Replace or instructions with test, the latter should be marginally more efficent, as it does not write to memory. Differential Revision: http://reviews.llvm.org/D14044 Patch by vadimcn llvm-svn: 251928 --- compiler-rt/lib/builtins/CMakeLists.txt | 2 ++ compiler-rt/lib/builtins/i386/chkstk.S | 4 +-- compiler-rt/lib/builtins/i386/chkstk2.S | 40 +++++++++++++++++++++ compiler-rt/lib/builtins/x86_64/chkstk.S | 4 +-- compiler-rt/lib/builtins/x86_64/chkstk2.S | 42 +++++++++++++++++++++++ 5 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 compiler-rt/lib/builtins/i386/chkstk2.S create mode 100644 compiler-rt/lib/builtins/x86_64/chkstk2.S diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index d6a972e5a5f169..a2bacf719e8ea4 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -177,6 +177,7 @@ if (NOT MSVC) set(x86_64_SOURCES ${x86_64_SOURCES} x86_64/chkstk.S) + x86_64/chkstk2.S) endif() set(i386_SOURCES @@ -200,6 +201,7 @@ if (NOT MSVC) set(i386_SOURCES ${i386_SOURCES} i386/chkstk.S) + i386/chkstk2.S) endif() set(i686_SOURCES diff --git a/compiler-rt/lib/builtins/i386/chkstk.S b/compiler-rt/lib/builtins/i386/chkstk.S index 3733d722ef19bb..b59974868f218c 100644 --- a/compiler-rt/lib/builtins/i386/chkstk.S +++ b/compiler-rt/lib/builtins/i386/chkstk.S @@ -19,13 +19,13 @@ DEFINE_COMPILERRT_FUNCTION(__chkstk_ms) jb 1f 2: sub $0x1000,%ecx - orl $0,(%ecx) + test %ecx,(%ecx) sub $0x1000,%eax cmp $0x1000,%eax ja 2b 1: sub %eax,%ecx - orl $0,(%ecx) + test %ecx,(%ecx) pop %eax pop %ecx ret diff --git a/compiler-rt/lib/builtins/i386/chkstk2.S b/compiler-rt/lib/builtins/i386/chkstk2.S new file mode 100644 index 00000000000000..7d65bb088928f5 --- /dev/null +++ b/compiler-rt/lib/builtins/i386/chkstk2.S @@ -0,0 +1,40 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "../assembly.h" + +#ifdef __i386__ + +// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments, +// then decrement %esp by %eax. Preserves all registers except %esp and flags. +// This routine is windows specific +// http://msdn.microsoft.com/en-us/library/ms648426.aspx + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function +DEFINE_COMPILERRT_FUNCTION(__chkstk) + push %ecx + cmp $0x1000,%eax + lea 8(%esp),%ecx // esp before calling this routine -> ecx + jb 1f +2: + sub $0x1000,%ecx + test %ecx,(%ecx) + sub $0x1000,%eax + cmp $0x1000,%eax + ja 2b +1: + sub %eax,%ecx + test %ecx,(%ecx) + + lea 4(%esp),%eax // load pointer to the return address into eax + mov %ecx,%esp // install the new top of stack pointer into esp + mov -4(%eax),%ecx // restore ecx + push (%eax) // push return address onto the stack + sub %esp,%eax // restore the original value in eax + ret +END_COMPILERRT_FUNCTION(__chkstk) +END_COMPILERRT_FUNCTION(_alloca) + +#endif // __i386__ diff --git a/compiler-rt/lib/builtins/x86_64/chkstk.S b/compiler-rt/lib/builtins/x86_64/chkstk.S index 5759e84498c699..4149ac63d9d014 100644 --- a/compiler-rt/lib/builtins/x86_64/chkstk.S +++ b/compiler-rt/lib/builtins/x86_64/chkstk.S @@ -24,13 +24,13 @@ DEFINE_COMPILERRT_FUNCTION(___chkstk_ms) jb 1f 2: sub $0x1000,%rcx - orl $0,(%rcx) + test %rcx,(%rcx) sub $0x1000,%rax cmp $0x1000,%rax ja 2b 1: sub %rax,%rcx - orl $0,(%rcx) + test %rcx,(%rcx) pop %rax pop %rcx ret diff --git a/compiler-rt/lib/builtins/x86_64/chkstk2.S b/compiler-rt/lib/builtins/x86_64/chkstk2.S new file mode 100644 index 00000000000000..ac1eb920e0e8ed --- /dev/null +++ b/compiler-rt/lib/builtins/x86_64/chkstk2.S @@ -0,0 +1,42 @@ +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. + +#include "../assembly.h" + +#ifdef __x86_64__ + +// _chkstk (_alloca) routine - probe stack between %rsp and (%rsp-%rax) in 4k increments, +// then decrement %rsp by %rax. Preserves all registers except %rsp and flags. +// This routine is windows specific +// http://msdn.microsoft.com/en-us/library/ms648426.aspx + +.text +.balign 4 +DEFINE_COMPILERRT_FUNCTION(__alloca) + mov %rcx,%rax // x64 _alloca is a normal function with parameter in rcx + // fallthrough +DEFINE_COMPILERRT_FUNCTION(___chkstk) + push %rcx + cmp $0x1000,%rax + lea 16(%rsp),%rcx // rsp before calling this routine -> rcx + jb 1f +2: + sub $0x1000,%rcx + test %rcx,(%rcx) + sub $0x1000,%rax + cmp $0x1000,%rax + ja 2b +1: + sub %rax,%rcx + test %rcx,(%rcx) + + lea 8(%rsp),%rax // load pointer to the return address into rax + mov %rcx,%rsp // install the new top of stack pointer into rsp + mov -8(%rax),%rcx // restore rcx + push (%rax) // push return address onto the stack + sub %rsp,%rax // restore the original value in rax + ret +END_COMPILERRT_FUNCTION(___chkstk) +END_COMPILERRT_FUNCTION(__alloca) + +#endif // __x86_64__