X-Git-Url: https://rtime.felk.cvut.cz/gitweb/l4.git/blobdiff_plain/f4122e6e085938b6d216a9ec724b974a603f6992..983fe7c4ac262f56d38a143b1efab1e4afb77a52:/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_generic_bb_to_IR.c diff --git a/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_generic_bb_to_IR.c b/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_generic_bb_to_IR.c index c2be377db..1e59c70e0 100644 --- a/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_generic_bb_to_IR.c +++ b/l4/pkg/valgrind/src/valgrind-3.6.0-svn/VEX/priv/guest_generic_bb_to_IR.c @@ -42,33 +42,60 @@ /* 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; @@ -173,16 +200,14 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, : 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 @@ -208,11 +233,6 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, 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 @@ -241,8 +261,21 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, /* 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. */ @@ -401,101 +434,167 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, */ 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) { @@ -508,7 +607,7 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, fn_generic_entry = (HWord)fn_generic; if (fn_spec) { fn_spec_entry = (HWord)fn_spec; - } else { + } else { fn_spec_entry = (HWord)NULL; } } @@ -516,34 +615,39 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, 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; @@ -558,22 +662,22 @@ IRSB* bb_to_IR ( /*OUT*/VexGuestExtents* vge, /* 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) { @@ -598,7 +702,7 @@ static UInt genericg_compute_checksum_4al ( HWord first_w32, HWord n_w32s ) /* 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; @@ -609,10 +713,10 @@ static UInt genericg_compute_checksum_4al_1 ( HWord first_w32 ) 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; @@ -622,7 +726,7 @@ static UInt genericg_compute_checksum_4al_2 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -637,21 +741,21 @@ static UInt genericg_compute_checksum_4al_3 ( HWord first_w32 ) 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; @@ -667,7 +771,7 @@ static UInt genericg_compute_checksum_4al_5 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -685,7 +789,7 @@ static UInt genericg_compute_checksum_4al_6 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -705,7 +809,7 @@ static UInt genericg_compute_checksum_4al_7 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -724,7 +828,7 @@ static UInt genericg_compute_checksum_4al_8 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -745,7 +849,7 @@ static UInt genericg_compute_checksum_4al_9 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -768,7 +872,7 @@ static UInt genericg_compute_checksum_4al_10 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -793,7 +897,7 @@ static UInt genericg_compute_checksum_4al_11 ( HWord first_w32 ) return sum1 + sum2; } -__attribute__((regparm(1))) +VEX_REGPARM(1) static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 ) { UInt sum1 = 0, sum2 = 0; @@ -817,6 +921,261 @@ static UInt genericg_compute_checksum_4al_12 ( HWord first_w32 ) 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 ---*/ /*--------------------------------------------------------------------*/