]>
Commit | Line | Data |
---|---|---|
f5c64a69 DS |
1 | /* stuff needed for libgcc on win32. |
2 | * | |
748086b7 | 3 | * Copyright (C) 1996, 1998, 2001, 2003, 2008, 2009 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 MM |
25 | |
26 | #ifdef L_chkstk | |
27 | ||
f5c64a69 DS |
28 | /* Function prologue calls _alloca to probe the stack when allocating more |
29 | than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K | |
30 | increments is necessary to ensure that the guard pages used | |
31 | by the OS virtual memory manger are allocated in correct sequence. */ | |
32 | ||
3a2c1cd8 MM |
33 | .global ___chkstk |
34 | .global __alloca | |
ccf8e764 | 35 | #ifndef _WIN64 |
3a2c1cd8 MM |
36 | ___chkstk: |
37 | __alloca: | |
ccf8e764 RH |
38 | pushl %ecx /* save temp */ |
39 | leal 8(%esp), %ecx /* point past return addr */ | |
40 | cmpl $0x1000, %eax /* > 4k ?*/ | |
41 | jb Ldone | |
3a2c1cd8 | 42 | |
ccf8e764 RH |
43 | Lprobe: |
44 | subl $0x1000, %ecx /* yes, move pointer down 4k*/ | |
45 | orl $0x0, (%ecx) /* probe there */ | |
46 | subl $0x1000, %eax /* decrement count */ | |
47 | cmpl $0x1000, %eax | |
48 | ja Lprobe /* and do it again */ | |
3a2c1cd8 | 49 | |
ccf8e764 RH |
50 | Ldone: |
51 | subl %eax, %ecx | |
52 | orl $0x0, (%ecx) /* less than 4k, just peek here */ | |
3a2c1cd8 | 53 | |
ccf8e764 RH |
54 | movl %esp, %eax /* save old stack pointer */ |
55 | movl %ecx, %esp /* decrement stack */ | |
56 | movl (%eax), %ecx /* recover saved temp */ | |
57 | movl 4(%eax), %eax /* recover return address */ | |
3a2c1cd8 | 58 | |
ccf8e764 RH |
59 | /* Push the return value back. Doing this instead of just |
60 | jumping to %eax preserves the cached call-return stack | |
61 | used by most modern processors. */ | |
62 | pushl %eax | |
63 | ret | |
64 | #else | |
35b35fd0 KT |
65 | /* __alloca is a normal function call, which uses %rcx as the argument. And stack space |
66 | for the argument is saved. */ | |
ccf8e764 | 67 | __alloca: |
35b35fd0 KT |
68 | movq %rcx, %rax |
69 | addq $0x7, %rax | |
70 | andq $0xfffffffffffffff8, %rax | |
71 | popq %rcx /* pop return address */ | |
72 | popq %r10 /* Pop the reserved stack space. */ | |
73 | movq %rsp, %r10 /* get sp */ | |
74 | cmpq $0x1000, %rax /* > 4k ?*/ | |
75 | jb Ldone_alloca | |
76 | ||
77 | Lprobe_alloca: | |
78 | subq $0x1000, %r10 /* yes, move pointer down 4k*/ | |
79 | orq $0x0, (%r10) /* probe there */ | |
80 | subq $0x1000, %rax /* decrement count */ | |
81 | cmpq $0x1000, %rax | |
82 | ja Lprobe_alloca /* and do it again */ | |
83 | ||
84 | Ldone_alloca: | |
85 | subq %rax, %r10 | |
86 | orq $0x0, (%r10) /* less than 4k, just peek here */ | |
87 | movq %r10, %rax | |
88 | subq $0x8, %r10 /* Reserve argument stack space. */ | |
89 | movq %r10, %rsp /* decrement stack */ | |
90 | ||
91 | /* Push the return value back. Doing this instead of just | |
92 | jumping to %rcx preserves the cached call-return stack | |
93 | used by most modern processors. */ | |
94 | pushq %rcx | |
95 | ret | |
ccf8e764 RH |
96 | |
97 | /* ___chkstk is a *special* function call, which uses %rax as the argument. | |
98 | We avoid clobbering the 4 integer argument registers, %rcx, %rdx, | |
99 | %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use. */ | |
100 | ___chkstk: | |
35b35fd0 KT |
101 | addq $0x7, %rax /* Make sure stack is on alignment of 8. */ |
102 | andq $0xfffffffffffffff8, %rax | |
ccf8e764 RH |
103 | popq %r11 /* pop return address */ |
104 | movq %rsp, %r10 /* get sp */ | |
105 | cmpq $0x1000, %rax /* > 4k ?*/ | |
106 | jb Ldone | |
3a2c1cd8 | 107 | |
ccf8e764 RH |
108 | Lprobe: |
109 | subq $0x1000, %r10 /* yes, move pointer down 4k*/ | |
110 | orl $0x0, (%r10) /* probe there */ | |
111 | subq $0x1000, %rax /* decrement count */ | |
112 | cmpq $0x1000, %rax | |
113 | ja Lprobe /* and do it again */ | |
114 | ||
115 | Ldone: | |
116 | subq %rax, %r10 | |
117 | orl $0x0, (%r10) /* less than 4k, just peek here */ | |
118 | movq %r10, %rsp /* decrement stack */ | |
119 | ||
120 | /* Push the return value back. Doing this instead of just | |
121 | jumping to %r11 preserves the cached call-return stack | |
122 | used by most modern processors. */ | |
123 | pushq %r11 | |
124 | ret | |
125 | #endif | |
3a2c1cd8 | 126 | #endif |