From: Julian Seward Date: Tue, 28 Aug 2007 14:48:35 +0000 (+0000) Subject: Better support for trap insns. This adds support for tw (previously twi and X-Git-Tag: svn/VALGRIND_3_3_1^2~29 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16758635401a1cccc51f688ca2893582ef496a9a;p=thirdparty%2Fvalgrind.git Better support for trap insns. This adds support for tw (previously twi and tdi only were supported). td to follow. git-svn-id: svn://svn.valgrind.org/vex/trunk@1784 --- diff --git a/VEX/priv/guest-ppc/toIR.c b/VEX/priv/guest-ppc/toIR.c index 78f81a1672..dbfa4c887d 100644 --- a/VEX/priv/guest-ppc/toIR.c +++ b/VEX/priv/guest-ppc/toIR.c @@ -4546,27 +4546,41 @@ static Bool dis_cond_logic ( UInt theInstr ) */ /* Do the code generation for a trap. Returned Bool is true iff - this is an unconditional trap. */ -static Bool do_trap ( Bool is_twi, UChar TO, - IRExpr* argL0, ULong argR0, Addr64 cia ) + this is an unconditional trap. If the two arg IRExpr*s are + Ity_I32s then the comparison is 32-bit. If they are Ity_I64s + then they are 64-bit, and we must be disassembling 64-bit + instructions. */ +static Bool do_trap ( UChar TO, + IRExpr* argL0, IRExpr* argR0, Addr64 cia ) { IRTemp argL, argR; IRExpr *argLe, *argRe, *cond, *tmp; - IROp opAND = is_twi ? Iop_And32 : Iop_And64; - IROp opOR = is_twi ? Iop_Or32 : Iop_Or64; - IROp opCMPORDS = is_twi ? Iop_CmpORD32S : Iop_CmpORD64S; - IROp opCMPORDU = is_twi ? Iop_CmpORD32U : Iop_CmpORD64U; - IROp opCMPNE = is_twi ? Iop_CmpNE32 : Iop_CmpNE64; - IROp opCMPEQ = is_twi ? Iop_CmpEQ32 : Iop_CmpEQ64; - IRExpr* const0 = is_twi ? mkU32(0) : mkU64(0); - IRExpr* const2 = is_twi ? mkU32(2) : mkU64(2); - IRExpr* const4 = is_twi ? mkU32(4) : mkU64(4); - IRExpr* const8 = is_twi ? mkU32(8) : mkU64(8); + Bool is32bit = typeOfIRExpr(irsb->tyenv, argL0 ) == Ity_I32; + + IROp opAND = is32bit ? Iop_And32 : Iop_And64; + IROp opOR = is32bit ? Iop_Or32 : Iop_Or64; + IROp opCMPORDS = is32bit ? Iop_CmpORD32S : Iop_CmpORD64S; + IROp opCMPORDU = is32bit ? Iop_CmpORD32U : Iop_CmpORD64U; + IROp opCMPNE = is32bit ? Iop_CmpNE32 : Iop_CmpNE64; + IROp opCMPEQ = is32bit ? Iop_CmpEQ32 : Iop_CmpEQ64; + IRExpr* const0 = is32bit ? mkU32(0) : mkU64(0); + IRExpr* const2 = is32bit ? mkU32(2) : mkU64(2); + IRExpr* const4 = is32bit ? mkU32(4) : mkU64(4); + IRExpr* const8 = is32bit ? mkU32(8) : mkU64(8); const UChar b11100 = 0x1C; const UChar b00111 = 0x07; + if (is32bit) { + vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I32 ); + vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I32 ); + } else { + vassert( typeOfIRExpr(irsb->tyenv, argL0) == Ity_I64 ); + vassert( typeOfIRExpr(irsb->tyenv, argR0) == Ity_I64 ); + vassert( mode64 ); + } + if ((TO & b11100) == b11100 || (TO & b00111) == b00111) { /* Unconditional trap. Just do the exit without testing the arguments. */ @@ -4578,21 +4592,20 @@ static Bool do_trap ( Bool is_twi, UChar TO, return True; /* unconditional trap */ } - if (is_twi) { + if (is32bit) { argL = newTemp(Ity_I32); argR = newTemp(Ity_I32); - assign( argL, mode64 ? mkSzNarrow32(Ity_I64,argL0) - : argL0 ); - assign( argR, mkU32( (UInt)argR0 )); } else { - vassert(mode64); argL = newTemp(Ity_I64); argR = newTemp(Ity_I64); - assign( argL, argL0 ); - assign( argR, mkU64( argR0 )); } + + assign( argL, argL0 ); + assign( argR, argR0 ); + argLe = mkexpr(argL); argRe = mkexpr(argR); + cond = const0; if (TO & 16) { // L next = mkSzImm( ty, nextInsnAddr() ); + irsb->jumpkind = Ijk_Boring; + dres->whatNext = Dis_StopHere; + } + + return True; +} + /* System Linkage Instructions @@ -9262,11 +9324,11 @@ DisResult disInstr_PPC_WRK ( //zz case 0x136: case 0x1B6: // eciwx, ecowx //zz DIP("external control op => not implemented\n"); //zz goto decode_failure; -//zz -//zz /* Trap Instructions */ -//zz case 0x004: // tw -//zz DIP("trap op (tw) => not implemented\n"); -//zz goto decode_failure; + + /* Trap Instructions */ + case 0x004: // tw + if (dis_trap(theInstr, &dres)) goto decode_success; + goto decode_failure; //zz case 0x044: // td //zz DIP("trap op (td) => not implemented\n"); //zz goto decode_failure;