guest_generic_bb_to_IR.c revision 2f10aa6f4e9ea78030c46cce9b073b19c63c0f60
19e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
29e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin                               guest_generic_bb_to_IR.c ---*/
49e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
59e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
69e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
99e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
10752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Copyright (C) 2004-2010 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Neither the names of the U.S. Department of Energy nor the
319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   University of California nor the names of its contributors may be
329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   used to endorse or promote products derived from this software
339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   without prior written permission.
349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj*/
359e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
369e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex_basictypes.h"
379e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex_ir.h"
389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex.h"
39cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h"
40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h"
41cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h"
429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
44db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* Forwards .. */
4503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
469581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s );
4703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
489581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_1 ( HWord first_w32 );
4903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
509581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_2 ( HWord first_w32 );
5103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
529581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_3 ( HWord first_w32 );
5303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
549581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_4 ( HWord first_w32 );
5503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
569581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_5 ( HWord first_w32 );
5703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
589581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_6 ( HWord first_w32 );
5903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
609581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_7 ( HWord first_w32 );
6103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
629581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_8 ( HWord first_w32 );
6303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
649581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_9 ( HWord first_w32 );
6503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
669581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_10 ( HWord first_w32 );
6703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
689581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_11 ( HWord first_w32 );
6903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
709581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_12 ( HWord first_w32 );
71db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
7203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
73d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s );
7403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
75d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_1 ( HWord first_w64 );
7603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
77d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_2 ( HWord first_w64 );
7803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
79d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_3 ( HWord first_w64 );
8003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
81d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_4 ( HWord first_w64 );
8203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
83d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_5 ( HWord first_w64 );
8403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
85d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_6 ( HWord first_w64 );
8603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
87d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_7 ( HWord first_w64 );
8803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
89d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_8 ( HWord first_w64 );
9003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
91d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_9 ( HWord first_w64 );
9203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
93d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_10 ( HWord first_w64 );
9403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
95d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_11 ( HWord first_w64 );
9603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
97d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_12 ( HWord first_w64 );
98d6c17253ec35b2233840542eaf8339fa92062902sewardj
99ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj/* Small helpers */
100c716aea1cafe66ee431dc7d6909c98f18788a028sewardjstatic Bool const_False ( void* callback_opaque, Addr64 a ) {
101c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   return False;
102c716aea1cafe66ee431dc7d6909c98f18788a028sewardj}
103db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
104ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj/* Disassemble a complete basic block, starting at guest_IP_start,
105f6c8ebf1294fea43756683ba7089b746168abb8esewardj   returning a new IRSB.  The disassembler may chase across basic
1069e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   block boundaries if it wishes and if chase_into_ok allows it.
1079e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   The precise guest address ranges from which code has been taken
10836d982b5d1041d1348fc3100377f905d66dfb4d1cerion   are written into vge.  guest_IP_bbstart is taken to be the IP in
1099e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   the guest's address space corresponding to the instruction at
1109e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   &guest_code[0].
1119e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   dis_instr_fn is the arch-specific fn to disassemble on function; it
1139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   is this that does the real work.
114db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
115db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   do_self_check indicates that the caller needs a self-checking
116db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   translation.
117db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
118c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   preamble_function is a callback which allows the caller to add
119c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   its own IR preamble (following the self-check, if any).  May be
120f6c8ebf1294fea43756683ba7089b746168abb8esewardj   NULL.  If non-NULL, the IRSB under construction is handed to
121c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   this function, which presumably adds IR statements to it.  The
122c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callback may optionally complete the block and direct bb_to_IR
123c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   not to disassemble any instructions into it; this is indicated
124c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   by the callback returning True.
125c716aea1cafe66ee431dc7d6909c98f18788a028sewardj
126c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   offB_TIADDR and offB_TILEN are the offsets of guest_TIADDR and
127c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   guest_TILEN.  Since this routine has to work for any guest state,
128c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   without knowing what it is, those offsets have to passed in.
129c716aea1cafe66ee431dc7d6909c98f18788a028sewardj
130c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callback_opaque is a caller-supplied pointer to data which the
131c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callbacks may want to see.  Vex has no idea what it is.
132c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   (In fact it's a VgInstrumentClosure.)
133ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj*/
1349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
135dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardjIRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge,
136c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                 /*IN*/ void*            callback_opaque,
1379e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 /*IN*/ DisOneInstrFn    dis_instr_fn,
1389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 /*IN*/ UChar*           guest_code,
1399e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 /*IN*/ Addr64           guest_IP_bbstart,
140c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                 /*IN*/ Bool             (*chase_into_ok)(void*,Addr64),
1419e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 /*IN*/ Bool             host_bigendian,
142a5f55da7e956978fddad927436da5fab9568f3f1sewardj                 /*IN*/ VexArch          arch_guest,
1439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 /*IN*/ VexArchInfo*     archinfo_guest,
144dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                 /*IN*/ VexAbiInfo*      abiinfo_both,
145db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                 /*IN*/ IRType           guest_word_type,
146db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                 /*IN*/ Bool             do_self_check,
147dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                 /*IN*/ Bool             (*preamble_function)(void*,IRSB*),
148db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj                 /*IN*/ Int              offB_TISTART,
149c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                 /*IN*/ Int              offB_TILEN )
1509e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj{
1519e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Long       delta;
1529e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Int        i, n_instrs, first_stmt_idx;
1539e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Bool       resteerOK, need_to_put_IP, debug_print;
1549e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   DisResult  dres;
1559e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   IRStmt*    imark;
1569e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   static Int n_resteers = 0;
1579e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Int        d_resteers = 0;
158db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   Int        selfcheck_idx = 0;
159dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   IRSB*      irsb;
1609e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Addr64     guest_IP_curr_instr;
161ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   IRConst*   guest_IP_bbstart_IRConst = NULL;
162984d9b164dd17f07e603c41fe1e506e641e57d18sewardj   Int        n_cond_resteers_allowed = 2;
1639e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
164c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   Bool (*resteerOKfn)(void*,Addr64) = NULL;
1659e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1669e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   debug_print = toBool(vex_traceflags & VEX_TRACE_FE);
1679e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
168db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /* Note: for adler32 to work without % operation for the self
169db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      check, need to limit length of stuff it scans to 5552 bytes.
170db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      Therefore limiting the max bb len to 100 insns seems generously
171db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      conservative. */
172db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
1739e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* check sanity .. */
174db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   vassert(sizeof(HWord) == sizeof(void*));
1759e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_max_insns >= 1);
176db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   vassert(vex_control.guest_max_insns < 100);
1779e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_chase_thresh >= 0);
1789e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
1799e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(guest_word_type == Ity_I32 || guest_word_type == Ity_I64);
1809e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1819e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* Start a new, empty extent. */
1829e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->n_used  = 1;
1839e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->base[0] = guest_IP_bbstart;
1849e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->len[0]  = 0;
1859e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
186dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   /* And a new IR superblock to dump the result into. */
187dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   irsb = emptyIRSB();
1889e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1899e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* Delta keeps track of how far along the guest_code array we have
1909e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      so far gone. */
1919e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   delta    = 0;
1929e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   n_instrs = 0;
1939e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
194ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   /* Guest addresses as IRConsts.  Used in the two self-checks
195ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj      generated. */
196ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   if (do_self_check) {
197ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj      guest_IP_bbstart_IRConst
198ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj         = guest_word_type==Ity_I32
199ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj              ? IRConst_U32(toUInt(guest_IP_bbstart))
200ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj              : IRConst_U64(guest_IP_bbstart);
201ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   }
202ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj
203d6c17253ec35b2233840542eaf8339fa92062902sewardj   /* If asked to make a self-checking translation, leave 15 spaces in
204d6c17253ec35b2233840542eaf8339fa92062902sewardj      which to put the check statements (up to 3 extents, and 5 stmts
205d6c17253ec35b2233840542eaf8339fa92062902sewardj      required for each).  We'll fill them in later when we know the
206d6c17253ec35b2233840542eaf8339fa92062902sewardj      extents and checksums of the areas to check. */
207db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   if (do_self_check) {
208dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      selfcheck_idx = irsb->stmts_used;
209d6c17253ec35b2233840542eaf8339fa92062902sewardj      for (i = 0; i < 3 * 5; i++)
210d6c17253ec35b2233840542eaf8339fa92062902sewardj         addStmtToIRSB( irsb, IRStmt_NoOp() );
211db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   }
212db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
213c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   /* If the caller supplied a function to add its own preamble, use
214c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      it now. */
215c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   if (preamble_function) {
216dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      Bool stopNow = preamble_function( callback_opaque, irsb );
217c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      if (stopNow) {
218c716aea1cafe66ee431dc7d6909c98f18788a028sewardj         /* The callback has completed the IR block without any guest
219c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            insns being disassembled into it, so just return it at
220c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            this point, even if a self-check was requested - as there
221c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            is nothing to self-check.  The five self-check no-ops will
222c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            still be in place, but they are harmless. */
223dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         return irsb;
224c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      }
225ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   }
226ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj
227db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /* Process instructions. */
2289e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   while (True) {
2299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(n_instrs < vex_control.guest_max_insns);
2309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Regardless of what chase_into_ok says, is chasing permissible
2329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         at all right now?  Set resteerOKfn accordingly. */
2339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      resteerOK
2349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = toBool(
2359e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              n_instrs < vex_control.guest_chase_thresh
2369e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              /* we can't afford to have a resteer once we're on the
2379e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 last extent slot. */
2389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              && vge->n_used < 3
2399e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj           );
2409e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2419e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      resteerOKfn
2429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = resteerOK ? chase_into_ok : const_False;
2439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
244984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* n_cond_resteers_allowed keeps track of whether we're still
245984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         allowing dis_instr_fn to chase conditional branches.  It
246984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         starts (at 2) and gets decremented each time dis_instr_fn
247984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         tells us it has chased a conditional branch.  We then
248984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         decrement it, and use it to tell later calls to dis_instr_fn
249984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         whether or not it is allowed to chase conditional
250984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         branches. */
251984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      vassert(n_cond_resteers_allowed >= 0 && n_cond_resteers_allowed <= 2);
252984d9b164dd17f07e603c41fe1e506e641e57d18sewardj
2539e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* This is the IP of the instruction we're just about to deal
2549e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         with. */
2559e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      guest_IP_curr_instr = guest_IP_bbstart + delta;
2569e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
257dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      /* This is the irsb statement array index of the first stmt in
2589e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         this insn.  That will always be the instruction-mark
2599e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         descriptor. */
260dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      first_stmt_idx = irsb->stmts_used;
2619e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2629e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Add an instruction-mark statement.  We won't know until after
2639e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         disassembling the instruction how long it instruction is, so
2643176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         just put in a zero length and we'll fix it up later.
2653176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj
2663176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         On ARM, the least significant bit of the instr address
2673176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         distinguishes ARM vs Thumb instructions.  All instructions
2683176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         actually start on at least 2-aligned addresses.  So we need
2693176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         to ignore the bottom bit of the insn address when forming the
2702f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         IMark's address field, but put that bottom bit in the delta
2712f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         field, so that comparisons against guest_R15T for Thumb can
2722f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         be done correctly.  By inspecting the delta field,
2732f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         instruction processors can determine whether the instruction
2742f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         was originally Thumb or ARM.  For more details of this
2752f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         convention, see comments on definition of guest_R15T in
2762f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         libvex_guest_arm.h. */
2772f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj      if (arch_guest == VexArchARM && (guest_IP_curr_instr & (Addr64)1)) {
2782f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         /* Thumb insn => mask out the T bit, but put it in delta */
2792f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         addStmtToIRSB( irsb,
2802f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        IRStmt_IMark(guest_IP_curr_instr & ~(Addr64)1,
2812f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0, /* len */
2822f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     1  /* delta */
2832f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        )
2842f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         );
2852f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj      } else {
2862f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         /* All other targets: store IP as-is, and set delta to zero. */
2872f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         addStmtToIRSB( irsb,
2882f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        IRStmt_IMark(guest_IP_curr_instr,
2892f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0, /* len */
2902f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0  /* delta */
2912f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        )
2922f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         );
2932f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj      }
2949e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2959e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* for the first insn, the dispatch loop will have set
2969e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         %IP, but for all the others we have to do it ourselves. */
2979e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      need_to_put_IP = toBool(n_instrs > 0);
2989e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2999e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Finally, actually disassemble an instruction. */
300dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      dres = dis_instr_fn ( irsb,
3019e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            need_to_put_IP,
3029e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            resteerOKfn,
303984d9b164dd17f07e603c41fe1e506e641e57d18sewardj                            toBool(n_cond_resteers_allowed > 0),
304c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                            callback_opaque,
3059e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            guest_code,
3069e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            delta,
3079e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            guest_IP_curr_instr,
308a5f55da7e956978fddad927436da5fab9568f3f1sewardj                            arch_guest,
3099e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            archinfo_guest,
310dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                            abiinfo_both,
3119e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            host_bigendian );
3129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* stay sane ... */
3149e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(dres.whatNext == Dis_StopHere
3159e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              || dres.whatNext == Dis_Continue
316984d9b164dd17f07e603c41fe1e506e641e57d18sewardj              || dres.whatNext == Dis_ResteerU
317984d9b164dd17f07e603c41fe1e506e641e57d18sewardj              || dres.whatNext == Dis_ResteerC);
318984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... disassembled insn length is sane ... */
319ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj      vassert(dres.len >= 0 && dres.len <= 20);
320984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... continueAt is zero if no resteer requested ... */
321984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      if (dres.whatNext != Dis_ResteerU && dres.whatNext != Dis_ResteerC)
3229e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         vassert(dres.continueAt == 0);
323984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... if we disallowed conditional resteers, check that one
324984d9b164dd17f07e603c41fe1e506e641e57d18sewardj             didn't actually happen anyway ... */
325984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      if (n_cond_resteers_allowed == 0)
326984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         vassert(dres.whatNext != Dis_ResteerC);
3279e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3289e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Fill in the insn-mark length field. */
329dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
330dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      imark = irsb->stmts[first_stmt_idx];
3319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark);
3329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark->tag == Ist_IMark);
3339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark->Ist.IMark.len == 0);
3349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      imark->Ist.IMark.len = toUInt(dres.len);
3359e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3369e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Print the resulting IR, if needed. */
3379e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      if (vex_traceflags & VEX_TRACE_FE) {
338dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         for (i = first_stmt_idx; i < irsb->stmts_used; i++) {
3399e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("              ");
340dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            ppIRStmt(irsb->stmts[i]);
3419e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("\n");
3429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         }
3439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
3449e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3459e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* If dis_instr_fn terminated the BB at this point, check it
3465eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         also filled in the irsb->next field. */
3479e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      if (dres.whatNext == Dis_StopHere) {
348dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         vassert(irsb->next != NULL);
3499e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         if (debug_print) {
3509e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("              ");
3519e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf( "goto {");
352dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            ppIRJumpKind(irsb->jumpkind);
3539e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf( "} ");
354dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            ppIRExpr( irsb->next );
3559e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf( "\n");
3569e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         }
3579e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
3589e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3599e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Update the VexGuestExtents we are constructing. */
360db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      /* If vex_control.guest_max_insns is required to be < 100 and
3615eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         each insn is at max 20 bytes long, this limit of 5000 then
3625eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         seems reasonable since the max possible extent length will be
3635eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         100 * 20 == 2000. */
364db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      vassert(vge->len[vge->n_used-1] < 5000);
3659e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vge->len[vge->n_used-1]
3669e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = toUShort(toUInt( vge->len[vge->n_used-1] + dres.len ));
3679e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      n_instrs++;
3689e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      if (debug_print)
3699e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         vex_printf("\n");
3709e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3719e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Advance delta (inconspicuous but very important :-) */
3729e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      delta += (Long)dres.len;
3739e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3749e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      switch (dres.whatNext) {
3759e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         case Dis_Continue:
376dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            vassert(irsb->next == NULL);
3779e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            if (n_instrs < vex_control.guest_max_insns) {
3789e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj               /* keep going */
3799e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            } else {
3809e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj               /* We have to stop. */
381dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj               irsb->next
3829e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                  = IRExpr_Const(
3839e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                       guest_word_type == Ity_I32
3849e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                          ? IRConst_U32(toUInt(guest_IP_bbstart+delta))
3859e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                          : IRConst_U64(guest_IP_bbstart+delta)
3869e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                    );
387db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj               goto done;
3889e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            }
3899e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            break;
3909e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         case Dis_StopHere:
391dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            vassert(irsb->next != NULL);
392db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj            goto done;
393984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         case Dis_ResteerU:
394984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         case Dis_ResteerC:
3959e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* Check that we actually allowed a resteer .. */
3969e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vassert(resteerOK);
397dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            vassert(irsb->next == NULL);
398984d9b164dd17f07e603c41fe1e506e641e57d18sewardj            if (dres.whatNext == Dis_ResteerC) {
399984d9b164dd17f07e603c41fe1e506e641e57d18sewardj               vassert(n_cond_resteers_allowed > 0);
400984d9b164dd17f07e603c41fe1e506e641e57d18sewardj               n_cond_resteers_allowed--;
401984d9b164dd17f07e603c41fe1e506e641e57d18sewardj            }
4029e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* figure out a new delta to continue at. */
403c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            vassert(resteerOKfn(callback_opaque,dres.continueAt));
4049e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            delta = dres.continueAt - guest_IP_bbstart;
4059e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* we now have to start a new extent slot. */
40692b643609c5fa432b11fc726c2706ae3f3296eb4cerion            vge->n_used++;
40792b643609c5fa432b11fc726c2706ae3f3296eb4cerion            vassert(vge->n_used <= 3);
4089e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vge->base[vge->n_used-1] = dres.continueAt;
4099e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vge->len[vge->n_used-1] = 0;
4109e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            n_resteers++;
4119e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            d_resteers++;
4129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            if (0 && (n_resteers & 0xFF) == 0)
4139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("resteer[%d,%d] to 0x%llx (delta = %lld)\n",
4149e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                       n_resteers, d_resteers,
4159e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                       dres.continueAt, delta);
4169e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            break;
4179e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         default:
4189e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vpanic("bb_to_IR");
4199e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
4209e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   }
421db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /*NOTREACHED*/
422db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   vassert(0);
423db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
424db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  done:
425db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /* We're done.  The only thing that might need attending to is that
4269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      a self-checking preamble may need to be created.
4279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
4289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      The scheme is to compute a rather crude checksum of the code
4299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      we're making a translation of, and add to the IR a call to a
4309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      helper routine which recomputes the checksum every time the
4319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      translation is run, and requests a retranslation if it doesn't
4329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      match.  This is obviously very expensive and considerable
4339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      efforts are made to speed it up:
4349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
4359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      * the checksum is computed from all the 32-bit words that
4369581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        overlap the translated code.  That means it could depend on up
4379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        to 3 bytes before and 3 bytes after which aren't part of the
4389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        translated area, and so if those change then we'll
4399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        unnecessarily have to discard and retranslate.  This seems
4409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        like a pretty remote possibility and it seems as if the
4419581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        benefit of not having to deal with the ends of the range at
4429581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        byte precision far outweigh any possible extra translations
4439581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        needed.
4449581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
4459581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      * there's a generic routine and 12 specialised cases, which
4469581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        handle the cases of 1 through 12-word lengths respectively.
4479581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        They seem to cover about 90% of the cases that occur in
4489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        practice.
4499581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   */
450db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   if (do_self_check) {
451db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
452d6c17253ec35b2233840542eaf8339fa92062902sewardj      Addr64   base2check;
453d6c17253ec35b2233840542eaf8339fa92062902sewardj      UInt     len2check;
454d6c17253ec35b2233840542eaf8339fa92062902sewardj      HWord    expectedhW;
45516a403bac07df30df6e6587c8c911cf6df3f780dsewardj      IRTemp   tistart_tmp, tilen_tmp;
45603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj      HWord    VEX_REGPARM(2) (*fn_generic)(HWord, HWord);
45703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj      HWord    VEX_REGPARM(1) (*fn_spec)(HWord);
4589581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HChar*   nm_generic;
4599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HChar*   nm_spec;
4609581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HWord    fn_generic_entry = 0;
4619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HWord    fn_spec_entry = 0;
462d6c17253ec35b2233840542eaf8339fa92062902sewardj      UInt     host_word_szB = sizeof(HWord);
463d6c17253ec35b2233840542eaf8339fa92062902sewardj      IRType   host_word_type = Ity_INVALID;
464d6c17253ec35b2233840542eaf8339fa92062902sewardj
465d6c17253ec35b2233840542eaf8339fa92062902sewardj      if (host_word_szB == 4) host_word_type = Ity_I32;
466d6c17253ec35b2233840542eaf8339fa92062902sewardj      if (host_word_szB == 8) host_word_type = Ity_I64;
467d6c17253ec35b2233840542eaf8339fa92062902sewardj      vassert(host_word_type != Ity_INVALID);
468d6c17253ec35b2233840542eaf8339fa92062902sewardj
469d6c17253ec35b2233840542eaf8339fa92062902sewardj      vassert(vge->n_used >= 1 && vge->n_used <= 3);
470d6c17253ec35b2233840542eaf8339fa92062902sewardj      for (i = 0; i < vge->n_used; i++) {
471d6c17253ec35b2233840542eaf8339fa92062902sewardj
472d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* the extent we're generating a check for */
473d6c17253ec35b2233840542eaf8339fa92062902sewardj         base2check = vge->base[i];
474d6c17253ec35b2233840542eaf8339fa92062902sewardj         len2check  = vge->len[i];
475d6c17253ec35b2233840542eaf8339fa92062902sewardj
476d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* stay sane */
477d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
478d6c17253ec35b2233840542eaf8339fa92062902sewardj
479d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* Skip the check if the translation involved zero bytes */
480d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (len2check == 0)
481d6c17253ec35b2233840542eaf8339fa92062902sewardj            continue;
482d6c17253ec35b2233840542eaf8339fa92062902sewardj
483d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord first_hW = ((HWord)base2check)
484d6c17253ec35b2233840542eaf8339fa92062902sewardj                          & ~(HWord)(host_word_szB-1);
485d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord last_hW  = (((HWord)base2check) + len2check - 1)
486d6c17253ec35b2233840542eaf8339fa92062902sewardj                          & ~(HWord)(host_word_szB-1);
487d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(first_hW <= last_hW);
488d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord hW_diff = last_hW - first_hW;
489d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(0 == (hW_diff & (host_word_szB-1)));
490d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord hWs_to_check = (hW_diff + host_word_szB) / host_word_szB;
491d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(hWs_to_check > 0
492d6c17253ec35b2233840542eaf8339fa92062902sewardj                 && hWs_to_check < 1004/*arbitrary*/ / host_word_szB);
4939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
4949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* vex_printf("%lx %lx  %ld\n", first_w32, last_w32, w32s_to_check); */
4959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
496d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (host_word_szB == 8) {
49703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
498d6c17253ec35b2233840542eaf8339fa92062902sewardj                          genericg_compute_checksum_8al;
499d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_generic = "genericg_compute_checksum_8al";
500d6c17253ec35b2233840542eaf8339fa92062902sewardj         } else {
50103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
502d6c17253ec35b2233840542eaf8339fa92062902sewardj                          genericg_compute_checksum_4al;
503d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_generic = "genericg_compute_checksum_4al";
504d6c17253ec35b2233840542eaf8339fa92062902sewardj         }
505d6c17253ec35b2233840542eaf8339fa92062902sewardj
5069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         fn_spec = NULL;
5079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         nm_spec = NULL;
5089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
509d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (host_word_szB == 8) {
510d6c17253ec35b2233840542eaf8339fa92062902sewardj            HChar* nm = NULL;
51103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            ULong  VEX_REGPARM(1) (*fn)(HWord)  = NULL;
512d6c17253ec35b2233840542eaf8339fa92062902sewardj            switch (hWs_to_check) {
513d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 1:  fn =  genericg_compute_checksum_8al_1;
514d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_1"; break;
515d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 2:  fn =  genericg_compute_checksum_8al_2;
516d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_2"; break;
517d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 3:  fn =  genericg_compute_checksum_8al_3;
518d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_3"; break;
519d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 4:  fn =  genericg_compute_checksum_8al_4;
520d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_4"; break;
521d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 5:  fn =  genericg_compute_checksum_8al_5;
522d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_5"; break;
523d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 6:  fn =  genericg_compute_checksum_8al_6;
524d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_6"; break;
525d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 7:  fn =  genericg_compute_checksum_8al_7;
526d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_7"; break;
527d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 8:  fn =  genericg_compute_checksum_8al_8;
528d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_8"; break;
529d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 9:  fn =  genericg_compute_checksum_8al_9;
530d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_9"; break;
531d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 10: fn =  genericg_compute_checksum_8al_10;
532d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_10"; break;
533d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 11: fn =  genericg_compute_checksum_8al_11;
534d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_11"; break;
535d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 12: fn =  genericg_compute_checksum_8al_12;
536d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_12"; break;
537d6c17253ec35b2233840542eaf8339fa92062902sewardj               default: break;
538d6c17253ec35b2233840542eaf8339fa92062902sewardj            }
53903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord)) fn;
540d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_spec = nm;
541d6c17253ec35b2233840542eaf8339fa92062902sewardj         } else {
542d6c17253ec35b2233840542eaf8339fa92062902sewardj            HChar* nm = NULL;
54303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            UInt   VEX_REGPARM(1) (*fn)(HWord) = NULL;
544d6c17253ec35b2233840542eaf8339fa92062902sewardj            switch (hWs_to_check) {
545d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 1:  fn =  genericg_compute_checksum_4al_1;
546d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_1"; break;
547d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 2:  fn =  genericg_compute_checksum_4al_2;
548d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_2"; break;
549d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 3:  fn =  genericg_compute_checksum_4al_3;
550d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_3"; break;
551d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 4:  fn =  genericg_compute_checksum_4al_4;
552d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_4"; break;
553d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 5:  fn =  genericg_compute_checksum_4al_5;
554d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_5"; break;
555d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 6:  fn =  genericg_compute_checksum_4al_6;
556d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_6"; break;
557d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 7:  fn =  genericg_compute_checksum_4al_7;
558d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_7"; break;
559d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 8:  fn =  genericg_compute_checksum_4al_8;
560d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_8"; break;
561d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 9:  fn =  genericg_compute_checksum_4al_9;
562d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_9"; break;
563d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 10: fn =  genericg_compute_checksum_4al_10;
564d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_10"; break;
565d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 11: fn =  genericg_compute_checksum_4al_11;
566d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_11"; break;
567d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 12: fn =  genericg_compute_checksum_4al_12;
568d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_12"; break;
569d6c17253ec35b2233840542eaf8339fa92062902sewardj               default: break;
570d6c17253ec35b2233840542eaf8339fa92062902sewardj            }
57103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord))fn;
572d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_spec = nm;
5739581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
5745eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
575d6c17253ec35b2233840542eaf8339fa92062902sewardj         expectedhW = fn_generic( first_hW, hWs_to_check );
5769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* If we got a specialised version, check it produces the same
5779581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            result as the generic version! */
5789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (fn_spec) {
5799581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            vassert(nm_spec);
580d6c17253ec35b2233840542eaf8339fa92062902sewardj            vassert(expectedhW == fn_spec( first_hW ));
5819581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
5829581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            vassert(!nm_spec);
5839581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
5845eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
5859581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* Set TISTART and TILEN.  These will describe to the despatcher
5869581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            the area of guest code to invalidate should we exit with a
5879581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            self-check failure. */
5885eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
5899581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
5909581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         tilen_tmp   = newIRTemp(irsb->tyenv, guest_word_type);
5915eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
592d6c17253ec35b2233840542eaf8339fa92062902sewardj         IRConst* base2check_IRConst
593d6c17253ec35b2233840542eaf8339fa92062902sewardj            = guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
594d6c17253ec35b2233840542eaf8339fa92062902sewardj                                       : IRConst_U64(base2check);
595d6c17253ec35b2233840542eaf8339fa92062902sewardj         IRConst* len2check_IRConst
596d6c17253ec35b2233840542eaf8339fa92062902sewardj            = guest_word_type==Ity_I32 ? IRConst_U32(len2check)
597d6c17253ec35b2233840542eaf8339fa92062902sewardj                                       : IRConst_U64(len2check);
5985eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
599d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 0]
600d6c17253ec35b2233840542eaf8339fa92062902sewardj            = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
601d6c17253ec35b2233840542eaf8339fa92062902sewardj
602d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 1]
603d6c17253ec35b2233840542eaf8339fa92062902sewardj            = IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
6045eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
605d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 2]
6069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            = IRStmt_Put( offB_TISTART, IRExpr_RdTmp(tistart_tmp) );
6075eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
608d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 3]
6099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            = IRStmt_Put( offB_TILEN, IRExpr_RdTmp(tilen_tmp) );
6105eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
6119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* Generate the entry point descriptors */
6129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (abiinfo_both->host_ppc_calls_use_fndescrs) {
6139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            HWord* descr = (HWord*)fn_generic;
6149581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            fn_generic_entry = descr[0];
6159581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            if (fn_spec) {
6169581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               descr = (HWord*)fn_spec;
6179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = descr[0];
6189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            } else {
6199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)NULL;
6209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            }
6219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
6229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            fn_generic_entry = (HWord)fn_generic;
6239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            if (fn_spec) {
6249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)fn_spec;
6259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            } else {
6269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)NULL;
6279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            }
6289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
6299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
6309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         IRExpr* callexpr = NULL;
6319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (fn_spec) {
6329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            callexpr = mkIRExprCCall(
633d6c17253ec35b2233840542eaf8339fa92062902sewardj                          host_word_type, 1/*regparms*/,
6349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          nm_spec, (void*)fn_spec_entry,
6359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          mkIRExprVec_1(
636d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)first_hW )
6379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          )
6389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                       );
6399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
6409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            callexpr = mkIRExprCCall(
641d6c17253ec35b2233840542eaf8339fa92062902sewardj                          host_word_type, 2/*regparms*/,
6429581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          nm_generic, (void*)fn_generic_entry,
6439581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          mkIRExprVec_2(
644d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)first_hW ),
645d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)hWs_to_check )
6469581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          )
6479581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                       );
6489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
6495eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
650d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 4]
6519581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            = IRStmt_Exit(
6529581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                 IRExpr_Binop(
653d6c17253ec35b2233840542eaf8339fa92062902sewardj                    host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
6549581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                    callexpr,
655d6c17253ec35b2233840542eaf8339fa92062902sewardj                       host_word_type==Ity_I64
656d6c17253ec35b2233840542eaf8339fa92062902sewardj                          ? IRExpr_Const(IRConst_U64(expectedhW))
657d6c17253ec35b2233840542eaf8339fa92062902sewardj                          : IRExpr_Const(IRConst_U32(expectedhW))
6585eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj                 ),
6599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                 Ijk_TInval,
660d6c17253ec35b2233840542eaf8339fa92062902sewardj                 /* Where we must restart if there's a failure: at the
661d6c17253ec35b2233840542eaf8339fa92062902sewardj                    first extent, regardless of which extent the
662d6c17253ec35b2233840542eaf8339fa92062902sewardj                    failure actually happened in. */
6639581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                 guest_IP_bbstart_IRConst
6649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj              );
6659581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      }
666db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   }
667db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
668dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   return irsb;
6699e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj}
6709e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
6719e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
672db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/*-------------------------------------------------------------
673db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  A support routine for doing self-checking translations.
674db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  -------------------------------------------------------------*/
675db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
676db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* CLEAN HELPER */
677db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* CALLED FROM GENERATED CODE */
678db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
6795eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj/* Compute a checksum of host memory at [addr .. addr+len-1], as fast
680d6c17253ec35b2233840542eaf8339fa92062902sewardj   as possible.  All _4al versions assume that the supplied address is
681d6c17253ec35b2233840542eaf8339fa92062902sewardj   4 aligned.  All length values are in 4-byte chunks.  These fns
682d6c17253ec35b2233840542eaf8339fa92062902sewardj   arecalled once for every use of a self-checking translation, so
683d6c17253ec35b2233840542eaf8339fa92062902sewardj   they needs to be as fast as possible. */
684d6c17253ec35b2233840542eaf8339fa92062902sewardj
685d6c17253ec35b2233840542eaf8339fa92062902sewardj/* --- 32-bit versions, used only on 32-bit hosts --- */
6865eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
6875eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardjstatic inline UInt ROL32 ( UInt w, Int n ) {
6885eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   w = (w << n) | (w >> (32-n));
6895eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return w;
6905eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj}
6915eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
69203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
6939581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s )
694db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj{
6959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
6969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
6979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   /* unrolled */
6989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   while (n_w32s >= 4) {
6995eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      UInt  w;
7005eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7015eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7025eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7035eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      p += 4;
7059581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      n_w32s -= 4;
7065eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      sum1 ^= sum2;
7075eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   }
7089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   while (n_w32s >= 1) {
7099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      UInt  w;
7109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      p += 1;
7129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      n_w32s -= 1;
7135eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      sum1 ^= sum2;
714db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   }
7155eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return sum1 + sum2;
716db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj}
717db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
7189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj/* Specialised versions of the above function */
7199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
72003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7219581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_1 ( HWord first_w32 )
7225eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj{
7239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
7299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
7309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
73103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7329581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_2 ( HWord first_w32 )
7339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
7349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7369581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7419581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
7429581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
7439581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
74403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7459581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_3 ( HWord first_w32 )
7469581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
7479581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7499581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7509581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7519581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7529581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7539581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7549581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7559581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7569581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
7579581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
7589581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
75903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7609581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_4 ( HWord first_w32 )
7619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
7629581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7639581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7659581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7669581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7679581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7689581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7699581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7709581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
7719581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
7729581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
77303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7749581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_5 ( HWord first_w32 )
7759581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
7769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7779581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7799581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7809581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7819581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7829581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7839581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7849581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7859581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
7869581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
7879581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
7889581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
78903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
7909581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_6 ( HWord first_w32 )
7919581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
7929581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
7959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8009581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8019581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8059581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
80703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8089581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_7 ( HWord first_w32 )
8099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8149581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8159581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8169581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
82703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8289581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_8 ( HWord first_w32 )
8299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8369581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8419581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8429581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8439581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8449581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8459581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
84603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8479581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_9 ( HWord first_w32 )
8489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8499581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8509581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8519581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8529581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8539581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8549581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8559581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8569581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8579581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8589581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8609581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8629581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8639581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8659581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8669581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
86703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8689581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_10 ( HWord first_w32 )
8699581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8709581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8719581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8729581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8739581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8749581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8759581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8779581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8799581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8809581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8819581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8829581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8839581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8849581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8859581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8869581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8879581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8889581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8899581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
89003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8919581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_11 ( HWord first_w32 )
8929581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9009581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9019581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9059581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9149581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
91503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9169581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_12 ( HWord first_w32 )
9179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[11]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9365eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return sum1 + sum2;
9375eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj}
9389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
939d6c17253ec35b2233840542eaf8339fa92062902sewardj
940d6c17253ec35b2233840542eaf8339fa92062902sewardj/* --- 64-bit versions, used only on 64-bit hosts --- */
941d6c17253ec35b2233840542eaf8339fa92062902sewardj
942d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic inline ULong ROL64 ( ULong w, Int n ) {
943d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = (w << n) | (w >> (64-n));
944d6c17253ec35b2233840542eaf8339fa92062902sewardj   return w;
945d6c17253ec35b2233840542eaf8339fa92062902sewardj}
946d6c17253ec35b2233840542eaf8339fa92062902sewardj
94703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
948d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s )
949d6c17253ec35b2233840542eaf8339fa92062902sewardj{
950d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
951d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
952d6c17253ec35b2233840542eaf8339fa92062902sewardj   /* unrolled */
953d6c17253ec35b2233840542eaf8339fa92062902sewardj   while (n_w64s >= 4) {
954d6c17253ec35b2233840542eaf8339fa92062902sewardj      ULong  w;
955d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
956d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
957d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
958d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
959d6c17253ec35b2233840542eaf8339fa92062902sewardj      p += 4;
960d6c17253ec35b2233840542eaf8339fa92062902sewardj      n_w64s -= 4;
961d6c17253ec35b2233840542eaf8339fa92062902sewardj      sum1 ^= sum2;
962d6c17253ec35b2233840542eaf8339fa92062902sewardj   }
963d6c17253ec35b2233840542eaf8339fa92062902sewardj   while (n_w64s >= 1) {
964d6c17253ec35b2233840542eaf8339fa92062902sewardj      ULong  w;
965d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
966d6c17253ec35b2233840542eaf8339fa92062902sewardj      p += 1;
967d6c17253ec35b2233840542eaf8339fa92062902sewardj      n_w64s -= 1;
968d6c17253ec35b2233840542eaf8339fa92062902sewardj      sum1 ^= sum2;
969d6c17253ec35b2233840542eaf8339fa92062902sewardj   }
970d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
971d6c17253ec35b2233840542eaf8339fa92062902sewardj}
972d6c17253ec35b2233840542eaf8339fa92062902sewardj
973d6c17253ec35b2233840542eaf8339fa92062902sewardj/* Specialised versions of the above function */
974d6c17253ec35b2233840542eaf8339fa92062902sewardj
97503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
976d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_1 ( HWord first_w64 )
977d6c17253ec35b2233840542eaf8339fa92062902sewardj{
978d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
979d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
980d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
981d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
982d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
983d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
984d6c17253ec35b2233840542eaf8339fa92062902sewardj}
985d6c17253ec35b2233840542eaf8339fa92062902sewardj
98603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
987d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_2 ( HWord first_w64 )
988d6c17253ec35b2233840542eaf8339fa92062902sewardj{
989d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
990d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
991d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
992d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
993d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
994d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
995d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
996d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
997d6c17253ec35b2233840542eaf8339fa92062902sewardj}
998d6c17253ec35b2233840542eaf8339fa92062902sewardj
99903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1000d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_3 ( HWord first_w64 )
1001d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1002d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1003d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1004d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1005d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1006d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1007d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1008d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1009d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1010d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1011d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1012d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1013d6c17253ec35b2233840542eaf8339fa92062902sewardj
101403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1015d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_4 ( HWord first_w64 )
1016d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1017d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1018d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1019d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1020d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1021d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1022d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1023d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1024d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1025d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1026d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1027d6c17253ec35b2233840542eaf8339fa92062902sewardj
102803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1029d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_5 ( HWord first_w64 )
1030d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1031d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1032d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1033d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1034d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1035d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1036d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1037d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1038d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1039d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1040d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1041d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1042d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1043d6c17253ec35b2233840542eaf8339fa92062902sewardj
104403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1045d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_6 ( HWord first_w64 )
1046d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1047d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1048d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1049d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1050d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1051d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1052d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1053d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1054d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1055d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1056d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1057d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1058d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1059d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1060d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1061d6c17253ec35b2233840542eaf8339fa92062902sewardj
106203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1063d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_7 ( HWord first_w64 )
1064d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1065d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1066d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1067d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1068d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1069d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1070d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1071d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1072d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1073d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1074d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1075d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1076d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1077d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1078d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1079d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1080d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1081d6c17253ec35b2233840542eaf8339fa92062902sewardj
108203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1083d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_8 ( HWord first_w64 )
1084d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1085d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1086d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1087d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1088d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1089d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1090d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1091d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1092d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1093d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1094d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1095d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1096d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1097d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1098d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1099d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1100d6c17253ec35b2233840542eaf8339fa92062902sewardj
110103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1102d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_9 ( HWord first_w64 )
1103d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1104d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1105d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1106d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1107d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1108d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1109d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1110d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1111d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1112d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1113d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1114d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1115d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1116d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1117d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1118d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1119d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1120d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1121d6c17253ec35b2233840542eaf8339fa92062902sewardj
112203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1123d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_10 ( HWord first_w64 )
1124d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1125d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1126d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1127d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1128d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1129d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1130d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1131d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1132d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1133d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1134d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1135d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1136d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1137d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1138d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1139d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1140d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1141d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1142d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1143d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1144d6c17253ec35b2233840542eaf8339fa92062902sewardj
114503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1146d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_11 ( HWord first_w64 )
1147d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1148d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1149d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1150d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1151d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1152d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1153d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1154d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1155d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1156d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1157d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1158d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1159d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1160d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1161d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1162d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1163d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1164d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1165d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1166d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1167d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1168d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1169d6c17253ec35b2233840542eaf8339fa92062902sewardj
117003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1171d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_12 ( HWord first_w64 )
1172d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1173d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1174d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1175d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1176d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1177d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1178d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1179d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1180d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1181d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1182d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1183d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1184d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1185d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1186d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1187d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1188d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1189d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[11]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1190d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1191d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1192d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1193d6c17253ec35b2233840542eaf8339fa92062902sewardj
11949e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
1195cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                 guest_generic_bb_to_IR.c ---*/
11969e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
1197