From: Julian Seward Date: Thu, 17 Jan 2013 14:23:53 +0000 (+0000) Subject: Merge, from branches/COMEM, revisions 2568 to 2641. X-Git-Tag: svn/VALGRIND_3_9_0^2~152 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c437ebd048d20fc1bf6f13983d4f0e73302736f8;p=thirdparty%2Fvalgrind.git Merge, from branches/COMEM, revisions 2568 to 2641. git-svn-id: svn://svn.valgrind.org/vex/trunk@2642 --- c437ebd048d20fc1bf6f13983d4f0e73302736f8 diff --cc VEX/priv/host_amd64_isel.c index 9c2c1070ae,9063b3fc84..5a13711496 --- a/VEX/priv/host_amd64_isel.c +++ b/VEX/priv/host_amd64_isel.c @@@ -1605,36 -1607,6 +1607,37 @@@ static HReg iselIntExpr_R_wrk ( ISelEnv return dst; } + case Iop_GetMSBs8x16: { + /* Note: the following assumes the helper is of signature + UInt fn ( ULong w64hi, ULong w64Lo ), + and is not a regparm fn. */ + HReg dst = newVRegI(env); + HReg vec = iselVecExpr(env, e->Iex.Unop.arg); + HReg rsp = hregAMD64_RSP(); + fn = (HWord)h_generic_calc_GetMSBs8x16; + AMD64AMode* m8_rsp = AMD64AMode_IR( -8, rsp); + AMD64AMode* m16_rsp = AMD64AMode_IR(-16, rsp); + addInstr(env, AMD64Instr_SseLdSt(False/*store*/, + 16, vec, m16_rsp)); + /* hi 64 bits into RDI -- the first arg */ + addInstr(env, AMD64Instr_Alu64R( Aalu_MOV, + AMD64RMI_Mem(m8_rsp), + hregAMD64_RDI() )); /* 1st arg */ + /* lo 64 bits into RSI -- the 2nd arg */ + addInstr(env, AMD64Instr_Alu64R( Aalu_MOV, + AMD64RMI_Mem(m16_rsp), + hregAMD64_RSI() )); /* 2nd arg */ - addInstr(env, AMD64Instr_Call( Acc_ALWAYS, (ULong)fn, 2 )); ++ addInstr(env, AMD64Instr_Call( Acc_ALWAYS, (ULong)fn, ++ 2, RetLocInt )); + /* MovxLQ is not exactly the right thing here. We just + need to get the bottom 16 bits of RAX into dst, and zero + out everything else. Assuming that the helper returns + a UInt with the top 16 bits zeroed out, it'll do, + though. */ + addInstr(env, AMD64Instr_MovxLQ(False, hregAMD64_RAX(), dst)); + return dst; + } + default: break; } diff --cc VEX/priv/ir_opt.c index 89db9ea380,c8d018f2b5..3c52c17373 --- a/VEX/priv/ir_opt.c +++ b/VEX/priv/ir_opt.c @@@ -2399,6 -2439,62 +2431,62 @@@ static IRStmt* subst_and_fold_Stmt ( IR fold_Expr(env, subst_Expr(env, st->Ist.Store.data)) ); + case Ist_StoreG: { + IRStoreG* sg = st->Ist.StoreG.details; + vassert(isIRAtom(sg->addr)); + vassert(isIRAtom(sg->data)); + vassert(isIRAtom(sg->guard)); + IRExpr* faddr = fold_Expr(env, subst_Expr(env, sg->addr)); + IRExpr* fdata = fold_Expr(env, subst_Expr(env, sg->data)); + IRExpr* fguard = fold_Expr(env, subst_Expr(env, sg->guard)); + if (fguard->tag == Iex_Const) { + /* The condition on this store has folded down to a constant. */ + vassert(fguard->Iex.Const.con->tag == Ico_U1); + if (fguard->Iex.Const.con->Ico.U1 == False) { + return IRStmt_NoOp(); + } else { + vassert(fguard->Iex.Const.con->Ico.U1 == True); + return IRStmt_Store(sg->end, faddr, fdata); + } + } + return IRStmt_StoreG(sg->end, faddr, fdata, fguard); + } + + case Ist_LoadG: { + /* This is complicated. If the guard folds down to 'false', - we can replace it with a NoOp, but if the guard folds down - to 'true', we can't conveniently replace it with an - unconditional load, because doing so requires generating a - new temporary, and that is not easy to do at this - point. */ ++ we can replace it with an assignment 'dst := alt', but if ++ the guard folds down to 'true', we can't conveniently ++ replace it with an unconditional load, because doing so ++ requires generating a new temporary, and that is not easy ++ to do at this point. */ + IRLoadG* lg = st->Ist.LoadG.details; + vassert(isIRAtom(lg->addr)); + vassert(isIRAtom(lg->alt)); + vassert(isIRAtom(lg->guard)); + IRExpr* faddr = fold_Expr(env, subst_Expr(env, lg->addr)); + IRExpr* falt = fold_Expr(env, subst_Expr(env, lg->alt)); + IRExpr* fguard = fold_Expr(env, subst_Expr(env, lg->guard)); + if (fguard->tag == Iex_Const) { + /* The condition on this load has folded down to a constant. */ + vassert(fguard->Iex.Const.con->tag == Ico_U1); + if (fguard->Iex.Const.con->Ico.U1 == False) { + /* The load is not going to happen -- instead 'alt' is + assigned to 'dst'. */ + return IRStmt_WrTmp(lg->dst, falt); + } else { + vassert(fguard->Iex.Const.con->Ico.U1 == True); + /* The load is always going to happen. We want to + convert to an unconditional load and assign to 'dst' + (IRStmt_WrTmp). Problem is we need an extra temp to + hold the loaded value, but none is available. + Instead, reconstitute the conditional load (with + folded args, of course) and let the caller of this + routine deal with the problem. */ + } + } + return IRStmt_LoadG(lg->end, lg->cvt, lg->dst, faddr, falt, fguard); + } + case Ist_CAS: { IRCAS *cas, *cas2; cas = st->Ist.CAS.details; diff --cc VEX/pub/libvex_ir.h index 1a34ca311d,715d85d070..c132995320 --- a/VEX/pub/libvex_ir.h +++ b/VEX/pub/libvex_ir.h @@@ -1980,12 -1920,13 +1981,12 @@@ extern void ppIRJumpKind ( IRJumpKind ) In order that instrumentation is possible, the call must state, and state correctly: - * whether it reads, writes or modifies memory, and if so where - (only one chunk can be stated) - * whether it reads, writes or modifies memory, and if so where Only - one chunk can be stated, although it is allowed to repeat some - number of times at a fixed interval. ++ * Whether it reads, writes or modifies memory, and if so where. -- * whether it reads, writes or modifies guest state, and if so which - pieces (several pieces may be stated, and currently their extents - must be known at translation-time). ++ * Whether it reads, writes or modifies guest state, and if so which + pieces. Several pieces may be stated, and their extents must be - known at translation-time. ++ known at translation-time. Each piece is allowed to repeat some ++ number of times at a fixed interval, if required. Normally, code is generated to pass just the args to the helper. However, if .needsBBP is set, then an extra first argument is