Skip to content

Commit a46b04e

Browse files
committed
builtins: Add __probestack support functions for x86
1 parent fc5fe22 commit a46b04e

File tree

4 files changed

+126
-0
lines changed

4 files changed

+126
-0
lines changed

lib/builtins/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ set(x86_64_SOURCES
152152
x86_64/floatundidf.S
153153
x86_64/floatundisf.S
154154
x86_64/floatundixf.S
155+
x86_64/probestack.S
155156
${GENERIC_SOURCES})
156157

157158
if(WIN32)
@@ -173,6 +174,7 @@ set(i386_SOURCES
173174
i386/lshrdi3.S
174175
i386/moddi3.S
175176
i386/muldi3.S
177+
i386/probestack.S
176178
i386/udivdi3.S
177179
i386/umoddi3.S
178180
${GENERIC_SOURCES})

lib/builtins/README.txt

+8
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,14 @@ long double _Complex __divtc3(long double a, long double b,
196196

197197
// Runtime support
198198

199+
// __probestack() is used to touch all pages of `size` bytes which will
200+
// later be allocated relative to the call site's stack pointer. It assumes
201+
// that the first and the last byte after the allocation will be touched by
202+
// something else. It has a custom platform specific calling convention.
203+
// This function is not available on Windows platforms as those have their
204+
// own builtins.
205+
void __probestack(du_int size);
206+
199207
// __clear_cache() is used to tell process that new instructions have been
200208
// written to an address range. Necessary on processors that do not have
201209
// a unified instruction and data cache.

lib/builtins/i386/probestack.S

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// This file is dual licensed under the MIT and the University of Illinois Open
2+
// Source Licenses. See LICENSE.TXT for details.
3+
4+
#include "../assembly.h"
5+
6+
// du_int __probestack(du_int size, du_int guard_size);
7+
8+
// `size` is passed in eax, `guard_size` is passed in ebx,
9+
// and this does not clobber any registers but eax.
10+
// `size` is returned in eax aligned up to 4 bytes.
11+
12+
#ifndef __WIN32__
13+
#ifdef __i386__
14+
15+
#if defined(__APPLE__)
16+
.const
17+
#elif defined(__ELF__)
18+
.section .rodata
19+
#else
20+
.section .rdata,"rd"
21+
#endif
22+
23+
.text
24+
.balign 4
25+
DEFINE_COMPILERRT_FUNCTION(__probestack)
26+
.cfi_startproc
27+
// Align size to 4 bytes
28+
addl $3, %eax
29+
andl $-4, %eax
30+
31+
pushl %eax
32+
.cfi_adjust_cfa_offset 4
33+
.cfi_rel_offset %eax, 0
34+
pushl %ecx
35+
.cfi_adjust_cfa_offset 4
36+
.cfi_rel_offset %ecx, 0
37+
38+
// Load the pre-call ESP into ECX
39+
leal 12(%esp), %ecx
40+
41+
1:
42+
subl %ebx, %ecx
43+
orb $0, (%ecx)
44+
subl %ebx, %eax
45+
ja 1b
46+
47+
popl %ecx
48+
.cfi_adjust_cfa_offset -4
49+
.cfi_restore %ecx
50+
popl %eax
51+
.cfi_adjust_cfa_offset -4
52+
.cfi_restore %eax
53+
ret
54+
.cfi_endproc
55+
END_COMPILERRT_FUNCTION(__probestack)
56+
57+
#endif // __i386__
58+
#endif // __WIN32__

lib/builtins/x86_64/probestack.S

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// This file is dual licensed under the MIT and the University of Illinois Open
2+
// Source Licenses. See LICENSE.TXT for details.
3+
4+
#include "../assembly.h"
5+
6+
// du_int __probestack(du_int size, du_int guard_size);
7+
8+
// `size` is passed in rax, `guard_size` is passed in rbx,
9+
// and this does not clobber any registers but rax.
10+
// `size` is returned in rax aligned up to 16 bytes.
11+
12+
#ifndef __WIN32__
13+
#ifdef __x86_64__
14+
15+
#if defined(__APPLE__)
16+
.const
17+
#elif defined(__ELF__)
18+
.section .rodata
19+
#else
20+
.section .rdata,"rd"
21+
#endif
22+
23+
.text
24+
.balign 4
25+
DEFINE_COMPILERRT_FUNCTION(__probestack)
26+
.cfi_startproc
27+
// Align size to 16 bytes
28+
addq $15, %rax
29+
andq $-16, %rax
30+
31+
pushq %rax
32+
.cfi_adjust_cfa_offset 8
33+
.cfi_rel_offset %rax, 0
34+
pushq %r11
35+
.cfi_adjust_cfa_offset 8
36+
.cfi_rel_offset %r11, 0
37+
38+
// Load the pre-call RSP into R11
39+
leaq 24(%rsp), %r11
40+
41+
1:
42+
subq %rbx, %r11
43+
orb $0, (%r11)
44+
subq %rbx, %rax
45+
ja 1b
46+
47+
popq %r11
48+
.cfi_adjust_cfa_offset -8
49+
.cfi_restore %r11
50+
popq %rax
51+
.cfi_adjust_cfa_offset -8
52+
.cfi_restore %rax
53+
ret
54+
.cfi_endproc
55+
END_COMPILERRT_FUNCTION(__probestack)
56+
57+
#endif // __x86_64__
58+
#endif // __WIN32__

0 commit comments

Comments
 (0)