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