bug-mes
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Implement setjmp for ARM mescc.


From: Danny Milosavljevic
Subject: [PATCH] Implement setjmp for ARM mescc.
Date: Thu, 4 Jun 2020 14:27:57 +0200

* include/setjmp.h: Add ARM case.
* lib/arm-mes-mescc/setjmp.c: New file.
---
 include/setjmp.h           | 10 +++++++
 lib/arm-mes-mescc/setjmp.c | 61 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 71 insertions(+)
 create mode 100644 lib/arm-mes-mescc/setjmp.c

diff --git a/include/setjmp.h b/include/setjmp.h
index 512ea111..fb5ae026 100644
--- a/include/setjmp.h
+++ b/include/setjmp.h
@@ -1,6 +1,7 @@
 /* -*-comment-start: "//";comment-end:""-*-
  * GNU Mes --- Maxwell Equations of Software
  * Copyright © 2017 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
  *
  * This file is part of GNU Mes.
  *
@@ -25,12 +26,21 @@
 #include_next <setjmp.h>
 #else // ! SYSTEM_LIBC
 
+#if __arm__
+typedef struct
+{
+  unsigned long sp;
+  unsigned long lr;
+  unsigned long fp;
+} __jmp_buf;
+#else
 typedef struct
 {
   long __bp;
   long __pc;
   long __sp;
 } __jmp_buf;
+#endif
 typedef __jmp_buf jmp_buf[1];
 
 #if __MESC__
diff --git a/lib/arm-mes-mescc/setjmp.c b/lib/arm-mes-mescc/setjmp.c
new file mode 100644
index 00000000..19f1ff1a
--- /dev/null
+++ b/lib/arm-mes-mescc/setjmp.c
@@ -0,0 +1,61 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * GNU Mes --- Maxwell Equations of Software
+ * Copyright © 2017,2018 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+ * Copyright © 2020 Danny Milosavljevic <dannym@scratchpost.org>
+ *
+ * This file is part of GNU Mes.
+ *
+ * GNU Mes is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or (at
+ * your option) any later version.
+ *
+ * GNU Mes is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+void
+longjmp (jmp_buf env, int val)
+{
+  val = val == 0 ? 1 : val;
+  asm ("!0xc ldr____%r0,(%fp,+#$i8)"); // val
+  asm ("!0x8 ldr____%fp,(%fp,+#$i8)"); // env
+
+  asm ("!0x0 ldr____%sp,(%fp,+#$i8)"); // env.sp
+  /* setjmp's ENV argument is missing in setjmp caller's frame.  Re-add it. */
+  asm ("pop____%lr"); // junk
+  asm ("push___%ebp");
+  asm ("!0x4 ldr____%lr,(%fp,+#$i8)"); // env.lr
+
+  asm ("!0x8 ldr____%fp,(%fp,+#$i8)"); // env.fp
+
+  asm ("push___%lr");
+  /* Avoid function epilogue */
+  asm ("ret");
+}
+
+int
+setjmp (__jmp_buf * env)
+{
+  /* Function prelude emitter emits: push %lr; push %fp; %fp := %sp */
+
+  long *p = (long*)&env; // location of parameter on stack
+  env[0].sp = p; // stack of caller of setjmp (location of ENV value)
+  env[0].lr = p[-1]; // caller of setjmp
+  env[0].fp = p[-2]; // frame of caller of setjmp
+
+  /* Function epilogue emitter emits: %sp := %fp; pop %fp; pop %lr; %pc := %lr.
+     That means that all of the setjmp state is gone after we return from
+     setjmp.
+     Once we enter longjmp, we can't use setjmp state and have to reconstruct
+     the state of setjmp's callsite instead. */
+  return 0;
+}



reply via email to

[Prev in Thread] Current Thread [Next in Thread]