]>
Commit | Line | Data |
---|---|---|
f5c64a69 DS |
1 | /* stuff needed for libgcc on win32. |
2 | * | |
a5544970 | 3 | * Copyright (C) 1996-2019 Free Software Foundation, Inc. |
f5c64a69 DS |
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 | |
748086b7 | 8 | * Free Software Foundation; either version 3, or (at your option) any |
f5c64a69 DS |
9 | * later version. |
10 | * | |
f5c64a69 DS |
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 | * | |
748086b7 JJ |
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. | |
f5c64a69 | 19 | * |
748086b7 JJ |
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/>. | |
f5c64a69 | 24 | */ |
3a2c1cd8 | 25 | |
ce579a4f JJ |
26 | #include "i386-asm.h" |
27 | ||
28 | #ifdef HAVE_AS_CFI_SECTIONS | |
174425ad | 29 | .cfi_sections .debug_frame |
e5868319 | 30 | #endif |
3a2c1cd8 | 31 | |
174425ad KT |
32 | #ifdef L_chkstk |
33 | /* Function prologue calls __chkstk to probe the stack when allocating more | |
f5c64a69 DS |
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. */ | |
37 | ||
3a2c1cd8 MM |
38 | .global ___chkstk |
39 | .global __alloca | |
55446c7e | 40 | #ifdef __x86_64__ |
174425ad KT |
41 | /* __alloca is a normal function call, which uses %rcx as the argument. */ |
42 | cfi_startproc() | |
3a2c1cd8 | 43 | __alloca: |
174425ad KT |
44 | movq %rcx, %rax |
45 | /* FALLTHRU */ | |
3a2c1cd8 | 46 | |
174425ad KT |
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 | |
3a2c1cd8 | 58 | |
174425ad KT |
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 */ | |
3a2c1cd8 | 64 | |
174425ad KT |
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 */ | |
3a2c1cd8 | 70 | |
ccf8e764 | 71 | /* Push the return value back. Doing this instead of just |
174425ad | 72 | jumping to %r11 preserves the cached call-return stack |
ccf8e764 | 73 | used by most modern processors. */ |
174425ad | 74 | pushq %r11 |
ccf8e764 | 75 | ret |
174425ad | 76 | cfi_endproc() |
ccf8e764 | 77 | #else |
174425ad KT |
78 | cfi_startproc() |
79 | ___chkstk: | |
ccf8e764 | 80 | __alloca: |
174425ad KT |
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 | |
86 | ||
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 */ | |
35b35fd0 | 92 | |
174425ad KT |
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 */ | |
35b35fd0 | 99 | |
174425ad KT |
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) | |
35b35fd0 | 104 | ret |
174425ad | 105 | cfi_endproc() |
55446c7e | 106 | #endif /* __x86_64__ */ |
174425ad | 107 | #endif /* L_chkstk */ |
ccf8e764 | 108 | |
174425ad KT |
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 | |
55446c7e | 114 | #ifdef __x86_64__ |
174425ad KT |
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 | |
124 | ||
125 | 1: subq $0x1000, %rcx /* yes, move pointer down 4k */ | |
126 | orq $0x0, (%rcx) /* probe there */ | |
ccf8e764 RH |
127 | subq $0x1000, %rax /* decrement count */ |
128 | cmpq $0x1000, %rax | |
174425ad | 129 | ja 1b /* and do it again */ |
ccf8e764 | 130 | |
174425ad KT |
131 | 2: subq %rax, %rcx |
132 | orq $0x0, (%rcx) /* less than 4k, just peek here */ | |
ccf8e764 | 133 | |
174425ad KT |
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 | |
150 | ||
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 */ | |
156 | ||
157 | 2: subl %eax, %ecx | |
158 | orl $0x0, (%ecx) /* less than 4k, just peek here */ | |
159 | ||
160 | popl %eax | |
161 | cfi_pop(%eax) | |
162 | popl %ecx | |
163 | cfi_pop(%ecx) | |
ccf8e764 | 164 | ret |
174425ad | 165 | cfi_endproc() |
55446c7e | 166 | #endif /* __x86_64__ */ |
174425ad | 167 | #endif /* L_chkstk_ms */ |