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
10663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Copyright (C) 2004-2012 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
143663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng/* Regarding IP updating.  dis_instr_fn (that does the guest specific
144663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   work of disassembling an individual instruction) must finish the
145663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   resulting IR with "PUT(guest_IP) = ".  Hence in all cases it must
146663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   state the next instruction address.
147663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
148663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   If the block is to be ended at that point, then this routine
149663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   (bb_to_IR) will set up the next/jumpkind/offsIP fields so as to
150663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   make a transfer (of the right kind) to "GET(guest_IP)".  Hence if
151663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   dis_instr_fn generates incorrect IP updates we will see it
152663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   immediately (due to jumping to the wrong next guest address).
153663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
154663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   However it is also necessary to set this up so it can be optimised
155663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   nicely.  The IRSB exit is defined to update the guest IP, so that
156663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   chaining works -- since the chain_me stubs expect the chain-to
157663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   address to be in the guest state.  Hence what the IRSB next fields
158663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   will contain initially is (implicitly)
159663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
160663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PUT(guest_IP) [implicitly] = GET(guest_IP) [explicit expr on ::next]
161663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
162663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   which looks pretty strange at first.  Eg so unconditional branch
163663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   to some address 0x123456 looks like this:
164663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
165663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PUT(guest_IP) = 0x123456;  // dis_instr_fn generates this
166663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // the exit
167663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PUT(guest_IP) [implicitly] = GET(guest_IP); exit-Boring
168663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
169663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   after redundant-GET and -PUT removal by iropt, we get what we want:
170663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
171663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   // the exit
172663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   PUT(guest_IP) [implicitly] = 0x123456; exit-Boring
173663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
174663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   This makes the IRSB-end case the same as the side-exit case: update
175663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   IP, then transfer.  There is no redundancy of representation for
176663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   the destination, and we use the destination specified by
177663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   dis_instr_fn, so any errors it makes show up sooner.
178663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng*/
179663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovIRSB* bb_to_IR (
181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*OUT*/VexGuestExtents* vge,
182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*OUT*/UInt*            n_sc_extents,
183663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /*OUT*/UInt*            n_guest_instrs, /* stats only */
184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ void*            callback_opaque,
185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ DisOneInstrFn    dis_instr_fn,
186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ UChar*           guest_code,
187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ Addr64           guest_IP_bbstart,
188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ Bool             (*chase_into_ok)(void*,Addr64),
189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ Bool             host_bigendian,
190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ VexArch          arch_guest,
191b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ VexArchInfo*     archinfo_guest,
192b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ VexAbiInfo*      abiinfo_both,
193b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ IRType           guest_word_type,
194b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ UInt             (*needs_self_check)(void*,VexGuestExtents*),
195b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /*IN*/ Bool             (*preamble_function)(void*,IRSB*),
196663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /*IN*/ Int              offB_GUEST_TISTART,
197663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /*IN*/ Int              offB_GUEST_TILEN,
198663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /*IN*/ Int              offB_GUEST_IP,
199663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         /*IN*/ Int              szB_GUEST_IP
200b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      )
201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Long       delta;
203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int        i, n_instrs, first_stmt_idx;
204663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   Bool       resteerOK, debug_print;
205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   DisResult  dres;
206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRStmt*    imark;
207b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   IRStmt*    nop;
208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   static Int n_resteers = 0;
209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int        d_resteers = 0;
210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int        selfcheck_idx = 0;
211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRSB*      irsb;
212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Addr64     guest_IP_curr_instr;
213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   IRConst*   guest_IP_bbstart_IRConst = NULL;
214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Int        n_cond_resteers_allowed = 2;
215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   Bool (*resteerOKfn)(void*,Addr64) = NULL;
217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
218ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   debug_print = toBool(vex_traceflags & VEX_TRACE_FE);
219ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
220ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* check sanity .. */
221ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(sizeof(HWord) == sizeof(void*));
222ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vex_control.guest_max_insns >= 1);
223ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vex_control.guest_max_insns < 100);
224ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vex_control.guest_chase_thresh >= 0);
225ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
226ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(guest_word_type == Ity_I32 || guest_word_type == Ity_I64);
227ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
228663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (guest_word_type == Ity_I32) {
229663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(szB_GUEST_IP == 4);
230663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert((offB_GUEST_IP % 4) == 0);
231663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   } else {
232663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(szB_GUEST_IP == 8);
233663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert((offB_GUEST_IP % 8) == 0);
234663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
235663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
236ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Start a new, empty extent. */
237ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vge->n_used  = 1;
238ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vge->base[0] = guest_IP_bbstart;
239ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vge->len[0]  = 0;
240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   *n_sc_extents = 0;
241ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
242ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* And a new IR superblock to dump the result into. */
243ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   irsb = emptyIRSB();
244ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
245ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Delta keeps track of how far along the guest_code array we have
246ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      so far gone. */
247ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   delta    = 0;
248ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   n_instrs = 0;
249663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   *n_guest_instrs = 0;
250ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Guest addresses as IRConsts.  Used in self-checks to specify the
252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      restart-after-discard point. */
253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   guest_IP_bbstart_IRConst
254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      = guest_word_type==Ity_I32
255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           ? IRConst_U32(toUInt(guest_IP_bbstart))
256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov           : IRConst_U64(guest_IP_bbstart);
257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* Leave 15 spaces in which to put the check statements for a self
259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      checking translation (up to 3 extents, and 5 stmts required for
260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      each).  We won't know until later the extents and checksums of
261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      the areas, if any, that need to be checked. */
262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   nop = IRStmt_NoOp();
263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   selfcheck_idx = irsb->stmts_used;
264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   for (i = 0; i < 3 * 5; i++)
265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      addStmtToIRSB( irsb, nop );
266ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
267ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* If the caller supplied a function to add its own preamble, use
268ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      it now. */
269ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   if (preamble_function) {
270ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      Bool stopNow = preamble_function( callback_opaque, irsb );
271ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (stopNow) {
272ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* The callback has completed the IR block without any guest
273ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            insns being disassembled into it, so just return it at
274ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            this point, even if a self-check was requested - as there
275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            is nothing to self-check.  The 15 self-check no-ops will
276ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            still be in place, but they are harmless. */
277ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         return irsb;
278ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
279ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
280ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
281ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* Process instructions. */
282ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (True) {
283ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(n_instrs < vex_control.guest_max_insns);
284ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
285ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Regardless of what chase_into_ok says, is chasing permissible
286ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         at all right now?  Set resteerOKfn accordingly. */
287ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      resteerOK
288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = toBool(
289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              n_instrs < vex_control.guest_chase_thresh
290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              /* we can't afford to have a resteer once we're on the
291ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 last extent slot. */
292ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              && vge->n_used < 3
293ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown           );
294ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
295ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      resteerOKfn
296ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = resteerOK ? chase_into_ok : const_False;
297ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
298ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* n_cond_resteers_allowed keeps track of whether we're still
299ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         allowing dis_instr_fn to chase conditional branches.  It
300ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         starts (at 2) and gets decremented each time dis_instr_fn
301ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tells us it has chased a conditional branch.  We then
302ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         decrement it, and use it to tell later calls to dis_instr_fn
303ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         whether or not it is allowed to chase conditional
304ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         branches. */
305ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(n_cond_resteers_allowed >= 0 && n_cond_resteers_allowed <= 2);
306ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
307ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This is the IP of the instruction we're just about to deal
308ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         with. */
309ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      guest_IP_curr_instr = guest_IP_bbstart + delta;
310ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
311ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* This is the irsb statement array index of the first stmt in
312ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         this insn.  That will always be the instruction-mark
313ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         descriptor. */
314ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      first_stmt_idx = irsb->stmts_used;
315ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
316ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Add an instruction-mark statement.  We won't know until after
317ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         disassembling the instruction how long it instruction is, so
318b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         just put in a zero length and we'll fix it up later.
319b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
320b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         On ARM, the least significant bit of the instr address
321b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         distinguishes ARM vs Thumb instructions.  All instructions
322b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         actually start on at least 2-aligned addresses.  So we need
323b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         to ignore the bottom bit of the insn address when forming the
324b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         IMark's address field, but put that bottom bit in the delta
325b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         field, so that comparisons against guest_R15T for Thumb can
326b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         be done correctly.  By inspecting the delta field,
327b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         instruction processors can determine whether the instruction
328b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         was originally Thumb or ARM.  For more details of this
329b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         convention, see comments on definition of guest_R15T in
330b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         libvex_guest_arm.h. */
331b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (arch_guest == VexArchARM && (guest_IP_curr_instr & (Addr64)1)) {
332b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Thumb insn => mask out the T bit, but put it in delta */
333b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addStmtToIRSB( irsb,
334b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        IRStmt_IMark(guest_IP_curr_instr & ~(Addr64)1,
335b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                     0, /* len */
336b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                     1  /* delta */
337b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        )
338b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         );
339b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } else {
340b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* All other targets: store IP as-is, and set delta to zero. */
341b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         addStmtToIRSB( irsb,
342b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        IRStmt_IMark(guest_IP_curr_instr,
343b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                     0, /* len */
344b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                     0  /* delta */
345b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        )
346b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         );
347b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      }
348ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
349663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      if (debug_print && n_instrs > 0)
350663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         vex_printf("\n");
351ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
352ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Finally, actually disassemble an instruction. */
353663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(irsb->next == NULL);
354ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      dres = dis_instr_fn ( irsb,
355ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            resteerOKfn,
356ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            toBool(n_cond_resteers_allowed > 0),
357ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            callback_opaque,
358ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            guest_code,
359ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            delta,
360ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            guest_IP_curr_instr,
361ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            arch_guest,
362ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            archinfo_guest,
363ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            abiinfo_both,
364ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                            host_bigendian );
365ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
366ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* stay sane ... */
367ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(dres.whatNext == Dis_StopHere
368ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              || dres.whatNext == Dis_Continue
369ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              || dres.whatNext == Dis_ResteerU
370ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              || dres.whatNext == Dis_ResteerC);
371ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... disassembled insn length is sane ... */
372ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(dres.len >= 0 && dres.len <= 20);
373ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... continueAt is zero if no resteer requested ... */
374ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (dres.whatNext != Dis_ResteerU && dres.whatNext != Dis_ResteerC)
375ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(dres.continueAt == 0);
376ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* ... if we disallowed conditional resteers, check that one
377ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown             didn't actually happen anyway ... */
378ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (n_cond_resteers_allowed == 0)
379ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         vassert(dres.whatNext != Dis_ResteerC);
380ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
381ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Fill in the insn-mark length field. */
382ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
383ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      imark = irsb->stmts[first_stmt_idx];
384ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(imark);
385ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(imark->tag == Ist_IMark);
386ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(imark->Ist.IMark.len == 0);
387ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      imark->Ist.IMark.len = toUInt(dres.len);
388ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
389ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Print the resulting IR, if needed. */
390ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      if (vex_traceflags & VEX_TRACE_FE) {
391ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         for (i = first_stmt_idx; i < irsb->stmts_used; i++) {
392ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("              ");
393ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            ppIRStmt(irsb->stmts[i]);
394ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("\n");
395ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
396ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
397ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
398663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Individual insn disassembly may not mess with irsb->next.
399663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         This function is the only place where it can be set. */
400663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(irsb->next == NULL);
401663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(irsb->jumpkind == Ijk_Boring);
402663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(irsb->offsIP == 0);
403663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
404663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* Individual insn disassembly must finish the IR for each
405663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng         instruction with an assignment to the guest PC. */
406663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vassert(first_stmt_idx < irsb->stmts_used);
407663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      /* it follows that irsb->stmts_used must be > 0 */
408663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      { IRStmt* st = irsb->stmts[irsb->stmts_used-1];
409663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        vassert(st);
410663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        vassert(st->tag == Ist_Put);
411663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        vassert(st->Ist.Put.offset == offB_GUEST_IP);
412663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng        /* Really we should also check that the type of the Put'd data
413663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng           == guest_word_type, but that's a bit expensive. */
414ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
415ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
416ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Update the VexGuestExtents we are constructing. */
417ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* If vex_control.guest_max_insns is required to be < 100 and
418ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         each insn is at max 20 bytes long, this limit of 5000 then
419ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         seems reasonable since the max possible extent length will be
420ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         100 * 20 == 2000. */
421ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vassert(vge->len[vge->n_used-1] < 5000);
422ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      vge->len[vge->n_used-1]
423ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         = toUShort(toUInt( vge->len[vge->n_used-1] + dres.len ));
424ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n_instrs++;
425ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
426ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      /* Advance delta (inconspicuous but very important :-) */
427ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      delta += (Long)dres.len;
428ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
429ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      switch (dres.whatNext) {
430ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case Dis_Continue:
431663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(dres.continueAt == 0);
432663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(dres.jk_StopHere == Ijk_INVALID);
433ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (n_instrs < vex_control.guest_max_insns) {
434ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               /* keep going */
435ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
436663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               /* We have to stop.  See comment above re irsb field
437663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                  settings here. */
438663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               irsb->next = IRExpr_Get(offB_GUEST_IP, guest_word_type);
439663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               /* irsb->jumpkind must already by Ijk_Boring */
440663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng               irsb->offsIP = offB_GUEST_IP;
441ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               goto done;
442ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
443ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            break;
444ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case Dis_StopHere:
445663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(dres.continueAt == 0);
446663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            vassert(dres.jk_StopHere != Ijk_INVALID);
447663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            /* See comment above re irsb field settings here. */
448663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            irsb->next = IRExpr_Get(offB_GUEST_IP, guest_word_type);
449663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            irsb->jumpkind = dres.jk_StopHere;
450663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            irsb->offsIP = offB_GUEST_IP;
451ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            goto done;
452663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
453ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case Dis_ResteerU:
454ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         case Dis_ResteerC:
455ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* Check that we actually allowed a resteer .. */
456ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(resteerOK);
457ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (dres.whatNext == Dis_ResteerC) {
458ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               vassert(n_cond_resteers_allowed > 0);
459ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               n_cond_resteers_allowed--;
460ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
461ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* figure out a new delta to continue at. */
462ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(resteerOKfn(callback_opaque,dres.continueAt));
463ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            delta = dres.continueAt - guest_IP_bbstart;
464ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            /* we now have to start a new extent slot. */
465ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vge->n_used++;
466ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(vge->n_used <= 3);
467ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vge->base[vge->n_used-1] = dres.continueAt;
468ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vge->len[vge->n_used-1] = 0;
469ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            n_resteers++;
470ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            d_resteers++;
471ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (0 && (n_resteers & 0xFF) == 0)
472ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vex_printf("resteer[%d,%d] to 0x%llx (delta = %lld)\n",
473ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       n_resteers, d_resteers,
474ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       dres.continueAt, delta);
475ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            break;
476ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         default:
477ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vpanic("bb_to_IR");
478ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      }
479ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
480ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /*NOTREACHED*/
481ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   vassert(0);
482ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
483ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  done:
484ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* We're done.  The only thing that might need attending to is that
485b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      a self-checking preamble may need to be created.  If so it gets
486b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      placed in the 15 slots reserved above.
487ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
488ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      The scheme is to compute a rather crude checksum of the code
489ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      we're making a translation of, and add to the IR a call to a
490ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      helper routine which recomputes the checksum every time the
491ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      translation is run, and requests a retranslation if it doesn't
492ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      match.  This is obviously very expensive and considerable
493ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      efforts are made to speed it up:
494ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
495b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      * the checksum is computed from all the naturally aligned
496b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        host-sized words that overlap the translated code.  That means
497b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        it could depend on up to 7 bytes before and 7 bytes after
498b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        which aren't part of the translated area, and so if those
499b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        change then we'll unnecessarily have to discard and
500b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        retranslate.  This seems like a pretty remote possibility and
501b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        it seems as if the benefit of not having to deal with the ends
502b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        of the range at byte precision far outweigh any possible extra
503b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov        translations needed.
504ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
505ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      * there's a generic routine and 12 specialised cases, which
506ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        handle the cases of 1 through 12-word lengths respectively.
507ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        They seem to cover about 90% of the cases that occur in
508ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown        practice.
5099bea4c13fca0e3bb4b719dcb3ed63d47d479294eKenny Root
510b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      We ask the caller, via needs_self_check, which of the 3 vge
511b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      extents needs a check, and only generate check code for those
512b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      that do.
513b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   */
514b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   {
515b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      Addr64   base2check;
516b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt     len2check;
517b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      HWord    expectedhW;
518ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      IRTemp   tistart_tmp, tilen_tmp;
519b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      HWord    VEX_REGPARM(2) (*fn_generic)(HWord, HWord);
520b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      HWord    VEX_REGPARM(1) (*fn_spec)(HWord);
521ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HChar*   nm_generic;
522ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HChar*   nm_spec;
523ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HWord    fn_generic_entry = 0;
524ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      HWord    fn_spec_entry = 0;
525b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt     host_word_szB = sizeof(HWord);
526b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      IRType   host_word_type = Ity_INVALID;
527b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
528b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      VexGuestExtents vge_tmp = *vge;
529b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      UInt extents_needing_check
530b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         = needs_self_check(callback_opaque, &vge_tmp);
531b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
532b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (host_word_szB == 4) host_word_type = Ity_I32;
533b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      if (host_word_szB == 8) host_word_type = Ity_I64;
534b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      vassert(host_word_type != Ity_INVALID);
535b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
536b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      vassert(vge->n_used >= 1 && vge->n_used <= 3);
537b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
538b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      /* Caller shouldn't claim that nonexistent extents need a
539b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         check. */
540b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      vassert((extents_needing_check >> vge->n_used) == 0);
541b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
542b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      for (i = 0; i < vge->n_used; i++) {
543b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
544b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Do we need to generate a check for this extent? */
545b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if ((extents_needing_check & (1 << i)) == 0)
546b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            continue;
547b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
548b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Tell the caller */
549b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         (*n_sc_extents)++;
550ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
551b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* the extent we're generating a check for */
552b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         base2check = vge->base[i];
553b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         len2check  = vge->len[i];
554ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
555b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* stay sane */
556b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
557ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
558b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* Skip the check if the translation involved zero bytes */
559b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (len2check == 0)
560b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            continue;
561ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
562b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         HWord first_hW = ((HWord)base2check)
563b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          & ~(HWord)(host_word_szB-1);
564b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         HWord last_hW  = (((HWord)base2check) + len2check - 1)
565b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          & ~(HWord)(host_word_szB-1);
566b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(first_hW <= last_hW);
567b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         HWord hW_diff = last_hW - first_hW;
568b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(0 == (hW_diff & (host_word_szB-1)));
569b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         HWord hWs_to_check = (hW_diff + host_word_szB) / host_word_szB;
570b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         vassert(hWs_to_check > 0
571b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 && hWs_to_check < 1004/*arbitrary*/ / host_word_szB);
572b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
573b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         /* vex_printf("%lx %lx  %ld\n", first_hW, last_hW, hWs_to_check); */
574b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
575b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (host_word_szB == 8) {
576b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
577b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          genericg_compute_checksum_8al;
578b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            nm_generic = "genericg_compute_checksum_8al";
579b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
580b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
581b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          genericg_compute_checksum_4al;
582b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            nm_generic = "genericg_compute_checksum_4al";
583b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         }
584ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
585ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         fn_spec = NULL;
586ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         nm_spec = NULL;
587ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
588b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         if (host_word_szB == 8) {
589b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            HChar* nm = NULL;
590b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            ULong  VEX_REGPARM(1) (*fn)(HWord)  = NULL;
591b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            switch (hWs_to_check) {
592b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 1:  fn =  genericg_compute_checksum_8al_1;
593b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_1"; break;
594b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 2:  fn =  genericg_compute_checksum_8al_2;
595b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_2"; break;
596b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 3:  fn =  genericg_compute_checksum_8al_3;
597b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_3"; break;
598b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 4:  fn =  genericg_compute_checksum_8al_4;
599b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_4"; break;
600b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 5:  fn =  genericg_compute_checksum_8al_5;
601b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_5"; break;
602b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 6:  fn =  genericg_compute_checksum_8al_6;
603b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_6"; break;
604b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 7:  fn =  genericg_compute_checksum_8al_7;
605b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_7"; break;
606b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 8:  fn =  genericg_compute_checksum_8al_8;
607b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_8"; break;
608b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 9:  fn =  genericg_compute_checksum_8al_9;
609b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_9"; break;
610b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 10: fn =  genericg_compute_checksum_8al_10;
611b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_10"; break;
612b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 11: fn =  genericg_compute_checksum_8al_11;
613b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_11"; break;
614b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 12: fn =  genericg_compute_checksum_8al_12;
615b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_8al_12"; break;
616b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               default: break;
617b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
618b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord)) fn;
619b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            nm_spec = nm;
620b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         } else {
621b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            HChar* nm = NULL;
622b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            UInt   VEX_REGPARM(1) (*fn)(HWord) = NULL;
623b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            switch (hWs_to_check) {
624b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 1:  fn =  genericg_compute_checksum_4al_1;
625b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_1"; break;
626b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 2:  fn =  genericg_compute_checksum_4al_2;
627b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_2"; break;
628b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 3:  fn =  genericg_compute_checksum_4al_3;
629b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_3"; break;
630b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 4:  fn =  genericg_compute_checksum_4al_4;
631b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_4"; break;
632b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 5:  fn =  genericg_compute_checksum_4al_5;
633b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_5"; break;
634b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 6:  fn =  genericg_compute_checksum_4al_6;
635b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_6"; break;
636b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 7:  fn =  genericg_compute_checksum_4al_7;
637b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_7"; break;
638b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 8:  fn =  genericg_compute_checksum_4al_8;
639b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_8"; break;
640b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 9:  fn =  genericg_compute_checksum_4al_9;
641b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_9"; break;
642b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 10: fn =  genericg_compute_checksum_4al_10;
643b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_10"; break;
644b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 11: fn =  genericg_compute_checksum_4al_11;
645b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_11"; break;
646b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               case 12: fn =  genericg_compute_checksum_4al_12;
647b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                        nm = "genericg_compute_checksum_4al_12"; break;
648b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov               default: break;
649b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            }
650b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord))fn;
651b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            nm_spec = nm;
652ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
653ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
654b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         expectedhW = fn_generic( first_hW, hWs_to_check );
655ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* If we got a specialised version, check it produces the same
656ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            result as the generic version! */
657ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (fn_spec) {
658ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(nm_spec);
659b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            vassert(expectedhW == fn_spec( first_hW ));
660ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
661ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            vassert(!nm_spec);
662ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
663ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
664ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Set TISTART and TILEN.  These will describe to the despatcher
665ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            the area of guest code to invalidate should we exit with a
666ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            self-check failure. */
667ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
668ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
669ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         tilen_tmp   = newIRTemp(irsb->tyenv, guest_word_type);
670ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
671b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         IRConst* base2check_IRConst
672b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            = guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
673b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                       : IRConst_U64(base2check);
674b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         IRConst* len2check_IRConst
675b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            = guest_word_type==Ity_I32 ? IRConst_U32(len2check)
676b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                                       : IRConst_U64(len2check);
677ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
678b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         irsb->stmts[selfcheck_idx + i * 5 + 0]
679b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
6808f943afc22a6a683b78271836c8ddc462b4824a9Evgeniy Stepanov
681b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         irsb->stmts[selfcheck_idx + i * 5 + 1]
682b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov            = IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
683b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
684b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         irsb->stmts[selfcheck_idx + i * 5 + 2]
685663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            = IRStmt_Put( offB_GUEST_TISTART, IRExpr_RdTmp(tistart_tmp) );
686ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
687b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         irsb->stmts[selfcheck_idx + i * 5 + 3]
688663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng            = IRStmt_Put( offB_GUEST_TILEN, IRExpr_RdTmp(tilen_tmp) );
689ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
690ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         /* Generate the entry point descriptors */
691ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (abiinfo_both->host_ppc_calls_use_fndescrs) {
692ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            HWord* descr = (HWord*)fn_generic;
693ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fn_generic_entry = descr[0];
694ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (fn_spec) {
695ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               descr = (HWord*)fn_spec;
696ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn_spec_entry = descr[0];
697ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
698ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn_spec_entry = (HWord)NULL;
699ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
700ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
701ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            fn_generic_entry = (HWord)fn_generic;
702ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            if (fn_spec) {
703ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn_spec_entry = (HWord)fn_spec;
704ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            } else {
705ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown               fn_spec_entry = (HWord)NULL;
706ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            }
707ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
708ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
709ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         IRExpr* callexpr = NULL;
710ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         if (fn_spec) {
711ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            callexpr = mkIRExprCCall(
712b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          host_word_type, 1/*regparms*/,
713ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          nm_spec, (void*)fn_spec_entry,
714ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          mkIRExprVec_1(
715b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                             mkIRExpr_HWord( (HWord)first_hW )
716ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          )
717ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       );
718ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         } else {
719ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            callexpr = mkIRExprCCall(
720b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          host_word_type, 2/*regparms*/,
721ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          nm_generic, (void*)fn_generic_entry,
722ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          mkIRExprVec_2(
723b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                             mkIRExpr_HWord( (HWord)first_hW ),
724b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                             mkIRExpr_HWord( (HWord)hWs_to_check )
725ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                          )
726ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                       );
727ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown         }
728ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
729b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov         irsb->stmts[selfcheck_idx + i * 5 + 4]
730ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            = IRStmt_Exit(
731ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 IRExpr_Binop(
732b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
733ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                    callexpr,
734b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                       host_word_type==Ity_I64
735b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          ? IRExpr_Const(IRConst_U64(expectedhW))
736b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                          : IRExpr_Const(IRConst_U32(expectedhW))
737ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 ),
738ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown                 Ijk_TInval,
739b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                 /* Where we must restart if there's a failure: at the
740b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    first extent, regardless of which extent the
741b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov                    failure actually happened in. */
742663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                 guest_IP_bbstart_IRConst,
743663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng                 offB_GUEST_IP
744ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown              );
745b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      } /* for (i = 0; i < vge->n_used; i++) */
746ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
747ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
748663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   /* irsb->next must now be set, since we've finished the block.
749663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      Print it if necessary.*/
750663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   vassert(irsb->next != NULL);
751663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   if (debug_print) {
752663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vex_printf("              ");
753663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vex_printf( "PUT(%d) = ", irsb->offsIP);
754663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ppIRExpr( irsb->next );
755663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vex_printf( "; exit-");
756663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      ppIRJumpKind(irsb->jumpkind);
757663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vex_printf( "\n");
758663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng      vex_printf( "\n");
759663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   }
760663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng
761663860b1408516d02ebfcb3a9999a134e6cfb223Ben Cheng   *n_guest_instrs = n_instrs;
762ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return irsb;
763ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
764ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
765ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
766ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*-------------------------------------------------------------
767ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  A support routine for doing self-checking translations.
768ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  -------------------------------------------------------------*/
769ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
770ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CLEAN HELPER */
771ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* CALLED FROM GENERATED CODE */
772ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
773ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Compute a checksum of host memory at [addr .. addr+len-1], as fast
774b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   as possible.  All _4al versions assume that the supplied address is
775b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   4 aligned.  All length values are in 4-byte chunks.  These fns
776b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   arecalled once for every use of a self-checking translation, so
777b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   they needs to be as fast as possible. */
778b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
779b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --- 32-bit versions, used only on 32-bit hosts --- */
780ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
781ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic inline UInt ROL32 ( UInt w, Int n ) {
782ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = (w << n) | (w >> (32-n));
783ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return w;
784ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
785ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
786b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(2)
787ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s )
788ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
789ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
790ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
791ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   /* unrolled */
792ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (n_w32s >= 4) {
793ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  w;
794ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
795ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
796ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
797ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
798ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += 4;
799ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n_w32s -= 4;
800ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sum1 ^= sum2;
801ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
802ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   while (n_w32s >= 1) {
803ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      UInt  w;
804ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
805ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      p += 1;
806ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      n_w32s -= 1;
807ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown      sum1 ^= sum2;
808ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   }
809ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
810ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
811ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
812ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Specialised versions of the above function */
813ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
814b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
815ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_1 ( 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   sum1 ^= sum2;
822ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
823ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
824ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
825b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
826ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_2 ( HWord first_w32 )
827ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
828ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
829ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
830ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
831ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
832ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
833ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
834ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
835ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
836ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
837ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
838b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
839ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_3 ( HWord first_w32 )
840ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
841ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
842ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
843ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
844ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
845ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
846ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
847ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
848ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
849ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
850ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
851ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
852ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
853b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
854ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_4 ( HWord first_w32 )
855ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
856ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
857ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
858ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
859ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
860ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
861ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
862ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
863ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
864ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
865ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
866ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
867b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
868ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_5 ( HWord first_w32 )
869ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
870ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
871ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
872ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
873ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
874ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
875ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
876ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
877ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
878ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
879ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
880ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
881ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
882ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
883b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
884ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_6 ( HWord first_w32 )
885ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
886ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
887ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
888ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
889ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
890ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
891ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
892ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
893ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
894ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
895ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
896ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
897ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
898ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
899ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
900ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
901b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
902ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_7 ( HWord first_w32 )
903ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
904ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
905ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
906ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
907ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
908ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
909ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
910ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
911ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
912ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
913ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
914ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
915ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
916ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
917ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
918ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
919ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
920ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
921b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
922ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_8 ( HWord first_w32 )
923ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
924ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
925ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
926ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
927ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
928ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
929ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
930ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
931ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
932ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
933ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
934ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
935ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[7];  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_9 ( 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   sum1 ^= sum2;
958ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
959ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
960ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
961b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
962ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_10 ( HWord first_w32 )
963ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
964ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
965ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
966ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
967ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
968ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
969ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
970ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
971ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
972ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
973ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
974ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
975ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
976ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
977ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
978ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
979ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
980ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
981ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
982ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
983ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
984b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
985ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_11 ( HWord first_w32 )
986ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
987ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
988ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
989ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
990ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
991ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
992ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
993ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
994ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
995ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
996ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
997ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
998ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
999ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1000ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1001ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1002ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1003ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1004ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1005ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1006ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
1007ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1008ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1009b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1010ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic UInt genericg_compute_checksum_4al_12 ( HWord first_w32 )
1011ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
1012ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  sum1 = 0, sum2 = 0;
1013ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt* p = (UInt*)first_w32;
1014ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   UInt  w;
1015ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1016ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1017ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1018ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1019ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1020ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1021ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1022ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1023ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1024ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1025ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1026ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1027ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1028ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   w = p[11]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
1029ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   sum1 ^= sum2;
1030ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown   return sum1 + sum2;
1031ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
1032ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
1033b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1034b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* --- 64-bit versions, used only on 64-bit hosts --- */
1035b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1036b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic inline ULong ROL64 ( ULong w, Int n ) {
1037b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = (w << n) | (w >> (64-n));
1038b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return w;
1039b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1040b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1041b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(2)
1042b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s )
1043b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1044b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1045b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1046b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   /* unrolled */
1047b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (n_w64s >= 4) {
1048b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ULong  w;
1049b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1050b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1051b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1052b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1053b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      p += 4;
1054b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      n_w64s -= 4;
1055b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 ^= sum2;
1056b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1057b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   while (n_w64s >= 1) {
1058b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      ULong  w;
1059b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1060b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      p += 1;
1061b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      n_w64s -= 1;
1062b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov      sum1 ^= sum2;
1063b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   }
1064b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1065b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1066b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1067b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov/* Specialised versions of the above function */
1068b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1069b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1070b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_1 ( 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   sum1 ^= sum2;
1077b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1078b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1079b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1080b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1081b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_2 ( HWord first_w64 )
1082b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1083b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1084b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1085b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1086b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1087b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1088b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1089b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1090b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1091b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1092b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1093b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1094b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_3 ( HWord first_w64 )
1095b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1096b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1097b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1098b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1099b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1100b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1101b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1102b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1103b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1104b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1105b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1106b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1107b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1108b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1109b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_4 ( HWord first_w64 )
1110b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1111b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1112b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1113b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1114b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1115b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1116b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1117b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1118b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1119b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1120b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1121b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1122b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1123b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_5 ( HWord first_w64 )
1124b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1125b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1126b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1127b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1128b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1129b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1130b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1131b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1132b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1133b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1134b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1135b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1136b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1137b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1138b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1139b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_6 ( HWord first_w64 )
1140b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1141b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1142b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1143b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1144b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1145b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1146b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1147b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1148b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1149b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1150b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1151b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1152b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1153b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1154b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1155b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1156b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1157b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_7 ( HWord first_w64 )
1158b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1159b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1160b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1161b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1162b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1163b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1164b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1165b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1166b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1167b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1168b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1169b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1170b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1171b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1172b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1173b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1174b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1175b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1176b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1177b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_8 ( HWord first_w64 )
1178b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1179b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1180b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1181b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1182b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1183b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1184b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1185b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1186b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1187b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1188b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1189b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1190b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[7];  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_9 ( 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   sum1 ^= sum2;
1213b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1214b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1215b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1216b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1217b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_10 ( HWord first_w64 )
1218b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1219b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1220b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1221b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1222b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1223b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1224b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1225b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1226b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1227b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1228b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1229b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1230b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1231b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1232b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1233b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1234b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1235b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1236b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1237b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1238b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1239b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1240b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_11 ( HWord first_w64 )
1241b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1242b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1243b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1244b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1245b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1246b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1247b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1248b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1249b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1250b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1251b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1252b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1253b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1254b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1255b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1256b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1257b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1258b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1259b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1260b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1261b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1262b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1263b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1264b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy StepanovVEX_REGPARM(1)
1265b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanovstatic ULong genericg_compute_checksum_8al_12 ( HWord first_w64 )
1266b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov{
1267b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  sum1 = 0, sum2 = 0;
1268b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong* p = (ULong*)first_w64;
1269b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   ULong  w;
1270b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1271b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1272b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1273b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1274b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1275b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1276b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1277b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1278b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1279b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1280b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1281b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1282b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1283b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   w = p[11]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1284b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   sum1 ^= sum2;
1285b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov   return sum1 + sum2;
1286b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov}
1287b32f58018498ea2225959b0ba11c18f0c433deefEvgeniy Stepanov
1288ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
1289ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--- end                                 guest_generic_bb_to_IR.c ---*/
1290ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/*--------------------------------------------------------------------*/
1291