summaryrefslogtreecommitdiff
path: root/lib/libpthread/arch/i386
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-01-17 23:49:50 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-01-17 23:49:50 +0000
commit4a7fc69d62f684a7548d428f1a09bcefbabe0b6f (patch)
tree065c4b70643fe8a9eacbe5f48901a9cc0f0363d3 /lib/libpthread/arch/i386
parent9ebd7c855719a914d8220cf8b7ab845bd006e6fc (diff)
mi+md jmp_buf; save i386s fs and gs for WINE (csapuntz@stanford.edu)
Diffstat (limited to 'lib/libpthread/arch/i386')
-rw-r--r--lib/libpthread/arch/i386/uthread_machdep.h92
1 files changed, 70 insertions, 22 deletions
diff --git a/lib/libpthread/arch/i386/uthread_machdep.h b/lib/libpthread/arch/i386/uthread_machdep.h
index 652f32d4285..6e6e83b850c 100644
--- a/lib/libpthread/arch/i386/uthread_machdep.h
+++ b/lib/libpthread/arch/i386/uthread_machdep.h
@@ -1,40 +1,88 @@
/*
* OpenBSD/i386 machine-dependent thread macros
*
- * $OpenBSD: uthread_machdep.h,v 1.3 1999/01/10 22:59:33 d Exp $
+ * $OpenBSD: uthread_machdep.h,v 1.4 1999/01/17 23:49:49 d Exp $
*/
#include <machine/reg.h>
-/* save the floating point state of a thread */
-#define _thread_machdep_save_float_state(thr) \
- { \
+/*
+ * We need to extend jmp_buf to hold extended segment registers
+ * for WINE.
+ */
+typedef struct _machdep_jmp_buf {
+ union {
+ jmp_buf jb;
+ struct {
+ int eip;
+ int ebx;
+ int esp;
+ int ebp;
+ int esi;
+ int edi;
+ } jbs;
+ } u;
+#define mjb_eip u.jbs.eip
+#define mjb_ebx u.jbs.ebx
+#define mjb_esp u.jbs.esp
+#define mjb_ebp u.jbs.ebp
+#define mjb_esi u.jbs.esi
+#define mjb_edi u.jbs.edi
+ int mjb_ds; /* informational only - not restored */
+ int mjb_es; /* informational only - not restored */
+ int mjb_fs;
+ int mjb_gs;
+} _machdep_jmp_buf;
+
+/* Extra machine-dependent information */
+struct _machdep_struct {
+ struct fpreg saved_fp; /* only saved with on signals */
+};
+
+/* Save the floating point state of a thread: */
+#define _thread_machdep_save_float_state(thr) \
+ { \
char *fdata = (char*)(&(thr)->_machdep.saved_fp); \
- __asm__("fsave %0"::"m" (*fdata)); \
+ __asm__("fsave %0"::"m" (*fdata)); \
}
-/* restore the floating point state of a thread */
-#define _thread_machdep_restore_float_state(thr) \
- { \
+/* Restore the floating point state of a thread: */
+#define _thread_machdep_restore_float_state(thr) \
+ { \
char *fdata = (char*)(&(thr)->_machdep.saved_fp); \
- __asm__("frstor %0"::"m" (*fdata)); \
+ __asm__("frstor %0"::"m" (*fdata)); \
}
-/* initialise the jmpbuf stack frame so it continues from entry */
+/* Initialise the jmpbuf stack frame so it continues from entry: */
#define _thread_machdep_thread_create(thr, entry, pattr) \
- { \
- /* entry */ \
- (thr)->saved_jmp_buf[0] = (long) entry; \
- /* stack */ \
- (thr)->saved_jmp_buf[2] = (long) (thr)->stack \
- + (pattr)->stacksize_attr \
- - sizeof(double); \
+ { \
+ /* entry */ \
+ (thr)->saved_jmp_buf.mjb_eip = (long) entry; \
+ /* stack */ \
+ (thr)->saved_jmp_buf.mjb_esp = (long) (thr)->stack \
+ + (pattr)->stacksize_attr \
+ - sizeof(double); \
}
-#define _thread_machdep_longjmp(a,v) longjmp(a,v)
-#define _thread_machdep_setjmp(a) setjmp(a)
+static __inline int
+_thread_machdep_setjmp_helper(a)
+ _machdep_jmp_buf *a;
+{
+ int v;
-struct _machdep_struct {
- struct fpreg saved_fp;
-};
+ __asm__("mov %%ds, %0\n" : "=m" (a->mjb_ds) );
+ __asm__("mov %%es, %0\n" : "=m" (a->mjb_es) );
+ __asm__("mov %%fs, %0\n" : "=m" (a->mjb_fs) );
+ __asm__("mov %%gs, %0\n" : "=m" (a->mjb_gs) );
+ v = setjmp(a->u.jb);
+ if (v) {
+ __asm__("mov %0, %%gs\n" :: "m" (a->mjb_gs) );
+ __asm__("mov %0, %%fs\n" :: "m" (a->mjb_fs) );
+ /* __asm__("mov %0, %%es\n" :: "m" (a->mjb_es) ); */
+ /* __asm__("mov %0, %%ds\n" :: "m" (a->mjb_ds) ); */
+ }
+ return (v);
+}
+#define _thread_machdep_longjmp(a,v) longjmp((a).u.jb,v)
+#define _thread_machdep_setjmp(a) _thread_machdep_setjmp_helper(&(a))