Late-breaking NEWS for late-breaking fixes
[sbcl.git] / src / runtime / x86-64-bsd-os.c
blob4a0c5f7a1f6aefdec7839ffa638431d30bb342b1
1 #include <signal.h>
2 #include <errno.h>
3 #include "genesis/sbcl.h"
4 #include "runtime.h"
5 #include "thread.h"
6 #include "interr.h"
7 #include "lispregs.h"
9 #if defined(LISP_FEATURE_FREEBSD)
10 #include <machine/fpu.h>
11 #endif
13 #if defined(LISP_FEATURE_OPENBSD)
14 #include <machine/fpu.h>
15 #endif
17 #if defined(LISP_FEATURE_DRAGONFLY)
18 #include <machine/npx.h>
19 #endif
21 /* KLUDGE: There is strong family resemblance in the signal context
22 * stuff in FreeBSD and OpenBSD, but in detail they're different in
23 * almost every line of code. It would be nice to find some way to
24 * factor out the commonality better; failing that, it might be best
25 * just to split this generic-BSD code into one variant for each BSD.
27 * KLUDGE II: this split has begun with the addition of the Darwin BSD
28 * flavour, with the cross-architecture complications that this
29 * entails; unfortunately, currently the situation is worse, not
30 * better, than in the above paragraph. */
32 #ifdef LISP_FEATURE_NETBSD
33 #define _REG_rax _REG_RAX
34 #define _REG_rcx _REG_RCX
35 #define _REG_rdx _REG_RDX
36 #define _REG_rbx _REG_RBX
37 #define _REG_rsp _REG_RSP
38 #define _REG_rbp _REG_RBP
39 #define _REG_rsi _REG_RSI
40 #define _REG_rdi _REG_RDI
41 #define _REG_r8 _REG_R8
42 #define _REG_r9 _REG_R9
43 #define _REG_r10 _REG_R10
44 #define _REG_r11 _REG_R11
45 #define _REG_r12 _REG_R12
46 #define _REG_r13 _REG_R13
47 #define _REG_r14 _REG_R14
48 #define _REG_r15 _REG_R15
49 #endif
51 void visit_context_registers(void (*proc)(os_context_register_t,void*),
52 os_context_t *context, void* arg)
54 proc(OS_CONTEXT_PC(context), arg);
55 proc(CONTEXT_SLOT(context, rax), arg); proc(CONTEXT_SLOT(context, r8), arg);
56 proc(CONTEXT_SLOT(context, rcx), arg); proc(CONTEXT_SLOT(context, r9), arg);
57 proc(CONTEXT_SLOT(context, rdx), arg); proc(CONTEXT_SLOT(context, r10), arg);
58 proc(CONTEXT_SLOT(context, rbx), arg); proc(CONTEXT_SLOT(context, r11), arg);
59 /* ignore rsp */ proc(CONTEXT_SLOT(context, r12), arg);
60 /* ignore rbp */ proc(CONTEXT_SLOT(context, r13), arg);
61 proc(CONTEXT_SLOT(context, rsi), arg); proc(CONTEXT_SLOT(context, r14), arg);
62 proc(CONTEXT_SLOT(context, rdi), arg); proc(CONTEXT_SLOT(context, r15), arg);
65 os_context_register_t *
66 os_context_register_addr(os_context_t *context, int offset)
68 switch(offset) {
69 case reg_RAX:
70 return CONTEXT_ADDR_FROM_STEM(rax);
71 case reg_RCX:
72 return CONTEXT_ADDR_FROM_STEM(rcx);
73 case reg_RDX:
74 return CONTEXT_ADDR_FROM_STEM(rdx);
75 case reg_RBX:
76 return CONTEXT_ADDR_FROM_STEM(rbx);
77 case reg_RSP:
78 return CONTEXT_ADDR_FROM_STEM(rsp);
79 case reg_RBP:
80 return CONTEXT_ADDR_FROM_STEM(rbp);
81 case reg_RSI:
82 return CONTEXT_ADDR_FROM_STEM(rsi);
83 case reg_RDI:
84 return CONTEXT_ADDR_FROM_STEM(rdi);
85 case reg_R8:
86 return CONTEXT_ADDR_FROM_STEM(r8);
87 case reg_R9:
88 return CONTEXT_ADDR_FROM_STEM(r9);
89 case reg_R10:
90 return CONTEXT_ADDR_FROM_STEM(r10);
91 case reg_R11:
92 return CONTEXT_ADDR_FROM_STEM(r11);
93 case reg_R12:
94 return CONTEXT_ADDR_FROM_STEM(r12);
95 case reg_R13:
96 return CONTEXT_ADDR_FROM_STEM(r13);
97 case reg_R14:
98 return CONTEXT_ADDR_FROM_STEM(r14);
99 case reg_R15:
100 return CONTEXT_ADDR_FROM_STEM(r15);
101 default:
102 return 0;
106 os_context_register_t *
107 os_context_sp_addr(os_context_t *context)
109 return CONTEXT_ADDR_FROM_STEM(rsp);
112 os_context_register_t *
113 os_context_fp_addr(os_context_t *context)
115 return CONTEXT_ADDR_FROM_STEM(rbp);
118 void
119 os_flush_icache(os_vm_address_t address, os_vm_size_t length)
123 int arch_os_thread_init(struct thread *thread) {
124 /* Signal handlers are run on the control stack, so if it is exhausted
125 * we had better use an alternate stack for whatever signal tells us
126 * we've exhausted it */
127 stack_t sigstack;
128 sigstack.ss_sp = calc_altstack_base(thread);
129 sigstack.ss_flags = 0;
130 sigstack.ss_size = calc_altstack_size(thread);
131 if (sigaltstack(&sigstack,0)<0)
132 lose("Cannot sigaltstack: %s",strerror(errno));
133 return 1; /* success */
136 int arch_os_thread_cleanup(struct thread *thread) {
137 return 1; /* success */
140 #if defined(LISP_FEATURE_DRAGONFLY)
141 void
142 os_restore_fp_control(os_context_t *context)
144 struct envxmm *ex = (struct envxmm*)(&context->uc_mcontext.mc_fpregs);
145 /* reset exception flags and restore control flags on SSE2 FPU */
146 unsigned int temp = (ex->en_mxcsr) & ~0x3F;
147 asm ("ldmxcsr %0" : : "m" (temp));
148 /* same for x87 FPU. */
149 asm ("fldcw %0" : : "m" (ex->en_cw));
151 #endif
153 #if defined(LISP_FEATURE_FREEBSD)
154 void
155 os_restore_fp_control(os_context_t *context)
157 struct envxmm *ex = (struct envxmm*)(&context->uc_mcontext.mc_fpstate);
158 /* reset exception flags and restore control flags on SSE2 FPU */
159 unsigned int temp = (ex->en_mxcsr) & ~0x3F;
160 asm ("ldmxcsr %0" : : "m" (temp));
161 /* same for x87 FPU. */
162 asm ("fldcw %0" : : "m" (ex->en_cw));
165 os_context_register_t *
166 os_context_float_register_addr(os_context_t *context, int offset)
168 return (os_context_register_t *)&((struct savefpu*)&context->uc_mcontext.mc_fpstate)->sv_xmm[offset];
171 #endif
173 #if defined(LISP_FEATURE_OPENBSD)
174 void
175 os_restore_fp_control(os_context_t *context)
177 if (context->sc_fpstate != NULL) {
178 u_int32_t mxcsr = context->sc_fpstate->fx_mxcsr & ~0x3F;
179 u_int16_t cw = context->sc_fpstate->fx_fcw;
180 asm ("ldmxcsr %0" : : "m" (mxcsr));
181 asm ("fldcw %0" : : "m" (cw));
185 os_context_register_t *
186 os_context_float_register_addr(os_context_t *context, int offset)
188 return (os_context_register_t *)&context->sc_fpstate->fx_xmm[offset];
190 #endif