Blob Blame History Raw
From c97607db5ccc03afbccacf853f2cd06305c28251 Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Tue, 15 May 2018 11:17:28 +1000
Subject: [PATCH] py/nlrx86: Use naked attribute on nlr_push for gcc 8.0 and
 higher.

gcc 8.0 supports the naked attribute for x86 systems so it can now be used
here.  And in fact it is necessary to use this for nlr_push because gcc 8.0
no longer generates a prelude for this function (even without the naked
attribute).
---
 py/nlrx86.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/py/nlrx86.c b/py/nlrx86.c
index 23882cc307..59b97d8ee6 100644
--- a/py/nlrx86.c
+++ b/py/nlrx86.c
@@ -39,15 +39,29 @@ unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail");
 __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
 #endif
 
+#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
+// Since gcc 8.0 the naked attribute is supported
+#define USE_NAKED (1)
+#define UNDO_PRELUDE (0)
+#elif defined(__ZEPHYR__) || defined(__ANDROID__)
+// Zephyr and Android use a different calling convention by default
+#define USE_NAKED (0)
+#define UNDO_PRELUDE (0)
+#else
+#define USE_NAKED (0)
+#define UNDO_PRELUDE (1)
+#endif
+
+#if USE_NAKED
+__attribute__((naked))
+#endif
 unsigned int nlr_push(nlr_buf_t *nlr) {
+    #if !USE_NAKED
     (void)nlr;
+    #endif
 
     __asm volatile (
-    // Check for Zephyr, which uses a different calling convention
-    // by default.
-    // TODE: Better support for various x86 calling conventions
-    // (unfortunately, __attribute__((naked)) is not supported on x86).
-    #if !(defined(__ZEPHYR__) || defined(__ANDROID__))
+    #if UNDO_PRELUDE
     "pop    %ebp                \n" // undo function's prelude
     #endif
     "mov    4(%esp), %edx       \n" // load nlr_buf
@@ -61,7 +75,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
     "jmp    nlr_push_tail       \n" // do the rest in C
     );
 
+    #if !USE_NAKED
     return 0; // needed to silence compiler warning
+    #endif
 }
 
 NORETURN void nlr_jump(void *val) {