* src/threads/thread.c: Moved to .cpp.
[cacao.git] / src / vm / jit / powerpc / darwin / md-os.c
1 /* src/vm/jit/powerpc/darwin/md-os.c - machine dependent PowerPC Darwin functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23 */
24
25
26 #include "config.h"
27
28 #include <assert.h>
29 #include <signal.h>
30 #include <stdint.h>
31 #include <ucontext.h>
32
33 #include "vm/types.h"
34
35 #include "vm/jit/powerpc/codegen.h"
36 #include "vm/jit/powerpc/darwin/md-abi.h"
37
38 #include "threads/thread.hpp"
39
40 #include "vm/builtin.h"
41 #include "vm/exceptions.h"
42 #include "vm/global.h"
43 #include "vm/signallocal.h"
44 #include "vm/stringlocal.h"
45
46 #include "vm/jit/asmpart.h"
47
48
49 /* md_signal_handler_sigsegv ***************************************************
50
51    NullPointerException signal handler for hardware null pointer
52    check.
53
54 *******************************************************************************/
55
56 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
57 {
58         ucontext_t         *_uc;
59         mcontext_t          _mc;
60         ppc_thread_state_t *_ss;
61         ptrint             *gregs;
62         u1                 *pv;
63         u1                 *sp;
64         u1                 *ra;
65         u1                 *xpc;
66         u4                  mcode;
67         int                 s1;
68         int16_t             disp;
69         int                 d;
70         intptr_t            addr;
71         intptr_t            val;
72         int                 type;
73         void               *p;
74
75         _uc = (ucontext_t *) _p;
76         _mc = _uc->uc_mcontext;
77         _ss = &_mc->ss;
78
79         /* immitate a gregs array */
80
81         gregs = &_ss->r0;
82
83         /* get register values */
84
85         pv  = (u1 *) _ss->r13;
86         sp  = (u1 *) _ss->r1;
87         ra  = (u1 *) _ss->lr;                        /* this is correct for leafs */
88         xpc = (u1 *) _ss->srr0;
89
90         /* get exception-throwing instruction */
91
92         mcode = *((u4 *) xpc);
93
94         s1   = M_INSTR_OP2_IMM_A(mcode);
95         disp = M_INSTR_OP2_IMM_I(mcode);
96         d    = M_INSTR_OP2_IMM_D(mcode);
97
98         val  = gregs[d];
99
100         /* check for special-load */
101
102         if (s1 == REG_ZERO) {
103                 /* we use the exception type as load displacement */
104
105                 type = disp;
106
107                 if (type == EXCEPTION_HARDWARE_COMPILER) {
108                         /* The XPC is the RA minus 4, because the RA points to the
109                            instruction after the call. */
110
111                         xpc = ra - 4;
112                 }
113         }
114         else {
115                 /* This is a normal NPE: addr must be NULL and the NPE-type
116                    define is 0. */
117
118                 addr = gregs[s1];
119                 type = EXCEPTION_HARDWARE_NULLPOINTER;
120
121                 if (addr != 0)
122                         vm_abort("md_signal_handler_sigsegv: faulting address is not NULL: addr=%p", addr);
123         }
124
125         /* Handle the type. */
126
127         p = signal_handle(type, val, pv, sp, ra, xpc, _p);
128
129         /* Set registers. */
130
131         switch (type) {
132         case EXCEPTION_HARDWARE_COMPILER:
133                 if (p != NULL) {
134                         _ss->r13  = (uintptr_t) p;                              /* REG_PV */
135                         _ss->srr0 = (uintptr_t) p;
136                         break;
137                 }
138
139                 /* Get and set the PV from the parent Java method. */
140
141                 pv = md_codegen_get_pv_from_pc(ra);
142
143                 _ss->r13 = (uintptr_t) pv;
144
145                 /* Get the exception object. */
146
147                 p = builtin_retrieve_exception();
148
149                 assert(p != NULL);
150
151                 /* fall-through */
152
153         case EXCEPTION_HARDWARE_PATCHER:
154                 if (p == NULL)
155                         break;
156
157                 /* fall-through */
158                 
159         default:
160                 _ss->r11  = (uintptr_t) p;
161                 _ss->r12  = (uintptr_t) xpc;
162                 _ss->srr0 = (uintptr_t) asm_handle_exception;
163         }
164 }
165
166
167 /* md_signal_handler_sigtrap ***************************************************
168
169    Signal handler for hardware-traps.
170
171 *******************************************************************************/
172
173 void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p)
174 {
175         ucontext_t         *_uc;
176         mcontext_t          _mc;
177         ppc_thread_state_t *_ss;
178         ptrint             *gregs;
179         u1                 *pv;
180         u1                 *sp;
181         u1                 *ra;
182         u1                 *xpc;
183         u4                  mcode;
184         int                 s1;
185         intptr_t            val;
186         int                 type;
187         void               *p;
188
189         _uc = (ucontext_t *) _p;
190         _mc = _uc->uc_mcontext;
191         _ss = &_mc->ss;
192
193         /* immitate a gregs array */
194
195         gregs = &_ss->r0;
196
197         /* get register values */
198
199         pv  = (u1 *) _ss->r13;
200         sp  = (u1 *) _ss->r1;
201         ra  = (u1 *) _ss->lr;                    /* this is correct for leafs */
202         xpc = (u1 *) _ss->srr0;
203
204         /* get exception-throwing instruction */
205
206         mcode = *((u4 *) xpc);
207
208         s1 = M_OP3_GET_A(mcode);
209
210         /* for now we only handle ArrayIndexOutOfBoundsException */
211
212         type = EXCEPTION_HARDWARE_ARRAYINDEXOUTOFBOUNDS;
213         val  = gregs[s1];
214
215         /* Handle the type. */
216
217         p = signal_handle(type, val, pv, sp, ra, xpc, _p);
218
219         /* set registers */
220
221         _ss->r11  = (intptr_t) p;
222         _ss->r12  = (intptr_t) xpc;
223         _ss->srr0 = (intptr_t) asm_handle_exception;
224 }
225
226
227 /* md_signal_handler_sigusr2 ***************************************************
228
229    Signal handler for profiling sampling.
230
231 *******************************************************************************/
232
233 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
234 {
235         threadobject       *t;
236         ucontext_t         *_uc;
237         mcontext_t          _mc;
238         ppc_thread_state_t *_ss;
239         u1                 *pc;
240
241         t = THREADOBJECT;
242
243         _uc = (ucontext_t *) _p;
244         _mc = _uc->uc_mcontext;
245         _ss = &_mc->ss;
246
247         pc = (u1 *) _ss->srr0;
248
249         t->pc = pc;
250 }
251
252
253 /*
254  * These are local overrides for various environment variables in Emacs.
255  * Please do not remove this and leave it at the end of the file, where
256  * Emacs will automagically detect them.
257  * ---------------------------------------------------------------------
258  * Local variables:
259  * mode: c
260  * indent-tabs-mode: t
261  * c-basic-offset: 4
262  * tab-width: 4
263  * End:
264  */