mlibc: GNU Gcc support: setjmp, longjmp.
authorJan Nieuwenhuizen <janneke@gnu.org>
Sun, 26 Nov 2017 12:10:46 +0000 (13:10 +0100)
committerJan Nieuwenhuizen <janneke@gnu.org>
Sun, 26 Nov 2017 12:10:46 +0000 (13:10 +0100)
* stage0/x86.M1 (jmp____*%ebx): New macro.
  (mov____0x8(%ebp),%ebp): New macro.
  (mov____0x8(%ebp),%esp): New macro.
* include/setjmp.h (jmp_buf): Redefine as struct.
* lib/libc-mes+tcc.c (longjmp, setjmp): Implement.
* scaffold/tests/80-setjmp.c: Test it.
* make.scm ("80-setjmp"): Build it.
* .gitignore: Ignore *.tcc-guile.

.gitignore
include/setjmp.h
lib/libc-mes+tcc.c
make.scm
scaffold/tests/80-setjmp.c [new file with mode: 0644]
stage0/x86.M1

index 4ab37c9137917c0916b89c692f6ef0f114f7206a..ea64ef76395f73994f97986aa4878c3a9a027e6c 100644 (file)
@@ -18,6 +18,7 @@
 *.mini-hex2
 *.mlibc-gcc
 *.mlibc-o
+*.tcc-guile
 !/stage0/*
 !/stage0/*.c
 /stage0/exit-42.*
@@ -48,3 +49,4 @@
 /doc/fosdem/fosdem.tex
 /doc/fosdem/fosdem.toc
 /doc/fosdem/fosdem.*vrb
+
index c1c5300c385f80d2887508939c0c44adc56e1228..09ec2c63284c1cdf5a7f99368a3c0ed682dda8b5 100644 (file)
 #include_next <setjmp.h>
 #else // ! (__GNUC__ && POSIX)
 
-typedef int jmp_buf;
+typedef struct
+{
+  int __bp;
+  int __pc;
+  int __sp;
+} __jmp_buf;
+typedef __jmp_buf jmp_buf[1];
+
+#if __MESC__
+__jmp_buf buf[1];
+#else
+jmp_buf buf;
+#endif
+
 void longjmp (jmp_buf env, int val);
 int setjmp (jmp_buf env);
 
index 213448af034b581673df4b9af98bd1a59d6b19d6..01d69ccdf0f793a1e52857cfcb05317c61028d48 100644 (file)
@@ -184,7 +184,27 @@ localtime (time_t const *timep)
 void
 longjmp (jmp_buf env, int val)
 {
-  eputs ("longjmp stub\n");
+  val = val == 0 ? 1 : val;
+#if __MESC__
+  asm ("mov____0x8(%ebp),%eax !0x0c"); // val
+  asm ("mov____0x8(%ebp),%ebp !0x08"); // env*
+
+  asm ("mov____0x8(%ebp),%ebx !0x4");  // env.__pc
+  asm ("mov____0x8(%ebp),%esp !0x8");  // env.__sp
+  asm ("mov____0x8(%ebp),%ebp !0x0");  // env.__bp
+  asm ("jmp____*%ebx");
+#else
+  asm ("mov    0xc(%ebp),%eax\n\t"     // val
+       "mov    0x8(%ebp),%ebp\n\t"     // env*
+
+       "mov    0x4(%ebp),%ebx\n\t"     // env->__pc
+       "mov    0x8(%ebp),%esp\n\t"     // env->__sp
+       "mov    0x0(%ebp),%ebp\n\t"     // env->__bp
+       "jmp    *%ebx\n\t"              // jmp *PC
+       );
+#endif
+  // not reached
+  exit (42);
 }
 
 void *
@@ -235,10 +255,36 @@ remove (char const *file_name)
   return 0;
 }
 
+#if 0
+int
+setjmp_debug (jmp_buf env, int val)
+{
+  int i;
+#if 1
+  i = env->__bp;
+  i = env->__pc;
+  i = env->__sp;
+#else
+  i = env[0].__bp;
+  i = env[0].__pc;
+  i = env[0].__sp;
+#endif
+  return val == 0 ? 1 : val;
+}
+#endif
+
+#if __MESC__
+int
+setjmp (__jmp_buf *env)
+#else
 int
 setjmp (jmp_buf env)
+#endif
 {
-  eputs ("setjmp stub\n");
+  int *p = (int*)&env;
+  env[0].__bp = p[-2];
+  env[0].__pc = p[-1];
+  env[0].__sp = (int)&env;
   return 0;
 }
 
index 8f3651c8505603ca0368cfa8b262d8b456f3b3ed..e8419c529d7d4dbc66e2fe6b9e585aba498fe148 100755 (executable)
--- a/make.scm
+++ b/make.scm
@@ -128,6 +128,7 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
   (add-target (bin.mescc (string-append "scaffold/tests/" name ".c") #:libc libc #:includes includes))
   (add-target (check (string-append "scaffold/tests/" name "." (cond ((not libc) "0-")
                                                                      ((eq? libc mini-libc-mes.hex2) "mini-")
+                                                                     ((eq? libc libc-mes+tcc.hex2) "tcc-")
                                                                      (else "")) "guile") #:exit exit)))
 
 (add-target (compile.gcc "lib/crt1.c" #:libc #f))
@@ -253,6 +254,15 @@ exec ${GUILE-guile} --no-auto-compile -L . -L guile -C . -C guile -s "$0" ${1+"$
 
 (add-target (group "check-scaffold-tests" #:dependencies (filter (target-prefix? "check-scaffold/tests") %targets)))
 
+;; tests/80: and beyond tinycc; building GNU GCC and dependencies
+(for-each
+ (cut add-scaffold-test <> #:libc libc-mes+tcc.hex2 #:libc-gcc libc-gcc+tcc.mlibc-o)
+ '("80-setjmp"))
+
+(add-target (group "check-scaffold-tests/8" #:dependencies (filter (target-prefix? "check-scaffold/tests/8") %targets)))
+
+(add-target (group "check-scaffold-tests" #:dependencies (filter (target-prefix? "check-scaffold/tests") %targets)))
+
 (add-target (cpp.mescc "lib/libc-mes+tcc.c"))
 (add-target (compile.mescc "lib/libc-mes+tcc.c"))
 
diff --git a/scaffold/tests/80-setjmp.c b/scaffold/tests/80-setjmp.c
new file mode 100644 (file)
index 0000000..f052492
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*-comment-start: "//";comment-end:""-*-
+ * Mes --- Maxwell Equations of Software
+ * Copyright © 2017 Jan Nieuwenhuizen <janneke@gnu.org>
+ *
+ * This file is part of Mes.
+ *
+ * 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.
+ *
+ * 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 Mes.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "30-test.i"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <setjmp.h>
+
+int foo;
+
+void
+second()
+{
+  if (foo++) exit (1);
+  printf ("second\n");      // prints
+  longjmp (buf,1);          // jumps back to where setjmp was called - making setjmp now return 1
+  exit (1);
+}
+
+void
+first ()
+{
+  second ();
+  printf ("first\n");       // does not print
+  exit (2);
+}
+
+int
+test ()
+{
+  if (!setjmp (buf))
+    first ();               // when executed, setjmp returned 0
+  else                      // when longjmp jumps back, setjmp returns 1
+    {
+      printf ("main\n");    // prints
+      return 0;
+    }
+
+  return 3;
+}
index c3bfd43990b3ca95d1a67cac4898d6c0ec73c4e2..cbac03e288fcfd6901a97f3cbc6be69f84784c21 100644 (file)
@@ -51,8 +51,8 @@ DEFINE cmp____%al,%dl 38c2
 DEFINE cmp____%edx,%eax 39d0
 DEFINE hlt f4
 DEFINE idiv___%ebx f7fb
-DEFINE int____$0x80 cd80
 DEFINE int cd
+DEFINE int____$0x80 cd80
 DEFINE je32 0f84
 DEFINE je8 74
 DEFINE jg32 0f8f
@@ -60,6 +60,7 @@ DEFINE jge32 0f8d
 DEFINE jl32 0f8c
 DEFINE jle32 0f8e
 DEFINE jmp32 e9
+DEFINE jmp____*%ebx ffe3
 DEFINE jne32 0f85
 DEFINE lahf 9f
 DEFINE lea____0x32(%ebp),%eax 8d85
@@ -128,9 +129,11 @@ DEFINE mov____0x8(%eax),%eax 8b40
 DEFINE mov____0x8(%eax),%ebx 8b58
 DEFINE mov____0x8(%eax),%ecx 8b48
 DEFINE mov____0x8(%ebp),%eax 8b45
+DEFINE mov____0x8(%ebp),%ebp 8b6d
 DEFINE mov____0x8(%ebp),%ebx 8b5d
 DEFINE mov____0x8(%ebp),%ecx 8b4d
 DEFINE mov____0x8(%ebp),%edx 8b55
+DEFINE mov____0x8(%ebp),%esp 8b65
 DEFINE movzbl_%al,%eax 0fb6c0
 DEFINE movzbl_%dl,%edx 0fb6d2
 DEFINE movzbl_(%eax),%eax 0fb600