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