From 4356fa3ec6d35e2d2029e42071392e4596b14a23 Mon Sep 17 00:00:00 2001 From: Martell Malone Date: Tue, 3 Nov 2015 15:46:23 +0000 Subject: 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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@251928 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/builtins/CMakeLists.txt | 2 ++ lib/builtins/i386/chkstk.S | 4 ++-- lib/builtins/i386/chkstk2.S | 40 ++++++++++++++++++++++++++++++++++++++++ lib/builtins/x86_64/chkstk.S | 4 ++-- lib/builtins/x86_64/chkstk2.S | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 lib/builtins/i386/chkstk2.S create mode 100644 lib/builtins/x86_64/chkstk2.S (limited to 'lib') diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt index d6a972e5a..a2bacf719 100644 --- a/lib/builtins/CMakeLists.txt +++ b/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/lib/builtins/i386/chkstk.S b/lib/builtins/i386/chkstk.S index 3733d722e..b59974868 100644 --- a/lib/builtins/i386/chkstk.S +++ b/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/lib/builtins/i386/chkstk2.S b/lib/builtins/i386/chkstk2.S new file mode 100644 index 000000000..7d65bb088 --- /dev/null +++ b/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/lib/builtins/x86_64/chkstk.S b/lib/builtins/x86_64/chkstk.S index 5759e8449..4149ac63d 100644 --- a/lib/builtins/x86_64/chkstk.S +++ b/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/lib/builtins/x86_64/chkstk2.S b/lib/builtins/x86_64/chkstk2.S new file mode 100644 index 000000000..ac1eb920e --- /dev/null +++ b/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__ -- cgit v1.2.3