2 /*---------------------------------------------------------------*/
3 /*--- begin guest_ppc_helpers.c ---*/
4 /*---------------------------------------------------------------*/
7 This file is part of Valgrind, a dynamic binary instrumentation
10 Copyright (C) 2004-2010 OpenWorks LLP
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.
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.
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
28 The GNU General Public License is contained in the file COPYING.
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.
36 #include "libvex_basictypes.h"
37 #include "libvex_emwarn.h"
38 #include "libvex_guest_ppc32.h"
39 #include "libvex_guest_ppc64.h"
40 #include "libvex_ir.h"
43 #include "main_util.h"
44 #include "guest_generic_bb_to_IR.h"
45 #include "guest_ppc_defs.h"
48 /* This file contains helper functions for ppc32 and ppc64 guest code.
49 Calls to these functions are generated by the back end. These
50 calls are of course in the host machine code and this file will be
51 compiled to host machine code, so that all makes sense.
53 Only change the signatures of these helper functions very
54 carefully. If you change the signature here, you'll have to change
55 the parameters passed to it in the IR calls constructed by
60 /*---------------------------------------------------------------*/
61 /*--- Misc integer helpers. ---*/
62 /*---------------------------------------------------------------*/
64 /* CALLED FROM GENERATED CODE */
65 /* DIRTY HELPER (non-referentially-transparent) */
66 /* Horrible hack. On non-ppc platforms, return 1. */
67 /* Reads a complete, consistent 64-bit TB value. */
68 ULong ppcg_dirtyhelper_MFTB ( void )
70 # if defined(__powerpc__) || defined(_AIX)
74 __asm__ __volatile__ ("\n"
78 : "=r" (hi1), "=r" (lo), "=r" (hi2)
80 if (hi1 == hi2) break;
82 res = ((ULong)hi1) << 32;
91 /* CALLED FROM GENERATED CODE */
92 /* DIRTY HELPER (non-referentially transparent) */
93 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 )
95 # if defined(__powerpc__) || defined(_AIX)
98 __asm__ __volatile__("mfspr %0,269" : "=b"(spr));
100 __asm__ __volatile__("mfspr %0,268" : "=b"(spr));
109 /* CALLED FROM GENERATED CODE */
110 /* DIRTY HELPER (I'm not really sure what the side effects are) */
111 UInt ppc32g_dirtyhelper_MFSPR_287 ( void )
113 # if defined(__powerpc__) || defined(_AIX)
115 __asm__ __volatile__("mfspr %0,287" : "=b"(spr));
123 /* CALLED FROM GENERATED CODE */
124 /* DIRTY HELPER (reads guest state, writes guest mem) */
125 void ppc32g_dirtyhelper_LVS ( VexGuestPPC32State* gst,
126 UInt vD_off, UInt sh, UInt shift_right )
129 UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
130 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
131 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
132 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
136 vassert( vD_off <= sizeof(VexGuestPPC32State)-8 );
138 vassert( shift_right <= 1 );
141 /* else shift left */
143 pU128_src = (U128*)&ref[sh];
144 pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
146 (*pU128_dst)[0] = (*pU128_src)[0];
147 (*pU128_dst)[1] = (*pU128_src)[1];
148 (*pU128_dst)[2] = (*pU128_src)[2];
149 (*pU128_dst)[3] = (*pU128_src)[3];
152 /* CALLED FROM GENERATED CODE */
153 /* DIRTY HELPER (reads guest state, writes guest mem) */
154 void ppc64g_dirtyhelper_LVS ( VexGuestPPC64State* gst,
155 UInt vD_off, UInt sh, UInt shift_right )
158 UChar ref[32] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
159 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
160 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
161 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F };
165 vassert( vD_off <= sizeof(VexGuestPPC64State)-8 );
167 vassert( shift_right <= 1 );
170 /* else shift left */
172 pU128_src = (U128*)&ref[sh];
173 pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
175 (*pU128_dst)[0] = (*pU128_src)[0];
176 (*pU128_dst)[1] = (*pU128_src)[1];
177 (*pU128_dst)[2] = (*pU128_src)[2];
178 (*pU128_dst)[3] = (*pU128_src)[3];
182 /* Helper-function specialiser. */
184 IRExpr* guest_ppc32_spechelper ( HChar* function_name,
190 IRExpr* guest_ppc64_spechelper ( HChar* function_name,
197 /*----------------------------------------------*/
198 /*--- The exported fns .. ---*/
199 /*----------------------------------------------*/
201 /* VISIBLE TO LIBVEX CLIENT */
202 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/VexGuestPPC32State* vex_state )
206 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \
207 | (vex_state->guest_CR##_n##_0 & 1) \
214 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
215 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
221 /* VISIBLE TO LIBVEX CLIENT */
222 /* Note: %CR is 32 bits even for ppc64 */
223 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/VexGuestPPC64State* vex_state )
227 ( (vex_state->guest_CR##_n##_321 & (7<<1)) \
228 | (vex_state->guest_CR##_n##_0 & 1) \
235 FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
236 | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
242 /* VISIBLE TO LIBVEX CLIENT */
243 void LibVEX_GuestPPC32_put_CR ( UInt cr_native,
244 /*OUT*/VexGuestPPC32State* vex_state )
250 t = cr_native >> (4*(7-(_n))); \
251 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \
252 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
268 /* VISIBLE TO LIBVEX CLIENT */
269 /* Note: %CR is 32 bits even for ppc64 */
270 void LibVEX_GuestPPC64_put_CR ( UInt cr_native,
271 /*OUT*/VexGuestPPC64State* vex_state )
277 t = cr_native >> (4*(7-(_n))); \
278 vex_state->guest_CR##_n##_0 = toUChar(t & 1); \
279 vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
295 /* VISIBLE TO LIBVEX CLIENT */
296 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/VexGuestPPC32State* vex_state )
299 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
300 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
301 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
302 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
307 /* VISIBLE TO LIBVEX CLIENT */
308 /* Note: %XER is 32 bits even for ppc64 */
309 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/VexGuestPPC64State* vex_state )
312 w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
313 w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
314 w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
315 w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
320 /* VISIBLE TO LIBVEX CLIENT */
321 void LibVEX_GuestPPC32_put_XER ( UInt xer_native,
322 /*OUT*/VexGuestPPC32State* vex_state )
324 vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
325 vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
326 vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
327 vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
330 /* VISIBLE TO LIBVEX CLIENT */
331 /* Note: %XER is 32 bits even for ppc64 */
332 void LibVEX_GuestPPC64_put_XER ( UInt xer_native,
333 /*OUT*/VexGuestPPC64State* vex_state )
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);
341 /* VISIBLE TO LIBVEX CLIENT */
342 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
345 vex_state->guest_GPR0 = 0;
346 vex_state->guest_GPR1 = 0;
347 vex_state->guest_GPR2 = 0;
348 vex_state->guest_GPR3 = 0;
349 vex_state->guest_GPR4 = 0;
350 vex_state->guest_GPR5 = 0;
351 vex_state->guest_GPR6 = 0;
352 vex_state->guest_GPR7 = 0;
353 vex_state->guest_GPR8 = 0;
354 vex_state->guest_GPR9 = 0;
355 vex_state->guest_GPR10 = 0;
356 vex_state->guest_GPR11 = 0;
357 vex_state->guest_GPR12 = 0;
358 vex_state->guest_GPR13 = 0;
359 vex_state->guest_GPR14 = 0;
360 vex_state->guest_GPR15 = 0;
361 vex_state->guest_GPR16 = 0;
362 vex_state->guest_GPR17 = 0;
363 vex_state->guest_GPR18 = 0;
364 vex_state->guest_GPR19 = 0;
365 vex_state->guest_GPR20 = 0;
366 vex_state->guest_GPR21 = 0;
367 vex_state->guest_GPR22 = 0;
368 vex_state->guest_GPR23 = 0;
369 vex_state->guest_GPR24 = 0;
370 vex_state->guest_GPR25 = 0;
371 vex_state->guest_GPR26 = 0;
372 vex_state->guest_GPR27 = 0;
373 vex_state->guest_GPR28 = 0;
374 vex_state->guest_GPR29 = 0;
375 vex_state->guest_GPR30 = 0;
376 vex_state->guest_GPR31 = 0;
378 vex_state->guest_FPR0 = 0;
379 vex_state->guest_FPR1 = 0;
380 vex_state->guest_FPR2 = 0;
381 vex_state->guest_FPR3 = 0;
382 vex_state->guest_FPR4 = 0;
383 vex_state->guest_FPR5 = 0;
384 vex_state->guest_FPR6 = 0;
385 vex_state->guest_FPR7 = 0;
386 vex_state->guest_FPR8 = 0;
387 vex_state->guest_FPR9 = 0;
388 vex_state->guest_FPR10 = 0;
389 vex_state->guest_FPR11 = 0;
390 vex_state->guest_FPR12 = 0;
391 vex_state->guest_FPR13 = 0;
392 vex_state->guest_FPR14 = 0;
393 vex_state->guest_FPR15 = 0;
394 vex_state->guest_FPR16 = 0;
395 vex_state->guest_FPR17 = 0;
396 vex_state->guest_FPR18 = 0;
397 vex_state->guest_FPR19 = 0;
398 vex_state->guest_FPR20 = 0;
399 vex_state->guest_FPR21 = 0;
400 vex_state->guest_FPR22 = 0;
401 vex_state->guest_FPR23 = 0;
402 vex_state->guest_FPR24 = 0;
403 vex_state->guest_FPR25 = 0;
404 vex_state->guest_FPR26 = 0;
405 vex_state->guest_FPR27 = 0;
406 vex_state->guest_FPR28 = 0;
407 vex_state->guest_FPR29 = 0;
408 vex_state->guest_FPR30 = 0;
409 vex_state->guest_FPR31 = 0;
411 /* Initialise the vector state. */
412 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
414 VECZERO(vex_state->guest_VR0 );
415 VECZERO(vex_state->guest_VR1 );
416 VECZERO(vex_state->guest_VR2 );
417 VECZERO(vex_state->guest_VR3 );
418 VECZERO(vex_state->guest_VR4 );
419 VECZERO(vex_state->guest_VR5 );
420 VECZERO(vex_state->guest_VR6 );
421 VECZERO(vex_state->guest_VR7 );
422 VECZERO(vex_state->guest_VR8 );
423 VECZERO(vex_state->guest_VR9 );
424 VECZERO(vex_state->guest_VR10);
425 VECZERO(vex_state->guest_VR11);
426 VECZERO(vex_state->guest_VR12);
427 VECZERO(vex_state->guest_VR13);
428 VECZERO(vex_state->guest_VR14);
429 VECZERO(vex_state->guest_VR15);
430 VECZERO(vex_state->guest_VR16);
431 VECZERO(vex_state->guest_VR17);
432 VECZERO(vex_state->guest_VR18);
433 VECZERO(vex_state->guest_VR19);
434 VECZERO(vex_state->guest_VR20);
435 VECZERO(vex_state->guest_VR21);
436 VECZERO(vex_state->guest_VR22);
437 VECZERO(vex_state->guest_VR23);
438 VECZERO(vex_state->guest_VR24);
439 VECZERO(vex_state->guest_VR25);
440 VECZERO(vex_state->guest_VR26);
441 VECZERO(vex_state->guest_VR27);
442 VECZERO(vex_state->guest_VR28);
443 VECZERO(vex_state->guest_VR29);
444 VECZERO(vex_state->guest_VR30);
445 VECZERO(vex_state->guest_VR31);
449 vex_state->guest_CIA = 0;
450 vex_state->guest_LR = 0;
451 vex_state->guest_CTR = 0;
453 vex_state->guest_XER_SO = 0;
454 vex_state->guest_XER_OV = 0;
455 vex_state->guest_XER_CA = 0;
456 vex_state->guest_XER_BC = 0;
458 vex_state->guest_CR0_321 = 0;
459 vex_state->guest_CR0_0 = 0;
460 vex_state->guest_CR1_321 = 0;
461 vex_state->guest_CR1_0 = 0;
462 vex_state->guest_CR2_321 = 0;
463 vex_state->guest_CR2_0 = 0;
464 vex_state->guest_CR3_321 = 0;
465 vex_state->guest_CR3_0 = 0;
466 vex_state->guest_CR4_321 = 0;
467 vex_state->guest_CR4_0 = 0;
468 vex_state->guest_CR5_321 = 0;
469 vex_state->guest_CR5_0 = 0;
470 vex_state->guest_CR6_321 = 0;
471 vex_state->guest_CR6_0 = 0;
472 vex_state->guest_CR7_321 = 0;
473 vex_state->guest_CR7_0 = 0;
475 vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
477 vex_state->guest_VRSAVE = 0;
479 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0
481 vex_state->guest_EMWARN = EmWarn_NONE;
483 vex_state->guest_TISTART = 0;
484 vex_state->guest_TILEN = 0;
486 vex_state->guest_NRADDR = 0;
487 vex_state->guest_NRADDR_GPR2 = 0;
489 vex_state->guest_REDIR_SP = -1;
490 for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
491 vex_state->guest_REDIR_STACK[i] = 0;
493 vex_state->guest_IP_AT_SYSCALL = 0;
494 vex_state->guest_SPRG3_RO = 0;
498 /* VISIBLE TO LIBVEX CLIENT */
499 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
502 vex_state->guest_GPR0 = 0;
503 vex_state->guest_GPR1 = 0;
504 vex_state->guest_GPR2 = 0;
505 vex_state->guest_GPR3 = 0;
506 vex_state->guest_GPR4 = 0;
507 vex_state->guest_GPR5 = 0;
508 vex_state->guest_GPR6 = 0;
509 vex_state->guest_GPR7 = 0;
510 vex_state->guest_GPR8 = 0;
511 vex_state->guest_GPR9 = 0;
512 vex_state->guest_GPR10 = 0;
513 vex_state->guest_GPR11 = 0;
514 vex_state->guest_GPR12 = 0;
515 vex_state->guest_GPR13 = 0;
516 vex_state->guest_GPR14 = 0;
517 vex_state->guest_GPR15 = 0;
518 vex_state->guest_GPR16 = 0;
519 vex_state->guest_GPR17 = 0;
520 vex_state->guest_GPR18 = 0;
521 vex_state->guest_GPR19 = 0;
522 vex_state->guest_GPR20 = 0;
523 vex_state->guest_GPR21 = 0;
524 vex_state->guest_GPR22 = 0;
525 vex_state->guest_GPR23 = 0;
526 vex_state->guest_GPR24 = 0;
527 vex_state->guest_GPR25 = 0;
528 vex_state->guest_GPR26 = 0;
529 vex_state->guest_GPR27 = 0;
530 vex_state->guest_GPR28 = 0;
531 vex_state->guest_GPR29 = 0;
532 vex_state->guest_GPR30 = 0;
533 vex_state->guest_GPR31 = 0;
535 vex_state->guest_FPR0 = 0;
536 vex_state->guest_FPR1 = 0;
537 vex_state->guest_FPR2 = 0;
538 vex_state->guest_FPR3 = 0;
539 vex_state->guest_FPR4 = 0;
540 vex_state->guest_FPR5 = 0;
541 vex_state->guest_FPR6 = 0;
542 vex_state->guest_FPR7 = 0;
543 vex_state->guest_FPR8 = 0;
544 vex_state->guest_FPR9 = 0;
545 vex_state->guest_FPR10 = 0;
546 vex_state->guest_FPR11 = 0;
547 vex_state->guest_FPR12 = 0;
548 vex_state->guest_FPR13 = 0;
549 vex_state->guest_FPR14 = 0;
550 vex_state->guest_FPR15 = 0;
551 vex_state->guest_FPR16 = 0;
552 vex_state->guest_FPR17 = 0;
553 vex_state->guest_FPR18 = 0;
554 vex_state->guest_FPR19 = 0;
555 vex_state->guest_FPR20 = 0;
556 vex_state->guest_FPR21 = 0;
557 vex_state->guest_FPR22 = 0;
558 vex_state->guest_FPR23 = 0;
559 vex_state->guest_FPR24 = 0;
560 vex_state->guest_FPR25 = 0;
561 vex_state->guest_FPR26 = 0;
562 vex_state->guest_FPR27 = 0;
563 vex_state->guest_FPR28 = 0;
564 vex_state->guest_FPR29 = 0;
565 vex_state->guest_FPR30 = 0;
566 vex_state->guest_FPR31 = 0;
568 /* Initialise the vector state. */
569 # define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
571 VECZERO(vex_state->guest_VR0 );
572 VECZERO(vex_state->guest_VR1 );
573 VECZERO(vex_state->guest_VR2 );
574 VECZERO(vex_state->guest_VR3 );
575 VECZERO(vex_state->guest_VR4 );
576 VECZERO(vex_state->guest_VR5 );
577 VECZERO(vex_state->guest_VR6 );
578 VECZERO(vex_state->guest_VR7 );
579 VECZERO(vex_state->guest_VR8 );
580 VECZERO(vex_state->guest_VR9 );
581 VECZERO(vex_state->guest_VR10);
582 VECZERO(vex_state->guest_VR11);
583 VECZERO(vex_state->guest_VR12);
584 VECZERO(vex_state->guest_VR13);
585 VECZERO(vex_state->guest_VR14);
586 VECZERO(vex_state->guest_VR15);
587 VECZERO(vex_state->guest_VR16);
588 VECZERO(vex_state->guest_VR17);
589 VECZERO(vex_state->guest_VR18);
590 VECZERO(vex_state->guest_VR19);
591 VECZERO(vex_state->guest_VR20);
592 VECZERO(vex_state->guest_VR21);
593 VECZERO(vex_state->guest_VR22);
594 VECZERO(vex_state->guest_VR23);
595 VECZERO(vex_state->guest_VR24);
596 VECZERO(vex_state->guest_VR25);
597 VECZERO(vex_state->guest_VR26);
598 VECZERO(vex_state->guest_VR27);
599 VECZERO(vex_state->guest_VR28);
600 VECZERO(vex_state->guest_VR29);
601 VECZERO(vex_state->guest_VR30);
602 VECZERO(vex_state->guest_VR31);
606 vex_state->guest_CIA = 0;
607 vex_state->guest_LR = 0;
608 vex_state->guest_CTR = 0;
610 vex_state->guest_XER_SO = 0;
611 vex_state->guest_XER_OV = 0;
612 vex_state->guest_XER_CA = 0;
613 vex_state->guest_XER_BC = 0;
615 vex_state->guest_CR0_321 = 0;
616 vex_state->guest_CR0_0 = 0;
617 vex_state->guest_CR1_321 = 0;
618 vex_state->guest_CR1_0 = 0;
619 vex_state->guest_CR2_321 = 0;
620 vex_state->guest_CR2_0 = 0;
621 vex_state->guest_CR3_321 = 0;
622 vex_state->guest_CR3_0 = 0;
623 vex_state->guest_CR4_321 = 0;
624 vex_state->guest_CR4_0 = 0;
625 vex_state->guest_CR5_321 = 0;
626 vex_state->guest_CR5_0 = 0;
627 vex_state->guest_CR6_321 = 0;
628 vex_state->guest_CR6_0 = 0;
629 vex_state->guest_CR7_321 = 0;
630 vex_state->guest_CR7_0 = 0;
632 vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
634 vex_state->guest_VRSAVE = 0;
636 vex_state->guest_VSCR = 0x0; // Non-Java mode = 0
638 vex_state->guest_EMWARN = EmWarn_NONE;
640 vex_state->padding = 0;
642 vex_state->guest_TISTART = 0;
643 vex_state->guest_TILEN = 0;
645 vex_state->guest_NRADDR = 0;
646 vex_state->guest_NRADDR_GPR2 = 0;
648 vex_state->guest_REDIR_SP = -1;
649 for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
650 vex_state->guest_REDIR_STACK[i] = 0;
652 vex_state->guest_IP_AT_SYSCALL = 0;
653 vex_state->guest_SPRG3_RO = 0;
655 vex_state->padding2 = 0;
659 /*-----------------------------------------------------------*/
660 /*--- Describing the ppc guest state, for the benefit ---*/
661 /*--- of iropt and instrumenters. ---*/
662 /*-----------------------------------------------------------*/
664 /* Figure out if any part of the guest state contained in minoff
665 .. maxoff requires precise memory exceptions. If in doubt return
666 True (but this is generates significantly slower code).
668 By default we enforce precise exns for guest R1 (stack pointer),
669 CIA (current insn address) and LR (link register). These are the
670 minimum needed to extract correct stack backtraces from ppc
671 code. [[NB: not sure if keeping LR up to date is actually
674 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
677 Int lr_min = offsetof(VexGuestPPC32State, guest_LR);
678 Int lr_max = lr_min + 4 - 1;
679 Int r1_min = offsetof(VexGuestPPC32State, guest_GPR1);
680 Int r1_max = r1_min + 4 - 1;
681 Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
682 Int cia_max = cia_min + 4 - 1;
684 if (maxoff < lr_min || minoff > lr_max) {
685 /* no overlap with LR */
690 if (maxoff < r1_min || minoff > r1_max) {
691 /* no overlap with R1 */
696 if (maxoff < cia_min || minoff > cia_max) {
697 /* no overlap with CIA */
705 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
708 /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
709 prudent to be conservative with it, even though thus far there
710 is no evidence to suggest that it actually needs to be kept up
711 to date wrt possible exceptions. */
712 Int lr_min = offsetof(VexGuestPPC64State, guest_LR);
713 Int lr_max = lr_min + 8 - 1;
714 Int r1_min = offsetof(VexGuestPPC64State, guest_GPR1);
715 Int r1_max = r1_min + 8 - 1;
716 Int r2_min = offsetof(VexGuestPPC64State, guest_GPR2);
717 Int r2_max = r2_min + 8 - 1;
718 Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
719 Int cia_max = cia_min + 8 - 1;
721 if (maxoff < lr_min || minoff > lr_max) {
722 /* no overlap with LR */
727 if (maxoff < r1_min || minoff > r1_max) {
728 /* no overlap with R1 */
733 if (maxoff < r2_min || minoff > r2_max) {
734 /* no overlap with R2 */
739 if (maxoff < cia_min || minoff > cia_max) {
740 /* no overlap with CIA */
749 #define ALWAYSDEFD32(field) \
750 { offsetof(VexGuestPPC32State, field), \
751 (sizeof ((VexGuestPPC32State*)0)->field) }
756 /* Total size of the guest state, in bytes. */
757 .total_sizeB = sizeof(VexGuestPPC32State),
759 /* Describe the stack pointer. */
760 .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
763 /* Describe the frame pointer. */
764 .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
767 /* Describe the instruction pointer. */
768 .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
771 /* Describe any sections to be regarded by Memcheck as
776 = { /* 0 */ ALWAYSDEFD32(guest_CIA),
777 /* 1 */ ALWAYSDEFD32(guest_EMWARN),
778 /* 2 */ ALWAYSDEFD32(guest_TISTART),
779 /* 3 */ ALWAYSDEFD32(guest_TILEN),
780 /* 4 */ ALWAYSDEFD32(guest_VSCR),
781 /* 5 */ ALWAYSDEFD32(guest_FPROUND),
782 /* 6 */ ALWAYSDEFD32(guest_NRADDR),
783 /* 7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
784 /* 8 */ ALWAYSDEFD32(guest_REDIR_SP),
785 /* 9 */ ALWAYSDEFD32(guest_REDIR_STACK),
786 /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
790 #define ALWAYSDEFD64(field) \
791 { offsetof(VexGuestPPC64State, field), \
792 (sizeof ((VexGuestPPC64State*)0)->field) }
797 /* Total size of the guest state, in bytes. */
798 .total_sizeB = sizeof(VexGuestPPC64State),
800 /* Describe the stack pointer. */
801 .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
804 /* Describe the frame pointer. */
805 .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
808 /* Describe the instruction pointer. */
809 .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
812 /* Describe any sections to be regarded by Memcheck as
817 = { /* 0 */ ALWAYSDEFD64(guest_CIA),
818 /* 1 */ ALWAYSDEFD64(guest_EMWARN),
819 /* 2 */ ALWAYSDEFD64(guest_TISTART),
820 /* 3 */ ALWAYSDEFD64(guest_TILEN),
821 /* 4 */ ALWAYSDEFD64(guest_VSCR),
822 /* 5 */ ALWAYSDEFD64(guest_FPROUND),
823 /* 6 */ ALWAYSDEFD64(guest_NRADDR),
824 /* 7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
825 /* 8 */ ALWAYSDEFD64(guest_REDIR_SP),
826 /* 9 */ ALWAYSDEFD64(guest_REDIR_STACK),
827 /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
831 /*---------------------------------------------------------------*/
832 /*--- end guest_ppc_helpers.c ---*/
833 /*---------------------------------------------------------------*/