Home | History | Annotate | Download | only in priv
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- begin                               guest_generic_bb_to_IR.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2004-2011 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_ir.h"
     38 #include "libvex.h"
     39 #include "main_util.h"
     40 #include "main_globals.h"
     41 #include "guest_generic_bb_to_IR.h"
     42 
     43 
     44 /* Forwards .. */
     45 VEX_REGPARM(2)
     46 static UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s );
     47 VEX_REGPARM(1)
     48 static UInt genericg_compute_checksum_4al_1 ( HWord first_w32 );
     49 VEX_REGPARM(1)
     50 static UInt genericg_compute_checksum_4al_2 ( HWord first_w32 );
     51 VEX_REGPARM(1)
     52 static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 );
     53 VEX_REGPARM(1)
     54 static UInt genericg_compute_checksum_4al_4 ( HWord first_w32 );
     55 VEX_REGPARM(1)
     56 static UInt genericg_compute_checksum_4al_5 ( HWord first_w32 );
     57 VEX_REGPARM(1)
     58 static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 );
     59 VEX_REGPARM(1)
     60 static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 );
     61 VEX_REGPARM(1)
     62 static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 );
     63 VEX_REGPARM(1)
     64 static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 );
     65 VEX_REGPARM(1)
     66 static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 );
     67 VEX_REGPARM(1)
     68 static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 );
     69 VEX_REGPARM(1)
     70 static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 );
     71 
     72 VEX_REGPARM(2)
     73 static ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s );
     74 VEX_REGPARM(1)
     75 static ULong genericg_compute_checksum_8al_1 ( HWord first_w64 );
     76 VEX_REGPARM(1)
     77 static ULong genericg_compute_checksum_8al_2 ( HWord first_w64 );
     78 VEX_REGPARM(1)
     79 static ULong genericg_compute_checksum_8al_3 ( HWord first_w64 );
     80 VEX_REGPARM(1)
     81 static ULong genericg_compute_checksum_8al_4 ( HWord first_w64 );
     82 VEX_REGPARM(1)
     83 static ULong genericg_compute_checksum_8al_5 ( HWord first_w64 );
     84 VEX_REGPARM(1)
     85 static ULong genericg_compute_checksum_8al_6 ( HWord first_w64 );
     86 VEX_REGPARM(1)
     87 static ULong genericg_compute_checksum_8al_7 ( HWord first_w64 );
     88 VEX_REGPARM(1)
     89 static ULong genericg_compute_checksum_8al_8 ( HWord first_w64 );
     90 VEX_REGPARM(1)
     91 static ULong genericg_compute_checksum_8al_9 ( HWord first_w64 );
     92 VEX_REGPARM(1)
     93 static ULong genericg_compute_checksum_8al_10 ( HWord first_w64 );
     94 VEX_REGPARM(1)
     95 static ULong genericg_compute_checksum_8al_11 ( HWord first_w64 );
     96 VEX_REGPARM(1)
     97 static ULong genericg_compute_checksum_8al_12 ( HWord first_w64 );
     98 
     99 /* Small helpers */
    100 static Bool const_False ( void* callback_opaque, Addr64 a ) {
    101    return False;
    102 }
    103 
    104 /* Disassemble a complete basic block, starting at guest_IP_start,
    105    returning a new IRSB.  The disassembler may chase across basic
    106    block boundaries if it wishes and if chase_into_ok allows it.
    107    The precise guest address ranges from which code has been taken
    108    are written into vge.  guest_IP_bbstart is taken to be the IP in
    109    the guest's address space corresponding to the instruction at
    110    &guest_code[0].
    111 
    112    dis_instr_fn is the arch-specific fn to disassemble on function; it
    113    is this that does the real work.
    114 
    115    needs_self_check is a callback used to ask the caller which of the
    116    extents, if any, a self check is required for.  The returned value
    117    is a bitmask with a 1 in position i indicating that the i'th extent
    118    needs a check.  Since there can be at most 3 extents, the returned
    119    values must be between 0 and 7.
    120 
    121    The number of extents which did get a self check (0 to 3) is put in
    122    n_sc_extents.  The caller already knows this because it told us
    123    which extents to add checks for, via the needs_self_check callback,
    124    but we ship the number back out here for the caller's convenience.
    125 
    126    preamble_function is a callback which allows the caller to add
    127    its own IR preamble (following the self-check, if any).  May be
    128    NULL.  If non-NULL, the IRSB under construction is handed to
    129    this function, which presumably adds IR statements to it.  The
    130    callback may optionally complete the block and direct bb_to_IR
    131    not to disassemble any instructions into it; this is indicated
    132    by the callback returning True.
    133 
    134    offB_TIADDR and offB_TILEN are the offsets of guest_TIADDR and
    135    guest_TILEN.  Since this routine has to work for any guest state,
    136    without knowing what it is, those offsets have to passed in.
    137 
    138    callback_opaque is a caller-supplied pointer to data which the
    139    callbacks may want to see.  Vex has no idea what it is.
    140    (In fact it's a VgInstrumentClosure.)
    141 */
    142 
    143 IRSB* bb_to_IR (
    144          /*OUT*/VexGuestExtents* vge,
    145          /*OUT*/UInt*            n_sc_extents,
    146          /*IN*/ void*            callback_opaque,
    147          /*IN*/ DisOneInstrFn    dis_instr_fn,
    148          /*IN*/ UChar*           guest_code,
    149          /*IN*/ Addr64           guest_IP_bbstart,
    150          /*IN*/ Bool             (*chase_into_ok)(void*,Addr64),
    151          /*IN*/ Bool             host_bigendian,
    152          /*IN*/ VexArch          arch_guest,
    153          /*IN*/ VexArchInfo*     archinfo_guest,
    154          /*IN*/ VexAbiInfo*      abiinfo_both,
    155          /*IN*/ IRType           guest_word_type,
    156          /*IN*/ UInt             (*needs_self_check)(void*,VexGuestExtents*),
    157          /*IN*/ Bool             (*preamble_function)(void*,IRSB*),
    158          /*IN*/ Int              offB_TISTART,
    159          /*IN*/ Int              offB_TILEN
    160       )
    161 {
    162    Long       delta;
    163    Int        i, n_instrs, first_stmt_idx;
    164    Bool       resteerOK, need_to_put_IP, debug_print;
    165    DisResult  dres;
    166    IRStmt*    imark;
    167    IRStmt*    nop;
    168    static Int n_resteers = 0;
    169    Int        d_resteers = 0;
    170    Int        selfcheck_idx = 0;
    171    IRSB*      irsb;
    172    Addr64     guest_IP_curr_instr;
    173    IRConst*   guest_IP_bbstart_IRConst = NULL;
    174    Int        n_cond_resteers_allowed = 2;
    175 
    176    Bool (*resteerOKfn)(void*,Addr64) = NULL;
    177 
    178    debug_print = toBool(vex_traceflags & VEX_TRACE_FE);
    179 
    180    /* check sanity .. */
    181    vassert(sizeof(HWord) == sizeof(void*));
    182    vassert(vex_control.guest_max_insns >= 1);
    183    vassert(vex_control.guest_max_insns < 100);
    184    vassert(vex_control.guest_chase_thresh >= 0);
    185    vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
    186    vassert(guest_word_type == Ity_I32 || guest_word_type == Ity_I64);
    187 
    188    /* Start a new, empty extent. */
    189    vge->n_used  = 1;
    190    vge->base[0] = guest_IP_bbstart;
    191    vge->len[0]  = 0;
    192    *n_sc_extents = 0;
    193 
    194    /* And a new IR superblock to dump the result into. */
    195    irsb = emptyIRSB();
    196 
    197    /* Delta keeps track of how far along the guest_code array we have
    198       so far gone. */
    199    delta    = 0;
    200    n_instrs = 0;
    201 
    202    /* Guest addresses as IRConsts.  Used in self-checks to specify the
    203       restart-after-discard point. */
    204    guest_IP_bbstart_IRConst
    205       = guest_word_type==Ity_I32
    206            ? IRConst_U32(toUInt(guest_IP_bbstart))
    207            : IRConst_U64(guest_IP_bbstart);
    208 
    209    /* Leave 15 spaces in which to put the check statements for a self
    210       checking translation (up to 3 extents, and 5 stmts required for
    211       each).  We won't know until later the extents and checksums of
    212       the areas, if any, that need to be checked. */
    213    nop = IRStmt_NoOp();
    214    selfcheck_idx = irsb->stmts_used;
    215    for (i = 0; i < 3 * 5; i++)
    216       addStmtToIRSB( irsb, nop );
    217 
    218    /* If the caller supplied a function to add its own preamble, use
    219       it now. */
    220    if (preamble_function) {
    221       Bool stopNow = preamble_function( callback_opaque, irsb );
    222       if (stopNow) {
    223          /* The callback has completed the IR block without any guest
    224             insns being disassembled into it, so just return it at
    225             this point, even if a self-check was requested - as there
    226             is nothing to self-check.  The 15 self-check no-ops will
    227             still be in place, but they are harmless. */
    228          return irsb;
    229       }
    230    }
    231 
    232    /* Process instructions. */
    233    while (True) {
    234       vassert(n_instrs < vex_control.guest_max_insns);
    235 
    236       /* Regardless of what chase_into_ok says, is chasing permissible
    237          at all right now?  Set resteerOKfn accordingly. */
    238       resteerOK
    239          = toBool(
    240               n_instrs < vex_control.guest_chase_thresh
    241               /* we can't afford to have a resteer once we're on the
    242                  last extent slot. */
    243               && vge->n_used < 3
    244            );
    245 
    246       resteerOKfn
    247          = resteerOK ? chase_into_ok : const_False;
    248 
    249       /* n_cond_resteers_allowed keeps track of whether we're still
    250          allowing dis_instr_fn to chase conditional branches.  It
    251          starts (at 2) and gets decremented each time dis_instr_fn
    252          tells us it has chased a conditional branch.  We then
    253          decrement it, and use it to tell later calls to dis_instr_fn
    254          whether or not it is allowed to chase conditional
    255          branches. */
    256       vassert(n_cond_resteers_allowed >= 0 && n_cond_resteers_allowed <= 2);
    257 
    258       /* This is the IP of the instruction we're just about to deal
    259          with. */
    260       guest_IP_curr_instr = guest_IP_bbstart + delta;
    261 
    262       /* This is the irsb statement array index of the first stmt in
    263          this insn.  That will always be the instruction-mark
    264          descriptor. */
    265       first_stmt_idx = irsb->stmts_used;
    266 
    267       /* Add an instruction-mark statement.  We won't know until after
    268          disassembling the instruction how long it instruction is, so
    269          just put in a zero length and we'll fix it up later.
    270 
    271          On ARM, the least significant bit of the instr address
    272          distinguishes ARM vs Thumb instructions.  All instructions
    273          actually start on at least 2-aligned addresses.  So we need
    274          to ignore the bottom bit of the insn address when forming the
    275          IMark's address field, but put that bottom bit in the delta
    276          field, so that comparisons against guest_R15T for Thumb can
    277          be done correctly.  By inspecting the delta field,
    278          instruction processors can determine whether the instruction
    279          was originally Thumb or ARM.  For more details of this
    280          convention, see comments on definition of guest_R15T in
    281          libvex_guest_arm.h. */
    282       if (arch_guest == VexArchARM && (guest_IP_curr_instr & (Addr64)1)) {
    283          /* Thumb insn => mask out the T bit, but put it in delta */
    284          addStmtToIRSB( irsb,
    285                         IRStmt_IMark(guest_IP_curr_instr & ~(Addr64)1,
    286                                      0, /* len */
    287                                      1  /* delta */
    288                         )
    289          );
    290       } else {
    291          /* All other targets: store IP as-is, and set delta to zero. */
    292          addStmtToIRSB( irsb,
    293                         IRStmt_IMark(guest_IP_curr_instr,
    294                                      0, /* len */
    295                                      0  /* delta */
    296                         )
    297          );
    298       }
    299 
    300       /* for the first insn, the dispatch loop will have set
    301          %IP, but for all the others we have to do it ourselves. */
    302       need_to_put_IP = toBool(n_instrs > 0);
    303 
    304       /* Finally, actually disassemble an instruction. */
    305       dres = dis_instr_fn ( irsb,
    306                             need_to_put_IP,
    307                             resteerOKfn,
    308                             toBool(n_cond_resteers_allowed > 0),
    309                             callback_opaque,
    310                             guest_code,
    311                             delta,
    312                             guest_IP_curr_instr,
    313                             arch_guest,
    314                             archinfo_guest,
    315                             abiinfo_both,
    316                             host_bigendian );
    317 
    318       /* stay sane ... */
    319       vassert(dres.whatNext == Dis_StopHere
    320               || dres.whatNext == Dis_Continue
    321               || dres.whatNext == Dis_ResteerU
    322               || dres.whatNext == Dis_ResteerC);
    323       /* ... disassembled insn length is sane ... */
    324       vassert(dres.len >= 0 && dres.len <= 20);
    325       /* ... continueAt is zero if no resteer requested ... */
    326       if (dres.whatNext != Dis_ResteerU && dres.whatNext != Dis_ResteerC)
    327          vassert(dres.continueAt == 0);
    328       /* ... if we disallowed conditional resteers, check that one
    329              didn't actually happen anyway ... */
    330       if (n_cond_resteers_allowed == 0)
    331          vassert(dres.whatNext != Dis_ResteerC);
    332 
    333       /* Fill in the insn-mark length field. */
    334       vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
    335       imark = irsb->stmts[first_stmt_idx];
    336       vassert(imark);
    337       vassert(imark->tag == Ist_IMark);
    338       vassert(imark->Ist.IMark.len == 0);
    339       imark->Ist.IMark.len = toUInt(dres.len);
    340 
    341       /* Print the resulting IR, if needed. */
    342       if (vex_traceflags & VEX_TRACE_FE) {
    343          for (i = first_stmt_idx; i < irsb->stmts_used; i++) {
    344             vex_printf("              ");
    345             ppIRStmt(irsb->stmts[i]);
    346             vex_printf("\n");
    347          }
    348       }
    349 
    350       /* If dis_instr_fn terminated the BB at this point, check it
    351          also filled in the irsb->next field. */
    352       if (dres.whatNext == Dis_StopHere) {
    353          vassert(irsb->next != NULL);
    354          if (debug_print) {
    355             vex_printf("              ");
    356             vex_printf( "goto {");
    357             ppIRJumpKind(irsb->jumpkind);
    358             vex_printf( "} ");
    359             ppIRExpr( irsb->next );
    360             vex_printf( "\n");
    361          }
    362       }
    363 
    364       /* Update the VexGuestExtents we are constructing. */
    365       /* If vex_control.guest_max_insns is required to be < 100 and
    366          each insn is at max 20 bytes long, this limit of 5000 then
    367          seems reasonable since the max possible extent length will be
    368          100 * 20 == 2000. */
    369       vassert(vge->len[vge->n_used-1] < 5000);
    370       vge->len[vge->n_used-1]
    371          = toUShort(toUInt( vge->len[vge->n_used-1] + dres.len ));
    372       n_instrs++;
    373       if (debug_print)
    374          vex_printf("\n");
    375 
    376       /* Advance delta (inconspicuous but very important :-) */
    377       delta += (Long)dres.len;
    378 
    379       switch (dres.whatNext) {
    380          case Dis_Continue:
    381             vassert(irsb->next == NULL);
    382             if (n_instrs < vex_control.guest_max_insns) {
    383                /* keep going */
    384             } else {
    385                /* We have to stop. */
    386                irsb->next
    387                   = IRExpr_Const(
    388                        guest_word_type == Ity_I32
    389                           ? IRConst_U32(toUInt(guest_IP_bbstart+delta))
    390                           : IRConst_U64(guest_IP_bbstart+delta)
    391                     );
    392                goto done;
    393             }
    394             break;
    395          case Dis_StopHere:
    396             vassert(irsb->next != NULL);
    397             goto done;
    398          case Dis_ResteerU:
    399          case Dis_ResteerC:
    400             /* Check that we actually allowed a resteer .. */
    401             vassert(resteerOK);
    402             vassert(irsb->next == NULL);
    403             if (dres.whatNext == Dis_ResteerC) {
    404                vassert(n_cond_resteers_allowed > 0);
    405                n_cond_resteers_allowed--;
    406             }
    407             /* figure out a new delta to continue at. */
    408             vassert(resteerOKfn(callback_opaque,dres.continueAt));
    409             delta = dres.continueAt - guest_IP_bbstart;
    410             /* we now have to start a new extent slot. */
    411             vge->n_used++;
    412             vassert(vge->n_used <= 3);
    413             vge->base[vge->n_used-1] = dres.continueAt;
    414             vge->len[vge->n_used-1] = 0;
    415             n_resteers++;
    416             d_resteers++;
    417             if (0 && (n_resteers & 0xFF) == 0)
    418             vex_printf("resteer[%d,%d] to 0x%llx (delta = %lld)\n",
    419                        n_resteers, d_resteers,
    420                        dres.continueAt, delta);
    421             break;
    422          default:
    423             vpanic("bb_to_IR");
    424       }
    425    }
    426    /*NOTREACHED*/
    427    vassert(0);
    428 
    429   done:
    430    /* We're done.  The only thing that might need attending to is that
    431       a self-checking preamble may need to be created.  If so it gets
    432       placed in the 15 slots reserved above.
    433 
    434       The scheme is to compute a rather crude checksum of the code
    435       we're making a translation of, and add to the IR a call to a
    436       helper routine which recomputes the checksum every time the
    437       translation is run, and requests a retranslation if it doesn't
    438       match.  This is obviously very expensive and considerable
    439       efforts are made to speed it up:
    440 
    441       * the checksum is computed from all the naturally aligned
    442         host-sized words that overlap the translated code.  That means
    443         it could depend on up to 7 bytes before and 7 bytes after
    444         which aren't part of the translated area, and so if those
    445         change then we'll unnecessarily have to discard and
    446         retranslate.  This seems like a pretty remote possibility and
    447         it seems as if the benefit of not having to deal with the ends
    448         of the range at byte precision far outweigh any possible extra
    449         translations needed.
    450 
    451       * there's a generic routine and 12 specialised cases, which
    452         handle the cases of 1 through 12-word lengths respectively.
    453         They seem to cover about 90% of the cases that occur in
    454         practice.
    455 
    456       We ask the caller, via needs_self_check, which of the 3 vge
    457       extents needs a check, and only generate check code for those
    458       that do.
    459    */
    460    {
    461       Addr64   base2check;
    462       UInt     len2check;
    463       HWord    expectedhW;
    464       IRTemp   tistart_tmp, tilen_tmp;
    465       HWord    VEX_REGPARM(2) (*fn_generic)(HWord, HWord);
    466       HWord    VEX_REGPARM(1) (*fn_spec)(HWord);
    467       HChar*   nm_generic;
    468       HChar*   nm_spec;
    469       HWord    fn_generic_entry = 0;
    470       HWord    fn_spec_entry = 0;
    471       UInt     host_word_szB = sizeof(HWord);
    472       IRType   host_word_type = Ity_INVALID;
    473 
    474       VexGuestExtents vge_tmp = *vge;
    475       UInt extents_needing_check
    476          = needs_self_check(callback_opaque, &vge_tmp);
    477 
    478       if (host_word_szB == 4) host_word_type = Ity_I32;
    479       if (host_word_szB == 8) host_word_type = Ity_I64;
    480       vassert(host_word_type != Ity_INVALID);
    481 
    482       vassert(vge->n_used >= 1 && vge->n_used <= 3);
    483 
    484       /* Caller shouldn't claim that nonexistent extents need a
    485          check. */
    486       vassert((extents_needing_check >> vge->n_used) == 0);
    487 
    488       for (i = 0; i < vge->n_used; i++) {
    489 
    490          /* Do we need to generate a check for this extent? */
    491          if ((extents_needing_check & (1 << i)) == 0)
    492             continue;
    493 
    494          /* Tell the caller */
    495          (*n_sc_extents)++;
    496 
    497          /* the extent we're generating a check for */
    498          base2check = vge->base[i];
    499          len2check  = vge->len[i];
    500 
    501          /* stay sane */
    502          vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
    503 
    504          /* Skip the check if the translation involved zero bytes */
    505          if (len2check == 0)
    506             continue;
    507 
    508          HWord first_hW = ((HWord)base2check)
    509                           & ~(HWord)(host_word_szB-1);
    510          HWord last_hW  = (((HWord)base2check) + len2check - 1)
    511                           & ~(HWord)(host_word_szB-1);
    512          vassert(first_hW <= last_hW);
    513          HWord hW_diff = last_hW - first_hW;
    514          vassert(0 == (hW_diff & (host_word_szB-1)));
    515          HWord hWs_to_check = (hW_diff + host_word_szB) / host_word_szB;
    516          vassert(hWs_to_check > 0
    517                  && hWs_to_check < 1004/*arbitrary*/ / host_word_szB);
    518 
    519          /* vex_printf("%lx %lx  %ld\n", first_hW, last_hW, hWs_to_check); */
    520 
    521          if (host_word_szB == 8) {
    522             fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
    523                           genericg_compute_checksum_8al;
    524             nm_generic = "genericg_compute_checksum_8al";
    525          } else {
    526             fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
    527                           genericg_compute_checksum_4al;
    528             nm_generic = "genericg_compute_checksum_4al";
    529          }
    530 
    531          fn_spec = NULL;
    532          nm_spec = NULL;
    533 
    534          if (host_word_szB == 8) {
    535             HChar* nm = NULL;
    536             ULong  VEX_REGPARM(1) (*fn)(HWord)  = NULL;
    537             switch (hWs_to_check) {
    538                case 1:  fn =  genericg_compute_checksum_8al_1;
    539                         nm = "genericg_compute_checksum_8al_1"; break;
    540                case 2:  fn =  genericg_compute_checksum_8al_2;
    541                         nm = "genericg_compute_checksum_8al_2"; break;
    542                case 3:  fn =  genericg_compute_checksum_8al_3;
    543                         nm = "genericg_compute_checksum_8al_3"; break;
    544                case 4:  fn =  genericg_compute_checksum_8al_4;
    545                         nm = "genericg_compute_checksum_8al_4"; break;
    546                case 5:  fn =  genericg_compute_checksum_8al_5;
    547                         nm = "genericg_compute_checksum_8al_5"; break;
    548                case 6:  fn =  genericg_compute_checksum_8al_6;
    549                         nm = "genericg_compute_checksum_8al_6"; break;
    550                case 7:  fn =  genericg_compute_checksum_8al_7;
    551                         nm = "genericg_compute_checksum_8al_7"; break;
    552                case 8:  fn =  genericg_compute_checksum_8al_8;
    553                         nm = "genericg_compute_checksum_8al_8"; break;
    554                case 9:  fn =  genericg_compute_checksum_8al_9;
    555                         nm = "genericg_compute_checksum_8al_9"; break;
    556                case 10: fn =  genericg_compute_checksum_8al_10;
    557                         nm = "genericg_compute_checksum_8al_10"; break;
    558                case 11: fn =  genericg_compute_checksum_8al_11;
    559                         nm = "genericg_compute_checksum_8al_11"; break;
    560                case 12: fn =  genericg_compute_checksum_8al_12;
    561                         nm = "genericg_compute_checksum_8al_12"; break;
    562                default: break;
    563             }
    564             fn_spec = (VEX_REGPARM(1) HWord(*)(HWord)) fn;
    565             nm_spec = nm;
    566          } else {
    567             HChar* nm = NULL;
    568             UInt   VEX_REGPARM(1) (*fn)(HWord) = NULL;
    569             switch (hWs_to_check) {
    570                case 1:  fn =  genericg_compute_checksum_4al_1;
    571                         nm = "genericg_compute_checksum_4al_1"; break;
    572                case 2:  fn =  genericg_compute_checksum_4al_2;
    573                         nm = "genericg_compute_checksum_4al_2"; break;
    574                case 3:  fn =  genericg_compute_checksum_4al_3;
    575                         nm = "genericg_compute_checksum_4al_3"; break;
    576                case 4:  fn =  genericg_compute_checksum_4al_4;
    577                         nm = "genericg_compute_checksum_4al_4"; break;
    578                case 5:  fn =  genericg_compute_checksum_4al_5;
    579                         nm = "genericg_compute_checksum_4al_5"; break;
    580                case 6:  fn =  genericg_compute_checksum_4al_6;
    581                         nm = "genericg_compute_checksum_4al_6"; break;
    582                case 7:  fn =  genericg_compute_checksum_4al_7;
    583                         nm = "genericg_compute_checksum_4al_7"; break;
    584                case 8:  fn =  genericg_compute_checksum_4al_8;
    585                         nm = "genericg_compute_checksum_4al_8"; break;
    586                case 9:  fn =  genericg_compute_checksum_4al_9;
    587                         nm = "genericg_compute_checksum_4al_9"; break;
    588                case 10: fn =  genericg_compute_checksum_4al_10;
    589                         nm = "genericg_compute_checksum_4al_10"; break;
    590                case 11: fn =  genericg_compute_checksum_4al_11;
    591                         nm = "genericg_compute_checksum_4al_11"; break;
    592                case 12: fn =  genericg_compute_checksum_4al_12;
    593                         nm = "genericg_compute_checksum_4al_12"; break;
    594                default: break;
    595             }
    596             fn_spec = (VEX_REGPARM(1) HWord(*)(HWord))fn;
    597             nm_spec = nm;
    598          }
    599 
    600          expectedhW = fn_generic( first_hW, hWs_to_check );
    601          /* If we got a specialised version, check it produces the same
    602             result as the generic version! */
    603          if (fn_spec) {
    604             vassert(nm_spec);
    605             vassert(expectedhW == fn_spec( first_hW ));
    606          } else {
    607             vassert(!nm_spec);
    608          }
    609 
    610          /* Set TISTART and TILEN.  These will describe to the despatcher
    611             the area of guest code to invalidate should we exit with a
    612             self-check failure. */
    613 
    614          tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
    615          tilen_tmp   = newIRTemp(irsb->tyenv, guest_word_type);
    616 
    617          IRConst* base2check_IRConst
    618             = guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
    619                                        : IRConst_U64(base2check);
    620          IRConst* len2check_IRConst
    621             = guest_word_type==Ity_I32 ? IRConst_U32(len2check)
    622                                        : IRConst_U64(len2check);
    623 
    624          irsb->stmts[selfcheck_idx + i * 5 + 0]
    625             = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
    626 
    627          irsb->stmts[selfcheck_idx + i * 5 + 1]
    628             = IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
    629 
    630          irsb->stmts[selfcheck_idx + i * 5 + 2]
    631             = IRStmt_Put( offB_TISTART, IRExpr_RdTmp(tistart_tmp) );
    632 
    633          irsb->stmts[selfcheck_idx + i * 5 + 3]
    634             = IRStmt_Put( offB_TILEN, IRExpr_RdTmp(tilen_tmp) );
    635 
    636          /* Generate the entry point descriptors */
    637          if (abiinfo_both->host_ppc_calls_use_fndescrs) {
    638             HWord* descr = (HWord*)fn_generic;
    639             fn_generic_entry = descr[0];
    640             if (fn_spec) {
    641                descr = (HWord*)fn_spec;
    642                fn_spec_entry = descr[0];
    643             } else {
    644                fn_spec_entry = (HWord)NULL;
    645             }
    646          } else {
    647             fn_generic_entry = (HWord)fn_generic;
    648             if (fn_spec) {
    649                fn_spec_entry = (HWord)fn_spec;
    650             } else {
    651                fn_spec_entry = (HWord)NULL;
    652             }
    653          }
    654 
    655          IRExpr* callexpr = NULL;
    656          if (fn_spec) {
    657             callexpr = mkIRExprCCall(
    658                           host_word_type, 1/*regparms*/,
    659                           nm_spec, (void*)fn_spec_entry,
    660                           mkIRExprVec_1(
    661                              mkIRExpr_HWord( (HWord)first_hW )
    662                           )
    663                        );
    664          } else {
    665             callexpr = mkIRExprCCall(
    666                           host_word_type, 2/*regparms*/,
    667                           nm_generic, (void*)fn_generic_entry,
    668                           mkIRExprVec_2(
    669                              mkIRExpr_HWord( (HWord)first_hW ),
    670                              mkIRExpr_HWord( (HWord)hWs_to_check )
    671                           )
    672                        );
    673          }
    674 
    675          irsb->stmts[selfcheck_idx + i * 5 + 4]
    676             = IRStmt_Exit(
    677                  IRExpr_Binop(
    678                     host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
    679                     callexpr,
    680                        host_word_type==Ity_I64
    681                           ? IRExpr_Const(IRConst_U64(expectedhW))
    682                           : IRExpr_Const(IRConst_U32(expectedhW))
    683                  ),
    684                  Ijk_TInval,
    685                  /* Where we must restart if there's a failure: at the
    686                     first extent, regardless of which extent the
    687                     failure actually happened in. */
    688                  guest_IP_bbstart_IRConst
    689               );
    690       } /* for (i = 0; i < vge->n_used; i++) */
    691    }
    692 
    693    return irsb;
    694 }
    695 
    696 
    697 /*-------------------------------------------------------------
    698   A support routine for doing self-checking translations.
    699   -------------------------------------------------------------*/
    700 
    701 /* CLEAN HELPER */
    702 /* CALLED FROM GENERATED CODE */
    703 
    704 /* Compute a checksum of host memory at [addr .. addr+len-1], as fast
    705    as possible.  All _4al versions assume that the supplied address is
    706    4 aligned.  All length values are in 4-byte chunks.  These fns
    707    arecalled once for every use of a self-checking translation, so
    708    they needs to be as fast as possible. */
    709 
    710 /* --- 32-bit versions, used only on 32-bit hosts --- */
    711 
    712 static inline UInt ROL32 ( UInt w, Int n ) {
    713    w = (w << n) | (w >> (32-n));
    714    return w;
    715 }
    716 
    717 VEX_REGPARM(2)
    718 static UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s )
    719 {
    720    UInt  sum1 = 0, sum2 = 0;
    721    UInt* p = (UInt*)first_w32;
    722    /* unrolled */
    723    while (n_w32s >= 4) {
    724       UInt  w;
    725       w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    726       w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    727       w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    728       w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    729       p += 4;
    730       n_w32s -= 4;
    731       sum1 ^= sum2;
    732    }
    733    while (n_w32s >= 1) {
    734       UInt  w;
    735       w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    736       p += 1;
    737       n_w32s -= 1;
    738       sum1 ^= sum2;
    739    }
    740    return sum1 + sum2;
    741 }
    742 
    743 /* Specialised versions of the above function */
    744 
    745 VEX_REGPARM(1)
    746 static UInt genericg_compute_checksum_4al_1 ( HWord first_w32 )
    747 {
    748    UInt  sum1 = 0, sum2 = 0;
    749    UInt* p = (UInt*)first_w32;
    750    UInt  w;
    751    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    752    sum1 ^= sum2;
    753    return sum1 + sum2;
    754 }
    755 
    756 VEX_REGPARM(1)
    757 static UInt genericg_compute_checksum_4al_2 ( HWord first_w32 )
    758 {
    759    UInt  sum1 = 0, sum2 = 0;
    760    UInt* p = (UInt*)first_w32;
    761    UInt  w;
    762    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    763    sum1 ^= sum2;
    764    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    765    sum1 ^= sum2;
    766    return sum1 + sum2;
    767 }
    768 
    769 VEX_REGPARM(1)
    770 static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 )
    771 {
    772    UInt  sum1 = 0, sum2 = 0;
    773    UInt* p = (UInt*)first_w32;
    774    UInt  w;
    775    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    776    sum1 ^= sum2;
    777    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    778    sum1 ^= sum2;
    779    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    780    sum1 ^= sum2;
    781    return sum1 + sum2;
    782 }
    783 
    784 VEX_REGPARM(1)
    785 static UInt genericg_compute_checksum_4al_4 ( HWord first_w32 )
    786 {
    787    UInt  sum1 = 0, sum2 = 0;
    788    UInt* p = (UInt*)first_w32;
    789    UInt  w;
    790    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    791    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    792    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    793    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    794    sum1 ^= sum2;
    795    return sum1 + sum2;
    796 }
    797 
    798 VEX_REGPARM(1)
    799 static UInt genericg_compute_checksum_4al_5 ( HWord first_w32 )
    800 {
    801    UInt  sum1 = 0, sum2 = 0;
    802    UInt* p = (UInt*)first_w32;
    803    UInt  w;
    804    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    805    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    806    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    807    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    808    sum1 ^= sum2;
    809    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    810    sum1 ^= sum2;
    811    return sum1 + sum2;
    812 }
    813 
    814 VEX_REGPARM(1)
    815 static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 )
    816 {
    817    UInt  sum1 = 0, sum2 = 0;
    818    UInt* p = (UInt*)first_w32;
    819    UInt  w;
    820    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    821    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    822    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    823    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    824    sum1 ^= sum2;
    825    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    826    sum1 ^= sum2;
    827    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    828    sum1 ^= sum2;
    829    return sum1 + sum2;
    830 }
    831 
    832 VEX_REGPARM(1)
    833 static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 )
    834 {
    835    UInt  sum1 = 0, sum2 = 0;
    836    UInt* p = (UInt*)first_w32;
    837    UInt  w;
    838    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    839    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    840    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    841    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    842    sum1 ^= sum2;
    843    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    844    sum1 ^= sum2;
    845    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    846    sum1 ^= sum2;
    847    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    848    sum1 ^= sum2;
    849    return sum1 + sum2;
    850 }
    851 
    852 VEX_REGPARM(1)
    853 static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 )
    854 {
    855    UInt  sum1 = 0, sum2 = 0;
    856    UInt* p = (UInt*)first_w32;
    857    UInt  w;
    858    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    859    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    860    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    861    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    862    sum1 ^= sum2;
    863    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    864    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    865    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    866    w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    867    sum1 ^= sum2;
    868    return sum1 + sum2;
    869 }
    870 
    871 VEX_REGPARM(1)
    872 static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 )
    873 {
    874    UInt  sum1 = 0, sum2 = 0;
    875    UInt* p = (UInt*)first_w32;
    876    UInt  w;
    877    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    878    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    879    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    880    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    881    sum1 ^= sum2;
    882    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    883    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    884    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    885    w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    886    sum1 ^= sum2;
    887    w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    888    sum1 ^= sum2;
    889    return sum1 + sum2;
    890 }
    891 
    892 VEX_REGPARM(1)
    893 static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 )
    894 {
    895    UInt  sum1 = 0, sum2 = 0;
    896    UInt* p = (UInt*)first_w32;
    897    UInt  w;
    898    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    899    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    900    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    901    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    902    sum1 ^= sum2;
    903    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    904    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    905    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    906    w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    907    sum1 ^= sum2;
    908    w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    909    sum1 ^= sum2;
    910    w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    911    sum1 ^= sum2;
    912    return sum1 + sum2;
    913 }
    914 
    915 VEX_REGPARM(1)
    916 static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 )
    917 {
    918    UInt  sum1 = 0, sum2 = 0;
    919    UInt* p = (UInt*)first_w32;
    920    UInt  w;
    921    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    922    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    923    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    924    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    925    sum1 ^= sum2;
    926    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    927    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    928    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    929    w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    930    sum1 ^= sum2;
    931    w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    932    sum1 ^= sum2;
    933    w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    934    sum1 ^= sum2;
    935    w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    936    sum1 ^= sum2;
    937    return sum1 + sum2;
    938 }
    939 
    940 VEX_REGPARM(1)
    941 static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 )
    942 {
    943    UInt  sum1 = 0, sum2 = 0;
    944    UInt* p = (UInt*)first_w32;
    945    UInt  w;
    946    w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    947    w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    948    w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    949    w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    950    sum1 ^= sum2;
    951    w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    952    w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    953    w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    954    w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    955    sum1 ^= sum2;
    956    w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    957    w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    958    w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    959    w = p[11]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
    960    sum1 ^= sum2;
    961    return sum1 + sum2;
    962 }
    963 
    964 
    965 /* --- 64-bit versions, used only on 64-bit hosts --- */
    966 
    967 static inline ULong ROL64 ( ULong w, Int n ) {
    968    w = (w << n) | (w >> (64-n));
    969    return w;
    970 }
    971 
    972 VEX_REGPARM(2)
    973 static ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s )
    974 {
    975    ULong  sum1 = 0, sum2 = 0;
    976    ULong* p = (ULong*)first_w64;
    977    /* unrolled */
    978    while (n_w64s >= 4) {
    979       ULong  w;
    980       w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
    981       w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
    982       w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
    983       w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
    984       p += 4;
    985       n_w64s -= 4;
    986       sum1 ^= sum2;
    987    }
    988    while (n_w64s >= 1) {
    989       ULong  w;
    990       w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
    991       p += 1;
    992       n_w64s -= 1;
    993       sum1 ^= sum2;
    994    }
    995    return sum1 + sum2;
    996 }
    997 
    998 /* Specialised versions of the above function */
    999 
   1000 VEX_REGPARM(1)
   1001 static ULong genericg_compute_checksum_8al_1 ( HWord first_w64 )
   1002 {
   1003    ULong  sum1 = 0, sum2 = 0;
   1004    ULong* p = (ULong*)first_w64;
   1005    ULong  w;
   1006    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1007    sum1 ^= sum2;
   1008    return sum1 + sum2;
   1009 }
   1010 
   1011 VEX_REGPARM(1)
   1012 static ULong genericg_compute_checksum_8al_2 ( HWord first_w64 )
   1013 {
   1014    ULong  sum1 = 0, sum2 = 0;
   1015    ULong* p = (ULong*)first_w64;
   1016    ULong  w;
   1017    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1018    sum1 ^= sum2;
   1019    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1020    sum1 ^= sum2;
   1021    return sum1 + sum2;
   1022 }
   1023 
   1024 VEX_REGPARM(1)
   1025 static ULong genericg_compute_checksum_8al_3 ( HWord first_w64 )
   1026 {
   1027    ULong  sum1 = 0, sum2 = 0;
   1028    ULong* p = (ULong*)first_w64;
   1029    ULong  w;
   1030    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1031    sum1 ^= sum2;
   1032    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1033    sum1 ^= sum2;
   1034    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1035    sum1 ^= sum2;
   1036    return sum1 + sum2;
   1037 }
   1038 
   1039 VEX_REGPARM(1)
   1040 static ULong genericg_compute_checksum_8al_4 ( HWord first_w64 )
   1041 {
   1042    ULong  sum1 = 0, sum2 = 0;
   1043    ULong* p = (ULong*)first_w64;
   1044    ULong  w;
   1045    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1046    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1047    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1048    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1049    sum1 ^= sum2;
   1050    return sum1 + sum2;
   1051 }
   1052 
   1053 VEX_REGPARM(1)
   1054 static ULong genericg_compute_checksum_8al_5 ( HWord first_w64 )
   1055 {
   1056    ULong  sum1 = 0, sum2 = 0;
   1057    ULong* p = (ULong*)first_w64;
   1058    ULong  w;
   1059    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1060    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1061    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1062    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1063    sum1 ^= sum2;
   1064    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1065    sum1 ^= sum2;
   1066    return sum1 + sum2;
   1067 }
   1068 
   1069 VEX_REGPARM(1)
   1070 static ULong genericg_compute_checksum_8al_6 ( HWord first_w64 )
   1071 {
   1072    ULong  sum1 = 0, sum2 = 0;
   1073    ULong* p = (ULong*)first_w64;
   1074    ULong  w;
   1075    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1076    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1077    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1078    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1079    sum1 ^= sum2;
   1080    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1081    sum1 ^= sum2;
   1082    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1083    sum1 ^= sum2;
   1084    return sum1 + sum2;
   1085 }
   1086 
   1087 VEX_REGPARM(1)
   1088 static ULong genericg_compute_checksum_8al_7 ( HWord first_w64 )
   1089 {
   1090    ULong  sum1 = 0, sum2 = 0;
   1091    ULong* p = (ULong*)first_w64;
   1092    ULong  w;
   1093    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1094    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1095    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1096    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1097    sum1 ^= sum2;
   1098    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1099    sum1 ^= sum2;
   1100    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1101    sum1 ^= sum2;
   1102    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1103    sum1 ^= sum2;
   1104    return sum1 + sum2;
   1105 }
   1106 
   1107 VEX_REGPARM(1)
   1108 static ULong genericg_compute_checksum_8al_8 ( HWord first_w64 )
   1109 {
   1110    ULong  sum1 = 0, sum2 = 0;
   1111    ULong* p = (ULong*)first_w64;
   1112    ULong  w;
   1113    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1114    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1115    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1116    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1117    sum1 ^= sum2;
   1118    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1119    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1120    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1121    w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1122    sum1 ^= sum2;
   1123    return sum1 + sum2;
   1124 }
   1125 
   1126 VEX_REGPARM(1)
   1127 static ULong genericg_compute_checksum_8al_9 ( HWord first_w64 )
   1128 {
   1129    ULong  sum1 = 0, sum2 = 0;
   1130    ULong* p = (ULong*)first_w64;
   1131    ULong  w;
   1132    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1133    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1134    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1135    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1136    sum1 ^= sum2;
   1137    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1138    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1139    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1140    w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1141    sum1 ^= sum2;
   1142    w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1143    sum1 ^= sum2;
   1144    return sum1 + sum2;
   1145 }
   1146 
   1147 VEX_REGPARM(1)
   1148 static ULong genericg_compute_checksum_8al_10 ( HWord first_w64 )
   1149 {
   1150    ULong  sum1 = 0, sum2 = 0;
   1151    ULong* p = (ULong*)first_w64;
   1152    ULong  w;
   1153    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1154    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1155    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1156    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1157    sum1 ^= sum2;
   1158    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1159    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1160    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1161    w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1162    sum1 ^= sum2;
   1163    w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1164    sum1 ^= sum2;
   1165    w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1166    sum1 ^= sum2;
   1167    return sum1 + sum2;
   1168 }
   1169 
   1170 VEX_REGPARM(1)
   1171 static ULong genericg_compute_checksum_8al_11 ( HWord first_w64 )
   1172 {
   1173    ULong  sum1 = 0, sum2 = 0;
   1174    ULong* p = (ULong*)first_w64;
   1175    ULong  w;
   1176    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1177    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1178    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1179    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1180    sum1 ^= sum2;
   1181    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1182    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1183    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1184    w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1185    sum1 ^= sum2;
   1186    w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1187    sum1 ^= sum2;
   1188    w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1189    sum1 ^= sum2;
   1190    w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1191    sum1 ^= sum2;
   1192    return sum1 + sum2;
   1193 }
   1194 
   1195 VEX_REGPARM(1)
   1196 static ULong genericg_compute_checksum_8al_12 ( HWord first_w64 )
   1197 {
   1198    ULong  sum1 = 0, sum2 = 0;
   1199    ULong* p = (ULong*)first_w64;
   1200    ULong  w;
   1201    w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1202    w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1203    w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1204    w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1205    sum1 ^= sum2;
   1206    w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1207    w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1208    w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1209    w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1210    sum1 ^= sum2;
   1211    w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1212    w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1213    w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1214    w = p[11]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
   1215    sum1 ^= sum2;
   1216    return sum1 + sum2;
   1217 }
   1218 
   1219 /*--------------------------------------------------------------------*/
   1220 /*--- end                                 guest_generic_bb_to_IR.c ---*/
   1221 /*--------------------------------------------------------------------*/
   1222