summaryrefslogtreecommitdiff
path: root/lib/builtins/i386/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/i386/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/i386/chkstk2.S')
-rw-r--r--lib/builtins/i386/chkstk2.S40
1 files changed, 40 insertions, 0 deletions
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__