diff --git a/py/nlr.h b/py/nlr.h
index 4e931919dbbfb5e5eebe60b43c2cc442eb34f62f..05fe63d22d44c845302c429406cff7b359a92d94 100644
--- a/py/nlr.h
+++ b/py/nlr.h
@@ -2,12 +2,14 @@
 // exception handling, basically a stack of setjmp/longjmp buffers
 
 #include <limits.h>
+#include <setjmp.h>
 
 typedef struct _nlr_buf_t nlr_buf_t;
 struct _nlr_buf_t {
     // the entries here must all be machine word size
     nlr_buf_t *prev;
     void *ret_val;
+#if !MICROPY_NLR_SETJMP
 #if defined(__i386__)
     void *regs[6];
 #elif defined(__x86_64__)
@@ -19,13 +21,29 @@ struct _nlr_buf_t {
 #elif defined(__thumb2__)
     void *regs[10];
 #else
-#error Unknown arch in nlr.h
+    #define MICROPY_NLR_SETJMP (1)
+    #warning "No native NLR support for this arch, using setjmp implementation"
+#endif
+#endif
+
+#if MICROPY_NLR_SETJMP
+    jmp_buf jmpbuf;
 #endif
 };
 
+#if MICROPY_NLR_SETJMP
+extern nlr_buf_t *nlr_setjmp_top;
+void nlr_setjmp_jump(void *val) __attribute__((noreturn));
+// nlr_push() must be defined as a macro, because "The stack context will be
+// invalidated if the function which called setjmp() returns."
+#define nlr_push(buf) ((buf)->prev = nlr_setjmp_top, nlr_setjmp_top = (buf), setjmp((buf)->jmpbuf))
+#define nlr_pop() { nlr_setjmp_top = nlr_setjmp_top->prev; }
+#define nlr_jump(val) nlr_setjmp_jump(val)
+#else
 unsigned int nlr_push(nlr_buf_t *);
 void nlr_pop(void);
 void nlr_jump(void *val) __attribute__((noreturn));
+#endif
 
 // This must be implemented by a port.  It's called by nlr_jump
 // if no nlr buf has been pushed.  It must not return, but rather
diff --git a/py/nlrsetjmp.c b/py/nlrsetjmp.c
new file mode 100644
index 0000000000000000000000000000000000000000..a97c8634b2d83c2d54679a724df885f3ce19c3fb
--- /dev/null
+++ b/py/nlrsetjmp.c
@@ -0,0 +1,16 @@
+#include <setjmp.h>
+#include <stdio.h>
+#include "nlr.h"
+
+#if MICROPY_NLR_SETJMP
+
+nlr_buf_t *nlr_setjmp_top;
+
+void nlr_setjmp_jump(void *val) {
+    nlr_buf_t *buf = nlr_setjmp_top;
+    nlr_setjmp_top = buf->prev;
+    buf->ret_val = val;
+    longjmp(buf->jmpbuf, 1);
+}
+
+#endif
diff --git a/py/py.mk b/py/py.mk
index 5d02c95faf840bf7dbb0f7e92efc3e25a6086e5c..29e76cf52a67e023fab31964ba19f048759cbe1d 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -10,6 +10,7 @@ PY_O_BASENAME = \
 	nlrx86.o \
 	nlrx64.o \
 	nlrthumb.o \
+	nlrsetjmp.o \
 	malloc.o \
 	gc.o \
 	qstr.o \