Skip to content
This repository has been archived by the owner on May 21, 2019. It is now read-only.

builtins: Add __probestack support functions for x86 #4

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,14 @@ long double _Complex __divtc3(long double a, long double b,

// Runtime support

// __probestack() is used to touch all pages of `size` bytes which will
// later be allocated relative to the call site's stack pointer. It assumes
// that the first and the last byte after the allocation will be touched by
// something else. It has a custom platform specific calling convention.
// This function is not available on Windows platforms as those have their
// own builtins.
+void __probestack(du_int size);

// __clear_cache() is used to tell process that new instructions have been
// written to an address range. Necessary on processors that do not have
// a unified instuction and data cache.
Expand Down
2 changes: 2 additions & 0 deletions lib/builtins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ set(x86_64_SOURCES
x86_64/floatundidf.S
x86_64/floatundisf.S
x86_64/floatundixf.S
x86_64/probestack.S
${GENERIC_SOURCES})

set(i386_SOURCES
Expand All @@ -155,6 +156,7 @@ set(i386_SOURCES
i386/lshrdi3.S
i386/moddi3.S
i386/muldi3.S
i386/probestack.S
i386/udivdi3.S
i386/umoddi3.S
${GENERIC_SOURCES})
Expand Down
54 changes: 54 additions & 0 deletions lib/builtins/i386/probestack.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.

#include "../assembly.h"

// void __probestack(du_int size);

// `size` is passed in eax and this does not clobber any registers
// including the parameter eax.

#ifndef __WIN32__
#ifdef __i386__

#if defined(__APPLE__)
.const
#elif defined(__ELF__)
.section .rodata
#else
.section .rdata,"rd"
#endif

.text
.balign 4
DEFINE_COMPILERRT_FUNCTION(__probestack)
.cfi_startproc
pushl %eax
.cfi_adjust_cfa_offset 4
.cfi_rel_offset %eax, 0
pushl %ecx
.cfi_adjust_cfa_offset 4
.cfi_rel_offset %ecx, 0
movl %esp, %ecx
subl $0x100C, %eax
jb 2f

1:
subl $0x1000, %ecx
orb $0, (%ecx)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've heard in the past that just a plain store may be the most efficient thing to do here as the CPU doesn't have to load the memory and wait for the result to come back.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just used the same instruction as GCC and libgcc, but a read+write seems like an odd choice indeed.

subl $0x1000, %eax
ja 1b

2:
popl %ecx
.cfi_adjust_cfa_offset -4
.cfi_restore %ecx
popl %eax
.cfi_adjust_cfa_offset -4
.cfi_restore %eax
ret
.cfi_endproc
END_COMPILERRT_FUNCTION(__probestack)

#endif // __i386__
#endif // __WIN32__
54 changes: 54 additions & 0 deletions lib/builtins/x86_64/probestack.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.

#include "../assembly.h"

// void __probestack(du_int size);

// `size` is passed in rax and this does not clobber any registers
// including the parameter rax.

#ifndef __WIN32__
#ifdef __x86_64__

#if defined(__APPLE__)
.const
#elif defined(__ELF__)
.section .rodata
#else
.section .rdata,"rd"
#endif

.text
.balign 4
DEFINE_COMPILERRT_FUNCTION(__probestack)
.cfi_startproc
pushq %rax
.cfi_adjust_cfa_offset 8
.cfi_rel_offset %rax, 0
pushq %r11
.cfi_adjust_cfa_offset 8
.cfi_rel_offset %r11, 0
movq %rsp, %r11
subq $0x1018, %rax
jb 2f

1:
subq $0x1000, %r11
orb $0, (%r11)
subq $0x1000, %rax
ja 1b

2:
popq %r11
.cfi_adjust_cfa_offset -8
.cfi_restore %r11
popq %rax
.cfi_adjust_cfa_offset -8
.cfi_restore %rax
ret
.cfi_endproc
END_COMPILERRT_FUNCTION(__probestack)

#endif // __x86_64__
#endif // __WIN32__