65 lines
2.1 KiB
Diff
65 lines
2.1 KiB
Diff
Source: https://github.com/micropython/micropython/commit/c97607db5ccc03afbccacf853f2cd06305c28251
|
|
Upstream: Yes
|
|
Reason: mpy-cross segfaults on i686
|
|
|
|
commit c97607db5ccc03afbccacf853f2cd06305c28251
|
|
Author: Damien George <damien.p.george@gmail.com>
|
|
Date: Tue May 15 11:17:28 2018 +1000
|
|
|
|
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).
|
|
|
|
diff --git py/nlrx86.c py/nlrx86.c
|
|
index 23882cc30..59b97d8ee 100644
|
|
--- py/nlrx86.c
|
|
+++ 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) {
|