Blame c97607db5ccc03afbccacf853f2cd06305c28251.patch

007ea5d
From c97607db5ccc03afbccacf853f2cd06305c28251 Mon Sep 17 00:00:00 2001
007ea5d
From: Damien George <damien.p.george@gmail.com>
007ea5d
Date: Tue, 15 May 2018 11:17:28 +1000
007ea5d
Subject: [PATCH] py/nlrx86: Use naked attribute on nlr_push for gcc 8.0 and
007ea5d
 higher.
007ea5d
007ea5d
gcc 8.0 supports the naked attribute for x86 systems so it can now be used
007ea5d
here.  And in fact it is necessary to use this for nlr_push because gcc 8.0
007ea5d
no longer generates a prelude for this function (even without the naked
007ea5d
attribute).
007ea5d
---
007ea5d
 py/nlrx86.c | 26 +++++++++++++++++++++-----
007ea5d
 1 file changed, 21 insertions(+), 5 deletions(-)
007ea5d
007ea5d
diff --git a/py/nlrx86.c b/py/nlrx86.c
007ea5d
index 23882cc307..59b97d8ee6 100644
007ea5d
--- a/py/nlrx86.c
007ea5d
+++ b/py/nlrx86.c
007ea5d
@@ -39,15 +39,29 @@ unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail");
007ea5d
 __attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
007ea5d
 #endif
007ea5d
 
007ea5d
+#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 8
007ea5d
+// Since gcc 8.0 the naked attribute is supported
007ea5d
+#define USE_NAKED (1)
007ea5d
+#define UNDO_PRELUDE (0)
007ea5d
+#elif defined(__ZEPHYR__) || defined(__ANDROID__)
007ea5d
+// Zephyr and Android use a different calling convention by default
007ea5d
+#define USE_NAKED (0)
007ea5d
+#define UNDO_PRELUDE (0)
007ea5d
+#else
007ea5d
+#define USE_NAKED (0)
007ea5d
+#define UNDO_PRELUDE (1)
007ea5d
+#endif
007ea5d
+
007ea5d
+#if USE_NAKED
007ea5d
+__attribute__((naked))
007ea5d
+#endif
007ea5d
 unsigned int nlr_push(nlr_buf_t *nlr) {
007ea5d
+    #if !USE_NAKED
007ea5d
     (void)nlr;
007ea5d
+    #endif
007ea5d
 
007ea5d
     __asm volatile (
007ea5d
-    // Check for Zephyr, which uses a different calling convention
007ea5d
-    // by default.
007ea5d
-    // TODE: Better support for various x86 calling conventions
007ea5d
-    // (unfortunately, __attribute__((naked)) is not supported on x86).
007ea5d
-    #if !(defined(__ZEPHYR__) || defined(__ANDROID__))
007ea5d
+    #if UNDO_PRELUDE
007ea5d
     "pop    %ebp                \n" // undo function's prelude
007ea5d
     #endif
007ea5d
     "mov    4(%esp), %edx       \n" // load nlr_buf
007ea5d
@@ -61,7 +75,9 @@ unsigned int nlr_push(nlr_buf_t *nlr) {
007ea5d
     "jmp    nlr_push_tail       \n" // do the rest in C
007ea5d
     );
007ea5d
 
007ea5d
+    #if !USE_NAKED
007ea5d
     return 0; // needed to silence compiler warning
007ea5d
+    #endif
007ea5d
 }
007ea5d
 
007ea5d
 NORETURN void nlr_jump(void *val) {