1
2 /*---------------------------------------------------------------*/
3 /*--- begin guest_ppc_helpers.c ---*/
4 /*---------------------------------------------------------------*/
5
6 /*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
10 Copyright (C) 2004-2013 OpenWorks LLP
11 info@open-works.net
12
13 This program is free software; you can redistribute it and/or
14 modify it under the terms of the GNU General Public License as
15 published by the Free Software Foundation; either version 2 of the
16 License, or (at your option) any later version.
17
18 This program is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
26 02110-1301, USA.
27
28 The GNU General Public License is contained in the file COPYING.
29
30 Neither the names of the U.S. Department of Energy nor the
31 University of California nor the names of its contributors may be
32 used to endorse or promote products derived from this software
33 without prior written permission.
34 */
35
36 #include "libvex_basictypes.h"
37 #include "libvex_emnote.h"
38 #include "libvex_guest_ppc32.h"
39 #include "libvex_guest_ppc64.h"
40 #include "libvex_ir.h"
41 #include "libvex.h"
42
43 #include "main_util.h"
44 #include "main_globals.h"
45 #include "guest_generic_bb_to_IR.h"
46 #include "guest_ppc_defs.h"
47
48
49 /* This file contains helper functions for ppc32 and ppc64 guest code.
50 Calls to these functions are generated by the back end. These
51 calls are of course in the host machine code and this file will be
52 compiled to host machine code, so that all makes sense.
53
54 Only change the signatures of these helper functions very
55 carefully. If you change the signature here, you'll have to change
56 the parameters passed to it in the IR calls constructed by
57 guest-ppc/toIR.c.
58 */
59
60
61 /*---------------------------------------------------------------*/
62 /*--- Misc integer helpers. ---*/
63 /*---------------------------------------------------------------*/
64
65 /* CALLED FROM GENERATED CODE */
66 /* DIRTY HELPER (non-referentially-transparent) */
67 /* Horrible hack. On non-ppc platforms, return 1. */
68 /* Reads a complete, consistent 64-bit TB value. */
ppcg_dirtyhelper_MFTB(void)69 ULong ppcg_dirtyhelper_MFTB ( void )
70 {
71 # if defined(__powerpc__) || defined(_AIX)
72 ULong res;
73 UInt lo, hi1, hi2;
74 while (1) {
75 __asm__ __volatile__ ("\n"
76 "\tmftbu %0\n"
77 "\tmftb %1\n"
78 "\tmftbu %2\n"
79 : "=r" (hi1), "=r" (lo), "=r" (hi2)
80 );
81 if (hi1 == hi2) break;
82 }
83 res = ((ULong)hi1) << 32;
84 res |= (ULong)lo;
85 return res;
86 # else
87 return 1ULL;
88 # endif
89 }
90
91
92 /* CALLED FROM GENERATED CODE */
93 /* DIRTY HELPER (non-referentially transparent) */
ppc32g_dirtyhelper_MFSPR_268_269(UInt r269)94 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 )
95 {
96 # if defined(__powerpc__) || defined(_AIX)
97 UInt spr;
98 if (r269) {
99 __asm__ __volatile__("mfspr %0,269" : "=b"(spr));
100 } else {
101 __asm__ __volatile__("mfspr %0,268" : "=b"(spr));
102 }
103 return spr;
104 # else
105 return 0;
106 # endif
107 }
108
109
110 /* CALLED FROM GENERATED CODE */
111 /* DIRTY HELPER (I'm not really sure what the side effects are) */
ppc32g_dirtyhelper_MFSPR_287(void)112 UInt ppc32g_dirtyhelper_MFSPR_287 ( void )
113 {
114 # if defined(__powerpc__) || defined(_AIX)
115 UInt spr;
116 __asm__ __volatile__("mfspr %0,287" : "=b"(spr));
117 return spr;
118 # else
119 return 0;
120 # endif
121 }
122
123
124 /* CALLED FROM GENERATED CODE */
125 /* DIRTY HELPER (reads guest state, writes guest mem) */
ppc32g_dirtyhelper_LVS(VexGuestPPC32State * gst,UInt vD_off,UInt sh,UInt shift_right)126 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
127 UInt vD_off, UInt sh, UInt shift_right )
128 {
129 static
130 UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
131 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
132 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
133 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
134 U128* pU128_src;
135 U128* pU128_dst;
136
137 vassert( vD_off <= sizeof(VexGuestPPC32State)-8 );
138 vassert( sh <= 15 );
139 vassert( shift_right <= 1 );
140 if (shift_right)
141 sh = 16-sh;
142 /* else shift left */
143
144 pU128_src = (U128*)&ref[sh];
145 pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
146
147 (*pU128_dst)[0] = (*pU128_src)[0];
148 (*pU128_dst)[1] = (*pU128_src)[1];
149 (*pU128_dst)[2] = (*pU128_src)[2];
150 (*pU128_dst)[3] = (*pU128_src)[3];
151 }
152
153 /* CALLED FROM GENERATED CODE */
154 /* DIRTY HELPER (reads guest state, writes guest mem) */
ppc64g_dirtyhelper_LVS(VexGuestPPC64State * gst,UInt vD_off,UInt sh,UInt shift_right)155 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst,
156 UInt vD_off, UInt sh, UInt shift_right )
157 {
158 UChar ref[32];
159 ULong i;
160 /* ref[] used to be a static const array, but this doesn't work on
161 ppc64 because VEX doesn't load the TOC pointer for the call here,
162 and so we wind up picking up some totally random other data.
163 (It's a wonder we don't segfault.) So, just to be clear, this
164 "fix" (vex r2073) is really a kludgearound for the fact that
165 VEX's 64-bit ppc code generation doesn't provide a valid TOC
166 pointer for helper function calls. Ick. (Bug 250038) */
167 for (i = 0; i < 32; i++) ref[i] = i;
168
169 U128* pU128_src;
170 U128* pU128_dst;
171
172 vassert( vD_off <= sizeof(VexGuestPPC64State)-8 );
173 vassert( sh <= 15 );
174 vassert( shift_right <= 1 );
175 if (shift_right)
176 sh = 16-sh;
177 /* else shift left */
178
179 pU128_src = (U128*)&ref[sh];
180 pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
181
182 (*pU128_dst)[0] = (*pU128_src)[0];
183 (*pU128_dst)[1] = (*pU128_src)[1];
184 (*pU128_dst)[2] = (*pU128_src)[2];
185 (*pU128_dst)[3] = (*pU128_src)[3];
186 }
187
188
189 /* Helper-function specialiser. */
190
guest_ppc32_spechelper(const HChar * function_name,IRExpr ** args,IRStmt ** precedingStmts,Int n_precedingStmts)191 IRExpr* guest_ppc32_spechelper ( const HChar* function_name,
192 IRExpr** args,
193 IRStmt** precedingStmts,
194 Int n_precedingStmts )
195 {
196 return NULL;
197 }
198
guest_ppc64_spechelper(const HChar * function_name,IRExpr ** args,IRStmt ** precedingStmts,Int n_precedingStmts)199 IRExpr* guest_ppc64_spechelper ( const HChar* function_name,
200 IRExpr** args,
201 IRStmt** precedingStmts,
202 Int n_precedingStmts )
203 {
204 return NULL;
205 }
206
207
208 /*----------------------------------------------*/
209 /*--- The exported fns .. ---*/
210 /*----------------------------------------------*/
211
212 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_get_CR(const VexGuestPPC32State * vex_state)213 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/const VexGuestPPC32State* vex_state )
214 {
215 # define FIELD(_n) \
216 ( ( (UInt) \
217 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \
218 | (vex_state->guest_CR##_n##_0 & 1) \
219 ) \
220 ) \
221 << (4 * (7-(_n))) \
222 )
223
224 return
225 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
226 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
227
228 # undef FIELD
229 }
230
231
232 /* VISIBLE TO LIBVEX CLIENT */
233 /* Note: %CR is 32 bits even for ppc64 */
LibVEX_GuestPPC64_get_CR(const VexGuestPPC64State * vex_state)234 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/const VexGuestPPC64State* vex_state )
235 {
236 # define FIELD(_n) \
237 ( ( (UInt) \
238 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \
239 | (vex_state->guest_CR##_n##_0 & 1) \
240 ) \
241 ) \
242 << (4 * (7-(_n))) \
243 )
244
245 return
246 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
247 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
248
249 # undef FIELD
250 }
251
252
253 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_put_CR(UInt cr_native,VexGuestPPC32State * vex_state)254 void LibVEX_GuestPPC32_put_CR ( UInt cr_native,
255 /*OUT*/VexGuestPPC32State* vex_state )
256 {
257 UInt t;
258
259 # define FIELD(_n) \
260 do { \
261 t = cr_native >> (4*(7-(_n))); \
262 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \
263 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
264 } while (0)
265
266 FIELD(0);
267 FIELD(1);
268 FIELD(2);
269 FIELD(3);
270 FIELD(4);
271 FIELD(5);
272 FIELD(6);
273 FIELD(7);
274
275 # undef FIELD
276 }
277
278
279 /* VISIBLE TO LIBVEX CLIENT */
280 /* Note: %CR is 32 bits even for ppc64 */
LibVEX_GuestPPC64_put_CR(UInt cr_native,VexGuestPPC64State * vex_state)281 void LibVEX_GuestPPC64_put_CR ( UInt cr_native,
282 /*OUT*/VexGuestPPC64State* vex_state )
283 {
284 UInt t;
285
286 # define FIELD(_n) \
287 do { \
288 t = cr_native >> (4*(7-(_n))); \
289 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \
290 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
291 } while (0)
292
293 FIELD(0);
294 FIELD(1);
295 FIELD(2);
296 FIELD(3);
297 FIELD(4);
298 FIELD(5);
299 FIELD(6);
300 FIELD(7);
301
302 # undef FIELD
303 }
304
305
306 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_get_XER(const VexGuestPPC32State * vex_state)307 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/const VexGuestPPC32State* vex_state )
308 {
309 UInt w = 0;
310 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
311 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
312 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
313 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
314 return w;
315 }
316
317
318 /* VISIBLE TO LIBVEX CLIENT */
319 /* Note: %XER is 32 bits even for ppc64 */
LibVEX_GuestPPC64_get_XER(const VexGuestPPC64State * vex_state)320 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/const VexGuestPPC64State* vex_state )
321 {
322 UInt w = 0;
323 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
324 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
325 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
326 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
327 return w;
328 }
329
330
331 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_put_XER(UInt xer_native,VexGuestPPC32State * vex_state)332 void LibVEX_GuestPPC32_put_XER ( UInt xer_native,
333 /*OUT*/VexGuestPPC32State* vex_state )
334 {
335 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
336 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
337 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
338 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
339 }
340
341 /* VISIBLE TO LIBVEX CLIENT */
342 /* Note: %XER is 32 bits even for ppc64 */
LibVEX_GuestPPC64_put_XER(UInt xer_native,VexGuestPPC64State * vex_state)343 void LibVEX_GuestPPC64_put_XER ( UInt xer_native,
344 /*OUT*/VexGuestPPC64State* vex_state )
345 {
346 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
347 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
348 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
349 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
350 }
351
352 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC32_initialise(VexGuestPPC32State * vex_state)353 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
354 {
355 Int i;
356 vex_state->host_EvC_FAILADDR = 0;
357 vex_state->host_EvC_COUNTER = 0;
358 vex_state->pad3 = 0;
359 vex_state->pad4 = 0;
360
361 vex_state->guest_GPR0 = 0;
362 vex_state->guest_GPR1 = 0;
363 vex_state->guest_GPR2 = 0;
364 vex_state->guest_GPR3 = 0;
365 vex_state->guest_GPR4 = 0;
366 vex_state->guest_GPR5 = 0;
367 vex_state->guest_GPR6 = 0;
368 vex_state->guest_GPR7 = 0;
369 vex_state->guest_GPR8 = 0;
370 vex_state->guest_GPR9 = 0;
371 vex_state->guest_GPR10 = 0;
372 vex_state->guest_GPR11 = 0;
373 vex_state->guest_GPR12 = 0;
374 vex_state->guest_GPR13 = 0;
375 vex_state->guest_GPR14 = 0;
376 vex_state->guest_GPR15 = 0;
377 vex_state->guest_GPR16 = 0;
378 vex_state->guest_GPR17 = 0;
379 vex_state->guest_GPR18 = 0;
380 vex_state->guest_GPR19 = 0;
381 vex_state->guest_GPR20 = 0;
382 vex_state->guest_GPR21 = 0;
383 vex_state->guest_GPR22 = 0;
384 vex_state->guest_GPR23 = 0;
385 vex_state->guest_GPR24 = 0;
386 vex_state->guest_GPR25 = 0;
387 vex_state->guest_GPR26 = 0;
388 vex_state->guest_GPR27 = 0;
389 vex_state->guest_GPR28 = 0;
390 vex_state->guest_GPR29 = 0;
391 vex_state->guest_GPR30 = 0;
392 vex_state->guest_GPR31 = 0;
393
394 /* Initialise the vector state. */
395 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
396
397 VECZERO(vex_state->guest_VSR0 );
398 VECZERO(vex_state->guest_VSR1 );
399 VECZERO(vex_state->guest_VSR2 );
400 VECZERO(vex_state->guest_VSR3 );
401 VECZERO(vex_state->guest_VSR4 );
402 VECZERO(vex_state->guest_VSR5 );
403 VECZERO(vex_state->guest_VSR6 );
404 VECZERO(vex_state->guest_VSR7 );
405 VECZERO(vex_state->guest_VSR8 );
406 VECZERO(vex_state->guest_VSR9 );
407 VECZERO(vex_state->guest_VSR10);
408 VECZERO(vex_state->guest_VSR11);
409 VECZERO(vex_state->guest_VSR12);
410 VECZERO(vex_state->guest_VSR13);
411 VECZERO(vex_state->guest_VSR14);
412 VECZERO(vex_state->guest_VSR15);
413 VECZERO(vex_state->guest_VSR16);
414 VECZERO(vex_state->guest_VSR17);
415 VECZERO(vex_state->guest_VSR18);
416 VECZERO(vex_state->guest_VSR19);
417 VECZERO(vex_state->guest_VSR20);
418 VECZERO(vex_state->guest_VSR21);
419 VECZERO(vex_state->guest_VSR22);
420 VECZERO(vex_state->guest_VSR23);
421 VECZERO(vex_state->guest_VSR24);
422 VECZERO(vex_state->guest_VSR25);
423 VECZERO(vex_state->guest_VSR26);
424 VECZERO(vex_state->guest_VSR27);
425 VECZERO(vex_state->guest_VSR28);
426 VECZERO(vex_state->guest_VSR29);
427 VECZERO(vex_state->guest_VSR30);
428 VECZERO(vex_state->guest_VSR31);
429 VECZERO(vex_state->guest_VSR32);
430 VECZERO(vex_state->guest_VSR33);
431 VECZERO(vex_state->guest_VSR34);
432 VECZERO(vex_state->guest_VSR35);
433 VECZERO(vex_state->guest_VSR36);
434 VECZERO(vex_state->guest_VSR37);
435 VECZERO(vex_state->guest_VSR38);
436 VECZERO(vex_state->guest_VSR39);
437 VECZERO(vex_state->guest_VSR40);
438 VECZERO(vex_state->guest_VSR41);
439 VECZERO(vex_state->guest_VSR42);
440 VECZERO(vex_state->guest_VSR43);
441 VECZERO(vex_state->guest_VSR44);
442 VECZERO(vex_state->guest_VSR45);
443 VECZERO(vex_state->guest_VSR46);
444 VECZERO(vex_state->guest_VSR47);
445 VECZERO(vex_state->guest_VSR48);
446 VECZERO(vex_state->guest_VSR49);
447 VECZERO(vex_state->guest_VSR50);
448 VECZERO(vex_state->guest_VSR51);
449 VECZERO(vex_state->guest_VSR52);
450 VECZERO(vex_state->guest_VSR53);
451 VECZERO(vex_state->guest_VSR54);
452 VECZERO(vex_state->guest_VSR55);
453 VECZERO(vex_state->guest_VSR56);
454 VECZERO(vex_state->guest_VSR57);
455 VECZERO(vex_state->guest_VSR58);
456 VECZERO(vex_state->guest_VSR59);
457 VECZERO(vex_state->guest_VSR60);
458 VECZERO(vex_state->guest_VSR61);
459 VECZERO(vex_state->guest_VSR62);
460 VECZERO(vex_state->guest_VSR63);
461
462 # undef VECZERO
463
464 vex_state->guest_CIA = 0;
465 vex_state->guest_LR = 0;
466 vex_state->guest_CTR = 0;
467
468 vex_state->guest_XER_SO = 0;
469 vex_state->guest_XER_OV = 0;
470 vex_state->guest_XER_CA = 0;
471 vex_state->guest_XER_BC = 0;
472
473 vex_state->guest_CR0_321 = 0;
474 vex_state->guest_CR0_0 = 0;
475 vex_state->guest_CR1_321 = 0;
476 vex_state->guest_CR1_0 = 0;
477 vex_state->guest_CR2_321 = 0;
478 vex_state->guest_CR2_0 = 0;
479 vex_state->guest_CR3_321 = 0;
480 vex_state->guest_CR3_0 = 0;
481 vex_state->guest_CR4_321 = 0;
482 vex_state->guest_CR4_0 = 0;
483 vex_state->guest_CR5_321 = 0;
484 vex_state->guest_CR5_0 = 0;
485 vex_state->guest_CR6_321 = 0;
486 vex_state->guest_CR6_0 = 0;
487 vex_state->guest_CR7_321 = 0;
488 vex_state->guest_CR7_0 = 0;
489
490 vex_state->guest_FPROUND = PPCrm_NEAREST;
491 vex_state->guest_DFPROUND = PPCrm_NEAREST;
492 vex_state->pad1 = 0;
493 vex_state->pad2 = 0;
494
495 vex_state->guest_VRSAVE = 0;
496
497 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0
498
499 vex_state->guest_EMNOTE = EmNote_NONE;
500
501 vex_state->guest_CMSTART = 0;
502 vex_state->guest_CMLEN = 0;
503
504 vex_state->guest_NRADDR = 0;
505 vex_state->guest_NRADDR_GPR2 = 0;
506
507 vex_state->guest_REDIR_SP = -1;
508 for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
509 vex_state->guest_REDIR_STACK[i] = 0;
510
511 vex_state->guest_IP_AT_SYSCALL = 0;
512 vex_state->guest_SPRG3_RO = 0;
513
514 vex_state->padding1 = 0;
515 vex_state->padding2 = 0;
516 }
517
518
519 /* VISIBLE TO LIBVEX CLIENT */
LibVEX_GuestPPC64_initialise(VexGuestPPC64State * vex_state)520 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
521 {
522 Int i;
523 vex_state->host_EvC_FAILADDR = 0;
524 vex_state->host_EvC_COUNTER = 0;
525 vex_state->pad0 = 0;
526 vex_state->guest_GPR0 = 0;
527 vex_state->guest_GPR1 = 0;
528 vex_state->guest_GPR2 = 0;
529 vex_state->guest_GPR3 = 0;
530 vex_state->guest_GPR4 = 0;
531 vex_state->guest_GPR5 = 0;
532 vex_state->guest_GPR6 = 0;
533 vex_state->guest_GPR7 = 0;
534 vex_state->guest_GPR8 = 0;
535 vex_state->guest_GPR9 = 0;
536 vex_state->guest_GPR10 = 0;
537 vex_state->guest_GPR11 = 0;
538 vex_state->guest_GPR12 = 0;
539 vex_state->guest_GPR13 = 0;
540 vex_state->guest_GPR14 = 0;
541 vex_state->guest_GPR15 = 0;
542 vex_state->guest_GPR16 = 0;
543 vex_state->guest_GPR17 = 0;
544 vex_state->guest_GPR18 = 0;
545 vex_state->guest_GPR19 = 0;
546 vex_state->guest_GPR20 = 0;
547 vex_state->guest_GPR21 = 0;
548 vex_state->guest_GPR22 = 0;
549 vex_state->guest_GPR23 = 0;
550 vex_state->guest_GPR24 = 0;
551 vex_state->guest_GPR25 = 0;
552 vex_state->guest_GPR26 = 0;
553 vex_state->guest_GPR27 = 0;
554 vex_state->guest_GPR28 = 0;
555 vex_state->guest_GPR29 = 0;
556 vex_state->guest_GPR30 = 0;
557 vex_state->guest_GPR31 = 0;
558
559 /* Initialise the vector state. */
560 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
561
562 VECZERO(vex_state->guest_VSR0 );
563 VECZERO(vex_state->guest_VSR1 );
564 VECZERO(vex_state->guest_VSR2 );
565 VECZERO(vex_state->guest_VSR3 );
566 VECZERO(vex_state->guest_VSR4 );
567 VECZERO(vex_state->guest_VSR5 );
568 VECZERO(vex_state->guest_VSR6 );
569 VECZERO(vex_state->guest_VSR7 );
570 VECZERO(vex_state->guest_VSR8 );
571 VECZERO(vex_state->guest_VSR9 );
572 VECZERO(vex_state->guest_VSR10);
573 VECZERO(vex_state->guest_VSR11);
574 VECZERO(vex_state->guest_VSR12);
575 VECZERO(vex_state->guest_VSR13);
576 VECZERO(vex_state->guest_VSR14);
577 VECZERO(vex_state->guest_VSR15);
578 VECZERO(vex_state->guest_VSR16);
579 VECZERO(vex_state->guest_VSR17);
580 VECZERO(vex_state->guest_VSR18);
581 VECZERO(vex_state->guest_VSR19);
582 VECZERO(vex_state->guest_VSR20);
583 VECZERO(vex_state->guest_VSR21);
584 VECZERO(vex_state->guest_VSR22);
585 VECZERO(vex_state->guest_VSR23);
586 VECZERO(vex_state->guest_VSR24);
587 VECZERO(vex_state->guest_VSR25);
588 VECZERO(vex_state->guest_VSR26);
589 VECZERO(vex_state->guest_VSR27);
590 VECZERO(vex_state->guest_VSR28);
591 VECZERO(vex_state->guest_VSR29);
592 VECZERO(vex_state->guest_VSR30);
593 VECZERO(vex_state->guest_VSR31);
594 VECZERO(vex_state->guest_VSR32);
595 VECZERO(vex_state->guest_VSR33);
596 VECZERO(vex_state->guest_VSR34);
597 VECZERO(vex_state->guest_VSR35);
598 VECZERO(vex_state->guest_VSR36);
599 VECZERO(vex_state->guest_VSR37);
600 VECZERO(vex_state->guest_VSR38);
601 VECZERO(vex_state->guest_VSR39);
602 VECZERO(vex_state->guest_VSR40);
603 VECZERO(vex_state->guest_VSR41);
604 VECZERO(vex_state->guest_VSR42);
605 VECZERO(vex_state->guest_VSR43);
606 VECZERO(vex_state->guest_VSR44);
607 VECZERO(vex_state->guest_VSR45);
608 VECZERO(vex_state->guest_VSR46);
609 VECZERO(vex_state->guest_VSR47);
610 VECZERO(vex_state->guest_VSR48);
611 VECZERO(vex_state->guest_VSR49);
612 VECZERO(vex_state->guest_VSR50);
613 VECZERO(vex_state->guest_VSR51);
614 VECZERO(vex_state->guest_VSR52);
615 VECZERO(vex_state->guest_VSR53);
616 VECZERO(vex_state->guest_VSR54);
617 VECZERO(vex_state->guest_VSR55);
618 VECZERO(vex_state->guest_VSR56);
619 VECZERO(vex_state->guest_VSR57);
620 VECZERO(vex_state->guest_VSR58);
621 VECZERO(vex_state->guest_VSR59);
622 VECZERO(vex_state->guest_VSR60);
623 VECZERO(vex_state->guest_VSR61);
624 VECZERO(vex_state->guest_VSR62);
625 VECZERO(vex_state->guest_VSR63);
626
627 # undef VECZERO
628
629 vex_state->guest_CIA = 0;
630 vex_state->guest_LR = 0;
631 vex_state->guest_CTR = 0;
632
633 vex_state->guest_XER_SO = 0;
634 vex_state->guest_XER_OV = 0;
635 vex_state->guest_XER_CA = 0;
636 vex_state->guest_XER_BC = 0;
637
638 vex_state->guest_CR0_321 = 0;
639 vex_state->guest_CR0_0 = 0;
640 vex_state->guest_CR1_321 = 0;
641 vex_state->guest_CR1_0 = 0;
642 vex_state->guest_CR2_321 = 0;
643 vex_state->guest_CR2_0 = 0;
644 vex_state->guest_CR3_321 = 0;
645 vex_state->guest_CR3_0 = 0;
646 vex_state->guest_CR4_321 = 0;
647 vex_state->guest_CR4_0 = 0;
648 vex_state->guest_CR5_321 = 0;
649 vex_state->guest_CR5_0 = 0;
650 vex_state->guest_CR6_321 = 0;
651 vex_state->guest_CR6_0 = 0;
652 vex_state->guest_CR7_321 = 0;
653 vex_state->guest_CR7_0 = 0;
654
655 vex_state->guest_FPROUND = PPCrm_NEAREST;
656 vex_state->guest_DFPROUND = PPCrm_NEAREST;
657 vex_state->pad1 = 0;
658 vex_state->pad2 = 0;
659
660 vex_state->guest_VRSAVE = 0;
661
662 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0
663
664 vex_state->guest_EMNOTE = EmNote_NONE;
665
666 vex_state->padding = 0;
667
668 vex_state->guest_CMSTART = 0;
669 vex_state->guest_CMLEN = 0;
670
671 vex_state->guest_NRADDR = 0;
672 vex_state->guest_NRADDR_GPR2 = 0;
673
674 vex_state->guest_REDIR_SP = -1;
675 for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
676 vex_state->guest_REDIR_STACK[i] = 0;
677
678 vex_state->guest_IP_AT_SYSCALL = 0;
679 vex_state->guest_SPRG3_RO = 0;
680 vex_state->guest_TFHAR = 0;
681 vex_state->guest_TFIAR = 0;
682 vex_state->guest_TEXASR = 0;
683 }
684
685
686 /*-----------------------------------------------------------*/
687 /*--- Describing the ppc guest state, for the benefit ---*/
688 /*--- of iropt and instrumenters. ---*/
689 /*-----------------------------------------------------------*/
690
691 /* Figure out if any part of the guest state contained in minoff
692 .. maxoff requires precise memory exceptions. If in doubt return
693 True (but this is generates significantly slower code).
694
695 By default we enforce precise exns for guest R1 (stack pointer),
696 CIA (current insn address) and LR (link register). These are the
697 minimum needed to extract correct stack backtraces from ppc
698 code. [[NB: not sure if keeping LR up to date is actually
699 necessary.]]
700
701 Only R1 is needed in mode VexRegUpdSpAtMemAccess.
702 */
guest_ppc32_state_requires_precise_mem_exns(Int minoff,Int maxoff)703 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
704 Int maxoff )
705 {
706 Int lr_min = offsetof(VexGuestPPC32State, guest_LR);
707 Int lr_max = lr_min + 4 - 1;
708 Int r1_min = offsetof(VexGuestPPC32State, guest_GPR1);
709 Int r1_max = r1_min + 4 - 1;
710 Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
711 Int cia_max = cia_min + 4 - 1;
712
713 if (maxoff < r1_min || minoff > r1_max) {
714 /* no overlap with R1 */
715 if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
716 return False; // We only need to check stack pointer.
717 } else {
718 return True;
719 }
720
721 if (maxoff < lr_min || minoff > lr_max) {
722 /* no overlap with LR */
723 } else {
724 return True;
725 }
726
727 if (maxoff < cia_min || minoff > cia_max) {
728 /* no overlap with CIA */
729 } else {
730 return True;
731 }
732
733 return False;
734 }
735
guest_ppc64_state_requires_precise_mem_exns(Int minoff,Int maxoff)736 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
737 Int maxoff )
738 {
739 /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
740 prudent to be conservative with it, even though thus far there
741 is no evidence to suggest that it actually needs to be kept up
742 to date wrt possible exceptions. */
743 Int lr_min = offsetof(VexGuestPPC64State, guest_LR);
744 Int lr_max = lr_min + 8 - 1;
745 Int r1_min = offsetof(VexGuestPPC64State, guest_GPR1);
746 Int r1_max = r1_min + 8 - 1;
747 Int r2_min = offsetof(VexGuestPPC64State, guest_GPR2);
748 Int r2_max = r2_min + 8 - 1;
749 Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
750 Int cia_max = cia_min + 8 - 1;
751
752 if (maxoff < r1_min || minoff > r1_max) {
753 /* no overlap with R1 */
754 if (vex_control.iropt_register_updates == VexRegUpdSpAtMemAccess)
755 return False; // We only need to check stack pointer.
756 } else {
757 return True;
758 }
759
760 if (maxoff < lr_min || minoff > lr_max) {
761 /* no overlap with LR */
762 } else {
763 return True;
764 }
765
766 if (maxoff < r2_min || minoff > r2_max) {
767 /* no overlap with R2 */
768 } else {
769 return True;
770 }
771
772 if (maxoff < cia_min || minoff > cia_max) {
773 /* no overlap with CIA */
774 } else {
775 return True;
776 }
777
778 return False;
779 }
780
781
782 #define ALWAYSDEFD32(field) \
783 { offsetof(VexGuestPPC32State, field), \
784 (sizeof ((VexGuestPPC32State*)0)->field) }
785
786 VexGuestLayout
787 ppc32Guest_layout
788 = {
789 /* Total size of the guest state, in bytes. */
790 .total_sizeB = sizeof(VexGuestPPC32State),
791
792 /* Describe the stack pointer. */
793 .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
794 .sizeof_SP = 4,
795
796 /* Describe the frame pointer. */
797 .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
798 .sizeof_FP = 4,
799
800 /* Describe the instruction pointer. */
801 .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
802 .sizeof_IP = 4,
803
804 /* Describe any sections to be regarded by Memcheck as
805 'always-defined'. */
806 .n_alwaysDefd = 11,
807
808 .alwaysDefd
809 = { /* 0 */ ALWAYSDEFD32(guest_CIA),
810 /* 1 */ ALWAYSDEFD32(guest_EMNOTE),
811 /* 2 */ ALWAYSDEFD32(guest_CMSTART),
812 /* 3 */ ALWAYSDEFD32(guest_CMLEN),
813 /* 4 */ ALWAYSDEFD32(guest_VSCR),
814 /* 5 */ ALWAYSDEFD32(guest_FPROUND),
815 /* 6 */ ALWAYSDEFD32(guest_NRADDR),
816 /* 7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
817 /* 8 */ ALWAYSDEFD32(guest_REDIR_SP),
818 /* 9 */ ALWAYSDEFD32(guest_REDIR_STACK),
819 /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
820 }
821 };
822
823 #define ALWAYSDEFD64(field) \
824 { offsetof(VexGuestPPC64State, field), \
825 (sizeof ((VexGuestPPC64State*)0)->field) }
826
827 VexGuestLayout
828 ppc64Guest_layout
829 = {
830 /* Total size of the guest state, in bytes. */
831 .total_sizeB = sizeof(VexGuestPPC64State),
832
833 /* Describe the stack pointer. */
834 .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
835 .sizeof_SP = 8,
836
837 /* Describe the frame pointer. */
838 .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
839 .sizeof_FP = 8,
840
841 /* Describe the instruction pointer. */
842 .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
843 .sizeof_IP = 8,
844
845 /* Describe any sections to be regarded by Memcheck as
846 'always-defined'. */
847 .n_alwaysDefd = 11,
848
849 .alwaysDefd
850 = { /* 0 */ ALWAYSDEFD64(guest_CIA),
851 /* 1 */ ALWAYSDEFD64(guest_EMNOTE),
852 /* 2 */ ALWAYSDEFD64(guest_CMSTART),
853 /* 3 */ ALWAYSDEFD64(guest_CMLEN),
854 /* 4 */ ALWAYSDEFD64(guest_VSCR),
855 /* 5 */ ALWAYSDEFD64(guest_FPROUND),
856 /* 6 */ ALWAYSDEFD64(guest_NRADDR),
857 /* 7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
858 /* 8 */ ALWAYSDEFD64(guest_REDIR_SP),
859 /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK),
860 /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
861 }
862 };
863
864 /*---------------------------------------------------------------*/
865 /*--- end guest_ppc_helpers.c ---*/
866 /*---------------------------------------------------------------*/
867