aboutsummaryrefslogtreecommitdiff
path: root/contrib/compiler-rt/lib/builtins/x86_64/chkstk2.S
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/compiler-rt/lib/builtins/x86_64/chkstk2.S')
-rw-r--r--contrib/compiler-rt/lib/builtins/x86_64/chkstk2.S42
1 files changed, 42 insertions, 0 deletions
diff --git a/contrib/compiler-rt/lib/builtins/x86_64/chkstk2.S b/contrib/compiler-rt/lib/builtins/x86_64/chkstk2.S
new file mode 100644
index 000000000000..ac1eb920e0e8
--- /dev/null
+++ b/contrib/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__