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