aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libthread/OpenBSD-386-asm.s54
-rw-r--r--src/libthread/OpenBSD-386.c38
2 files changed, 92 insertions, 0 deletions
diff --git a/src/libthread/OpenBSD-386-asm.s b/src/libthread/OpenBSD-386-asm.s
new file mode 100644
index 00000000..f9a80255
--- /dev/null
+++ b/src/libthread/OpenBSD-386-asm.s
@@ -0,0 +1,54 @@
+.globl _tas
+_tas:
+ movl $0xCAFEBABE, %eax
+ movl 4(%esp), %ecx
+ xchgl %eax, 0(%ecx)
+ ret
+
+.globl setmcontext
+setmcontext:
+ movl 4(%esp), %edx
+ movl 8(%edx), %fs
+ movl 12(%edx), %es
+ movl 16(%edx), %ds
+ movl 76(%edx), %ss
+ movl 20(%edx), %edi
+ movl 24(%edx), %esi
+ movl 28(%edx), %ebp
+ movl %esp, %ecx
+ movl 72(%edx), %esp
+ pushl 60(%edx) /* eip */
+ pushl 44(%edx) /* ecx */
+ pushl 48(%edx) /* eax */
+ movl 36(%edx), %ebx
+ movl 40(%edx), %edx
+ movl 12(%ecx), %eax
+ popl %eax
+ popl %ecx
+ ret
+
+.globl getmcontext
+getmcontext:
+ pushl %edx
+ movl 8(%esp), %edx
+ movl %fs, 8(%edx)
+ movl %es, 12(%edx)
+ movl %ds, 16(%edx)
+ movl %ss, 76(%edx)
+ movl %edi, 20(%edx)
+ movl %esi, 24(%edx)
+ movl %ebp, 28(%edx)
+ movl %ebx, 36(%edx)
+ movl $1, 48(%edx)
+ popl %eax
+ movl %eax, 40(%edx)
+ movl %ecx, 44(%edx)
+ movl (%esp), %eax /* eip */
+ movl %eax, 60(%edx)
+ movl %esp, %eax
+ addl $4, %eax /* setmcontext will re-push the eip */
+ movl %eax, 72(%edx)
+ movl 40(%edx), %edx
+ xorl %eax, %eax
+ ret
+
diff --git a/src/libthread/OpenBSD-386.c b/src/libthread/OpenBSD-386.c
new file mode 100644
index 00000000..74179743
--- /dev/null
+++ b/src/libthread/OpenBSD-386.c
@@ -0,0 +1,38 @@
+#include "threadimpl.h"
+
+void
+makecontext(ucontext_t *ucp, void (*func)(void), int argc, ...)
+{
+ int *sp;
+
+ sp = (int*)ucp->uc_stack.ss_sp+ucp->uc_stack.ss_size/4;
+ sp -= argc;
+ memmove(sp, &argc+1, argc*sizeof(int));
+ *--sp = 0; /* return address */
+ ucp->uc_mcontext.mc_eip = (long)func;
+ ucp->uc_mcontext.mc_esp = (int)sp;
+}
+
+extern int getmcontext(mcontext_t*);
+extern int setmcontext(mcontext_t*);
+
+int
+getcontext(ucontext_t *uc)
+{
+ return getmcontext(&uc->uc_mcontext);
+}
+
+void
+setcontext(ucontext_t *uc)
+{
+ setmcontext(&uc->uc_mcontext);
+}
+
+int
+swapcontext(ucontext_t *oucp, ucontext_t *ucp)
+{
+ if(getcontext(oucp) == 0)
+ setcontext(ucp);
+ return 0;
+}
+