diff --git a/libc/Makefile b/libc/Makefile
index 83d3d051..5afd48a0 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -166,6 +166,7 @@ clock.o \
close.o \
$(CPUDIR)/calltrace.o \
$(CPUDIR)/fork.o \
+$(CPUDIR)/setjmp.o \
$(CPUDIR)/signal.o \
$(CPUDIR)/syscall.o \
creat.o \
@@ -293,7 +294,6 @@ select.o \
setegid.o \
seteuid.o \
setgid.o \
-setjmp.o \
setlocale.o \
settermmode.o \
setuid.o \
diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h
index 2fce613d..943c9ccc 100644
--- a/libc/include/setjmp.h
+++ b/libc/include/setjmp.h
@@ -29,12 +29,13 @@
__BEGIN_DECLS
-struct jmp_buf_struct
-{
- int unused;
-};
-
-typedef struct jmp_buf_struct jmp_buf[1];
+#if defined(__x86_64__)
+typedef unsigned long jmp_buf[8];
+#elif defined(__i386__)
+typedef unsigned long jmp_buf[6];
+#else
+#error "You need to implement jmp_buf on your CPU"
+#endif
void longjmp(jmp_buf env, int val);
int setjmp(jmp_buf env);
diff --git a/libc/x64/setjmp.s b/libc/x64/setjmp.s
new file mode 100644
index 00000000..24f44b2a
--- /dev/null
+++ b/libc/x64/setjmp.s
@@ -0,0 +1,62 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
+
+ This file is part of the Sortix C Library.
+
+ The Sortix C Library is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or (at your
+ option) any later version.
+
+ The Sortix C Library 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 Lesser General Public
+ License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with the Sortix C Library. If not, see .
+
+ x64/setjmp.s
+ Implement the assembly part of setjmp.
+
+*******************************************************************************/
+
+.global setjmp
+.type setjmp, @function
+setjmp:
+ # TODO: Floating point stuff!
+ mov %rbx, 0x00(%rdi)
+ mov %rsp, 0x08(%rdi)
+ mov %rbp, 0x10(%rdi)
+ mov %r12, 0x18(%rdi)
+ mov %r13, 0x20(%rdi)
+ mov %r14, 0x28(%rdi)
+ mov %r15, 0x30(%rdi)
+ mov 0(%rsp), %rax
+ mov %rax, 0x38(%rdi)
+ xorl %eax, %eax
+.Lsetjmp_return:
+ ret
+.size setjmp, . - setjmp
+
+.global longjmp
+.type longjmp, @function
+longjmp:
+ testl %esi, %esi
+ jnz 1f
+ mov $1, %esi
+1:
+ # TODO: Floating point stuff!
+ mov 0x00(%rdi), %rbx
+ mov 0x08(%rdi), %rsp
+ mov 0x10(%rdi), %rbp
+ mov 0x18(%rdi), %r12
+ mov 0x20(%rdi), %r13
+ mov 0x28(%rdi), %r14
+ mov 0x30(%rdi), %r15
+ mov 0x38(%rdi), %rax
+ mov %rax, 0(%rsp)
+ mov %esi, %eax
+ jmp .Lsetjmp_return
+.size longjmp, . - longjmp
diff --git a/libc/setjmp.c b/libc/x86/setjmp.s
similarity index 54%
rename from libc/setjmp.c
rename to libc/x86/setjmp.s
index 7d3cbe39..5e590214 100644
--- a/libc/setjmp.c
+++ b/libc/x86/setjmp.s
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2013.
This file is part of the Sortix C Library.
@@ -17,25 +17,44 @@
You should have received a copy of the GNU Lesser General Public License
along with the Sortix C Library. If not, see .
- setjmp.c
- Stack environment declarations.
+ x86/setjmp.s
+ Implement the assembly part of setjmp.
*******************************************************************************/
-#include
-#include
-#include
+.global setjmp
+.type setjmp, @function
+setjmp:
+ mov 4(%esp), %ecx
+ # TODO: Floating point stuff!
+ mov %ebx, 0x00(%ecx)
+ mov %esi, 0x04(%ecx)
+ mov %edi, 0x08(%ecx)
+ mov %ebp, 0x0C(%ecx)
+ mov %esp, 0x10(%ecx)
+ mov 0(%esp), %eax
+ mov %eax, 0x14(%ecx)
+ xorl %eax, %eax
+.Lsetjmp_return:
+ ret
+.size setjmp, . - setjmp
-void longjmp(jmp_buf env, int val)
-{
- (void) env;
- (void) val;
- fprintf(stderr, "setjmp(3) and longjmp(3) are unimplemented, abort!\n");
- abort();
-}
-
-int setjmp(jmp_buf env)
-{
- (void) env;
- return 0;
-}
+.global longjmp
+.type longjmp, @function
+longjmp:
+ mov 4(%esp), %ecx
+ mov 8(%esp), %edx
+ testl %edx, %edx
+ jnz 1f
+ mov $1, %edx
+1:
+ # TODO: Floating point stuff!
+ mov 0x04(%ecx), %esi
+ mov 0x08(%ecx), %edi
+ mov 0x0C(%ecx), %ebp
+ mov 0x10(%ecx), %esp
+ mov 0x14(%ecx), %eax
+ mov %eax, 0(%esp)
+ mov %edx, %eax
+ jmp .Lsetjmp_return
+.size longjmp, . - longjmp