|
From: <sv...@va...> - 2006-03-05 19:20:17
|
Author: sewardj
Date: 2006-03-05 19:20:08 +0000 (Sun, 05 Mar 2006)
New Revision: 1580
Log:
merge r1579 (Implement mtocrf/mfocrf.)
Modified:
branches/VEX_3_1_BRANCH/priv/guest-ppc32/toIR.c
Modified: branches/VEX_3_1_BRANCH/priv/guest-ppc32/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
--- branches/VEX_3_1_BRANCH/priv/guest-ppc32/toIR.c 2006-03-01 18:58:39 U=
TC (rev 1579)
+++ branches/VEX_3_1_BRANCH/priv/guest-ppc32/toIR.c 2006-03-05 19:20:08 U=
TC (rev 1580)
@@ -3760,14 +3760,23 @@
break;
}
=20
- case 0x013: // mfcr (Move from Condition Register, PPC32 p467)
- if (b11to20 !=3D 0) {
- vex_printf("dis_proc_ctl(PPC32)(mfcr,b11to20)\n");
- return False;
+ case 0x013:
+ // b11to20=3D=3D0: mfcr (Move from Cond Register, PPC32 p467)
+ // b20=3D=3D1 & b11=3D=3D0: mfocrf (Move from One CR Field)
+ // However it seems that the 'mfcr' behaviour is an acceptable
+ // implementation of mfocr (from the 2.02 arch spec)
+ if (b11to20 =3D=3D 0) {
+ DIP("mfcr r%u\n", rD_addr);
+ putIReg( rD_addr, getSPR( PPC32_SPR_CR ) );
+ break;
}
- DIP("mfcr r%d\n", rD_addr);
- putIReg( rD_addr, getSPR( PPC32_SPR_CR ) );
- break;
+ if (b20 =3D=3D 1 && b11 =3D=3D 0) {
+ DIP("mfocrf r%u,%u\n", rD_addr, CRM);
+ putIReg( rD_addr, getSPR( PPC32_SPR_CR ) );
+ break;
+ }
+ /* not decodable */
+ return False;
=20
/* XFX-Form */
case 0x153: // mfspr (Move from Special-Purpose Register, PPC32 p470)
@@ -3838,14 +3847,27 @@
break;
}
=20
- case 0x090: { // mtcrf (Move to Condition Register Fields, PPC32 p477=
)
+ case 0x090: {
+ // b20=3D=3D0: mtcrf (Move to Cond Register Fields, PPC32 p477)
+ // b20=3D=3D1: mtocrf (Move to One Cond Reg Field)
Int cr;
UChar shft;
- if (b11 !=3D 0 || b20 !=3D 0) {
- vex_printf("dis_proc_ctl(PPC32)(mtcrf,b11|b20)\n");
+ if (b11 !=3D 0)
return False;
+ if (b20 =3D=3D 1) {
+ /* ppc64 v2.02 spec says mtocrf gives undefined outcome if >
+ 1 field is written. It seems more robust to decline to
+ decode the insn if so. */
+ switch (CRM) {
+ case 0x01: case 0x02: case 0x04: case 0x08:
+ case 0x10: case 0x20: case 0x40: case 0x80:
+ break;
+ default:
+ return False;
+ }
}
- DIP("mtcrf 0x%x,r%d\n", CRM, rS_addr);
+ DIP("%s 0x%x,r%u\n", b20=3D=3D1 ? "mtocrf" : "mtcrf",
+ CRM, rS_addr);
/* Write to each field specified by CRM */
for (cr =3D 0; cr < 8; cr++) {
if ((CRM & (1 << (7-cr))) =3D=3D 0)
@@ -3857,6 +3879,9 @@
break;
}
=20
+
+
+
case 0x1D3: // mtspr (Move to Special-Purpose Register, PPC32 p483)
=20
switch (SPR) { // Choose a register...
|