head	1.3;
access;
symbols;
locks; strict;
comment	@# @;


1.3
date	2006.12.27.15.17.05;	author miwi;	state dead;
branches;
next	1.2;

1.2
date	2006.12.09.09.31.29;	author miwi;	state Exp;
branches;
next	1.1;

1.1
date	2006.12.02.00.20.41;	author miwi;	state Exp;
branches;
next	;


desc
@@


1.3
log
@- Update to 1.0.1

PR:             ports/107223
Submitted by:   NIIMI Satoshi <sa2c@@sa2c.net> (maintainer)
@
text
@--- make-config.sh	Thu Nov 30 02:36:43 2006 +0000
+++ make-config.sh	Thu Nov 30 11:42:35 2006 +0900
@@@@ -102,6 +102,7 @@@@ case `uname -m` in
     *86) guessed_sbcl_arch=x86 ;;
     i86pc) guessed_sbcl_arch=x86 ;;
     *x86_64) guessed_sbcl_arch=x86-64 ;;
+    amd64) guessed_sbcl_arch=x86-64 ;;
     [Aa]lpha) guessed_sbcl_arch=alpha ;;
     sparc*) guessed_sbcl_arch=sparc ;;
     sun*) guessed_sbcl_arch=sparc ;;
--- src/runtime/GNUmakefile	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/GNUmakefile	Thu Nov 30 13:26:27 2006 +0900
@@@@ -58,7 +58,7 @@@@ targets: $(TARGET) sbcl.nm
 	$(CC) ${LINKFLAGS} -o $@@ $^ $(LIBS)
 
 sbcl.nm: $(TARGET)
-	$(NM) $(TARGET) | $(GREP) -v " F \| U " > ,$@@
+	$(NM) $(TARGET) | $(GREP) -v " [FUw] " > ,$@@
 	mv -f ,$@@ $@@
 
 sbcl.h: $(wildcard genesis/*.h)
--- src/runtime/breakpoint.h	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/breakpoint.h	Thu Nov 30 18:16:38 2006 +0900
@@@@ -22,5 +22,7 @@@@ extern void handle_breakpoint(int signal
                               os_context_t *context);
 extern void *handle_fun_end_breakpoint(int signal, siginfo_t *info,
                                        os_context_t *context);
+extern void handle_single_step_trap (os_context_t *context, int kind,
+                                     int register_offset);
 
 #endif
--- src/runtime/bsd-os.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/bsd-os.c	Thu Nov 30 18:38:30 2006 +0900
@@@@ -41,6 +41,9 @@@@
 #include <signal.h>
 /* #include <sys/sysinfo.h> */
 #include "validate.h"
+#if defined LISP_FEATURE_GENCGC
+#include "gencgc-internal.h"
+#endif
 
 os_vm_size_t os_vm_page_size;
 
@@@@ -55,7 +58,6 @@@@ static void netbsd_init();
 
 #ifdef __FreeBSD__
 #include <sys/sysctl.h>
-#include <osreldate.h>
 
 static void freebsd_init();
 #endif /* __FreeBSD__ */
@@@@ -71,23 +73,6 @@@@ os_init(char *argv[], char *envp[])
 #ifdef __FreeBSD__
     freebsd_init();
 #endif /* __FreeBSD__ */
-}
-
-int *os_context_pc_addr(os_context_t *context)
-{
-#if defined __FreeBSD__
-    return CONTEXT_ADDR_FROM_STEM(eip);
-#elif defined __OpenBSD__
-    return CONTEXT_ADDR_FROM_STEM(pc);
-#elif defined __NetBSD__
-    return CONTEXT_ADDR_FROM_STEM(EIP);
-#elif defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
-    return CONTEXT_ADDR_FROM_STEM(eip);
-#elif defined LISP_FEATURE_DARWIN
-    return &context->uc_mcontext->ss.srr0;
-#else
-#error unsupported BSD variant
-#endif
 }
 
 sigset_t *
@@@@ -172,9 +157,11 @@@@ is_valid_lisp_addr(os_vm_address_t addr)
        in_range_p(addr, DYNAMIC_SPACE_START  , dynamic_space_size))
         return 1;
     for_each_thread(th) {
-        if((th->control_stack_start <= addr) && (addr < th->control_stack_end))
+        if(((os_vm_address_t)th->control_stack_start <= addr) &&
+           (addr < (os_vm_address_t)th->control_stack_end))
             return 1;
-        if(in_range_p(addr, th->binding_stack_start, BINDING_STACK_SIZE))
+        if(in_range_p(addr, (lispobj)th->binding_stack_start,
+                      BINDING_STACK_SIZE))
             return 1;
     }
     return 0;
@@@@ -191,10 +178,20 @@@@ is_valid_lisp_addr(os_vm_address_t addr)
  * page fault on this OS.
  */
 static void
-memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context)
+memory_fault_handler(int signal, siginfo_t *siginfo, void *void_context
+#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
+/* FreeBSD/amd64 stores fault address only in undocumented 4th arg. */
+                     ,void *fault_addr
+#endif
+    )
 {
     os_context_t *context = arch_os_get_context(&void_context);
+#if defined(LISP_FEATURE_FREEBSD) && defined(LISP_FEATURE_X86_64)
+    /* KLUDGE: Store fault address into si_addr for compatibilities. */
+    siginfo->si_addr = fault_addr;
+#else
     void *fault_addr = arch_get_bad_addr(signal, siginfo, context);
+#endif
 
 #if defined(LISP_FEATURE_RESTORE_TLS_SEGMENT_REGISTER_FROM_CONTEXT)
     FSHOW_SIGNAL((stderr, "/ TLS: restoring fs: %p in memory_fault_handler\n",
@@@@ -202,7 +199,7 @@@@ memory_fault_handler(int signal, siginfo
     os_restore_tls_segment_register(context);
 #endif
 
-    FSHOW((stderr, "Memory fault at: %p, PC: %x\n", fault_addr, *os_context_pc_addr(context)));
+    FSHOW((stderr, "Memory fault at: %p, PC: %p\n", fault_addr, *os_context_pc_addr(context)));
 
     if (!gencgc_handle_wp_violation(fault_addr))
         if(!handle_guard_page_triggered(context,fault_addr)) {
@@@@ -225,9 +222,15 @@@@ os_install_interrupt_handlers(void)
 {
     SHOW("os_install_interrupt_handlers()/bsd-os/defined(GENCGC)");
     undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT,
+#ifdef LISP_FEATURE_FREEBSD
+                                                 (__siginfohandler_t *)
+#endif
                                                  memory_fault_handler);
 #ifdef SIG_MEMORY_FAULT2
     undoably_install_low_level_interrupt_handler(SIG_MEMORY_FAULT2,
+#ifdef LISP_FEATURE_FREEBSD
+                                                 (__siginfohandler_t *)
+#endif
                                                  memory_fault_handler);
 #endif
 
@@@@ -363,6 +366,8 @@@@ static void freebsd_init()
 #define KERN_PROC_PATHNAME 12
 #endif
 
+extern int getosreldate(void);
+
 char *
 os_get_runtime_executable_path()
 {
--- src/runtime/bsd-os.h	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/bsd-os.h	Thu Nov 30 12:46:02 2006 +0900
@@@@ -31,7 +31,6 @@@@ typedef vm_size_t os_vm_size_t;
 #endif
 typedef off_t os_vm_offset_t;
 typedef int os_vm_prot_t;
-typedef int os_context_register_t;
 
 #if defined __OpenBSD__
 /* name defined for compatibility between OpenBSD 3.1 sigaltstack(2) and
--- src/runtime/coreparse.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/coreparse.c	Thu Nov 30 18:19:58 2006 +0900
@@@@ -107,7 +107,7 @@@@ lose:
 }
 
 static void
-process_directory(int fd, u32 *ptr, int count, os_vm_offset_t file_offset)
+process_directory(int fd, lispobj *ptr, int count, os_vm_offset_t file_offset)
 {
     struct ndir_entry *entry;
 
--- src/runtime/interrupt.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/interrupt.c	Thu Nov 30 18:21:43 2006 +0900
@@@@ -584,7 +584,6 @@@@ run_deferred_handler(struct interrupt_da
      * pending handler before calling it. Trust the handler to finish
      * with the siginfo before enabling interrupts. */
     void (*pending_handler) (int, siginfo_t*, void*)=data->pending_handler;
-    os_context_t *context = arch_os_get_context(&v_context);
 
     data->pending_handler=0;
     (*pending_handler)(data->pending_signal,&(data->pending_info), v_context);
--- src/runtime/parse.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/parse.c	Thu Nov 30 18:22:24 2006 +0900
@@@@ -12,6 +12,7 @@@@
  */
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <ctype.h>
 #include <signal.h>
 
--- src/runtime/print.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/print.c	Thu Nov 30 18:22:44 2006 +0900
@@@@ -19,6 +19,7 @@@@
  */
 
 #include <stdio.h>
+#include <string.h>
 
 #include "sbcl.h"
 #include "print.h"
--- src/runtime/x86-64-arch.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/x86-64-arch.c	Thu Nov 30 19:03:02 2006 +0900
@@@@ -50,7 +50,7 @@@@ arch_get_bad_addr(int sig, siginfo_t *co
  * want to get to, and on OS, which determines how we get to it.)
  */
 
-int *
+os_context_register_t *
 context_eflags_addr(os_context_t *context)
 {
 #if defined __linux__
@@@@ -61,7 +61,7 @@@@ context_eflags_addr(os_context_t *contex
      * instead. */
     return &context->uc_mcontext.gregs[17];
 #elif defined __FreeBSD__
-    return &context->uc_mcontext.mc_eflags;
+    return &context->uc_mcontext.mc_rflags;
 #elif defined __OpenBSD__
     return &context->sc_eflags;
 #else
@@@@ -106,7 +106,7 @@@@ void arch_skip_instruction(os_context_t 
             break;
 
         default:
-            fprintf(stderr,"[arch_skip_inst invalid code %d\n]\n",code);
+            fprintf(stderr,"[arch_skip_inst invalid code %ld\n]\n",code);
             break;
         }
 
@@@@ -166,6 +166,11 @@@@ arch_remove_breakpoint(void *pc, unsigne
 /* When single stepping, single_stepping holds the original instruction
  * PC location. */
 unsigned int *single_stepping = NULL;
+#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
+unsigned int  single_step_save1;
+unsigned int  single_step_save2;
+unsigned int  single_step_save3;
+#endif
 
 void
 arch_do_displaced_inst(os_context_t *context, unsigned int orig_inst)
@@@@ -176,9 +181,24 @@@@ arch_do_displaced_inst(os_context_t *con
     *((char *)pc) = orig_inst & 0xff;
     *((char *)pc + 1) = (orig_inst & 0xff00) >> 8;
 
+#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
+    /* Install helper instructions for the single step:
+     * pushf; or [esp],0x100; popf. */
+    single_step_save1 = *(pc-3);
+    single_step_save2 = *(pc-2);
+    single_step_save3 = *(pc-1);
+    *(pc-3) = 0x9c909090;
+    *(pc-2) = 0x00240c81;
+    *(pc-1) = 0x9d000001;
+#else
     *context_eflags_addr(context) |= 0x100;
+#endif
 
     single_stepping = pc;
+
+#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
+    *os_context_pc_addr(context) = (os_context_register_t)((char *)pc - 9);
+#endif
 }
 
 
@@@@ -191,10 +211,17 @@@@ sigtrap_handler(int signal, siginfo_t *i
 
     if (single_stepping && (signal==SIGTRAP))
     {
+#ifdef CANNOT_GET_TO_SINGLE_STEP_FLAG
+        /* Un-install single step helper instructions. */
+        *(single_stepping-3) = single_step_save1;
+        *(single_stepping-2) = single_step_save2;
+        *(single_stepping-1) = single_step_save3;
+#else
         *context_eflags_addr(context) ^= 0x100;
-
+#endif
         /* Re-install the breakpoint if possible. */
-        if (*os_context_pc_addr(context) == (int)single_stepping + 1) {
+        if ((char *)*os_context_pc_addr(context) ==
+            (char *)single_stepping + 1) {
             fprintf(stderr, "warning: couldn't reinstall breakpoint\n");
         } else {
             *((char *)single_stepping) = BREAKPOINT_INST;       /* x86 INT3 */
@@@@ -216,7 +243,7 @@@@ sigtrap_handler(int signal, siginfo_t *i
        single-stepping (as far as I can tell) this is somewhat moot,
        but it might be worth either moving this code up or deleting
        the single-stepping code entirely.  -- CSR, 2002-07-15 */
-#ifdef LISP_FEATURE_LINUX
+#if defined(LISP_FEATURE_LINUX) || defined(RESTORE_FP_CONTROL_FROM_CONTEXT)
     os_restore_fp_control(context);
 #endif
 
--- src/runtime/x86-bsd-os.c	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/x86-bsd-os.c	Thu Nov 30 12:28:00 2006 +0900
@@@@ -100,6 +100,22 @@@@ os_context_sp_addr(os_context_t *context
 
 #endif  /* __NetBSD__ */
 
+int *os_context_pc_addr(os_context_t *context)
+{
+#if defined __FreeBSD__
+    return CONTEXT_ADDR_FROM_STEM(eip);
+#elif defined __OpenBSD__
+    return CONTEXT_ADDR_FROM_STEM(pc);
+#elif defined __NetBSD__
+    return CONTEXT_ADDR_FROM_STEM(EIP);
+#elif defined(LISP_FEATURE_DARWIN) && defined(LISP_FEATURE_X86)
+    return CONTEXT_ADDR_FROM_STEM(eip);
+#elif defined LISP_FEATURE_DARWIN
+    return &context->uc_mcontext->ss.srr0;
+#else
+#error unsupported BSD variant
+#endif
+}
 
 /* FIXME: If this can be a no-op on BSD/x86, then it
  * deserves a more precise name.
--- src/runtime/x86-bsd-os.h	Thu Nov 30 02:36:43 2006 +0000
+++ src/runtime/x86-bsd-os.h	Thu Nov 30 12:43:00 2006 +0900
@@@@ -5,6 +5,8 @@@@
 #include <machine/segments.h>
 #include <machine/cpufunc.h>
 #endif
+
+typedef int os_context_register_t;
 
 static inline os_context_t *arch_os_get_context(void **void_context) {
     return (os_context_t *) *void_context;
--- tests/foreign-stack-alignment.impure.lisp	Thu Nov 30 02:36:43 2006 +0000
+++ tests/foreign-stack-alignment.impure.lisp	Thu Nov 30 16:41:00 2006 +0900
@@@@ -43,7 +43,7 @@@@
 ;;;; number.
 
 (run "cc"
-     #+(and linux (or x86-64 ppc)) "-fPIC"
+     #+(and (or linux freebsd) (or x86-64 ppc)) "-fPIC"
      "stack-alignment-offset.c" "-o" "stack-alignment-offset")
 
 (defparameter *good-offset*
@@@@ -53,7 +53,7 @@@@
 ;;;; Build the tool again, this time as a shared object, and load it
 
 (run "cc" "stack-alignment-offset.c"
-     #+(and linux (or x86-64 ppc)) "-fPIC"
+     #+(and (or linux freebsd) (or x86-64 ppc)) "-fPIC"
      #+darwin "-bundle" #-darwin "-shared"
      "-o" "stack-alignment-offset.so")
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ src/runtime/Config.x86-64-bsd	Thu Nov 30 17:01:43 2006 +0900
@@@@ -0,0 +1,25 @@@@
+# -*- makefile -*- for the C-level run-time support for SBCL
+# configuration stuff shared between various *BSD OSes
+
+# This software is part of the SBCL system. See the README file for
+# more information.
+#
+# This software is derived from the CMU CL system, which was
+# written at Carnegie Mellon University and released into the
+# public domain. The software is in the public domain and is
+# provided with absolutely no warranty. See the COPYING and CREDITS
+# files for more information.
+
+ASSEM_SRC = x86-64-assem.S
+ARCH_SRC = x86-64-arch.c
+
+OS_SRC = bsd-os.c x86-64-bsd-os.c
+OS_LIBS = # -ldl
+
+CFLAGS += -fno-omit-frame-pointer
+
+GC_SRC = gencgc.c
+
+# Nothing to do for after-grovel-headers.
+.PHONY: after-grovel-headers
+after-grovel-headers:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ src/runtime/Config.x86-64-freebsd	Thu Nov 30 11:47:03 2006 +0900
@@@@ -0,0 +1,26 @@@@
+# -*- makefile -*- for the C-level run-time support for SBCL
+
+# This software is part of the SBCL system. See the README file for
+# more information.
+#
+# This software is derived from the CMU CL system, which was
+# written at Carnegie Mellon University and released into the
+# public domain. The software is in the public domain and is
+# provided with absolutely no warranty. See the COPYING and CREDITS
+# files for more information.
+
+include Config.x86-64-bsd
+
+ASSEM_SRC += ldso-stubs.S
+
+# Until sbcl-0.6.7.3, we used "LINKFLAGS+=-static" here, which
+# worked fine for most things, but LOAD-FOREIGN & friends require
+# dlopen() etc., which in turn depend on dynamic linking of the
+# runtime.
+LINKFLAGS += -dynamic -export-dynamic
+
+# use libthr (1:1 threading).  libpthread (m:n threading) does not work.
+ifdef LISP_FEATURE_SB_THREAD
+  #OS_LIBS += -lpthread
+  OS_LIBS += -lthr
+endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ src/runtime/x86-64-bsd-os.c	Thu Nov 30 16:02:37 2006 +0900
@@@@ -0,0 +1,115 @@@@
+#include <signal.h>
+#include "sbcl.h"
+#include "runtime.h"
+#include "thread.h"
+#include "lispregs.h"
+
+#if defined(LISP_FEATURE_FREEBSD)
+#include <machine/fpu.h>
+#endif
+
+/* KLUDGE: There is strong family resemblance in the signal context
+ * stuff in FreeBSD and OpenBSD, but in detail they're different in
+ * almost every line of code. It would be nice to find some way to
+ * factor out the commonality better; failing that, it might be best
+ * just to split this generic-BSD code into one variant for each BSD.
+ *
+ * KLUDGE II: this split has begun with the addition of the Darwin BSD
+ * flavour, with the cross-architecture complications that this
+ * entails; unfortunately, currently the situation is worse, not
+ * better, than in the above paragraph. */
+
+#if defined(LISP_FEATURE_FREEBSD)
+os_context_register_t *
+os_context_register_addr(os_context_t *context, int offset)
+{
+    switch(offset) {
+    case reg_RAX:
+        return CONTEXT_ADDR_FROM_STEM(rax);
+    case reg_RCX:
+        return CONTEXT_ADDR_FROM_STEM(rcx);
+    case reg_RDX:
+        return CONTEXT_ADDR_FROM_STEM(rdx);
+    case reg_RBX:
+        return CONTEXT_ADDR_FROM_STEM(rbx);
+    case reg_RSP:
+        return CONTEXT_ADDR_FROM_STEM(rsp);
+    case reg_RBP:
+        return CONTEXT_ADDR_FROM_STEM(rbp);
+    case reg_RSI:
+        return CONTEXT_ADDR_FROM_STEM(rsi);
+    case reg_RDI:
+        return CONTEXT_ADDR_FROM_STEM(rdi);
+    case reg_R8:
+        return CONTEXT_ADDR_FROM_STEM(r8);
+    case reg_R9:
+        return CONTEXT_ADDR_FROM_STEM(r9);
+    case reg_R10:
+        return CONTEXT_ADDR_FROM_STEM(r10);
+    case reg_R11:
+        return CONTEXT_ADDR_FROM_STEM(r11);
+    case reg_R12:
+        return CONTEXT_ADDR_FROM_STEM(r12);
+    case reg_R13:
+        return CONTEXT_ADDR_FROM_STEM(r13);
+    case reg_R14:
+        return CONTEXT_ADDR_FROM_STEM(r14);
+    case reg_R15:
+        return CONTEXT_ADDR_FROM_STEM(r15);
+    default:
+        return 0;
+    }
+}
+
+os_context_register_t *
+os_context_sp_addr(os_context_t *context)
+{
+    return CONTEXT_ADDR_FROM_STEM(rsp);
+}
+
+os_context_register_t *
+os_context_pc_addr(os_context_t *context)
+{
+    return CONTEXT_ADDR_FROM_STEM(rip);
+}
+
+#endif
+
+void
+os_flush_icache(os_vm_address_t address, os_vm_size_t length)
+{
+}
+
+int arch_os_thread_init(struct thread *thread) {
+    stack_t sigstack;
+#ifdef LISP_FEATURE_SB_THREAD
+    pthread_setspecific(specials,thread);
+#endif
+#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
+    /* Signal handlers are run on the control stack, so if it is exhausted
+     * we had better use an alternate stack for whatever signal tells us
+     * we've exhausted it */
+    sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
+    sigstack.ss_flags=0;
+    sigstack.ss_size = 32*SIGSTKSZ;
+    sigaltstack(&sigstack,0);
+#endif
+    return 1;                  /* success */
+}
+
+int arch_os_thread_cleanup(struct thread *thread) {
+    return 1;                  /* success */
+}
+
+#if defined(LISP_FEATURE_FREEBSD)
+void
+os_restore_fp_control(os_context_t *context)
+{
+    struct envxmm *ex = (struct envxmm*)(&context->uc_mcontext.mc_fpstate);
+    /* reset exception flags and restore control flags on SSE2 FPU */
+    unsigned int temp = (ex->en_mxcsr) & ~0x3F;
+    asm ("ldmxcsr %0" : : "m" (temp));
+    /* same for x87 FPU. */
+    asm ("fldcw %0" : : "m" (ex->en_cw));
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ src/runtime/x86-64-bsd-os.h	Thu Nov 30 12:45:17 2006 +0900
@@@@ -0,0 +1,34 @@@@
+#ifndef _X86_64_BSD_OS_H
+#define _X86_64_BSD_OS_H
+
+#ifdef LISP_FEATURE_FREEBSD
+#include <machine/segments.h>
+#include <machine/cpufunc.h>
+#endif
+
+typedef register_t os_context_register_t;
+
+static inline os_context_t *arch_os_get_context(void **void_context) {
+    return (os_context_t *) *void_context;
+}
+
+/* The different BSD variants have diverged in exactly where they
+ * store signal context information, but at least they tend to use the
+ * same stems to name the structure fields, so by using this macro we
+ * can share a fair amount of code between different variants. */
+#if defined __FreeBSD__
+#define CONTEXT_ADDR_FROM_STEM(stem) &context->uc_mcontext.mc_ ## stem
+#elif defined(__OpenBSD__)
+#define CONTEXT_ADDR_FROM_STEM(stem) &context->sc_ ## stem
+#elif defined __NetBSD__
+#define CONTEXT_ADDR_FROM_STEM(stem) &((context)->uc_mcontext.__gregs[_REG_ ## stem])
+#else
+#error unsupported BSD variant
+#endif
+
+#if defined LISP_FEATURE_FREEBSD
+#define RESTORE_FP_CONTROL_FROM_CONTEXT
+void os_restore_fp_control(os_context_t *context);
+#endif
+
+#endif /* _X86_64_BSD_OS_H */
--- src/runtime/x86-64-arch.c	Thu Nov 30 19:20:11 2006 +0900
+++ src/runtime/x86-64-arch.c	Sun Dec 03 02:26:51 2006 +0900
@@@@ -308,6 +308,56 @@@@ sigill_handler(int signal, siginfo_t *si
     lose("fake_foreign_function_call fell through");
 }
 
+#ifdef X86_64_SIGFPE_FIXUP
+#define MXCSR_IE (0x01)         /* Invalid Operation */
+#define MXCSR_DE (0x02)         /* Denormal */
+#define MXCSR_ZE (0x04)         /* Devide-by-Zero */
+#define MXCSR_OE (0x08)         /* Overflow */
+#define MXCSR_UE (0x10)         /* Underflow */
+#define MXCSR_PE (0x20)         /* Precision */
+
+static inline int
+mxcsr_to_code(unsigned int mxcsr)
+{
+    /* Extract unmasked exception bits. */
+    mxcsr &= ~(mxcsr >> 7) & 0x3F;
+
+    /* This order is defined at "Intel 64 and IA-32 Architectures
+     * Software Developerfs Manual" Volume 1: "Basic Architecture",
+     * 4.9.2 "Floating-Point Exception Priority". */
+    if (mxcsr & MXCSR_IE)
+        return FPE_FLTINV;
+    else if (mxcsr & MXCSR_ZE)
+        return FPE_FLTDIV;
+    else if (mxcsr & MXCSR_DE)
+        return FPE_FLTUND;
+    else if (mxcsr & MXCSR_OE)
+        return FPE_FLTOVF;
+    else if (mxcsr & MXCSR_UE)
+        return FPE_FLTUND;
+    else if (mxcsr & MXCSR_PE)
+        return FPE_FLTRES;
+
+    return 0;
+}
+
+static void
+sigfpe_handler(int signal, siginfo_t *siginfo, void *void_context)
+{
+    os_context_t *context = arch_os_get_context(&void_context);
+    unsigned int *mxcsr = arch_os_context_mxcsr_addr(context);
+
+    if (siginfo->si_code == 0) { /* XMM exception */
+        siginfo->si_code = mxcsr_to_code(*mxcsr);
+
+        /* Clear sticky exception flag. */
+        *mxcsr &= ~0x3F;
+    }
+
+    interrupt_handle_now(signal, siginfo, context);
+}
+#endif
+
 void
 arch_install_interrupt_handlers()
 {
@@@@ -325,6 +375,9 @@@@ arch_install_interrupt_handlers()
      * why.. -- WHN 2001-06-07 */
     undoably_install_low_level_interrupt_handler(SIGILL , sigill_handler);
     undoably_install_low_level_interrupt_handler(SIGTRAP, sigtrap_handler);
+#ifdef X86_64_SIGFPE_FIXUP
+    undoably_install_low_level_interrupt_handler(SIGFPE, sigfpe_handler);
+#endif
 
     SHOW("returning from arch_install_interrupt_handlers()");
 }
--- src/runtime/x86-64-bsd-os.h	Thu Nov 30 19:20:11 2006 +0900
+++ src/runtime/x86-64-bsd-os.h	Sun Dec 03 02:26:51 2006 +0900
@@@@ -2,8 +2,7 @@@@
 #define _X86_64_BSD_OS_H
 
 #ifdef LISP_FEATURE_FREEBSD
-#include <machine/segments.h>
-#include <machine/cpufunc.h>
+#include <machine/fpu.h>
 #endif
 
 typedef register_t os_context_register_t;
@@@@ -29,6 +28,16 @@@@ static inline os_context_t *arch_os_get_
 #if defined LISP_FEATURE_FREEBSD
 #define RESTORE_FP_CONTROL_FROM_CONTEXT
 void os_restore_fp_control(os_context_t *context);
+
+/* FreeBSD does not setup si_code on XMM exception. */
+#define X86_64_SIGFPE_FIXUP
+
+static inline unsigned int *
+arch_os_context_mxcsr_addr(os_context_t *context)
+{
+    struct envxmm *ex = (struct envxmm *)(&context->uc_mcontext.mc_fpstate);
+    return &ex->en_mxcsr;
+}
 #endif
 
 #endif /* _X86_64_BSD_OS_H */
@


1.2
log
@- Fix handling of floating point exception on AMD64.
- Support build on AMD64 with threading.

PR:             ports/106506
Submitted  by:  NIIMI Satoshi <sa2c@@sa2c.net>
@
text
@@


1.1
log
@- Update to 1.0

Submitted by:   NIIMI Satoshi <sa2c@@sa2c.net> (maintainer)
@
text
@d560 98
@

