merged volatile memory barriers
[cacao.git] / src / vm / jit / x86_64 / solaris / md-os.c
1 /* src/vm/jit/x86_64/solaris/md-os.c - machine dependent x86_64 Solaris functions
2
3    Copyright (C) 2008, 2009
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 <stdint.h>
30 #include <stdlib.h>
31 #include <ucontext.h>
32
33 #include "vm/types.h"
34
35 #include "vm/jit/x86_64/codegen.h"
36 #include "vm/jit/x86_64/md.h"
37
38 #include "threads/thread.hpp"
39
40 #include "vm/signallocal.hpp"
41
42 #include "vm/jit/asmpart.h"
43 #include "vm/jit/executionstate.h"
44 #include "vm/jit/trap.hpp"
45
46
47 /**
48  * Signal handler for hardware exceptions.
49  */
50 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
51 {
52         ucontext_t *_uc = (ucontext_t *) _p;
53         mcontext_t *_mc = &_uc->uc_mcontext;
54
55         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
56            different to the ones in <ucontext.h>. */
57
58         void* xpc = (void *) _mc->gregs[REG_RIP];
59
60     // Handle the trap.
61     trap_handle(TRAP_SIGSEGV, xpc, _p);
62 }
63
64
65 /**
66  * Signal handler for hardware divide by zero (ArithmeticException)
67  * check.
68  */
69 void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p)
70 {
71         ucontext_t *_uc = (ucontext_t *) _p;
72         mcontext_t *_mc = &_uc->uc_mcontext;
73
74         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
75            different to the ones in <ucontext.h>. */
76
77         void* xpc = (void *) _mc->gregs[REG_RIP];
78
79     // Handle the trap.
80     trap_handle(TRAP_SIGFPE, xpc, _p);
81 }
82
83
84 /**
85  * Signal handler for hardware patcher traps (ud2).
86  */
87 void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
88 {
89         ucontext_t *_uc = (ucontext_t *) _p;
90         mcontext_t *_mc = &_uc->uc_mcontext;
91
92         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
93            different to the ones in <ucontext.h>. */
94
95         void* xpc = (void *) _mc->gregs[REG_RIP];
96
97     // Handle the trap.
98     trap_handle(TRAP_SIGILL, xpc, _p);
99 }
100
101
102 /* md_signal_handler_sigusr2 ***************************************************
103
104    Signal handler for profiling sampling.
105
106 *******************************************************************************/
107
108 #if defined(ENABLE_THREADS)
109 void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p)
110 {
111         threadobject *t;
112         ucontext_t   *_uc;
113         mcontext_t   *_mc;
114         u1           *pc;
115
116         t = THREADOBJECT;
117
118         _uc = (ucontext_t *) _p;
119         _mc = &_uc->uc_mcontext;
120
121         /* ATTENTION: Don't use CACAO's internal REG_* defines as they are
122            different to the ones in <ucontext.h>. */
123
124         pc = (u1 *) _mc->gregs[REG_RIP];
125
126         t->pc = pc;
127 }
128 #endif
129
130
131 /* md_executionstate_read ******************************************************
132
133    Read the given context into an executionstate.
134
135 *******************************************************************************/
136
137 void md_executionstate_read(executionstate_t *es, void *context)
138 {
139         ucontext_t *_uc;
140         mcontext_t *_mc;
141         s4          i;
142         s4          d;
143
144         _uc = (ucontext_t *) context;
145         _mc = &_uc->uc_mcontext;
146
147         /* read special registers */
148         es->pc = (u1 *) _mc->gregs[REG_RIP];
149         es->sp = (u1 *) _mc->gregs[REG_RSP];
150         es->pv = NULL;
151
152         /* read integer registers */
153         for (i = 0; i < INT_REG_CNT; i++) {
154                 switch (i) {
155                 case 0:  /* REG_RAX */
156                         d = REG_RAX;
157                         break;
158                 case 1:  /* REG_RCX */
159                         d = REG_RCX;
160                         break;
161                 case 2:  /* REG_RDX */
162                         d = REG_RDX;
163                         break;
164                 case 3:  /* REG_RBX */
165                         d = REG_RBX;
166                         break;
167                 case 4:  /* REG_RSP */
168                         d = REG_RSP;
169                         break;
170                 case 5:  /* REG_RBP */
171                         d = REG_RBP;
172                         break;
173                 case 6:  /* REG_RSI */
174                         d = REG_RSI;
175                         break;
176                 case 7:  /* REG_RDI */
177                         d = REG_RDI;
178                         break;
179                 case 8:  /* REG_R8  == 7  */
180                 case 9:  /* REG_R9  == 6  */
181                 case 10: /* REG_R10 == 5  */
182                 case 11: /* REG_R11 == 4  */
183                 case 12: /* REG_R12 == 3  */
184                 case 13: /* REG_R13 == 2  */
185                 case 14: /* REG_R14 == 1  */
186                 case 15: /* REG_R15 == 0  */
187                         d = 15 - i;
188                         break;
189                 }
190
191                 es->intregs[i] = _mc->gregs[d];
192         }
193
194         /* read float registers */
195         for (i = 0; i < FLT_REG_CNT; i++)
196                 es->fltregs[i] = 0xdeadbeefdeadbeefL;
197 }
198
199
200 /* md_executionstate_write *****************************************************
201
202    Write the given executionstate back to the context.
203
204 *******************************************************************************/
205
206 void md_executionstate_write(executionstate_t *es, void *context)
207 {
208         ucontext_t *_uc;
209         mcontext_t *_mc;
210         s4          i;
211         s4          d;
212
213         _uc = (ucontext_t *) context;
214         _mc = &_uc->uc_mcontext;
215
216         /* write integer registers */
217         for (i = 0; i < INT_REG_CNT; i++) {
218                 switch (i) {
219                 case 0:  /* REG_RAX */
220                         d = REG_RAX;
221                         break;
222                 case 1:  /* REG_RCX */
223                         d = REG_RCX;
224                         break;
225                 case 2:  /* REG_RDX */
226                         d = REG_RDX;
227                         break;
228                 case 3:  /* REG_RBX */
229                         d = REG_RBX;
230                         break;
231                 case 4:  /* REG_RSP */
232                         d = REG_RSP;
233                         break;
234                 case 5:  /* REG_RBP */
235                         d = REG_RBP;
236                         break;
237                 case 6:  /* REG_RSI */
238                         d = REG_RSI;
239                         break;
240                 case 7:  /* REG_RDI */
241                         d = REG_RDI;
242                         break;
243                 case 8:  /* REG_R8  == 7  */
244                 case 9:  /* REG_R9  == 6  */
245                 case 10: /* REG_R10 == 5  */
246                 case 11: /* REG_R11 == 4  */
247                 case 12: /* REG_R12 == 3  */
248                 case 13: /* REG_R13 == 2  */
249                 case 14: /* REG_R14 == 1  */
250                 case 15: /* REG_R15 == 0  */
251                         d = 15 - i;
252                         break;
253                 }
254
255                 _mc->gregs[d] = es->intregs[i];
256         }
257
258         /* write special registers */
259         _mc->gregs[REG_RIP] = (ptrint) es->pc;
260         _mc->gregs[REG_RSP] = (ptrint) es->sp;
261 }
262
263
264 /*
265  * These are local overrides for various environment variables in Emacs.
266  * Please do not remove this and leave it at the end of the file, where
267  * Emacs will automagically detect them.
268  * ---------------------------------------------------------------------
269  * Local variables:
270  * mode: c
271  * indent-tabs-mode: t
272  * c-basic-offset: 4
273  * tab-width: 4
274  * End:
275  * vim:noexpandtab:sw=4:ts=4:
276  */