From: Julian Seward Date: Tue, 23 Aug 2005 15:41:14 +0000 (+0000) Subject: Support x86 RCL instructions. X-Git-Tag: svn/VALGRIND_3_1_1^2~139 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f9350d2f3d22065f90e1b201073a8429b91b925;p=thirdparty%2Fvalgrind.git Support x86 RCL instructions. git-svn-id: svn://svn.valgrind.org/vex/trunk@1341 --- diff --git a/VEX/priv/guest-x86/gdefs.h b/VEX/priv/guest-x86/gdefs.h index 2d4b899e5a..1df4a446e3 100644 --- a/VEX/priv/guest-x86/gdefs.h +++ b/VEX/priv/guest-x86/gdefs.h @@ -104,7 +104,10 @@ extern UInt x86g_calculate_condition ( extern UInt x86g_calculate_FXAM ( UInt tag, ULong dbl ); -extern ULong x86g_calculate_RCR ( +extern ULong x86g_calculate_RCR ( + UInt arg, UInt rot_amt, UInt eflags_in, UInt sz + ); +extern ULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ); diff --git a/VEX/priv/guest-x86/ghelpers.c b/VEX/priv/guest-x86/ghelpers.c index db3487f11a..5aaaf9a45b 100644 --- a/VEX/priv/guest-x86/ghelpers.c +++ b/VEX/priv/guest-x86/ghelpers.c @@ -1638,6 +1638,61 @@ ULong x86g_calculate_RCR ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) } +/* CALLED FROM GENERATED CODE: CLEAN HELPER */ +/* Calculate both flags and value result for rotate left + through the carry bit. Result in low 32 bits, + new flags (OSZACP) in high 32 bits. +*/ +ULong x86g_calculate_RCL ( UInt arg, UInt rot_amt, UInt eflags_in, UInt sz ) +{ + UInt tempCOUNT = rot_amt & 0x1F, cf=0, of=0, tempcf; + + switch (sz) { + case 4: + cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; + while (tempCOUNT > 0) { + tempcf = (arg >> 31) & 1; + arg = (arg << 1) | (cf & 1); + cf = tempcf; + tempCOUNT--; + } + of = ((arg >> 31) ^ cf) & 1; + break; + case 2: + while (tempCOUNT >= 17) tempCOUNT -= 17; + cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; + while (tempCOUNT > 0) { + tempcf = (arg >> 15) & 1; + arg = 0xFFFF & ((arg << 1) | (cf & 1)); + cf = tempcf; + tempCOUNT--; + } + of = ((arg >> 15) ^ cf) & 1; + break; + case 1: + while (tempCOUNT >= 9) tempCOUNT -= 9; + cf = (eflags_in >> X86G_CC_SHIFT_C) & 1; + while (tempCOUNT > 0) { + tempcf = (arg >> 7) & 1; + arg = 0xFF & ((arg << 1) | (cf & 1)); + cf = tempcf; + tempCOUNT--; + } + of = ((arg >> 7) ^ cf) & 1; + break; + default: + vpanic("calculate_RCL: invalid size"); + } + + cf &= 1; + of &= 1; + eflags_in &= ~(X86G_CC_MASK_C | X86G_CC_MASK_O); + eflags_in |= (cf << X86G_CC_SHIFT_C) | (of << X86G_CC_SHIFT_O); + + return (((ULong)eflags_in) << 32) | ((ULong)arg); +} + + /* CALLED FROM GENERATED CODE */ /* DIRTY HELPER (modifies guest state) */ /* Claim to be a P55C (Intel Pentium/MMX) */ diff --git a/VEX/priv/guest-x86/toIR.c b/VEX/priv/guest-x86/toIR.c index 2cac30c6ed..f69dc5e1ef 100644 --- a/VEX/priv/guest-x86/toIR.c +++ b/VEX/priv/guest-x86/toIR.c @@ -2146,7 +2146,7 @@ UInt dis_Grp2 ( UChar sorb, /* delta on entry points at the modrm byte. */ HChar dis_buf[50]; Int len; - Bool isShift, isRotate, isRotateRC; + Bool isShift, isRotate, isRotateC; IRType ty = szToITy(sz); IRTemp dst0 = newTemp(ty); IRTemp dst1 = newTemp(ty); @@ -2170,16 +2170,18 @@ UInt dis_Grp2 ( UChar sorb, isRotate = False; switch (gregOfRM(modrm)) { case 0: case 1: isRotate = True; } - isRotateRC = toBool(gregOfRM(modrm) == 3); + isRotateC = False; + switch (gregOfRM(modrm)) { case 2: case 3: isRotateC = True; } - if (!isShift && !isRotate && !isRotateRC) { + if (!isShift && !isRotate && !isRotateC) { vex_printf("\ncase %d\n", gregOfRM(modrm)); vpanic("dis_Grp2(Reg): unhandled case(x86)"); } - if (isRotateRC) { - /* call a helper; this insn is so ridiculous it does not deserve - better */ + if (isRotateC) { + /* call a helper; these insns are so ridiculous they do not + deserve better */ + Bool left = toBool(gregOfRM(modrm) == 2); IRTemp r64 = newTemp(Ity_I64); IRExpr** args = mkIRExprVec_4( widenUto32(mkexpr(dst0)), /* thing to rotate */ @@ -2189,7 +2191,8 @@ UInt dis_Grp2 ( UChar sorb, assign( r64, mkIRExprCCall( Ity_I64, 0/*regparm*/, - "x86g_calculate_RCR", &x86g_calculate_RCR, + left ? "x86g_calculate_RCL" : "x86g_calculate_RCR", + left ? &x86g_calculate_RCL : &x86g_calculate_RCR, args ) );