|
From: <sv...@va...> - 2007-01-12 20:29:10
|
Author: sewardj
Date: 2007-01-12 20:29:01 +0000 (Fri, 12 Jan 2007)
New Revision: 1725
Log:
Implement rcl{b,w,l,q} on amd64.
Modified:
trunk/priv/guest-amd64/gdefs.h
trunk/priv/guest-amd64/ghelpers.c
trunk/priv/guest-amd64/toIR.c
Modified: trunk/priv/guest-amd64/gdefs.h
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/gdefs.h 2007-01-10 05:22:03 UTC (rev 1724)
+++ trunk/priv/guest-amd64/gdefs.h 2007-01-12 20:29:01 UTC (rev 1725)
@@ -112,6 +112,10 @@
ULong arg, ULong rot_amt, ULong rflags_in, Long sz=20
);
=20
+extern ULong amd64g_calculate_RCL (=20
+ ULong arg, ULong rot_amt, ULong rflags_in, Long sz=20
+ );
+
extern ULong amd64g_check_fldcw ( ULong fpucw );
=20
extern ULong amd64g_create_fpucw ( ULong fpround );
Modified: trunk/priv/guest-amd64/ghelpers.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/ghelpers.c 2007-01-10 05:22:03 UTC (rev 1724)
+++ trunk/priv/guest-amd64/ghelpers.c 2007-01-12 20:29:01 UTC (rev 1725)
@@ -1899,7 +1899,73 @@
return wantRflags ? rflags_in : arg;
}
=20
+ULong amd64g_calculate_RCL ( ULong arg,=20
+ ULong rot_amt,=20
+ ULong rflags_in,=20
+ Long szIN )
+{
+ Bool wantRflags =3D toBool(szIN < 0);
+ ULong sz =3D wantRflags ? (-szIN) : szIN;
+ ULong tempCOUNT =3D rot_amt & (sz =3D=3D 8 ? 0x3F : 0x1F);
+ ULong cf=3D0, of=3D0, tempcf;
=20
+ switch (sz) {
+ case 8:
+ cf =3D (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ while (tempCOUNT > 0) {
+ tempcf =3D (arg >> 63) & 1;
+ arg =3D (arg << 1) | (cf & 1);
+ cf =3D tempcf;
+ tempCOUNT--;
+ }
+ of =3D ((arg >> 63) ^ cf) & 1;
+ break;
+ case 4:
+ while (tempCOUNT >=3D 33) tempCOUNT -=3D 33;
+ cf =3D (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ while (tempCOUNT > 0) {
+ tempcf =3D (arg >> 31) & 1;
+ arg =3D 0xFFFFFFFFULL & ((arg << 1) | (cf & 1));
+ cf =3D tempcf;
+ tempCOUNT--;
+ }
+ of =3D ((arg >> 31) ^ cf) & 1;
+ break;
+ case 2:
+ while (tempCOUNT >=3D 17) tempCOUNT -=3D 17;
+ cf =3D (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ while (tempCOUNT > 0) {
+ tempcf =3D (arg >> 15) & 1;
+ arg =3D 0xFFFFULL & ((arg << 1) | (cf & 1));
+ cf =3D tempcf;
+ tempCOUNT--;
+ }
+ of =3D ((arg >> 15) ^ cf) & 1;
+ break;
+ case 1:
+ while (tempCOUNT >=3D 9) tempCOUNT -=3D 9;
+ cf =3D (rflags_in >> AMD64G_CC_SHIFT_C) & 1;
+ while (tempCOUNT > 0) {
+ tempcf =3D (arg >> 7) & 1;
+ arg =3D 0xFFULL & ((arg << 1) | (cf & 1));
+ cf =3D tempcf;
+ tempCOUNT--;
+ }
+ of =3D ((arg >> 7) ^ cf) & 1;
+ break;
+ default:=20
+ vpanic("calculate_RCL(amd64g): invalid size");
+ }
+
+ cf &=3D 1;
+ of &=3D 1;
+ rflags_in &=3D ~(AMD64G_CC_MASK_C | AMD64G_CC_MASK_O);
+ rflags_in |=3D (cf << AMD64G_CC_SHIFT_C) | (of << AMD64G_CC_SHIFT_O);
+
+ return wantRflags ? rflags_in : arg;
+}
+
+
/* CALLED FROM GENERATED CODE */
/* DIRTY HELPER (non-referentially-transparent) */
/* Horrible hack. On non-amd64 platforms, return 1. */
Modified: trunk/priv/guest-amd64/toIR.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
--- trunk/priv/guest-amd64/toIR.c 2007-01-10 05:22:03 UTC (rev 1724)
+++ trunk/priv/guest-amd64/toIR.c 2007-01-12 20:29:01 UTC (rev 1725)
@@ -3006,7 +3006,7 @@
/* delta on entry points at the modrm byte. */
HChar dis_buf[50];
Int len;
- Bool isShift, isRotate, isRotateRC;
+ Bool isShift, isRotate, isRotateC;
IRType ty =3D szToITy(sz);
IRTemp dst0 =3D newTemp(ty);
IRTemp dst1 =3D newTemp(ty);
@@ -3030,14 +3030,15 @@
isRotate =3D False;
switch (gregLO3ofRM(modrm)) { case 0: case 1: isRotate =3D True; }
=20
- isRotateRC =3D toBool(gregLO3ofRM(modrm) =3D=3D 3);
+ isRotateC =3D False;
+ switch (gregLO3ofRM(modrm)) { case 2: case 3: isRotateC =3D True; }
=20
- if (!isShift && !isRotate && !isRotateRC) {
+ if (!isShift && !isRotate && !isRotateC) {
vex_printf("\ncase %d\n", gregLO3ofRM(modrm));
vpanic("dis_Grp2(Reg): unhandled case(amd64)");
}
=20
- if (isRotateRC) {
+ if (isRotateC) {
/* Call a helper; this insn is so ridiculous it does not deserve
better. One problem is, the helper has to calculate both the
new value and the new flags. This is more than 64 bits, and
@@ -3046,6 +3047,7 @@
using the sign of the sz field to indicate whether it is the
value or rflags result we want.
*/
+ Bool left =3D toBool(gregLO3ofRM(modrm) =3D=3D 2);
IRExpr** argsVALUE;
IRExpr** argsRFLAGS;
=20
@@ -3064,7 +3066,8 @@
mkIRExprCCall(
Ity_I64,=20
0/*regparm*/,=20
- "amd64g_calculate_RCR", &amd64g_calculate_RCR,
+ left ? "amd64g_calculate_RCL" : "amd64g_calculate_RC=
R",
+ left ? &amd64g_calculate_RCL : &amd64g_calculate_RC=
R,
argsVALUE
)
);
@@ -3078,7 +3081,8 @@
mkIRExprCCall(
Ity_I64,=20
0/*regparm*/,=20
- "amd64g_calculate_RCR", &amd64g_calculate_RCR,
+ left ? "amd64g_calculate_RCL" : "amd64g_calculate_RC=
R",
+ left ? &amd64g_calculate_RCL : &amd64g_calculate_RC=
R,
argsRFLAGS
)
);
|