OSDN Git Service

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