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
);
}
+/* 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) */
/* 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);
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 */
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
)
);