summaryrefslogtreecommitdiff
path: root/py/nlrx64.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/nlrx64.c')
-rw-r--r--py/nlrx64.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/py/nlrx64.c b/py/nlrx64.c
index 6f006e755..6b7d0262f 100644
--- a/py/nlrx64.c
+++ b/py/nlrx64.c
@@ -35,8 +35,27 @@
__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
+#if !MICROPY_NLR_OS_WINDOWS
+#if defined(__clang__) || (defined(__GNUC__) && __GNUC__ >= 8)
+#define USE_NAKED 1
+#else
+// On older gcc the equivalent here is to force omit-frame-pointer
+__attribute__((optimize("omit-frame-pointer")))
+#endif
+#endif
+
+#if !defined(USE_NAKED)
+#define USE_NAKED 0
+#endif
+
+#if USE_NAKED
+// nlr_push prelude should never push frame pointer register ebp onto the stack
+__attribute__((naked))
+#endif
unsigned int nlr_push(nlr_buf_t *nlr) {
+ #if !USE_NAKED
(void)nlr;
+ #endif
#if MICROPY_NLR_OS_WINDOWS
@@ -58,9 +77,6 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
#else
__asm volatile (
- #if defined(__APPLE__) && defined(__MACH__)
- "pop %rbp \n" // undo function's prelude
- #endif
"movq (%rsp), %rax \n" // load return %rip
"movq %rax, 16(%rdi) \n" // store %rip into nlr_buf
"movq %rbp, 24(%rdi) \n" // store %rbp into nlr_buf
@@ -79,7 +95,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
#endif
+ #if !USE_NAKED
return 0; // needed to silence compiler warning
+ #endif
}
NORETURN void nlr_jump(void *val) {