Home | History | Annotate | Download | only in priv
      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-2010 OpenWorks LLP
     11       info (at) 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_emwarn.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 "guest_generic_bb_to_IR.h"
     45 #include "guest_ppc_defs.h"
     46 
     47 
     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.
     52 
     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
     56    guest-ppc/toIR.c.
     57 */
     58 
     59 
     60 /*---------------------------------------------------------------*/
     61 /*--- Misc integer helpers.                                   ---*/
     62 /*---------------------------------------------------------------*/
     63 
     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 )
     69 {
     70 #  if defined(__powerpc__) || defined(_AIX)
     71    ULong res;
     72    UInt  lo, hi1, hi2;
     73    while (1) {
     74       __asm__ __volatile__ ("\n"
     75          "\tmftbu %0\n"
     76          "\tmftb %1\n"
     77          "\tmftbu %2\n"
     78          : "=r" (hi1), "=r" (lo), "=r" (hi2)
     79       );
     80       if (hi1 == hi2) break;
     81    }
     82    res = ((ULong)hi1) << 32;
     83    res |= (ULong)lo;
     84    return res;
     85 #  else
     86    return 1ULL;
     87 #  endif
     88 }
     89 
     90 
     91 /* CALLED FROM GENERATED CODE */
     92 /* DIRTY HELPER (non-referentially transparent) */
     93 UInt ppc32g_dirtyhelper_MFSPR_268_269 ( UInt r269 )
     94 {
     95 #  if defined(__powerpc__) || defined(_AIX)
     96    UInt spr;
     97    if (r269) {
     98       __asm__ __volatile__("mfspr %0,269" : "=b"(spr));
     99    } else {
    100       __asm__ __volatile__("mfspr %0,268" : "=b"(spr));
    101    }
    102    return spr;
    103 #  else
    104    return 0;
    105 #  endif
    106 }
    107 
    108 
    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 )
    112 {
    113 #  if defined(__powerpc__) || defined(_AIX)
    114    UInt spr;
    115    __asm__ __volatile__("mfspr %0,287" : "=b"(spr));
    116    return spr;
    117 #  else
    118    return 0;
    119 #  endif
    120 }
    121 
    122 
    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 )
    127 {
    128   static
    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 };
    133   U128* pU128_src;
    134   U128* pU128_dst;
    135 
    136   vassert( vD_off       <= sizeof(VexGuestPPC32State)-8 );
    137   vassert( sh           <= 15 );
    138   vassert( shift_right  <=  1 );
    139   if (shift_right)
    140      sh = 16-sh;
    141   /* else shift left  */
    142 
    143   pU128_src = (U128*)&ref[sh];
    144   pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
    145 
    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];
    150 }
    151 
    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 )
    156 {
    157   UChar ref[32];
    158   ULong i;
    159   /* ref[] used to be a static const array, but this doesn't work on
    160      ppc64 because VEX doesn't load the TOC pointer for the call here,
    161      and so we wind up picking up some totally random other data.
    162      (It's a wonder we don't segfault.)  So, just to be clear, this
    163      "fix" (vex r2073) is really a kludgearound for the fact that
    164      VEX's 64-bit ppc code generation doesn't provide a valid TOC
    165      pointer for helper function calls.  Ick.  (Bug 250038) */
    166   for (i = 0; i < 32; i++) ref[i] = i;
    167 
    168   U128* pU128_src;
    169   U128* pU128_dst;
    170 
    171   vassert( vD_off       <= sizeof(VexGuestPPC64State)-8 );
    172   vassert( sh           <= 15 );
    173   vassert( shift_right  <=  1 );
    174   if (shift_right)
    175      sh = 16-sh;
    176   /* else shift left  */
    177 
    178   pU128_src = (U128*)&ref[sh];
    179   pU128_dst = (U128*)( ((UChar*)gst) + vD_off );
    180 
    181   (*pU128_dst)[0] = (*pU128_src)[0];
    182   (*pU128_dst)[1] = (*pU128_src)[1];
    183   (*pU128_dst)[2] = (*pU128_src)[2];
    184   (*pU128_dst)[3] = (*pU128_src)[3];
    185 }
    186 
    187 
    188 /* Helper-function specialiser. */
    189 
    190 IRExpr* guest_ppc32_spechelper ( HChar* function_name,
    191                                  IRExpr** args,
    192                                  IRStmt** precedingStmts,
    193                                  Int      n_precedingStmts )
    194 {
    195    return NULL;
    196 }
    197 
    198 IRExpr* guest_ppc64_spechelper ( HChar* function_name,
    199                                  IRExpr** args,
    200                                  IRStmt** precedingStmts,
    201                                  Int      n_precedingStmts )
    202 {
    203    return NULL;
    204 }
    205 
    206 
    207 /*----------------------------------------------*/
    208 /*--- The exported fns ..                    ---*/
    209 /*----------------------------------------------*/
    210 
    211 /* VISIBLE TO LIBVEX CLIENT */
    212 UInt LibVEX_GuestPPC32_get_CR ( /*IN*/VexGuestPPC32State* vex_state )
    213 {
    214 #  define FIELD(_n)                                    \
    215       ( ( (UInt)                                       \
    216            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
    217              | (vex_state->guest_CR##_n##_0 & 1)       \
    218            )                                           \
    219         )                                              \
    220         << (4 * (7-(_n)))                              \
    221       )
    222 
    223    return
    224       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
    225       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
    226 
    227 #  undef FIELD
    228 }
    229 
    230 
    231 /* VISIBLE TO LIBVEX CLIENT */
    232 /* Note: %CR is 32 bits even for ppc64 */
    233 UInt LibVEX_GuestPPC64_get_CR ( /*IN*/VexGuestPPC64State* vex_state )
    234 {
    235 #  define FIELD(_n)                                    \
    236       ( ( (UInt)                                       \
    237            ( (vex_state->guest_CR##_n##_321 & (7<<1))  \
    238              | (vex_state->guest_CR##_n##_0 & 1)       \
    239            )                                           \
    240         )                                              \
    241         << (4 * (7-(_n)))                              \
    242       )
    243 
    244    return
    245       FIELD(0) | FIELD(1) | FIELD(2) | FIELD(3)
    246       | FIELD(4) | FIELD(5) | FIELD(6) | FIELD(7);
    247 
    248 #  undef FIELD
    249 }
    250 
    251 
    252 /* VISIBLE TO LIBVEX CLIENT */
    253 void LibVEX_GuestPPC32_put_CR ( UInt cr_native,
    254                                 /*OUT*/VexGuestPPC32State* vex_state )
    255 {
    256    UInt t;
    257 
    258 #  define FIELD(_n)                                           \
    259       do {                                                    \
    260          t = cr_native >> (4*(7-(_n)));                       \
    261          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
    262          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
    263       } while (0)
    264 
    265    FIELD(0);
    266    FIELD(1);
    267    FIELD(2);
    268    FIELD(3);
    269    FIELD(4);
    270    FIELD(5);
    271    FIELD(6);
    272    FIELD(7);
    273 
    274 #  undef FIELD
    275 }
    276 
    277 
    278 /* VISIBLE TO LIBVEX CLIENT */
    279 /* Note: %CR is 32 bits even for ppc64 */
    280 void LibVEX_GuestPPC64_put_CR ( UInt cr_native,
    281                                 /*OUT*/VexGuestPPC64State* vex_state )
    282 {
    283    UInt t;
    284 
    285 #  define FIELD(_n)                                           \
    286       do {                                                    \
    287          t = cr_native >> (4*(7-(_n)));                       \
    288          vex_state->guest_CR##_n##_0 = toUChar(t & 1);        \
    289          vex_state->guest_CR##_n##_321 = toUChar(t & (7<<1)); \
    290       } while (0)
    291 
    292    FIELD(0);
    293    FIELD(1);
    294    FIELD(2);
    295    FIELD(3);
    296    FIELD(4);
    297    FIELD(5);
    298    FIELD(6);
    299    FIELD(7);
    300 
    301 #  undef FIELD
    302 }
    303 
    304 
    305 /* VISIBLE TO LIBVEX CLIENT */
    306 UInt LibVEX_GuestPPC32_get_XER ( /*IN*/VexGuestPPC32State* vex_state )
    307 {
    308    UInt w = 0;
    309    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
    310    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
    311    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
    312    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
    313    return w;
    314 }
    315 
    316 
    317 /* VISIBLE TO LIBVEX CLIENT */
    318 /* Note: %XER is 32 bits even for ppc64 */
    319 UInt LibVEX_GuestPPC64_get_XER ( /*IN*/VexGuestPPC64State* vex_state )
    320 {
    321    UInt w = 0;
    322    w |= ( ((UInt)vex_state->guest_XER_BC) & 0xFF );
    323    w |= ( (((UInt)vex_state->guest_XER_SO) & 0x1) << 31 );
    324    w |= ( (((UInt)vex_state->guest_XER_OV) & 0x1) << 30 );
    325    w |= ( (((UInt)vex_state->guest_XER_CA) & 0x1) << 29 );
    326    return w;
    327 }
    328 
    329 
    330 /* VISIBLE TO LIBVEX CLIENT */
    331 void LibVEX_GuestPPC32_put_XER ( UInt xer_native,
    332                                  /*OUT*/VexGuestPPC32State* vex_state )
    333 {
    334    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
    335    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
    336    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
    337    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
    338 }
    339 
    340 /* VISIBLE TO LIBVEX CLIENT */
    341 /* Note: %XER is 32 bits even for ppc64 */
    342 void LibVEX_GuestPPC64_put_XER ( UInt xer_native,
    343                                  /*OUT*/VexGuestPPC64State* vex_state )
    344 {
    345    vex_state->guest_XER_BC = toUChar(xer_native & 0xFF);
    346    vex_state->guest_XER_SO = toUChar((xer_native >> 31) & 0x1);
    347    vex_state->guest_XER_OV = toUChar((xer_native >> 30) & 0x1);
    348    vex_state->guest_XER_CA = toUChar((xer_native >> 29) & 0x1);
    349 }
    350 
    351 /* VISIBLE TO LIBVEX CLIENT */
    352 void LibVEX_GuestPPC32_initialise ( /*OUT*/VexGuestPPC32State* vex_state )
    353 {
    354    Int i;
    355    vex_state->guest_GPR0  = 0;
    356    vex_state->guest_GPR1  = 0;
    357    vex_state->guest_GPR2  = 0;
    358    vex_state->guest_GPR3  = 0;
    359    vex_state->guest_GPR4  = 0;
    360    vex_state->guest_GPR5  = 0;
    361    vex_state->guest_GPR6  = 0;
    362    vex_state->guest_GPR7  = 0;
    363    vex_state->guest_GPR8  = 0;
    364    vex_state->guest_GPR9  = 0;
    365    vex_state->guest_GPR10 = 0;
    366    vex_state->guest_GPR11 = 0;
    367    vex_state->guest_GPR12 = 0;
    368    vex_state->guest_GPR13 = 0;
    369    vex_state->guest_GPR14 = 0;
    370    vex_state->guest_GPR15 = 0;
    371    vex_state->guest_GPR16 = 0;
    372    vex_state->guest_GPR17 = 0;
    373    vex_state->guest_GPR18 = 0;
    374    vex_state->guest_GPR19 = 0;
    375    vex_state->guest_GPR20 = 0;
    376    vex_state->guest_GPR21 = 0;
    377    vex_state->guest_GPR22 = 0;
    378    vex_state->guest_GPR23 = 0;
    379    vex_state->guest_GPR24 = 0;
    380    vex_state->guest_GPR25 = 0;
    381    vex_state->guest_GPR26 = 0;
    382    vex_state->guest_GPR27 = 0;
    383    vex_state->guest_GPR28 = 0;
    384    vex_state->guest_GPR29 = 0;
    385    vex_state->guest_GPR30 = 0;
    386    vex_state->guest_GPR31 = 0;
    387 
    388    vex_state->guest_FPR0  = 0;
    389    vex_state->guest_FPR1  = 0;
    390    vex_state->guest_FPR2  = 0;
    391    vex_state->guest_FPR3  = 0;
    392    vex_state->guest_FPR4  = 0;
    393    vex_state->guest_FPR5  = 0;
    394    vex_state->guest_FPR6  = 0;
    395    vex_state->guest_FPR7  = 0;
    396    vex_state->guest_FPR8  = 0;
    397    vex_state->guest_FPR9  = 0;
    398    vex_state->guest_FPR10 = 0;
    399    vex_state->guest_FPR11 = 0;
    400    vex_state->guest_FPR12 = 0;
    401    vex_state->guest_FPR13 = 0;
    402    vex_state->guest_FPR14 = 0;
    403    vex_state->guest_FPR15 = 0;
    404    vex_state->guest_FPR16 = 0;
    405    vex_state->guest_FPR17 = 0;
    406    vex_state->guest_FPR18 = 0;
    407    vex_state->guest_FPR19 = 0;
    408    vex_state->guest_FPR20 = 0;
    409    vex_state->guest_FPR21 = 0;
    410    vex_state->guest_FPR22 = 0;
    411    vex_state->guest_FPR23 = 0;
    412    vex_state->guest_FPR24 = 0;
    413    vex_state->guest_FPR25 = 0;
    414    vex_state->guest_FPR26 = 0;
    415    vex_state->guest_FPR27 = 0;
    416    vex_state->guest_FPR28 = 0;
    417    vex_state->guest_FPR29 = 0;
    418    vex_state->guest_FPR30 = 0;
    419    vex_state->guest_FPR31 = 0;
    420 
    421    /* Initialise the vector state. */
    422 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
    423 
    424    VECZERO(vex_state->guest_VR0 );
    425    VECZERO(vex_state->guest_VR1 );
    426    VECZERO(vex_state->guest_VR2 );
    427    VECZERO(vex_state->guest_VR3 );
    428    VECZERO(vex_state->guest_VR4 );
    429    VECZERO(vex_state->guest_VR5 );
    430    VECZERO(vex_state->guest_VR6 );
    431    VECZERO(vex_state->guest_VR7 );
    432    VECZERO(vex_state->guest_VR8 );
    433    VECZERO(vex_state->guest_VR9 );
    434    VECZERO(vex_state->guest_VR10);
    435    VECZERO(vex_state->guest_VR11);
    436    VECZERO(vex_state->guest_VR12);
    437    VECZERO(vex_state->guest_VR13);
    438    VECZERO(vex_state->guest_VR14);
    439    VECZERO(vex_state->guest_VR15);
    440    VECZERO(vex_state->guest_VR16);
    441    VECZERO(vex_state->guest_VR17);
    442    VECZERO(vex_state->guest_VR18);
    443    VECZERO(vex_state->guest_VR19);
    444    VECZERO(vex_state->guest_VR20);
    445    VECZERO(vex_state->guest_VR21);
    446    VECZERO(vex_state->guest_VR22);
    447    VECZERO(vex_state->guest_VR23);
    448    VECZERO(vex_state->guest_VR24);
    449    VECZERO(vex_state->guest_VR25);
    450    VECZERO(vex_state->guest_VR26);
    451    VECZERO(vex_state->guest_VR27);
    452    VECZERO(vex_state->guest_VR28);
    453    VECZERO(vex_state->guest_VR29);
    454    VECZERO(vex_state->guest_VR30);
    455    VECZERO(vex_state->guest_VR31);
    456 
    457 #  undef VECZERO
    458 
    459    vex_state->guest_CIA  = 0;
    460    vex_state->guest_LR   = 0;
    461    vex_state->guest_CTR  = 0;
    462 
    463    vex_state->guest_XER_SO = 0;
    464    vex_state->guest_XER_OV = 0;
    465    vex_state->guest_XER_CA = 0;
    466    vex_state->guest_XER_BC = 0;
    467 
    468    vex_state->guest_CR0_321 = 0;
    469    vex_state->guest_CR0_0   = 0;
    470    vex_state->guest_CR1_321 = 0;
    471    vex_state->guest_CR1_0   = 0;
    472    vex_state->guest_CR2_321 = 0;
    473    vex_state->guest_CR2_0   = 0;
    474    vex_state->guest_CR3_321 = 0;
    475    vex_state->guest_CR3_0   = 0;
    476    vex_state->guest_CR4_321 = 0;
    477    vex_state->guest_CR4_0   = 0;
    478    vex_state->guest_CR5_321 = 0;
    479    vex_state->guest_CR5_0   = 0;
    480    vex_state->guest_CR6_321 = 0;
    481    vex_state->guest_CR6_0   = 0;
    482    vex_state->guest_CR7_321 = 0;
    483    vex_state->guest_CR7_0   = 0;
    484 
    485    vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
    486 
    487    vex_state->guest_VRSAVE = 0;
    488 
    489    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
    490 
    491    vex_state->guest_EMWARN = EmWarn_NONE;
    492 
    493    vex_state->guest_TISTART = 0;
    494    vex_state->guest_TILEN   = 0;
    495 
    496    vex_state->guest_NRADDR = 0;
    497    vex_state->guest_NRADDR_GPR2 = 0;
    498 
    499    vex_state->guest_REDIR_SP = -1;
    500    for (i = 0; i < VEX_GUEST_PPC32_REDIR_STACK_SIZE; i++)
    501       vex_state->guest_REDIR_STACK[i] = 0;
    502 
    503    vex_state->guest_IP_AT_SYSCALL = 0;
    504    vex_state->guest_SPRG3_RO = 0;
    505 }
    506 
    507 
    508 /* VISIBLE TO LIBVEX CLIENT */
    509 void LibVEX_GuestPPC64_initialise ( /*OUT*/VexGuestPPC64State* vex_state )
    510 {
    511    Int i;
    512    vex_state->guest_GPR0  = 0;
    513    vex_state->guest_GPR1  = 0;
    514    vex_state->guest_GPR2  = 0;
    515    vex_state->guest_GPR3  = 0;
    516    vex_state->guest_GPR4  = 0;
    517    vex_state->guest_GPR5  = 0;
    518    vex_state->guest_GPR6  = 0;
    519    vex_state->guest_GPR7  = 0;
    520    vex_state->guest_GPR8  = 0;
    521    vex_state->guest_GPR9  = 0;
    522    vex_state->guest_GPR10 = 0;
    523    vex_state->guest_GPR11 = 0;
    524    vex_state->guest_GPR12 = 0;
    525    vex_state->guest_GPR13 = 0;
    526    vex_state->guest_GPR14 = 0;
    527    vex_state->guest_GPR15 = 0;
    528    vex_state->guest_GPR16 = 0;
    529    vex_state->guest_GPR17 = 0;
    530    vex_state->guest_GPR18 = 0;
    531    vex_state->guest_GPR19 = 0;
    532    vex_state->guest_GPR20 = 0;
    533    vex_state->guest_GPR21 = 0;
    534    vex_state->guest_GPR22 = 0;
    535    vex_state->guest_GPR23 = 0;
    536    vex_state->guest_GPR24 = 0;
    537    vex_state->guest_GPR25 = 0;
    538    vex_state->guest_GPR26 = 0;
    539    vex_state->guest_GPR27 = 0;
    540    vex_state->guest_GPR28 = 0;
    541    vex_state->guest_GPR29 = 0;
    542    vex_state->guest_GPR30 = 0;
    543    vex_state->guest_GPR31 = 0;
    544 
    545    vex_state->guest_FPR0  = 0;
    546    vex_state->guest_FPR1  = 0;
    547    vex_state->guest_FPR2  = 0;
    548    vex_state->guest_FPR3  = 0;
    549    vex_state->guest_FPR4  = 0;
    550    vex_state->guest_FPR5  = 0;
    551    vex_state->guest_FPR6  = 0;
    552    vex_state->guest_FPR7  = 0;
    553    vex_state->guest_FPR8  = 0;
    554    vex_state->guest_FPR9  = 0;
    555    vex_state->guest_FPR10 = 0;
    556    vex_state->guest_FPR11 = 0;
    557    vex_state->guest_FPR12 = 0;
    558    vex_state->guest_FPR13 = 0;
    559    vex_state->guest_FPR14 = 0;
    560    vex_state->guest_FPR15 = 0;
    561    vex_state->guest_FPR16 = 0;
    562    vex_state->guest_FPR17 = 0;
    563    vex_state->guest_FPR18 = 0;
    564    vex_state->guest_FPR19 = 0;
    565    vex_state->guest_FPR20 = 0;
    566    vex_state->guest_FPR21 = 0;
    567    vex_state->guest_FPR22 = 0;
    568    vex_state->guest_FPR23 = 0;
    569    vex_state->guest_FPR24 = 0;
    570    vex_state->guest_FPR25 = 0;
    571    vex_state->guest_FPR26 = 0;
    572    vex_state->guest_FPR27 = 0;
    573    vex_state->guest_FPR28 = 0;
    574    vex_state->guest_FPR29 = 0;
    575    vex_state->guest_FPR30 = 0;
    576    vex_state->guest_FPR31 = 0;
    577 
    578    /* Initialise the vector state. */
    579 #  define VECZERO(_vr) _vr[0]=_vr[1]=_vr[2]=_vr[3] = 0;
    580 
    581    VECZERO(vex_state->guest_VR0 );
    582    VECZERO(vex_state->guest_VR1 );
    583    VECZERO(vex_state->guest_VR2 );
    584    VECZERO(vex_state->guest_VR3 );
    585    VECZERO(vex_state->guest_VR4 );
    586    VECZERO(vex_state->guest_VR5 );
    587    VECZERO(vex_state->guest_VR6 );
    588    VECZERO(vex_state->guest_VR7 );
    589    VECZERO(vex_state->guest_VR8 );
    590    VECZERO(vex_state->guest_VR9 );
    591    VECZERO(vex_state->guest_VR10);
    592    VECZERO(vex_state->guest_VR11);
    593    VECZERO(vex_state->guest_VR12);
    594    VECZERO(vex_state->guest_VR13);
    595    VECZERO(vex_state->guest_VR14);
    596    VECZERO(vex_state->guest_VR15);
    597    VECZERO(vex_state->guest_VR16);
    598    VECZERO(vex_state->guest_VR17);
    599    VECZERO(vex_state->guest_VR18);
    600    VECZERO(vex_state->guest_VR19);
    601    VECZERO(vex_state->guest_VR20);
    602    VECZERO(vex_state->guest_VR21);
    603    VECZERO(vex_state->guest_VR22);
    604    VECZERO(vex_state->guest_VR23);
    605    VECZERO(vex_state->guest_VR24);
    606    VECZERO(vex_state->guest_VR25);
    607    VECZERO(vex_state->guest_VR26);
    608    VECZERO(vex_state->guest_VR27);
    609    VECZERO(vex_state->guest_VR28);
    610    VECZERO(vex_state->guest_VR29);
    611    VECZERO(vex_state->guest_VR30);
    612    VECZERO(vex_state->guest_VR31);
    613 
    614 #  undef VECZERO
    615 
    616    vex_state->guest_CIA  = 0;
    617    vex_state->guest_LR   = 0;
    618    vex_state->guest_CTR  = 0;
    619 
    620    vex_state->guest_XER_SO = 0;
    621    vex_state->guest_XER_OV = 0;
    622    vex_state->guest_XER_CA = 0;
    623    vex_state->guest_XER_BC = 0;
    624 
    625    vex_state->guest_CR0_321 = 0;
    626    vex_state->guest_CR0_0   = 0;
    627    vex_state->guest_CR1_321 = 0;
    628    vex_state->guest_CR1_0   = 0;
    629    vex_state->guest_CR2_321 = 0;
    630    vex_state->guest_CR2_0   = 0;
    631    vex_state->guest_CR3_321 = 0;
    632    vex_state->guest_CR3_0   = 0;
    633    vex_state->guest_CR4_321 = 0;
    634    vex_state->guest_CR4_0   = 0;
    635    vex_state->guest_CR5_321 = 0;
    636    vex_state->guest_CR5_0   = 0;
    637    vex_state->guest_CR6_321 = 0;
    638    vex_state->guest_CR6_0   = 0;
    639    vex_state->guest_CR7_321 = 0;
    640    vex_state->guest_CR7_0   = 0;
    641 
    642    vex_state->guest_FPROUND = (UInt)PPCrm_NEAREST;
    643 
    644    vex_state->guest_VRSAVE = 0;
    645 
    646    vex_state->guest_VSCR = 0x0;  // Non-Java mode = 0
    647 
    648    vex_state->guest_EMWARN = EmWarn_NONE;
    649 
    650    vex_state->padding = 0;
    651 
    652    vex_state->guest_TISTART = 0;
    653    vex_state->guest_TILEN   = 0;
    654 
    655    vex_state->guest_NRADDR = 0;
    656    vex_state->guest_NRADDR_GPR2 = 0;
    657 
    658    vex_state->guest_REDIR_SP = -1;
    659    for (i = 0; i < VEX_GUEST_PPC64_REDIR_STACK_SIZE; i++)
    660       vex_state->guest_REDIR_STACK[i] = 0;
    661 
    662    vex_state->guest_IP_AT_SYSCALL = 0;
    663    vex_state->guest_SPRG3_RO = 0;
    664 
    665    vex_state->padding2 = 0;
    666 }
    667 
    668 
    669 /*-----------------------------------------------------------*/
    670 /*--- Describing the ppc guest state, for the benefit     ---*/
    671 /*--- of iropt and instrumenters.                         ---*/
    672 /*-----------------------------------------------------------*/
    673 
    674 /* Figure out if any part of the guest state contained in minoff
    675    .. maxoff requires precise memory exceptions.  If in doubt return
    676    True (but this is generates significantly slower code).
    677 
    678    By default we enforce precise exns for guest R1 (stack pointer),
    679    CIA (current insn address) and LR (link register).  These are the
    680    minimum needed to extract correct stack backtraces from ppc
    681    code. [[NB: not sure if keeping LR up to date is actually
    682    necessary.]]
    683 */
    684 Bool guest_ppc32_state_requires_precise_mem_exns ( Int minoff,
    685                                                    Int maxoff )
    686 {
    687    Int lr_min  = offsetof(VexGuestPPC32State, guest_LR);
    688    Int lr_max  = lr_min + 4 - 1;
    689    Int r1_min  = offsetof(VexGuestPPC32State, guest_GPR1);
    690    Int r1_max  = r1_min + 4 - 1;
    691    Int cia_min = offsetof(VexGuestPPC32State, guest_CIA);
    692    Int cia_max = cia_min + 4 - 1;
    693 
    694    if (maxoff < lr_min || minoff > lr_max) {
    695       /* no overlap with LR */
    696    } else {
    697       return True;
    698    }
    699 
    700    if (maxoff < r1_min || minoff > r1_max) {
    701       /* no overlap with R1 */
    702    } else {
    703       return True;
    704    }
    705 
    706    if (maxoff < cia_min || minoff > cia_max) {
    707       /* no overlap with CIA */
    708    } else {
    709       return True;
    710    }
    711 
    712    return False;
    713 }
    714 
    715 Bool guest_ppc64_state_requires_precise_mem_exns ( Int minoff,
    716                                                    Int maxoff )
    717 {
    718    /* Given that R2 is a Big Deal in the ELF ppc64 ABI, it seems
    719       prudent to be conservative with it, even though thus far there
    720       is no evidence to suggest that it actually needs to be kept up
    721       to date wrt possible exceptions. */
    722    Int lr_min  = offsetof(VexGuestPPC64State, guest_LR);
    723    Int lr_max  = lr_min + 8 - 1;
    724    Int r1_min  = offsetof(VexGuestPPC64State, guest_GPR1);
    725    Int r1_max  = r1_min + 8 - 1;
    726    Int r2_min  = offsetof(VexGuestPPC64State, guest_GPR2);
    727    Int r2_max  = r2_min + 8 - 1;
    728    Int cia_min = offsetof(VexGuestPPC64State, guest_CIA);
    729    Int cia_max = cia_min + 8 - 1;
    730 
    731    if (maxoff < lr_min || minoff > lr_max) {
    732       /* no overlap with LR */
    733    } else {
    734       return True;
    735    }
    736 
    737    if (maxoff < r1_min || minoff > r1_max) {
    738       /* no overlap with R1 */
    739    } else {
    740       return True;
    741    }
    742 
    743    if (maxoff < r2_min || minoff > r2_max) {
    744       /* no overlap with R2 */
    745    } else {
    746       return True;
    747    }
    748 
    749    if (maxoff < cia_min || minoff > cia_max) {
    750       /* no overlap with CIA */
    751    } else {
    752       return True;
    753    }
    754 
    755    return False;
    756 }
    757 
    758 
    759 #define ALWAYSDEFD32(field)                           \
    760     { offsetof(VexGuestPPC32State, field),            \
    761       (sizeof ((VexGuestPPC32State*)0)->field) }
    762 
    763 VexGuestLayout
    764    ppc32Guest_layout
    765       = {
    766           /* Total size of the guest state, in bytes. */
    767           .total_sizeB = sizeof(VexGuestPPC32State),
    768 
    769           /* Describe the stack pointer. */
    770           .offset_SP = offsetof(VexGuestPPC32State,guest_GPR1),
    771           .sizeof_SP = 4,
    772 
    773           /* Describe the frame pointer. */
    774           .offset_FP = offsetof(VexGuestPPC32State,guest_GPR1),
    775           .sizeof_FP = 4,
    776 
    777           /* Describe the instruction pointer. */
    778           .offset_IP = offsetof(VexGuestPPC32State,guest_CIA),
    779           .sizeof_IP = 4,
    780 
    781           /* Describe any sections to be regarded by Memcheck as
    782              'always-defined'. */
    783           .n_alwaysDefd = 11,
    784 
    785           .alwaysDefd
    786 	  = { /*  0 */ ALWAYSDEFD32(guest_CIA),
    787 	      /*  1 */ ALWAYSDEFD32(guest_EMWARN),
    788 	      /*  2 */ ALWAYSDEFD32(guest_TISTART),
    789 	      /*  3 */ ALWAYSDEFD32(guest_TILEN),
    790 	      /*  4 */ ALWAYSDEFD32(guest_VSCR),
    791 	      /*  5 */ ALWAYSDEFD32(guest_FPROUND),
    792               /*  6 */ ALWAYSDEFD32(guest_NRADDR),
    793 	      /*  7 */ ALWAYSDEFD32(guest_NRADDR_GPR2),
    794 	      /*  8 */ ALWAYSDEFD32(guest_REDIR_SP),
    795 	      /*  9 */ ALWAYSDEFD32(guest_REDIR_STACK),
    796 	      /* 10 */ ALWAYSDEFD32(guest_IP_AT_SYSCALL)
    797             }
    798         };
    799 
    800 #define ALWAYSDEFD64(field)                           \
    801     { offsetof(VexGuestPPC64State, field),            \
    802       (sizeof ((VexGuestPPC64State*)0)->field) }
    803 
    804 VexGuestLayout
    805    ppc64Guest_layout
    806       = {
    807           /* Total size of the guest state, in bytes. */
    808           .total_sizeB = sizeof(VexGuestPPC64State),
    809 
    810           /* Describe the stack pointer. */
    811           .offset_SP = offsetof(VexGuestPPC64State,guest_GPR1),
    812           .sizeof_SP = 8,
    813 
    814           /* Describe the frame pointer. */
    815           .offset_FP = offsetof(VexGuestPPC64State,guest_GPR1),
    816           .sizeof_FP = 8,
    817 
    818           /* Describe the instruction pointer. */
    819           .offset_IP = offsetof(VexGuestPPC64State,guest_CIA),
    820           .sizeof_IP = 8,
    821 
    822           /* Describe any sections to be regarded by Memcheck as
    823              'always-defined'. */
    824           .n_alwaysDefd = 11,
    825 
    826           .alwaysDefd
    827 	  = { /*  0 */ ALWAYSDEFD64(guest_CIA),
    828 	      /*  1 */ ALWAYSDEFD64(guest_EMWARN),
    829 	      /*  2 */ ALWAYSDEFD64(guest_TISTART),
    830 	      /*  3 */ ALWAYSDEFD64(guest_TILEN),
    831 	      /*  4 */ ALWAYSDEFD64(guest_VSCR),
    832 	      /*  5 */ ALWAYSDEFD64(guest_FPROUND),
    833 	      /*  6 */ ALWAYSDEFD64(guest_NRADDR),
    834 	      /*  7 */ ALWAYSDEFD64(guest_NRADDR_GPR2),
    835 	      /*  8 */ ALWAYSDEFD64(guest_REDIR_SP),
    836 	      /*  9 */ ALWAYSDEFD64(guest_REDIR_STACK),
    837 	      /* 10 */ ALWAYSDEFD64(guest_IP_AT_SYSCALL)
    838             }
    839         };
    840 
    841 /*---------------------------------------------------------------*/
    842 /*--- end                                 guest_ppc_helpers.c ---*/
    843 /*---------------------------------------------------------------*/
    844