]>
Commit | Line | Data |
---|---|---|
f5c64a69 DS |
1 | /* stuff needed for libgcc on win32. |
2 | * | |
3 | * Copyright (C) 1996, 1998, 2001, 2003 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 2, or (at your option) any | |
9 | * later version. | |
10 | * | |
11 | * In addition to the permissions in the GNU General Public License, the | |
12 | * Free Software Foundation gives you unlimited permission to link the | |
13 | * compiled version of this file with other programs, and to distribute | |
14 | * those programs without any restriction coming from the use of this | |
15 | * file. (The General Public License restrictions do apply in other | |
16 | * respects; for example, they cover modification of the file, and | |
17 | * distribution when not linked into another program.) | |
18 | * | |
19 | * This file is distributed in the hope that it will be useful, but | |
20 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
22 | * General Public License for more details. | |
23 | * | |
24 | * You should have received a copy of the GNU General Public License | |
25 | * along with this program; see the file COPYING. If not, write to | |
39d14dda KC |
26 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
27 | * Boston, MA 02110-1301, USA. | |
f5c64a69 DS |
28 | * |
29 | * As a special exception, if you link this library with files | |
30 | * compiled with GCC to produce an executable, this does not cause | |
31 | * the resulting executable to be covered by the GNU General Public License. | |
32 | * This exception does not however invalidate any other reasons why | |
33 | * the executable file might be covered by the GNU General Public License. | |
34 | */ | |
3a2c1cd8 MM |
35 | |
36 | #ifdef L_chkstk | |
37 | ||
f5c64a69 DS |
38 | /* Function prologue calls _alloca to probe the stack when allocating more |
39 | than CHECK_STACK_LIMIT bytes in one go. Touching the stack at 4K | |
40 | increments is necessary to ensure that the guard pages used | |
41 | by the OS virtual memory manger are allocated in correct sequence. */ | |
42 | ||
3a2c1cd8 MM |
43 | .global ___chkstk |
44 | .global __alloca | |
ccf8e764 | 45 | #ifndef _WIN64 |
3a2c1cd8 MM |
46 | ___chkstk: |
47 | __alloca: | |
ccf8e764 RH |
48 | pushl %ecx /* save temp */ |
49 | leal 8(%esp), %ecx /* point past return addr */ | |
50 | cmpl $0x1000, %eax /* > 4k ?*/ | |
51 | jb Ldone | |
3a2c1cd8 | 52 | |
ccf8e764 RH |
53 | Lprobe: |
54 | subl $0x1000, %ecx /* yes, move pointer down 4k*/ | |
55 | orl $0x0, (%ecx) /* probe there */ | |
56 | subl $0x1000, %eax /* decrement count */ | |
57 | cmpl $0x1000, %eax | |
58 | ja Lprobe /* and do it again */ | |
3a2c1cd8 | 59 | |
ccf8e764 RH |
60 | Ldone: |
61 | subl %eax, %ecx | |
62 | orl $0x0, (%ecx) /* less than 4k, just peek here */ | |
3a2c1cd8 | 63 | |
ccf8e764 RH |
64 | movl %esp, %eax /* save old stack pointer */ |
65 | movl %ecx, %esp /* decrement stack */ | |
66 | movl (%eax), %ecx /* recover saved temp */ | |
67 | movl 4(%eax), %eax /* recover return address */ | |
3a2c1cd8 | 68 | |
ccf8e764 RH |
69 | /* Push the return value back. Doing this instead of just |
70 | jumping to %eax preserves the cached call-return stack | |
71 | used by most modern processors. */ | |
72 | pushl %eax | |
73 | ret | |
74 | #else | |
75 | /* __alloca is a normal function call, which uses %rcx as the argument. */ | |
76 | __alloca: | |
77 | movq %rcx, %rax | |
78 | /* FALLTHRU */ | |
79 | ||
80 | /* ___chkstk is a *special* function call, which uses %rax as the argument. | |
81 | We avoid clobbering the 4 integer argument registers, %rcx, %rdx, | |
82 | %r8 and %r9, which leaves us with %rax, %r10, and %r11 to use. */ | |
83 | ___chkstk: | |
84 | popq %r11 /* pop return address */ | |
85 | movq %rsp, %r10 /* get sp */ | |
86 | cmpq $0x1000, %rax /* > 4k ?*/ | |
87 | jb Ldone | |
3a2c1cd8 | 88 | |
ccf8e764 RH |
89 | Lprobe: |
90 | subq $0x1000, %r10 /* yes, move pointer down 4k*/ | |
91 | orl $0x0, (%r10) /* probe there */ | |
92 | subq $0x1000, %rax /* decrement count */ | |
93 | cmpq $0x1000, %rax | |
94 | ja Lprobe /* and do it again */ | |
95 | ||
96 | Ldone: | |
97 | subq %rax, %r10 | |
98 | orl $0x0, (%r10) /* less than 4k, just peek here */ | |
99 | movq %r10, %rsp /* decrement stack */ | |
100 | ||
101 | /* Push the return value back. Doing this instead of just | |
102 | jumping to %r11 preserves the cached call-return stack | |
103 | used by most modern processors. */ | |
104 | pushq %r11 | |
105 | ret | |
106 | #endif | |
3a2c1cd8 | 107 | #endif |