PR debug/83917
[official-gcc.git] / libgcc / config / i386 / cygwin.S
blobf856be3e88a4665caa543aaaeb2b23ff429c1925
1 /* stuff needed for libgcc on win32.
2  *
3  *   Copyright (C) 1996-2018 Free Software Foundation, Inc.
4  *   Written By Steve Chamberlain
5  * 
6  * This file is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the
8  * Free Software Foundation; either version 3, or (at your option) any
9  * later version.
10  * 
11  * This file is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  * 
16  * Under Section 7 of GPL version 3, you are granted additional
17  * permissions described in the GCC Runtime Library Exception, version
18  * 3.1, as published by the Free Software Foundation.
19  * 
20  * You should have received a copy of the GNU General Public License and
21  * a copy of the GCC Runtime Library Exception along with this program;
22  * see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23  * <http://www.gnu.org/licenses/>.
24  */
26 #ifdef HAVE_GAS_CFI_SECTIONS_DIRECTIVE
27 # define USE_GAS_CFI_DIRECTIVES 1
28         .cfi_sections   .debug_frame
29 #else
30 # define USE_GAS_CFI_DIRECTIVES 0
31 #endif
32 #include "i386-asm.h"
34 #ifdef L_chkstk
35 /* Function prologue calls __chkstk to probe the stack when allocating more
36    than CHECK_STACK_LIMIT bytes in one go.  Touching the stack at 4K
37    increments is necessary to ensure that the guard pages used
38    by the OS virtual memory manger are allocated in correct sequence.  */
40         .global ___chkstk
41         .global __alloca
42 #ifdef __x86_64__
43 /* __alloca is a normal function call, which uses %rcx as the argument.  */
44         cfi_startproc()
45 __alloca:
46         movq    %rcx, %rax
47         /* FALLTHRU */
49 /* ___chkstk is a *special* function call, which uses %rax as the argument.
50    We avoid clobbering the 4 integer argument registers, %rcx, %rdx, 
51    %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use.  */
52         .align  4
53 ___chkstk:
54         popq    %r11                    /* pop return address */
55         cfi_adjust_cfa_offset(-8)       /* indicate return address in r11 */
56         cfi_register(%rip, %r11)
57         movq    %rsp, %r10
58         cmpq    $0x1000, %rax           /* > 4k ?*/
59         jb      2f
61 1:      subq    $0x1000, %r10           /* yes, move pointer down 4k*/
62         orl     $0x0, (%r10)            /* probe there */
63         subq    $0x1000, %rax           /* decrement count */
64         cmpq    $0x1000, %rax
65         ja      1b                      /* and do it again */
67 2:      subq    %rax, %r10
68         movq    %rsp, %rax              /* hold CFA until return */
69         cfi_def_cfa_register(%rax)
70         orl     $0x0, (%r10)            /* less than 4k, just peek here */
71         movq    %r10, %rsp              /* decrement stack */
73         /* Push the return value back.  Doing this instead of just
74            jumping to %r11 preserves the cached call-return stack
75            used by most modern processors.  */
76         pushq   %r11
77         ret
78         cfi_endproc()
79 #else
80         cfi_startproc()
81 ___chkstk:
82 __alloca:
83         pushl   %ecx                    /* save temp */
84         cfi_push(%eax)
85         leal    8(%esp), %ecx           /* point past return addr */
86         cmpl    $0x1000, %eax           /* > 4k ?*/
87         jb      2f
89 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
90         orl     $0x0, (%ecx)            /* probe there */
91         subl    $0x1000, %eax           /* decrement count */
92         cmpl    $0x1000, %eax
93         ja      1b                      /* and do it again */
95 2:      subl    %eax, %ecx         
96         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
97         movl    %esp, %eax              /* save current stack pointer */
98         cfi_def_cfa_register(%eax)
99         movl    %ecx, %esp              /* decrement stack */
100         movl    (%eax), %ecx            /* recover saved temp */
102         /* Copy the return register.  Doing this instead of just jumping to
103            the address preserves the cached call-return stack used by most
104            modern processors.  */
105         pushl   4(%eax)
106         ret
107         cfi_endproc()
108 #endif /* __x86_64__ */
109 #endif /* L_chkstk */
111 #ifdef L_chkstk_ms
112 /* ___chkstk_ms is a *special* function call, which uses %rax as the argument.
113    We avoid clobbering any registers.  Unlike ___chkstk, it just probes the
114    stack and does no stack allocation.  */
115         .global ___chkstk_ms
116 #ifdef __x86_64__
117         cfi_startproc()
118 ___chkstk_ms:
119         pushq   %rcx                    /* save temps */
120         cfi_push(%rcx)
121         pushq   %rax
122         cfi_push(%rax)
123         cmpq    $0x1000, %rax           /* > 4k ?*/
124         leaq    24(%rsp), %rcx          /* point past return addr */
125         jb      2f
127 1:      subq    $0x1000, %rcx           /* yes, move pointer down 4k */
128         orq     $0x0, (%rcx)            /* probe there */
129         subq    $0x1000, %rax           /* decrement count */
130         cmpq    $0x1000, %rax
131         ja      1b                      /* and do it again */
133 2:      subq    %rax, %rcx
134         orq     $0x0, (%rcx)            /* less than 4k, just peek here */
136         popq    %rax
137         cfi_pop(%rax)
138         popq    %rcx
139         cfi_pop(%rcx)
140         ret
141         cfi_endproc()
142 #else
143         cfi_startproc()
144 ___chkstk_ms:
145         pushl   %ecx                    /* save temp */
146         cfi_push(%ecx)
147         pushl   %eax
148         cfi_push(%eax)
149         cmpl    $0x1000, %eax           /* > 4k ?*/
150         leal    12(%esp), %ecx          /* point past return addr */
151         jb      2f
153 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
154         orl     $0x0, (%ecx)            /* probe there */
155         subl    $0x1000, %eax           /* decrement count */
156         cmpl    $0x1000, %eax
157         ja      1b                      /* and do it again */
159 2:      subl    %eax, %ecx
160         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
162         popl    %eax
163         cfi_pop(%eax)
164         popl    %ecx
165         cfi_pop(%ecx)
166         ret
167         cfi_endproc()
168 #endif /* __x86_64__ */
169 #endif /* L_chkstk_ms */