3 #include "genesis/sbcl.h"
9 #if defined(LISP_FEATURE_FREEBSD)
10 #include <machine/fpu.h>
13 #if defined(LISP_FEATURE_OPENBSD)
14 #include <machine/fpu.h>
17 #if defined(LISP_FEATURE_DRAGONFLY)
18 #include <machine/npx.h>
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
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
)
70 return CONTEXT_ADDR_FROM_STEM(rax
);
72 return CONTEXT_ADDR_FROM_STEM(rcx
);
74 return CONTEXT_ADDR_FROM_STEM(rdx
);
76 return CONTEXT_ADDR_FROM_STEM(rbx
);
78 return CONTEXT_ADDR_FROM_STEM(rsp
);
80 return CONTEXT_ADDR_FROM_STEM(rbp
);
82 return CONTEXT_ADDR_FROM_STEM(rsi
);
84 return CONTEXT_ADDR_FROM_STEM(rdi
);
86 return CONTEXT_ADDR_FROM_STEM(r8
);
88 return CONTEXT_ADDR_FROM_STEM(r9
);
90 return CONTEXT_ADDR_FROM_STEM(r10
);
92 return CONTEXT_ADDR_FROM_STEM(r11
);
94 return CONTEXT_ADDR_FROM_STEM(r12
);
96 return CONTEXT_ADDR_FROM_STEM(r13
);
98 return CONTEXT_ADDR_FROM_STEM(r14
);
100 return CONTEXT_ADDR_FROM_STEM(r15
);
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
);
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 */
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)
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
));
153 #if defined(LISP_FEATURE_FREEBSD)
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
];
173 #if defined(LISP_FEATURE_OPENBSD)
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
];