Home | History | Annotate | Download | only in x86_64
      1 // This file is dual licensed under the MIT and the University of Illinois Open
      2 // Source Licenses. See LICENSE.TXT for details.
      3 
      4 #include "../assembly.h"
      5 
      6 #ifdef __x86_64__
      7 
      8 // _chkstk (_alloca) routine - probe stack between %rsp and (%rsp-%rax) in 4k increments,
      9 // then decrement %rsp by %rax.  Preserves all registers except %rsp and flags.
     10 // This routine is windows specific
     11 // http://msdn.microsoft.com/en-us/library/ms648426.aspx
     12 
     13 .text
     14 .balign 4
     15 DEFINE_COMPILERRT_FUNCTION(__alloca)
     16         mov    %rcx,%rax        // x64 _alloca is a normal function with parameter in rcx
     17         // fallthrough
     18 DEFINE_COMPILERRT_FUNCTION(___chkstk)
     19         push   %rcx
     20         cmp    $0x1000,%rax
     21         lea    16(%rsp),%rcx     // rsp before calling this routine -> rcx
     22         jb     1f
     23 2:
     24         sub    $0x1000,%rcx
     25         test   %rcx,(%rcx)
     26         sub    $0x1000,%rax
     27         cmp    $0x1000,%rax
     28         ja     2b
     29 1:
     30         sub    %rax,%rcx
     31         test   %rcx,(%rcx)
     32 
     33         lea    8(%rsp),%rax     // load pointer to the return address into rax
     34         mov    %rcx,%rsp        // install the new top of stack pointer into rsp
     35         mov    -8(%rax),%rcx    // restore rcx
     36         push   (%rax)           // push return address onto the stack
     37         sub    %rsp,%rax        // restore the original value in rax
     38         ret
     39 END_COMPILERRT_FUNCTION(___chkstk)
     40 END_COMPILERRT_FUNCTION(__alloca)
     41 
     42 #endif // __x86_64__
     43