1353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2353358Sdim// See https://llvm.org/LICENSE.txt for license information.
3353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4292925Sdim
5292925Sdim#include "../assembly.h"
6292925Sdim
7292925Sdim#ifdef __i386__
8292925Sdim
9292925Sdim// _chkstk (_alloca) routine - probe stack between %esp and (%esp-%eax) in 4k increments,
10292925Sdim// then decrement %esp by %eax.  Preserves all registers except %esp and flags.
11292925Sdim// This routine is windows specific
12292925Sdim// http://msdn.microsoft.com/en-us/library/ms648426.aspx
13292925Sdim
14292925Sdim.text
15292925Sdim.balign 4
16292925SdimDEFINE_COMPILERRT_FUNCTION(_alloca) // _chkstk and _alloca are the same function
17292925SdimDEFINE_COMPILERRT_FUNCTION(__chkstk)
18292925Sdim        push   %ecx
19292925Sdim        cmp    $0x1000,%eax
20292925Sdim        lea    8(%esp),%ecx     // esp before calling this routine -> ecx
21292925Sdim        jb     1f
22292925Sdim2:
23292925Sdim        sub    $0x1000,%ecx
24292925Sdim        test   %ecx,(%ecx)
25292925Sdim        sub    $0x1000,%eax
26292925Sdim        cmp    $0x1000,%eax
27292925Sdim        ja     2b
28292925Sdim1:
29292925Sdim        sub    %eax,%ecx
30292925Sdim        test   %ecx,(%ecx)
31292925Sdim
32292925Sdim        lea    4(%esp),%eax     // load pointer to the return address into eax
33292925Sdim        mov    %ecx,%esp        // install the new top of stack pointer into esp
34292925Sdim        mov    -4(%eax),%ecx    // restore ecx
35292925Sdim        push   (%eax)           // push return address onto the stack
36292925Sdim        sub    %esp,%eax        // restore the original value in eax
37292925Sdim        ret
38292925SdimEND_COMPILERRT_FUNCTION(__chkstk)
39292925SdimEND_COMPILERRT_FUNCTION(_alloca)
40292925Sdim
41292925Sdim#endif // __i386__
42