PR debug/83917
[official-gcc.git] / libgcc / config / i386 / cygwin.S
blobece17f82a68497e2fec07159f99a4fe3b764bba2
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 #include "i386-asm.h"
28 #ifdef HAVE_AS_CFI_SECTIONS
29         .cfi_sections   .debug_frame
30 #endif
32 #ifdef L_chkstk
33 /* Function prologue calls __chkstk to probe the stack when allocating more
34    than CHECK_STACK_LIMIT bytes in one go.  Touching the stack at 4K
35    increments is necessary to ensure that the guard pages used
36    by the OS virtual memory manger are allocated in correct sequence.  */
38         .global ___chkstk
39         .global __alloca
40 #ifdef __x86_64__
41 /* __alloca is a normal function call, which uses %rcx as the argument.  */
42         cfi_startproc()
43 __alloca:
44         movq    %rcx, %rax
45         /* FALLTHRU */
47 /* ___chkstk is a *special* function call, which uses %rax as the argument.
48    We avoid clobbering the 4 integer argument registers, %rcx, %rdx, 
49    %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use.  */
50         .align  4
51 ___chkstk:
52         popq    %r11                    /* pop return address */
53         cfi_adjust_cfa_offset(-8)       /* indicate return address in r11 */
54         cfi_register(%rip, %r11)
55         movq    %rsp, %r10
56         cmpq    $0x1000, %rax           /* > 4k ?*/
57         jb      2f
59 1:      subq    $0x1000, %r10           /* yes, move pointer down 4k*/
60         orl     $0x0, (%r10)            /* probe there */
61         subq    $0x1000, %rax           /* decrement count */
62         cmpq    $0x1000, %rax
63         ja      1b                      /* and do it again */
65 2:      subq    %rax, %r10
66         movq    %rsp, %rax              /* hold CFA until return */
67         cfi_def_cfa_register(%rax)
68         orl     $0x0, (%r10)            /* less than 4k, just peek here */
69         movq    %r10, %rsp              /* decrement stack */
71         /* Push the return value back.  Doing this instead of just
72            jumping to %r11 preserves the cached call-return stack
73            used by most modern processors.  */
74         pushq   %r11
75         ret
76         cfi_endproc()
77 #else
78         cfi_startproc()
79 ___chkstk:
80 __alloca:
81         pushl   %ecx                    /* save temp */
82         cfi_push(%eax)
83         leal    8(%esp), %ecx           /* point past return addr */
84         cmpl    $0x1000, %eax           /* > 4k ?*/
85         jb      2f
87 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
88         orl     $0x0, (%ecx)            /* probe there */
89         subl    $0x1000, %eax           /* decrement count */
90         cmpl    $0x1000, %eax
91         ja      1b                      /* and do it again */
93 2:      subl    %eax, %ecx         
94         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
95         movl    %esp, %eax              /* save current stack pointer */
96         cfi_def_cfa_register(%eax)
97         movl    %ecx, %esp              /* decrement stack */
98         movl    (%eax), %ecx            /* recover saved temp */
100         /* Copy the return register.  Doing this instead of just jumping to
101            the address preserves the cached call-return stack used by most
102            modern processors.  */
103         pushl   4(%eax)
104         ret
105         cfi_endproc()
106 #endif /* __x86_64__ */
107 #endif /* L_chkstk */
109 #ifdef L_chkstk_ms
110 /* ___chkstk_ms is a *special* function call, which uses %rax as the argument.
111    We avoid clobbering any registers.  Unlike ___chkstk, it just probes the
112    stack and does no stack allocation.  */
113         .global ___chkstk_ms
114 #ifdef __x86_64__
115         cfi_startproc()
116 ___chkstk_ms:
117         pushq   %rcx                    /* save temps */
118         cfi_push(%rcx)
119         pushq   %rax
120         cfi_push(%rax)
121         cmpq    $0x1000, %rax           /* > 4k ?*/
122         leaq    24(%rsp), %rcx          /* point past return addr */
123         jb      2f
125 1:      subq    $0x1000, %rcx           /* yes, move pointer down 4k */
126         orq     $0x0, (%rcx)            /* probe there */
127         subq    $0x1000, %rax           /* decrement count */
128         cmpq    $0x1000, %rax
129         ja      1b                      /* and do it again */
131 2:      subq    %rax, %rcx
132         orq     $0x0, (%rcx)            /* less than 4k, just peek here */
134         popq    %rax
135         cfi_pop(%rax)
136         popq    %rcx
137         cfi_pop(%rcx)
138         ret
139         cfi_endproc()
140 #else
141         cfi_startproc()
142 ___chkstk_ms:
143         pushl   %ecx                    /* save temp */
144         cfi_push(%ecx)
145         pushl   %eax
146         cfi_push(%eax)
147         cmpl    $0x1000, %eax           /* > 4k ?*/
148         leal    12(%esp), %ecx          /* point past return addr */
149         jb      2f
151 1:      subl    $0x1000, %ecx           /* yes, move pointer down 4k*/
152         orl     $0x0, (%ecx)            /* probe there */
153         subl    $0x1000, %eax           /* decrement count */
154         cmpl    $0x1000, %eax
155         ja      1b                      /* and do it again */
157 2:      subl    %eax, %ecx
158         orl     $0x0, (%ecx)            /* less than 4k, just peek here */
160         popl    %eax
161         cfi_pop(%eax)
162         popl    %ecx
163         cfi_pop(%ecx)
164         ret
165         cfi_endproc()
166 #endif /* __x86_64__ */
167 #endif /* L_chkstk_ms */