1.0.0.32: support for FreeBSD/x86-64
[sbcl.git] / src / runtime / x86-64-bsd-os.c
1 #include <signal.h>
2 #include "sbcl.h"
3 #include "runtime.h"
4 #include "thread.h"
5 #include "lispregs.h"
6
7 #if defined(LISP_FEATURE_FREEBSD)
8 #include <machine/fpu.h>
9 #endif
10
11 /* KLUDGE: There is strong family resemblance in the signal context
12  * stuff in FreeBSD and OpenBSD, but in detail they're different in
13  * almost every line of code. It would be nice to find some way to
14  * factor out the commonality better; failing that, it might be best
15  * just to split this generic-BSD code into one variant for each BSD.
16  *
17  * KLUDGE II: this split has begun with the addition of the Darwin BSD
18  * flavour, with the cross-architecture complications that this
19  * entails; unfortunately, currently the situation is worse, not
20  * better, than in the above paragraph. */
21
22 #if defined(LISP_FEATURE_FREEBSD)
23 os_context_register_t *
24 os_context_register_addr(os_context_t *context, int offset)
25 {
26     switch(offset) {
27     case reg_RAX:
28         return CONTEXT_ADDR_FROM_STEM(rax);
29     case reg_RCX:
30         return CONTEXT_ADDR_FROM_STEM(rcx);
31     case reg_RDX:
32         return CONTEXT_ADDR_FROM_STEM(rdx);
33     case reg_RBX:
34         return CONTEXT_ADDR_FROM_STEM(rbx);
35     case reg_RSP:
36         return CONTEXT_ADDR_FROM_STEM(rsp);
37     case reg_RBP:
38         return CONTEXT_ADDR_FROM_STEM(rbp);
39     case reg_RSI:
40         return CONTEXT_ADDR_FROM_STEM(rsi);
41     case reg_RDI:
42         return CONTEXT_ADDR_FROM_STEM(rdi);
43     case reg_R8:
44         return CONTEXT_ADDR_FROM_STEM(r8);
45     case reg_R9:
46         return CONTEXT_ADDR_FROM_STEM(r9);
47     case reg_R10:
48         return CONTEXT_ADDR_FROM_STEM(r10);
49     case reg_R11:
50         return CONTEXT_ADDR_FROM_STEM(r11);
51     case reg_R12:
52         return CONTEXT_ADDR_FROM_STEM(r12);
53     case reg_R13:
54         return CONTEXT_ADDR_FROM_STEM(r13);
55     case reg_R14:
56         return CONTEXT_ADDR_FROM_STEM(r14);
57     case reg_R15:
58         return CONTEXT_ADDR_FROM_STEM(r15);
59     default:
60         return 0;
61     }
62 }
63
64 os_context_register_t *
65 os_context_sp_addr(os_context_t *context)
66 {
67     return CONTEXT_ADDR_FROM_STEM(rsp);
68 }
69
70 os_context_register_t *
71 os_context_pc_addr(os_context_t *context)
72 {
73     return CONTEXT_ADDR_FROM_STEM(rip);
74 }
75
76 #endif
77
78 void
79 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
80 {
81 }
82
83 int arch_os_thread_init(struct thread *thread) {
84     stack_t sigstack;
85 #ifdef LISP_FEATURE_SB_THREAD
86     pthread_setspecific(specials,thread);
87 #endif
88 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
89     /* Signal handlers are run on the control stack, so if it is exhausted
90      * we had better use an alternate stack for whatever signal tells us
91      * we've exhausted it */
92     sigstack.ss_sp=((void *) thread)+dynamic_values_bytes;
93     sigstack.ss_flags=0;
94     sigstack.ss_size = 32*SIGSTKSZ;
95     sigaltstack(&sigstack,0);
96 #endif
97     return 1;                  /* success */
98 }
99
100 int arch_os_thread_cleanup(struct thread *thread) {
101     return 1;                  /* success */
102 }
103
104 #if defined(LISP_FEATURE_FREEBSD)
105 void
106 os_restore_fp_control(os_context_t *context)
107 {
108     struct envxmm *ex = (struct envxmm*)(&context->uc_mcontext.mc_fpstate);
109     /* reset exception flags and restore control flags on SSE2 FPU */
110     unsigned int temp = (ex->en_mxcsr) & ~0x3F;
111     asm ("ldmxcsr %0" : : "m" (temp));
112     /* same for x87 FPU. */
113     asm ("fldcw %0" : : "m" (ex->en_cw));
114 }
115 #endif