diff --git a/src/lisp/gencgc.c b/src/lisp/gencgc.c
index cab6a0c6cb0ac5538533e736862dfc13b1098ca0..905f551751099f96e63a3b154e5227b56a797138 100644
--- a/src/lisp/gencgc.c
+++ b/src/lisp/gencgc.c
@@ -663,38 +663,6 @@ gen_av_mem_age(int gen)
 	generations[gen].bytes_allocated;
 }
 
-/*
- * Define macro to allocate a local array of the appropriate size
- * where the fpu state can be stored.
- */
-#if defined(i386) || defined(__x86_64)
-#define FPU_STATE_SIZE 27
-    /* 
-     * Need 512 byte area, aligned on a 16-byte boundary.  So allocate
-     * 512+16 bytes of space and let the routine adjust use the
-     * appropriate alignment.
-     */
-#define SSE_STATE_SIZE ((512+16)/4)
-
-/*
- * Just use the SSE size for both x87 and sse2 since the SSE size is
- * enough for either.
- */
-#define FPU_STATE(name)    int name[SSE_STATE_SIZE];
-
-#elif defined(sparc)
-/*
- * 32 (single-precision) FP registers, and the FP state register.
- * But Sparc V9 has 32 double-precision registers (equivalent to 64
- * single-precision, but can't be accessed), so we leave enough room
- * for that.
- */
-#define FPU_STATE_SIZE (((32 + 32 + 1) + 1)/2)
-#define FPU_STATE(name)    long long name[FPU_STATE_SIZE];
-#elif defined(DARWIN) && defined(__ppc__)
-#define FPU_STATE_SIZE 32
-#define FPU_STATE(name0    long long name[FPU_STATE_SIZE];
-#endif
 
 void
 save_fpu_state(void* state)
diff --git a/src/lisp/os.h b/src/lisp/os.h
index 4c76df2a89bb7d1563030c29f4977e040483606e..c99647481fd43f5594b8e7f967bb4b652e855957 100644
--- a/src/lisp/os.h
+++ b/src/lisp/os.h
@@ -122,4 +122,39 @@ extern boolean os_support_sse2(void);
 
 char* convert_lisp_string(char* c_string, void* lisp_string, int len);
 
+/*
+ * Define macro to allocate a local array of the appropriate size
+ * where the fpu state can be stored.
+ */
+#if defined(i386) || defined(__x86_64)
+#define FPU_STATE_SIZE 27
+    /* 
+     * Need 512 byte area, aligned on a 16-byte boundary.  So allocate
+     * 512+16 bytes of space and let the routine adjust use the
+     * appropriate alignment.
+     */
+#define SSE_STATE_SIZE ((512+16)/4)
+
+/*
+ * Just use the SSE size for both x87 and sse2 since the SSE size is
+ * enough for either.
+ */
+#define FPU_STATE(name)    int name[SSE_STATE_SIZE];
+
+#elif defined(sparc)
+/*
+ * 32 (single-precision) FP registers, and the FP state register.
+ * But Sparc V9 has 32 double-precision registers (equivalent to 64
+ * single-precision, but can't be accessed), so we leave enough room
+ * for that.
+ */
+#define FPU_STATE_SIZE (((32 + 32 + 1) + 1)/2)
+#define FPU_STATE(name)    long long name[FPU_STATE_SIZE];
+#elif defined(DARWIN) && defined(__ppc__)
+#define FPU_STATE_SIZE 32
+#define FPU_STATE(name)    long long name[FPU_STATE_SIZE];
+#endif
+extern void save_fpu_state(void*);
+extern void restore_fpu_state(void*);
+
 #endif /* _OS_H_ */
diff --git a/src/lisp/x86-arch.c b/src/lisp/x86-arch.c
index 2932b135f459bd8a91ad1fc885a58963c600eb39..ee38f92a39fd4f3d939b64713658300e5890e54a 100644
--- a/src/lisp/x86-arch.c
+++ b/src/lisp/x86-arch.c
@@ -340,17 +340,14 @@ sigtrap_handler(HANDLER_ARGS)
 
       case trap_Halt:
 	  {
-#ifndef __linux__
-	      int fpu_state[27];
+              FPU_STATE(fpu_state);
+              save_fpu_state(fpu_state);
 
-	      fpu_save(fpu_state);
-#endif
 	      fake_foreign_function_call(os_context);
 	      lose("%%primitive halt called; the party is over.\n");
 	      undo_fake_foreign_function_call(os_context);
-#ifndef __linux__
-	      fpu_restore(fpu_state);
-#endif
+
+              restore_fpu_state(fpu_state);
 	      arch_skip_instruction(os_context);
 	      break;
 	  }