merged volatile memory barriers
[cacao.git] / src / vm / jit / powerpc / linux / md-os.c
1 /* src/vm/jit/powerpc/linux/md-os.c - machine dependent PowerPC Linux functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5    Copyright (C) 2008, 2009 Theobroma Systems Ltd.
6
7    This file is part of CACAO.
8
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2, or (at
12    your option) any later version.
13
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22    02110-1301, USA.
23
24 */
25
26
27 #include "config.h"
28
29 #include <assert.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/md.h"
37 #include "vm/jit/powerpc/linux/md-abi.h"
38
39 #include "threads/thread.hpp"
40
41 #include "vm/signallocal.hpp"
42 #include "vm/os.hpp"
43
44 #include "vm/jit/executionstate.h"
45 #include "vm/jit/trap.hpp"
46
47
48 /**
49  * Signal handler for hardware-exceptions.
50  */
51 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
52 {
53         ucontext_t* _uc = (ucontext_t*) _p;
54         mcontext_t* _mc;
55         unsigned long* _gregs;
56
57 #if defined(__UCLIBC__)
58         _mc    = &(_uc->uc_mcontext);
59         _gregs = _mc->regs->gpr;
60 #else
61         _mc    = _uc->uc_mcontext.uc_regs;
62         _gregs = _mc->gregs;
63 #endif
64
65         void* xpc = (void*) _gregs[PT_NIP];
66
67         // Handle the trap.
68         trap_handle(TRAP_SIGSEGV, xpc, _p);
69 }
70
71
72 /**
73  * Signal handler for patcher calls.
74  */
75 void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p)
76 {
77         ucontext_t* _uc = (ucontext_t*) _p;
78         mcontext_t* _mc;
79         unsigned long* _gregs;
80
81 #if defined(__UCLIBC__)
82         _mc    = &(_uc->uc_mcontext);
83         _gregs = _mc->regs->gpr;
84 #else
85         _mc    = _uc->uc_mcontext.uc_regs;
86         _gregs = _mc->gregs;
87 #endif
88
89         void* xpc = (void*) _gregs[PT_NIP];
90
91         // Handle the trap.
92         trap_handle(TRAP_SIGILL, xpc, _p);
93 }
94
95
96 /**
97  * Signal handler for hardware-traps.
98  */
99 void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p)
100 {
101         ucontext_t* _uc = (ucontext_t*) _p;
102         mcontext_t* _mc;
103         unsigned long* _gregs;
104
105 #if defined(__UCLIBC__)
106         _mc    = &(_uc->uc_mcontext);
107         _gregs = _mc->regs->gpr;
108 #else
109         _mc    = _uc->uc_mcontext.uc_regs;
110         _gregs = _mc->gregs;
111 #endif
112
113         void* xpc = (void*) _gregs[PT_NIP];
114
115         // Handle the trap.
116         trap_handle(TRAP_SIGTRAP, xpc, _p);
117 }
118
119
120 /* md_signal_handler_sigusr2 ***************************************************
121
122    Signal handler for profiling sampling.
123
124 *******************************************************************************/
125
126 #if defined(ENABLE_THREADS)
127 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
128 {
129         threadobject  *tobj;
130         ucontext_t    *_uc;
131         mcontext_t    *_mc;
132         unsigned long *_gregs;
133         u1            *pc;
134
135         tobj = THREADOBJECT;
136
137         _uc = (ucontext_t *) _p;
138
139 #if defined(__UCLIBC__)
140         _mc    = &(_uc->uc_mcontext);
141         _gregs = _mc->regs->gpr;
142 #else
143         _mc    = _uc->uc_mcontext.uc_regs;
144         _gregs = _mc->gregs;
145 #endif
146
147         pc = (u1 *) _gregs[PT_NIP];
148
149         tobj->pc = pc;
150 }
151 #endif
152
153
154 /* md_executionstate_read ******************************************************
155
156    Read the given context into an executionstate.
157
158 *******************************************************************************/
159
160 void md_executionstate_read(executionstate_t *es, void *context)
161 {
162         ucontext_t    *_uc;
163         mcontext_t    *_mc;
164         unsigned long *_gregs;
165         s4              i;
166
167         _uc = (ucontext_t *) context;
168
169 #if defined(__UCLIBC__)
170 #error Please port md_executionstate_read to __UCLIBC__
171 #else
172         _mc    = _uc->uc_mcontext.uc_regs;
173         _gregs = _mc->gregs;
174 #endif
175
176         /* read special registers */
177         es->pc = (u1 *) _gregs[PT_NIP];
178         es->sp = (u1 *) _gregs[REG_SP];
179         es->pv = (u1 *) _gregs[REG_PV];
180         es->ra = (u1 *) _gregs[PT_LNK];
181
182         /* read integer registers */
183         for (i = 0; i < INT_REG_CNT; i++)
184                 es->intregs[i] = _gregs[i];
185
186         /* read float registers */
187         /* Do not use the assignment operator '=', as the type of
188          * the _mc->fpregs[i] can cause invalid conversions. */
189
190         assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
191         os_memcpy(&es->fltregs, &_mc->fpregs.fpregs, sizeof(_mc->fpregs.fpregs));
192 }
193
194
195 /* md_executionstate_write *****************************************************
196
197    Write the given executionstate back to the context.
198
199 *******************************************************************************/
200
201 void md_executionstate_write(executionstate_t *es, void *context)
202 {
203         ucontext_t    *_uc;
204         mcontext_t    *_mc;
205         unsigned long *_gregs;
206         s4              i;
207
208         _uc = (ucontext_t *) context;
209
210 #if defined(__UCLIBC__)
211 #error Please port md_executionstate_write to __UCLIBC__
212 #else
213         _mc    = _uc->uc_mcontext.uc_regs;
214         _gregs = _mc->gregs;
215 #endif
216
217         /* write integer registers */
218         for (i = 0; i < INT_REG_CNT; i++)
219                 _gregs[i] = es->intregs[i];
220
221         /* write float registers */
222         /* Do not use the assignment operator '=', as the type of
223          * the _mc->fpregs[i] can cause invalid conversions. */
224
225         assert(sizeof(_mc->fpregs.fpregs) == sizeof(es->fltregs));
226         os_memcpy(&_mc->fpregs.fpregs, &es->fltregs, sizeof(_mc->fpregs.fpregs));
227
228         /* write special registers */
229         _gregs[PT_NIP] = (ptrint) es->pc;
230         _gregs[REG_SP] = (ptrint) es->sp;
231         _gregs[REG_PV] = (ptrint) es->pv;
232         _gregs[PT_LNK] = (ptrint) es->ra;
233 }
234
235
236 /*
237  * These are local overrides for various environment variables in Emacs.
238  * Please do not remove this and leave it at the end of the file, where
239  * Emacs will automagically detect them.
240  * ---------------------------------------------------------------------
241  * Local variables:
242  * mode: c
243  * indent-tabs-mode: t
244  * c-basic-offset: 4
245  * tab-width: 4
246  * End:
247  */