19e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
29e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
3752f90673ebbb6b2f55fc5e46606dea371313713sewardj/*--- begin                               guest_generic_bb_to_IR.c ---*/
49e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
59e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
69e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*
7752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This file is part of Valgrind, a dynamic binary instrumentation
8752f90673ebbb6b2f55fc5e46606dea371313713sewardj   framework.
99e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1089ae8477745fd2a15453557d729a50e627325ee2sewardj   Copyright (C) 2004-2013 OpenWorks LLP
11752f90673ebbb6b2f55fc5e46606dea371313713sewardj      info@open-works.net
127bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
13752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is free software; you can redistribute it and/or
14752f90673ebbb6b2f55fc5e46606dea371313713sewardj   modify it under the terms of the GNU General Public License as
15752f90673ebbb6b2f55fc5e46606dea371313713sewardj   published by the Free Software Foundation; either version 2 of the
16752f90673ebbb6b2f55fc5e46606dea371313713sewardj   License, or (at your option) any later version.
177bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
18752f90673ebbb6b2f55fc5e46606dea371313713sewardj   This program is distributed in the hope that it will be useful, but
19752f90673ebbb6b2f55fc5e46606dea371313713sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
20752f90673ebbb6b2f55fc5e46606dea371313713sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21752f90673ebbb6b2f55fc5e46606dea371313713sewardj   General Public License for more details.
22752f90673ebbb6b2f55fc5e46606dea371313713sewardj
23752f90673ebbb6b2f55fc5e46606dea371313713sewardj   You should have received a copy of the GNU General Public License
24752f90673ebbb6b2f55fc5e46606dea371313713sewardj   along with this program; if not, write to the Free Software
25752f90673ebbb6b2f55fc5e46606dea371313713sewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
267bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj   02110-1301, USA.
277bd6ffe203f3aa9e7b25f7eae40a9b9cf48710cfsewardj
28752f90673ebbb6b2f55fc5e46606dea371313713sewardj   The GNU General Public License is contained in the file COPYING.
299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Neither the names of the U.S. Department of Energy nor the
319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   University of California nor the names of its contributors may be
329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   used to endorse or promote products derived from this software
339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   without prior written permission.
349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj*/
359e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
369e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex_basictypes.h"
379e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex_ir.h"
389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj#include "libvex.h"
39cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_util.h"
40cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "main_globals.h"
41cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj#include "guest_generic_bb_to_IR.h"
429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
44db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* Forwards .. */
4503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
469581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s );
4703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
489581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_1 ( HWord first_w32 );
4903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
509581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_2 ( HWord first_w32 );
5103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
529581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_3 ( HWord first_w32 );
5303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
549581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_4 ( HWord first_w32 );
5503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
569581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_5 ( HWord first_w32 );
5703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
589581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_6 ( HWord first_w32 );
5903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
609581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_7 ( HWord first_w32 );
6103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
629581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_8 ( HWord first_w32 );
6303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
649581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_9 ( HWord first_w32 );
6503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
669581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_10 ( HWord first_w32 );
6703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
689581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_11 ( HWord first_w32 );
6903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
709581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_12 ( HWord first_w32 );
71db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
7203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
73d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s );
7403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
75d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_1 ( HWord first_w64 );
7603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
77d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_2 ( HWord first_w64 );
7803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
79d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_3 ( HWord first_w64 );
8003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
81d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_4 ( HWord first_w64 );
8203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
83d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_5 ( HWord first_w64 );
8403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
85d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_6 ( HWord first_w64 );
8603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
87d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_7 ( HWord first_w64 );
8803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
89d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_8 ( HWord first_w64 );
9003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
91d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_9 ( HWord first_w64 );
9203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
93d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_10 ( HWord first_w64 );
9403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
95d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_11 ( HWord first_w64 );
9603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
97d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_12 ( HWord first_w64 );
98d6c17253ec35b2233840542eaf8339fa92062902sewardj
99ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj/* Small helpers */
100beac530a718fcc646bc61fe60a86f599df54e1d7florianstatic Bool const_False ( void* callback_opaque, Addr a ) {
101c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   return False;
102c716aea1cafe66ee431dc7d6909c98f18788a028sewardj}
103db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
104ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj/* Disassemble a complete basic block, starting at guest_IP_start,
105f6c8ebf1294fea43756683ba7089b746168abb8esewardj   returning a new IRSB.  The disassembler may chase across basic
1069e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   block boundaries if it wishes and if chase_into_ok allows it.
1079e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   The precise guest address ranges from which code has been taken
10836d982b5d1041d1348fc3100377f905d66dfb4d1cerion   are written into vge.  guest_IP_bbstart is taken to be the IP in
1099e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   the guest's address space corresponding to the instruction at
1109e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   &guest_code[0].
1119e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   dis_instr_fn is the arch-specific fn to disassemble on function; it
1139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   is this that does the real work.
114db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
115bc161a407b3cbd722821812afb8fb47420ae538fsewardj   needs_self_check is a callback used to ask the caller which of the
116bc161a407b3cbd722821812afb8fb47420ae538fsewardj   extents, if any, a self check is required for.  The returned value
117bc161a407b3cbd722821812afb8fb47420ae538fsewardj   is a bitmask with a 1 in position i indicating that the i'th extent
118bc161a407b3cbd722821812afb8fb47420ae538fsewardj   needs a check.  Since there can be at most 3 extents, the returned
119bc161a407b3cbd722821812afb8fb47420ae538fsewardj   values must be between 0 and 7.
120bc161a407b3cbd722821812afb8fb47420ae538fsewardj
121bc161a407b3cbd722821812afb8fb47420ae538fsewardj   The number of extents which did get a self check (0 to 3) is put in
122bc161a407b3cbd722821812afb8fb47420ae538fsewardj   n_sc_extents.  The caller already knows this because it told us
123bc161a407b3cbd722821812afb8fb47420ae538fsewardj   which extents to add checks for, via the needs_self_check callback,
124bc161a407b3cbd722821812afb8fb47420ae538fsewardj   but we ship the number back out here for the caller's convenience.
125db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
126c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   preamble_function is a callback which allows the caller to add
127c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   its own IR preamble (following the self-check, if any).  May be
128f6c8ebf1294fea43756683ba7089b746168abb8esewardj   NULL.  If non-NULL, the IRSB under construction is handed to
129c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   this function, which presumably adds IR statements to it.  The
130c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callback may optionally complete the block and direct bb_to_IR
131c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   not to disassemble any instructions into it; this is indicated
132c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   by the callback returning True.
133c716aea1cafe66ee431dc7d6909c98f18788a028sewardj
13405f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   offB_CMADDR and offB_CMLEN are the offsets of guest_CMADDR and
13505f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj   guest_CMLEN.  Since this routine has to work for any guest state,
136c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   without knowing what it is, those offsets have to passed in.
137c716aea1cafe66ee431dc7d6909c98f18788a028sewardj
138c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callback_opaque is a caller-supplied pointer to data which the
139c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   callbacks may want to see.  Vex has no idea what it is.
140c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   (In fact it's a VgInstrumentClosure.)
141ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj*/
1429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
143c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj/* Regarding IP updating.  dis_instr_fn (that does the guest specific
144c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   work of disassembling an individual instruction) must finish the
145c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   resulting IR with "PUT(guest_IP) = ".  Hence in all cases it must
146c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   state the next instruction address.
147c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
148c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   If the block is to be ended at that point, then this routine
149c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   (bb_to_IR) will set up the next/jumpkind/offsIP fields so as to
150c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   make a transfer (of the right kind) to "GET(guest_IP)".  Hence if
151c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   dis_instr_fn generates incorrect IP updates we will see it
152c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   immediately (due to jumping to the wrong next guest address).
153c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
154c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   However it is also necessary to set this up so it can be optimised
155c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   nicely.  The IRSB exit is defined to update the guest IP, so that
156c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   chaining works -- since the chain_me stubs expect the chain-to
157c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   address to be in the guest state.  Hence what the IRSB next fields
158c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   will contain initially is (implicitly)
159c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
160c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   PUT(guest_IP) [implicitly] = GET(guest_IP) [explicit expr on ::next]
161c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
162c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   which looks pretty strange at first.  Eg so unconditional branch
163c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   to some address 0x123456 looks like this:
164c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
165c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   PUT(guest_IP) = 0x123456;  // dis_instr_fn generates this
166c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   // the exit
167c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   PUT(guest_IP) [implicitly] = GET(guest_IP); exit-Boring
168c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
169c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   after redundant-GET and -PUT removal by iropt, we get what we want:
170c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
171c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   // the exit
172c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   PUT(guest_IP) [implicitly] = 0x123456; exit-Boring
173c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
174c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   This makes the IRSB-end case the same as the side-exit case: update
175c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   IP, then transfer.  There is no redundancy of representation for
176c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   the destination, and we use the destination specified by
177c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   dis_instr_fn, so any errors it makes show up sooner.
178c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj*/
179c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
180bc161a407b3cbd722821812afb8fb47420ae538fsewardjIRSB* bb_to_IR (
181bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*OUT*/VexGuestExtents* vge,
182bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*OUT*/UInt*            n_sc_extents,
183fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj         /*OUT*/UInt*            n_guest_instrs, /* stats only */
184ca2c3c75784d35d136fc7c952717cdee5063c193sewardj         /*MOD*/VexRegisterUpdates* pxControl,
185bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*IN*/ void*            callback_opaque,
186bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*IN*/ DisOneInstrFn    dis_instr_fn,
1878462d113e3efeacceb304222dada8d85f748295aflorian         /*IN*/ const UChar*     guest_code,
188d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian         /*IN*/ Addr             guest_IP_bbstart,
189beac530a718fcc646bc61fe60a86f599df54e1d7florian         /*IN*/ Bool             (*chase_into_ok)(void*,Addr),
1909b76916dcc1628e133d57db001563429c6e3a590sewardj         /*IN*/ VexEndness       host_endness,
191442e51a26cf3bc7f243167a4ff3fbfb02206f6e6sewardj         /*IN*/ Bool             sigill_diag,
192bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*IN*/ VexArch          arch_guest,
193cacba8e675988fbf21b08feea1f317a9c896c053florian         /*IN*/ const VexArchInfo* archinfo_guest,
194cacba8e675988fbf21b08feea1f317a9c896c053florian         /*IN*/ const VexAbiInfo*  abiinfo_both,
195bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*IN*/ IRType           guest_word_type,
196ca2c3c75784d35d136fc7c952717cdee5063c193sewardj         /*IN*/ UInt             (*needs_self_check)
197ca2c3c75784d35d136fc7c952717cdee5063c193sewardj                                    (void*, /*MB_MOD*/VexRegisterUpdates*,
198ca2c3c75784d35d136fc7c952717cdee5063c193sewardj                                            const VexGuestExtents*),
199bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /*IN*/ Bool             (*preamble_function)(void*,IRSB*),
20005f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         /*IN*/ Int              offB_GUEST_CMSTART,
20105f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         /*IN*/ Int              offB_GUEST_CMLEN,
202c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         /*IN*/ Int              offB_GUEST_IP,
203c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         /*IN*/ Int              szB_GUEST_IP
204bc161a407b3cbd722821812afb8fb47420ae538fsewardj      )
2059e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj{
2069e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Long       delta;
2079e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Int        i, n_instrs, first_stmt_idx;
208c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   Bool       resteerOK, debug_print;
2099e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   DisResult  dres;
2109e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   IRStmt*    imark;
211bc161a407b3cbd722821812afb8fb47420ae538fsewardj   IRStmt*    nop;
2129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   static Int n_resteers = 0;
2139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   Int        d_resteers = 0;
214db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   Int        selfcheck_idx = 0;
215dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   IRSB*      irsb;
216d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian   Addr       guest_IP_curr_instr;
217ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   IRConst*   guest_IP_bbstart_IRConst = NULL;
218984d9b164dd17f07e603c41fe1e506e641e57d18sewardj   Int        n_cond_resteers_allowed = 2;
2199e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
220beac530a718fcc646bc61fe60a86f599df54e1d7florian   Bool (*resteerOKfn)(void*,Addr) = NULL;
2219e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2229e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   debug_print = toBool(vex_traceflags & VEX_TRACE_FE);
2239e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2249e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* check sanity .. */
225db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   vassert(sizeof(HWord) == sizeof(void*));
2269e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_max_insns >= 1);
227471d006475d906a99da5640d34c1b5bb3fd798f2philippe   vassert(vex_control.guest_max_insns <= 100);
2289e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_chase_thresh >= 0);
2299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(vex_control.guest_chase_thresh < vex_control.guest_max_insns);
2309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vassert(guest_word_type == Ity_I32 || guest_word_type == Ity_I64);
2319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
232c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   if (guest_word_type == Ity_I32) {
233c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(szB_GUEST_IP == 4);
234c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert((offB_GUEST_IP % 4) == 0);
235c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   } else {
236c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(szB_GUEST_IP == 8);
237c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert((offB_GUEST_IP % 8) == 0);
238c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
239c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
2409e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* Start a new, empty extent. */
2419e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->n_used  = 1;
2429e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->base[0] = guest_IP_bbstart;
2439e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   vge->len[0]  = 0;
244bc161a407b3cbd722821812afb8fb47420ae538fsewardj   *n_sc_extents = 0;
2459e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
246dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   /* And a new IR superblock to dump the result into. */
247dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   irsb = emptyIRSB();
2489e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2499e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   /* Delta keeps track of how far along the guest_code array we have
2509e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      so far gone. */
2519e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   delta    = 0;
2529e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   n_instrs = 0;
253fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   *n_guest_instrs = 0;
2549e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
255bc161a407b3cbd722821812afb8fb47420ae538fsewardj   /* Guest addresses as IRConsts.  Used in self-checks to specify the
256bc161a407b3cbd722821812afb8fb47420ae538fsewardj      restart-after-discard point. */
257bc161a407b3cbd722821812afb8fb47420ae538fsewardj   guest_IP_bbstart_IRConst
258bc161a407b3cbd722821812afb8fb47420ae538fsewardj      = guest_word_type==Ity_I32
259bc161a407b3cbd722821812afb8fb47420ae538fsewardj           ? IRConst_U32(toUInt(guest_IP_bbstart))
260bc161a407b3cbd722821812afb8fb47420ae538fsewardj           : IRConst_U64(guest_IP_bbstart);
261bc161a407b3cbd722821812afb8fb47420ae538fsewardj
262bc161a407b3cbd722821812afb8fb47420ae538fsewardj   /* Leave 15 spaces in which to put the check statements for a self
263bc161a407b3cbd722821812afb8fb47420ae538fsewardj      checking translation (up to 3 extents, and 5 stmts required for
264bc161a407b3cbd722821812afb8fb47420ae538fsewardj      each).  We won't know until later the extents and checksums of
265bc161a407b3cbd722821812afb8fb47420ae538fsewardj      the areas, if any, that need to be checked. */
266bc161a407b3cbd722821812afb8fb47420ae538fsewardj   nop = IRStmt_NoOp();
267bc161a407b3cbd722821812afb8fb47420ae538fsewardj   selfcheck_idx = irsb->stmts_used;
268bc161a407b3cbd722821812afb8fb47420ae538fsewardj   for (i = 0; i < 3 * 5; i++)
269bc161a407b3cbd722821812afb8fb47420ae538fsewardj      addStmtToIRSB( irsb, nop );
270db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
271c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   /* If the caller supplied a function to add its own preamble, use
272c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      it now. */
273c716aea1cafe66ee431dc7d6909c98f18788a028sewardj   if (preamble_function) {
274dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      Bool stopNow = preamble_function( callback_opaque, irsb );
275c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      if (stopNow) {
276c716aea1cafe66ee431dc7d6909c98f18788a028sewardj         /* The callback has completed the IR block without any guest
277c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            insns being disassembled into it, so just return it at
278c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            this point, even if a self-check was requested - as there
279bc161a407b3cbd722821812afb8fb47420ae538fsewardj            is nothing to self-check.  The 15 self-check no-ops will
280c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            still be in place, but they are harmless. */
281dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         return irsb;
282c716aea1cafe66ee431dc7d6909c98f18788a028sewardj      }
283ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj   }
284ce02aa77bc02dbe225a068df0fb6b31faddedcdfsewardj
285db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /* Process instructions. */
2869e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   while (True) {
2879e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(n_instrs < vex_control.guest_max_insns);
2889e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2899e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Regardless of what chase_into_ok says, is chasing permissible
2909e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         at all right now?  Set resteerOKfn accordingly. */
2919e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      resteerOK
2929e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = toBool(
2939e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              n_instrs < vex_control.guest_chase_thresh
2949e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              /* we can't afford to have a resteer once we're on the
2959e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                 last extent slot. */
2969e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              && vge->n_used < 3
2979e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj           );
2989e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
2999e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      resteerOKfn
3009e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = resteerOK ? chase_into_ok : const_False;
3019e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
302984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* n_cond_resteers_allowed keeps track of whether we're still
303984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         allowing dis_instr_fn to chase conditional branches.  It
304984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         starts (at 2) and gets decremented each time dis_instr_fn
305984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         tells us it has chased a conditional branch.  We then
306984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         decrement it, and use it to tell later calls to dis_instr_fn
307984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         whether or not it is allowed to chase conditional
308984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         branches. */
309984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      vassert(n_cond_resteers_allowed >= 0 && n_cond_resteers_allowed <= 2);
310984d9b164dd17f07e603c41fe1e506e641e57d18sewardj
3119e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* This is the IP of the instruction we're just about to deal
3129e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         with. */
3139e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      guest_IP_curr_instr = guest_IP_bbstart + delta;
3149e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
315dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      /* This is the irsb statement array index of the first stmt in
3169e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         this insn.  That will always be the instruction-mark
3179e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         descriptor. */
318dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      first_stmt_idx = irsb->stmts_used;
3199e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3209e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Add an instruction-mark statement.  We won't know until after
3219e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         disassembling the instruction how long it instruction is, so
3223176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         just put in a zero length and we'll fix it up later.
3233176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj
3243176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         On ARM, the least significant bit of the instr address
3253176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         distinguishes ARM vs Thumb instructions.  All instructions
3263176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         actually start on at least 2-aligned addresses.  So we need
3273176386f5c7257f4aa30e9558e7bc3e612da23b5sewardj         to ignore the bottom bit of the insn address when forming the
3282f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         IMark's address field, but put that bottom bit in the delta
3292f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         field, so that comparisons against guest_R15T for Thumb can
3302f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         be done correctly.  By inspecting the delta field,
3312f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         instruction processors can determine whether the instruction
3322f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         was originally Thumb or ARM.  For more details of this
3332f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         convention, see comments on definition of guest_R15T in
3342f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         libvex_guest_arm.h. */
335d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian      if (arch_guest == VexArchARM && (guest_IP_curr_instr & 1)) {
3362f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         /* Thumb insn => mask out the T bit, but put it in delta */
3372f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         addStmtToIRSB( irsb,
338d4cc0deec55ec0be1f2ac3b20f0d340265341f83florian                        IRStmt_IMark(guest_IP_curr_instr & ~(Addr)1,
3392f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0, /* len */
3402f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     1  /* delta */
3412f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        )
3422f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         );
3432f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj      } else {
3442f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         /* All other targets: store IP as-is, and set delta to zero. */
3452f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         addStmtToIRSB( irsb,
3462f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        IRStmt_IMark(guest_IP_curr_instr,
3472f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0, /* len */
3482f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                                     0  /* delta */
3492f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj                        )
3502f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj         );
3512f10aa6f4e9ea78030c46cce9b073b19c63c0f60sewardj      }
3529e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
353c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      if (debug_print && n_instrs > 0)
354c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         vex_printf("\n");
3559e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3569e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Finally, actually disassemble an instruction. */
357c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(irsb->next == NULL);
358dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      dres = dis_instr_fn ( irsb,
3599e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            resteerOKfn,
360984d9b164dd17f07e603c41fe1e506e641e57d18sewardj                            toBool(n_cond_resteers_allowed > 0),
361c716aea1cafe66ee431dc7d6909c98f18788a028sewardj                            callback_opaque,
3629e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            guest_code,
3639e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            delta,
3649e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            guest_IP_curr_instr,
365a5f55da7e956978fddad927436da5fab9568f3f1sewardj                            arch_guest,
3669e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                            archinfo_guest,
367dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj                            abiinfo_both,
3689b76916dcc1628e133d57db001563429c6e3a590sewardj                            host_endness,
369442e51a26cf3bc7f243167a4ff3fbfb02206f6e6sewardj                            sigill_diag );
3709e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3719e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* stay sane ... */
3729e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(dres.whatNext == Dis_StopHere
3739e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj              || dres.whatNext == Dis_Continue
374984d9b164dd17f07e603c41fe1e506e641e57d18sewardj              || dres.whatNext == Dis_ResteerU
375984d9b164dd17f07e603c41fe1e506e641e57d18sewardj              || dres.whatNext == Dis_ResteerC);
376984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... disassembled insn length is sane ... */
3770de80192f57cd132b31b233c65734de04939ce65sewardj      vassert(dres.len >= 0 && dres.len <= 24);
378984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... continueAt is zero if no resteer requested ... */
379984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      if (dres.whatNext != Dis_ResteerU && dres.whatNext != Dis_ResteerC)
3809e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         vassert(dres.continueAt == 0);
381984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      /* ... if we disallowed conditional resteers, check that one
382984d9b164dd17f07e603c41fe1e506e641e57d18sewardj             didn't actually happen anyway ... */
383984d9b164dd17f07e603c41fe1e506e641e57d18sewardj      if (n_cond_resteers_allowed == 0)
384984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         vassert(dres.whatNext != Dis_ResteerC);
3859e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3869e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Fill in the insn-mark length field. */
387dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      vassert(first_stmt_idx >= 0 && first_stmt_idx < irsb->stmts_used);
388dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj      imark = irsb->stmts[first_stmt_idx];
3899e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark);
3909e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark->tag == Ist_IMark);
3919e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vassert(imark->Ist.IMark.len == 0);
3928e2d97185921fc9a9b97c8e111fc980e01ff746eflorian      imark->Ist.IMark.len = dres.len;
3939e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
3949e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Print the resulting IR, if needed. */
3959e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      if (vex_traceflags & VEX_TRACE_FE) {
396dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj         for (i = first_stmt_idx; i < irsb->stmts_used; i++) {
3979e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("              ");
398dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj            ppIRStmt(irsb->stmts[i]);
3999e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vex_printf("\n");
4009e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         }
4019e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
4029e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
403c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      /* Individual insn disassembly may not mess with irsb->next.
404c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         This function is the only place where it can be set. */
405c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(irsb->next == NULL);
406c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(irsb->jumpkind == Ijk_Boring);
407c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(irsb->offsIP == 0);
408c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
409c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      /* Individual insn disassembly must finish the IR for each
410c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj         instruction with an assignment to the guest PC. */
411c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vassert(first_stmt_idx < irsb->stmts_used);
412c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      /* it follows that irsb->stmts_used must be > 0 */
413c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      { IRStmt* st = irsb->stmts[irsb->stmts_used-1];
414c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        vassert(st);
415c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        vassert(st->tag == Ist_Put);
416c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        vassert(st->Ist.Put.offset == offB_GUEST_IP);
417c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj        /* Really we should also check that the type of the Put'd data
418c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj           == guest_word_type, but that's a bit expensive. */
4199e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
4209e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
4219e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Update the VexGuestExtents we are constructing. */
422db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      /* If vex_control.guest_max_insns is required to be < 100 and
4235eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         each insn is at max 20 bytes long, this limit of 5000 then
4245eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         seems reasonable since the max possible extent length will be
4255eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj         100 * 20 == 2000. */
426db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj      vassert(vge->len[vge->n_used-1] < 5000);
4279e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      vge->len[vge->n_used-1]
4289e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         = toUShort(toUInt( vge->len[vge->n_used-1] + dres.len ));
4299e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      n_instrs++;
4309e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
4319e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      /* Advance delta (inconspicuous but very important :-) */
4329e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      delta += (Long)dres.len;
4339e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
4349e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      switch (dres.whatNext) {
4359e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         case Dis_Continue:
436c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            vassert(dres.continueAt == 0);
437c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            vassert(dres.jk_StopHere == Ijk_INVALID);
4389e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            if (n_instrs < vex_control.guest_max_insns) {
4399e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj               /* keep going */
4409e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            } else {
441c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj               /* We have to stop.  See comment above re irsb field
442c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                  settings here. */
443c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj               irsb->next = IRExpr_Get(offB_GUEST_IP, guest_word_type);
444c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj               /* irsb->jumpkind must already by Ijk_Boring */
445c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj               irsb->offsIP = offB_GUEST_IP;
446db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj               goto done;
4479e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            }
4489e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            break;
4499e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         case Dis_StopHere:
450c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            vassert(dres.continueAt == 0);
451c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            vassert(dres.jk_StopHere != Ijk_INVALID);
452c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            /* See comment above re irsb field settings here. */
453c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            irsb->next = IRExpr_Get(offB_GUEST_IP, guest_word_type);
454c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            irsb->jumpkind = dres.jk_StopHere;
455c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj            irsb->offsIP = offB_GUEST_IP;
456db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj            goto done;
457c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
458984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         case Dis_ResteerU:
459984d9b164dd17f07e603c41fe1e506e641e57d18sewardj         case Dis_ResteerC:
4609e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* Check that we actually allowed a resteer .. */
4619e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vassert(resteerOK);
462984d9b164dd17f07e603c41fe1e506e641e57d18sewardj            if (dres.whatNext == Dis_ResteerC) {
463984d9b164dd17f07e603c41fe1e506e641e57d18sewardj               vassert(n_cond_resteers_allowed > 0);
464984d9b164dd17f07e603c41fe1e506e641e57d18sewardj               n_cond_resteers_allowed--;
465984d9b164dd17f07e603c41fe1e506e641e57d18sewardj            }
4669e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* figure out a new delta to continue at. */
467c716aea1cafe66ee431dc7d6909c98f18788a028sewardj            vassert(resteerOKfn(callback_opaque,dres.continueAt));
4689e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            delta = dres.continueAt - guest_IP_bbstart;
4699e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            /* we now have to start a new extent slot. */
47092b643609c5fa432b11fc726c2706ae3f3296eb4cerion            vge->n_used++;
47192b643609c5fa432b11fc726c2706ae3f3296eb4cerion            vassert(vge->n_used <= 3);
4729e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vge->base[vge->n_used-1] = dres.continueAt;
4739e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vge->len[vge->n_used-1] = 0;
4749e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            n_resteers++;
4759e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            d_resteers++;
4769e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            if (0 && (n_resteers & 0xFF) == 0)
4770eaa35ff5569f09129073be27c2f827926f7010dflorian            vex_printf("resteer[%d,%d] to 0x%lx (delta = %lld)\n",
4789e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                       n_resteers, d_resteers,
4799e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj                       dres.continueAt, delta);
4809e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            break;
4819e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj         default:
4829e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj            vpanic("bb_to_IR");
4839e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj      }
4849e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj   }
485db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /*NOTREACHED*/
486db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   vassert(0);
487db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
488db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  done:
489db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   /* We're done.  The only thing that might need attending to is that
490bc161a407b3cbd722821812afb8fb47420ae538fsewardj      a self-checking preamble may need to be created.  If so it gets
491bc161a407b3cbd722821812afb8fb47420ae538fsewardj      placed in the 15 slots reserved above.
4929581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
4939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      The scheme is to compute a rather crude checksum of the code
4949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      we're making a translation of, and add to the IR a call to a
4959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      helper routine which recomputes the checksum every time the
4969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      translation is run, and requests a retranslation if it doesn't
4979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      match.  This is obviously very expensive and considerable
4989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      efforts are made to speed it up:
4999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
500bc161a407b3cbd722821812afb8fb47420ae538fsewardj      * the checksum is computed from all the naturally aligned
501bc161a407b3cbd722821812afb8fb47420ae538fsewardj        host-sized words that overlap the translated code.  That means
502bc161a407b3cbd722821812afb8fb47420ae538fsewardj        it could depend on up to 7 bytes before and 7 bytes after
503bc161a407b3cbd722821812afb8fb47420ae538fsewardj        which aren't part of the translated area, and so if those
504bc161a407b3cbd722821812afb8fb47420ae538fsewardj        change then we'll unnecessarily have to discard and
505bc161a407b3cbd722821812afb8fb47420ae538fsewardj        retranslate.  This seems like a pretty remote possibility and
506bc161a407b3cbd722821812afb8fb47420ae538fsewardj        it seems as if the benefit of not having to deal with the ends
507bc161a407b3cbd722821812afb8fb47420ae538fsewardj        of the range at byte precision far outweigh any possible extra
508bc161a407b3cbd722821812afb8fb47420ae538fsewardj        translations needed.
5099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
5109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      * there's a generic routine and 12 specialised cases, which
5119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        handle the cases of 1 through 12-word lengths respectively.
5129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        They seem to cover about 90% of the cases that occur in
5139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj        practice.
514db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
515bc161a407b3cbd722821812afb8fb47420ae538fsewardj      We ask the caller, via needs_self_check, which of the 3 vge
516bc161a407b3cbd722821812afb8fb47420ae538fsewardj      extents needs a check, and only generate check code for those
517bc161a407b3cbd722821812afb8fb47420ae538fsewardj      that do.
518bc161a407b3cbd722821812afb8fb47420ae538fsewardj   */
519bc161a407b3cbd722821812afb8fb47420ae538fsewardj   {
520bdf99f06a5f44fd617c51ac80861ff07da09a50fflorian      Addr     base2check;
521d6c17253ec35b2233840542eaf8339fa92062902sewardj      UInt     len2check;
522d6c17253ec35b2233840542eaf8339fa92062902sewardj      HWord    expectedhW;
52316a403bac07df30df6e6587c8c911cf6df3f780dsewardj      IRTemp   tistart_tmp, tilen_tmp;
52403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj      HWord    VEX_REGPARM(2) (*fn_generic)(HWord, HWord);
52503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj      HWord    VEX_REGPARM(1) (*fn_spec)(HWord);
52655085f8680acc89d727e321f3b34cae1a8c4093aflorian      const HChar* nm_generic;
52755085f8680acc89d727e321f3b34cae1a8c4093aflorian      const HChar* nm_spec;
5289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HWord    fn_generic_entry = 0;
5299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      HWord    fn_spec_entry = 0;
530d6c17253ec35b2233840542eaf8339fa92062902sewardj      UInt     host_word_szB = sizeof(HWord);
531d6c17253ec35b2233840542eaf8339fa92062902sewardj      IRType   host_word_type = Ity_INVALID;
532d6c17253ec35b2233840542eaf8339fa92062902sewardj
533bc161a407b3cbd722821812afb8fb47420ae538fsewardj      UInt extents_needing_check
534ca2c3c75784d35d136fc7c952717cdee5063c193sewardj         = needs_self_check(callback_opaque, pxControl, vge);
535bc161a407b3cbd722821812afb8fb47420ae538fsewardj
536d6c17253ec35b2233840542eaf8339fa92062902sewardj      if (host_word_szB == 4) host_word_type = Ity_I32;
537d6c17253ec35b2233840542eaf8339fa92062902sewardj      if (host_word_szB == 8) host_word_type = Ity_I64;
538d6c17253ec35b2233840542eaf8339fa92062902sewardj      vassert(host_word_type != Ity_INVALID);
539d6c17253ec35b2233840542eaf8339fa92062902sewardj
540d6c17253ec35b2233840542eaf8339fa92062902sewardj      vassert(vge->n_used >= 1 && vge->n_used <= 3);
541bc161a407b3cbd722821812afb8fb47420ae538fsewardj
542bc161a407b3cbd722821812afb8fb47420ae538fsewardj      /* Caller shouldn't claim that nonexistent extents need a
543bc161a407b3cbd722821812afb8fb47420ae538fsewardj         check. */
544bc161a407b3cbd722821812afb8fb47420ae538fsewardj      vassert((extents_needing_check >> vge->n_used) == 0);
545bc161a407b3cbd722821812afb8fb47420ae538fsewardj
546d6c17253ec35b2233840542eaf8339fa92062902sewardj      for (i = 0; i < vge->n_used; i++) {
547d6c17253ec35b2233840542eaf8339fa92062902sewardj
548bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /* Do we need to generate a check for this extent? */
549bc161a407b3cbd722821812afb8fb47420ae538fsewardj         if ((extents_needing_check & (1 << i)) == 0)
550bc161a407b3cbd722821812afb8fb47420ae538fsewardj            continue;
551bc161a407b3cbd722821812afb8fb47420ae538fsewardj
552bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /* Tell the caller */
553bc161a407b3cbd722821812afb8fb47420ae538fsewardj         (*n_sc_extents)++;
554bc161a407b3cbd722821812afb8fb47420ae538fsewardj
555d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* the extent we're generating a check for */
556d6c17253ec35b2233840542eaf8339fa92062902sewardj         base2check = vge->base[i];
557d6c17253ec35b2233840542eaf8339fa92062902sewardj         len2check  = vge->len[i];
558d6c17253ec35b2233840542eaf8339fa92062902sewardj
559d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* stay sane */
560d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
561d6c17253ec35b2233840542eaf8339fa92062902sewardj
562d6c17253ec35b2233840542eaf8339fa92062902sewardj         /* Skip the check if the translation involved zero bytes */
563d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (len2check == 0)
564d6c17253ec35b2233840542eaf8339fa92062902sewardj            continue;
565d6c17253ec35b2233840542eaf8339fa92062902sewardj
566d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord first_hW = ((HWord)base2check)
567d6c17253ec35b2233840542eaf8339fa92062902sewardj                          & ~(HWord)(host_word_szB-1);
568d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord last_hW  = (((HWord)base2check) + len2check - 1)
569d6c17253ec35b2233840542eaf8339fa92062902sewardj                          & ~(HWord)(host_word_szB-1);
570d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(first_hW <= last_hW);
571d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord hW_diff = last_hW - first_hW;
572d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(0 == (hW_diff & (host_word_szB-1)));
573d6c17253ec35b2233840542eaf8339fa92062902sewardj         HWord hWs_to_check = (hW_diff + host_word_szB) / host_word_szB;
574d6c17253ec35b2233840542eaf8339fa92062902sewardj         vassert(hWs_to_check > 0
575d6c17253ec35b2233840542eaf8339fa92062902sewardj                 && hWs_to_check < 1004/*arbitrary*/ / host_word_szB);
5769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
577bc161a407b3cbd722821812afb8fb47420ae538fsewardj         /* vex_printf("%lx %lx  %ld\n", first_hW, last_hW, hWs_to_check); */
5789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
579d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (host_word_szB == 8) {
58003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
581d6c17253ec35b2233840542eaf8339fa92062902sewardj                          genericg_compute_checksum_8al;
582d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_generic = "genericg_compute_checksum_8al";
583d6c17253ec35b2233840542eaf8339fa92062902sewardj         } else {
58403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_generic =  (VEX_REGPARM(2) HWord(*)(HWord, HWord))
585d6c17253ec35b2233840542eaf8339fa92062902sewardj                          genericg_compute_checksum_4al;
586d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_generic = "genericg_compute_checksum_4al";
587d6c17253ec35b2233840542eaf8339fa92062902sewardj         }
588d6c17253ec35b2233840542eaf8339fa92062902sewardj
5899581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         fn_spec = NULL;
5909581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         nm_spec = NULL;
5919581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
592d6c17253ec35b2233840542eaf8339fa92062902sewardj         if (host_word_szB == 8) {
59355085f8680acc89d727e321f3b34cae1a8c4093aflorian            const HChar* nm = NULL;
59403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            ULong  VEX_REGPARM(1) (*fn)(HWord)  = NULL;
595d6c17253ec35b2233840542eaf8339fa92062902sewardj            switch (hWs_to_check) {
596d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 1:  fn =  genericg_compute_checksum_8al_1;
597d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_1"; break;
598d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 2:  fn =  genericg_compute_checksum_8al_2;
599d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_2"; break;
600d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 3:  fn =  genericg_compute_checksum_8al_3;
601d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_3"; break;
602d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 4:  fn =  genericg_compute_checksum_8al_4;
603d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_4"; break;
604d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 5:  fn =  genericg_compute_checksum_8al_5;
605d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_5"; break;
606d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 6:  fn =  genericg_compute_checksum_8al_6;
607d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_6"; break;
608d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 7:  fn =  genericg_compute_checksum_8al_7;
609d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_7"; break;
610d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 8:  fn =  genericg_compute_checksum_8al_8;
611d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_8"; break;
612d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 9:  fn =  genericg_compute_checksum_8al_9;
613d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_9"; break;
614d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 10: fn =  genericg_compute_checksum_8al_10;
615d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_10"; break;
616d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 11: fn =  genericg_compute_checksum_8al_11;
617d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_11"; break;
618d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 12: fn =  genericg_compute_checksum_8al_12;
619d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_8al_12"; break;
620d6c17253ec35b2233840542eaf8339fa92062902sewardj               default: break;
621d6c17253ec35b2233840542eaf8339fa92062902sewardj            }
62203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord)) fn;
623d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_spec = nm;
624d6c17253ec35b2233840542eaf8339fa92062902sewardj         } else {
62555085f8680acc89d727e321f3b34cae1a8c4093aflorian            const HChar* nm = NULL;
62603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            UInt   VEX_REGPARM(1) (*fn)(HWord) = NULL;
627d6c17253ec35b2233840542eaf8339fa92062902sewardj            switch (hWs_to_check) {
628d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 1:  fn =  genericg_compute_checksum_4al_1;
629d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_1"; break;
630d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 2:  fn =  genericg_compute_checksum_4al_2;
631d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_2"; break;
632d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 3:  fn =  genericg_compute_checksum_4al_3;
633d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_3"; break;
634d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 4:  fn =  genericg_compute_checksum_4al_4;
635d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_4"; break;
636d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 5:  fn =  genericg_compute_checksum_4al_5;
637d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_5"; break;
638d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 6:  fn =  genericg_compute_checksum_4al_6;
639d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_6"; break;
640d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 7:  fn =  genericg_compute_checksum_4al_7;
641d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_7"; break;
642d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 8:  fn =  genericg_compute_checksum_4al_8;
643d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_8"; break;
644d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 9:  fn =  genericg_compute_checksum_4al_9;
645d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_9"; break;
646d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 10: fn =  genericg_compute_checksum_4al_10;
647d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_10"; break;
648d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 11: fn =  genericg_compute_checksum_4al_11;
649d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_11"; break;
650d6c17253ec35b2233840542eaf8339fa92062902sewardj               case 12: fn =  genericg_compute_checksum_4al_12;
651d6c17253ec35b2233840542eaf8339fa92062902sewardj                        nm = "genericg_compute_checksum_4al_12"; break;
652d6c17253ec35b2233840542eaf8339fa92062902sewardj               default: break;
653d6c17253ec35b2233840542eaf8339fa92062902sewardj            }
65403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardj            fn_spec = (VEX_REGPARM(1) HWord(*)(HWord))fn;
655d6c17253ec35b2233840542eaf8339fa92062902sewardj            nm_spec = nm;
6569581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
6575eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
658d6c17253ec35b2233840542eaf8339fa92062902sewardj         expectedhW = fn_generic( first_hW, hWs_to_check );
6599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* If we got a specialised version, check it produces the same
6609581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            result as the generic version! */
6619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (fn_spec) {
6629581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            vassert(nm_spec);
663d6c17253ec35b2233840542eaf8339fa92062902sewardj            vassert(expectedhW == fn_spec( first_hW ));
6649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
6659581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            vassert(!nm_spec);
6669581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
6675eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
66805f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj         /* Set CMSTART and CMLEN.  These will describe to the despatcher
6699581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            the area of guest code to invalidate should we exit with a
6709581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            self-check failure. */
6715eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
6729581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
6739581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         tilen_tmp   = newIRTemp(irsb->tyenv, guest_word_type);
6745eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
675d6c17253ec35b2233840542eaf8339fa92062902sewardj         IRConst* base2check_IRConst
676d6c17253ec35b2233840542eaf8339fa92062902sewardj            = guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
677d6c17253ec35b2233840542eaf8339fa92062902sewardj                                       : IRConst_U64(base2check);
678d6c17253ec35b2233840542eaf8339fa92062902sewardj         IRConst* len2check_IRConst
679d6c17253ec35b2233840542eaf8339fa92062902sewardj            = guest_word_type==Ity_I32 ? IRConst_U32(len2check)
680d6c17253ec35b2233840542eaf8339fa92062902sewardj                                       : IRConst_U64(len2check);
6815eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
682d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 0]
683d6c17253ec35b2233840542eaf8339fa92062902sewardj            = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
684d6c17253ec35b2233840542eaf8339fa92062902sewardj
685d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 1]
686d6c17253ec35b2233840542eaf8339fa92062902sewardj            = IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
6875eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
688d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 2]
68905f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj            = IRStmt_Put( offB_GUEST_CMSTART, IRExpr_RdTmp(tistart_tmp) );
6905eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
691d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 3]
69205f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj            = IRStmt_Put( offB_GUEST_CMLEN, IRExpr_RdTmp(tilen_tmp) );
6935eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
6949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         /* Generate the entry point descriptors */
6959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (abiinfo_both->host_ppc_calls_use_fndescrs) {
6969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            HWord* descr = (HWord*)fn_generic;
6979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            fn_generic_entry = descr[0];
6989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            if (fn_spec) {
6999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               descr = (HWord*)fn_spec;
7009581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = descr[0];
7019581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            } else {
7029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)NULL;
7039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            }
7049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
7059581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            fn_generic_entry = (HWord)fn_generic;
7069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            if (fn_spec) {
7079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)fn_spec;
7089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            } else {
7099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj               fn_spec_entry = (HWord)NULL;
7109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            }
7119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
7129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
7139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         IRExpr* callexpr = NULL;
7149581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         if (fn_spec) {
7159581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            callexpr = mkIRExprCCall(
716d6c17253ec35b2233840542eaf8339fa92062902sewardj                          host_word_type, 1/*regparms*/,
7179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          nm_spec, (void*)fn_spec_entry,
7189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          mkIRExprVec_1(
719d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)first_hW )
7209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          )
7219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                       );
7229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         } else {
7239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            callexpr = mkIRExprCCall(
724d6c17253ec35b2233840542eaf8339fa92062902sewardj                          host_word_type, 2/*regparms*/,
7259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          nm_generic, (void*)fn_generic_entry,
7269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          mkIRExprVec_2(
727d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)first_hW ),
728d6c17253ec35b2233840542eaf8339fa92062902sewardj                             mkIRExpr_HWord( (HWord)hWs_to_check )
7299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                          )
7309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                       );
7319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj         }
7325eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
733d6c17253ec35b2233840542eaf8339fa92062902sewardj         irsb->stmts[selfcheck_idx + i * 5 + 4]
7349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj            = IRStmt_Exit(
7359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                 IRExpr_Binop(
736d6c17253ec35b2233840542eaf8339fa92062902sewardj                    host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
7379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj                    callexpr,
738d6c17253ec35b2233840542eaf8339fa92062902sewardj                       host_word_type==Ity_I64
739d6c17253ec35b2233840542eaf8339fa92062902sewardj                          ? IRExpr_Const(IRConst_U64(expectedhW))
740d6c17253ec35b2233840542eaf8339fa92062902sewardj                          : IRExpr_Const(IRConst_U32(expectedhW))
7415eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj                 ),
74205f5e0172384dd2983fb16fbb7deebd74d71cd35sewardj                 Ijk_InvalICache,
743d6c17253ec35b2233840542eaf8339fa92062902sewardj                 /* Where we must restart if there's a failure: at the
744d6c17253ec35b2233840542eaf8339fa92062902sewardj                    first extent, regardless of which extent the
745d6c17253ec35b2233840542eaf8339fa92062902sewardj                    failure actually happened in. */
746c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                 guest_IP_bbstart_IRConst,
747c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj                 offB_GUEST_IP
7489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj              );
749bc161a407b3cbd722821812afb8fb47420ae538fsewardj      } /* for (i = 0; i < vge->n_used; i++) */
750db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   }
751db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
752c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   /* irsb->next must now be set, since we've finished the block.
753c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      Print it if necessary.*/
754c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   vassert(irsb->next != NULL);
755c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   if (debug_print) {
756c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vex_printf("              ");
757c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vex_printf( "PUT(%d) = ", irsb->offsIP);
758c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      ppIRExpr( irsb->next );
759c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vex_printf( "; exit-");
760c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      ppIRJumpKind(irsb->jumpkind);
761c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vex_printf( "\n");
762c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj      vex_printf( "\n");
763c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj   }
764c6f970f1fadb640d69c78ac2669efab5c08f1e8dsewardj
765fadbbe2870ffba4e4565563f21fc20b9ab89fd8fsewardj   *n_guest_instrs = n_instrs;
766dd40fdf58cc8a6fe9466c4f00bdfc9fe9bf00449sewardj   return irsb;
7679e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj}
7689e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
7699e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
770db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/*-------------------------------------------------------------
771db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  A support routine for doing self-checking translations.
772db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj  -------------------------------------------------------------*/
773db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
774db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* CLEAN HELPER */
775db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj/* CALLED FROM GENERATED CODE */
776db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
7775eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj/* Compute a checksum of host memory at [addr .. addr+len-1], as fast
778d6c17253ec35b2233840542eaf8339fa92062902sewardj   as possible.  All _4al versions assume that the supplied address is
779d6c17253ec35b2233840542eaf8339fa92062902sewardj   4 aligned.  All length values are in 4-byte chunks.  These fns
780d6c17253ec35b2233840542eaf8339fa92062902sewardj   arecalled once for every use of a self-checking translation, so
781d6c17253ec35b2233840542eaf8339fa92062902sewardj   they needs to be as fast as possible. */
782d6c17253ec35b2233840542eaf8339fa92062902sewardj
783d6c17253ec35b2233840542eaf8339fa92062902sewardj/* --- 32-bit versions, used only on 32-bit hosts --- */
7845eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
7855eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardjstatic inline UInt ROL32 ( UInt w, Int n ) {
7865eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   w = (w << n) | (w >> (32-n));
7875eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return w;
7885eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj}
7895eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj
79003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
7919581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s )
792db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj{
7939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
7949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
7959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   /* unrolled */
7969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   while (n_w32s >= 4) {
7975eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      UInt  w;
7985eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
7995eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8005eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8015eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      p += 4;
8039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      n_w32s -= 4;
8045eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      sum1 ^= sum2;
8055eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   }
8069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   while (n_w32s >= 1) {
8079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      UInt  w;
8089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      p += 1;
8109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj      n_w32s -= 1;
8115eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj      sum1 ^= sum2;
812db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj   }
8135eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return sum1 + sum2;
814db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj}
815db4738ab05bf88fabe7fd931a24fab2fa2060e73sewardj
8169581906c85c93b1afd1bb9e543965da49a68aaf8sewardj/* Specialised versions of the above function */
8179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
81803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8199581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_1 ( HWord first_w32 )
8205eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj{
8219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
82903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8309581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_2 ( HWord first_w32 )
8319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8369581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8419581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
84203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8439581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_3 ( HWord first_w32 )
8449581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8459581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8469581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8479581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8499581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8509581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8519581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8529581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8539581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8549581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8559581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8569581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
85703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8589581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_4 ( HWord first_w32 )
8599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8609581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8629581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8639581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8659581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8669581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8679581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8689581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8699581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8709581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
87103d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8729581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_5 ( HWord first_w32 )
8739581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8749581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8759581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8779581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8799581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8809581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8819581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8829581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8839581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8849581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
8859581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
8869581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
88703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
8889581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_6 ( HWord first_w32 )
8899581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
8909581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
8919581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
8929581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
8939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
8989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
8999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9009581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9019581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
90503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9069581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_7 ( HWord first_w32 )
9079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9139581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9149581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9159581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9169581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
92503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9269581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_8 ( HWord first_w32 )
9279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9349581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9359581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9369581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9379581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9389581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9399581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9409581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9419581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9429581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9439581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
94403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9459581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_9 ( HWord first_w32 )
9469581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9479581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9489581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9499581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9509581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9519581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9529581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9539581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9549581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9559581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9569581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9579581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9589581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9599581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9609581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9619581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9629581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9639581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9649581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
96503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9669581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_10 ( HWord first_w32 )
9679581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9689581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9699581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9709581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9719581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9729581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9739581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9749581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9759581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9769581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9779581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9789581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9799581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9809581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9819581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9829581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9839581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9849581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9859581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
9869581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
9879581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
98803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
9899581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_11 ( HWord first_w32 )
9909581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
9919581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
9929581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
9939581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
9949581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9959581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9969581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9979581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
9989581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
9999581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10009581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10019581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10029581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10039581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10049581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10059581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10069581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10079581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10089581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10099581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10109581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   return sum1 + sum2;
10119581906c85c93b1afd1bb9e543965da49a68aaf8sewardj}
10129581906c85c93b1afd1bb9e543965da49a68aaf8sewardj
101303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
10149581906c85c93b1afd1bb9e543965da49a68aaf8sewardjstatic UInt genericg_compute_checksum_4al_12 ( HWord first_w32 )
10159581906c85c93b1afd1bb9e543965da49a68aaf8sewardj{
10169581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  sum1 = 0, sum2 = 0;
10179581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt* p = (UInt*)first_w32;
10189581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   UInt  w;
10199581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[0];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10209581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[1];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10219581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[2];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10229581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[3];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10239581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10249581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[4];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10259581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[5];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10269581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[6];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10279581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[7];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10289581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10299581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[8];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10309581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[9];  sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10319581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[10]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10329581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   w = p[11]; sum1 = ROL32(sum1 ^ w, 31);  sum2 += w;
10339581906c85c93b1afd1bb9e543965da49a68aaf8sewardj   sum1 ^= sum2;
10345eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj   return sum1 + sum2;
10355eaf82b7f0f5e83daea6f05c43c18cff6f6bf66esewardj}
10369e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj
1037d6c17253ec35b2233840542eaf8339fa92062902sewardj
1038d6c17253ec35b2233840542eaf8339fa92062902sewardj/* --- 64-bit versions, used only on 64-bit hosts --- */
1039d6c17253ec35b2233840542eaf8339fa92062902sewardj
1040d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic inline ULong ROL64 ( ULong w, Int n ) {
1041d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = (w << n) | (w >> (64-n));
1042d6c17253ec35b2233840542eaf8339fa92062902sewardj   return w;
1043d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1044d6c17253ec35b2233840542eaf8339fa92062902sewardj
104503d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(2)
1046d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s )
1047d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1048d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1049d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1050d6c17253ec35b2233840542eaf8339fa92062902sewardj   /* unrolled */
1051d6c17253ec35b2233840542eaf8339fa92062902sewardj   while (n_w64s >= 4) {
1052d6c17253ec35b2233840542eaf8339fa92062902sewardj      ULong  w;
1053d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1054d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1055d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1056d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1057d6c17253ec35b2233840542eaf8339fa92062902sewardj      p += 4;
1058d6c17253ec35b2233840542eaf8339fa92062902sewardj      n_w64s -= 4;
1059d6c17253ec35b2233840542eaf8339fa92062902sewardj      sum1 ^= sum2;
1060d6c17253ec35b2233840542eaf8339fa92062902sewardj   }
1061d6c17253ec35b2233840542eaf8339fa92062902sewardj   while (n_w64s >= 1) {
1062d6c17253ec35b2233840542eaf8339fa92062902sewardj      ULong  w;
1063d6c17253ec35b2233840542eaf8339fa92062902sewardj      w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1064d6c17253ec35b2233840542eaf8339fa92062902sewardj      p += 1;
1065d6c17253ec35b2233840542eaf8339fa92062902sewardj      n_w64s -= 1;
1066d6c17253ec35b2233840542eaf8339fa92062902sewardj      sum1 ^= sum2;
1067d6c17253ec35b2233840542eaf8339fa92062902sewardj   }
1068d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1069d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1070d6c17253ec35b2233840542eaf8339fa92062902sewardj
1071d6c17253ec35b2233840542eaf8339fa92062902sewardj/* Specialised versions of the above function */
1072d6c17253ec35b2233840542eaf8339fa92062902sewardj
107303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1074d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_1 ( HWord first_w64 )
1075d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1076d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1077d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1078d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1079d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1080d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1081d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1082d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1083d6c17253ec35b2233840542eaf8339fa92062902sewardj
108403d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1085d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_2 ( HWord first_w64 )
1086d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1087d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1088d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1089d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1090d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1091d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1092d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1093d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1094d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1095d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1096d6c17253ec35b2233840542eaf8339fa92062902sewardj
109703d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1098d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_3 ( HWord first_w64 )
1099d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1100d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1101d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1102d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1103d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1104d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1105d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1106d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1107d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1108d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1109d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1110d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1111d6c17253ec35b2233840542eaf8339fa92062902sewardj
111203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1113d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_4 ( HWord first_w64 )
1114d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1115d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1116d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1117d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1118d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1119d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1120d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1121d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1122d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1123d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1124d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1125d6c17253ec35b2233840542eaf8339fa92062902sewardj
112603d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1127d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_5 ( HWord first_w64 )
1128d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1129d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1130d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1131d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1132d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1133d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1134d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1135d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1136d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1137d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1138d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1139d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1140d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1141d6c17253ec35b2233840542eaf8339fa92062902sewardj
114203d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1143d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_6 ( HWord first_w64 )
1144d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1145d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1146d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1147d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1148d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1149d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1150d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1151d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1152d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1153d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1154d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1155d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1156d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1157d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1158d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1159d6c17253ec35b2233840542eaf8339fa92062902sewardj
116003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1161d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_7 ( HWord first_w64 )
1162d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1163d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1164d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1165d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1166d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1167d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1168d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1169d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1170d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1171d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1172d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1173d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1174d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1175d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1176d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1177d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1178d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1179d6c17253ec35b2233840542eaf8339fa92062902sewardj
118003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1181d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_8 ( HWord first_w64 )
1182d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1183d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1184d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1185d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1186d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1187d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1188d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1189d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1190d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1191d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1192d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1193d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1194d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1195d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1196d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1197d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1198d6c17253ec35b2233840542eaf8339fa92062902sewardj
119903d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1200d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_9 ( HWord first_w64 )
1201d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1202d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1203d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1204d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1205d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1206d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1207d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1208d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1209d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1210d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1211d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1212d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1213d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1214d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1215d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1216d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1217d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1218d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1219d6c17253ec35b2233840542eaf8339fa92062902sewardj
122003d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1221d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_10 ( HWord first_w64 )
1222d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1223d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1224d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1225d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1226d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1227d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1228d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1229d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1230d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1231d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1232d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1233d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1234d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1235d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1236d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1237d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1238d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1239d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1240d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1241d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1242d6c17253ec35b2233840542eaf8339fa92062902sewardj
124303d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1244d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_11 ( HWord first_w64 )
1245d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1246d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1247d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1248d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1249d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1250d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1251d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1252d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1253d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1254d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1255d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1256d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1257d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1258d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1259d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1260d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1261d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1262d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1263d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1264d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1265d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1266d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1267d6c17253ec35b2233840542eaf8339fa92062902sewardj
126803d91140809def2f5afc04b0cc9beb0f4f0a1b13sewardjVEX_REGPARM(1)
1269d6c17253ec35b2233840542eaf8339fa92062902sewardjstatic ULong genericg_compute_checksum_8al_12 ( HWord first_w64 )
1270d6c17253ec35b2233840542eaf8339fa92062902sewardj{
1271d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  sum1 = 0, sum2 = 0;
1272d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong* p = (ULong*)first_w64;
1273d6c17253ec35b2233840542eaf8339fa92062902sewardj   ULong  w;
1274d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[0];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1275d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[1];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1276d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[2];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1277d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[3];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1278d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1279d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[4];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1280d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[5];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1281d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[6];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1282d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[7];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1283d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1284d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[8];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1285d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[9];  sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1286d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[10]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1287d6c17253ec35b2233840542eaf8339fa92062902sewardj   w = p[11]; sum1 = ROL64(sum1 ^ w, 63);  sum2 += w;
1288d6c17253ec35b2233840542eaf8339fa92062902sewardj   sum1 ^= sum2;
1289d6c17253ec35b2233840542eaf8339fa92062902sewardj   return sum1 + sum2;
1290d6c17253ec35b2233840542eaf8339fa92062902sewardj}
1291d6c17253ec35b2233840542eaf8339fa92062902sewardj
12929e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
1293cef7d3e3df4796e35b4521158d9dc058f034aa87sewardj/*--- end                                 guest_generic_bb_to_IR.c ---*/
12949e6491ab55324b8e45e187b1e1e9632ac3cb3e27sewardj/*--------------------------------------------------------------------*/
1295