Handle fpu state
diff --git a/src/x86_64/getcontext.S b/src/x86_64/getcontext.S
index 48a52d0..0488bad 100644
--- a/src/x86_64/getcontext.S
+++ b/src/x86_64/getcontext.S
@@ -55,12 +55,20 @@
movq %rax, UC_MCONTEXT_GREGS_RAX(%rdi)
movq %rcx, UC_MCONTEXT_GREGS_RCX(%rdi)
+#if defined __linux__
/* Save fp state (not needed, except for setcontext not
restoring garbage). */
leaq UC_MCONTEXT_FPREGS_MEM(%rdi),%r8
movq %r8, UC_MCONTEXT_FPREGS_PTR(%rdi)
fnstenv (%r8)
stmxcsr FPREGS_OFFSET_MXCSR(%r8)
+#elif defined __FreeBSD__
+ fxsave UC_MCONTEXT_FPSTATE(%rdi)
+ movq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
+ movq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
+#else
+#error Port me
+#endif
leaq 8(%rsp), %rax /* exclude this call. */
movq %rax, UC_MCONTEXT_GREGS_RSP(%rdi)
@@ -71,7 +79,5 @@
xorq %rax, %rax
retq
-#ifdef __linux__
/* We do not need executable stack. */
.section .note.GNU-stack,"",@progbits
-#endif
diff --git a/src/x86_64/setcontext.S b/src/x86_64/setcontext.S
index 6b06a7b..adbcf22 100644
--- a/src/x86_64/setcontext.S
+++ b/src/x86_64/setcontext.S
@@ -37,9 +37,20 @@
_Ux86_64_setcontext:
/* restore fp state */
+#if defined __linux__
mov UC_MCONTEXT_FPREGS_PTR(%rdi),%r8
fldenv (%r8)
ldmxcsr FPREGS_OFFSET_MXCSR(%r8)
+#elif defined __FreeBSD__
+ cmpq $UC_MCONTEXT_FPOWNED_FPU,UC_MCONTEXT_OWNEDFP(%rdi)
+ jne 1f
+ cmpq $UC_MCONTEXT_FPFMT_XMM,UC_MCONTEXT_FPFORMAT(%rdi)
+ jne 1f
+ fxrstor UC_MCONTEXT_FPSTATE(%rdi)
+1:
+#else
+#error Port me
+#endif
/* restore the rest of the state */
mov UC_MCONTEXT_GREGS_R8(%rdi),%r8
diff --git a/src/x86_64/ucontext_i.h b/src/x86_64/ucontext_i.h
index 2724bc0..c942080 100644
--- a/src/x86_64/ucontext_i.h
+++ b/src/x86_64/ucontext_i.h
@@ -61,7 +61,10 @@
#define UC_MCONTEXT_GREGS_RCX 0x30
#define UC_MCONTEXT_GREGS_RSP 0xa0
#define UC_MCONTEXT_GREGS_RIP 0xb0
-#define UC_MCONTEXT_FPREGS_PTR 0x1a8 /* XXXKIB */
-#define UC_MCONTEXT_FPREGS_MEM 0xe0 /* XXXKIB */
-#define FPREGS_OFFSET_MXCSR 0x18 /* XXXKIB */
+#define UC_MCONTEXT_FPSTATE 0xf0
+#define UC_MCONTEXT_OWNEDFP 0xe8
+#define UC_MCONTEXT_FPFORMAT 0xe0
+#define UC_MCONTEXT_FPOWNED_FPU 0x20001
+#define UC_MCONTEXT_FPFMT_XMM 0x10002
+
#endif