|
From: <sv...@va...> - 2005-08-04 18:32:26
|
Author: sewardj
Date: 2005-08-04 19:32:19 +0100 (Thu, 04 Aug 2005)
New Revision: 1316
Log:
- Partial implementation of reservations, to make lwarx/stwcx. work
- Reenable some more integer insns
Modified:
trunk/priv/guest-ppc32/ghelpers.c
trunk/priv/guest-ppc32/toIR.c
trunk/pub/libvex_guest_ppc32.h
Modified: trunk/priv/guest-ppc32/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-ppc32/ghelpers.c 2005-08-03 23:48:38 UTC (rev 1315)
+++ trunk/priv/guest-ppc32/ghelpers.c 2005-08-04 18:32:19 UTC (rev 1316)
@@ -374,6 +374,8 @@
=20
vex_state->guest_TISTART =3D 0;
vex_state->guest_TILEN =3D 0;
+
+ vex_state->guest_RESVN =3D 0;
}
=20
=20
@@ -444,7 +446,7 @@
=20
/* Describe any sections to be regarded by Memcheck as
'always-defined'. */
- .n_alwaysDefd =3D 6,
+ .n_alwaysDefd =3D 7,
=20
.alwaysDefd=20
=3D { /* 0 */ ALWAYSDEFD(guest_CIA),
@@ -452,7 +454,8 @@
/* 2 */ ALWAYSDEFD(guest_TISTART),
/* 3 */ ALWAYSDEFD(guest_TILEN),
/* 4 */ ALWAYSDEFD(guest_VSCR),
- /* 5 */ ALWAYSDEFD(guest_FPROUND)
+ /* 5 */ ALWAYSDEFD(guest_FPROUND),
+ /* 6 */ ALWAYSDEFD(guest_RESVN)
}
};
=20
Modified: trunk/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
--- trunk/priv/guest-ppc32/toIR.c 2005-08-03 23:48:38 UTC (rev 1315)
+++ trunk/priv/guest-ppc32/toIR.c 2005-08-04 18:32:19 UTC (rev 1316)
@@ -154,7 +154,9 @@
#define OFFB_TISTART offsetof(VexGuestPPC32State,guest_TISTART)
#define OFFB_TILEN offsetof(VexGuestPPC32State,guest_TILEN)
=20
+#define OFFB_RESVN offsetof(VexGuestPPC32State,guest_RESVN)
=20
+
/*------------------------------------------------------------*/
/*--- Extract instruction fields --- */
/*------------------------------------------------------------*/
@@ -368,6 +370,7 @@
=20
static void storeBE ( IRExpr* addr, IRExpr* data )
{
+ vassert(typeOfIRExpr(irbb->tyenv, addr) =3D=3D Ity_I32);
stmt( IRStmt_Store(Iend_BE,addr,data) );
}
=20
@@ -2339,15 +2342,15 @@
loadBE(Ity_I16, mkexpr(EA_reg))) );
break;
=20
-//zz case 0x037: // lwzux (Load W & Zero with Update Indexed, PPC3=
2 p462)
-//zz if (Ra_addr =3D=3D 0 || Ra_addr =3D=3D Rd_addr) {
-//zz vex_printf("dis_int_load(PPC32)(lwzux,Ra_addr|Rd_addr)\=
n");
-//zz return False;
-//zz }
-//zz DIP("lwzux r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr);
-//zz putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA_reg)) );
-//zz putIReg( Ra_addr, mkexpr(EA_reg) );
-//zz break;
+ case 0x037: // lwzux (Load W & Zero with Update Indexed, PPC32 p46=
2)
+ if (Ra_addr =3D=3D 0 || Ra_addr =3D=3D Rd_addr) {
+ vex_printf("dis_int_load(PPC32)(lwzux,Ra_addr|Rd_addr)\n");
+ return False;
+ }
+ DIP("lwzux r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr);
+ putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA_reg)) );
+ putIReg( Ra_addr, mkexpr(EA_reg) );
+ break;
=20
case 0x017: // lwzx (Load W & Zero Indexed, PPC32 p463)
DIP("lwzx r%d,r%d,r%d\n", Rd_addr, Ra_addr, Rb_addr);
@@ -2521,71 +2524,67 @@
=20
=20
=20
+/*
+ Integer Load/Store Multiple Instructions
+*/
+static Bool dis_int_ldst_mult ( UInt theInstr )
+{
+ /* D-Form */
+ UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr[26:3=
1] */
+ UChar Rd_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:2=
5] */
+ UChar Rs_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr[21:2=
5] */
+ UChar Ra_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr[16:2=
0] */
+ UInt d_imm =3D (theInstr >> 0) & 0xFFFF; /* theInstr[0:15=
] */
+ =20
+ UInt exts_d_imm =3D extend_s_16to32(d_imm);
+ UInt reg_idx =3D 0;
+ UInt offset =3D 0;
+ =20
+ IRTemp Ra =3D newTemp(Ity_I32);
+ IRTemp EA =3D newTemp(Ity_I32);
+ =20
+ IRExpr* irx_addr;
+ =20
+ if (Ra_addr =3D=3D 0) {
+ assign( EA, binop(Iop_Add32, mkU32(0), mkU32(exts_d_imm)) );
+ } else {
+ assign( Ra, getIReg(Ra_addr) );
+ assign( EA, binop(Iop_Add32, mkexpr(Ra), mkU32(exts_d_imm)) );
+ }
+ =20
+ switch (opc1) {
+ case 0x2E: // lmw (Load Multiple Word, PPC32 p454)
+ if (Ra_addr >=3D Rd_addr) {
+ vex_printf("dis_int_ldst_mult(PPC32)(lmw,Ra_addr)\n");
+ return False;
+ }
+ DIP("lmw r%d,%d(r%d)\n", Rd_addr, (Int)d_imm, Ra_addr);
+ for (reg_idx =3D Rd_addr; reg_idx <=3D 31; reg_idx++) {
+ irx_addr =3D binop(Iop_Add32, mkexpr(EA), mkU32(offset));
+ putIReg( reg_idx, loadBE(Ity_I32, irx_addr ) );
+ offset +=3D 4;
+ }
+ break;
+ =20
+ case 0x2F: // stmw (Store Multiple Word, PPC32 p527)
+ DIP("stmw r%d,%d(r%d)\n", Rs_addr, (Int)d_imm, Ra_addr);
+ for (reg_idx =3D Rs_addr; reg_idx <=3D 31; reg_idx++) {
+ irx_addr =3D binop(Iop_Add32, mkexpr(EA), mkU32(offset));
+ storeBE( irx_addr, getIReg(reg_idx) );
+ offset +=3D 4;
+ }
+ break;
+ =20
+ default:
+ vex_printf("dis_int_ldst_mult(PPC32)(opc1)\n");
+ return False;
+ }
+ return True;
+}
+
+
+
//zz /*
-//zz Integer Load/Store Multiple Instructions
-//zz */
-//zz static Bool dis_int_ldst_mult ( UInt theInstr )
-//zz {
-//zz /* D-Form */
-//zz UChar opc1 =3D toUChar((theInstr >> 26) & 0x3F); /* theInstr=
[26:31] */
-//zz UChar Rd_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr=
[21:25] */
-//zz UChar Rs_addr =3D toUChar((theInstr >> 21) & 0x1F); /* theInstr=
[21:25] */
-//zz UChar Ra_addr =3D toUChar((theInstr >> 16) & 0x1F); /* theInstr=
[16:20] */
-//zz UInt d_imm =3D (theInstr >> 0) & 0xFFFF; /* theInstr=
[0:15] */
-//zz =20
-//zz UInt exts_d_imm =3D extend_s_16to32(d_imm);
-//zz UInt reg_idx =3D 0;
-//zz UInt offset =3D 0;
-//zz =20
-//zz IRTemp Ra =3D newTemp(Ity_I32);
-//zz IRTemp EA =3D newTemp(Ity_I32);
-//zz =20
-//zz IRExpr* irx_addr;
-//zz =20
-//zz if (Ra_addr =3D=3D 0) {
-//zz assign( EA, binop(Iop_Add32, mkU32(0), mkU32(exts_d_imm)) );
-//zz } else {
-//zz assign( Ra, getIReg(Ra_addr) );
-//zz assign( EA, binop(Iop_Add32, mkexpr(Ra), mkU32(exts_d_imm)) )=
;
-//zz }
-//zz =20
-//zz switch (opc1) {
-//zz case 0x2E: // lmw (Load Multiple Word, PPC32 p454)
-//zz vassert(1);
-//zz=20
-//zz if (Ra_addr >=3D Rd_addr) {
-//zz vex_printf("dis_int_ldst_mult(PPC32)(lmw,Ra_addr)\n");
-//zz return False;
-//zz }
-//zz DIP("lmw r%d,%d(r%d)\n", Rd_addr, (Int)d_imm, Ra_addr);
-//zz for (reg_idx =3D Rd_addr; reg_idx<=3D31; reg_idx++) {
-//zz irx_addr =3D binop(Iop_Add32, mkexpr(EA), mkU32(offset));
-//zz putIReg( reg_idx, loadBE(Ity_I32, irx_addr ) );
-//zz offset +=3D4;
-//zz }
-//zz break;
-//zz =20
-//zz case 0x2F: // stmw (Store Multiple Word, PPC32 p527)
-//zz vassert(1);
-//zz=20
-//zz DIP("stmw r%d,%d(r%d)\n", Rs_addr, (Int)d_imm, Ra_addr);
-//zz for (reg_idx =3D Rs_addr; reg_idx<=3D31; reg_idx++) {
-//zz irx_addr =3D binop(Iop_Add32, mkexpr(EA), mkU32(offset));
-//zz storeBE( irx_addr, getIReg(reg_idx) );
-//zz offset +=3D4;
-//zz }
-//zz break;
-//zz =20
-//zz default:
-//zz vex_printf("dis_int_ldst_mult(PPC32)(opc1)\n");
-//zz return False;
-//zz }
-//zz return True;
-//zz }
-//zz=20
-//zz=20
-//zz=20
-//zz /*
//zz Integer Load/Store String Instructions
//zz */
//zz static Bool dis_int_ldst_str ( UInt theInstr )
@@ -3067,11 +3066,12 @@
//zz DIP("crand crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, crb=
B_addr);
//zz assign( crbD, binop(Iop_And32, mkexpr(crbA), mkexpr(crbB))=
);
//zz break;
-//zz case 0x081: // crandc (Cond Reg AND w. Complement, PPC32 p37=
3)
-//zz DIP("crandc crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, cr=
bB_addr);
-//zz assign( crbD, binop(Iop_And32, mkexpr(crbA),
-//zz unop(Iop_Not32, mkexpr(crbB))) );
-//zz break;
+ case 0x081: // crandc (Cond Reg AND w. Complement, PPC32 p373)
+ DIP("crandc crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, crbB_ad=
dr);
+ assign( crbD, binop(Iop_And32,=20
+ mkexpr(crbA),
+ unop(Iop_Not32, mkexpr(crbB))) );
+ break;
case 0x121: // creqv (Cond Reg Equivalent, PPC32 p374)
DIP("creqv crb%d,crb%d,crb%d\n", crbD_addr, crbA_addr, crbB_add=
r);
assign( crbD, unop(Iop_Not32,
@@ -3176,15 +3176,15 @@
/* X-Form */
case 0x1F:
switch (opc2) {
-//zz case 0x356: // eieio (Enforce In-Order Execution of I/O, PPC3=
2 p394)
-//zz vassert(0);
-//zz=20
-//zz if (b11to25 !=3D 0 || b0 !=3D 0) {
-//zz vex_printf("dis_int_memsync(PPC32)(eiei0,b11to25|b0)\n"=
);
-//zz return False;
-//zz }
-//zz DIP("eieio\n");
-//zz return False;
+ case 0x356: // eieio (Enforce In-Order Execution of I/O, PPC32 p39=
4)
+ if (b11to25 !=3D 0 || b0 !=3D 0) {
+ vex_printf("dis_int_memsync(PPC32)(eiei0,b11to25|b0)\n");
+ return False;
+ }
+ DIP("eieio\n");
+ /* Insert a memory fence, just to be on the safe side. */
+ stmt( IRStmt_MFence() );
+ break;
=20
case 0x014: // lwarx (Load Word and Reserve Indexed, PPC32 p458)
/* Note: RESERVE, RESERVE_ADDR not implemented.
@@ -3203,12 +3203,17 @@
assign( EA, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) );
}
putIReg( Rd_addr, loadBE(Ity_I32, mkexpr(EA)) );
+ /* Take a reservation */
+ stmt( IRStmt_Put( OFFB_RESVN, mkexpr(EA) ));
+// stmt( IRStmt_Put( OFFB_RESVN, mkU32(1) ));
break;
=20
- case 0x096: // stwcx. (Store Word Conditional Indexed, PPC32 p532)
+ case 0x096: {=20
+ // stwcx. (Store Word Conditional Indexed, PPC32 p532)
/* Note: RESERVE, RESERVE_ADDR not implemented.
stwcx. is assumed to be always successful
*/
+ IRTemp resaddr =3D newTemp(Ity_I32);
if (b0 !=3D 1) {
vex_printf("dis_int_memsync(PPC32)(stwcx.,b0)\n");
return False;
@@ -3223,13 +3228,35 @@
assign( Ra, getIReg(Ra_addr) );
assign( EA, binop(Iop_Add32, mkexpr(Ra), mkexpr(Rb)) );
}
+ /* First set up as if the reservation failed */
+ // Set CR0[LT GT EQ S0] =3D 0b000 || XER[SO]
+ putCR321(0, mkU8(0<<1));
+ putCR0(0, getXER_SO());
+
+ /* Get the reservation address into a temporary, then
+ clear it. */
+ assign( resaddr, IRExpr_Get(OFFB_RESVN, Ity_I32) );
+ stmt( IRStmt_Put( OFFB_RESVN, mkU32(0) ));
+
+ /* Skip the rest if the reservation really did fail. */
+ stmt( IRStmt_Exit(
+ binop(Iop_CmpNE32, mkexpr(resaddr),
+ mkexpr(EA)),
+ // binop(Iop_CmpEQ32, IRExpr_Get(OFFB_RESVN, Ity_I32),
+ // mkU32(0)),
+ Ijk_Boring,
+ IRConst_U32(guest_CIA_curr_instr + 4)
+ )
+ );
+
+ /* Success? Do the store */
storeBE( mkexpr(EA), mkexpr(Rs) );
=20
// Set CR0[LT GT EQ S0] =3D 0b001 || XER[SO]
putCR321(0, mkU8(1<<1));
- putCR0(0, getXER_SO());
break;
- =20
+ }
+
case 0x256: // sync (Synchronize, PPC32 p543)
if (b11to25 !=3D 0 || b0 !=3D 0) {
vex_printf("dis_int_memsync(PPC32)(sync,b11to25|b0)\n");
@@ -6190,10 +6217,10 @@
if (dis_int_store( theInstr )) goto decode_success;
goto decode_failure;
=20
-//zz /* Integer Load and Store Multiple Instructions */
-//zz case 0x2E: case 0x2F: // lmw, stmw
-//zz if (dis_int_ldst_mult( theInstr )) goto decode_success;
-//zz goto decode_failure;
+ /* Integer Load and Store Multiple Instructions */
+ case 0x2E: case 0x2F: // lmw, stmw
+ if (dis_int_ldst_mult( theInstr )) goto decode_success;
+ goto decode_failure;
=20
/* Branch Instructions */
case 0x12: case 0x10: // b, bc
Modified: trunk/pub/libvex_guest_ppc32.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/pub/libvex_guest_ppc32.h 2005-08-03 23:48:38 UTC (rev 1315)
+++ trunk/pub/libvex_guest_ppc32.h 2005-08-04 18:32:19 UTC (rev 1316)
@@ -203,6 +203,10 @@
/* 944 */ UInt guest_TISTART;
/* 948 */ UInt guest_TILEN;
=20
+ /* For lwarx/stwcx.: 0 =3D=3D no reservation exists, non-0 =3D=3D =
a
+ reservation exists. */
+ /* 952 */ UInt guest_RESVN;
+
/* Padding to make it have an 8-aligned size */
/* UInt padding; */
}
|