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-2013 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_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. */
     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) */
     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) */
    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) */
    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) */
    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 
    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 
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 */
    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 
    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