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) {