summaryrefslogtreecommitdiff
path: root/lib/builtins/x86_64/chkstk2.S
diff options
context:
space:
mode:
authorMartell Malone <martellmalone@gmail.com>2015-11-03 15:46:23 +0000
committerMartell Malone <martellmalone@gmail.com>2015-11-03 15:46:23 +0000
commit4356fa3ec6d35e2d2029e42071392e4596b14a23 (patch)
treedab789d0d0fbb88d2f2b92cf9253ecf1df6dfd22 /lib/builtins/x86_64/chkstk2.S
parent1d301e42d6dc140d86a861685b37b85d6494ece7 (diff)
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
Diffstat (limited to 'lib/builtins/x86_64/chkstk2.S')
-rw-r--r--lib/builtins/x86_64/chkstk2.S42
1 files changed, 42 insertions, 0 deletions
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__