|
From: <sv...@va...> - 2006-02-07 16:43:47
|
Author: sewardj
Date: 2006-02-07 16:42:39 +0000 (Tue, 07 Feb 2006)
New Revision: 1571
Log:
ppc32/64: handle twi/tdi (conditional trap) instructions
Modified:
trunk/priv/guest-ppc/toIR.c
trunk/priv/host-ppc/hdefs.c
trunk/priv/ir/irdefs.c
trunk/pub/libvex_ir.h
trunk/pub/libvex_trc_values.h
Modified: trunk/priv/guest-ppc/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-ppc/toIR.c 2006-02-06 22:19:17 UTC (rev 1570)
+++ trunk/priv/guest-ppc/toIR.c 2006-02-07 16:42:39 UTC (rev 1571)
@@ -4483,6 +4483,130 @@
}
=20
=20
+/*=20
+ Trap instructions
+*/
+
+/* Do the code generation for a trap. Returned Bool is true iff
+ this is an unconditional trap. */
+static Bool do_trap ( IRType ty, UChar TO,=20
+ IRExpr* argL0, ULong argR0, Addr64 cia )
+{
+ IRTemp argL, argR;
+ IRExpr *argLe, *argRe, *cond, *tmp;
+
+ IROp opAND =3D ty=3D=3DIty_I32 ? Iop_And32 : Iop_And64;
+ IROp opOR =3D ty=3D=3DIty_I32 ? Iop_Or32 : Iop_Or64;
+ IROp opCMPORDS =3D ty=3D=3DIty_I32 ? Iop_CmpORD32S : Iop_CmpORD64S=
;
+ IROp opCMPORDU =3D ty=3D=3DIty_I32 ? Iop_CmpORD32U : Iop_CmpORD64U=
;
+ IROp opCMPNE =3D ty=3D=3DIty_I32 ? Iop_CmpNE32 : Iop_CmpNE64;
+ IROp opCMPEQ =3D ty=3D=3DIty_I32 ? Iop_CmpEQ32 : Iop_CmpEQ64;
+ IRExpr* const0 =3D ty=3D=3DIty_I32 ? mkU32(0) : mkU64(0);
+ IRExpr* const2 =3D ty=3D=3DIty_I32 ? mkU32(2) : mkU64(2);
+ IRExpr* const4 =3D ty=3D=3DIty_I32 ? mkU32(4) : mkU64(4);
+ IRExpr* const8 =3D ty=3D=3DIty_I32 ? mkU32(8) : mkU64(8);
+
+ const UChar b11100 =3D 0x1C;
+ const UChar b00111 =3D 0x07;
+
+ if ((TO & b11100) =3D=3D b11100 || (TO & b00111) =3D=3D b00111) {
+ /* Unconditional trap. Just do the exit without=20
+ testing the arguments. */
+ stmt( IRStmt_Exit(=20
+ binop(opCMPEQ, const0, const0),=20
+ Ijk_Trap,
+ mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia)=20
+ ));
+ return True; /* unconditional trap */
+ }
+
+ /* ty is the type at which the comparisons are done. This is not
+ the same as the 32/64-mode-ness. */
+ vassert(ty =3D=3D Ity_I32 || ty =3D=3D Ity_I64);
+ argL =3D newTemp(ty);
+ argR =3D newTemp(ty);
+ if (ty =3D=3D Ity_I32) {
+ assign( argL, mkSzNarrow32(Ity_I32, argL0) );
+ assign( argR, mkU32( (UInt)argR0 ));
+ } else {
+ vassert(mode64);
+ assign( argL, argL0 );
+ assign( argR, mkU64( argR0 ));
+ }
+ argLe =3D mkexpr(argL);
+ argRe =3D mkexpr(argR);
+ cond =3D const0;
+ if (TO & 16) { // L <s R
+ tmp =3D binop(opAND, binop(opCMPORDS, argLe, argRe), const8);
+ cond =3D binop(opOR, tmp, cond);
+ }
+ if (TO & 8) { // L >s R
+ tmp =3D binop(opAND, binop(opCMPORDS, argLe, argRe), const4);
+ cond =3D binop(opOR, tmp, cond);
+ }
+ if (TO & 4) { // L =3D=3D R
+ tmp =3D binop(opAND, binop(opCMPORDS, argLe, argRe), const2);
+ cond =3D binop(opOR, tmp, cond);
+ }
+ if (TO & 2) { // L <u R
+ tmp =3D binop(opAND, binop(opCMPORDU, argLe, argRe), const8);
+ cond =3D binop(opOR, tmp, cond);
+ }
+ if (TO & 1) { // L >u R
+ tmp =3D binop(opAND, binop(opCMPORDU, argLe, argRe), const4);
+ cond =3D binop(opOR, tmp, cond);
+ }
+ stmt( IRStmt_Exit(=20
+ binop(opCMPNE, cond, const0),=20
+ Ijk_Trap,
+ mode64 ? IRConst_U64(cia) : IRConst_U32((UInt)cia)=20
+ ));
+ return False; /* not an unconditional trap */
+}
+
+static Bool dis_trapi ( UInt theInstr,
+ /*OUT*/DisResult* dres )
+{
+ /* D-Form */
+ UChar opc1 =3D ifieldOPC(theInstr);
+ UChar TO =3D ifieldRegDS(theInstr);
+ UChar rA_addr =3D ifieldRegA(theInstr);
+ UInt uimm16 =3D ifieldUIMM16(theInstr);
+ ULong simm16 =3D extend_s_16to64(uimm16);
+ Addr64 cia =3D guest_CIA_curr_instr;
+ IRType ty =3D mode64 ? Ity_I64 : Ity_I32;
+ Bool uncond =3D False;
+
+ switch (opc1) {
+ case 0x03: // twi (Trap Word Immediate, PPC32 p548)
+ uncond =3D do_trap( Ity_I32, TO, getIReg(rA_addr), simm16, cia );
+ if (TO =3D=3D 4) {
+ DIP("tweqi r%u,%d\n", (UInt)rA_addr, (Int)simm16);
+ } else {
+ DIP("tw%di r%u,%d\n", (Int)TO, (UInt)rA_addr, (Int)simm16);
+ }
+ break;
+ case 0x02: // tdi
+ if (!mode64)
+ return False;
+ uncond =3D do_trap( Ity_I64, TO, getIReg(rA_addr), simm16, cia );
+ break;
+ default:
+ return False;
+ }
+
+ if (uncond) {
+ /* If the trap shows signs of being unconditional, don't
+ continue decoding past it. */
+ irbb->next =3D mkSzImm( ty, nextInsnAddr() );
+ irbb->jumpkind =3D Ijk_Boring;
+ dres->whatNext =3D Dis_StopHere;
+ }
+
+ return True;
+}
+
+
/*
System Linkage Instructions
*/
@@ -8725,13 +8849,10 @@
if (dis_syslink(theInstr, &dres)) goto decode_success;
goto decode_failure;
=20
-//zz /* Trap Instructions */
-//zz case 0x02: // tdi
-//zz DIP("trap op (tdi) =3D> not implemented\n");
-//zz goto decode_failure;
-//zz case 0x03: // twi
-//zz DIP("trap op (twi) =3D> not implemented\n");
-//zz goto decode_failure;
+ /* Trap Instructions */
+ case 0x02: case 0x03: // tdi, twi
+ if (dis_trapi(theInstr, &dres)) goto decode_success;
+ goto decode_failure;
=20
/* Floating Point Load Instructions */
case 0x30: case 0x31: case 0x32: // lfs, lfsu, lfd
Modified: trunk/priv/host-ppc/hdefs.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/host-ppc/hdefs.c 2006-02-06 22:19:17 UTC (rev 1570)
+++ trunk/priv/host-ppc/hdefs.c 2006-02-07 16:42:39 UTC (rev 1571)
@@ -2941,6 +2941,7 @@
case Ijk_NoDecode: trc =3D VEX_TRC_JMP_NODECODE; break;
case Ijk_TInval: trc =3D VEX_TRC_JMP_TINVAL; break;
case Ijk_NoRedir: trc =3D VEX_TRC_JMP_NOREDIR; break;
+ case Ijk_Trap: trc =3D VEX_TRC_JMP_TRAP; break;
case Ijk_Ret:
case Ijk_Call:
case Ijk_Boring:
Modified: trunk/priv/ir/irdefs.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/ir/irdefs.c 2006-02-06 22:19:17 UTC (rev 1570)
+++ trunk/priv/ir/irdefs.c 2006-02-07 16:42:39 UTC (rev 1571)
@@ -703,6 +703,7 @@
case Ijk_MapFail: vex_printf("MapFail"); break;
case Ijk_TInval: vex_printf("Invalidate"); break;
case Ijk_NoRedir: vex_printf("NoRedir"); break;
+ case Ijk_Trap: vex_printf("Trap"); break;
case Ijk_Sys_syscall: vex_printf("Sys_syscall"); break;
case Ijk_Sys_int32: vex_printf("Sys_int32"); break;
case Ijk_Sys_int128: vex_printf("Sys_int128"); break;
Modified: trunk/pub/libvex_ir.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_ir.h 2006-02-06 22:19:17 UTC (rev 1570)
+++ trunk/pub/libvex_ir.h 2006-02-07 16:42:39 UTC (rev 1571)
@@ -912,6 +912,7 @@
Ijk_MapFail, /* Vex-provided address translation failed */
Ijk_TInval, /* Invalidate translations before continuing. =
*/
Ijk_NoRedir, /* Jump to un-redirected guest addr */
+ Ijk_Trap, /* current instruction did a user trap */
/* Unfortunately, various guest-dependent syscall kinds. They
all mean: do a syscall before continuing. */
Ijk_Sys_syscall, /* amd64 'syscall', ppc 'sc' */
Modified: trunk/pub/libvex_trc_values.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_trc_values.h 2006-02-06 22:19:17 UTC (rev 1570)
+++ trunk/pub/libvex_trc_values.h 2006-02-07 16:42:39 UTC (rev 1571)
@@ -62,6 +62,8 @@
#define VEX_TRC_JMP_TINVAL 61 /* invalidate translations before
continuing */
#define VEX_TRC_JMP_NOREDIR 81 /* jump to undirected guest addr */
+#define VEX_TRC_JMP_TRAP 85 /* deliver trap (SIGTRAP?) before
+ continuing */
#define VEX_TRC_JMP_EMWARN 63 /* deliver emulation warning before
continuing */
#define VEX_TRC_JMP_EMFAIL 83 /* emulation fatal error; abort syste=
m */
|