/* Forwards .. */
-__attribute__((regparm(2)))
+VEX_REGPARM(2)
static UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_1 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_2 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_4 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_5 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 );
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 );
+VEX_REGPARM(2)
+static ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_1 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_2 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_3 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_4 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_5 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_6 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_7 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_8 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_9 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_10 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_11 ( HWord first_w64 );
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_12 ( HWord first_w64 );
+
/* Small helpers */
static Bool const_False ( void* callback_opaque, Addr64 a ) {
return False;
: IRConst_U64(guest_IP_bbstart);
}
- /* If asked to make a self-checking translation, leave 5 spaces
- in which to put the check statements. We'll fill them in later
- when we know the length and adler32 of the area to check. */
+ /* If asked to make a self-checking translation, leave 15 spaces in
+ which to put the check statements (up to 3 extents, and 5 stmts
+ required for each). We'll fill them in later when we know the
+ extents and checksums of the areas to check. */
if (do_self_check) {
selfcheck_idx = irsb->stmts_used;
- addStmtToIRSB( irsb, IRStmt_NoOp() );
- addStmtToIRSB( irsb, IRStmt_NoOp() );
- addStmtToIRSB( irsb, IRStmt_NoOp() );
- addStmtToIRSB( irsb, IRStmt_NoOp() );
- addStmtToIRSB( irsb, IRStmt_NoOp() );
+ for (i = 0; i < 3 * 5; i++)
+ addStmtToIRSB( irsb, IRStmt_NoOp() );
}
/* If the caller supplied a function to add its own preamble, use
resteerOK
= toBool(
n_instrs < vex_control.guest_chase_thresh
- /* If making self-checking translations, don't chase
- .. it makes the checks too complicated. We only want
- to scan just one sequence of bytes in the check, not
- a whole bunch. */
- && !do_self_check
/* we can't afford to have a resteer once we're on the
last extent slot. */
&& vge->n_used < 3
/* Add an instruction-mark statement. We won't know until after
disassembling the instruction how long it instruction is, so
- just put in a zero length and we'll fix it up later. */
- addStmtToIRSB( irsb, IRStmt_IMark( guest_IP_curr_instr, 0 ));
+ just put in a zero length and we'll fix it up later.
+
+ On ARM, the least significant bit of the instr address
+ distinguishes ARM vs Thumb instructions. All instructions
+ actually start on at least 2-aligned addresses. So we need
+ to ignore the bottom bit of the insn address when forming the
+ IMark. For more details of this convention, see comments on
+ definition of guest_R15 in libvex_guest_arm.h. */
+ addStmtToIRSB( irsb,
+ IRStmt_IMark( arch_guest == VexArchARM
+ ? (guest_IP_curr_instr & ~(Addr64)1)
+ : guest_IP_curr_instr,
+ 0
+ )
+ );
/* for the first insn, the dispatch loop will have set
%IP, but for all the others we have to do it ourselves. */
*/
if (do_self_check) {
- UInt len2check, expected32;
+ Addr64 base2check;
+ UInt len2check;
+ HWord expectedhW;
IRTemp tistart_tmp, tilen_tmp;
- UInt (*fn_generic)(HWord, HWord) __attribute__((regparm(2)));
- UInt (*fn_spec)(HWord) __attribute__((regparm(1)));
+ HWord VEX_REGPARM(2) (*fn_generic)(HWord, HWord);
+ HWord VEX_REGPARM(1) (*fn_spec)(HWord);
HChar* nm_generic;
HChar* nm_spec;
HWord fn_generic_entry = 0;
HWord fn_spec_entry = 0;
-
- vassert(vge->n_used == 1);
- len2check = vge->len[0];
-
- /* stay sane */
- vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
-
- /* Skip the check if the translation involved zero bytes */
- if (len2check > 0) {
- HWord first_w32 = ((HWord)guest_code) & ~(HWord)3;
- HWord last_w32 = (((HWord)guest_code) + len2check - 1) & ~(HWord)3;
- vassert(first_w32 <= last_w32);
- HWord w32_diff = last_w32 - first_w32;
- vassert(0 == (w32_diff & 3));
- HWord w32s_to_check = (w32_diff + 4) / 4;
- vassert(w32s_to_check > 0 && w32s_to_check < 1004/*arbitrary*//4);
+ UInt host_word_szB = sizeof(HWord);
+ IRType host_word_type = Ity_INVALID;
+
+ if (host_word_szB == 4) host_word_type = Ity_I32;
+ if (host_word_szB == 8) host_word_type = Ity_I64;
+ vassert(host_word_type != Ity_INVALID);
+
+ vassert(vge->n_used >= 1 && vge->n_used <= 3);
+ for (i = 0; i < vge->n_used; i++) {
+
+ /* the extent we're generating a check for */
+ base2check = vge->base[i];
+ len2check = vge->len[i];
+
+ /* stay sane */
+ vassert(len2check >= 0 && len2check < 1000/*arbitrary*/);
+
+ /* Skip the check if the translation involved zero bytes */
+ if (len2check == 0)
+ continue;
+
+ HWord first_hW = ((HWord)base2check)
+ & ~(HWord)(host_word_szB-1);
+ HWord last_hW = (((HWord)base2check) + len2check - 1)
+ & ~(HWord)(host_word_szB-1);
+ vassert(first_hW <= last_hW);
+ HWord hW_diff = last_hW - first_hW;
+ vassert(0 == (hW_diff & (host_word_szB-1)));
+ HWord hWs_to_check = (hW_diff + host_word_szB) / host_word_szB;
+ vassert(hWs_to_check > 0
+ && hWs_to_check < 1004/*arbitrary*/ / host_word_szB);
/* vex_printf("%lx %lx %ld\n", first_w32, last_w32, w32s_to_check); */
- fn_generic = genericg_compute_checksum_4al;
- nm_generic = "genericg_compute_checksum_4al";
+ if (host_word_szB == 8) {
+ fn_generic = (VEX_REGPARM(2) HWord(*)(HWord, HWord))
+ genericg_compute_checksum_8al;
+ nm_generic = "genericg_compute_checksum_8al";
+ } else {
+ fn_generic = (VEX_REGPARM(2) HWord(*)(HWord, HWord))
+ genericg_compute_checksum_4al;
+ nm_generic = "genericg_compute_checksum_4al";
+ }
+
fn_spec = NULL;
nm_spec = NULL;
- switch (w32s_to_check) {
- case 1: fn_spec = genericg_compute_checksum_4al_1;
- nm_spec = "genericg_compute_checksum_4al_1"; break;
- case 2: fn_spec = genericg_compute_checksum_4al_2;
- nm_spec = "genericg_compute_checksum_4al_2"; break;
- case 3: fn_spec = genericg_compute_checksum_4al_3;
- nm_spec = "genericg_compute_checksum_4al_3"; break;
- case 4: fn_spec = genericg_compute_checksum_4al_4;
- nm_spec = "genericg_compute_checksum_4al_4"; break;
- case 5: fn_spec = genericg_compute_checksum_4al_5;
- nm_spec = "genericg_compute_checksum_4al_5"; break;
- case 6: fn_spec = genericg_compute_checksum_4al_6;
- nm_spec = "genericg_compute_checksum_4al_6"; break;
- case 7: fn_spec = genericg_compute_checksum_4al_7;
- nm_spec = "genericg_compute_checksum_4al_7"; break;
- case 8: fn_spec = genericg_compute_checksum_4al_8;
- nm_spec = "genericg_compute_checksum_4al_8"; break;
- case 9: fn_spec = genericg_compute_checksum_4al_9;
- nm_spec = "genericg_compute_checksum_4al_9"; break;
- case 10: fn_spec = genericg_compute_checksum_4al_10;
- nm_spec = "genericg_compute_checksum_4al_10"; break;
- case 11: fn_spec = genericg_compute_checksum_4al_11;
- nm_spec = "genericg_compute_checksum_4al_11"; break;
- case 12: fn_spec = genericg_compute_checksum_4al_12;
- nm_spec = "genericg_compute_checksum_4al_12"; break;
- default: break;
+ if (host_word_szB == 8) {
+ HChar* nm = NULL;
+ ULong VEX_REGPARM(1) (*fn)(HWord) = NULL;
+ switch (hWs_to_check) {
+ case 1: fn = genericg_compute_checksum_8al_1;
+ nm = "genericg_compute_checksum_8al_1"; break;
+ case 2: fn = genericg_compute_checksum_8al_2;
+ nm = "genericg_compute_checksum_8al_2"; break;
+ case 3: fn = genericg_compute_checksum_8al_3;
+ nm = "genericg_compute_checksum_8al_3"; break;
+ case 4: fn = genericg_compute_checksum_8al_4;
+ nm = "genericg_compute_checksum_8al_4"; break;
+ case 5: fn = genericg_compute_checksum_8al_5;
+ nm = "genericg_compute_checksum_8al_5"; break;
+ case 6: fn = genericg_compute_checksum_8al_6;
+ nm = "genericg_compute_checksum_8al_6"; break;
+ case 7: fn = genericg_compute_checksum_8al_7;
+ nm = "genericg_compute_checksum_8al_7"; break;
+ case 8: fn = genericg_compute_checksum_8al_8;
+ nm = "genericg_compute_checksum_8al_8"; break;
+ case 9: fn = genericg_compute_checksum_8al_9;
+ nm = "genericg_compute_checksum_8al_9"; break;
+ case 10: fn = genericg_compute_checksum_8al_10;
+ nm = "genericg_compute_checksum_8al_10"; break;
+ case 11: fn = genericg_compute_checksum_8al_11;
+ nm = "genericg_compute_checksum_8al_11"; break;
+ case 12: fn = genericg_compute_checksum_8al_12;
+ nm = "genericg_compute_checksum_8al_12"; break;
+ default: break;
+ }
+ fn_spec = (VEX_REGPARM(1) HWord(*)(HWord)) fn;
+ nm_spec = nm;
+ } else {
+ HChar* nm = NULL;
+ UInt VEX_REGPARM(1) (*fn)(HWord) = NULL;
+ switch (hWs_to_check) {
+ case 1: fn = genericg_compute_checksum_4al_1;
+ nm = "genericg_compute_checksum_4al_1"; break;
+ case 2: fn = genericg_compute_checksum_4al_2;
+ nm = "genericg_compute_checksum_4al_2"; break;
+ case 3: fn = genericg_compute_checksum_4al_3;
+ nm = "genericg_compute_checksum_4al_3"; break;
+ case 4: fn = genericg_compute_checksum_4al_4;
+ nm = "genericg_compute_checksum_4al_4"; break;
+ case 5: fn = genericg_compute_checksum_4al_5;
+ nm = "genericg_compute_checksum_4al_5"; break;
+ case 6: fn = genericg_compute_checksum_4al_6;
+ nm = "genericg_compute_checksum_4al_6"; break;
+ case 7: fn = genericg_compute_checksum_4al_7;
+ nm = "genericg_compute_checksum_4al_7"; break;
+ case 8: fn = genericg_compute_checksum_4al_8;
+ nm = "genericg_compute_checksum_4al_8"; break;
+ case 9: fn = genericg_compute_checksum_4al_9;
+ nm = "genericg_compute_checksum_4al_9"; break;
+ case 10: fn = genericg_compute_checksum_4al_10;
+ nm = "genericg_compute_checksum_4al_10"; break;
+ case 11: fn = genericg_compute_checksum_4al_11;
+ nm = "genericg_compute_checksum_4al_11"; break;
+ case 12: fn = genericg_compute_checksum_4al_12;
+ nm = "genericg_compute_checksum_4al_12"; break;
+ default: break;
+ }
+ fn_spec = (VEX_REGPARM(1) HWord(*)(HWord))fn;
+ nm_spec = nm;
}
- expected32 = fn_generic( first_w32, w32s_to_check );
+ expectedhW = fn_generic( first_hW, hWs_to_check );
/* If we got a specialised version, check it produces the same
result as the generic version! */
if (fn_spec) {
vassert(nm_spec);
- vassert(expected32 == fn_spec( first_w32 ));
- } else {
+ vassert(expectedhW == fn_spec( first_hW ));
+ } else {
vassert(!nm_spec);
- }
+ }
- /* Set TISTART and TILEN. These will describe to the despatcher
- the area of guest code to invalidate should we exit with a
- self-check failure. */
+ /* Set TISTART and TILEN. These will describe to the despatcher
+ the area of guest code to invalidate should we exit with a
+ self-check failure. */
- tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
- tilen_tmp = newIRTemp(irsb->tyenv, guest_word_type);
+ tistart_tmp = newIRTemp(irsb->tyenv, guest_word_type);
+ tilen_tmp = newIRTemp(irsb->tyenv, guest_word_type);
- irsb->stmts[selfcheck_idx+0]
- = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(guest_IP_bbstart_IRConst) );
+ IRConst* base2check_IRConst
+ = guest_word_type==Ity_I32 ? IRConst_U32(toUInt(base2check))
+ : IRConst_U64(base2check);
+ IRConst* len2check_IRConst
+ = guest_word_type==Ity_I32 ? IRConst_U32(len2check)
+ : IRConst_U64(len2check);
- irsb->stmts[selfcheck_idx+1]
- = IRStmt_WrTmp(tilen_tmp,
- guest_word_type==Ity_I32
- ? IRExpr_Const(IRConst_U32(len2check))
- : IRExpr_Const(IRConst_U64(len2check))
- );
+ irsb->stmts[selfcheck_idx + i * 5 + 0]
+ = IRStmt_WrTmp(tistart_tmp, IRExpr_Const(base2check_IRConst) );
+
+ irsb->stmts[selfcheck_idx + i * 5 + 1]
+ = IRStmt_WrTmp(tilen_tmp, IRExpr_Const(len2check_IRConst) );
- irsb->stmts[selfcheck_idx+2]
- = IRStmt_Put( offB_TISTART, IRExpr_RdTmp(tistart_tmp) );
+ irsb->stmts[selfcheck_idx + i * 5 + 2]
+ = IRStmt_Put( offB_TISTART, IRExpr_RdTmp(tistart_tmp) );
- irsb->stmts[selfcheck_idx+3]
- = IRStmt_Put( offB_TILEN, IRExpr_RdTmp(tilen_tmp) );
+ irsb->stmts[selfcheck_idx + i * 5 + 3]
+ = IRStmt_Put( offB_TILEN, IRExpr_RdTmp(tilen_tmp) );
/* Generate the entry point descriptors */
- if (abiinfo_both->host_ppc_calls_use_fndescrs) {
+ if (abiinfo_both->host_ppc_calls_use_fndescrs) {
HWord* descr = (HWord*)fn_generic;
fn_generic_entry = descr[0];
if (fn_spec) {
fn_generic_entry = (HWord)fn_generic;
if (fn_spec) {
fn_spec_entry = (HWord)fn_spec;
- } else {
+ } else {
fn_spec_entry = (HWord)NULL;
}
}
IRExpr* callexpr = NULL;
if (fn_spec) {
callexpr = mkIRExprCCall(
- Ity_I32, 1/*regparms*/,
+ host_word_type, 1/*regparms*/,
nm_spec, (void*)fn_spec_entry,
mkIRExprVec_1(
- mkIRExpr_HWord( (HWord)first_w32 )
+ mkIRExpr_HWord( (HWord)first_hW )
)
);
} else {
callexpr = mkIRExprCCall(
- Ity_I32, 2/*regparms*/,
+ host_word_type, 2/*regparms*/,
nm_generic, (void*)fn_generic_entry,
mkIRExprVec_2(
- mkIRExpr_HWord( (HWord)first_w32 ),
- mkIRExpr_HWord( (HWord)w32s_to_check )
+ mkIRExpr_HWord( (HWord)first_hW ),
+ mkIRExpr_HWord( (HWord)hWs_to_check )
)
);
- }
+ }
- irsb->stmts[selfcheck_idx+4]
- = IRStmt_Exit(
- IRExpr_Binop(
- Iop_CmpNE32,
+ irsb->stmts[selfcheck_idx + i * 5 + 4]
+ = IRStmt_Exit(
+ IRExpr_Binop(
+ host_word_type==Ity_I64 ? Iop_CmpNE64 : Iop_CmpNE32,
callexpr,
- IRExpr_Const(IRConst_U32(expected32))
- ),
- Ijk_TInval,
- guest_IP_bbstart_IRConst
- );
- }
+ host_word_type==Ity_I64
+ ? IRExpr_Const(IRConst_U64(expectedhW))
+ : IRExpr_Const(IRConst_U32(expectedhW))
+ ),
+ Ijk_TInval,
+ /* Where we must restart if there's a failure: at the
+ first extent, regardless of which extent the
+ failure actually happened in. */
+ guest_IP_bbstart_IRConst
+ );
+ }
}
return irsb;
/* CALLED FROM GENERATED CODE */
/* Compute a checksum of host memory at [addr .. addr+len-1], as fast
- as possible. The _4al_4plus version is assured that the request is
- for 4-aligned memory and for a block of 4 or more long, whilst the
- _generic version must be able to handle any alignment, and lengths
- down to zero too. This fn is called once for every use of a
- self-checking translation, so it needs to be as fast as
- possible. */
+ as possible. All _4al versions assume that the supplied address is
+ 4 aligned. All length values are in 4-byte chunks. These fns
+ arecalled once for every use of a self-checking translation, so
+ they needs to be as fast as possible. */
+
+/* --- 32-bit versions, used only on 32-bit hosts --- */
static inline UInt ROL32 ( UInt w, Int n ) {
w = (w << n) | (w >> (32-n));
return w;
}
-__attribute((regparm(2)))
+VEX_REGPARM(2)
static UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s )
{
- UInt sum1 = 0, sum2 = 0;
+ UInt sum1 = 0, sum2 = 0;
UInt* p = (UInt*)first_w32;
/* unrolled */
while (n_w32s >= 4) {
/* Specialised versions of the above function */
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_1 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_2 ( HWord first_w32 )
{
- UInt sum1 = 0, sum2 = 0;
+ UInt sum1 = 0, sum2 = 0;
UInt* p = (UInt*)first_w32;
UInt w;
w = p[0]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_4 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
UInt* p = (UInt*)first_w32;
- UInt w;
- w = p[0]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
- w = p[1]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
- w = p[2]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
- w = p[3]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
- sum1 ^= sum2;
+ UInt w;
+ w = p[0]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
+ w = p[1]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
+ w = p[2]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
+ w = p[3]; sum1 = ROL32(sum1 ^ w, 31); sum2 += w;
+ sum1 ^= sum2;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_5 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
-__attribute__((regparm(1)))
+VEX_REGPARM(1)
static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 )
{
UInt sum1 = 0, sum2 = 0;
return sum1 + sum2;
}
+
+/* --- 64-bit versions, used only on 64-bit hosts --- */
+
+static inline ULong ROL64 ( ULong w, Int n ) {
+ w = (w << n) | (w >> (64-n));
+ return w;
+}
+
+VEX_REGPARM(2)
+static ULong genericg_compute_checksum_8al ( HWord first_w64, HWord n_w64s )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ /* unrolled */
+ while (n_w64s >= 4) {
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ p += 4;
+ n_w64s -= 4;
+ sum1 ^= sum2;
+ }
+ while (n_w64s >= 1) {
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ p += 1;
+ n_w64s -= 1;
+ sum1 ^= sum2;
+ }
+ return sum1 + sum2;
+}
+
+/* Specialised versions of the above function */
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_1 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_2 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_3 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_4 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_5 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_6 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_7 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_8 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[7]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_9 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[7]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[8]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_10 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[7]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[8]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[9]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_11 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[7]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[8]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[9]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[10]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
+VEX_REGPARM(1)
+static ULong genericg_compute_checksum_8al_12 ( HWord first_w64 )
+{
+ ULong sum1 = 0, sum2 = 0;
+ ULong* p = (ULong*)first_w64;
+ ULong w;
+ w = p[0]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[1]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[2]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[3]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[4]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[5]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[6]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[7]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ w = p[8]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[9]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[10]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ w = p[11]; sum1 = ROL64(sum1 ^ w, 63); sum2 += w;
+ sum1 ^= sum2;
+ return sum1 + sum2;
+}
+
/*--------------------------------------------------------------------*/
/*--- end guest_generic_bb_to_IR.c ---*/
/*--------------------------------------------------------------------*/